From 199ca1781a5c372144d905f3f56fcee0cf593590 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:45:28 +0300 Subject: [PATCH] accrue performance fee in underlying asset --- src/FourSixTwoSixAgg.sol | 24 ++++++++++++++++-------- test/e2e/PerformanceFeeE2ETest.t.sol | 3 +-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/FourSixTwoSixAgg.sol b/src/FourSixTwoSixAgg.sol index daff6e86..12e09ab8 100644 --- a/src/FourSixTwoSixAgg.sol +++ b/src/FourSixTwoSixAgg.sol @@ -104,7 +104,7 @@ contract FourSixTwoSixAgg is IFourSixTwoSixAgg, BalanceForwarder, EVCUtil, ERC46 event ReorderWithdrawalQueue(uint8 index1, uint8 index2); event AddStrategy(address indexed strategy, uint256 allocationPoints); event RemoveStrategy(address indexed _strategy); - event AccruePerformanceFee(address indexed feeRecipient, uint256 performanceFee, uint256 yield, uint256 feeShares); + event AccruePerformanceFee(address indexed feeRecipient, uint256 yield, uint256 feeAssets); event SetStrategyCap(address indexed strategy, uint256 cap); event Rebalance(address indexed strategy, uint256 _amountToRebalance, bool _isDeposit); @@ -609,10 +609,15 @@ contract FourSixTwoSixAgg is IFourSixTwoSixAgg, BalanceForwarder, EVCUtil, ERC46 } else if (underlyingBalance > strategyAllocatedAmount) { // There's yield! uint256 yield = underlyingBalance - strategyAllocatedAmount; + uint120 accruedPerformanceFee = _accruePerformanceFee(_strategy, yield); + + if (accruedPerformanceFee != 0) { + underlyingBalance -= accruedPerformanceFee; + yield -= accruedPerformanceFee; + } + strategies[_strategy].allocated = uint120(underlyingBalance); totalAllocated += yield; - - _accruePerformanceFee(yield); } else { uint256 loss = strategyAllocatedAmount - underlyingBalance; @@ -632,19 +637,22 @@ contract FourSixTwoSixAgg is IFourSixTwoSixAgg, BalanceForwarder, EVCUtil, ERC46 emit Harvest(_strategy, underlyingBalance, strategyAllocatedAmount); } - function _accruePerformanceFee(uint256 _yield) internal { + function _accruePerformanceFee(address _strategy, uint256 _yield) internal returns (uint120) { address cachedFeeRecipient = feeRecipient; uint256 cachedPerformanceFee = performanceFee; - if (cachedFeeRecipient == address(0) || cachedPerformanceFee == 0) return; + if (cachedFeeRecipient == address(0) || cachedPerformanceFee == 0) return 0; // `feeAssets` will be rounded down to 0 if `yield * performanceFee < 1e18`. uint256 feeAssets = Math.mulDiv(_yield, cachedPerformanceFee, 1e18, Math.Rounding.Down); - uint256 feeShares = _convertToShares(feeAssets, Math.Rounding.Down); - if (feeShares != 0) _mint(cachedFeeRecipient, feeShares); + if(feeAssets > 0) { + IERC4626(_strategy).withdraw(feeAssets, cachedFeeRecipient, address(this)); + } + + emit AccruePerformanceFee(cachedFeeRecipient, _yield, feeAssets); - emit AccruePerformanceFee(cachedFeeRecipient, cachedPerformanceFee, _yield, feeShares); + return feeAssets.toUint120(); } /// @dev Override _afterTokenTransfer hook to call IBalanceTracker.balanceTrackerHook() diff --git a/test/e2e/PerformanceFeeE2ETest.t.sol b/test/e2e/PerformanceFeeE2ETest.t.sol index f8cec8a9..81652b74 100644 --- a/test/e2e/PerformanceFeeE2ETest.t.sol +++ b/test/e2e/PerformanceFeeE2ETest.t.sol @@ -102,13 +102,12 @@ contract PerformanceFeeE2ETest is FourSixTwoSixAggBase { } uint256 expectedPerformanceFee = yield * fourSixTwoSixAgg.performanceFee() / 1e18; - uint256 expectedPerformanceFeeShares = fourSixTwoSixAgg.convertToShares(expectedPerformanceFee); // harvest vm.prank(user1); fourSixTwoSixAgg.harvest(address(eTST)); - assertEq(fourSixTwoSixAgg.balanceOf(feeRecipient), expectedPerformanceFeeShares); + assertEq(assetTST.balanceOf(feeRecipient), expectedPerformanceFee); // full withdraw, will have to withdraw from strategy as cash reserve is not enough {