forked from Cyfrin/defi-reth
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEigenLayerRestake.sol
More file actions
175 lines (155 loc) · 6.63 KB
/
EigenLayerRestake.sol
File metadata and controls
175 lines (155 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20} from "../interfaces/IERC20.sol";
import {IStrategyManager} from "../interfaces/eigen-layer/IStrategyManager.sol";
import {IStrategy} from "../interfaces/eigen-layer/IStrategy.sol";
import {IDelegationManager} from
"../interfaces/eigen-layer/IDelegationManager.sol";
import {IRewardsCoordinator} from
"../interfaces/eigen-layer/IRewardsCoordinator.sol";
import {
RETH,
EIGEN_LAYER_STRATEGY_MANAGER,
EIGEN_LAYER_STRATEGY_RETH,
EIGEN_LAYER_DELEGATION_MANAGER,
EIGEN_LAYER_REWARDS_COORDINATOR,
EIGEN_LAYER_OPERATOR
} from "../Constants.sol";
import {max} from "../Util.sol";
/// @title EigenLayerRestake
/// @notice This contract allows users to deposit RETH into EigenLayer's staking system,
// delegate to an operator, and manage withdrawals and rewards.
/// @dev The contract interacts with EigenLayer's StrategyManager, DelegationManager,
// and RewardsCoordinator to facilitate staking, delegation, and reward claims.
contract EigenLayerRestake {
IERC20 constant reth = IERC20(RETH);
IStrategyManager constant strategyManager =
IStrategyManager(EIGEN_LAYER_STRATEGY_MANAGER);
IStrategy constant strategy = IStrategy(EIGEN_LAYER_STRATEGY_RETH);
IDelegationManager constant delegationManager =
IDelegationManager(EIGEN_LAYER_DELEGATION_MANAGER);
IRewardsCoordinator constant rewardsCoordinator =
IRewardsCoordinator(EIGEN_LAYER_REWARDS_COORDINATOR);
address public owner;
modifier auth() {
require(msg.sender == owner, "not authorized");
_;
}
constructor() {
owner = msg.sender;
}
/// @notice Deposit RETH into the EigenLayer
/// @param rethAmount The amount of RETH to deposit into EigenLayer
/// @return shares The number of shares received from the deposit
/// @dev This function transfers RETH from the user to the contract, approves it for the StrategyManager,
/// and then deposits it into the EigenLayer strategy. The user receives shares in return.
function deposit(uint256 rethAmount) external returns (uint256 shares) {
// Write your code here
}
/// @notice Delegate staking to a specific operator
/// @param operator The address of the operator to delegate to
/// @dev This function allows the owner to delegate their stake to a specified operator.
/// The operator will perform actions on behalf of the staker.
function delegate(address operator) external auth {
// Write your code here
}
/// @notice Undelegate from the current operator and queue a withdrawal
/// @return withdrawalRoot The root of the withdrawal Merkle tree
/// @dev This function allows the owner to undelegate from their current operator.
/// It also queues a withdrawal from the operator, enabling the user to reclaim their stake.
function undelegate()
external
auth
returns (bytes32[] memory withdrawalRoot)
{
// Write your code here
}
/// @notice Withdraw staked RETH from an operator after undelegation
/// @param operator The address of the operator to withdraw from
/// @param shares The number of shares to withdraw
/// @param startBlockNum The block number to start the withdrawal
/// @dev This function allows the owner to withdraw staked RETH from an operator,
/// including the specified number of shares and the block number to begin the withdrawal.
function withdraw(address operator, uint256 shares, uint32 startBlockNum)
external
auth
{
// Write your code here
}
/* Notes on claim rewards
struct EarnerTreeMerkleLeaf {
address earner;
bytes32 earnerTokenRoot;
}
struct TokenTreeMerkleLeaf {
address token;
uint256 cumulativeEarnings;
}
struct RewardsMerkleClaim {
uint32 rootIndex;
uint32 earnerIndex;
bytes earnerTreeProof;
EarnerTreeMerkleLeaf earnerLeaf;
uint32[] tokenIndices;
bytes[] tokenTreeProofs;
TokenTreeMerkleLeaf[] tokenLeaves;
}
struct DistributionRoot {
bytes32 root;
uint32 rewardsCalculationEndTimestamp;
uint32 activatedAt;
bool disabled;
}
*/
// root
// - earner leaf 0
// - earner 0 address
// - earner 0 token root ------+
// - earner leaf 1 |
// - earner 1 address |
// - earner 1 token root |
// - earner leaf 2 |
// ... |
// |
// earner token root <-----------+
// - token leaf 0
// - token 0
// - cumulative earnings 0
// - token leaf 1
// - token 1
// - cumulative earnings 1
// - ...
/// @notice Claim rewards for staked RETH
/// @param claim The rewards claim data
/// @dev This function processes a rewards claim by interacting with the RewardsCoordinator.
/// It allows the owner to claim rewards associated with their staked RETH.
function claimRewards(IRewardsCoordinator.RewardsMerkleClaim memory claim)
external
{
// Write your code here
}
/// @notice Get the number of shares held in the strategy for the current staker
/// @return The number of shares held in the EigenLayer strategy
function getShares() external view returns (uint256) {
return strategyManager.stakerDepositShares(
address(this), address(strategy)
);
}
/// @notice Get the withdrawal delay for the current staker
/// @return The withdrawal delay in blocks
/// @dev This function returns the maximum of the protocol's minimum withdrawal delay and the strategy's delay.
function getWithdrawalDelay() external view returns (uint256) {
uint256 protocolDelay = delegationManager.minWithdrawalDelayBlocks();
address[] memory strategies = new address[](1);
strategies[0] = address(strategy);
uint256 strategyDelay = delegationManager.getWithdrawalDelay(strategies);
return max(protocolDelay, strategyDelay);
}
/// @notice Transfer all of a specific token from the contract to the given address
/// @param token The address of the token to transfer
/// @param dst The address to transfer the token to
/// @dev This function allows the owner to transfer any token from the contract to a specified address.
function transfer(address token, address dst) external auth {
IERC20(token).transfer(dst, IERC20(token).balanceOf(address(this)));
}
}