From acde08c5791f26520dc1bb0c0249360eabf3622d Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Mon, 8 Jul 2024 14:52:41 +0000 Subject: [PATCH] allow staking of locked bundles (#418) --- contracts/pool/BundleService.sol | 4 ++- contracts/pool/IBundleService.sol | 2 +- test/TestBundle.t.sol | 54 +++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/contracts/pool/BundleService.sol b/contracts/pool/BundleService.sol index 147013e06..34b67c37c 100644 --- a/contracts/pool/BundleService.sol +++ b/contracts/pool/BundleService.sol @@ -246,7 +246,9 @@ contract BundleService is IBundle.BundleInfo memory bundleInfo = instance.getInstanceReader().getBundleInfo(bundleNftId); StateId bundleState = instance.getInstanceReader().getBundleState(bundleNftId); - if(bundleState != ACTIVE() || bundleInfo.expiredAt < TimestampLib.blockTimestamp() || bundleInfo.closedAt.gtz()) { + if( (bundleState != ACTIVE() && bundleState != PAUSED()) // locked bundles can be staked + || bundleInfo.expiredAt < TimestampLib.blockTimestamp() + || bundleInfo.closedAt.gtz()) { revert ErrorBundleServiceBundleNotOpen(bundleNftId, bundleState, bundleInfo.expiredAt); } diff --git a/contracts/pool/IBundleService.sol b/contracts/pool/IBundleService.sol index 82c898b4c..04fb75c70 100644 --- a/contracts/pool/IBundleService.sol +++ b/contracts/pool/IBundleService.sol @@ -52,7 +52,7 @@ interface IBundleService is IService { returns(NftId bundleNftId); // the nft id of the newly created bundle - /// @dev increase bundle stakes by the specified amount + /// @dev increase bundle stakes by the specified amount. bundle must not be expired or closed /// may only be called by the pool service function stake(IInstance instance, NftId bundleNftId, Amount amount) external; diff --git a/test/TestBundle.t.sol b/test/TestBundle.t.sol index 8377fa49a..bd03304a4 100644 --- a/test/TestBundle.t.sol +++ b/test/TestBundle.t.sol @@ -81,6 +81,60 @@ contract TestBundle is GifTest { assertEq(instanceReader.getFeeAmount(bundleNftId).toInt(), 0, "bundle fees 0"); } + /// @dev test staking of an existing locked bundle + function test_Bundle_stakeBundle_lockedBundle() public { + // GIVEN + initialStakingFee = FeeLib.percentageFee(4); + _prepareProduct(false); + + IComponents.ComponentInfo memory poolComponentInfo = instanceReader.getComponentInfo(poolNftId); + + vm.startPrank(investor); + token.approve(address(pool.getTokenHandler()), 2000); + + Seconds lifetime = SecondsLib.toSeconds(604800); + (bundleNftId,) = pool.createBundle( + FeeLib.zero(), + 1000, + lifetime, + "" + ); + + assertTrue(!bundleNftId.eqz(), "bundle nft id is zero"); + + assertEq(token.balanceOf(poolComponentInfo.wallet), 1000, "pool wallet token balance not 1000"); + uint256 investorBalanceBefore = token.balanceOf(investor); + + assertEq(instanceReader.getBalanceAmount(poolNftId).toInt(), 1000, "pool balance not 1000"); + assertEq(instanceReader.getFeeAmount(poolNftId).toInt(), 40, "pool fees not 40"); + + assertEq(instanceReader.getBalanceAmount(bundleNftId).toInt(), 960, "bundle balance not 960"); + assertEq(instanceReader.getFeeAmount(bundleNftId).toInt(), 0, "bundle fees 0"); + + uint256 stakeAmount = 1000; + Amount stakeAmt = AmountLib.toAmount(stakeAmount); + Amount stakeNetAmt = AmountLib.toAmount(960); + + pool.lockBundle(bundleNftId); + + // THEN - expect log event + vm.expectEmit(); + emit IPoolService.LogPoolServiceBundleStaked(instanceNftId, poolNftId, bundleNftId, stakeAmt, stakeNetAmt); + + // WHEN - pool is staked with another 1000 tokens + pool.stake(bundleNftId, stakeAmt); + + // THEN - assert all counters are updated + assertEq(token.balanceOf(poolComponentInfo.wallet), 2000, "pool wallet token balance not 2000"); + assertEq(token.balanceOf(investor), investorBalanceBefore - stakeAmount, "investor token balance not 0"); + + assertEq(instanceReader.getBalanceAmount(poolNftId).toInt(), 2000, "pool balance not 2000"); + assertEq(instanceReader.getFeeAmount(poolNftId).toInt(), 80, "pool fees not 80"); + + assertEq(instanceReader.getBalanceAmount(bundleNftId).toInt(), 1920, "bundle balance not 1920"); + assertEq(instanceReader.getFeeAmount(bundleNftId).toInt(), 0, "bundle fees 0"); + } + /// @dev test staking when the allowance is too small function test_Bundle_stakeBundle_allowanceTooSmall() public { // GIVEN