@@ -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}
0 commit comments