Skip to content

Commit

Permalink
Merge pull request #32 from euler-xyz/plugins/setters
Browse files Browse the repository at this point in the history
[WIP]feat: add setters for plugins
  • Loading branch information
haythemsellami authored Jul 1, 2024
2 parents e09ae62 + 7a63756 commit e4eb399
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
version: nightly

- name: Run foundry build
run: forge build --sizes
run: forge build --force --sizes

- name: Run foundry fmt check
run: forge fmt --check
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ quote_style = "double"
number_underscore = "preserve"
override_spacing = true
ignore = [
"src/lib/StorageLib.sol"
"src/core/lib/StorageLib.sol"
]

[profile.test]
Expand Down
108 changes: 73 additions & 35 deletions src/core/EulerAggregationLayer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ contract EulerAggregationLayer is
bytes32 public constant STRATEGY_ADDER_ADMIN = keccak256("STRATEGY_ADDER_ADMIN");
bytes32 public constant STRATEGY_REMOVER = keccak256("STRATEGY_REMOVER");
bytes32 public constant STRATEGY_REMOVER_ADMIN = keccak256("STRATEGY_REMOVER_ADMIN");
bytes32 public constant AGGREGATION_VAULT_MANAGER = keccak256("AGGREGATION_VAULT_MANAGER");
bytes32 public constant AGGREGATION_VAULT_MANAGER_ADMIN = keccak256("AGGREGATION_VAULT_MANAGER_ADMIN");
bytes32 public constant REBALANCER = keccak256("REBALANCER");
bytes32 public constant REBALANCER_ADMIN = keccak256("REBALANCER_ADMIN");
bytes32 public constant AGGREGATION_LAYER_MANAGER = keccak256("AGGREGATION_LAYER_MANAGER");
bytes32 public constant AGGREGATION_LAYER_MANAGER_ADMIN = keccak256("AGGREGATION_LAYER_MANAGER_ADMIN");

/// @dev interest rate smearing period
uint256 public constant INTEREST_SMEAR = 2 weeks;
Expand All @@ -70,6 +68,7 @@ contract EulerAggregationLayer is
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();
$.locked = REENTRANCYLOCK__UNLOCKED;
$.withdrawalQueue = _initParams.withdrawalQueuePlugin;
$.rebalancer = _initParams.rebalancerPlugin;
$.strategies[address(0)] = IEulerAggregationLayer.Strategy({
allocated: 0,
allocationPoints: _initParams.initialCashAllocationPoints.toUint120(),
Expand All @@ -80,70 +79,68 @@ contract EulerAggregationLayer is
$.balanceTracker = _initParams.balanceTracker;

// Setup DEFAULT_ADMIN
_grantRole(DEFAULT_ADMIN_ROLE, _initParams.aggregationVaultOwner);
_grantRole(DEFAULT_ADMIN_ROLE, _initParams.aggregationLayerOwner);

// Setup role admins
_setRoleAdmin(ALLOCATIONS_MANAGER, ALLOCATIONS_MANAGER_ADMIN);
_setRoleAdmin(STRATEGY_ADDER, STRATEGY_ADDER_ADMIN);
_setRoleAdmin(STRATEGY_REMOVER, STRATEGY_REMOVER_ADMIN);
_setRoleAdmin(AGGREGATION_VAULT_MANAGER, AGGREGATION_VAULT_MANAGER_ADMIN);
_setRoleAdmin(REBALANCER, REBALANCER_ADMIN);

// By default, the Rebalancer contract is assigned the REBALANCER role
_grantRole(REBALANCER, _initParams.rebalancerPlugin);
_setRoleAdmin(AGGREGATION_LAYER_MANAGER, AGGREGATION_LAYER_MANAGER_ADMIN);
}

/// @dev See {FeeModule-setFeeRecipient}.
function setFeeRecipient(address _newFeeRecipient) external onlyRole(AGGREGATION_VAULT_MANAGER) use(MODULE_FEE) {}
function setFeeRecipient(address _newFeeRecipient) external onlyRole(AGGREGATION_LAYER_MANAGER) use(MODULE_FEE) {}

/// @dev See {FeeModule-setPerformanceFee}.
function setPerformanceFee(uint256 _newFee) external onlyRole(AGGREGATION_VAULT_MANAGER) use(MODULE_FEE) {}
function setPerformanceFee(uint256 _newFee) external onlyRole(AGGREGATION_LAYER_MANAGER) use(MODULE_FEE) {}

/// @dev See {RewardsModule-optInStrategyRewards}.
function optInStrategyRewards(address _strategy)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_REWARDS)
{}

