Skip to content

Commit 2fcc925

Browse files
authored
Merge branch 'lidofinance:develop' into develop
2 parents ef214c7 + 1ffa251 commit 2fcc925

File tree

70 files changed

+7355
-1291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+7355
-1291
lines changed

contracts/DualGovernance.sol

Lines changed: 262 additions & 84 deletions
Large diffs are not rendered by default.

contracts/DualGovernanceConfigProvider.sol

Lines changed: 0 additions & 76 deletions
This file was deleted.

contracts/EmergencyProtectedTimelock.sol

Lines changed: 138 additions & 77 deletions
Large diffs are not rendered by default.

contracts/Escrow.sol

Lines changed: 205 additions & 58 deletions
Large diffs are not rendered by default.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.26;
3+
4+
import {Duration} from "./types/Duration.sol";
5+
import {PercentD16} from "./types/PercentD16.sol";
6+
7+
import {IDualGovernanceConfigProvider} from "./interfaces/IDualGovernanceConfigProvider.sol";
8+
9+
import {DualGovernanceConfig} from "./libraries/DualGovernanceConfig.sol";
10+
11+
contract ImmutableDualGovernanceConfigProvider is IDualGovernanceConfigProvider {
12+
using DualGovernanceConfig for DualGovernanceConfig.Context;
13+
14+
PercentD16 public immutable FIRST_SEAL_RAGE_QUIT_SUPPORT;
15+
PercentD16 public immutable SECOND_SEAL_RAGE_QUIT_SUPPORT;
16+
17+
Duration public immutable MIN_ASSETS_LOCK_DURATION;
18+
19+
Duration public immutable VETO_SIGNALLING_MIN_DURATION;
20+
Duration public immutable VETO_SIGNALLING_MAX_DURATION;
21+
Duration public immutable VETO_SIGNALLING_MIN_ACTIVE_DURATION;
22+
Duration public immutable VETO_SIGNALLING_DEACTIVATION_MAX_DURATION;
23+
24+
Duration public immutable VETO_COOLDOWN_DURATION;
25+
26+
Duration public immutable RAGE_QUIT_EXTENSION_PERIOD_DURATION;
27+
Duration public immutable RAGE_QUIT_ETH_WITHDRAWALS_MIN_DELAY;
28+
Duration public immutable RAGE_QUIT_ETH_WITHDRAWALS_MAX_DELAY;
29+
Duration public immutable RAGE_QUIT_ETH_WITHDRAWALS_DELAY_GROWTH;
30+
31+
constructor(DualGovernanceConfig.Context memory dualGovernanceConfig) {
32+
dualGovernanceConfig.validate();
33+
34+
FIRST_SEAL_RAGE_QUIT_SUPPORT = dualGovernanceConfig.firstSealRageQuitSupport;
35+
SECOND_SEAL_RAGE_QUIT_SUPPORT = dualGovernanceConfig.secondSealRageQuitSupport;
36+
37+
MIN_ASSETS_LOCK_DURATION = dualGovernanceConfig.minAssetsLockDuration;
38+
VETO_SIGNALLING_MIN_DURATION = dualGovernanceConfig.vetoSignallingMinDuration;
39+
VETO_SIGNALLING_MAX_DURATION = dualGovernanceConfig.vetoSignallingMaxDuration;
40+
41+
VETO_SIGNALLING_MIN_ACTIVE_DURATION = dualGovernanceConfig.vetoSignallingMinActiveDuration;
42+
VETO_SIGNALLING_DEACTIVATION_MAX_DURATION = dualGovernanceConfig.vetoSignallingDeactivationMaxDuration;
43+
44+
VETO_COOLDOWN_DURATION = dualGovernanceConfig.vetoCooldownDuration;
45+
46+
RAGE_QUIT_EXTENSION_PERIOD_DURATION = dualGovernanceConfig.rageQuitExtensionPeriodDuration;
47+
RAGE_QUIT_ETH_WITHDRAWALS_MIN_DELAY = dualGovernanceConfig.rageQuitEthWithdrawalsMinDelay;
48+
RAGE_QUIT_ETH_WITHDRAWALS_MAX_DELAY = dualGovernanceConfig.rageQuitEthWithdrawalsMaxDelay;
49+
RAGE_QUIT_ETH_WITHDRAWALS_DELAY_GROWTH = dualGovernanceConfig.rageQuitEthWithdrawalsDelayGrowth;
50+
}
51+
52+
function getDualGovernanceConfig() external view returns (DualGovernanceConfig.Context memory config) {
53+
config.firstSealRageQuitSupport = FIRST_SEAL_RAGE_QUIT_SUPPORT;
54+
config.secondSealRageQuitSupport = SECOND_SEAL_RAGE_QUIT_SUPPORT;
55+
56+
config.minAssetsLockDuration = MIN_ASSETS_LOCK_DURATION;
57+
config.vetoSignallingMinDuration = VETO_SIGNALLING_MIN_DURATION;
58+
config.vetoSignallingMaxDuration = VETO_SIGNALLING_MAX_DURATION;
59+
config.vetoSignallingMinActiveDuration = VETO_SIGNALLING_MIN_ACTIVE_DURATION;
60+
config.vetoSignallingDeactivationMaxDuration = VETO_SIGNALLING_DEACTIVATION_MAX_DURATION;
61+
62+
config.vetoCooldownDuration = VETO_COOLDOWN_DURATION;
63+
64+
config.rageQuitExtensionPeriodDuration = RAGE_QUIT_EXTENSION_PERIOD_DURATION;
65+
config.rageQuitEthWithdrawalsMinDelay = RAGE_QUIT_ETH_WITHDRAWALS_MIN_DELAY;
66+
config.rageQuitEthWithdrawalsMaxDelay = RAGE_QUIT_ETH_WITHDRAWALS_MAX_DELAY;
67+
config.rageQuitEthWithdrawalsDelayGrowth = RAGE_QUIT_ETH_WITHDRAWALS_DELAY_GROWTH;
68+
}
69+
}

