Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update interfaces #178

Open
wants to merge 6 commits into
base: develop-archive
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 1 addition & 25 deletions contracts/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ETHValue, ETHValues} from "./types/ETHValue.sol";
import {SharesValue, SharesValues} from "./types/SharesValue.sol";
import {PercentD16, PercentsD16} from "./types/PercentD16.sol";

import {IEscrow} from "./interfaces/IEscrow.sol";
import {IEscrow, LockedAssetsTotals, VetoerState} from "./interfaces/IEscrow.sol";
import {IStETH} from "./interfaces/IStETH.sol";
import {IWstETH} from "./interfaces/IWstETH.sol";
import {IWithdrawalQueue, WithdrawalRequestStatus} from "./interfaces/IWithdrawalQueue.sol";
Expand All @@ -19,30 +19,6 @@ import {EscrowState} from "./libraries/EscrowState.sol";
import {WithdrawalsBatchesQueue} from "./libraries/WithdrawalBatchesQueue.sol";
import {HolderAssets, StETHAccounting, UnstETHAccounting, AssetsAccounting} from "./libraries/AssetsAccounting.sol";

/// @notice Summary of the total locked assets in the Escrow.
/// @param stETHLockedShares The total number of stETH shares currently locked in the Escrow.
/// @param stETHClaimedETH The total amount of ETH claimed from the stETH shares locked in the Escrow.
/// @param unstETHUnfinalizedShares The total number of shares from unstETH NFTs that have not yet been marked as finalized.
/// @param unstETHFinalizedETH The total amount of ETH claimable from unstETH NFTs that have been marked as finalized.
struct LockedAssetsTotals {
uint256 stETHLockedShares;
uint256 stETHClaimedETH;
uint256 unstETHUnfinalizedShares;
uint256 unstETHFinalizedETH;
}

/// @notice Summary of the assets locked in the Escrow by a specific vetoer.
/// @param stETHLockedShares The total number of stETH shares currently locked in the Escrow by the vetoer.
/// @param unstETHLockedShares The total number of unstETH shares currently locked in the Escrow by the vetoer.
/// @param unstETHIdsCount The total number of unstETH NFTs locked in the Escrow by the vetoer.
/// @param lastAssetsLockTimestamp The timestamp of the last time the vetoer locked stETH, wstETH, or unstETH in the Escrow.
struct VetoerState {
uint256 stETHLockedShares;
uint256 unstETHLockedShares;
uint256 unstETHIdsCount;
uint256 lastAssetsLockTimestamp;
}

/// @notice This contract is used to accumulate stETH, wstETH, unstETH, and withdrawn ETH from vetoers during the
/// veto signalling and rage quit processes.
/// @dev This contract is intended to be used behind a minimal proxy deployed by the DualGovernance contract.
Expand Down
31 changes: 30 additions & 1 deletion contracts/interfaces/IDualGovernance.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import {IDualGovernanceConfigProvider} from "./IDualGovernanceConfigProvider.sol";
import {IGovernance} from "./IGovernance.sol";
import {IEscrow} from "./IEscrow.sol";
import {IResealManager} from "./IResealManager.sol";
import {ITiebreaker} from "./ITiebreaker.sol";
import {Timestamp} from "../types/Timestamp.sol";
import {Duration} from "../types/Duration.sol";
import {State} from "../libraries/DualGovernanceStateMachine.sol";
import {Proposers} from "../libraries/Proposers.sol";