/// @dev See {RewardsModule-optOutStrategyRewards}.
function optOutStrategyRewards(address _strategy)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_REWARDS)
{}

/// @dev See {RewardsModule-optOutStrategyRewards}.
function enableRewardForStrategy(address _strategy, address _reward)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_REWARDS)
{}

/// @dev See {RewardsModule-disableRewardForStrategy}.
function disableRewardForStrategy(address _strategy, address _reward, bool _forfeitRecentReward)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_REWARDS)
{}

/// @dev See {RewardsModule-claimStrategyReward}.
function claimStrategyReward(address _strategy, address _reward, address _recipient, bool _forfeitRecentReward)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_REWARDS)
{}

/// @dev See {RewardsModule-enableBalanceForwarder}.
function enableBalanceForwarder() external override use(MODULE_REWARDS) {}

/// @dev See {RewardsModule-disableBalanceForwarder}.
function disableBalanceForwarder() external override use(MODULE_REWARDS) {}
/// @dev See {HooksModule-setHooksConfig}.
function setHooksConfig(address _hooksTarget, uint32 _hookedFns)
external
override
onlyRole(AGGREGATION_LAYER_MANAGER)
use(MODULE_HOOKS)
{}

/// @dev See {AllocationPointsModule-adjustAllocationPoints}.
function adjustAllocationPoints(address _strategy, uint256 _newPoints)
Expand All @@ -169,26 +166,48 @@ contract EulerAggregationLayer is
/// @dev See {AllocationPointsModule-removeStrategy}.
function removeStrategy(address _strategy) external use(MODULE_ALLOCATION_POINTS) onlyRole(STRATEGY_REMOVER) {}

/// @dev See {HooksModule-setHooksConfig}.
function setHooksConfig(address _hooksTarget, uint32 _hookedFns)
external
override
onlyRole(AGGREGATION_VAULT_MANAGER)
use(MODULE_HOOKS)
{}
/// @dev See {RewardsModule-enableBalanceForwarder}.
function enableBalanceForwarder() external override use(MODULE_REWARDS) {}

/// @dev See {RewardsModule-disableBalanceForwarder}.
function disableBalanceForwarder() external override use(MODULE_REWARDS) {}

/// @notice Set a new address for WithdrawalQueue plugin.
/// @dev Can only be called by an address with the `AGGREGATION_LAYER_MANAGER` role.
/// @param _withdrawalQueue New WithdrawalQueue contract address.
function setWithdrawalQueue(address _withdrawalQueue) external onlyRole(AGGREGATION_LAYER_MANAGER) {
if (_withdrawalQueue == address(0)) revert Errors.InvalidPlugin();

AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

emit Events.SetWithdrawalQueue($.withdrawalQueue, _withdrawalQueue);

$.withdrawalQueue = _withdrawalQueue;
}

/// @notice Set a new address for Rebalancer plugin.
/// @dev Can only be called by an address with the `AGGREGATION_LAYER_MANAGER` role.
/// @param _rebalancer New Rebalancer contract address.
function setRebalancer(address _rebalancer) external onlyRole(AGGREGATION_LAYER_MANAGER) {
if (_rebalancer == address(0)) revert Errors.InvalidPlugin();

AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

emit Events.SetRebalancer($.rebalancer, _rebalancer);

$.rebalancer = _rebalancer;
}

