Skip to content

Commit

Permalink
NAY4-1 Risk of Denial of Service if Rewards Are Not Collected for Too…
Browse files Browse the repository at this point in the history
… Many Intervals (#146)

* feat: add collectRewards exposing interval

* refactor: rename to collectRewardsToInterval, update lock functions

* chore: add natspec for collectRewardsToInterval
  • Loading branch information
kevin-fruitful authored Oct 3, 2024
1 parent 1bf43e7 commit 75bf214
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/facets/StakingFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ contract StakingFacet is Modifiers {
LibTokenizedVaultStaking._collectRewards(parentId, _entityId, lastPaid);
}

/**
* @notice Collect rewards for a staker
* @param _entityId staking entity ID
* @param _interval interval to collect rewards up to
*/
function collectRewardsToInterval(bytes32 _entityId, uint64 _interval) external notLocked {
bytes32 parentId = LibObject._getParent(msg.sender._getIdForAddress());

LibTokenizedVaultStaking._collectRewards(parentId, _entityId, _interval);
}

function payReward(bytes32 _stakingRewardId, bytes32 _entityId, bytes32 _rewardTokenId, uint256 _amount) external notLocked assertPrivilege(_entityId, LC.GROUP_ENTITY_ADMINS) {
LibTokenizedVaultStaking._payReward(_stakingRewardId, _entityId, _rewardTokenId, _amount);
}
Expand Down
8 changes: 6 additions & 2 deletions src/libs/LibAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ library LibAdmin {
s.locked[IDiamondProxy.stake.selector] = true;
s.locked[IDiamondProxy.unstake.selector] = true;
s.locked[IDiamondProxy.collectRewards.selector] = true;
s.locked[IDiamondProxy.collectRewardsToInterval.selector] = true;
s.locked[IDiamondProxy.payReward.selector] = true;
s.locked[IDiamondProxy.cancelSimplePolicy.selector] = true;
s.locked[IDiamondProxy.createSimplePolicy.selector] = true;
s.locked[IDiamondProxy.createEntity.selector] = true;

bytes4[] memory lockedFunctions = new bytes4[](21);
bytes4[] memory lockedFunctions = new bytes4[](22);
lockedFunctions[0] = IDiamondProxy.startTokenSale.selector;
lockedFunctions[1] = IDiamondProxy.paySimpleClaim.selector;
lockedFunctions[2] = IDiamondProxy.paySimplePremium.selector;
Expand All @@ -168,6 +169,7 @@ library LibAdmin {
lockedFunctions[18] = IDiamondProxy.cancelSimplePolicy.selector;
lockedFunctions[19] = IDiamondProxy.createSimplePolicy.selector;
lockedFunctions[20] = IDiamondProxy.createEntity.selector;
lockedFunctions[21] = IDiamondProxy.collectRewardsToInterval.selector;

emit FunctionsLocked(lockedFunctions);
}
Expand Down Expand Up @@ -195,8 +197,9 @@ library LibAdmin {
s.locked[IDiamondProxy.cancelSimplePolicy.selector] = false;
s.locked[IDiamondProxy.createSimplePolicy.selector] = false;
s.locked[IDiamondProxy.createEntity.selector] = false;
s.locked[IDiamondProxy.collectRewardsToInterval.selector] = false;

bytes4[] memory lockedFunctions = new bytes4[](21);
bytes4[] memory lockedFunctions = new bytes4[](22);
lockedFunctions[0] = IDiamondProxy.startTokenSale.selector;
lockedFunctions[1] = IDiamondProxy.paySimpleClaim.selector;
lockedFunctions[2] = IDiamondProxy.paySimplePremium.selector;
Expand All @@ -218,6 +221,7 @@ library LibAdmin {
lockedFunctions[18] = IDiamondProxy.cancelSimplePolicy.selector;
lockedFunctions[19] = IDiamondProxy.createSimplePolicy.selector;
lockedFunctions[20] = IDiamondProxy.createEntity.selector;
lockedFunctions[21] = IDiamondProxy.collectRewardsToInterval.selector;

emit FunctionsUnlocked(lockedFunctions);
}
Expand Down
7 changes: 6 additions & 1 deletion test/T02Admin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ contract T02AdminTest is D03ProtocolDefaults, MockAccounts {
assertEq(entries[0].topics[0], keccak256("FunctionsLocked(bytes4[])"));
(s_functionSelectors) = abi.decode(entries[0].data, (bytes4[]));

bytes4[] memory lockedFunctions = new bytes4[](21);
bytes4[] memory lockedFunctions = new bytes4[](22);
lockedFunctions[0] = IDiamondProxy.startTokenSale.selector;
lockedFunctions[1] = IDiamondProxy.paySimpleClaim.selector;
lockedFunctions[2] = IDiamondProxy.paySimplePremium.selector;
Expand All @@ -263,6 +263,7 @@ contract T02AdminTest is D03ProtocolDefaults, MockAccounts {
lockedFunctions[18] = IDiamondProxy.cancelSimplePolicy.selector;
lockedFunctions[19] = IDiamondProxy.createSimplePolicy.selector;
lockedFunctions[20] = IDiamondProxy.createEntity.selector;
lockedFunctions[21] = IDiamondProxy.collectRewardsToInterval.selector;

for (uint256 i = 0; i < lockedFunctions.length; i++) {
assertTrue(nayms.isFunctionLocked(lockedFunctions[i]));
Expand Down Expand Up @@ -322,6 +323,9 @@ contract T02AdminTest is D03ProtocolDefaults, MockAccounts {
vm.expectRevert("function is locked");
nayms.collectRewards(bytes32(0));

vm.expectRevert("function is locked");
nayms.collectRewardsToInterval(bytes32(0), 5);

vm.expectRevert("function is locked");
nayms.cancelSimplePolicy(bytes32(0));

Expand Down Expand Up @@ -354,6 +358,7 @@ contract T02AdminTest is D03ProtocolDefaults, MockAccounts {
assertFalse(nayms.isFunctionLocked(IDiamondProxy.unstake.selector), "function unstake locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.payReward.selector), "function payReward locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.collectRewards.selector), "function collectRewards locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.collectRewardsToInterval.selector), "function collectRewardsToInterval locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.cancelSimplePolicy.selector), "function cancelSimplePolicy locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.createSimplePolicy.selector), "function createSimplePolicy locked");
assertFalse(nayms.isFunctionLocked(IDiamondProxy.createEntity.selector), "function createEntity locked");
Expand Down

0 comments on commit 75bf214

Please sign in to comment.