interface IDualGovernance is IGovernance, ITiebreaker {
struct StateDetails {
Expand All @@ -19,7 +23,32 @@ interface IDualGovernance is IGovernance, ITiebreaker {
Duration vetoSignallingDuration;
}

function MIN_TIEBREAKER_ACTIVATION_TIMEOUT() external view returns (Duration);
function MAX_TIEBREAKER_ACTIVATION_TIMEOUT() external view returns (Duration);
function MAX_SEALABLE_WITHDRAWAL_BLOCKERS_COUNT() external view returns (uint256);
function ESCROW_MASTER_COPY() external view returns (IEscrow);

function canSubmitProposal() external view returns (bool);
function canCancelAllPendingProposals() external view returns (bool);
function activateNextState() external;
function setConfigProvider(IDualGovernanceConfigProvider newConfigProvider) external;
function getConfigProvider() external view returns (IDualGovernanceConfigProvider);
function getVetoSignallingEscrow() external view returns (address);
function getRageQuitEscrow() external view returns (address);
function getPersistedState() external view returns (State persistedState);
function getEffectiveState() external view returns (State effectiveState);
function getStateDetails() external view returns (StateDetails memory stateDetails);

function registerProposer(address proposer, address executor) external;
function unregisterProposer(address proposer) external;
function isProposer(address account) external view returns (bool);
function getProposer(address account) external view returns (Proposers.Proposer memory proposer);
function getProposers() external view returns (Proposers.Proposer[] memory proposers);
function isExecutor(address account) external view returns (bool);

function resealSealable(address sealables) external;
function resealSealable(address sealable) external;
function setResealCommittee(address resealCommittee) external;
function setResealManager(address resealManager) external;
function getResealManager() external view returns (IResealManager);
function getResealCommittee() external view returns (address);
}
22 changes: 21 additions & 1 deletion contracts/interfaces/IEmergencyProtectedTimelock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,31 @@ interface IEmergencyProtectedTimelock is ITimelock {
Timestamp emergencyProtectionEndsAfter;
}

function MAX_AFTER_SUBMIT_DELAY() external view returns (Duration);
function MAX_AFTER_SCHEDULE_DELAY() external view returns (Duration);
function MAX_EMERGENCY_MODE_DURATION() external view returns (Duration);
function MAX_EMERGENCY_PROTECTION_DURATION() external view returns (Duration);

function setupDelays(Duration afterSubmitDelay, Duration afterScheduleDelay) external;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move methods setupDelays(), transferExecutorOwnership(), getAfterSubmitDelay(), getAfterScheduleDelay() and setAdminExecutor() into the ITimelock.sol interface

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

function transferExecutorOwnership(address executor, address owner) external;
function setEmergencyProtectionActivationCommittee(address emergencyActivationCommittee) external;
function setEmergencyProtectionExecutionCommittee(address emergencyExecutionCommittee) external;
function setEmergencyProtectionEndDate(Timestamp emergencyProtectionEndDate) external;
function setEmergencyModeDuration(Duration emergencyModeDuration) external;
function setEmergencyGovernance(address emergencyGovernance) external;

function activateEmergencyMode() external;
function emergencyExecute(uint256 proposalId) external;
function deactivateEmergencyMode() external;
function emergencyReset() external;
function isEmergencyProtectionEnabled() external view returns (bool);
function isEmergencyModeActive() external view returns (bool);
function getEmergencyProtectionDetails() external view returns (EmergencyProtectionDetails memory details);
function getEmergencyGovernance() external view returns (address emergencyGovernance);
function getEmergencyActivationCommittee() external view returns (address committee);
function getEmergencyExecutionCommittee() external view returns (address committee);
function getEmergencyProtectionDetails() external view returns (EmergencyProtectionDetails memory details);
function getAfterSubmitDelay() external view returns (Duration);
function getAfterScheduleDelay() external view returns (Duration);

function setAdminExecutor(address newAdminExecutor) external;
}
54 changes: 53 additions & 1 deletion contracts/interfaces/IEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,63 @@ pragma solidity 0.8.26;

import {Duration} from "../types/Duration.sol";
import {PercentD16} from "../types/PercentD16.sol";
import {Timestamp} from "../types/Timestamp.sol";

/// @notice Summary of the total locked assets in the Escrow.
/// @param stETHLockedShares The total number of stETH shares currently locked in the Escrow.
/// @param stETHClaimedETH The total amount of ETH claimed from the stETH shares locked in the Escrow.
/// @param unstETHUnfinalizedShares The total number of shares from unstETH NFTs that have not yet been marked as finalized.
/// @param unstETHFinalizedETH The total amount of ETH claimable from unstETH NFTs that have been marked as finalized.
struct LockedAssetsTotals {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose putting these structures inside the IEscrow interface. Then, they may be used inside the Escrow contract without additional imports.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

uint256 stETHLockedShares;
uint256 stETHClaimedETH;
uint256 unstETHUnfinalizedShares;
uint256 unstETHFinalizedETH;
}

/// @notice Summary of the assets locked in the Escrow by a specific vetoer.
/// @param stETHLockedShares The total number of stETH shares currently locked in the Escrow by the vetoer.
/// @param unstETHLockedShares The total number of unstETH shares currently locked in the Escrow by the vetoer.
/// @param unstETHIdsCount The total number of unstETH NFTs locked in the Escrow by the vetoer.
/// @param lastAssetsLockTimestamp The timestamp of the last time the vetoer locked stETH, wstETH, or unstETH in the Escrow.
struct VetoerState {
uint256 stETHLockedShares;
uint256 unstETHLockedShares;
uint256 unstETHIdsCount;
uint256 lastAssetsLockTimestamp;
}

