diff --git a/configs/config_holesky.py b/configs/config_holesky.py index c9b22258..ed7527b9 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -48,6 +48,11 @@ WITHDRAWAL_VAULT = "0xF0179dEC45a37423EAD4FaD5fCb136197872EAd9" +# Dual Governance +DUAL_GOVERNANCE = "0xb291a7f092D5cCE0A3C93eA21Bda3431129dB202" +DUAL_GOVERNANCE_ADMIN_EXECUTOR = "0xD5EE9991f44b36E186A658dc2A0357EcCf11b69B" +TIME_CONSTRAINTS = "0x3db5ABA48123bb8789f6f09ec714e7082Bc26747" + # EasyTracks EASYTRACK = "0x1763b9ED3586B08AE796c7787811a2E1bc16163a" @@ -63,6 +68,8 @@ EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0xC91a676A69Eb49be9ECa1954fE6fc861AE07A9A2" EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xb8C4728bc0826bA5864D02FA53148de7A44C2f7E" +EASYTRACK_ALLOWED_TOKENS_REGISTRY = "0x091C0eC8B4D54a9fcB36269B5D5E5AF43309e666" + # Multisigs FINANCE_MULTISIG = "" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 1c784fe6..9cead77e 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -54,6 +54,11 @@ DEPOSIT_SECURITY_MODULE_V1 = "0x710B3303fB508a84F10793c1106e32bE873C24cd" WITHDRAWAL_VAULT = "0xB9D7934878B5FB9610B3fE8A5e441e8fad7E293f" +# Dual Governance +DUAL_GOVERNANCE = "0x0000000000000000000000000000000000000000" +DUAL_GOVERNANCE_ADMIN_EXECUTOR = "0x0000000000000000000000000000000000000000" +TIME_CONSTRAINTS = "0x0000000000000000000000000000000000000000" + # EasyTracks EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" @@ -70,6 +75,8 @@ EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" +EASYTRACK_ALLOWED_TOKENS_REGISTRY = "0x4AC40c34f8992bb1e5E856A448792158022551ca" + # Multisigs FINANCE_MULTISIG = "0x48F300bD3C52c7dA6aAbDE4B683dEB27d38B9ABb" L1_EMERGENCY_BRAKES_MULTISIG = "0x73b047fe6337183A454c5217241D780a932777bD" diff --git a/interfaces/DualGovernance.json b/interfaces/DualGovernance.json new file mode 100644 index 00000000..9f9c30d4 --- /dev/null +++ b/interfaces/DualGovernance.json @@ -0,0 +1,1117 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "contract ITimelock", + "name": "timelock", + "type": "address" + }, + { + "internalType": "contract IResealManager", + "name": "resealManager", + "type": "address" + }, + { + "internalType": "contract IDualGovernanceConfigProvider", + "name": "configProvider", + "type": "address" + } + ], + "internalType": "struct DualGovernance.DualGovernanceComponents", + "name": "components", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "contract IStETH", + "name": "stETH", + "type": "address" + }, + { + "internalType": "contract IWstETH", + "name": "wstETH", + "type": "address" + }, + { + "internalType": "contract IWithdrawalQueue", + "name": "withdrawalQueue", + "type": "address" + } + ], + "internalType": "struct DualGovernance.SignallingTokens", + "name": "signallingTokens", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "minWithdrawalsBatchSize", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "minTiebreakerActivationTimeout", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxTiebreakerActivationTimeout", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "maxSealableWithdrawalBlockersCount", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "maxMinAssetsLockDuration", + "type": "uint32" + } + ], + "internalType": "struct DualGovernance.SanityCheckParams", + "name": "sanityCheckParams", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AlreadyInitialized", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotAdminExecutor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotProposalsCanceller", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotResealCommittee", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotTiebreakerCommittee", + "type": "error" + }, + { "inputs": [], "name": "DurationOverflow", "type": "error" }, + { "inputs": [], "name": "DurationUnderflow", "type": "error" }, + { "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" } + ], + "name": "ExecutorNotRegistered", + "type": "error" + }, + { "inputs": [], "name": "IndexOneBasedOverflow", "type": "error" }, + { "inputs": [], "name": "IndexOneBasedUnderflow", "type": "error" }, + { + "inputs": [ + { + "internalType": "contract IDualGovernanceConfigProvider", + "name": "configProvider", + "type": "address" + } + ], + "name": "InvalidConfigProvider", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" } + ], + "name": "InvalidExecutor", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "minAssetsLockDuration", + "type": "uint32" + } + ], + "name": "InvalidMinAssetsLockDuration", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "canceller", "type": "address" } + ], + "name": "InvalidProposalsCanceller", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "InvalidProposerAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "rageQuitEthWithdrawalsMinDelay", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "rageQuitEthWithdrawalsMaxDelay", + "type": "uint32" + } + ], + "name": "InvalidRageQuitEthWithdrawalsDelayRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "PercentD16", + "name": "firstSealRageQuitSupport", + "type": "uint128" + }, + { + "internalType": "PercentD16", + "name": "secondSealRageQuitSupport", + "type": "uint128" + } + ], + "name": "InvalidRageQuitSupportRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "resealCommittee", + "type": "address" + } + ], + "name": "InvalidResealCommittee", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IResealManager", + "name": "resealManager", + "type": "address" + } + ], + "name": "InvalidResealManager", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sealable", "type": "address" } + ], + "name": "InvalidSealable", + "type": "error" + }, + { + "inputs": [ + { "internalType": "Duration", "name": "timeout", "type": "uint32" } + ], + "name": "InvalidTiebreakerActivationTimeout", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "minTiebreakerActivationTimeout", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxTiebreakerActivationTimeout", + "type": "uint32" + } + ], + "name": "InvalidTiebreakerActivationTimeoutBounds", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "InvalidTiebreakerCommittee", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "vetoSignallingMinDuration", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "vetoSignallingMaxDuration", + "type": "uint32" + } + ], + "name": "InvalidVetoSignallingDurationRange", + "type": "error" + }, + { "inputs": [], "name": "PercentD16Underflow", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "ProposalSchedulingBlocked", + "type": "error" + }, + { "inputs": [], "name": "ProposalSubmissionBlocked", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "ProposerAlreadyRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "ProposerNotRegistered", + "type": "error" + }, + { "inputs": [], "name": "ResealIsNotAllowedInNormalState", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "sealable", "type": "address" } + ], + "name": "SealableWithdrawalBlockerAlreadyAdded", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sealable", "type": "address" } + ], + "name": "SealableWithdrawalBlockerNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "SealableWithdrawalBlockersLimitReached", + "type": "error" + }, + { "inputs": [], "name": "TiebreakNotAllowed", "type": "error" }, + { "inputs": [], "name": "TimestampOverflow", "type": "error" }, + { + "anonymous": false, + "inputs": [], + "name": "CancelAllPendingProposalsExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "CancelAllPendingProposalsSkipped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IDualGovernanceConfigProvider", + "name": "newConfigProvider", + "type": "address" + } + ], + "name": "ConfigProviderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum State", + "name": "from", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "enum State", + "name": "to", + "type": "uint8" + }, + { + "components": [ + { "internalType": "enum State", "name": "state", "type": "uint8" }, + { + "internalType": "Timestamp", + "name": "enteredAt", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "vetoSignallingActivatedAt", + "type": "uint40" + }, + { + "internalType": "contract ISignallingEscrow", + "name": "signallingEscrow", + "type": "address" + }, + { "internalType": "uint8", "name": "rageQuitRound", "type": "uint8" }, + { + "internalType": "Timestamp", + "name": "vetoSignallingReactivationTime", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "normalOrVetoCooldownExitedAt", + "type": "uint40" + }, + { + "internalType": "contract IRageQuitEscrow", + "name": "rageQuitEscrow", + "type": "address" + }, + { + "internalType": "contract IDualGovernanceConfigProvider", + "name": "configProvider", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct DualGovernanceStateMachine.Context", + "name": "state", + "type": "tuple" + } + ], + "name": "DualGovernanceStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IEscrowBase", + "name": "escrowMasterCopy", + "type": "address" + } + ], + "name": "EscrowMasterCopyDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISignallingEscrow", + "name": "escrow", + "type": "address" + } + ], + "name": "NewSignallingEscrowDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "metadata", + "type": "string" + } + ], + "name": "ProposalSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "proposalsCanceller", + "type": "address" + } + ], + "name": "ProposalsCancellerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + } + ], + "name": "ProposerExecutorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + } + ], + "name": "ProposerRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + } + ], + "name": "ProposerUnregistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "resealCommittee", + "type": "address" + } + ], + "name": "ResealCommitteeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IResealManager", + "name": "resealManager", + "type": "address" + } + ], + "name": "ResealManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sealable", + "type": "address" + } + ], + "name": "SealableWithdrawalBlockerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sealable", + "type": "address" + } + ], + "name": "SealableWithdrawalBlockerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "Duration", + "name": "newTiebreakerActivationTimeout", + "type": "uint32" + } + ], + "name": "TiebreakerActivationTimeoutSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newTiebreakerCommittee", + "type": "address" + } + ], + "name": "TiebreakerCommitteeSet", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_SEALABLE_WITHDRAWAL_BLOCKERS_COUNT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TIEBREAKER_ACTIVATION_TIMEOUT", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_TIEBREAKER_ACTIVATION_TIMEOUT", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TIMELOCK", + "outputs": [ + { "internalType": "contract ITimelock", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activateNextState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sealableWithdrawalBlocker", + "type": "address" + } + ], + "name": "addTiebreakerSealableWithdrawalBlocker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "canCancelAllPendingProposals", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "canScheduleProposal", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "canSubmitProposal", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cancelAllPendingProposals", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getConfigProvider", + "outputs": [ + { + "internalType": "contract IDualGovernanceConfigProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEffectiveState", + "outputs": [ + { + "internalType": "enum State", + "name": "effectiveState", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPersistedState", + "outputs": [ + { + "internalType": "enum State", + "name": "persistedState", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProposalsCanceller", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "getProposer", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "executor", "type": "address" } + ], + "internalType": "struct Proposers.Proposer", + "name": "proposer", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProposers", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "executor", "type": "address" } + ], + "internalType": "struct Proposers.Proposer[]", + "name": "proposers", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRageQuitEscrow", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getResealCommittee", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getResealManager", + "outputs": [ + { + "internalType": "contract IResealManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStateDetails", + "outputs": [ + { + "components": [ + { + "internalType": "enum State", + "name": "effectiveState", + "type": "uint8" + }, + { + "internalType": "enum State", + "name": "persistedState", + "type": "uint8" + }, + { + "internalType": "Timestamp", + "name": "persistedStateEnteredAt", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "vetoSignallingActivatedAt", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "vetoSignallingReactivationTime", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "normalOrVetoCooldownExitedAt", + "type": "uint40" + }, + { + "internalType": "uint256", + "name": "rageQuitRound", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "vetoSignallingDuration", + "type": "uint32" + } + ], + "internalType": "struct IDualGovernance.StateDetails", + "name": "stateDetails", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTiebreakerDetails", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "isTie", "type": "bool" }, + { + "internalType": "address", + "name": "tiebreakerCommittee", + "type": "address" + }, + { + "internalType": "Duration", + "name": "tiebreakerActivationTimeout", + "type": "uint32" + }, + { + "internalType": "address[]", + "name": "sealableWithdrawalBlockers", + "type": "address[]" + } + ], + "internalType": "struct ITiebreaker.TiebreakerDetails", + "name": "tiebreakerState", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVetoSignallingEscrow", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" } + ], + "name": "isExecutor", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "isProposer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { "internalType": "address", "name": "executor", "type": "address" } + ], + "name": "registerProposer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sealableWithdrawalBlocker", + "type": "address" + } + ], + "name": "removeTiebreakerSealableWithdrawalBlocker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sealable", "type": "address" } + ], + "name": "resealSealable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "scheduleProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IDualGovernanceConfigProvider", + "name": "newConfigProvider", + "type": "address" + } + ], + "name": "setConfigProvider", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newProposalsCanceller", + "type": "address" + } + ], + "name": "setProposalsCanceller", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + }, + { "internalType": "address", "name": "newExecutor", "type": "address" } + ], + "name": "setProposerExecutor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResealCommittee", + "type": "address" + } + ], + "name": "setResealCommittee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IResealManager", + "name": "newResealManager", + "type": "address" + } + ], + "name": "setResealManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "newTiebreakerActivationTimeout", + "type": "uint32" + } + ], + "name": "setTiebreakerActivationTimeout", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTiebreakerCommittee", + "type": "address" + } + ], + "name": "setTiebreakerCommittee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint96", "name": "value", "type": "uint96" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "internalType": "struct ExternalCall[]", + "name": "calls", + "type": "tuple[]" + }, + { "internalType": "string", "name": "metadata", "type": "string" } + ], + "name": "submitProposal", + "outputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sealable", "type": "address" } + ], + "name": "tiebreakerResumeSealable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "tiebreakerScheduleProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "proposerAccount", + "type": "address" + } + ], + "name": "unregisterProposer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/DualGovernanceAdminExecutor.json b/interfaces/DualGovernanceAdminExecutor.json new file mode 100644 index 00000000..ccf0c519 --- /dev/null +++ b/interfaces/DualGovernanceAdminExecutor.json @@ -0,0 +1,142 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "ETHReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "returndata", + "type": "bytes" + } + ], + "name": "Executed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "name": "execute", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/interfaces/EmergencyProtectedTimelock.json b/interfaces/EmergencyProtectedTimelock.json new file mode 100644 index 00000000..9d294c37 --- /dev/null +++ b/interfaces/EmergencyProtectedTimelock.json @@ -0,0 +1,836 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "Duration", + "name": "minExecutionDelay", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxAfterSubmitDelay", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxAfterScheduleDelay", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxEmergencyModeDuration", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "maxEmergencyProtectionDuration", + "type": "uint32" + } + ], + "internalType": "struct EmergencyProtectedTimelock.SanityCheckParams", + "name": "sanityCheckParams", + "type": "tuple" + }, + { "internalType": "address", "name": "adminExecutor", "type": "address" }, + { + "internalType": "Duration", + "name": "afterSubmitDelay", + "type": "uint32" + }, + { + "internalType": "Duration", + "name": "afterScheduleDelay", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "AfterScheduleDelayNotPassed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "AfterSubmitDelayNotPassed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotAdminExecutor", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotEmergencyActivationCommittee", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotEmergencyExecutionCommittee", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "CallerIsNotGovernance", + "type": "error" + }, + { "inputs": [], "name": "DurationOverflow", "type": "error" }, + { + "inputs": [ + { "internalType": "Timestamp", "name": "protectedTill", "type": "uint40" } + ], + "name": "EmergencyProtectionExpired", + "type": "error" + }, + { "inputs": [], "name": "EmptyCalls", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "adminExecutor", "type": "address" } + ], + "name": "InvalidAdminExecutor", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "afterScheduleDelay", + "type": "uint32" + } + ], + "name": "InvalidAfterScheduleDelay", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "afterSubmitDelay", + "type": "uint32" + } + ], + "name": "InvalidAfterSubmitDelay", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "committee", "type": "address" } + ], + "name": "InvalidEmergencyActivationCommittee", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "committee", "type": "address" } + ], + "name": "InvalidEmergencyExecutionCommittee", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "governance", "type": "address" } + ], + "name": "InvalidEmergencyGovernance", + "type": "error" + }, + { + "inputs": [ + { "internalType": "Duration", "name": "value", "type": "uint32" } + ], + "name": "InvalidEmergencyModeDuration", + "type": "error" + }, + { + "inputs": [ + { "internalType": "Timestamp", "name": "value", "type": "uint40" } + ], + "name": "InvalidEmergencyProtectionEndDate", + "type": "error" + }, + { + "inputs": [ + { "internalType": "Duration", "name": "executionDelay", "type": "uint32" } + ], + "name": "InvalidExecutionDelay", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "governance", "type": "address" } + ], + "name": "InvalidGovernance", + "type": "error" + }, + { "inputs": [], "name": "TimestampOverflow", "type": "error" }, + { + "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], + "name": "UnexpectedEmergencyModeState", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" }, + { "internalType": "enum Status", "name": "status", "type": "uint8" } + ], + "name": "UnexpectedProposalStatus", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAdminExecutor", + "type": "address" + } + ], + "name": "AdminExecutorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "Duration", + "name": "newAfterScheduleDelay", + "type": "uint32" + } + ], + "name": "AfterScheduleDelaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "Duration", + "name": "newAfterSubmitDelay", + "type": "uint32" + } + ], + "name": "AfterSubmitDelaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newActivationCommittee", + "type": "address" + } + ], + "name": "EmergencyActivationCommitteeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newExecutionCommittee", + "type": "address" + } + ], + "name": "EmergencyExecutionCommitteeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newEmergencyGovernance", + "type": "address" + } + ], + "name": "EmergencyGovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EmergencyModeActivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EmergencyModeDeactivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "Duration", + "name": "newEmergencyModeDuration", + "type": "uint32" + } + ], + "name": "EmergencyModeDurationSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "Timestamp", + "name": "newEmergencyProtectionEndDate", + "type": "uint40" + } + ], + "name": "EmergencyProtectionEndDateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newGovernance", + "type": "address" + } + ], + "name": "GovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "ProposalExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "ProposalScheduled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint96", "name": "value", "type": "uint96" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "indexed": false, + "internalType": "struct ExternalCall[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "ProposalSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "ProposalsCancelledTill", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_AFTER_SCHEDULE_DELAY", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_AFTER_SUBMIT_DELAY", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_EMERGENCY_MODE_DURATION", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_EMERGENCY_PROTECTION_DURATION", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_EXECUTION_DELAY", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activateEmergencyMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "canExecute", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "canSchedule", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cancelAllNonExecutedProposals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deactivateEmergencyMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "emergencyExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyReset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAdminExecutor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAfterScheduleDelay", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAfterSubmitDelay", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEmergencyActivationCommittee", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEmergencyExecutionCommittee", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEmergencyGovernance", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEmergencyProtectionDetails", + "outputs": [ + { + "components": [ + { + "internalType": "Duration", + "name": "emergencyModeDuration", + "type": "uint32" + }, + { + "internalType": "Timestamp", + "name": "emergencyModeEndsAfter", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "emergencyProtectionEndsAfter", + "type": "uint40" + } + ], + "internalType": "struct IEmergencyProtectedTimelock.EmergencyProtectionDetails", + "name": "details", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGovernance", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "getProposal", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "address", "name": "executor", "type": "address" }, + { + "internalType": "Timestamp", + "name": "submittedAt", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "scheduledAt", + "type": "uint40" + }, + { "internalType": "enum Status", "name": "status", "type": "uint8" } + ], + "internalType": "struct ITimelock.ProposalDetails", + "name": "proposalDetails", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint96", "name": "value", "type": "uint96" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "internalType": "struct ExternalCall[]", + "name": "calls", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "getProposalCalls", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint96", "name": "value", "type": "uint96" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "internalType": "struct ExternalCall[]", + "name": "calls", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "getProposalDetails", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "address", "name": "executor", "type": "address" }, + { + "internalType": "Timestamp", + "name": "submittedAt", + "type": "uint40" + }, + { + "internalType": "Timestamp", + "name": "scheduledAt", + "type": "uint40" + }, + { "internalType": "enum Status", "name": "status", "type": "uint8" } + ], + "internalType": "struct ITimelock.ProposalDetails", + "name": "proposalDetails", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProposalsCount", + "outputs": [ + { "internalType": "uint256", "name": "count", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEmergencyModeActive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEmergencyProtectionEnabled", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "proposalId", "type": "uint256" } + ], + "name": "schedule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdminExecutor", + "type": "address" + } + ], + "name": "setAdminExecutor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "newAfterScheduleDelay", + "type": "uint32" + } + ], + "name": "setAfterScheduleDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "newAfterSubmitDelay", + "type": "uint32" + } + ], + "name": "setAfterSubmitDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newEmergencyGovernance", + "type": "address" + } + ], + "name": "setEmergencyGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Duration", + "name": "newEmergencyModeDuration", + "type": "uint32" + } + ], + "name": "setEmergencyModeDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newEmergencyActivationCommittee", + "type": "address" + } + ], + "name": "setEmergencyProtectionActivationCommittee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Timestamp", + "name": "newEmergencyProtectionEndDate", + "type": "uint40" + } + ], + "name": "setEmergencyProtectionEndDate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newEmergencyExecutionCommittee", + "type": "address" + } + ], + "name": "setEmergencyProtectionExecutionCommittee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newGovernance", "type": "address" } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "uint96", "name": "value", "type": "uint96" }, + { "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "internalType": "struct ExternalCall[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "submit", + "outputs": [ + { "internalType": "uint256", "name": "newProposalId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "transferExecutorOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/Foo.json b/interfaces/Foo.json new file mode 100644 index 00000000..3aa18943 --- /dev/null +++ b/interfaces/Foo.json @@ -0,0 +1,29 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "BarCall", + "type": "event" + }, + { + "inputs": [], + "name": "bar", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "callCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/interfaces/RolesValidator.json b/interfaces/RolesValidator.json new file mode 100644 index 00000000..f963945f --- /dev/null +++ b/interfaces/RolesValidator.json @@ -0,0 +1,132 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [ + { "internalType": "address", "name": "entity", "type": "address" }, + { "internalType": "string", "name": "roleName", "type": "string" }, + { "internalType": "address", "name": "app", "type": "address" } + ], + "name": "AragonPermissionGranted", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "entity", "type": "address" }, + { "internalType": "string", "name": "roleName", "type": "string" }, + { + "internalType": "address", + "name": "expectedManager", + "type": "address" + }, + { "internalType": "address", "name": "actualManager", "type": "address" } + ], + "name": "AragonPermissionInvalidManager", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "entity", "type": "address" }, + { "internalType": "string", "name": "roleName", "type": "string" }, + { "internalType": "address", "name": "app", "type": "address" } + ], + "name": "AragonPermissionNotGranted", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "entity", "type": "address" }, + { "internalType": "string", "name": "roleName", "type": "string" }, + { "internalType": "address", "name": "app", "type": "address" } + ], + "name": "OZRoleNotGranted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "entity", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "roleName", + "type": "string" + } + ], + "name": "RoleValidated", + "type": "event" + }, + { + "inputs": [], + "name": "ACL", + "outputs": [ + { "internalType": "contract IACL", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ACL_ADDRESS", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "AGENT", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EASYTRACK_ALLOWED_TOKENS_REGISTRY", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIDO", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VOTING", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WITHDRAWAL_QUEUE", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dgAdminExecutor", + "type": "address" + }, + { + "internalType": "address", + "name": "dgResealManager", + "type": "address" + } + ], + "name": "validate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/TimeConstraints.json b/interfaces/TimeConstraints.json new file mode 100644 index 00000000..f46fb65d --- /dev/null +++ b/interfaces/TimeConstraints.json @@ -0,0 +1,69 @@ +[ + { + "inputs": [ + { + "internalType": "Duration", + "name": "currentDayTime", + "type": "uint32" + }, + { "internalType": "Duration", "name": "startDayTime", "type": "uint32" }, + { "internalType": "Duration", "name": "endDayTime", "type": "uint32" } + ], + "name": "DayTimeOutOfRange", + "type": "error" + }, + { "inputs": [], "name": "DayTimeOverflow", "type": "error" }, + { "inputs": [], "name": "DurationOverflow", "type": "error" }, + { + "inputs": [ + { "internalType": "Duration", "name": "startDayTime", "type": "uint32" }, + { "internalType": "Duration", "name": "endDayTime", "type": "uint32" } + ], + "name": "InvalidDayTimeRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Timestamp", + "name": "requiredTimestamp", + "type": "uint40" + } + ], + "name": "TimestampNotReached", + "type": "error" + }, + { + "inputs": [], + "name": "DAY_DURATION", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "Timestamp", "name": "timestamp", "type": "uint40" } + ], + "name": "checkExecuteAfterTimestamp", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "Duration", "name": "startDayTime", "type": "uint32" }, + { "internalType": "Duration", "name": "endDayTime", "type": "uint32" } + ], + "name": "checkExecuteWithinDayTime", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentDayTime", + "outputs": [{ "internalType": "Duration", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/scripts/dual_governance_downgrade_holesky.py b/scripts/dual_governance_downgrade_holesky.py new file mode 100644 index 00000000..11496216 --- /dev/null +++ b/scripts/dual_governance_downgrade_holesky.py @@ -0,0 +1,147 @@ +import time + +from typing import Dict + +from utils.agent import agent_forward, dual_governance_agent_forward +from utils.voting import bake_vote_items, confirm_vote_script, create_vote +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description +from utils.config import ( + contracts, + get_deployer_account, + get_is_live, + get_priority_fee, +) +from utils.permissions import ( + encode_permission_set_manager, + encode_permission_create, + encode_permission_revoke, + encode_permission_grant, +) +from utils.mainnet_fork import pass_and_exec_dao_vote +from scripts.dual_governance_upgrade_holesky import dual_governance_contracts + + +try: + from brownie import interface +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + +description = "Holesky dual governance downgrade dry-run" + +def start_vote(tx_params: Dict[str, str], silent: bool = False): + vote_desc_items, call_script_items = zip( + ( + "Change permission manager for Lido STAKING_CONTROL_ROLE.", + agent_forward( + [ + encode_permission_set_manager(contracts.lido, "STAKING_CONTROL_ROLE", contracts.voting) + ] + ) + ), + ( + "Revoke permission for STAKING_CONTROL_ROLE from Agent contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", revoke_from=contracts.agent + ), + ), + ( + "Grant permission for STAKING_CONTROL_ROLE to Voting contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", grant_to=contracts.voting + ), + ), + ( + "Revoke WithdrawalQueue PAUSE_ROLE from Reseal Manager.", + ( + agent_forward( + [ + ( + contracts.withdrawal_queue.address, + contracts.withdrawal_queue.revokeRole.encode_input( + contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"] + ), + ) + ] + ) + ), + ), + ( + "Revoke WithdrawalQueue RESUME_ROLE from Reseal Manager.", + ( + agent_forward( + [ + ( + contracts.withdrawal_queue.address, + contracts.withdrawal_queue.revokeRole.encode_input( + contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"] + ), + ) + ] + ) + ), + ), + ( + "Grant AllowedTokensRegistry DEFAULT_ADMIN_ROLE to Agent.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.grantRole.encode_input( + contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent + ), + ), + ), + ( + "Revoke AllowedTokensRegistry DEFAULT_ADMIN_ROLE from Voting.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.revokeRole.encode_input( + contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting + ), + ), + ), + ( + "Revoke permission for RUN_SCRIPT_ROLE from DG Executor contract.", + encode_permission_revoke( + target_app=contracts.agent, + permission_name="RUN_SCRIPT_ROLE", + revoke_from=contracts.dual_governance_admin_executor, + ), + ), + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) + + +def main(): + tx_params: Dict[str, str] = {"from": get_deployer_account().address} + if get_is_live(): + tx_params["priority_fee"] = get_priority_fee() + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(5) # hack for waiting thread #2. + + +def start_and_execute_vote_on_fork(): + if get_is_live(): + raise Exception("This script is for local testing only.") + + tx_params = {"from": get_deployer_account()} + vote_id, _ = start_vote(tx_params=tx_params, silent=True) + + time.sleep(5) # hack for waiting thread #2. + + print(f"Vote created: {vote_id}.") + pass_and_exec_dao_vote(int(vote_id)) diff --git a/scripts/dual_governance_upgrade_holesky.py b/scripts/dual_governance_upgrade_holesky.py new file mode 100644 index 00000000..0411298b --- /dev/null +++ b/scripts/dual_governance_upgrade_holesky.py @@ -0,0 +1,182 @@ +import time + +from typing import Dict + +from utils.agent import agent_forward, dual_governance_agent_forward +from utils.voting import bake_vote_items, confirm_vote_script, create_vote +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description +from utils.config import ( + contracts, + get_deployer_account, + get_is_live, + get_priority_fee, +) +from utils.permissions import ( + encode_permission_set_manager, + encode_permission_create, + encode_permission_revoke, + encode_permission_grant, +) +from utils.mainnet_fork import pass_and_exec_dao_vote + + +try: + from brownie import interface +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + + +description = "Holesky dual governance upgrade dry-run" + +dual_governance_contracts = { + "dualGovernance": "0xb291a7f092D5cCE0A3C93eA21Bda3431129dB202", + "adminExecutor": "0xD5EE9991f44b36E186A658dc2A0357EcCf11b69B", + "resealManager": "0xc2764655e3fe0bd2D3C710D74Fa5a89162099FD8", +} + +def start_vote(tx_params: Dict[str, str], silent: bool = False): + foo_contract = interface.Foo("0xC3fc22C7e0d20247B797fb6dc743BD3879217c81") + roles_validator = interface.RolesValidator("0x0F8826a574BCFDC4997939076f6D82877971feB3") + + vote_desc_items, call_script_items = zip( + ( + "Revoke permission for STAKING_CONTROL_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", revoke_from=contracts.voting + ), + ), + ( + "Grant permission for STAKING_CONTROL_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Lido STAKING_CONTROL_ROLE.", + encode_permission_set_manager(contracts.lido, "STAKING_CONTROL_ROLE", contracts.agent), + ), + ( + "Grant WithdrawalQueue PAUSE_ROLE to Reseal Manager.", + ( + agent_forward( + [ + ( + contracts.withdrawal_queue.address, + contracts.withdrawal_queue.grantRole.encode_input( + contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"] + ), + ) + ] + ) + ), + ), + ( + "Grant WithdrawalQueue RESUME_ROLE to Reseal Manager.", + ( + agent_forward( + [ + ( + contracts.withdrawal_queue.address, + contracts.withdrawal_queue.grantRole.encode_input( + contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"] + ), + ) + ] + ) + ), + ), + ( + "Grant AllowedTokensRegistry DEFAULT_ADMIN_ROLE to Voting.", + ( + agent_forward( + [ + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.grantRole.encode_input( + contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting + ), + ) + ] + ) + ), + ), + ( + "Revoke AllowedTokensRegistry DEFAULT_ADMIN_ROLE from Agent.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.revokeRole.encode_input( + contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent + ), + ), + ), + ( + "Grant permission for RUN_SCRIPT_ROLE to DG Executor contract.", + encode_permission_grant( + target_app=contracts.agent, + permission_name="RUN_SCRIPT_ROLE", + grant_to=dual_governance_contracts["adminExecutor"], + ), + ), + ( + "Validate transferred roles", + ( + roles_validator.address, + roles_validator.validate.encode_input( + dual_governance_contracts['adminExecutor'], dual_governance_contracts['resealManager'] + ), + ) + ), + ( + "Submit first dual governance proposal", + ( + dual_governance_agent_forward( + [( + foo_contract.address, + foo_contract.bar.encode_input() + ), + ( + contracts.time_constraints.address, + contracts.time_constraints.checkExecuteWithinDayTime.encode_input(28800, 72000) + )] + ) + ) + ) + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) + + +def main(): + tx_params: Dict[str, str] = {"from": get_deployer_account().address} + if get_is_live(): + tx_params["priority_fee"] = get_priority_fee() + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(5) # hack for waiting thread #2. + + +def start_and_execute_vote_on_fork(): + if get_is_live(): + raise Exception("This script is for local testing only.") + + tx_params = {"from": get_deployer_account()} + vote_id, _ = start_vote(tx_params=tx_params, silent=True) + + time.sleep(5) # hack for waiting thread #2. + + print(f"Vote created: {vote_id}.") + pass_and_exec_dao_vote(int(vote_id)) diff --git a/tests/dual_governance_downgrade_holesky_test.py b/tests/dual_governance_downgrade_holesky_test.py new file mode 100644 index 00000000..897a6170 --- /dev/null +++ b/tests/dual_governance_downgrade_holesky_test.py @@ -0,0 +1,56 @@ +from scripts.dual_governance_downgrade_holesky import start_vote, dual_governance_contracts +from utils.config import contracts +from utils.test.tx_tracing_helpers import * +from brownie.network.transaction import TransactionReceipt +from utils.config import contracts +from brownie.network.account import Account + +try: + from brownie import interface, chain +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + +def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, bypass_events_decoding, stranger: Account): + dao_voting = contracts.voting + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + # Reseal manager + assert contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"]) + assert contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"]) + + # Allowed tokens registry + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + + # Agent + assert contracts.acl.hasPermission(contracts.dual_governance_admin_executor, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + assert contracts.acl.hasPermission(contracts.voting, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + + # START VOTE + vote_id = vote_ids_from_env[0] if vote_ids_from_env else start_vote({"from": ldo_holder}, silent=True)[0] + + tx: TransactionReceipt = helpers.execute_vote( + vote_id=vote_id, accounts=accounts, dao_voting=dao_voting, skip_time=3 * 60 * 60 * 24 + ) + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + # Reseal manager + assert not contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"]) + assert not contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"]) + + # Allowed tokens registry + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + + # Agent + assert not contracts.acl.hasPermission(contracts.dual_governance_admin_executor, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + assert contracts.acl.hasPermission(contracts.voting, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) diff --git a/tests/dual_governance_upgrade_holesky_test.py b/tests/dual_governance_upgrade_holesky_test.py new file mode 100644 index 00000000..eefa0b12 --- /dev/null +++ b/tests/dual_governance_upgrade_holesky_test.py @@ -0,0 +1,69 @@ +from scripts.dual_governance_upgrade_holesky import start_vote, dual_governance_contracts +from utils.config import contracts +from utils.test.tx_tracing_helpers import * +from brownie.network.transaction import TransactionReceipt +from utils.config import contracts +from brownie.network.account import Account + +try: + from brownie import interface, chain +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + +def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, bypass_events_decoding, stranger: Account): + dao_voting = contracts.voting + timelock = interface.EmergencyProtectedTimelock(contracts.dual_governance.TIMELOCK()) + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + # Allowed tokens registry + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + + # Agent + assert not contracts.acl.hasPermission(contracts.dual_governance_admin_executor, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + assert contracts.acl.hasPermission(contracts.voting, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + + # Reseal manager + assert not contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"]) + assert not contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"]) + + # START VOTE + vote_id = vote_ids_from_env[0] if vote_ids_from_env else start_vote({"from": ldo_holder}, silent=True)[0] + + tx: TransactionReceipt = helpers.execute_vote( + vote_id=vote_id, accounts=accounts, dao_voting=dao_voting, skip_time=3 * 60 * 60 * 24 + ) + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + # # Allowed tokens registry + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + + # Agent + assert contracts.acl.hasPermission(contracts.dual_governance_admin_executor, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + assert contracts.acl.hasPermission(contracts.voting, contracts.agent, contracts.agent.RUN_SCRIPT_ROLE()) + + # Reseal manager + assert contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.PAUSE_ROLE(), dual_governance_contracts["resealManager"]) + assert contracts.withdrawal_queue.hasRole(contracts.withdrawal_queue.RESUME_ROLE(), dual_governance_contracts["resealManager"]) + + proposal_id = timelock.getProposalsCount() + + # while not contracts.dual_governance.canScheduleProposal(proposal_id): + chain.sleep(60 * 24) + + contracts.dual_governance.scheduleProposal(proposal_id, {"from": stranger}) + + # while not timelock.canExecute(proposal_id): + chain.sleep(60 * 24) + + timelock.execute(proposal_id, {"from": stranger}) diff --git a/utils/agent.py b/utils/agent.py index 4538e4b8..f89ec926 100644 --- a/utils/agent.py +++ b/utils/agent.py @@ -1,10 +1,11 @@ from utils.config import contracts -from utils.config import AGENT +from utils.config import AGENT, DUAL_GOVERNANCE from utils.evm_script import ( encode_call_script, ) from typing import ( Tuple, + Optional, Sequence, ) @@ -18,3 +19,13 @@ def agent_forward(call_script: Sequence[Tuple[str, str]]) -> Tuple[str, str]: def agent_execute(target: str, value: str, data: str) -> Tuple[str, str]: agent = contracts.agent return (AGENT, agent.execute.encode_input(target, value, data)) + + +def dual_governance_agent_forward( + call_script: Sequence[Tuple[str, str]], + description: Optional[str] = "", +) -> Tuple[str, str]: + dual_governance = contracts.dual_governance + (agent_address, agent_calldata) = agent_forward(call_script) + + return (DUAL_GOVERNANCE, dual_governance.submitProposal.encode_input([(agent_address, 0, agent_calldata)], description)) diff --git a/utils/config.py b/utils/config.py index 767e86af..aa7007d0 100644 --- a/utils/config.py +++ b/utils/config.py @@ -391,6 +391,22 @@ def trp_escrow_factory(self) -> interface.VestingEscrowFactory: def token_rate_notifier(self) -> interface.TokenRateNotifier: return interface.TokenRateNotifier(L1_TOKEN_RATE_NOTIFIER) + @property + def allowed_tokens_registry(self) -> interface.AllowedTokensRegistry: + return interface.AllowedTokensRegistry(EASYTRACK_ALLOWED_TOKENS_REGISTRY) + + @property + def dual_governance(self) -> interface.DualGovernance: + return interface.DualGovernance(DUAL_GOVERNANCE) + + @property + def dual_governance_admin_executor(self) -> interface.DualGovernanceAdminExecutor: + return interface.DualGovernanceAdminExecutor(DUAL_GOVERNANCE_ADMIN_EXECUTOR) + + @property + def time_constraints(self) -> interface.TimeConstraints: + return interface.TimeConstraints(TIME_CONSTRAINTS) + def __getattr__(name: str) -> Any: if name == "contracts": return ContractsLazyLoader() diff --git a/utils/mainnet_fork.py b/utils/mainnet_fork.py index 3c03ee6a..7db63b5d 100644 --- a/utils/mainnet_fork.py +++ b/utils/mainnet_fork.py @@ -1,7 +1,7 @@ from contextlib import contextmanager from brownie import chain, accounts, interface -from utils.config import VOTING +from utils.config import VOTING, network_name @contextmanager @@ -27,12 +27,16 @@ def pass_and_exec_dao_vote(vote_id): if not dao_voting.canExecute(vote_id): print(f"Passing vote {vote_id}") - # together these accounts hold 15% of LDO total supply - ldo_holders = [ - "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", - "0xb8d83908aab38a159f3da47a59d84db8e1838712", - "0xa2dfc431297aee387c05beef507e5335e684fbcd", - ] + + if network_name() in ("holesky", "holesky-fork"): + ldo_holders = ["0xc807d4036B400dE8f6cD2aDbd8d9cf9a3a01CC30"] + else: + # together these accounts hold 15% of LDO total supply + ldo_holders = [ + "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", + "0xb8d83908aab38a159f3da47a59d84db8e1838712", + "0xa2dfc431297aee387c05beef507e5335e684fbcd", + ] for holder_addr in ldo_holders: print(f" voting from {holder_addr}") diff --git a/utils/permissions.py b/utils/permissions.py index 4089f05e..c6a5d185 100644 --- a/utils/permissions.py +++ b/utils/permissions.py @@ -24,6 +24,18 @@ def encode_permission_revoke(target_app, permission_name, revoke_from) -> Tuple[ return acl.address, acl.revokePermission.encode_input(revoke_from, target_app, permission_id) +def encode_permission_set_manager(target_app, permission_name: str, grant_to: str) -> Tuple[str, str]: + acl = contracts.acl + permission_id = convert.to_uint(Web3.keccak(text=permission_name)) + return acl.address, acl.setPermissionManager.encode_input(grant_to, target_app, permission_id) + + +def encode_permission_create(target_app, permission_name: str, grant_to, manager) -> Tuple[str, str]: + acl = contracts.acl + permission_id = convert.to_uint(Web3.keccak(text=permission_name)) + return acl.address, acl.createPermission.encode_input(grant_to, target_app, permission_id, manager) + + def encode_permission_grant_p( target_app, permission_name: str,