From e662cb7ab76ff5794c2b955e25217fac1efbb1e4 Mon Sep 17 00:00:00 2001 From: nelson-pereira8 <94120714+nican0r@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:08:55 -0300 Subject: [PATCH 1/4] test: rational flow for allocating/claiming bribe --- test/BribeInitiative.t.sol | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/BribeInitiative.t.sol b/test/BribeInitiative.t.sol index 5333182..b40aedb 100644 --- a/test/BribeInitiative.t.sol +++ b/test/BribeInitiative.t.sol @@ -346,6 +346,51 @@ contract BribeInitiativeTest is Test { assertEq(totalLQTYAllocated, 0); } + // forge test --match-test test_rationalFlow -vv + function test_rationalFlow() public { + vm.warp(block.timestamp + (EPOCH_DURATION)); // Initiative not active + + // We are now at epoch + + // Deposit + _stakeLQTY(user1, 1e18); + + // Deposit Bribe for now + _allocateLQTY(user1, 5e17, 0); /// @audit Allocate b4 or after bribe should be irrelevant + + /// @audit WTF + _depositBribe(1e18, 1e18, governance.epoch() + 1); /// @audit IMO this should also work + + _allocateLQTY(user1, 5e17, 0); /// @audit Allocate b4 or after bribe should be irrelevant + + // deposit bribe for Epoch + 2 + _depositBribe(1e18, 1e18, governance.epoch() + 2); + + + (uint88 totalLQTYAllocated,) = + bribeInitiative.totalLQTYAllocatedByEpoch(governance.epoch()); + (uint88 userLQTYAllocated,) = + bribeInitiative.lqtyAllocatedByUserAtEpoch(user1, governance.epoch()); + assertEq(totalLQTYAllocated, 1e18, "total allocation"); + assertEq(userLQTYAllocated, 1e18, "user allocation"); + + vm.warp(block.timestamp + (EPOCH_DURATION)); + // We are now at epoch + 1 // Should be able to claim epoch - 1 + + // user should receive bribe from their allocated stake + (uint256 boldAmount, uint256 bribeTokenAmount) = _claimBribe(user1, governance.epoch(), governance.epoch() - 1, governance.epoch() - 1); + assertEq(boldAmount, 1e18, "bold amount"); + assertEq(bribeTokenAmount, 1e18, "bribe amount"); + + // decrease user allocation for the initiative + _allocateLQTY(user1, -1e18, 0); + + (userLQTYAllocated,) = bribeInitiative.lqtyAllocatedByUserAtEpoch(user1, governance.epoch()); + (totalLQTYAllocated,) = bribeInitiative.totalLQTYAllocatedByEpoch(governance.epoch()); + assertEq(userLQTYAllocated, 0, "total allocation"); + assertEq(totalLQTYAllocated, 0, "user allocation"); + } + /** Revert Cases */ From 3a6c038d253588f238d50b3815abf85973a5daf6 Mon Sep 17 00:00:00 2001 From: gallo Date: Mon, 14 Oct 2024 14:20:04 +0200 Subject: [PATCH 2/4] fix: bribe CEI --- src/BribeInitiative.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/BribeInitiative.sol b/src/BribeInitiative.sol index 8da4d51..b1d8ad0 100644 --- a/src/BribeInitiative.sol +++ b/src/BribeInitiative.sol @@ -56,8 +56,6 @@ contract BribeInitiative is IInitiative, IBribeInitiative { /// @inheritdoc IBribeInitiative function depositBribe(uint128 _boldAmount, uint128 _bribeTokenAmount, uint16 _epoch) external { - bold.safeTransferFrom(msg.sender, address(this), _boldAmount); - bribeToken.safeTransferFrom(msg.sender, address(this), _bribeTokenAmount); uint16 epoch = governance.epoch(); require(_epoch > epoch, "BribeInitiative: only-future-epochs"); @@ -68,6 +66,9 @@ contract BribeInitiative is IInitiative, IBribeInitiative { bribeByEpoch[_epoch] = bribe; emit DepositBribe(msg.sender, _boldAmount, _bribeTokenAmount, _epoch); + + bold.safeTransferFrom(msg.sender, address(this), _boldAmount); + bribeToken.safeTransferFrom(msg.sender, address(this), _bribeTokenAmount); } function _claimBribe( From af5132f20ae264a2f0eb0ffa0a0d1a7054799a70 Mon Sep 17 00:00:00 2001 From: gallo Date: Mon, 14 Oct 2024 14:20:31 +0200 Subject: [PATCH 3/4] fix: cannot claim in the future --- src/BribeInitiative.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BribeInitiative.sol b/src/BribeInitiative.sol index b1d8ad0..cd810d6 100644 --- a/src/BribeInitiative.sol +++ b/src/BribeInitiative.sol @@ -77,7 +77,7 @@ contract BribeInitiative is IInitiative, IBribeInitiative { uint16 _prevLQTYAllocationEpoch, uint16 _prevTotalLQTYAllocationEpoch ) internal returns (uint256 boldAmount, uint256 bribeTokenAmount) { - require(_epoch != governance.epoch(), "BribeInitiative: cannot-claim-for-current-epoch"); + require(_epoch < governance.epoch(), "BribeInitiative: cannot-claim-for-current-epoch"); require(!claimedBribeAtEpoch[_user][_epoch], "BribeInitiative: already-claimed"); Bribe memory bribe = bribeByEpoch[_epoch]; From f118d1f28abd44bc1b23d9c00283638fb163bee5 Mon Sep 17 00:00:00 2001 From: gallo Date: Mon, 14 Oct 2024 14:25:41 +0200 Subject: [PATCH 4/4] feat: rational flow --- src/BribeInitiative.sol | 2 +- test/BribeInitiative.t.sol | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/BribeInitiative.sol b/src/BribeInitiative.sol index cd810d6..6392c76 100644 --- a/src/BribeInitiative.sol +++ b/src/BribeInitiative.sol @@ -58,7 +58,7 @@ contract BribeInitiative is IInitiative, IBribeInitiative { function depositBribe(uint128 _boldAmount, uint128 _bribeTokenAmount, uint16 _epoch) external { uint16 epoch = governance.epoch(); - require(_epoch > epoch, "BribeInitiative: only-future-epochs"); + require(_epoch >= epoch, "BribeInitiative: only-future-epochs"); Bribe memory bribe = bribeByEpoch[_epoch]; bribe.boldAmount += _boldAmount; diff --git a/test/BribeInitiative.t.sol b/test/BribeInitiative.t.sol index b40aedb..6e4931c 100644 --- a/test/BribeInitiative.t.sol +++ b/test/BribeInitiative.t.sol @@ -346,7 +346,7 @@ contract BribeInitiativeTest is Test { assertEq(totalLQTYAllocated, 0); } - // forge test --match-test test_rationalFlow -vv + // forge test --match-test test_rationalFlow -vvvv function test_rationalFlow() public { vm.warp(block.timestamp + (EPOCH_DURATION)); // Initiative not active @@ -359,12 +359,12 @@ contract BribeInitiativeTest is Test { _allocateLQTY(user1, 5e17, 0); /// @audit Allocate b4 or after bribe should be irrelevant /// @audit WTF - _depositBribe(1e18, 1e18, governance.epoch() + 1); /// @audit IMO this should also work + _depositBribe(1e18, 1e18, governance.epoch()); /// @audit IMO this should also work _allocateLQTY(user1, 5e17, 0); /// @audit Allocate b4 or after bribe should be irrelevant // deposit bribe for Epoch + 2 - _depositBribe(1e18, 1e18, governance.epoch() + 2); + _depositBribe(1e18, 1e18, governance.epoch() + 1); (uint88 totalLQTYAllocated,) = @@ -378,10 +378,13 @@ contract BribeInitiativeTest is Test { // We are now at epoch + 1 // Should be able to claim epoch - 1 // user should receive bribe from their allocated stake - (uint256 boldAmount, uint256 bribeTokenAmount) = _claimBribe(user1, governance.epoch(), governance.epoch() - 1, governance.epoch() - 1); + (uint256 boldAmount, uint256 bribeTokenAmount) = _claimBribe(user1, governance.epoch() - 1, governance.epoch() - 1, governance.epoch() - 1); assertEq(boldAmount, 1e18, "bold amount"); assertEq(bribeTokenAmount, 1e18, "bribe amount"); + // And they cannot claim the one that is being added currently + _claimBribe(user1, governance.epoch(), governance.epoch() - 1, governance.epoch() - 1, true); + // decrease user allocation for the initiative _allocateLQTY(user1, -1e18, 0); @@ -643,11 +646,18 @@ contract BribeInitiativeTest is Test { } function _claimBribe(address claimer, uint16 epoch, uint16 prevLQTYAllocationEpoch, uint16 prevTotalLQTYAllocationEpoch) public returns (uint256 boldAmount, uint256 bribeTokenAmount){ + return _claimBribe(claimer, epoch, prevLQTYAllocationEpoch, prevTotalLQTYAllocationEpoch, false); + } + + function _claimBribe(address claimer, uint16 epoch, uint16 prevLQTYAllocationEpoch, uint16 prevTotalLQTYAllocationEpoch, bool expectRevert) public returns (uint256 boldAmount, uint256 bribeTokenAmount){ vm.startPrank(claimer); BribeInitiative.ClaimData[] memory epochs = new BribeInitiative.ClaimData[](1); epochs[0].epoch = epoch; epochs[0].prevLQTYAllocationEpoch = prevLQTYAllocationEpoch; epochs[0].prevTotalLQTYAllocationEpoch = prevTotalLQTYAllocationEpoch; + if(expectRevert) { + vm.expectRevert(); + } (boldAmount, bribeTokenAmount) = bribeInitiative.claimBribes(epochs); vm.stopPrank(); }