Skip to content

Commit d9ba6e7

Browse files
committed
feat: make epoch's increase auto-commit
1 parent 3c79587 commit d9ba6e7

File tree

8 files changed

+354
-216
lines changed

8 files changed

+354
-216
lines changed

src/contracts/vault/v1.1/Vault.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, Prox
146146

147147
burner = params.burner;
148148

149-
epochDurationInit = Time.timestamp();
150-
epochDuration = params.epochDuration;
149+
epochDurationInitInternal = Time.timestamp();
150+
epochDurationInternal = params.epochDuration;
151151

152152
depositWhitelist = params.depositWhitelist;
153153

src/contracts/vault/v1.1/VaultImplementation.sol

Lines changed: 75 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,74 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
2929

3030
constructor(address delegatorFactory, address slasherFactory) VaultStorage(delegatorFactory, slasherFactory) {}
3131

32+
/**
33+
* @inheritdoc IVault
34+
*/
35+
function epochDuration() public view returns (uint48) {
36+
if (nextEpochDurationInitInternal == 0 || Time.timestamp() < nextEpochDurationInitInternal) {
37+
return epochDurationInternal;
38+
}
39+
return nextEpochDurationInternal;
40+
}
41+
42+
/**
43+
* @inheritdoc IVault
44+
*/
45+
function epochDurationInit() public view returns (uint48) {
46+
if (nextEpochDurationInitInternal == 0 || Time.timestamp() < nextEpochDurationInitInternal) {
47+
return epochDurationInitInternal;
48+
}
49+
return nextEpochDurationInitInternal;
50+
}
51+
3252
/**
3353
* @inheritdoc IVault
3454
*/
3555
function epochAt(
3656
uint48 timestamp
3757
) public view returns (uint256) {
38-
if (timestamp < epochDurationInit) {
39-
if (previousEpochDurationInit == 0 || timestamp < previousEpochDurationInit) {
58+
if (timestamp < epochDurationInitInternal) {
59+
if (prevEpochDurationInitInternal == 0 || timestamp < prevEpochDurationInitInternal) {
4060
revert InvalidTimestamp();
4161
}
42-
return epochInit - (epochDurationInit - timestamp).ceilDiv(previousEpochDuration);
62+
return prevEpochInitInternal + (timestamp - prevEpochDurationInitInternal) / prevEpochDurationInternal;
63+
} else if (nextEpochDurationInitInternal == 0 || timestamp < nextEpochDurationInitInternal) {
64+
return epochInitInternal + (timestamp - epochDurationInitInternal) / epochDurationInternal;
65+
} else {
66+
return nextEpochInitInternal + (timestamp - nextEpochDurationInitInternal) / nextEpochDurationInternal;
67+
}
68+
}
69+
70+
function epochStart(
71+
uint256 epoch
72+
) public view returns (uint48) {
73+
if (epoch < prevEpochInitInternal) {
74+
revert();
75+
}
76+
77+
if (epoch < epochInitInternal) {
78+
return
79+
(prevEpochDurationInitInternal + (epoch - prevEpochInitInternal) * prevEpochDurationInternal).toUint48();
80+
} else if (nextEpochInitInternal == 0 || epoch < nextEpochInitInternal) {
81+
return (epochDurationInitInternal + (epoch - epochInitInternal) * epochDurationInternal).toUint48();
82+
} else {
83+
return
84+
(nextEpochDurationInitInternal + (epoch - nextEpochInitInternal) * nextEpochDurationInternal).toUint48();
4385
}
44-
return epochInit + (timestamp - epochDurationInit) / epochDuration;
4586
}
4687

4788
/**
4889
* @inheritdoc IVault
4990
*/
5091
function currentEpoch() public view returns (uint256) {
51-
return epochInit + (Time.timestamp() - epochDurationInit) / epochDuration;
92+
return epochAt(Time.timestamp());
5293
}
5394

5495
/**
5596
* @inheritdoc IVault
5697
*/
5798
function currentEpochStart() public view returns (uint48) {
58-
return (epochDurationInit + (currentEpoch() - epochInit) * epochDuration).toUint48();
99+
return epochStart(currentEpoch());
59100
}
60101

61102
/**
@@ -66,17 +107,14 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
66107
if (epoch == 0) {
67108
revert NoPreviousEpoch();
68109
}
69-
if (epoch == epochInit) {
70-
return epochDurationInit - previousEpochDuration;
71-
}
72-
return (epochDurationInit + (epoch - epochInit - 1) * epochDuration).toUint48();
110+
return epochStart(epoch - 1);
73111
}
74112

75113
/**
76114
* @inheritdoc IVault
77115
*/
78116
function nextEpochStart() public view returns (uint48) {
79-
return currentEpochStart() + epochDuration;
117+
return epochStart(currentEpoch() + 1);
80118
}
81119

82120
/**
@@ -215,8 +253,6 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
215253
revert NotWhitelistedDepositor();
216254
}
217255

218-
_tryAcceptEpochDuration();
219-
220256
uint256 balanceBefore = IERC20(collateral).balanceOf(address(this));
221257
IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);
222258
depositedAmount = IERC20(collateral).balanceOf(address(this)) - balanceBefore;
@@ -483,37 +519,43 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
483519
function setEpochDuration(
484520
uint48 epochDuration_
485521
) external nonReentrant onlyRole(EPOCH_DURATION_SET_ROLE) {
486-
_tryAcceptEpochDuration();
487-
488-
if (epochDuration > epochDuration_) {
522+
if (nextEpochDurationInitInternal != 0 && nextEpochDurationInitInternal <= Time.timestamp()) {
523+
uint256 currentEpoch_ = currentEpoch();
524+
uint48 currentEpochStart_ = currentEpochStart();
525+
526+
prevEpochInitInternal = epochInitInternal;
527+
prevEpochDurationInternal = epochDurationInternal;
528+
prevEpochDurationInitInternal = epochDurationInitInternal;
529+
epochInitInternal = currentEpoch_;
530+
epochDurationInternal = nextEpochDurationInternal;
531+
epochDurationInitInternal = currentEpochStart_;
532+
nextEpochInitInternal = 0;
533+
nextEpochDurationInternal = 0;
534+
nextEpochDurationInitInternal = 0;
535+
}
536+
537+
if (epochDurationInternal > epochDuration_) {
489538
revert InvalidNewEpochDuration();
490539
}
491540

492-
if (nextEpochDurationInit != 0) {
493-
nextEpochDuration = 0;
494-
nextEpochDurationInit = 0;
495-
} else if (epochDuration == epochDuration_) {
541+
if (nextEpochDurationInitInternal != 0) {
542+
nextEpochInitInternal = 0;
543+
nextEpochDurationInternal = 0;
544+
nextEpochDurationInitInternal = 0;
545+
} else if (epochDurationInternal == epochDuration_) {
496546
revert AlreadySet();
497547
}
498548

499-
if (epochDuration != epochDuration_) {
500-
nextEpochDuration = epochDuration_;
501-
nextEpochDurationInit = (currentEpochStart() + epochDurationSetEpochsDelay * epochDuration).toUint48();
549+
if (epochDurationInternal != epochDuration_) {
550+
nextEpochInitInternal = currentEpoch() + epochDurationSetEpochsDelay;
551+
nextEpochDurationInternal = epochDuration_;
552+
nextEpochDurationInitInternal =
553+
(currentEpochStart() + epochDurationSetEpochsDelay * epochDurationInternal).toUint48();
502554
}
503555

504556
emit SetEpochDuration(epochDuration_);
505557
}
506558

507-
/**
508-
* @inheritdoc IVault
509-
*/
510-
function acceptEpochDuration() external nonReentrant {
511-
if (nextEpochDurationInit == 0 || nextEpochDurationInit > Time.timestamp()) {
512-
revert NewEpochDurationNotReady();
513-
}
514-
_acceptEpochDuration();
515-
}
516-
517559
/**
518560
* @inheritdoc IVault
519561
*/
@@ -599,8 +641,6 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
599641
uint256 withdrawnAssets,
600642
uint256 burnedShares
601643
) internal returns (uint256 mintedShares) {
602-
_tryAcceptEpochDuration();
603-
604644
_activeSharesOf[msg.sender].push(Time.timestamp(), activeSharesOf(msg.sender) - burnedShares);
605645
_activeShares.push(Time.timestamp(), activeShares() - burnedShares);
606646
_activeStake.push(Time.timestamp(), activeStake() - withdrawnAssets);
@@ -638,26 +678,5 @@ contract VaultImplementation is VaultStorage, AccessControlUpgradeable, Reentran
638678
isWithdrawalsClaimed[epoch][msg.sender] = true;
639679
}
640680

641-
function _tryAcceptEpochDuration() internal {
642-
if (nextEpochDurationInit != 0 && nextEpochDurationInit <= Time.timestamp()) {
643-
_acceptEpochDuration();
644-
}
645-
}
646-
647-
function _acceptEpochDuration() internal {
648-
uint256 currentEpoch_ = currentEpoch();
649-
uint48 currentEpochStart_ = currentEpochStart();
650-
651-
previousEpochDuration = epochDuration;
652-
previousEpochDurationInit = epochDurationInit;
653-
epochInit = currentEpoch_;
654-
epochDuration = nextEpochDuration;
655-
epochDurationInit = currentEpochStart_;
656-
nextEpochDuration = 0;
657-
nextEpochDurationInit = 0;
658-
659-
emit AcceptEpochDuration();
660-
}
661-
662681
function _Vault_init() external {}
663682
}

