Skip to content

Commit

Permalink
refactor: use single root
Browse files Browse the repository at this point in the history
  • Loading branch information
jparklev committed Apr 15, 2024
1 parent ad209ae commit c1525f3
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 19 deletions.
23 changes: 11 additions & 12 deletions contracts/PointTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ contract PointTokenVault is UUPSUpgradeable, OwnableUpgradeable {

// Merkle root distribution.
mapping(address => mapping(bytes32 => uint256)) public claimedPTokens; // user => pointsId => claimed
mapping(bytes32 => bytes32) public currRoot; // pointsId => root
mapping(bytes32 => bytes32) public prevRoot; // pointsId => root
bytes32 public currRoot;
bytes32 public prevRoot;
mapping(address => mapping(bytes32 => uint256)) public claimedRedemptionRights; // user => pointsId => claimed

struct Claim {
Expand All @@ -38,7 +38,7 @@ contract PointTokenVault is UUPSUpgradeable, OwnableUpgradeable {

event Deposit(address indexed user, address indexed token, uint256 amount);
event Withdraw(address indexed user, address indexed token, uint256 amount);
event RootUpdated(bytes32 indexed pointsId, bytes32 newRoot);
event RootUpdated(bytes32 prevRoot, bytes32 newRoot);
event PTokensClaimed(address indexed account, bytes32 indexed pointsId, uint256 amount);
event RewardsClaimed(address indexed owner, address indexed receiver, bytes32 indexed pointsId, uint256 amount);

Expand Down Expand Up @@ -81,9 +81,9 @@ contract PointTokenVault is UUPSUpgradeable, OwnableUpgradeable {

// Adapted from Morpho's RewardsDistributor.sol (https://github.com/morpho-org/morpho-optimizers/blob/main/src/common/rewards-distribution/RewardsDistributor.sol)
function _claimPointsToken(Claim calldata _claim, address _account) internal {
(bytes32 pointsId, uint256 totalClaimable) = (_claim.pointsId, _claim.totalClaimable);
bytes32 pointsId = _claim.pointsId;

bytes32 claimHash = keccak256(abi.encodePacked(_account, pointsId, totalClaimable));
bytes32 claimHash = keccak256(abi.encodePacked(_account, pointsId, _claim.totalClaimable));
verifyClaimAndUpdateClaimed(_claim, claimHash, _account, claimedPTokens);

pointTokenHub.mint(_account, pointsId, _claim.amountToClaim);
Expand Down Expand Up @@ -128,10 +128,10 @@ contract PointTokenVault is UUPSUpgradeable, OwnableUpgradeable {
) internal {
bytes32 candidateRoot = _claim.proof.processProof(_claimHash);
bytes32 pointsId = _claim.pointsId;
uint256 totalClaimable = _claim.totalClaimable; // IMPORTANT: Assumed to be in the claim hash.
uint256 totalClaimable = _claim.totalClaimable; // IMPORTANT: Must be in the claim hash.
uint256 amountToClaim = _claim.amountToClaim;

if (candidateRoot != currRoot[pointsId] && candidateRoot != prevRoot[pointsId]) {
if (candidateRoot != currRoot && candidateRoot != prevRoot) {
revert ProofInvalidOrExpired();
}

Expand All @@ -145,11 +145,10 @@ contract PointTokenVault is UUPSUpgradeable, OwnableUpgradeable {
// Admin ---

// Assume the points id was created using LibString.packTwo for readable token names.
function updateRoot(bytes32 _newRoot, bytes32 _pointsId) external onlyOwner {
if (_pointsId == bytes32(0)) revert InvalidPointsId();
prevRoot[_pointsId] = currRoot[_pointsId];
currRoot[_pointsId] = _newRoot;
emit RootUpdated(_pointsId, _newRoot);
function updateRoot(bytes32 _newRoot) external onlyOwner {
emit RootUpdated(prevRoot, _newRoot);
prevRoot = currRoot;
currRoot = _newRoot;
}

// To handle arbitrary reward claiming logic.
Expand Down
14 changes: 7 additions & 7 deletions contracts/test/PointTokenVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ contract PointTokenVaultTest is Test {
// Only admin can update root
vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vitalik));
vm.prank(vitalik);
pointTokenVault.updateRoot(root, bytes32("1"));
pointTokenVault.updateRoot(root);

// Update the root
vm.prank(admin);
pointTokenVault.updateRoot(root, bytes32("1"));
pointTokenVault.updateRoot(root);

// todo: can't submit bytes32(0)
}
Expand Down Expand Up @@ -189,7 +189,7 @@ contract PointTokenVaultTest is Test {
bytes32 pointsId = LibString.packTwo("Eigen Layer Point", "pEL");

vm.prank(admin);
pointTokenVault.updateRoot(root, pointsId);
pointTokenVault.updateRoot(root);

// Can't claim with the wrong proof
vm.prank(vitalik);
Expand Down Expand Up @@ -228,7 +228,7 @@ contract PointTokenVaultTest is Test {
bytes32 root = 0x4e40a10ce33f33a4786960a8bb843fe0e170b651acd83da27abc97176c4bed3c;

vm.prank(admin);
pointTokenVault.updateRoot(root, pointsId);
pointTokenVault.updateRoot(root);

bytes32[] memory vitalikProof = new bytes32[](1);
vitalikProof[0] = 0x6d0fcb8de12b1f57f81e49fa18b641487b932cdba4f064409fde3b05d3824ca2;
Expand Down Expand Up @@ -264,7 +264,7 @@ contract PointTokenVaultTest is Test {
proof[0] = 0x6d0fcb8de12b1f57f81e49fa18b641487b932cdba4f064409fde3b05d3824ca2;

vm.prank(admin);
pointTokenVault.updateRoot(root, pointsId);
pointTokenVault.updateRoot(root);

PointTokenVault.Claim[] memory claims = new PointTokenVault.Claim[](1);
claims[0] = PointTokenVault.Claim(pointsId, 1e18, 1e18, proof);
Expand Down Expand Up @@ -296,7 +296,7 @@ contract PointTokenVaultTest is Test {

// Set up the Merkle root and redemption parameters
vm.startPrank(admin);
pointTokenVault.updateRoot(root, pointsId);
pointTokenVault.updateRoot(root);
pointTokenHub.setRedemption(pointsId, rewardToken, 2e18, true); // Set isMerkleBased true
vm.stopPrank();

Expand Down Expand Up @@ -339,7 +339,7 @@ contract PointTokenVaultTest is Test {
bytes32 pointsId = LibString.packTwo("Eigen Layer Point", "pEL");

vm.prank(admin);
pointTokenVault.updateRoot(root, pointsId);
pointTokenVault.updateRoot(root);

// Can do a partial claim
vm.prank(vitalik);
Expand Down

0 comments on commit c1525f3

Please sign in to comment.