From 20baa96bdf743344b0ab29f8dc62dd034b94b597 Mon Sep 17 00:00:00 2001 From: Bogdan Kovtun Date: Mon, 9 Dec 2024 12:30:50 +0400 Subject: [PATCH] Update spec with the code changes. Add scheduleProposal method --- docs/specification.md | 140 ++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 60 deletions(-) diff --git a/docs/specification.md b/docs/specification.md index 9d6ecb76..cac5f864 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -266,56 +266,85 @@ The id of the successfully registered proposal. Triggers a transition of the current governance state (if one is possible) before checking the preconditions. -### Function: DualGovernance.tiebreakerScheduleProposal +### Function: DualGovernance.scheduleProposal -[`DualGovernance.tiebreakerScheduleProposal`]: #Function-DualGovernancetiebreakerScheduleProposal +[`DualGovernance.scheduleProposal`]: #Function-DualGovernancescheduleProposal ```solidity -function tiebreakerScheduleProposal(uint256 proposalId) +function scheduleProposal(uint256 proposalId) external ``` -Instructs the [`EmergencyProtectedTimelock`](#Contract-EmergencyProtectedTimelocksol) singleton instance to schedule the proposal with the id `proposalId` for execution, bypassing the proposal dynamic timelock and given that the proposal was previously approved by the [Tiebreaker committee](#Tiebreaker-committee). +Schedules a previously submitted proposal for execution in the Dual Governance system. The function ensures that the proposal meets specific conditions before it can be scheduled. If the conditions are met, the proposal is registered for execution in the `EmergencyProtectedTimelock` singleton instance. -#### Preconditions +Preconditions -* MUST be called by the [Tiebreaker committee](#Tiebreaker-committee) address -* Either the Tiebreaker Condition A or the Tiebreaker Condition B MUST be met (see the [mechanism design document][mech design - tiebreaker]). -* The proposal with the given id MUST be already submitted using the `DualGovernance.submitProposal` call. -* The proposal MUST NOT be cancelled. +- The proposal with the specified proposalId MUST exist in the system. +- The required delay since submission (`EmergencyProtectedTimelock.getAfterSubmitDelay()`) MUST have elapsed. +- The Dual Governance system MUST BE in the `Normal` or `VetoCooldown` state +- If the system is in the `VetoCooldown` state, the proposal MUST have been submitted not later than the `VetoSignalling` state was entered. +- The proposal MUST NOT have been cancelled. +- The proposal MUST NOT already be scheduled. Triggers a transition of the current governance state (if one is possible) before checking the preconditions. -### Function: DualGovernance.tiebreakerResumeSealable - -[`DualGovernance.tiebreakerResumeSealable`]: #Function-DualGovernancetiebreakerResumeSealable +### Function: DualGovernance.cancelAllPendingProposals ```solidity -function tiebreakerResumeSealable(address sealable) +function cancelAllPendingProposals() returns (bool) ``` -Calls the `ResealManager.resumeSealable(address sealable)` if all preconditions met. +Cancels all currently submitted and non-executed proposals. If a proposal was submitted but not scheduled, it becomes unschedulable. If a proposal was scheduled, it becomes unexecutable. + +If the current governance state is neither `VetoSignalling` nor `VetoSignallingDeactivation`, the function will exit early without canceling any proposals, emitting the `CancelAllPendingProposalsSkipped` event and returning `false`. If proposals are successfully canceled, the `CancelAllPendingProposalsExecuted` event will be emitted, and the function will return `true`. #### Preconditions -* MUST be called by the [Tiebreaker committee](#Tiebreaker-committee) address -* Either the Tiebreaker Condition A or the Tiebreaker Condition B MUST be met (see the [mechanism design document][mech design - tiebreaker]). +- MUST be called by an authorized `proposalsCanceller` +Triggers a transition of the current governance state, if one is possible. -### Function: DualGovernance.cancelAllPendingProposals +### Function: DualGovernance.activateNextState ```solidity -function cancelAllPendingProposals() returns (bool) +function activateNextState() ``` -Cancels all currently submitted and non-executed proposals. If a proposal was submitted but not scheduled, it becomes unschedulable. If a proposal was scheduled, it becomes unexecutable. +Triggers a transition of the [global governance state](#Governance-state), if one is possible; does nothing otherwise. -If the current governance state is neither `VetoSignalling` nor `VetoSignallingDeactivation`, the function will exit early without canceling any proposals, emitting the `CancelAllPendingProposalsSkipped` event and returning `false`. If proposals are successfully canceled, the `CancelAllPendingProposalsExecuted` event will be emitted, and the function will return `true`. -Triggers a transition of the current governance state, if one is possible. +### Function: DualGovernance.getPersistedState -#### Preconditions +```solidity +function getPersistedState() view returns (State persistedState) +``` + +Returns the most recently persisted state of the DualGovernance. + +### Function: DualGovernance.getEffectiveState + +```solidity +function getEffectiveState() view returns (State persistedState) +``` + +Returns the effective state of the DualGovernance. The effective state refers to the state the DualGovernance would transition to upon calling `DualGovernance.activateNextState()`. + +### Function DualGovernance.getStateDetails + +```solidity +function getStateDetails() view returns (StateDetails) +``` + +This function returns detailed information about the current state of the `DualGovernance`, comprising the following data: + +- **`State effectiveState`**: The state that the `DualGovernance` would transition to upon calling `DualGovernance.activateNextState()`. +- **`State persistedState`**: The current stored state of the `DualGovernance`. +- **`Timestamp persistedStateEnteredAt`**: The timestamp when the `persistedState` was entered. +- **`Timestamp vetoSignallingActivatedAt`**: The timestamp when the `VetoSignalling` state was last activated. +- **`Timestamp vetoSignallingReactivationTime`**: The timestamp when the `VetoSignalling` state was last re-activated. +- **`Timestamp normalOrVetoCooldownExitedAt`**: The timestamp when the `Normal` or `VetoCooldown` state was last exited. +- **`uint256 rageQuitRound`**: The number of continuous RageQuit rounds. +- **`Duration vetoSignallingDuration`**: The duration of the `VetoSignalling` state, calculated based on the RageQuit support in the Veto Signalling `Escrow`. -- MUST be called by an [admin proposer](#Administrative-actions). ### Function: DualGovernance.registerProposer @@ -347,61 +376,55 @@ Removes the registered `proposer` address from the list of valid proposers and d * The `proposer` address MUST NOT be the only one assigned to the admin executor. -### Function: DualGovernance.setTiebreakerCommittee +### Function: DualGovernance.tiebreakerScheduleProposal + +[`DualGovernance.tiebreakerScheduleProposal`]: #Function-DualGovernancetiebreakerScheduleProposal ```solidity -function setTiebreakerCommittee(address newTiebreaker) +function tiebreakerScheduleProposal(uint256 proposalId) ``` -Updates the address of the [Tiebreaker committee](#Tiebreaker-committee). +Instructs the [`EmergencyProtectedTimelock`](#Contract-EmergencyProtectedTimelocksol) singleton instance to schedule the proposal with the id `proposalId` for execution, bypassing the proposal dynamic timelock and given that the proposal was previously approved by the [Tiebreaker committee](#Tiebreaker-committee). #### Preconditions -* MUST be called by the admin executor contract. -* The `newTiebreaker` address MUST NOT be the zero address. -* The `newTiebreaker` address MUST be different from the current tiebreaker address. +* MUST be called by the [Tiebreaker committee](#Tiebreaker-committee) address +* Either the Tiebreaker Condition A or the Tiebreaker Condition B MUST be met (see the [mechanism design document][mech design - tiebreaker]). +* The proposal with the given id MUST be already submitted using the `DualGovernance.submitProposal` call. +* The proposal MUST NOT be cancelled. +Triggers a transition of the current governance state (if one is possible) before checking the preconditions. -### Function: DualGovernance.activateNextState +### Function: DualGovernance.tiebreakerResumeSealable + +[`DualGovernance.tiebreakerResumeSealable`]: #Function-DualGovernancetiebreakerResumeSealable ```solidity -function activateNextState() +function tiebreakerResumeSealable(address sealable) ``` -Triggers a transition of the [global governance state](#Governance-state), if one is possible; does nothing otherwise. +Calls the `ResealManager.resumeSealable(address sealable)` if all preconditions met. -### Function: DualGovernance.getPersistedState +#### Preconditions -```solidity -function getPersistedState() view returns (State persistedState) -``` +* MUST be called by the [Tiebreaker committee](#Tiebreaker-committee) address +* Either the Tiebreaker Condition A or the Tiebreaker Condition B MUST be met (see the [mechanism design document][mech design - tiebreaker]). -Returns the most recently persisted state of the DualGovernance. -### Function: DualGovernance.getEffectiveState +### Function: DualGovernance.setTiebreakerCommittee ```solidity -function getEffectiveState() view returns (State persistedState) +function setTiebreakerCommittee(address newTiebreaker) ``` -Returns the effective state of the DualGovernance. The effective state refers to the state the DualGovernance would transition to upon calling `DualGovernance.activateNextState()`. - -### Function DualGovernance.getStateDetails +Updates the address of the [Tiebreaker committee](#Tiebreaker-committee). -```solidity -function getStateDetails() view returns (StateDetails) -``` +#### Preconditions -This function returns detailed information about the current state of the `DualGovernance`, comprising the following data: +* MUST be called by the admin executor contract. +* The `newTiebreaker` address MUST NOT be the zero address. +* The `newTiebreaker` address MUST be different from the current tiebreaker address. -- **`State effectiveState`**: The state that the `DualGovernance` would transition to upon calling `DualGovernance.activateNextState()`. -- **`State persistedState`**: The current stored state of the `DualGovernance`. -- **`Timestamp persistedStateEnteredAt`**: The timestamp when the `persistedState` was entered. -- **`Timestamp vetoSignallingActivatedAt`**: The timestamp when the `VetoSignalling` state was last activated. -- **`Timestamp vetoSignallingReactivationTime`**: The timestamp when the `VetoSignalling` state was last re-activated. -- **`Timestamp normalOrVetoCooldownExitedAt`**: The timestamp when the `Normal` or `VetoCooldown` state was last exited. -- **`uint256 rageQuitRound`**: The number of continuous RageQuit rounds. -- **`Duration vetoSignallingDuration`**: The duration of the `VetoSignalling` state, calculated based on the RageQuit support in the Veto Signalling `Escrow`. ## Contract: Executor.sol @@ -409,20 +432,17 @@ Issues calls resulting from governance proposals' execution. Every protocol perm The system supports multiple instances of this contract, but all instances SHOULD be owned by the [`EmergencyProtectedTimelock`](#Contract-EmergencyProtectedTimelocksol) singleton instance. + ### Function: execute ```solidity -function execute(address target, uint256 value, bytes payload) - payable returns (bytes result) +function execute(address target, uint256 value, bytes payload) payable ``` Issues a EVM call to the `target` address with the `payload` calldata, optionally sending `value` wei ETH. Reverts if the call was unsuccessful. -#### Returns - -The result of the call. #### Preconditions @@ -921,7 +941,7 @@ The governance reset entails the following steps: ### Function: EmergencyProtectedTimelock.submit ```solidity -function submit(address proposer, address executor, ExecutorCall[] calls, string calldata metadata) +function submit(address executor, ExecutorCall[] calls) returns (uint256 proposalId) ```