contracts/TimelockedGovernance.sol

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ contract TimelockedGovernance is IGovernance {
2525
/// @dev Submits a proposal to the timelock.
2626
/// @param calls An array of ExternalCall structs representing the calls to be executed in the proposal.
2727
/// @return proposalId The ID of the submitted proposal.
28-
function submitProposal(ExternalCall[] calldata calls) external returns (uint256 proposalId) {
28+
function submitProposal(
29+
ExternalCall[] calldata calls,
30+
string calldata metadata
31+
) external returns (uint256 proposalId) {
2932
_checkCallerIsGovernance();
30-
return TIMELOCK.submit(TIMELOCK.getAdminExecutor(), calls);
33+
return TIMELOCK.submit(TIMELOCK.getAdminExecutor(), calls, metadata);
3134
}
3235

3336
/// @dev Schedules a submitted proposal.
@@ -50,9 +53,10 @@ contract TimelockedGovernance is IGovernance {
5053
}
5154

5255
/// @dev Cancels all pending proposals that have not been executed.
53-
function cancelAllPendingProposals() external {
56+
function cancelAllPendingProposals() external returns (bool) {
5457
_checkCallerIsGovernance();
5558
TIMELOCK.cancelAllNonExecutedProposals();
59+
return true;
5660
}
5761

5862
/// @dev Checks if the msg.sender is the governance address.

contracts/committees/EmergencyActivationCommittee.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ pragma solidity 0.8.26;
33

44
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
55

6-
import {HashConsensus} from "./HashConsensus.sol";
7-
import {ITimelock} from "../interfaces/ITimelock.sol";
8-
import {Duration, Durations} from "../types/Duration.sol";
6+
import {Durations} from "../types/Duration.sol";
97
import {Timestamp} from "../types/Timestamp.sol";
108

9+
import {IEmergencyProtectedTimelock} from "../interfaces/IEmergencyProtectedTimelock.sol";
10+
11+
import {HashConsensus} from "./HashConsensus.sol";
12+
1113
/// @title Emergency Activation Committee Contract
1214
/// @notice This contract allows a committee to approve and execute an emergency activation
1315
/// @dev Inherits from HashConsensus to utilize voting and consensus mechanisms
@@ -21,7 +23,7 @@ contract EmergencyActivationCommittee is HashConsensus {
2123
address[] memory committeeMembers,
2224
uint256 executionQuorum,
2325
address emergencyProtectedTimelock
24-
) HashConsensus(owner, Durations.from(0)) {
26+
) HashConsensus(owner, Durations.ZERO) {
2527
EMERGENCY_PROTECTED_TIMELOCK = emergencyProtectedTimelock;
2628

2729
_addMembers(committeeMembers, executionQuorum);
@@ -52,7 +54,8 @@ contract EmergencyActivationCommittee is HashConsensus {
5254
function executeActivateEmergencyMode() external {
5355
_markUsed(EMERGENCY_ACTIVATION_HASH);
5456
Address.functionCall(
55-
EMERGENCY_PROTECTED_TIMELOCK, abi.encodeWithSelector(ITimelock.activateEmergencyMode.selector)
57+
EMERGENCY_PROTECTED_TIMELOCK,
58+
abi.encodeWithSelector(IEmergencyProtectedTimelock.activateEmergencyMode.selector)
5659
);
5760
}
5861
}

contracts/committees/EmergencyExecutionCommittee.sol

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
pragma solidity 0.8.26;
33

44
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
5+
6+
import {Durations} from "../types/Duration.sol";
7+
import {Timestamp} from "../types/Timestamp.sol";
8+
9+
import {IEmergencyProtectedTimelock} from "../interfaces/IEmergencyProtectedTimelock.sol";
10+
511
import {HashConsensus} from "./HashConsensus.sol";
612
import {ProposalsList} from "./ProposalsList.sol";
7-
import {ITimelock} from "../interfaces/ITimelock.sol";
8-
import {Timestamp} from "../types/Timestamp.sol";
9-
import {Durations} from "../types/Duration.sol";
1013

1114
enum ProposalType {
1215
EmergencyExecute,
@@ -17,14 +20,16 @@ enum ProposalType {
1720
/// @notice This contract allows a committee to vote on and execute emergency proposals
1821
/// @dev Inherits from HashConsensus for voting mechanisms and ProposalsList for proposal management
1922
contract EmergencyExecutionCommittee is HashConsensus, ProposalsList {
23+
error ProposalDoesNotExist(uint256 proposalId);
24+
2025
address public immutable EMERGENCY_PROTECTED_TIMELOCK;
2126

2227
constructor(
2328
address owner,
2429
address[] memory committeeMembers,
2530
uint256 executionQuorum,
2631
address emergencyProtectedTimelock
27-
) HashConsensus(owner, Durations.from(0)) {
32+
) HashConsensus(owner, Durations.ZERO) {
2833
EMERGENCY_PROTECTED_TIMELOCK = emergencyProtectedTimelock;
2934

3035
_addMembers(committeeMembers, executionQuorum);
@@ -37,11 +42,12 @@ contract EmergencyExecutionCommittee is HashConsensus, ProposalsList {
3742
/// @notice Votes on an emergency execution proposal
3843
/// @dev Only callable by committee members
3944
/// @param proposalId The ID of the proposal to vote on
40-
/// @param _supports Indicates whether the member supports the proposal execution
41-
function voteEmergencyExecute(uint256 proposalId, bool _supports) public {
45+
/// @param _support Indicates whether the member supports the proposal execution
46+
function voteEmergencyExecute(uint256 proposalId, bool _support) public {
4247
_checkCallerIsMember();
48+
_checkProposalExists(proposalId);
4349
(bytes memory proposalData, bytes32 key) = _encodeEmergencyExecute(proposalId);
44-
_vote(key, _supports);
50+
_vote(key, _support);
4551
_pushProposal(key, uint256(ProposalType.EmergencyExecute), proposalData);
4652
}
4753

@@ -66,10 +72,22 @@ contract EmergencyExecutionCommittee is HashConsensus, ProposalsList {
6672
(, bytes32 key) = _encodeEmergencyExecute(proposalId);
6773
_markUsed(key);
6874
Address.functionCall(
69-
EMERGENCY_PROTECTED_TIMELOCK, abi.encodeWithSelector(ITimelock.emergencyExecute.selector, proposalId)
75+
EMERGENCY_PROTECTED_TIMELOCK,
76+
abi.encodeWithSelector(IEmergencyProtectedTimelock.emergencyExecute.selector, proposalId)
7077
);
7178
}
7279

80+
/// @notice Checks if a proposal exists
81+
/// @param proposalId The ID of the proposal to check
82+
function _checkProposalExists(uint256 proposalId) internal view {
83+
if (
84+
proposalId == 0
85+
|| proposalId > IEmergencyProtectedTimelock(EMERGENCY_PROTECTED_TIMELOCK).getProposalsCount()
86+
) {
87+
revert ProposalDoesNotExist(proposalId);
88+
}
89+
}
90+
7391
/// @dev Encodes the proposal data and generates the proposal key for an emergency execution
7492
/// @param proposalId The ID of the proposal to encode
7593
/// @return proposalData The encoded proposal data
@@ -114,7 +132,9 @@ contract EmergencyExecutionCommittee is HashConsensus, ProposalsList {
114132
function executeEmergencyReset() external {
115133
bytes32 proposalKey = _encodeEmergencyResetProposalKey();
116134
_markUsed(proposalKey);
117-
Address.functionCall(EMERGENCY_PROTECTED_TIMELOCK, abi.encodeWithSelector(ITimelock.emergencyReset.selector));
135+
Address.functionCall(
136+
EMERGENCY_PROTECTED_TIMELOCK, abi.encodeWithSelector(IEmergencyProtectedTimelock.emergencyReset.selector)
137+
);
118138
}
119139

120140
/// @notice Encodes the proposal key for an emergency reset

0 commit comments

Comments
 (0)