diff --git a/contracts/pool/BundleService.sol b/contracts/pool/BundleService.sol index cd7129c31..a5d588527 100644 --- a/contracts/pool/BundleService.sol +++ b/contracts/pool/BundleService.sol @@ -318,6 +318,10 @@ contract BundleService is revert ErrorBundleServiceBundleNotOpen(bundleNftId, bundleState, bundleInfo.expiredAt); } + if (lifetimeExtension.eqz()) { + revert ErrorBundleServiceExtensionLifetimeIsZero(); + } + bundleInfo.expiredAt = bundleInfo.expiredAt.addSeconds(lifetimeExtension); instance.getInstanceStore().updateBundle(bundleNftId, bundleInfo, KEEP_STATE()); diff --git a/contracts/pool/IBundleService.sol b/contracts/pool/IBundleService.sol index 8ef4abbe0..82c898b4c 100644 --- a/contracts/pool/IBundleService.sol +++ b/contracts/pool/IBundleService.sol @@ -26,13 +26,14 @@ interface IBundleService is IService { error ErrorBundleServicePolicyNotCloseable(NftId policyNftId); - // error ErrorBundleServiceBundleNotActive(NftId distributorNftId); error ErrorBundleServiceFeesWithdrawAmountExceedsLimit(Amount amount, Amount limit); error ErrorBundleServiceFeesWithdrawAmountIsZero(); error ErrorBundleServiceWalletAllowanceTooSmall(address wallet, address tokenHandler, uint256 allowance, uint256 amount); error ErrorBundleServiceUnstakeAmountExceedsLimit(Amount amount, Amount limit); + error ErrorBundleServiceExtensionLifetimeIsZero(); + event LogBundleServiceFeesWithdrawn(NftId bundleNftId, address recipient, address tokenAddress, Amount amount); event LogBundleServiceBundleExtended(NftId bundleNftId, Seconds lifetimeExtension, Timestamp extendedExpiredAt); diff --git a/test/TestBundle.t.sol b/test/TestBundle.t.sol index cb15e51b5..7bf26435f 100644 --- a/test/TestBundle.t.sol +++ b/test/TestBundle.t.sol @@ -500,7 +500,7 @@ contract TestBundle is GifTest { pool.extend(bundleNftId, lifetime); } - /// @dev test extension of an expired bundle + /// @dev test extension of a closed bundle function test_Bundle_extend_bundleClosed() public { // GIVEN _prepareProduct(false); @@ -532,6 +532,30 @@ contract TestBundle is GifTest { pool.extend(bundleNftId, lifetime); } + /// @dev test extension with lifetime is zero + function test_Bundle_extend_lifetimeIsZero() public { + // GIVEN + _prepareProduct(false); + + IComponents.ComponentInfo memory poolComponentInfo = instanceReader.getComponentInfo(poolNftId); + + vm.startPrank(investor); + token.approve(address(pool.getTokenHandler()), 1000); + + Seconds lifetime = SecondsLib.toSeconds(0); + bundleNftId = pool.createBundle( + FeeLib.zero(), + 1000, + lifetime, + "" + ); + // THEN - expect a revert + vm.expectRevert(abi.encodeWithSelector(IBundleService.ErrorBundleServiceExtensionLifetimeIsZero.selector)); + + // WHEN - bundle is extended + pool.extend(bundleNftId, lifetime); + } + function _fundInvestor(uint256 amount) internal { vm.startPrank(registryOwner); token.transfer(investor, amount);