@@ -147,7 +147,7 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable {
147147 event MarketAdded (address indexed market );
148148 event MarketRemoved (address indexed market );
149149 event ARMBufferUpdated (uint256 armBuffer );
150- event Allocated (address indexed market , int256 assets );
150+ event Allocated (address indexed market , int256 targetLiquidityDelta , int256 actualLiquidityDelta );
151151
152152 constructor (
153153 address _token0 ,
@@ -905,59 +905,73 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable {
905905
906906 /// @notice Deposit or withdraw liquidity assets to/from the active lending market
907907 /// to match the ARM's liquidity buffer which is a percentage of the available assets.
908+ /// The buffer excludes liquidity assets reserved for the ARM's withdrawal queue. That is, more
909+ /// liquidity assets will be withdrawn from the lending market if the ARM's liquidity asset balance
910+ /// does not cover the buffer, which can be zero, and the ARM's outstanding withdrawals.
908911 /// Will revert if there is no active lending market set.
909- /// @return liquidityDelta The actual liquidity less target liquidity before
910- /// the deposit/withdrawal to/from the active lending market.
911- function allocate () external returns (int256 liquidityDelta ) {
912+ /// @return targetLiquidityDelta the desired amount that is deposited/withdrawn to/from the lending market.
913+ /// A positive value is the liquidity assets that should be deposited to the lending market.
914+ /// A negative value is the desired liquidity assets that should be withdrawn from the lending market.
915+ /// @return actualLiquidityDelta the actual amount that is deposited/withdrawn to/from the lending market.
916+ /// A positive value is the liquidity assets that were deposited to the lending market.
917+ /// A negative value is the liquidity assets that were withdrawn from the lending market. This can be less than
918+ /// the `targetLiquidityDelta`, or even zero, if there is high utilization in the lending market.
919+ function allocate () external returns (int256 targetLiquidityDelta , int256 actualLiquidityDelta ) {
912920 require (activeMarket != address (0 ), "ARM: no active market " );
913921
914- liquidityDelta = _allocate ();
922+ return _allocate ();
915923 }
916924
917- function _allocate () internal returns (int256 liquidityDelta ) {
925+ function _allocate () internal returns (int256 targetLiquidityDelta , int256 actualLiquidityDelta ) {
918926 (uint256 availableAssets , uint256 outstandingWithdrawals ) = _availableAssets ();
919- if (availableAssets == 0 ) return 0 ;
927+ if (availableAssets == 0 ) return (0 , 0 );
928+ uint256 targetArmLiquidity = availableAssets * armBuffer / 1e18 ;
920929
921- int256 armLiquidity = SafeCast.toInt256 (IERC20 (liquidityAsset).balanceOf (address (this )))
930+ // The current liquidity available in swap is the liquidity asset balance less
931+ // any outstanding withdrawals from the ARM's withdrawal queue
932+ int256 currentArmLiquidity = SafeCast.toInt256 (IERC20 (liquidityAsset).balanceOf (address (this )))
922933 - SafeCast.toInt256 (outstandingWithdrawals);
923- uint256 targetArmLiquidity = availableAssets * armBuffer / 1e18 ;
924934
925- liquidityDelta = armLiquidity - SafeCast.toInt256 (targetArmLiquidity);
935+ targetLiquidityDelta = currentArmLiquidity - SafeCast.toInt256 (targetArmLiquidity);
926936
927937 // Load the active lending market address from storage to save gas
928938 address activeMarketMem = activeMarket;
929939
930940 // The allocateThreshold prevents the ARM from constantly depositing and withdrawing if there are rounding issues
931- if (liquidityDelta > allocateThreshold) {
941+ if (targetLiquidityDelta > allocateThreshold) {
932942 // We have too much liquidity in the ARM, we need to deposit some to the active lending market
933943
934- uint256 depositAmount = SafeCast.toUint256 (liquidityDelta );
944+ uint256 depositAmount = SafeCast.toUint256 (targetLiquidityDelta );
935945
936946 IERC20 (liquidityAsset).approve (activeMarketMem, depositAmount);
937947 IERC4626 (activeMarketMem).deposit (depositAmount, address (this ));
938- } else if (liquidityDelta < 0 ) {
948+
949+ actualLiquidityDelta = SafeCast.toInt256 (depositAmount);
950+ } else if (targetLiquidityDelta < 0 ) {
939951 // We have too little liquidity in the ARM, we need to withdraw some from the active lending market
940952
941953 uint256 availableMarketAssets = IERC4626 (activeMarketMem).maxWithdraw (address (this ));
942- uint256 desiredWithdrawAmount = SafeCast.toUint256 (- liquidityDelta );
954+ uint256 desiredWithdrawAmount = SafeCast.toUint256 (- targetLiquidityDelta );
943955
944956 if (availableMarketAssets < desiredWithdrawAmount) {
945957 // Not enough assets in the market so redeem as much as possible.
946958 // maxRedeem is used instead of balanceOf as we want to redeem as much as possible without failing.
947959 // redeem of the ARM's balance can fail if the lending market is highly utilized or temporarily paused.
948960 // Redeem and not withdrawal is used to avoid leaving a small amount of assets in the market.
949961 uint256 shares = IERC4626 (activeMarketMem).maxRedeem (address (this ));
950- if (shares <= minSharesToRedeem) return liquidityDelta ;
962+ if (shares <= minSharesToRedeem) return (targetLiquidityDelta, 0 ) ;
951963 // This should not fail according to the ERC-4626 spec as maxRedeem was used earlier
952964 // but it depends on the 4626 implementation of the lending market.
953965 // It may fail if the market is highly utilized and not compliant with 4626.
954- IERC4626 (activeMarketMem).redeem (shares, address (this ), address (this ));
966+ uint256 redeemedAssets = IERC4626 (activeMarketMem).redeem (shares, address (this ), address (this ));
967+ actualLiquidityDelta = - SafeCast.toInt256 (redeemedAssets);
955968 } else {
956969 IERC4626 (activeMarketMem).withdraw (desiredWithdrawAmount, address (this ), address (this ));
970+ actualLiquidityDelta = - SafeCast.toInt256 (desiredWithdrawAmount);
957971 }
958972 }
959973
960- emit Allocated (activeMarketMem, liquidityDelta );
974+ emit Allocated (activeMarketMem, targetLiquidityDelta, actualLiquidityDelta );
961975 }
962976
963977 ////////////////////////////////////////////////////
0 commit comments