Skip to content

Commit 96f1c05

Browse files
committed
add completionTimestamp
1 parent a986841 commit 96f1c05

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

src/monad/StakingLens.sol

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ contract StakingLens {
1818
uint256 public constant MONAD_BLOCK_REWARD = 25 ether;
1919
uint256 public constant MONAD_BLOCKS_PER_YEAR = 78_840_000;
2020
uint64 public constant APY_BPS_PRECISION = 10_000;
21+
uint64 public constant MONAD_BOUNDARY_BLOCK_PERIOD = 50_000;
22+
uint64 public constant MONAD_EPOCH_SECONDS = MONAD_BOUNDARY_BLOCK_PERIOD * 2 / 5; // 0.4s block time
2123

2224
enum DelegationState {
2325
Active,
@@ -33,6 +35,7 @@ contract StakingLens {
3335
uint256 amount;
3436
uint256 rewards; // unclaimed rewards only for Active entries
3537
uint64 withdrawEpoch; // populated for withdrawals
38+
uint64 completionTimestamp;
3639
}
3740

3841
struct DelegatorSnapshot {
@@ -152,7 +155,8 @@ contract StakingLens {
152155
state: DelegationState.Active,
153156
amount: snap.stake,
154157
rewards: snap.rewards,
155-
withdrawEpoch: 0
158+
withdrawEpoch: 0,
159+
completionTimestamp: 0
156160
});
157161
++positionCount;
158162
}
@@ -164,7 +168,8 @@ contract StakingLens {
164168
state: DelegationState.Activating,
165169
amount: snap.pendingStake,
166170
rewards: 0,
167-
withdrawEpoch: 0
171+
withdrawEpoch: 0,
172+
completionTimestamp: 0
168173
});
169174
++positionCount;
170175
}
@@ -200,7 +205,10 @@ contract StakingLens {
200205
state: withdrawEpoch < currentEpoch ? DelegationState.AwaitingWithdrawal : DelegationState.Deactivating,
201206
amount: amount,
202207
rewards: 0,
203-
withdrawEpoch: withdrawEpoch
208+
withdrawEpoch: withdrawEpoch,
209+
completionTimestamp: withdrawEpoch < currentEpoch
210+
? 0
211+
: _withdrawCompletionTimestamp(withdrawEpoch, currentEpoch)
204212
});
205213

206214
++count;
@@ -211,6 +219,18 @@ contract StakingLens {
211219
return (count, lastWithdrawId, hasWithdrawals);
212220
}
213221

222+
function _withdrawCompletionTimestamp(uint64 withdrawEpoch, uint64 currentEpoch) internal view returns (uint64) {
223+
if (withdrawEpoch < currentEpoch) {
224+
return 0;
225+
}
226+
227+
uint64 remainingEpochs = withdrawEpoch - currentEpoch + 1;
228+
uint256 completion = block.timestamp + uint256(remainingEpochs) * uint256(MONAD_EPOCH_SECONDS);
229+
// casting to uint64 is safe because completion timestamps are bounded by the type max guard above
230+
// forge-lint: disable-next-line(unsafe-typecast)
231+
return completion > type(uint64).max ? type(uint64).max : uint64(completion);
232+
}
233+
214234
/**
215235
* @notice Return validator stats plus APY for a set of validator ids.
216236
* @param validatorIds If empty, uses the curated Monad validator list.

0 commit comments

Comments
 (0)