Skip to content

Commit

Permalink
clean; add invariants tests
Browse files Browse the repository at this point in the history
  • Loading branch information
haythemsellami committed Jul 9, 2024
1 parent 1fc4174 commit 04e1fea
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 78 deletions.
106 changes: 53 additions & 53 deletions src/core/EulerAggregationVault.sol

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/core/EulerAggregationVaultFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ contract EulerAggregationVaultFactory is Ownable {
emit WhitelistWithdrawalQueueImpl(_withdrawalQueuImpl);
}

/// @notice Deploy a new aggregation layer vault.
/// @dev This will clone a new WithdrawalQueue plugin instance for the aggregation layer vault.
/// @notice Deploy a new aggregation vault.
/// @dev This will clone a new WithdrawalQueue plugin instance for the aggregation vault.
/// @dev This will use the defaut Rebalancer plugin configured in this factory.
/// @dev Both plugins are possible to change by the aggregation layer vault manager.
/// @param _asset Aggreation layer vault' asset address.
/// @dev Both plugins are possible to change by the aggregation vault manager.
/// @param _asset Aggreation vault' asset address.
/// @param _name Vaut name.
/// @param _symbol Vault symbol.
/// @param _initialCashAllocationPoints The amount of points to initally allocate for cash reserve.
/// @return eulerAggregationVault The address of the new deployed aggregation layer vault.
/// @return eulerAggregationVault The address of the new deployed aggregation vault.
function deployEulerAggregationVault(
address _withdrawalQueueImpl,
address _asset,
Expand Down
1 change: 1 addition & 0 deletions src/core/lib/ErrorsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ library ErrorsLib {
error NotRebalancer();
error InvalidAllocationPoints();
error CanNotRemoveStartegyWithAllocatedAmount();
error NoCapOnCashReserveStrategy();
}
4 changes: 4 additions & 0 deletions src/core/module/AllocationPoints.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ abstract contract AllocationPointsModule is Shared {
revert Errors.InactiveStrategy();
}

if (_strategy == address(0)) {
revert Errors.NoCapOnCashReserveStrategy();
}

$.strategies[_strategy].cap = _cap.toUint120();

emit Events.SetStrategyCap(_strategy, _cap);
Expand Down
4 changes: 2 additions & 2 deletions src/core/module/Rewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ abstract contract RewardsModule is IBalanceForwarder, Shared {
emit Events.OptOutStrategyRewards(_strategy);
}

/// @notice Enable aggregation layer vault rewards for specific strategy's reward token.
/// @notice Enable aggregation vault rewards for specific strategy's reward token.
/// @param _strategy Strategy address.
/// @param _reward Reward token address.
function enableRewardForStrategy(address _strategy, address _reward) external virtual nonReentrant {
Expand All @@ -52,7 +52,7 @@ abstract contract RewardsModule is IBalanceForwarder, Shared {
emit Events.EnableRewardForStrategy(_strategy, _reward);
}

/// @notice Disable aggregation layer vault rewards for specific strategy's reward token.
/// @notice Disable aggregation vault rewards for specific strategy's reward token.
/// @param _strategy Strategy address.
/// @param _reward Reward token address.
/// @param _forfeitRecentReward Whether to forfeit the recent rewards or not.
Expand Down
4 changes: 2 additions & 2 deletions src/plugin/Rebalancer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract Rebalancer {
);

/// @notice Rebalance strategies allocation for a specific curated vault.
/// @param _aggregationVault Aggregation layer vault address.
/// @param _aggregationVault Aggregation vault address.
/// @param _strategies Strategies addresses.
function executeRebalance(address _aggregationVault, address[] calldata _strategies) external {
IEulerAggregationVault(_aggregationVault).gulp();
Expand All @@ -33,7 +33,7 @@ contract Rebalancer {
/// If current allocation is less than target allocation, the aggregator will:
/// - Try to deposit the delta, if the cash is not sufficient, deposit all the available cash
/// - If all the available cash is greater than the max deposit, deposit the max deposit
/// @param _aggregationVault Aggregation layer vault address.
/// @param _aggregationVault Aggregation vault address.
/// @param _strategy Strategy address.
function _rebalance(address _aggregationVault, address _strategy) private {
if (_strategy == address(0)) {
Expand Down
16 changes: 8 additions & 8 deletions src/plugin/WithdrawalQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ contract WithdrawalQueue is AccessControlEnumerableUpgradeable, IWithdrawalQueue
event ReorderWithdrawalQueue(uint8 index1, uint8 index2);

/// @notice Initialize WithdrawalQueue.
/// @param _owner Aggregation layer vault owner.
/// @param _eulerAggregationVault Address of aggregation layer vault.
/// @param _owner Aggregation vault owner.
/// @param _eulerAggregationVault Address of aggregation vault.
function init(address _owner, address _eulerAggregationVault) external initializer {
WithdrawalQueueStorage storage $ = _getWithdrawalQueueStorage();
$.eulerAggregationVault = _eulerAggregationVault;
Expand All @@ -49,7 +49,7 @@ contract WithdrawalQueue is AccessControlEnumerableUpgradeable, IWithdrawalQueue
}

/// @notice Add a strategy to withdrawal queue array.
/// @dev Can only be called by the aggregation layer vault's address.
/// @dev Can only be called by the aggregation vault's address.
/// @param _strategy Strategy address to add
function addStrategyToWithdrawalQueue(address _strategy) external {
_isCallerAggregationVault();
Expand All @@ -60,7 +60,7 @@ contract WithdrawalQueue is AccessControlEnumerableUpgradeable, IWithdrawalQueue
}

/// @notice Remove a strategy from withdrawal queue array.
/// @dev Can only be called by the aggregation layer vault's address.
/// @dev Can only be called by the aggregation vault's address.
/// @param _strategy Strategy address to add.
function removeStrategyFromWithdrawalQueue(address _strategy) external {
_isCallerAggregationVault();
Expand Down Expand Up @@ -102,14 +102,14 @@ contract WithdrawalQueue is AccessControlEnumerableUpgradeable, IWithdrawalQueue
emit ReorderWithdrawalQueue(_index1, _index2);
}

/// @notice Execute the withdraw initiated in the aggregation layer vault.
/// @dev Can only be called by the aggregation layer vault's address.
/// @notice Execute the withdraw initiated in the aggregation vault.
/// @dev Can only be called by the aggregation vault's address.
/// @param _caller Initiator's address of withdraw.
/// @param _receiver Withdraw receiver address.
/// @param _owner Shares's owner to burn.
/// @param _assets Amount of asset to withdraw.
/// @param _shares Amount of shares to burn.
/// @param _availableAssets Amount of available asset in aggregation layer vault's cash reserve.
/// @param _availableAssets Amount of available asset in aggregation vault's cash reserve.
function callWithdrawalQueue(
address _caller,
address _receiver,
Expand Down Expand Up @@ -187,7 +187,7 @@ contract WithdrawalQueue is AccessControlEnumerableUpgradeable, IWithdrawalQueue
return $.withdrawalQueue.length;
}

/// @dev Check if the msg.sender is the aggregation layer vault.
/// @dev Check if the msg.sender is the aggregation vault.
function _isCallerAggregationVault() private view {
WithdrawalQueueStorage storage $ = _getWithdrawalQueueStorage();

Expand Down
12 changes: 6 additions & 6 deletions test/common/EulerAggregationVaultBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ contract EulerAggregationVaultBase is EVaultTestBase {
eulerAggregationVault.grantRole(eulerAggregationVault.ALLOCATIONS_MANAGER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_ADDER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_REMOVER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer);
withdrawalQueue.grantRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer);

// grant roles to manager
eulerAggregationVault.grantRole(eulerAggregationVault.ALLOCATIONS_MANAGER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_ADDER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_REMOVER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER(), manager);
withdrawalQueue.grantRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER(), manager);

vm.stopPrank();
Expand Down Expand Up @@ -122,8 +122,8 @@ contract EulerAggregationVaultBase is EVaultTestBase {
eulerAggregationVault.STRATEGY_REMOVER_ADMIN()
);
assertEq(
eulerAggregationVault.getRoleAdmin(eulerAggregationVault.AGGREGATION_LAYER_MANAGER()),
eulerAggregationVault.AGGREGATION_LAYER_MANAGER_ADMIN()
eulerAggregationVault.getRoleAdmin(eulerAggregationVault.AGGREGATION_VAULT_MANAGER()),
eulerAggregationVault.AGGREGATION_VAULT_MANAGER_ADMIN()
);
assertEq(
withdrawalQueue.getRoleAdmin(withdrawalQueue.WITHDRAW_QUEUE_MANAGER()),
Expand All @@ -133,13 +133,13 @@ contract EulerAggregationVaultBase is EVaultTestBase {
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.ALLOCATIONS_MANAGER_ADMIN(), deployer));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.STRATEGY_ADDER_ADMIN(), deployer));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.STRATEGY_REMOVER_ADMIN(), deployer));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer));
assertTrue(withdrawalQueue.hasRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer));

assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.ALLOCATIONS_MANAGER(), manager));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.STRATEGY_ADDER(), manager));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.STRATEGY_REMOVER(), manager));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER(), manager));
assertTrue(eulerAggregationVault.hasRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER(), manager));
assertTrue(withdrawalQueue.hasRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER(), manager));

assertEq(eulerAggregationVaultFactory.getWithdrawalQueueImplsListLength(), 1);
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/BalanceForwarderE2ETest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ contract BalanceForwarderE2ETest is EulerAggregationVaultBase {
// eulerAggregationVault.grantRole(eulerAggregationVault.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_ADDER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_REMOVER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer);

// grant roles to manager
eulerAggregationVault.grantRole(eulerAggregationVault.ALLOCATIONS_MANAGER(), manager);
// eulerAggregationVault.grantRole(eulerAggregationVault.WITHDRAW_QUEUE_MANAGER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_ADDER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.STRATEGY_REMOVER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_LAYER_MANAGER(), manager);
eulerAggregationVault.grantRole(eulerAggregationVault.AGGREGATION_VAULT_MANAGER(), manager);
vm.stopPrank();

uint256 initialStrategyAllocationPoints = 500e18;
Expand Down
18 changes: 18 additions & 0 deletions test/invariant/EulerAggregationLayerInvariants.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ contract EulerAggregationVaultInvariants is EulerAggregationVaultBase {
strategyUtil.includeStrategy(address(eTSTforth));
strategyUtil.includeStrategy(address(eTSTfifth));
strategyUtil.includeStrategy(address(eTSTsixth));
// cash reserve strategy
strategyUtil.includeStrategy(address(0));

eulerAggregationVaultHandler =
new EulerAggregationVaultHandler(eulerAggregationVault, actorUtil, strategyUtil, withdrawalQueue);
Expand Down Expand Up @@ -96,6 +98,18 @@ contract EulerAggregationVaultInvariants is EulerAggregationVaultBase {
assertEq(eulerAggregationVault.totalAllocationPoints(), expectedTotalAllocationpoints);
}

// Every strategy in the withdrawal queue should have an allocation points > 0.
function invariant_withdrawalQueueStrategiesAllocationPoints() public view {
address withdrawalQueueAddr = eulerAggregationVault.withdrawalQueue();

(address[] memory withdrawalQueueArray, uint256 withdrawalQueueLength) =
IWithdrawalQueue(withdrawalQueueAddr).getWithdrawalQueueArray();

for (uint256 i; i < withdrawalQueueLength; i++) {
assertGt(eulerAggregationVault.getStrategy(withdrawalQueueArray[i]).allocationPoints, 0);
}
}

// If `total allocation points - cash reserve allocation points == 0`(no strategy added), the withdrawal queue length should be zero.
// Else, the length should be greater than zero.
function invariant_withdrawalQueue() public view {
Expand Down Expand Up @@ -147,6 +161,10 @@ contract EulerAggregationVaultInvariants is EulerAggregationVaultBase {
assertGe(aggregationVaultSavingRate.interestLeft, accruedInterest);
}

function invariant_cashReserveStrategyCap() public view {
assertEq(eulerAggregationVault.getStrategy(address(0)).cap, 0);
}

function _deployOtherStrategies() private {
eTSTsecond = IEVault(
factory.createProxy(address(0), true, abi.encodePacked(address(assetTST), address(oracle), unitOfAccount))
Expand Down

0 comments on commit 04e1fea

Please sign in to comment.