interface IEscrow {
function initialize(Duration minAssetsLockDuration) external;

function startRageQuit(Duration rageQuitExtraTimelock, Duration rageQuitWithdrawalsTimelock) external;
function lockStETH(uint256 amount) external returns (uint256 lockedStETHShares);
function unlockStETH() external returns (uint256 unlockedStETHShares);
function lockWstETH(uint256 amount) external returns (uint256 lockedStETHShares);
function unlockWstETH() external returns (uint256 unlockedStETHShares);
function lockUnstETH(uint256[] memory unstETHIds) external;
function unlockUnstETH(uint256[] memory unstETHIds) external;
function markUnstETHFinalized(uint256[] memory unstETHIds, uint256[] calldata hints) external;

function startRageQuit(Duration rageQuitExtensionPeriodDuration, Duration rageQuitEthWithdrawalsDelay) external;

function requestNextWithdrawalsBatch(uint256 batchSize) external;

function claimNextWithdrawalsBatch(uint256 fromUnstETHId, uint256[] calldata hints) external;
function claimNextWithdrawalsBatch(uint256 maxUnstETHIdsCount) external;

function startRageQuitExtensionPeriod() external;
function claimUnstETH(uint256[] calldata unstETHIds, uint256[] calldata hints) external;

function withdrawETH() external;
function withdrawETH(uint256[] calldata unstETHIds) external;

function getLockedAssetsTotals() external view returns (LockedAssetsTotals memory totals);
function getVetoerState(address vetoer) external view returns (VetoerState memory state);
function getUnclaimedUnstETHIdsCount() external view returns (uint256);
function getNextWithdrawalBatch(uint256 limit) external view returns (uint256[] memory unstETHIds);
function isWithdrawalsBatchesFinalized() external view returns (bool);
function isRageQuitExtensionPeriodStarted() external view returns (bool);
function getRageQuitExtensionPeriodStartedAt() external view returns (Timestamp);

function isRageQuitFinalized() external view returns (bool);
function getRageQuitSupport() external view returns (PercentD16 rageQuitSupport);
Expand Down
6 changes: 0 additions & 6 deletions contracts/interfaces/IGateSeal.sol

This file was deleted.

1 change: 1 addition & 0 deletions contracts/interfaces/ITiebreaker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ interface ITiebreaker {
function setTiebreakerCommittee(address tiebreakerCommittee) external;
function setTiebreakerActivationTimeout(Duration tiebreakerActivationTimeout) external;
function tiebreakerScheduleProposal(uint256 proposalId) external;
function getTiebreakerDetails() external view returns (TiebreakerDetails memory tiebreakerState);
function tiebreakerResumeSealable(address sealable) external;
}
1 change: 1 addition & 0 deletions contracts/interfaces/ITimelock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ interface ITimelock {
view
returns (ProposalDetails memory proposal, ExternalCall[] memory calls);
function getProposalDetails(uint256 proposalId) external view returns (ProposalDetails memory proposalDetails);
function getProposalCalls(uint256 proposalId) external view returns (ExternalCall[] memory calls);
function getProposalsCount() external view returns (uint256 count);
}
3 changes: 1 addition & 2 deletions scripts/deploy/DeployVerification.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {Timestamps} from "contracts/types/Timestamp.sol";
import {Durations} from "contracts/types/Duration.sol";
import {Executor} from "contracts/Executor.sol";
import {IEmergencyProtectedTimelock} from "contracts/interfaces/IEmergencyProtectedTimelock.sol";
import {EmergencyProtectedTimelock} from "contracts/EmergencyProtectedTimelock.sol";
import {ITiebreaker} from "contracts/interfaces/ITiebreaker.sol";
import {TiebreakerCoreCommittee} from "contracts/committees/TiebreakerCoreCommittee.sol";
import {TiebreakerSubCommittee} from "contracts/committees/TiebreakerSubCommittee.sol";
Expand Down Expand Up @@ -55,7 +54,7 @@ library DeployVerification {
}

function checkTimelock(DeployedAddresses memory res, DeployConfig memory dgDeployConfig) internal view {
EmergencyProtectedTimelock timelockInstance = EmergencyProtectedTimelock(res.timelock);
IEmergencyProtectedTimelock timelockInstance = IEmergencyProtectedTimelock(res.timelock);
require(
timelockInstance.getAdminExecutor() == res.adminExecutor,
"Incorrect adminExecutor address in EmergencyProtectedTimelock"
Expand Down
92 changes: 89 additions & 3 deletions test/mocks/EscrowMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ pragma solidity 0.8.26;

import {Duration} from "contracts/types/Duration.sol";
import {PercentD16} from "contracts/types/PercentD16.sol";
import {Timestamp} from "contracts/types/Timestamp.sol";

import {IEscrow} from "contracts/interfaces/IEscrow.sol";
import {IEscrow, LockedAssetsTotals, VetoerState} from "contracts/interfaces/IEscrow.sol";

/* solhint-disable custom-errors */
contract EscrowMock is IEscrow {
event __RageQuitStarted(Duration rageQuitExtraTimelock, Duration rageQuitWithdrawalsTimelock);

Expand All @@ -25,8 +27,92 @@ contract EscrowMock is IEscrow {
__minAssetsLockDuration = minAssetsLockDuration;
}

function startRageQuit(Duration rageQuitExtraTimelock, Duration rageQuitWithdrawalsTimelock) external {
emit __RageQuitStarted(rageQuitExtraTimelock, rageQuitWithdrawalsTimelock);
function lockStETH(uint256 /* amount */ ) external returns (uint256 /* lockedStETHShares */ ) {
revert("Not implemented");
}

function unlockStETH() external returns (uint256 /* unlockedStETHShares */ ) {
revert("Not implemented");
}

function lockWstETH(uint256 /* amount */ ) external returns (uint256 /* lockedStETHShares */ ) {
revert("Not implemented");
}

function unlockWstETH() external returns (uint256 /* unlockedStETHShares */ ) {
revert("Not implemented");
}

function lockUnstETH(uint256[] memory /* unstETHIds */ ) external {
revert("Not implemented");
}

function unlockUnstETH(uint256[] memory /* unstETHIds */ ) external {
revert("Not implemented");
}

function markUnstETHFinalized(uint256[] memory, /* unstETHIds */ uint256[] calldata /* hints */ ) external {
revert("Not implemented");
}

function startRageQuit(Duration rageQuitExtensionPeriodDuration, Duration rageQuitEthWithdrawalsDelay) external {
emit __RageQuitStarted(rageQuitExtensionPeriodDuration, rageQuitEthWithdrawalsDelay);
}

function requestNextWithdrawalsBatch(uint256 /* batchSize */ ) external {
revert("Not implemented");
}

function claimNextWithdrawalsBatch(uint256, /* fromUnstETHId */ uint256[] calldata /* hints */ ) external {
revert("Not implemented");
}

function claimNextWithdrawalsBatch(uint256 /* maxUnstETHIdsCount */ ) external {
revert("Not implemented");
}

function startRageQuitExtensionPeriod() external {
revert("Not implemented");
}

function claimUnstETH(uint256[] calldata, /* unstETHIds */ uint256[] calldata /* hints */ ) external {
revert("Not implemented");
}

function withdrawETH() external {
revert("Not implemented");
}

function withdrawETH(uint256[] calldata /* unstETHIds */ ) external {
revert("Not implemented");
}

function getLockedAssetsTotals() external view returns (LockedAssetsTotals memory /* totals */ ) {
revert("Not implemented");
}

function getVetoerState(address /* vetoer */ ) external view returns (VetoerState memory /* state */ ) {
revert("Not implemented");
}

function getUnclaimedUnstETHIdsCount() external view returns (uint256) {
revert("Not implemented");
}

function getNextWithdrawalBatch(uint256 /* limit */ ) external view returns (uint256[] memory /* unstETHIds */ ) {
revert("Not implemented");
}

function isWithdrawalsBatchesFinalized() external view returns (bool) {
revert("Not implemented");
}

function isRageQuitExtensionPeriodStarted() external view returns (bool) {
revert("Not implemented");
}

function getRageQuitExtensionPeriodStartedAt() external view returns (Timestamp) {
revert("Not implemented");
}

function isRageQuitFinalized() external view returns (bool) {
Expand Down
37 changes: 0 additions & 37 deletions test/mocks/GateSealMock.sol

This file was deleted.

4 changes: 4 additions & 0 deletions test/mocks/TimelockMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ contract TimelockMock is ITimelock {
revert("Not Implemented");
}

function getProposalCalls(uint256 proposalId) external view returns (ExternalCall[] memory calls) {
revert("Not Implemented");
}

function getProposalsCount() external view returns (uint256 count) {
return submittedProposals.length;
}
Expand Down
3 changes: 2 additions & 1 deletion test/scenario/escrow.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {WithdrawalRequestStatus} from "contracts/interfaces/IWithdrawalQueue.sol

import {EscrowState, State} from "contracts/libraries/EscrowState.sol";

import {Escrow, VetoerState, LockedAssetsTotals, WithdrawalsBatchesQueue} from "contracts/Escrow.sol";
import {IEscrow, LockedAssetsTotals, VetoerState} from "contracts/interfaces/IEscrow.sol";
import {Escrow, WithdrawalsBatchesQueue} from "contracts/Escrow.sol";
import {AssetsAccounting, UnstETHRecordStatus} from "contracts/libraries/AssetsAccounting.sol";

import {ScenarioTestBlueprint, LidoUtils, console} from "../utils/scenario-test-blueprint.sol";
Expand Down
Loading