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

Naming consistency for contracts and files #129

Merged
merged 4 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion contracts/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ contract Escrow is IEscrow {
WITHDRAWAL_QUEUE.claimWithdrawals(unstETHIds, hints);
ETHValue ethBalanceAfter = ETHValues.fromAddressBalance(address(this));

_accounting.accountClaimedStETH(ethBalanceAfter - ethBalanceBefore);
_accounting.accountClaimedETH(ethBalanceAfter - ethBalanceBefore);
}

function _checkCallerIsDualGovernance() internal view {
Expand Down
2 changes: 1 addition & 1 deletion contracts/committees/EmergencyActivationCommittee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ contract EmergencyActivationCommittee is HashConsensus {
address[] memory committeeMembers,
uint256 executionQuorum,
address emergencyProtectedTimelock
) HashConsensus(owner, Durations.from(0)) {
) HashConsensus(owner, Durations.ZERO) {
EMERGENCY_PROTECTED_TIMELOCK = emergencyProtectedTimelock;

_addMembers(committeeMembers, executionQuorum);
Expand Down
2 changes: 1 addition & 1 deletion contracts/committees/EmergencyExecutionCommittee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract EmergencyExecutionCommittee is HashConsensus, ProposalsList {
address[] memory committeeMembers,
uint256 executionQuorum,
address emergencyProtectedTimelock
) HashConsensus(owner, Durations.from(0)) {
) HashConsensus(owner, Durations.ZERO) {
EMERGENCY_PROTECTED_TIMELOCK = emergencyProtectedTimelock;

_addMembers(committeeMembers, executionQuorum);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {Timestamp} from "../types/Timestamp.sol";

import {ITimelock} from "../interfaces/ITimelock.sol";
import {ITiebreaker} from "../interfaces/ITiebreaker.sol";
import {ITiebreakerCore} from "../interfaces/ITiebreakerCore.sol";
import {IDualGovernance} from "../interfaces/IDualGovernance.sol";
import {ITiebreakerCoreCommittee} from "../interfaces/ITiebreakerCoreCommittee.sol";

import {HashConsensus} from "./HashConsensus.sol";
import {ProposalsList} from "./ProposalsList.sol";
Expand All @@ -19,10 +19,10 @@ enum ProposalType {
ResumeSealable
}

/// @title Tiebreaker Core Contract
/// @title Tiebreaker Core Committee Contract
/// @notice This contract allows a committee to vote on and execute proposals for scheduling and resuming sealable addresses
/// @dev Inherits from HashConsensus for voting mechanisms and ProposalsList for proposal management
contract TiebreakerCore is ITiebreakerCore, HashConsensus, ProposalsList {
contract TiebreakerCoreCommittee is ITiebreakerCoreCommittee, HashConsensus, ProposalsList {
error ResumeSealableNonceMismatch();
error ProposalDoesNotExist(uint256 proposalId);

Expand Down
20 changes: 11 additions & 9 deletions contracts/committees/TiebreakerSubCommittee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {Durations} from "../types/Duration.sol";
import {Timestamp} from "../types/Timestamp.sol";

import {ITiebreakerCore} from "../interfaces/ITiebreakerCore.sol";
import {ITiebreakerCoreCommittee} from "../interfaces/ITiebreakerCoreCommittee.sol";

import {HashConsensus} from "./HashConsensus.sol";
import {ProposalsList} from "./ProposalsList.sol";
Expand All @@ -20,15 +20,15 @@ enum ProposalType {
/// @notice This contract allows a subcommittee to vote on and execute proposals for scheduling and resuming sealable addresses
/// @dev Inherits from HashConsensus for voting mechanisms and ProposalsList for proposal management
contract TiebreakerSubCommittee is HashConsensus, ProposalsList {
address immutable TIEBREAKER_CORE;
address public immutable TIEBREAKER_CORE_COMMITTEE;

constructor(
address owner,
address[] memory committeeMembers,
uint256 executionQuorum,
address tiebreakerCore
) HashConsensus(owner, Durations.from(0)) {
TIEBREAKER_CORE = tiebreakerCore;
address tiebreakerCoreCommittee
) HashConsensus(owner, Durations.ZERO) {
TIEBREAKER_CORE_COMMITTEE = tiebreakerCoreCommittee;

_addMembers(committeeMembers, executionQuorum);
}
Expand All @@ -42,7 +42,7 @@ contract TiebreakerSubCommittee is HashConsensus, ProposalsList {
/// @param proposalId The ID of the proposal to schedule
function scheduleProposal(uint256 proposalId) public {
_checkCallerIsMember();
ITiebreakerCore(TIEBREAKER_CORE).checkProposalExists(proposalId);
ITiebreakerCoreCommittee(TIEBREAKER_CORE_COMMITTEE).checkProposalExists(proposalId);
(bytes memory proposalData, bytes32 key) = _encodeApproveProposal(proposalId);
_vote(key, true);
_pushProposal(key, uint256(ProposalType.ScheduleProposal), proposalData);
Expand Down Expand Up @@ -71,7 +71,8 @@ contract TiebreakerSubCommittee is HashConsensus, ProposalsList {
(, bytes32 key) = _encodeApproveProposal(proposalId);
_markUsed(key);
Address.functionCall(
TIEBREAKER_CORE, abi.encodeWithSelector(ITiebreakerCore.scheduleProposal.selector, proposalId)
TIEBREAKER_CORE_COMMITTEE,
abi.encodeWithSelector(ITiebreakerCoreCommittee.scheduleProposal.selector, proposalId)
);
}

Expand Down Expand Up @@ -122,7 +123,8 @@ contract TiebreakerSubCommittee is HashConsensus, ProposalsList {
(, bytes32 key, uint256 nonce) = _encodeSealableResume(sealable);
_markUsed(key);
Address.functionCall(
TIEBREAKER_CORE, abi.encodeWithSelector(ITiebreakerCore.sealableResume.selector, sealable, nonce)
TIEBREAKER_CORE_COMMITTEE,
abi.encodeWithSelector(ITiebreakerCoreCommittee.sealableResume.selector, sealable, nonce)
);
}

Expand All @@ -137,7 +139,7 @@ contract TiebreakerSubCommittee is HashConsensus, ProposalsList {
view
returns (bytes memory data, bytes32 key, uint256 nonce)
{
nonce = ITiebreakerCore(TIEBREAKER_CORE).getSealableResumeNonce(sealable);
nonce = ITiebreakerCoreCommittee(TIEBREAKER_CORE_COMMITTEE).getSealableResumeNonce(sealable);
data = abi.encode(sealable, nonce);
key = keccak256(data);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

interface ITiebreakerCore {
interface ITiebreakerCoreCommittee {
function getSealableResumeNonce(address sealable) external view returns (uint256 nonce);
function scheduleProposal(uint256 _proposalId) external;
function sealableResume(address sealable, uint256 nonce) external;
Expand Down
2 changes: 1 addition & 1 deletion contracts/libraries/AssetsAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ library AssetsAccounting {
emit ETHWithdrawn(holder, stETHSharesToWithdraw, ethWithdrawn);
}

function accountClaimedStETH(Context storage self, ETHValue amount) internal {
function accountClaimedETH(Context storage self, ETHValue amount) internal {
self.stETHTotals.claimedETH = self.stETHTotals.claimedETH + amount;
emit ETHClaimed(amount);
}
Expand Down
36 changes: 18 additions & 18 deletions docs/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This document provides the system description on the code architecture level. A
* [Contract: ProposalsList.sol](#contract-proposalslistsol)
* [Contract: HashConsensus.sol](#contract-hashconsensussol)
* [Contract: ResealCommittee.sol](#contract-resealcommitteesol)
* [Contract: TiebreakerCore.sol](#contract-tiebreakercoresol)
* [Contract: TiebreakerCoreCommittee.sol](#contract-tiebreakercorecommitteesol)
* [Contract: TiebreakerSubCommittee.sol](#contract-tiebreakersubcommitteesol)
* [Contract: EmergencyActivationCommittee.sol](#contract-emergencyactivationcommitteesol)
* [Contract: EmergencyExecutionCommittee.sol](#contract-emergencyexecutioncommitteesol)
Expand All @@ -56,12 +56,12 @@ The system is composed of the following main contracts:
* [`ImmutableDualGovernanceConfigProvider.sol`](#contract-immutabledualgovernanceconfigprovidersol) is a singleton contract that stores the configurable parameters of the DualGovernance system in an immutable manner.
* [`ResealManager.sol`](#contract-resealmanagersol) is a singleton contract responsible for extending or resuming sealable contracts paused by the [GateSeal emergency protection mechanism](https://github.com/lidofinance/gate-seals). This contract is essential due to the dynamic timelock of Dual Governance, which may prevent the DAO from extending the pause in time. It holds the authority to manage the pausing and resuming of specific protocol components protected by GateSeal.

Additionally, the system uses several committee contracts that allow members to execute, acquiring quorum, a narrow set of actions while protecting management of the committees by the Dual Governance mechanism:
Additionally, the system uses several committee contracts that allow members to execute, acquiring quorum, a narrow set of actions while protecting management of the committees by the Dual Governance mechanism:

* [`ResealCommittee.sol`](#contract-resealcommitteesol) is a committee contract that allows members to obtain a quorum and reseal contracts temporarily paused by the [GateSeal emergency protection mechanism](https://github.com/lidofinance/gate-seals).
* [`TiebreakerCore.sol`](#contract-tiebreakercoresol) is a committee contract designed to approve proposals for execution in extreme situations where the Dual Governance system is deadlocked. This includes scenarios such as the inability to finalize user withdrawal requests during ongoing `RageQuit` or when the system is held in a locked state for an extended period. The `TiebreakerCore` consists of multiple `TiebreakerSubCommittee` contracts appointed by the DAO.
* [`TiebreakerSubCommittee.sol`](#contract-tiebreakersubcommitteesol) is a committee contracts that provides ability to participate in `TiebreakerCore` for external actors.
* [`EmergencyActivationCommittee`](#contract-emergencyactivationcommitteesol) is a committee contract responsible for activating Emergency Mode by acquiring quorum. Only the EmergencyExecutionCommittee can execute proposals. This committee is expected to be active for a limited period following the initial deployment or update of the DualGovernance system.
* [`TiebreakerCoreCommittee.sol`](#contract-tiebreakercorecommitteesol) is a committee contract designed to approve proposals for execution in extreme situations where the Dual Governance system is deadlocked. This includes scenarios such as the inability to finalize user withdrawal requests during ongoing `RageQuit` or when the system is held in a locked state for an extended period. The `TiebreakerCoreCommittee` consists of multiple `TiebreakerSubCommittee` contracts appointed by the DAO.
* [`TiebreakerSubCommittee.sol`](#contract-tiebreakersubcommitteesol) is a committee contracts that provides ability to participate in `TiebreakerCoreCommittee` for external actors.
* [`EmergencyActivationCommittee`](#contract-emergencyactivationcommitteesol) is a committee contract responsible for activating Emergency Mode by acquiring quorum. Only the EmergencyExecutionCommittee can execute proposals. This committee is expected to be active for a limited period following the initial deployment or update of the DualGovernance system.
* [`EmergencyExecutionCommittee`](#contract-emergencyexecutioncommitteesol) is a committee contract that enables quorum-based execution of proposals during Emergency Mode or disabling the DualGovernance mechanism by assigning the EmergencyProtectedTimelock to Aragon Voting. Like the EmergencyActivationCommittee, this committee is also intended for short-term use after the system’s deployment or update.


Expand Down Expand Up @@ -1167,11 +1167,11 @@ Executes a reseal of the sealable contract by calling the `resealSealable` metho
* Proposal MUST be scheduled for execution and passed the timelock duration.


## Contract: TiebreakerCore.sol
## Contract: TiebreakerCoreCommittee.sol

`TiebreakerCore` is a smart contract that extends the `HashConsensus` and `ProposalsList` contracts to manage the scheduling of proposals and the resuming of sealable contracts through a consensus-based mechanism. It interacts with a DualGovernance contract to execute decisions once consensus is reached.
`TiebreakerCoreCommittee` is a smart contract that extends the `HashConsensus` and `ProposalsList` contracts to manage the scheduling of proposals and the resuming of sealable contracts through a consensus-based mechanism. It interacts with a DualGovernance contract to execute decisions once consensus is reached.

### Function: TiebreakerCore.scheduleProposal
### Function: TiebreakerCoreCommittee.scheduleProposal

```solidity
function scheduleProposal(uint256 proposalId)
Expand All @@ -1184,7 +1184,7 @@ Schedules a proposal for execution by voting on it and adding it to the proposal
* MUST be called by a member.
* Proposal with the given id MUST be submitted into `EmergencyProtectedTimelock`

### Function: TiebreakerCore.getScheduleProposalState
### Function: TiebreakerCoreCommittee.getScheduleProposalState

```solidity
function getScheduleProposalState(uint256 proposalId)
Expand All @@ -1194,7 +1194,7 @@ function getScheduleProposalState(uint256 proposalId)

Returns the state of a scheduled proposal including support count, quorum, and execution status.

### Function: TiebreakerCore.executeScheduleProposal
### Function: TiebreakerCoreCommittee.executeScheduleProposal

```solidity
function executeScheduleProposal(uint256 proposalId)
Expand All @@ -1206,15 +1206,15 @@ Executes a scheduled proposal by calling the `tiebreakerScheduleProposal` functi

* Proposal MUST be scheduled for execution and passed the timelock duration.

### Function: TiebreakerCore.getSealableResumeNonce
### Function: TiebreakerCoreCommittee.getSealableResumeNonce

```solidity
function getSealableResumeNonce(address sealable) view returns (uint256)
```

Returns the current nonce for resuming operations of a sealable contract.

### Function: TiebreakerCore.sealableResume
### Function: TiebreakerCoreCommittee.sealableResume

```solidity
function sealableResume(address sealable, uint256 nonce)
Expand All @@ -1227,7 +1227,7 @@ Submits a request to resume operations of a sealable contract by voting on it an
* MUST be called by a member.
* The provided nonce MUST match the current nonce of the sealable contract.

### Function: TiebreakerCore.getSealableResumeState
### Function: TiebreakerCoreCommittee.getSealableResumeState

```solidity
function getSealableResumeState(address sealable, uint256 nonce)
Expand All @@ -1237,7 +1237,7 @@ function getSealableResumeState(address sealable, uint256 nonce)

Returns the state of a sealable resume request including support count, quorum, and execution status.

### Function: TiebreakerCore.executeSealableResume
### Function: TiebreakerCoreCommittee.executeSealableResume

```solidity
function executeSealableResume(address sealable)
Expand All @@ -1251,7 +1251,7 @@ Executes a sealable resume request by calling the `tiebreakerResumeSealable` fun

## Contract: TiebreakerSubCommittee.sol

`TiebreakerSubCommittee` is a smart contract that extends the functionalities of `HashConsensus` and `ProposalsList` to manage the scheduling of proposals and the resumption of sealable contracts through a consensus mechanism. It interacts with the `TiebreakerCore` contract to execute decisions once consensus is reached.
`TiebreakerSubCommittee` is a smart contract that extends the functionalities of `HashConsensus` and `ProposalsList` to manage the scheduling of proposals and the resumption of sealable contracts through a consensus mechanism. It interacts with the `TiebreakerCoreCommittee` contract to execute decisions once consensus is reached.

### Function: TiebreakerSubCommittee.scheduleProposal

Expand Down Expand Up @@ -1282,7 +1282,7 @@ Returns the state of a scheduled proposal including support count, quorum, and e
function executeScheduleProposal(uint256 proposalId)
```

Executes a scheduled proposal by calling the scheduleProposal function on the TiebreakerCore contract.
Executes a scheduled proposal by calling the scheduleProposal function on the `TiebreakerCoreCommittee` contract.

#### Preconditions

Expand Down Expand Up @@ -1314,7 +1314,7 @@ Returns the state of a sealable resume request including support count, quorum,
function executeSealableResume(address sealable) public
```

Executes a sealable resume request by calling the sealableResume function on the TiebreakerCore contract and increments the nonce.
Executes a sealable resume request by calling the sealableResume function on the `TiebreakerCoreCommittee` contract and increments the nonce.

#### Preconditions

Expand Down
2 changes: 1 addition & 1 deletion test/unit/DualGovernance.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
DualGovernanceConfig,
IDualGovernanceConfigProvider,
ImmutableDualGovernanceConfigProvider
} from "contracts/DualGovernanceConfigProvider.sol";
} from "contracts/ImmutableDualGovernanceConfigProvider.sol";

import {IDualGovernance} from "contracts/interfaces/IDualGovernance.sol";
import {IWstETH} from "contracts/interfaces/IWstETH.sol";
Expand Down
18 changes: 11 additions & 7 deletions test/unit/committees/TiebreakerCore.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import {TiebreakerCore} from "contracts/committees/TiebreakerCore.sol";
import {TiebreakerCoreCommittee} from "contracts/committees/TiebreakerCoreCommittee.sol";
import {HashConsensus} from "contracts/committees/HashConsensus.sol";
import {Durations, Duration} from "contracts/types/Duration.sol";
import {Timestamp} from "contracts/types/Timestamp.sol";
Expand Down Expand Up @@ -33,7 +33,7 @@ contract EmergencyProtectedTimelockMock is TargetMock {
}

contract TiebreakerCoreUnitTest is UnitTest {
TiebreakerCore internal tiebreakerCore;
TiebreakerCoreCommittee internal tiebreakerCore;
uint256 internal quorum = 2;
address internal owner = makeAddr("owner");
address[] internal committeeMembers = [address(0x1), address(0x2), address(0x3)];
Expand All @@ -47,15 +47,15 @@ contract TiebreakerCoreUnitTest is UnitTest {
emergencyProtectedTimelock = address(new EmergencyProtectedTimelockMock());
EmergencyProtectedTimelockMock(payable(emergencyProtectedTimelock)).setProposalsCount(1);
dualGovernance = address(new DualGovernanceMock(emergencyProtectedTimelock));
tiebreakerCore = new TiebreakerCore(owner, dualGovernance, timelock);
tiebreakerCore = new TiebreakerCoreCommittee(owner, dualGovernance, timelock);

vm.prank(owner);
tiebreakerCore.addMembers(committeeMembers, quorum);
}

function testFuzz_constructor_HappyPath(address _owner, address _dualGovernance, Duration _timelock) external {
vm.assume(_owner != address(0));
new TiebreakerCore(_owner, _dualGovernance, _timelock);
new TiebreakerCoreCommittee(_owner, _dualGovernance, _timelock);
}

function test_scheduleProposal_HappyPath() external {
Expand Down Expand Up @@ -87,15 +87,19 @@ contract TiebreakerCoreUnitTest is UnitTest {
function test_scheduleProposal_RevertOn_ProposalDoesNotExist() external {
uint256 nonExistentProposalId = proposalId + 1;

vm.expectRevert(abi.encodeWithSelector(TiebreakerCore.ProposalDoesNotExist.selector, nonExistentProposalId));
vm.expectRevert(
abi.encodeWithSelector(TiebreakerCoreCommittee.ProposalDoesNotExist.selector, nonExistentProposalId)
);
vm.prank(committeeMembers[0]);
tiebreakerCore.scheduleProposal(nonExistentProposalId);
}

function test_scheduleProposal_RevertOn_ProposalIdIsZero() external {
uint256 nonExistentProposalId = 0;

vm.expectRevert(abi.encodeWithSelector(TiebreakerCore.ProposalDoesNotExist.selector, nonExistentProposalId));
vm.expectRevert(
abi.encodeWithSelector(TiebreakerCoreCommittee.ProposalDoesNotExist.selector, nonExistentProposalId)
);
vm.prank(committeeMembers[0]);
tiebreakerCore.scheduleProposal(nonExistentProposalId);
}
Expand Down Expand Up @@ -142,7 +146,7 @@ contract TiebreakerCoreUnitTest is UnitTest {
uint256 wrongNonce = 999;

vm.prank(committeeMembers[0]);
vm.expectRevert(abi.encodeWithSelector(TiebreakerCore.ResumeSealableNonceMismatch.selector));
vm.expectRevert(abi.encodeWithSelector(TiebreakerCoreCommittee.ResumeSealableNonceMismatch.selector));
tiebreakerCore.sealableResume(sealable, wrongNonce);
}

Expand Down
Loading