/// @notice Rebalance strategy by depositing or withdrawing the amount to rebalance to hit target allocation.
/// @dev Can only be called by an address that hold the REBALANCER role.
/// @dev Can only be called only by the WithdrawalQueue plugin.
/// @param _strategy Strategy address.
/// @param _amountToRebalance Amount to deposit or withdraw.
/// @param _isDeposit bool to indicate if it is a deposit or a withdraw.
function rebalance(address _strategy, uint256 _amountToRebalance, bool _isDeposit)
external
nonReentrant
onlyRole(REBALANCER)
{
function rebalance(address _strategy, uint256 _amountToRebalance, bool _isDeposit) external nonReentrant {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

if (_msgSender() != $.rebalancer) revert Errors.NotRebalancer();

IEulerAggregationLayer.Strategy memory strategyData = $.strategies[_strategy];

if (_isDeposit) {
Expand Down Expand Up @@ -295,30 +314,49 @@ contract EulerAggregationLayer is
return avsr;
}

/// @notice Get the total allocated amount.
/// @return uint256 Total allocated.
function totalAllocated() external view returns (uint256) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

return $.totalAllocated;
}

/// @notice Get the total allocation points.
/// @return uint256 Total allocation points.
function totalAllocationPoints() external view returns (uint256) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

return $.totalAllocationPoints;
}

/// @notice Get the total assets deposited into the aggregation layer.
/// @return uint256 Total assets deposited.
function totalAssetsDeposited() external view returns (uint256) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

return $.totalAssetsDeposited;
}

/// @notice Get the WithdrawalQueue plugin address.
/// @return address Withdrawal queue address.
function withdrawalQueue() external view returns (address) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

return $.withdrawalQueue;
}

/// @notice Get the Rebalancer plugin address.
/// @return address Rebalancer address.
function rebalancer() external view returns (address) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

return $.rebalancer;
}

