diff --git a/src/v2/Carousel/Carousel.sol b/src/v2/Carousel/Carousel.sol index 310e5461..51909d2b 100644 --- a/src/v2/Carousel/Carousel.sol +++ b/src/v2/Carousel/Carousel.sol @@ -398,12 +398,6 @@ contract Carousel is VaultV2 { while ((index - prevIndex) < (_operations)) { - // skip the rollover for the user if the assets cannot cover the relayer fee instead of revert. - if (queue[index].assets < relayerFee) { - index++; - continue; - } - // only roll over if last epoch is resolved and user rollover position is valid if (epochResolved[queue[index].epochId] && queue[index].assets > 0) { @@ -411,13 +405,22 @@ contract Carousel is VaultV2 { queue[index].epochId, queue[index].assets ); + // mint only if user won epoch he is rolling over if (entitledAmount > queue[index].assets) { - uint256 diff = entitledAmount - queue[index].assets; - // get diff amount in assets - uint256 diffInAssets = diff.mulDivUp(finalTVL[queue[index].epochId], claimTVL[queue[index].epochId]); - - uint256 originalDepositValue = queue[index].assets - diffInAssets; + // @note previewAmountInShares can only be called if epoch is in profit + uint256 relayerFeeInShares = previewAmountInShares(queue[index].epochId, relayerFee); + + // skip the rollover for the user if the assets cannot cover the relayer fee instead of revert. + if (queue[index].assets < relayerFeeInShares) { + index++; + continue; + } + + // to calculate originalDepositValue get the diff between shares and value of shares + // convert this value amount value back to shares + // subtract from assets + uint256 originalDepositValue = queue[index].assets - previewAmountInShares(queue[index].epochId, (entitledAmount - queue[index].assets)); // @note we know shares were locked up to this point _burn( queue[index].receiver, @@ -447,7 +450,7 @@ contract Carousel is VaultV2 { originalDepositValue, entitledAmount ); - uint256 assetsToMint = queue[index].assets - relayerFee; + uint256 assetsToMint = queue[index].assets - relayerFeeInShares; _mintShares(queue[index].receiver, _epochId, assetsToMint); emit Deposit( msg.sender, @@ -690,6 +693,25 @@ contract Carousel is VaultV2 { entitledAmount = _assets.mulDivDown(emissions[_id], finalTVL[_id]); } + /** @notice returns the emissions to withdraw + * @param _id epoch id + * @param _assets amount of shares + * @return entitledShareAmount amount of emissions to withdraw + */ + function previewAmountInShares(uint256 _id, uint256 _assets) + public + view + returns (uint256 entitledShareAmount) + { + if(claimTVL[_id] != 0) { + entitledShareAmount = _assets.mulDivDown(finalTVL[_id], claimTVL[_id]); + } else { + entitledShareAmount = 0; + } + + } + + /** @notice returns the deposit queue length * @return queue length for the deposit */ diff --git a/test/V2/Carousel/CarouselTest.t.sol b/test/V2/Carousel/CarouselTest.t.sol index 45cce350..e6a6427d 100644 --- a/test/V2/Carousel/CarouselTest.t.sol +++ b/test/V2/Carousel/CarouselTest.t.sol @@ -319,8 +319,6 @@ contract CarouselTest is Helper { .with_key(prevEpoch) .checked_write(1000 ether); - console.log("rollover queue length", vault.getRolloverQueueLenght()); - // get value of prev epoch sahres for user uint256 prevEpochShareValue = vault.previewWithdraw(prevEpoch, vault.balanceOf(USER, prevEpoch)); @@ -337,23 +335,23 @@ contract CarouselTest is Helper { uint256 _relayerFee = (balanceAfter - balanceBefore) / 6; assertEq(_relayerFee, relayerFee); + uint256 relayerFeeInShares = vault.previewAmountInShares(prevEpoch,relayerFee); //@note after rollover, prev value of shares should subtract by original deposit value uint256 prevEpochSharesValueAfterRollover = vault.previewWithdraw(prevEpoch, vault.balanceOf(USER, prevEpoch)); - assertEq(((prevEpochSharesValueAfterRollover >> 1) << 1) , ((prevEpochShareValue - prevEpochUserBalance) >> 1) << 1); // zero out last bit to avoid rounding errors - + assertEq(((prevEpochSharesValueAfterRollover >> 1) << 1) , (((prevEpochShareValue) - (prevEpochUserBalance) - 16) >> 1) << 1); // zero out last bit to avoid rounding errors // check balances - assertEq(vault.balanceOf(USER, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOf(USER2, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER2, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOf(USER3, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER3, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOf(USER4, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER4, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOf(USER5, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER5, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOf(USER6, _epochId), prevEpochUserBalance - relayerFee); - assertEq(vault.balanceOfEmissions(USER6, _epochId), prevEpochUserBalance - relayerFee); + assertEq(vault.balanceOf(USER, _epochId), prevEpochUserBalance - relayerFeeInShares ); + assertEq(vault.balanceOfEmissions(USER, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOf(USER2, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOfEmissions(USER2, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOf(USER3, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOfEmissions(USER3, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOf(USER4, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOfEmissions(USER4, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOf(USER5, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOfEmissions(USER5, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOf(USER6, _epochId), prevEpochUserBalance - relayerFeeInShares); + assertEq(vault.balanceOfEmissions(USER6, _epochId), prevEpochUserBalance - relayerFeeInShares); } diff --git a/test/V2/Helper.sol b/test/V2/Helper.sol index e0b1ccaa..9732f282 100644 --- a/test/V2/Helper.sol +++ b/test/V2/Helper.sol @@ -9,10 +9,10 @@ contract Helper is Test { uint256 public constant STRIKE = 1000000000000000000; uint256 public constant COLLATERAL_MINUS_FEES = 21989999998398551453; uint256 public constant COLLATERAL_MINUS_FEES_DIV10 = 2198999999839855145; - uint256 public constant NEXT_COLLATERAL_MINUS_FEES = 21827317001456829250; - uint256 public constant USER1_EMISSIONS_AFTER_WITHDRAW = 1096655439903230405185; - uint256 public constant USER2_EMISSIONS_AFTER_WITHDRAW = 96655439903230405185; - uint256 public constant USER_AMOUNT_AFTER_WITHDRAW = 13112658495640855090; + uint256 public constant NEXT_COLLATERAL_MINUS_FEES = 21827317001324992496; + uint256 public constant USER1_EMISSIONS_AFTER_WITHDRAW = 1096655439903230405190; + uint256 public constant USER2_EMISSIONS_AFTER_WITHDRAW = 96655439903230405190; + uint256 public constant USER_AMOUNT_AFTER_WITHDRAW = 13112658495821846450; address public constant ADMIN = address(0x1); address public constant WETH = address(0x888); address public constant TREASURY = address(0x777); diff --git a/test/V2/e2e/EndToEndCarouselTest.t.sol b/test/V2/e2e/EndToEndCarouselTest.t.sol index d02a79e0..75b719c2 100644 --- a/test/V2/e2e/EndToEndCarouselTest.t.sol +++ b/test/V2/e2e/EndToEndCarouselTest.t.sol @@ -269,8 +269,8 @@ contract EndToEndCarouselTest is Helper { //assert balance in next epoch uint256 balanceInNextEpoch = Carousel(collateral).balanceOf(USER, nextEpochId); - //assert rollover minus relayer fee - assertEq(balanceInNextEpoch, 8 ether - relayerFee); + //assert rollover minus relayer fee which is subtracted based on the value of the shares of the prev epoch + assertEq(balanceInNextEpoch, (8 ether - Carousel(collateral).previewAmountInShares(epochId, relayerFee))); //withdraw after rollover Carousel(collateral).withdraw(nextEpochId, balanceInNextEpoch, USER, USER); @@ -302,8 +302,8 @@ contract EndToEndCarouselTest is Helper { //assert balance in next epoch balanceInNextEpoch = Carousel(collateral).balanceOf(USER2, nextEpochId); - //assert rollover minus relayer fee - assertTrue(balanceInNextEpoch == 8 ether - relayerFee); + //assert rollover minus relayer fee which is subtracted based on the value of the shares of the prev epoch + assertTrue(balanceInNextEpoch == 8 ether - Carousel(collateral).previewAmountInShares(epochId, relayerFee)); //withdraw after rollover Carousel(collateral).withdraw(nextEpochId, balanceInNextEpoch, USER2, USER2);