src/contracts/vault/v1.1/VaultStorage.sol

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ abstract contract VaultStorage is StaticDelegateCallable, IVaultStorage {
8686
/**
8787
* @inheritdoc IVaultStorage
8888
*/
89-
uint48 public epochDurationInit;
89+
uint48 public epochDurationInitInternal;
9090

9191
/**
9292
* @inheritdoc IVaultStorage
9393
*/
94-
uint48 public epochDuration;
94+
uint48 public epochDurationInternal;
9595

9696
/**
9797
* @inheritdoc IVaultStorage
@@ -157,27 +157,37 @@ abstract contract VaultStorage is StaticDelegateCallable, IVaultStorage {
157157
/**
158158
* @inheritdoc IVaultStorage
159159
*/
160-
uint256 public epochInit;
160+
uint256 public epochInitInternal;
161161

162162
/**
163163
* @inheritdoc IVaultStorage
164164
*/
165-
uint48 public previousEpochDurationInit;
165+
uint256 public prevEpochInitInternal;
166166

167167
/**
168168
* @inheritdoc IVaultStorage
169169
*/
170-
uint48 public previousEpochDuration;
170+
uint48 public prevEpochDurationInitInternal;
171171

172172
/**
173173
* @inheritdoc IVaultStorage
174174
*/
175-
uint48 public nextEpochDurationInit;
175+
uint48 public prevEpochDurationInternal;
176176

177177
/**
178178
* @inheritdoc IVaultStorage
179179
*/
180-
uint48 public nextEpochDuration;
180+
uint48 public nextEpochDurationInitInternal;
181+
182+
/**
183+
* @inheritdoc IVaultStorage
184+
*/
185+
uint48 public nextEpochDurationInternal;
186+
187+
/**
188+
* @inheritdoc IVaultStorage
189+
*/
190+
uint256 public nextEpochInitInternal;
181191

182192
/**
183193
* @inheritdoc IVaultStorage
@@ -194,5 +204,5 @@ abstract contract VaultStorage is StaticDelegateCallable, IVaultStorage {
194204
SLASHER_FACTORY = slasherFactory;
195205
}
196206

197-
uint256[45] private __gap;
207+
uint256[43] private __gap;
198208
}

src/interfaces/vault/v1.1/IVault.sol

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,18 @@ interface IVault is IVaultStorage, IAccessControl, IERC165, IERC3156FlashLender
228228
*/
229229
event SetSlasher(address indexed slasher);
230230

231+
/**
232+
* @notice Get a time point of the epoch duration set.
233+
* @return time point of the epoch duration set
234+
*/
235+
function epochDurationInit() external view returns (uint48);
236+
237+
/**
238+
* @notice Get a duration of the vault epoch.
239+
* @return duration of the epoch
240+
*/
241+
function epochDuration() external view returns (uint48);
242+
231243
/**
232244
* @notice Get an epoch at a given timestamp.
233245
* @param timestamp time point to get the epoch at
@@ -460,12 +472,6 @@ interface IVault is IVaultStorage, IAccessControl, IERC165, IERC3156FlashLender
460472
uint48 epochDuration_
461473
) external;
462474

463-
/**
464-
* @notice Accept an epoch duration.
465-
* @dev Only a EPOCH_DURATION_SET_ROLE holder can call this function.
466-
*/
467-
function acceptEpochDuration() external;
468-
469475
/**
470476
* @notice Set a flash fee rate (100% = 1_000_000_000; 0.03% = 300_000).
471477
* @param flashFeeRate_ flash fee rate

0 commit comments

Comments
 (0)