/// @notice Get the performance fee config.
/// @return adddress Fee recipient.
/// @return uint256 Fee percentage.
function performanceFeeConfig() external view returns (address, uint256) {
AggregationVaultStorage storage $ = StorageLib._getAggregationVaultStorage();

Expand Down
2 changes: 1 addition & 1 deletion src/core/EulerAggregationLayerFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ contract EulerAggregationLayerFactory {
balanceTracker: balanceTracker,
withdrawalQueuePlugin: address(withdrawalQueue),
rebalancerPlugin: rebalancer,
aggregationVaultOwner: msg.sender,
aggregationLayerOwner: msg.sender,
asset: _asset,
name: _name,
symbol: _symbol,
Expand Down
2 changes: 1 addition & 1 deletion src/core/interface/IEulerAggregationLayer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface IEulerAggregationLayer {
address balanceTracker;
address withdrawalQueuePlugin;
address rebalancerPlugin;
address aggregationVaultOwner;
address aggregationLayerOwner;
address asset;
string name;
string symbol;
Expand Down
2 changes: 2 additions & 0 deletions src/core/lib/ErrorsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ library ErrorsLib {
error InvalidHookedFns();
error EmptyError();
error NotWithdrawaQueue();
error InvalidPlugin();
error NotRebalancer();
}
2 changes: 2 additions & 0 deletions src/core/lib/EventsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ library EventsLib {
event Rebalance(address indexed strategy, uint256 amountToRebalance, bool isDeposit);
event ExecuteHarvest(address indexed strategy, uint256 strategyBalanceAmount, uint256 strategyAllocatedAmount);
event Harvest(uint256 totalAllocated, uint256 totlaYield, uint256 totalLoss);
event SetWithdrawalQueue(address _oldWithdrawalQueuePlugin, address _newWithdrawalQueuePlugin);
event SetRebalancer(address _oldRebalancer, address _newRebalancer);

/// @dev Allocationpoints events
event AdjustAllocationPoints(address indexed strategy, uint256 oldPoints, uint256 newPoints);
Expand Down
8 changes: 7 additions & 1 deletion src/core/lib/StorageLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ struct AggregationVaultStorage {
uint256 performanceFee;
/// fee recipient address
address feeRecipient;
/// Withdrawal queue contract's address
/// WithdrawalQueue plugin address
address withdrawalQueue;
/// Rebalancer plugin address
address rebalancer;
/// Mapping between strategy address and it's allocation config
mapping(address => IEulerAggregationLayer.Strategy) strategies;
/// lastInterestUpdate: last timestamo where interest was updated.
Expand All @@ -28,10 +30,14 @@ struct AggregationVaultStorage {
uint168 interestLeft;
/// locked: if locked or not for update.
uint8 locked;


/// Address of balance tracker contract for reward streams integration.
address balanceTracker;
/// A mapping to check if a user address enabled balance forwarding for reward streams integration.
mapping(address => bool) isBalanceForwarderEnabled;


/// @dev storing the hooks target and kooked functions.
uint256 hooksConfig;
}
Expand Down
1 change: 0 additions & 1 deletion src/plugin/Rebalancer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {IERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.s
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice A contract to execute rebalance() on the EulerAggregationLayer.
/// @dev Usually this contract will hold the `REBALANCER` role.
contract Rebalancer {
event ExecuteRebalance(
address indexed curatedVault,
Expand Down
13 changes: 6 additions & 7 deletions test/common/EulerAggregationLayerBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,14 @@ contract EulerAggregationLayerBase is EVaultTestBase {
eulerAggregationLayer.grantRole(eulerAggregationLayer.ALLOCATIONS_MANAGER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.STRATEGY_ADDER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.STRATEGY_REMOVER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.REBALANCER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer);
withdrawalQueue.grantRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer);

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

vm.stopPrank();
Expand All @@ -110,8 +109,8 @@ contract EulerAggregationLayerBase is EVaultTestBase {
eulerAggregationLayer.STRATEGY_REMOVER_ADMIN()
);
assertEq(
eulerAggregationLayer.getRoleAdmin(eulerAggregationLayer.AGGREGATION_VAULT_MANAGER()),
eulerAggregationLayer.AGGREGATION_VAULT_MANAGER_ADMIN()
eulerAggregationLayer.getRoleAdmin(eulerAggregationLayer.AGGREGATION_LAYER_MANAGER()),
eulerAggregationLayer.AGGREGATION_LAYER_MANAGER_ADMIN()
);
assertEq(
withdrawalQueue.getRoleAdmin(withdrawalQueue.WITHDRAW_QUEUE_MANAGER()),
Expand All @@ -121,13 +120,13 @@ contract EulerAggregationLayerBase is EVaultTestBase {
assertTrue(eulerAggregationLayer.hasRole(eulerAggregationLayer.ALLOCATIONS_MANAGER_ADMIN(), deployer));
assertTrue(eulerAggregationLayer.hasRole(eulerAggregationLayer.STRATEGY_ADDER_ADMIN(), deployer));
assertTrue(eulerAggregationLayer.hasRole(eulerAggregationLayer.STRATEGY_REMOVER_ADMIN(), deployer));
assertTrue(eulerAggregationLayer.hasRole(eulerAggregationLayer.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer));
assertTrue(eulerAggregationLayer.hasRole(eulerAggregationLayer.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer));
assertTrue(withdrawalQueue.hasRole(withdrawalQueue.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer));

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

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 @@ -46,14 +46,14 @@ contract BalanceForwarderE2ETest is EulerAggregationLayerBase {
// eulerAggregationLayer.grantRole(eulerAggregationLayer.WITHDRAW_QUEUE_MANAGER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.STRATEGY_ADDER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.STRATEGY_REMOVER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.AGGREGATION_VAULT_MANAGER_ADMIN(), deployer);
eulerAggregationLayer.grantRole(eulerAggregationLayer.AGGREGATION_LAYER_MANAGER_ADMIN(), deployer);

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

uint256 initialStrategyAllocationPoints = 500e18;
Expand Down
10 changes: 9 additions & 1 deletion test/unit/RebalanceTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
IEVault,
IRMTestDefault,
TestERC20,
IEulerAggregationLayer
IEulerAggregationLayer,
ErrorsLib
} from "../common/EulerAggregationLayerBase.t.sol";

contract RebalanceTest is EulerAggregationLayerBase {
Expand Down Expand Up @@ -346,4 +347,11 @@ contract RebalanceTest is EulerAggregationLayerBase {
// );
// assertEq((eulerAggregationLayer.getStrategy(address(eTST))).allocated, strategyBefore.allocated - eTSTMaxWithdraw);
}

function testRebalanceFromRandomSender() public {
vm.startPrank(user1);
vm.expectRevert(ErrorsLib.NotRebalancer.selector);
eulerAggregationLayer.rebalance(address(eTST), 1, true);
vm.stopPrank();
}
}
Loading

0 comments on commit e4eb399

Please sign in to comment.