From 4759ecdeb5f9b9e557da19115ffb17c1a2493e9d Mon Sep 17 00:00:00 2001 From: web3rover Date: Wed, 27 Nov 2024 22:56:41 +0700 Subject: [PATCH 01/15] feat: wip - vip for multichain governance --- .../proposals/basesepolia/vip-006/index.ts | 18 + .../vip-006/abi/AccessControlManager.json | 360 ++++++++++++++++++ .../simulations/basesepolia/vip-006/index.ts | 39 ++ src/networkAddresses.ts | 2 + src/types.ts | 1 + vips/vip-384/bsctestnet.ts | 64 ++++ 6 files changed, 484 insertions(+) create mode 100644 multisig/proposals/basesepolia/vip-006/index.ts create mode 100644 multisig/simulations/basesepolia/vip-006/abi/AccessControlManager.json create mode 100644 multisig/simulations/basesepolia/vip-006/index.ts create mode 100644 vips/vip-384/bsctestnet.ts diff --git a/multisig/proposals/basesepolia/vip-006/index.ts b/multisig/proposals/basesepolia/vip-006/index.ts new file mode 100644 index 000000000..588a04a1b --- /dev/null +++ b/multisig/proposals/basesepolia/vip-006/index.ts @@ -0,0 +1,18 @@ +import { makeProposal } from "../../../../src/utils"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; + +const { basesepolia } = NETWORK_ADDRESSES; + +export const ACM = "0x724138223D8F76b519fdE715f60124E7Ce51e051"; +const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; + +export const vip007 = () => { + return makeProposal([ + { + target: ACM, + signature: "grantRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, basesepolia.NORMAL_TIMELOCK], + }, + ]); +}; +export default vip007; \ No newline at end of file diff --git a/multisig/simulations/basesepolia/vip-006/abi/AccessControlManager.json b/multisig/simulations/basesepolia/vip-006/abi/AccessControlManager.json new file mode 100644 index 000000000..4a118fcc4 --- /dev/null +++ b/multisig/simulations/basesepolia/vip-006/abi/AccessControlManager.json @@ -0,0 +1,360 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "PermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "PermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "accountToPermit", + "type": "address" + } + ], + "name": "giveCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "hasPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "isAllowedToCall", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "accountToRevoke", + "type": "address" + } + ], + "name": "revokeCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/multisig/simulations/basesepolia/vip-006/index.ts b/multisig/simulations/basesepolia/vip-006/index.ts new file mode 100644 index 000000000..a7249a4c9 --- /dev/null +++ b/multisig/simulations/basesepolia/vip-006/index.ts @@ -0,0 +1,39 @@ +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { forking, pretendExecutingVip } from "src/vip-framework/index"; + +import vip006, { ACM } from "../../../proposals/basesepolia/vip-006"; +import ACM_ABI from "./abi/AccessControlManager.json"; + +const { basesepolia } = NETWORK_ADDRESSES; + +forking(18477210, async () => { + let acm: Contract; + let defaultAdminRole: string; + + before(async () => { + acm = await ethers.getContractAt(ACM_ABI, ACM); + defaultAdminRole = await acm.DEFAULT_ADMIN_ROLE(); + }); + + describe("Pre-VIP behaviour", async () => { + it("Normal Timelock does not has default admin role", async () => { + const hasRole = await acm.hasRole(defaultAdminRole, basesepolia.NORMAL_TIMELOCK); + expect(hasRole).equals(false); + }); + }); + + describe("Post-VIP behavior", async () => { + before(async () => { + await pretendExecutingVip(await vip006()); + }); + + it("Normal Timelock has default admin role", async () => { + const hasRole = await acm.hasRole(defaultAdminRole, basesepolia.NORMAL_TIMELOCK); + expect(hasRole).equals(true); + }); + }); +}); \ No newline at end of file diff --git a/src/networkAddresses.ts b/src/networkAddresses.ts index 365f5448b..3cc42a050 100644 --- a/src/networkAddresses.ts +++ b/src/networkAddresses.ts @@ -218,5 +218,7 @@ export const NETWORK_ADDRESSES = { GENERIC_TEST_USER_ACCOUNT: "0x6f057A858171e187124ddEDF034dAc63De5dE5dB", REDSTONE_ORACLE: "0x8267FE3f75E0A37ee34e113E767F9C9727206838", POOL_REGISTRY: "0xCa330282BEeb07a81963336d0bf8f5f34317916c", + NORMAL_TIMELOCK: "0xCc84f6122649eDc48f4a426814e6b6C6fF9bBe0a", + OMNICHAIN_GOVERNANCE_EXECUTOR: "0xDD59be81B3B5BFa391bDA3a84c9f5233BfEF52a4", }, }; diff --git a/src/types.ts b/src/types.ts index 0e50a3aff..db6dc7195 100644 --- a/src/types.ts +++ b/src/types.ts @@ -78,4 +78,5 @@ export enum LzChainId { zksyncmainnet = 165, opsepolia = 10232, opmainnet = 111, + basesepolia = 10245, } diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts new file mode 100644 index 000000000..5c04d61bd --- /dev/null +++ b/vips/vip-384/bsctestnet.ts @@ -0,0 +1,64 @@ +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId, ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { basesepolia } = NETWORK_ADDRESSES; +export const OMNICHAIN_PROPOSAL_SENDER = "0xCfD34AEB46b1CB4779c945854d405E91D27A1899"; + +export const OMNICHAIN_EXECUTOR_OWNER = "0xe3fb08B8817a0c88d39A4DA4eFFD586D3326b73b"; +export const ACM = "0x724138223D8F76b519fdE715f60124E7Ce51e051"; +export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; +export const ACM_AGGREGATOR = "0xEEeF13364fD22b8eA6932A9ed337e2638f8E0eD6"; +export const MAX_DAILY_LIMIT = 100; + +const vip389 = () => { + const meta = { + version: "v2", + title: "VIP-389 Enable Multichain Governance on op sepolia", + description: `### Summary`, + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + return makeProposal( + [ + { + target: OMNICHAIN_PROPOSAL_SENDER, + signature: "setMaxDailyLimit(uint16,uint256)", + params: [LzChainId.basesepolia, MAX_DAILY_LIMIT], + }, + { + target: OMNICHAIN_PROPOSAL_SENDER, + signature: "setTrustedRemoteAddress(uint16,bytes)", + params: [LzChainId.basesepolia, basesepolia.OMNICHAIN_GOVERNANCE_EXECUTOR], + }, + { + target: OMNICHAIN_EXECUTOR_OWNER, + signature: "acceptOwnership()", + params: [], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM, + signature: "grantRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [0], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM, + signature: "revokeRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basesepolia, + }, + ], + meta, + ProposalType.REGULAR, + ); +}; +export default vip389; \ No newline at end of file From c5077d362f3f70d29a9f4bef75a2e02e645b0623 Mon Sep 17 00:00:00 2001 From: web3rover Date: Thu, 28 Nov 2024 15:57:43 +0700 Subject: [PATCH 02/15] feat: wip - bsctestnet vip --- .../vip-384/abi/AccessControlManager_ABI.json | 157 +++++ .../abi/OmnichainExecutorOwner_ABI.json | 145 +++++ .../abi/OmnichainGovernanceExecutor_ABI.json | 539 ++++++++++++++++++ .../vip-384/abi/OmnichainProposalSender.json | 314 ++++++++++ simulations/vip-384/basesepolia.ts | 151 +++++ simulations/vip-384/bsctestnet.ts | 55 ++ src/networkAddresses.ts | 2 + src/types.ts | 5 +- src/vip-framework/index.ts | 1 + vips/vip-384/bsctestnet.ts | 18 - 10 files changed, 1367 insertions(+), 20 deletions(-) create mode 100644 simulations/vip-384/abi/AccessControlManager_ABI.json create mode 100644 simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json create mode 100644 simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json create mode 100644 simulations/vip-384/abi/OmnichainProposalSender.json create mode 100644 simulations/vip-384/basesepolia.ts create mode 100644 simulations/vip-384/bsctestnet.ts diff --git a/simulations/vip-384/abi/AccessControlManager_ABI.json b/simulations/vip-384/abi/AccessControlManager_ABI.json new file mode 100644 index 000000000..92a2de297 --- /dev/null +++ b/simulations/vip-384/abi/AccessControlManager_ABI.json @@ -0,0 +1,157 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "account", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "contractAddress", "type": "address" }, + { "indexed": false, "internalType": "string", "name": "functionSig", "type": "string" } + ], + "name": "PermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "account", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "contractAddress", "type": "address" }, + { "indexed": false, "internalType": "string", "name": "functionSig", "type": "string" } + ], + "name": "PermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "indexed": true, "internalType": "bytes32", "name": "previousAdminRole", "type": "bytes32" }, + { "indexed": true, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32" } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "role", "type": "bytes32" }], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "contractAddress", "type": "address" }, + { "internalType": "string", "name": "functionSig", "type": "string" }, + { "internalType": "address", "name": "accountToPermit", "type": "address" } + ], + "name": "giveCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "contractAddress", "type": "address" }, + { "internalType": "string", "name": "functionSig", "type": "string" } + ], + "name": "hasPermission", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "string", "name": "functionSig", "type": "string" } + ], + "name": "isAllowedToCall", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "contractAddress", "type": "address" }, + { "internalType": "string", "name": "functionSig", "type": "string" }, + { "internalType": "address", "name": "accountToRevoke", "type": "address" } + ], + "name": "revokeCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json b/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json new file mode 100644 index 000000000..bc2097b5e --- /dev/null +++ b/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json @@ -0,0 +1,145 @@ +[ + { + "inputs": [{ "internalType": "address", "name": "omnichainGovernanceExecutor_", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "calledContract", "type": "address" }, + { "internalType": "string", "name": "methodSignature", "type": "string" } + ], + "name": "Unauthorized", + "type": "error" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "string", "name": "signature", "type": "string" }, + { "indexed": false, "internalType": "bool", "name": "active", "type": "bool" } + ], + "name": "FunctionRegistryChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "oldAccessControlManager", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "newAccessControlManager", "type": "address" } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferStarted", + "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" + }, + { "stateMutability": "nonpayable", "type": "fallback" }, + { + "inputs": [], + "name": "OMNICHAIN_GOVERNANCE_EXECUTOR", + "outputs": [{ "internalType": "contract IOmnichainGovernanceExecutor", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [{ "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "name": "functionRegistry", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "srcChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "srcAddress_", "type": "bytes" } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner_", "type": "address" }], + "name": "transferBridgeOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string[]", "name": "signatures_", "type": "string[]" }, + { "internalType": "bool[]", "name": "active_", "type": "bool[]" } + ], + "name": "upsertSignature", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json b/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json new file mode 100644 index 000000000..fffb660db --- /dev/null +++ b/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json @@ -0,0 +1,539 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "endpoint_", "type": "address" }, + { "internalType": "address", "name": "guardian_", "type": "address" }, + { "internalType": "uint16", "name": "srcChainId_", "type": "uint16" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "InvalidProposalId", "type": "error" }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "_srcAddress", "type": "bytes" }, + { "indexed": false, "internalType": "uint64", "name": "_nonce", "type": "uint64" }, + { "indexed": false, "internalType": "bytes", "name": "_payload", "type": "bytes" }, + { "indexed": false, "internalType": "bytes", "name": "_reason", "type": "bytes" } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldGuardian", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newGuardian", "type": "address" } + ], + "name": "NewGuardian", + "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" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "uint256", "name": "id", "type": "uint256" }], + "name": "ProposalCanceled", + "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" }, + { "indexed": false, "internalType": "uint256", "name": "eta", "type": "uint256" } + ], + "name": "ProposalQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "proposalId", "type": "uint256" }, + { "indexed": false, "internalType": "address[]", "name": "targets", "type": "address[]" }, + { "indexed": false, "internalType": "uint256[]", "name": "values", "type": "uint256[]" }, + { "indexed": false, "internalType": "string[]", "name": "signatures", "type": "string[]" }, + { "indexed": false, "internalType": "bytes[]", "name": "calldatas", "type": "bytes[]" }, + { "indexed": false, "internalType": "uint8", "name": "proposalType", "type": "uint8" } + ], + "name": "ProposalReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint16", "name": "srcChainId", "type": "uint16" }, + { "indexed": true, "internalType": "bytes", "name": "srcAddress", "type": "bytes" }, + { "indexed": false, "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "indexed": false, "internalType": "bytes", "name": "reason", "type": "bytes" } + ], + "name": "ReceivePayloadFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "_srcAddress", "type": "bytes" }, + { "indexed": false, "internalType": "uint64", "name": "_nonce", "type": "uint64" }, + { "indexed": false, "internalType": "bytes32", "name": "_payloadHash", "type": "bytes32" } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldMaxLimit", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newMaxLimit", "type": "uint256" } + ], + "name": "SetMaxDailyReceiveLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint16", "name": "_dstChainId", "type": "uint16" }, + { "indexed": false, "internalType": "uint16", "name": "_type", "type": "uint16" }, + { "indexed": false, "internalType": "uint256", "name": "_minDstGas", "type": "uint256" } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "precrime", "type": "address" }], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint16", "name": "oldSrcChainId", "type": "uint16" }, + { "indexed": true, "internalType": "uint16", "name": "newSrcChainId", "type": "uint16" } + ], + "name": "SetSrcChainId", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "", "type": "address" }, + { "indexed": false, "internalType": "uint8", "name": "", "type": "uint8" } + ], + "name": "SetTimelockPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint16", "name": "_remoteChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "_path", "type": "bytes" } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint16", "name": "_remoteChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "_remoteAddress", "type": "bytes" } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint8", "name": "routeType", "type": "uint8" }, + { "indexed": true, "internalType": "address", "name": "oldTimelock", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newTimelock", "type": "address" } + ], + "name": "TimelockAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract ITimelock[]", "name": "timelocks_", "type": "address[]" }], + "name": "addTimelocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "proposalId_", "type": "uint256" }], + "name": "cancel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "proposalId_", "type": "uint256" }], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "", "type": "uint16" }, + { "internalType": "bytes", "name": "", "type": "bytes" }, + { "internalType": "uint64", "name": "", "type": "uint64" } + ], + "name": "failedMessages", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_srcAddress", "type": "bytes" } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_version", "type": "uint16" }, + { "internalType": "uint16", "name": "_chainId", "type": "uint16" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "_configType", "type": "uint256" } + ], + "name": "getConfig", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "_remoteChainId", "type": "uint16" }], + "name": "getTrustedRemoteAddress", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_srcAddress", "type": "bytes" } + ], + "name": "isTrustedRemote", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "last24HourCommandsReceived", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "last24HourReceiveWindowStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastProposalReceived", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [{ "internalType": "contract ILayerZeroEndpoint", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_srcAddress", "type": "bytes" }, + { "internalType": "uint64", "name": "_nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "_payload", "type": "bytes" } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxDailyReceiveLimit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "", "type": "uint16" }, + { "internalType": "uint16", "name": "", "type": "uint16" } + ], + "name": "minDstGasLookup", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_srcChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_srcAddress", "type": "bytes" }, + { "internalType": "uint64", "name": "_nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "_payload", "type": "bytes" } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "payloadSizeLimitLookup", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "proposalTimelocks", + "outputs": [{ "internalType": "contract ITimelock", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "proposals", + "outputs": [ + { "internalType": "uint256", "name": "id", "type": "uint256" }, + { "internalType": "uint256", "name": "eta", "type": "uint256" }, + { "internalType": "bool", "name": "canceled", "type": "bool" }, + { "internalType": "bool", "name": "executed", "type": "bool" }, + { "internalType": "uint8", "name": "proposalType", "type": "uint8" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "queued", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { "internalType": "uint16", "name": "srcChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "srcAddress_", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce_", "type": "uint64" }, + { "internalType": "bytes", "name": "payload_", "type": "bytes" } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_version", "type": "uint16" }, + { "internalType": "uint16", "name": "_chainId", "type": "uint16" }, + { "internalType": "uint256", "name": "_configType", "type": "uint256" }, + { "internalType": "bytes", "name": "_config", "type": "bytes" } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newGuardian", "type": "address" }], + "name": "setGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "limit_", "type": "uint256" }], + "name": "setMaxDailyReceiveLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_dstChainId", "type": "uint16" }, + { "internalType": "uint16", "name": "_packetType", "type": "uint16" }, + { "internalType": "uint256", "name": "_minGas", "type": "uint256" } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_dstChainId", "type": "uint16" }, + { "internalType": "uint256", "name": "_size", "type": "uint256" } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_precrime", "type": "address" }], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "_version", "type": "uint16" }], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "_version", "type": "uint16" }], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "srcChainId_", "type": "uint16" }], + "name": "setSrcChainId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pendingAdmin_", "type": "address" }, + { "internalType": "uint8", "name": "proposalType_", "type": "uint8" } + ], + "name": "setTimelockPendingAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_remoteChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_path", "type": "bytes" } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_remoteChainId", "type": "uint16" }, + { "internalType": "bytes", "name": "_remoteAddress", "type": "bytes" } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "srcChainId", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "proposalId_", "type": "uint256" }], + "name": "state", + "outputs": [{ "internalType": "enum OmnichainGovernanceExecutor.ProposalState", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "trustedRemoteLookup", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" } +] \ No newline at end of file diff --git a/simulations/vip-384/abi/OmnichainProposalSender.json b/simulations/vip-384/abi/OmnichainProposalSender.json new file mode 100644 index 000000000..4112cfed0 --- /dev/null +++ b/simulations/vip-384/abi/OmnichainProposalSender.json @@ -0,0 +1,314 @@ +[ + { + "inputs": [ + { "internalType": "contract ILayerZeroEndpoint", "name": "lzEndpoint_", "type": "address" }, + { "internalType": "address", "name": "accessControlManager_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "proposalId", "type": "uint256" }, + { "indexed": false, "internalType": "bytes32", "name": "executionHash", "type": "bytes32" } + ], + "name": "ClearPayload", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint16", "name": "remoteChainId", "type": "uint16" }, + { "indexed": false, "internalType": "uint256", "name": "proposalId", "type": "uint256" }, + { "indexed": false, "internalType": "bytes", "name": "payload", "type": "bytes" } + ], + "name": "ExecuteRemoteProposal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "receiver", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "FallbackWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldAccessControlManager", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newAccessControlManager", "type": "address" } + ], + "name": "NewAccessControlManager", + "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" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint16", "name": "chainId", "type": "uint16" }, + { "indexed": false, "internalType": "uint256", "name": "oldMaxLimit", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newMaxLimit", "type": "uint256" } + ], + "name": "SetMaxDailyLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint16", "name": "remoteChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "oldRemoteAddress", "type": "bytes" }, + { "indexed": false, "internalType": "bytes", "name": "newRemoteAddress", "type": "bytes" } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "proposalId", "type": "uint256" }, + { "indexed": true, "internalType": "uint16", "name": "remoteChainId", "type": "uint16" }, + { "indexed": false, "internalType": "bytes", "name": "payload", "type": "bytes" }, + { "indexed": false, "internalType": "bytes", "name": "adapterParams", "type": "bytes" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }, + { "indexed": false, "internalType": "bytes", "name": "reason", "type": "bytes" } + ], + "name": "StorePayload", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "uint16", "name": "chainId", "type": "uint16" }], + "name": "TrustedRemoteRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "LZ_ENDPOINT", + "outputs": [{ "internalType": "contract ILayerZeroEndpoint", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "chainIdToLast24HourCommandsSent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "chainIdToLast24HourWindowStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "chainIdToLastProposalSentTimestamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "chainIdToMaxDailyLimit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "payload_", "type": "bytes" }, + { "internalType": "bool", "name": "useZro_", "type": "bool" }, + { "internalType": "bytes", "name": "adapterParams_", "type": "bytes" } + ], + "name": "estimateFees", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "payload_", "type": "bytes" }, + { "internalType": "bytes", "name": "adapterParams_", "type": "bytes" }, + { "internalType": "address", "name": "zroPaymentAddress_", "type": "address" } + ], + "name": "execute", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to_", "type": "address" }, + { "internalType": "uint256", "name": "pId_", "type": "uint256" }, + { "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "payload_", "type": "bytes" }, + { "internalType": "bytes", "name": "adapterParams_", "type": "bytes" }, + { "internalType": "uint256", "name": "originalValue_", "type": "uint256" } + ], + "name": "fallbackWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "version_", "type": "uint16" }, + { "internalType": "uint16", "name": "chainId_", "type": "uint16" }, + { "internalType": "uint256", "name": "configType_", "type": "uint256" } + ], + "name": "getConfig", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposalCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }], + "name": "removeTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { "internalType": "uint256", "name": "pId_", "type": "uint256" }, + { "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "payload_", "type": "bytes" }, + { "internalType": "bytes", "name": "adapterParams_", "type": "bytes" }, + { "internalType": "address", "name": "zroPaymentAddress_", "type": "address" }, + { "internalType": "uint256", "name": "originalValue_", "type": "uint256" } + ], + "name": "retryExecute", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "version_", "type": "uint16" }, + { "internalType": "uint16", "name": "chainId_", "type": "uint16" }, + { "internalType": "uint256", "name": "configType_", "type": "uint256" }, + { "internalType": "bytes", "name": "config_", "type": "bytes" } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "chainId_", "type": "uint16" }, + { "internalType": "uint256", "name": "limit_", "type": "uint256" } + ], + "name": "setMaxDailyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "version_", "type": "uint16" }], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "remoteChainId_", "type": "uint16" }, + { "internalType": "bytes", "name": "newRemoteAddress_", "type": "bytes" } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "storedExecutionHashes", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "name": "trustedRemoteLookup", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" } +] \ No newline at end of file diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts new file mode 100644 index 000000000..512020adb --- /dev/null +++ b/simulations/vip-384/basesepolia.ts @@ -0,0 +1,151 @@ +import { expect } from "chai"; +import { BigNumber, Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId } from "src/types"; +import { expectEvents, getOmnichainProposalSenderAddress } from "src/utils"; +import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/vip-framework"; + +import vip006 from "../../multisig/proposals/basesepolia/vip-006"; +import vip384, { + DEFAULT_ADMIN_ROLE, + ACM, + ACM_AGGREGATOR, + OMNICHAIN_EXECUTOR_OWNER, +} from "../../vips/vip-384/bsctestnet"; +// import ACMAggregator_ABI from "./abi/ACMAggregator.json"; +import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; +import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; +import OMNICHAIN_GOVERNANCE_EXECUTOR_ABI from "./abi/OmnichainGovernanceExecutor_ABI.json"; + +const { basesepolia } = NETWORK_ADDRESSES; +const FAST_TRACK_TIMELOCK = "0x3dFA652D3aaDcb93F9EA7d160d674C441AaA8EE2"; +const CRITICAL_TIMELOCK = "0xbeDb7F2d0617292364bA4D73cf016c0f6BB5542E"; + +forking(18507489, async () => { + const provider = ethers.provider; + let lastProposalReceived: BigNumber; + let executor: Contract; + let executorOwner: Contract; + + before(async () => { + executor = new ethers.Contract( + basesepolia.OMNICHAIN_GOVERNANCE_EXECUTOR, + OMNICHAIN_GOVERNANCE_EXECUTOR_ABI, + provider, + ); + executorOwner = new ethers.Contract(OMNICHAIN_EXECUTOR_OWNER, OMNICHAIN_EXECUTOR_OWNER_ABI, provider); + lastProposalReceived = await executor.lastProposalReceived(); + await pretendExecutingVip(await vip006()); + }); + + describe("Pre-VIP behaviour", async () => { + it("Normal Timelock has default admin role on OP sepolia", async () => { + const acm = await ethers.getContractAt(ACCESS_CONTROL_MANAGER_ABI, ACM); + const hasRole = await acm.hasRole(DEFAULT_ADMIN_ROLE, basesepolia.NORMAL_TIMELOCK); + expect(hasRole).equals(true); + }); + }); + + testForkedNetworkVipCommands("vip384 configures bridge", await vip384(), { + callbackAfterExecution: async txResponse => { + // await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [39]); + // await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [1]); + }, + }); + + describe("Post-VIP behaviour", async () => { + const acm = new ethers.Contract(ACM, ACCESS_CONTROL_MANAGER_ABI, provider); + + it("Proposal id should be incremented", async () => { + expect(await executor.lastProposalReceived()).to.be.equals(lastProposalReceived.add(1)); + }); + it("proposal should be executed", async () => { + const pId = await executor.lastProposalReceived(); + expect(await executor.state(pId)).to.be.equals(2); + }); + it("check configuration", async () => { + // Check Timelock configurations + expect(await executor.proposalTimelocks(0)).equals(basesepolia.NORMAL_TIMELOCK); + expect(await executor.proposalTimelocks(1)).equals(FAST_TRACK_TIMELOCK); + expect(await executor.proposalTimelocks(2)).equals(CRITICAL_TIMELOCK); + + // Check trusted remote + expect(await executor.trustedRemoteLookup(LzChainId.bsctestnet)).equals( + ethers.utils.solidityPack( + ["address", "address"], + [getOmnichainProposalSenderAddress(), basesepolia.OMNICHAIN_GOVERNANCE_EXECUTOR], + ), + ); + + // Check receiving limit + expect(await executor.maxDailyReceiveLimit()).equals(100); + expect(await executor.last24HourCommandsReceived()).equals(4); + + // Check function registry + const functionSignatures: string[] = [ + "forceResumeReceive(uint16,bytes)", + "pause()", + "unpause()", + "setSendVersion(uint16)", + "setReceiveVersion(uint16)", + "setMaxDailyReceiveLimit(uint256)", + "setTrustedRemoteAddress(uint16,bytes)", + "setPrecrime(address)", + "setMinDstGas(uint16,uint16,uint256)", + "setPayloadSizeLimit(uint16,uint256)", + "setConfig(uint16,uint16,uint256,bytes)", + "addTimelocks(ITimelock[])", + "setTimelockPendingAdmin(address,uint8)", + "retryMessage(uint16,bytes,uint64,bytes)", + "setGuardian(address)", + "setSrcChainId(uint16)", + ]; + const getFunctionSelector = (signature: string): string => { + return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).substring(0, 10); + }; + + for (const signature of functionSignatures) { + const selector = getFunctionSelector(signature); + expect(await executorOwner.functionRegistry(selector)).equals(signature); + } + }); + it("Default admin role must be revoked from ACMAggregator contract on OP sepolia", async () => { + expect(await acm.hasRole(DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR)).to.be.false; + }); + it("Guardian and all timelocks are allowed to call retryMessage ", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "retryMessage(uint16,bytes,uint64,bytes)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basesepolia.GUARDIAN)).to.be.true; + expect(await acm.hasRole(roleHash, basesepolia.NORMAL_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.true; + }); + + it("Guardian is allowed to call forceResumeReceive but not timelocks", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "forceResumeReceive(uint16,bytes)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basesepolia.GUARDIAN)).to.be.true; + expect(await acm.hasRole(roleHash, basesepolia.NORMAL_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.false; + }); + it("Normal Timelock is allowed to call setSendVersion but not other timelocks and guardian", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "setSendVersion(uint16)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basesepolia.GUARDIAN)).to.be.false; + expect(await acm.hasRole(roleHash, basesepolia.NORMAL_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.false; + }); + }); +}); \ No newline at end of file diff --git a/simulations/vip-384/bsctestnet.ts b/simulations/vip-384/bsctestnet.ts new file mode 100644 index 000000000..ba485c092 --- /dev/null +++ b/simulations/vip-384/bsctestnet.ts @@ -0,0 +1,55 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId } from "src/types"; +import { expectEvents } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import vip384, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-384/bsctestnet"; +import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; +import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; + +const { basesepolia } = NETWORK_ADDRESSES; +forking(46020691, async () => { + const provider = ethers.provider; + const omnichainProposalSender = new ethers.Contract( + OMNICHAIN_PROPOSAL_SENDER, + OMNICHAIN_PROPOSAL_SENDER_ABI, + provider, + ); + + describe("Pre-VIP behaviour", () => { + it("Daily limit should be 0", async () => { + expect(await omnichainProposalSender.chainIdToMaxDailyLimit(LzChainId.basesepolia)).to.equals(0); + }); + it("Trusted remote should not be set", async () => { + expect(await omnichainProposalSender.trustedRemoteLookup(LzChainId.basesepolia)).to.be.equals("0x"); + }); + }); + + testVip("vip384 give permissions to timelock", await vip384(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [ACCESS_CONTROL_MANAGER_ABI, OMNICHAIN_PROPOSAL_SENDER_ABI], + ["SetMaxDailyLimit", "SetTrustedRemoteAddress", "ExecuteRemoteProposal", "StorePayload"], + [1, 1, 1, 0], + ); + }, + }); + + describe("Post-VIP behavior", () => { + it("Daily limit should be 100 of basesepolia", async () => { + expect(await omnichainProposalSender.chainIdToMaxDailyLimit(LzChainId.basesepolia)).to.equals(MAX_DAILY_LIMIT); + }); + + it("Trusted remote should be set of basesepolia", async () => { + expect(await omnichainProposalSender.trustedRemoteLookup(LzChainId.basesepolia)).to.be.equals( + ethers.utils.solidityPack( + ["address", "address"], + [basesepolia.OMNICHAIN_GOVERNANCE_EXECUTOR, OMNICHAIN_PROPOSAL_SENDER], + ), + ); + }); + }); +}); \ No newline at end of file diff --git a/src/networkAddresses.ts b/src/networkAddresses.ts index 3cc42a050..59569f554 100644 --- a/src/networkAddresses.ts +++ b/src/networkAddresses.ts @@ -220,5 +220,7 @@ export const NETWORK_ADDRESSES = { POOL_REGISTRY: "0xCa330282BEeb07a81963336d0bf8f5f34317916c", NORMAL_TIMELOCK: "0xCc84f6122649eDc48f4a426814e6b6C6fF9bBe0a", OMNICHAIN_GOVERNANCE_EXECUTOR: "0xDD59be81B3B5BFa391bDA3a84c9f5233BfEF52a4", + LZ_LIBRARY: "0x35AdD9321507A87471a11EBd4aE4f592d531e620", + ENDPOINT: "0x55370E0fBB5f5b8dAeD978BA1c075a499eB107B8" }, }; diff --git a/src/types.ts b/src/types.ts index db6dc7195..580a0c9cd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,9 +15,10 @@ export type REMOTE_NETWORKS = | "opbnbtestnet" | "opbnbmainnet" | "arbitrumsepolia" - | "arbitrumone"; + | "arbitrumone" + | "basesepolia"; -export const REMOTE_TESTNET_NETWORKS = ["sepolia", "opbnbtestnet", "arbitrumsepolia", "zksyncsepolia"]; +export const REMOTE_TESTNET_NETWORKS = ["sepolia", "opbnbtestnet", "arbitrumsepolia", "zksyncsepolia", "basesepolia"]; export const REMOTE_MAINNET_NETWORKS = ["ethereum", "opbnbmainnet", "arbitrumone", "zksyncmainnet"]; export interface ProposalMeta { version: string; diff --git a/src/vip-framework/index.ts b/src/vip-framework/index.ts index ff4bc7343..19a867cec 100644 --- a/src/vip-framework/index.ts +++ b/src/vip-framework/index.ts @@ -226,6 +226,7 @@ export const testForkedNetworkVipCommands = (description: string, proposal: Prop ENDPOINT_ABI, provider, ); + const srcAddress = ethers.utils.solidityPack( ["address", "address"], [OMNICHAIN_PROPOSAL_SENDER, OMNICHAIN_GOVERNANCE_EXECUTOR], diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index 5c04d61bd..19e1ef695 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -38,24 +38,6 @@ const vip389 = () => { params: [], dstChainId: LzChainId.basesepolia, }, - { - target: ACM, - signature: "grantRole(bytes32,address)", - params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], - dstChainId: LzChainId.basesepolia, - }, - { - target: ACM_AGGREGATOR, - signature: "executeGrantPermissions(uint256)", - params: [0], - dstChainId: LzChainId.basesepolia, - }, - { - target: ACM, - signature: "revokeRole(bytes32,address)", - params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], - dstChainId: LzChainId.basesepolia, - }, ], meta, ProposalType.REGULAR, From bbbfde39627564d51febf5acfa800a5371a5d4a0 Mon Sep 17 00:00:00 2001 From: web3rover Date: Thu, 28 Nov 2024 17:25:14 +0700 Subject: [PATCH 03/15] fix: fixed simulation --- .../proposals/basesepolia/vip-006/index.ts | 5 +- .../simulations/basesepolia/vip-006/index.ts | 3 +- simulations/vip-384/abi/ACMAggregator.json | 242 ++++++++++++++++++ .../vip-384/abi/AccessControlManager_ABI.json | 2 +- .../abi/OmnichainExecutorOwner_ABI.json | 2 +- .../abi/OmnichainGovernanceExecutor_ABI.json | 2 +- .../vip-384/abi/OmnichainProposalSender.json | 2 +- simulations/vip-384/basesepolia.ts | 14 +- simulations/vip-384/bsctestnet.ts | 2 +- src/networkAddresses.ts | 2 +- vips/vip-384/bsctestnet.ts | 28 +- 11 files changed, 285 insertions(+), 19 deletions(-) create mode 100644 simulations/vip-384/abi/ACMAggregator.json diff --git a/multisig/proposals/basesepolia/vip-006/index.ts b/multisig/proposals/basesepolia/vip-006/index.ts index 588a04a1b..b6a4f296f 100644 --- a/multisig/proposals/basesepolia/vip-006/index.ts +++ b/multisig/proposals/basesepolia/vip-006/index.ts @@ -1,6 +1,7 @@ -import { makeProposal } from "../../../../src/utils"; import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { makeProposal } from "../../../../src/utils"; + const { basesepolia } = NETWORK_ADDRESSES; export const ACM = "0x724138223D8F76b519fdE715f60124E7Ce51e051"; @@ -15,4 +16,4 @@ export const vip007 = () => { }, ]); }; -export default vip007; \ No newline at end of file +export default vip007; diff --git a/multisig/simulations/basesepolia/vip-006/index.ts b/multisig/simulations/basesepolia/vip-006/index.ts index a7249a4c9..f480f902a 100644 --- a/multisig/simulations/basesepolia/vip-006/index.ts +++ b/multisig/simulations/basesepolia/vip-006/index.ts @@ -1,4 +1,3 @@ -import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; import { expect } from "chai"; import { Contract } from "ethers"; import { ethers } from "hardhat"; @@ -36,4 +35,4 @@ forking(18477210, async () => { expect(hasRole).equals(true); }); }); -}); \ No newline at end of file +}); diff --git a/simulations/vip-384/abi/ACMAggregator.json b/simulations/vip-384/abi/ACMAggregator.json new file mode 100644 index 000000000..6650a3f3c --- /dev/null +++ b/simulations/vip-384/abi/ACMAggregator.json @@ -0,0 +1,242 @@ +[ + { + "inputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "_acm", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "EmptyPermissions", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "GrantPermissionsAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "GrantPermissionsExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "RevokePermissionsAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "RevokePermissionsExecuted", + "type": "event" + }, + { + "inputs": [], + "name": "ACM", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "internalType": "struct ACMCommandsAggregator.Permission[]", + "name": "_permissions", + "type": "tuple[]" + } + ], + "name": "addGrantPermissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "internalType": "struct ACMCommandsAggregator.Permission[]", + "name": "_permissions", + "type": "tuple[]" + } + ], + "name": "addRevokePermissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "executeGrantPermissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "executeRevokePermissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "grantPermissions", + "outputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "revokePermissions", + "outputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-384/abi/AccessControlManager_ABI.json b/simulations/vip-384/abi/AccessControlManager_ABI.json index 92a2de297..2ef119947 100644 --- a/simulations/vip-384/abi/AccessControlManager_ABI.json +++ b/simulations/vip-384/abi/AccessControlManager_ABI.json @@ -154,4 +154,4 @@ "stateMutability": "view", "type": "function" } -] \ No newline at end of file +] diff --git a/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json b/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json index bc2097b5e..f75834e6c 100644 --- a/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json +++ b/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json @@ -142,4 +142,4 @@ "stateMutability": "nonpayable", "type": "function" } -] \ No newline at end of file +] diff --git a/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json b/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json index fffb660db..b40c3cf44 100644 --- a/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json +++ b/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json @@ -536,4 +536,4 @@ "type": "function" }, { "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" } -] \ No newline at end of file +] diff --git a/simulations/vip-384/abi/OmnichainProposalSender.json b/simulations/vip-384/abi/OmnichainProposalSender.json index 4112cfed0..66fd4df02 100644 --- a/simulations/vip-384/abi/OmnichainProposalSender.json +++ b/simulations/vip-384/abi/OmnichainProposalSender.json @@ -311,4 +311,4 @@ "type": "function" }, { "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" } -] \ No newline at end of file +] diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 512020adb..286fb265d 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -8,12 +8,12 @@ import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/ import vip006 from "../../multisig/proposals/basesepolia/vip-006"; import vip384, { - DEFAULT_ADMIN_ROLE, ACM, ACM_AGGREGATOR, + DEFAULT_ADMIN_ROLE, OMNICHAIN_EXECUTOR_OWNER, } from "../../vips/vip-384/bsctestnet"; -// import ACMAggregator_ABI from "./abi/ACMAggregator.json"; +import ACMAggregator_ABI from "./abi/ACMAggregator.json"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; import OMNICHAIN_GOVERNANCE_EXECUTOR_ABI from "./abi/OmnichainGovernanceExecutor_ABI.json"; @@ -22,7 +22,7 @@ const { basesepolia } = NETWORK_ADDRESSES; const FAST_TRACK_TIMELOCK = "0x3dFA652D3aaDcb93F9EA7d160d674C441AaA8EE2"; const CRITICAL_TIMELOCK = "0xbeDb7F2d0617292364bA4D73cf016c0f6BB5542E"; -forking(18507489, async () => { +forking(18510243, async () => { const provider = ethers.provider; let lastProposalReceived: BigNumber; let executor: Contract; @@ -49,8 +49,8 @@ forking(18507489, async () => { testForkedNetworkVipCommands("vip384 configures bridge", await vip384(), { callbackAfterExecution: async txResponse => { - // await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [39]); - // await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [1]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); }, }); @@ -80,7 +80,7 @@ forking(18507489, async () => { // Check receiving limit expect(await executor.maxDailyReceiveLimit()).equals(100); - expect(await executor.last24HourCommandsReceived()).equals(4); + expect(await executor.last24HourCommandsReceived()).equals(5); // Check function registry const functionSignatures: string[] = [ @@ -148,4 +148,4 @@ forking(18507489, async () => { expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.false; }); }); -}); \ No newline at end of file +}); diff --git a/simulations/vip-384/bsctestnet.ts b/simulations/vip-384/bsctestnet.ts index ba485c092..0114f4ed8 100644 --- a/simulations/vip-384/bsctestnet.ts +++ b/simulations/vip-384/bsctestnet.ts @@ -52,4 +52,4 @@ forking(46020691, async () => { ); }); }); -}); \ No newline at end of file +}); diff --git a/src/networkAddresses.ts b/src/networkAddresses.ts index 59569f554..e2fbc095e 100644 --- a/src/networkAddresses.ts +++ b/src/networkAddresses.ts @@ -221,6 +221,6 @@ export const NETWORK_ADDRESSES = { NORMAL_TIMELOCK: "0xCc84f6122649eDc48f4a426814e6b6C6fF9bBe0a", OMNICHAIN_GOVERNANCE_EXECUTOR: "0xDD59be81B3B5BFa391bDA3a84c9f5233BfEF52a4", LZ_LIBRARY: "0x35AdD9321507A87471a11EBd4aE4f592d531e620", - ENDPOINT: "0x55370E0fBB5f5b8dAeD978BA1c075a499eB107B8" + ENDPOINT: "0x55370E0fBB5f5b8dAeD978BA1c075a499eB107B8", }, }; diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index 19e1ef695..e0f78d834 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -8,7 +8,7 @@ export const OMNICHAIN_PROPOSAL_SENDER = "0xCfD34AEB46b1CB4779c945854d405E91D27A export const OMNICHAIN_EXECUTOR_OWNER = "0xe3fb08B8817a0c88d39A4DA4eFFD586D3326b73b"; export const ACM = "0x724138223D8F76b519fdE715f60124E7Ce51e051"; export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; -export const ACM_AGGREGATOR = "0xEEeF13364fD22b8eA6932A9ed337e2638f8E0eD6"; +export const ACM_AGGREGATOR = "0xd82A217713F6c61f3ed4199cdEEDfbB80e5E4562"; export const MAX_DAILY_LIMIT = 100; const vip389 = () => { @@ -38,9 +38,33 @@ const vip389 = () => { params: [], dstChainId: LzChainId.basesepolia, }, + { + target: ACM, + signature: "grantRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [0], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [1], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM, + signature: "revokeRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basesepolia, + }, ], meta, ProposalType.REGULAR, ); }; -export default vip389; \ No newline at end of file +export default vip389; From 4015688d7e6c89553193dd590f3635a6c9b2d49e Mon Sep 17 00:00:00 2001 From: web3rover Date: Thu, 28 Nov 2024 18:12:44 +0700 Subject: [PATCH 04/15] fix: fixed prime permissions --- simulations/vip-384/basesepolia.ts | 2 +- vips/vip-384/bsctestnet.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 286fb265d..91860ca0f 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -22,7 +22,7 @@ const { basesepolia } = NETWORK_ADDRESSES; const FAST_TRACK_TIMELOCK = "0x3dFA652D3aaDcb93F9EA7d160d674C441AaA8EE2"; const CRITICAL_TIMELOCK = "0xbeDb7F2d0617292364bA4D73cf016c0f6BB5542E"; -forking(18510243, async () => { +forking(18511708, async () => { const provider = ethers.provider; let lastProposalReceived: BigNumber; let executor: Contract; diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index e0f78d834..16c13eedd 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -47,13 +47,13 @@ const vip389 = () => { { target: ACM_AGGREGATOR, signature: "executeGrantPermissions(uint256)", - params: [0], + params: [1], dstChainId: LzChainId.basesepolia, }, { target: ACM_AGGREGATOR, signature: "executeGrantPermissions(uint256)", - params: [1], + params: [2], dstChainId: LzChainId.basesepolia, }, { From 953bec0bbad954a95121e341ffd4bd6815a56a37 Mon Sep 17 00:00:00 2001 From: web3rover Date: Mon, 2 Dec 2024 23:00:01 +0530 Subject: [PATCH 05/15] fix: fixed permissions --- simulations/vip-384/basesepolia.ts | 2 +- vips/vip-384/bsctestnet.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 91860ca0f..465dc7a89 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -22,7 +22,7 @@ const { basesepolia } = NETWORK_ADDRESSES; const FAST_TRACK_TIMELOCK = "0x3dFA652D3aaDcb93F9EA7d160d674C441AaA8EE2"; const CRITICAL_TIMELOCK = "0xbeDb7F2d0617292364bA4D73cf016c0f6BB5542E"; -forking(18511708, async () => { +forking(18695738, async () => { const provider = ethers.provider; let lastProposalReceived: BigNumber; let executor: Contract; diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index 16c13eedd..96d41c752 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -53,7 +53,7 @@ const vip389 = () => { { target: ACM_AGGREGATOR, signature: "executeGrantPermissions(uint256)", - params: [2], + params: [3], dstChainId: LzChainId.basesepolia, }, { From 3d96b4cd5fdb73adcb4e41ed5ac96b5a35164cd6 Mon Sep 17 00:00:00 2001 From: web3rover <7037606+web3rover@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:50:29 +0530 Subject: [PATCH 06/15] fix: fixed description Co-authored-by: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> --- simulations/vip-384/basesepolia.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 465dc7a89..0d98e6309 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -40,7 +40,7 @@ forking(18695738, async () => { }); describe("Pre-VIP behaviour", async () => { - it("Normal Timelock has default admin role on OP sepolia", async () => { + it("Normal Timelock has default admin role on base sepolia", async () => { const acm = await ethers.getContractAt(ACCESS_CONTROL_MANAGER_ABI, ACM); const hasRole = await acm.hasRole(DEFAULT_ADMIN_ROLE, basesepolia.NORMAL_TIMELOCK); expect(hasRole).equals(true); From f383be6458efbc1ff00863b8dfc35ef534f945c7 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 4 Dec 2024 16:29:36 +0530 Subject: [PATCH 07/15] fix: remove grant permissions --- simulations/vip-384/basesepolia.ts | 6 +++--- vips/vip-384/bsctestnet.ts | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 0d98e6309..a2892a31b 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -49,8 +49,8 @@ forking(18695738, async () => { testForkedNetworkVipCommands("vip384 configures bridge", await vip384(), { callbackAfterExecution: async txResponse => { - await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); - await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [39]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [1]); }, }); @@ -80,7 +80,7 @@ forking(18695738, async () => { // Check receiving limit expect(await executor.maxDailyReceiveLimit()).equals(100); - expect(await executor.last24HourCommandsReceived()).equals(5); + expect(await executor.last24HourCommandsReceived()).equals(4); // Check function registry const functionSignatures: string[] = [ diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index 96d41c752..7808b7ea0 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -50,12 +50,6 @@ const vip389 = () => { params: [1], dstChainId: LzChainId.basesepolia, }, - { - target: ACM_AGGREGATOR, - signature: "executeGrantPermissions(uint256)", - params: [3], - dstChainId: LzChainId.basesepolia, - }, { target: ACM, signature: "revokeRole(bytes32,address)", From 7630d77a5337c90bb5dae7865c6d4b708724cdf8 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 4 Dec 2024 17:18:44 +0530 Subject: [PATCH 08/15] fix: added revoke commands --- simulations/vip-384/basesepolia.ts | 10 ++++++---- vips/vip-384/bsctestnet.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index a2892a31b..17f56e752 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -40,7 +40,7 @@ forking(18695738, async () => { }); describe("Pre-VIP behaviour", async () => { - it("Normal Timelock has default admin role on base sepolia", async () => { + it("Normal Timelock has default admin role on OP sepolia", async () => { const acm = await ethers.getContractAt(ACCESS_CONTROL_MANAGER_ABI, ACM); const hasRole = await acm.hasRole(DEFAULT_ADMIN_ROLE, basesepolia.NORMAL_TIMELOCK); expect(hasRole).equals(true); @@ -49,8 +49,10 @@ forking(18695738, async () => { testForkedNetworkVipCommands("vip384 configures bridge", await vip384(), { callbackAfterExecution: async txResponse => { - await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [39]); - await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [1]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionRevoked"], [60]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["RevokePermissionsExecuted"], [1]); }, }); @@ -80,7 +82,7 @@ forking(18695738, async () => { // Check receiving limit expect(await executor.maxDailyReceiveLimit()).equals(100); - expect(await executor.last24HourCommandsReceived()).equals(4); + expect(await executor.last24HourCommandsReceived()).equals(6); // Check function registry const functionSignatures: string[] = [ diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-384/bsctestnet.ts index 7808b7ea0..f33a0e5af 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-384/bsctestnet.ts @@ -50,6 +50,18 @@ const vip389 = () => { params: [1], dstChainId: LzChainId.basesepolia, }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [3], + dstChainId: LzChainId.basesepolia, + }, + { + target: ACM_AGGREGATOR, + signature: "executeRevokePermissions(uint256)", + params: [2], + dstChainId: LzChainId.basesepolia, + }, { target: ACM, signature: "revokeRole(bytes32,address)", From 8609c4afa54536c03cdfe053142854f4977dffc3 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 4 Dec 2024 21:53:05 +0530 Subject: [PATCH 09/15] fix: fixed description --- simulations/vip-384/basesepolia.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-384/basesepolia.ts index 17f56e752..dd13ecd30 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-384/basesepolia.ts @@ -40,7 +40,7 @@ forking(18695738, async () => { }); describe("Pre-VIP behaviour", async () => { - it("Normal Timelock has default admin role on OP sepolia", async () => { + it("Normal Timelock has default admin role on base sepolia", async () => { const acm = await ethers.getContractAt(ACCESS_CONTROL_MANAGER_ABI, ACM); const hasRole = await acm.hasRole(DEFAULT_ADMIN_ROLE, basesepolia.NORMAL_TIMELOCK); expect(hasRole).equals(true); @@ -112,7 +112,7 @@ forking(18695738, async () => { expect(await executorOwner.functionRegistry(selector)).equals(signature); } }); - it("Default admin role must be revoked from ACMAggregator contract on OP sepolia", async () => { + it("Default admin role must be revoked from ACMAggregator contract on base sepolia", async () => { expect(await acm.hasRole(DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR)).to.be.false; }); it("Guardian and all timelocks are allowed to call retryMessage ", async () => { From cbbaa17a233d39b8bc484b6603067b1f6d166319 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Wed, 4 Dec 2024 17:37:40 +0100 Subject: [PATCH 10/15] chore: move to a new temporary ID to avoid conflicts --- simulations/{vip-384 => vip-501}/abi/ACMAggregator.json | 0 .../{vip-384 => vip-501}/abi/AccessControlManager_ABI.json | 0 .../abi/OmnichainExecutorOwner_ABI.json | 0 .../abi/OmnichainGovernanceExecutor_ABI.json | 0 .../{vip-384 => vip-501}/abi/OmnichainProposalSender.json | 0 simulations/{vip-384 => vip-501}/basesepolia.ts | 6 +++--- simulations/{vip-384 => vip-501}/bsctestnet.ts | 4 ++-- vips/{vip-384 => vip-501}/bsctestnet.ts | 6 +++--- 8 files changed, 8 insertions(+), 8 deletions(-) rename simulations/{vip-384 => vip-501}/abi/ACMAggregator.json (100%) rename simulations/{vip-384 => vip-501}/abi/AccessControlManager_ABI.json (100%) rename simulations/{vip-384 => vip-501}/abi/OmnichainExecutorOwner_ABI.json (100%) rename simulations/{vip-384 => vip-501}/abi/OmnichainGovernanceExecutor_ABI.json (100%) rename simulations/{vip-384 => vip-501}/abi/OmnichainProposalSender.json (100%) rename simulations/{vip-384 => vip-501}/basesepolia.ts (98%) rename simulations/{vip-384 => vip-501}/bsctestnet.ts (92%) rename vips/{vip-384 => vip-501}/bsctestnet.ts (95%) diff --git a/simulations/vip-384/abi/ACMAggregator.json b/simulations/vip-501/abi/ACMAggregator.json similarity index 100% rename from simulations/vip-384/abi/ACMAggregator.json rename to simulations/vip-501/abi/ACMAggregator.json diff --git a/simulations/vip-384/abi/AccessControlManager_ABI.json b/simulations/vip-501/abi/AccessControlManager_ABI.json similarity index 100% rename from simulations/vip-384/abi/AccessControlManager_ABI.json rename to simulations/vip-501/abi/AccessControlManager_ABI.json diff --git a/simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json b/simulations/vip-501/abi/OmnichainExecutorOwner_ABI.json similarity index 100% rename from simulations/vip-384/abi/OmnichainExecutorOwner_ABI.json rename to simulations/vip-501/abi/OmnichainExecutorOwner_ABI.json diff --git a/simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json b/simulations/vip-501/abi/OmnichainGovernanceExecutor_ABI.json similarity index 100% rename from simulations/vip-384/abi/OmnichainGovernanceExecutor_ABI.json rename to simulations/vip-501/abi/OmnichainGovernanceExecutor_ABI.json diff --git a/simulations/vip-384/abi/OmnichainProposalSender.json b/simulations/vip-501/abi/OmnichainProposalSender.json similarity index 100% rename from simulations/vip-384/abi/OmnichainProposalSender.json rename to simulations/vip-501/abi/OmnichainProposalSender.json diff --git a/simulations/vip-384/basesepolia.ts b/simulations/vip-501/basesepolia.ts similarity index 98% rename from simulations/vip-384/basesepolia.ts rename to simulations/vip-501/basesepolia.ts index dd13ecd30..193d01fcf 100644 --- a/simulations/vip-384/basesepolia.ts +++ b/simulations/vip-501/basesepolia.ts @@ -7,12 +7,12 @@ import { expectEvents, getOmnichainProposalSenderAddress } from "src/utils"; import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/vip-framework"; import vip006 from "../../multisig/proposals/basesepolia/vip-006"; -import vip384, { +import vip501, { ACM, ACM_AGGREGATOR, DEFAULT_ADMIN_ROLE, OMNICHAIN_EXECUTOR_OWNER, -} from "../../vips/vip-384/bsctestnet"; +} from "../../vips/vip-501/bsctestnet"; import ACMAggregator_ABI from "./abi/ACMAggregator.json"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; @@ -47,7 +47,7 @@ forking(18695738, async () => { }); }); - testForkedNetworkVipCommands("vip384 configures bridge", await vip384(), { + testForkedNetworkVipCommands("vip501 configures bridge", await vip501(), { callbackAfterExecution: async txResponse => { await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); diff --git a/simulations/vip-384/bsctestnet.ts b/simulations/vip-501/bsctestnet.ts similarity index 92% rename from simulations/vip-384/bsctestnet.ts rename to simulations/vip-501/bsctestnet.ts index 0114f4ed8..dd5e3d6a9 100644 --- a/simulations/vip-384/bsctestnet.ts +++ b/simulations/vip-501/bsctestnet.ts @@ -5,7 +5,7 @@ import { LzChainId } from "src/types"; import { expectEvents } from "src/utils"; import { forking, testVip } from "src/vip-framework"; -import vip384, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-384/bsctestnet"; +import vip501, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-501/bsctestnet"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; @@ -27,7 +27,7 @@ forking(46020691, async () => { }); }); - testVip("vip384 give permissions to timelock", await vip384(), { + testVip("vip501 give permissions to timelock", await vip501(), { callbackAfterExecution: async txResponse => { await expectEvents( txResponse, diff --git a/vips/vip-384/bsctestnet.ts b/vips/vip-501/bsctestnet.ts similarity index 95% rename from vips/vip-384/bsctestnet.ts rename to vips/vip-501/bsctestnet.ts index f33a0e5af..610ed8f0d 100644 --- a/vips/vip-384/bsctestnet.ts +++ b/vips/vip-501/bsctestnet.ts @@ -11,10 +11,10 @@ export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000 export const ACM_AGGREGATOR = "0xd82A217713F6c61f3ed4199cdEEDfbB80e5E4562"; export const MAX_DAILY_LIMIT = 100; -const vip389 = () => { +const vip501 = () => { const meta = { version: "v2", - title: "VIP-389 Enable Multichain Governance on op sepolia", + title: "VIP-501 Enable Multichain Governance on op sepolia", description: `### Summary`, forDescription: "I agree that Venus Protocol should proceed with this proposal", againstDescription: "I do not think that Venus Protocol should proceed with this proposal", @@ -73,4 +73,4 @@ const vip389 = () => { ProposalType.REGULAR, ); }; -export default vip389; +export default vip501; From 4e86f8ffe9b286b8195b043ea57667454ae2fb01 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 4 Dec 2024 23:45:37 +0530 Subject: [PATCH 11/15] fix: updated revoke commands index --- simulations/vip-501/basesepolia.ts | 4 ++-- vips/vip-501/bsctestnet.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/simulations/vip-501/basesepolia.ts b/simulations/vip-501/basesepolia.ts index 193d01fcf..92b4d1402 100644 --- a/simulations/vip-501/basesepolia.ts +++ b/simulations/vip-501/basesepolia.ts @@ -22,7 +22,7 @@ const { basesepolia } = NETWORK_ADDRESSES; const FAST_TRACK_TIMELOCK = "0x3dFA652D3aaDcb93F9EA7d160d674C441AaA8EE2"; const CRITICAL_TIMELOCK = "0xbeDb7F2d0617292364bA4D73cf016c0f6BB5542E"; -forking(18695738, async () => { +forking(18783561, async () => { const provider = ethers.provider; let lastProposalReceived: BigNumber; let executor: Contract; @@ -51,7 +51,7 @@ forking(18695738, async () => { callbackAfterExecution: async txResponse => { await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); - await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionRevoked"], [60]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionRevoked"], [50]); await expectEvents(txResponse, [ACMAggregator_ABI], ["RevokePermissionsExecuted"], [1]); }, }); diff --git a/vips/vip-501/bsctestnet.ts b/vips/vip-501/bsctestnet.ts index 610ed8f0d..710538fa3 100644 --- a/vips/vip-501/bsctestnet.ts +++ b/vips/vip-501/bsctestnet.ts @@ -59,7 +59,7 @@ const vip501 = () => { { target: ACM_AGGREGATOR, signature: "executeRevokePermissions(uint256)", - params: [2], + params: [3], dstChainId: LzChainId.basesepolia, }, { From 29147302a9149591074b384f5f86ff17f1492160 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Tue, 10 Dec 2024 23:48:37 +0530 Subject: [PATCH 12/15] feat: added base mainnet vip --- .../proposals/basemainnet/vip-006/index.ts | 19 + .../vip-006/abi/AccessControlManager.json | 360 ++++++++++++++++++ .../simulations/basemainnet/vip-006/index.ts | 38 ++ simulations/vip-501/basemainnet.ts | 153 ++++++++ simulations/vip-501/bscmainnet.ts | 55 +++ src/networkAddresses.ts | 4 + src/types.ts | 13 +- vips/vip-501/bscmainnet.ts | 76 ++++ 8 files changed, 716 insertions(+), 2 deletions(-) create mode 100644 multisig/proposals/basemainnet/vip-006/index.ts create mode 100644 multisig/simulations/basemainnet/vip-006/abi/AccessControlManager.json create mode 100644 multisig/simulations/basemainnet/vip-006/index.ts create mode 100644 simulations/vip-501/basemainnet.ts create mode 100644 simulations/vip-501/bscmainnet.ts create mode 100644 vips/vip-501/bscmainnet.ts diff --git a/multisig/proposals/basemainnet/vip-006/index.ts b/multisig/proposals/basemainnet/vip-006/index.ts new file mode 100644 index 000000000..3ed62b83b --- /dev/null +++ b/multisig/proposals/basemainnet/vip-006/index.ts @@ -0,0 +1,19 @@ +import { NETWORK_ADDRESSES } from "src/networkAddresses"; + +import { makeProposal } from "../../../../src/utils"; + +const { basemainnet } = NETWORK_ADDRESSES; + +export const ACM = "0x9E6CeEfDC6183e4D0DF8092A9B90cDF659687daB"; +const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; + +export const vip006 = () => { + return makeProposal([ + { + target: ACM, + signature: "grantRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, basemainnet.NORMAL_TIMELOCK], + }, + ]); +}; +export default vip006; diff --git a/multisig/simulations/basemainnet/vip-006/abi/AccessControlManager.json b/multisig/simulations/basemainnet/vip-006/abi/AccessControlManager.json new file mode 100644 index 000000000..4a118fcc4 --- /dev/null +++ b/multisig/simulations/basemainnet/vip-006/abi/AccessControlManager.json @@ -0,0 +1,360 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "PermissionGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "PermissionRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "accountToPermit", + "type": "address" + } + ], + "name": "giveCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "hasPermission", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + } + ], + "name": "isAllowedToCall", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "functionSig", + "type": "string" + }, + { + "internalType": "address", + "name": "accountToRevoke", + "type": "address" + } + ], + "name": "revokeCallPermission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/multisig/simulations/basemainnet/vip-006/index.ts b/multisig/simulations/basemainnet/vip-006/index.ts new file mode 100644 index 000000000..04ea846e0 --- /dev/null +++ b/multisig/simulations/basemainnet/vip-006/index.ts @@ -0,0 +1,38 @@ +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { forking, pretendExecutingVip } from "src/vip-framework/index"; + +import vip006, { ACM } from "../../../proposals/basemainnet/vip-006"; +import ACM_ABI from "./abi/AccessControlManager.json"; + +const { basemainnet } = NETWORK_ADDRESSES; + +forking(23531762, async () => { + let acm: Contract; + let defaultAdminRole: string; + + before(async () => { + acm = await ethers.getContractAt(ACM_ABI, ACM); + defaultAdminRole = await acm.DEFAULT_ADMIN_ROLE(); + }); + + describe("Pre-VIP behaviour", async () => { + it("Normal Timelock does not has default admin role", async () => { + const hasRole = await acm.hasRole(defaultAdminRole, basemainnet.NORMAL_TIMELOCK); + expect(hasRole).equals(false); + }); + }); + + describe("Post-VIP behavior", async () => { + before(async () => { + await pretendExecutingVip(await vip006()); + }); + + it("Normal Timelock has default admin role", async () => { + const hasRole = await acm.hasRole(defaultAdminRole, basemainnet.NORMAL_TIMELOCK); + expect(hasRole).equals(true); + }); + }); +}); diff --git a/simulations/vip-501/basemainnet.ts b/simulations/vip-501/basemainnet.ts new file mode 100644 index 000000000..e0567a56b --- /dev/null +++ b/simulations/vip-501/basemainnet.ts @@ -0,0 +1,153 @@ +import { expect } from "chai"; +import { BigNumber, Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId } from "src/types"; +import { expectEvents, getOmnichainProposalSenderAddress } from "src/utils"; +import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/vip-framework"; + +import vip006 from "../../multisig/proposals/basemainnet/vip-006"; +import vip501, { + ACM, + ACM_AGGREGATOR, + DEFAULT_ADMIN_ROLE, + OMNICHAIN_EXECUTOR_OWNER, +} from "../../vips/vip-501/bscmainnet"; +import ACMAggregator_ABI from "./abi/ACMAggregator.json"; +import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; +import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; +import OMNICHAIN_GOVERNANCE_EXECUTOR_ABI from "./abi/OmnichainGovernanceExecutor_ABI.json"; + +const { basemainnet } = NETWORK_ADDRESSES; +const FAST_TRACK_TIMELOCK = "0x209F73Ee2Fa9A72aF3Fa6aF1933A3B58ed3De5D7"; +const CRITICAL_TIMELOCK = "0x47F65466392ff2aE825d7a170889F7b5b9D8e60D"; + +forking(23531762, async () => { + const provider = ethers.provider; + let lastProposalReceived: BigNumber; + let executor: Contract; + let executorOwner: Contract; + + before(async () => { + executor = new ethers.Contract( + basemainnet.OMNICHAIN_GOVERNANCE_EXECUTOR, + OMNICHAIN_GOVERNANCE_EXECUTOR_ABI, + provider, + ); + executorOwner = new ethers.Contract(OMNICHAIN_EXECUTOR_OWNER, OMNICHAIN_EXECUTOR_OWNER_ABI, provider); + lastProposalReceived = await executor.lastProposalReceived(); + await pretendExecutingVip(await vip006()); + }); + + describe("Pre-VIP behaviour", async () => { + it("Normal Timelock has default admin role on base mainnet", async () => { + const acm = await ethers.getContractAt(ACCESS_CONTROL_MANAGER_ABI, ACM); + const hasRole = await acm.hasRole(DEFAULT_ADMIN_ROLE, basemainnet.NORMAL_TIMELOCK); + expect(hasRole).equals(true); + }); + }); + + testForkedNetworkVipCommands("vip501 configures bridge", await vip501(), { + callbackAfterExecution: async txResponse => { + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [229]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); + await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionRevoked"], [50]); + await expectEvents(txResponse, [ACMAggregator_ABI], ["RevokePermissionsExecuted"], [1]); + }, + }); + + describe("Post-VIP behaviour", async () => { + const acm = new ethers.Contract(ACM, ACCESS_CONTROL_MANAGER_ABI, provider); + + it("Proposal id should be incremented", async () => { + expect(await executor.lastProposalReceived()).to.be.equals(lastProposalReceived.add(1)); + }); + it("proposal should be executed", async () => { + const pId = await executor.lastProposalReceived(); + expect(await executor.state(pId)).to.be.equals(2); + }); + it("check configuration", async () => { + // Check Timelock configurations + expect(await executor.proposalTimelocks(0)).equals(basemainnet.NORMAL_TIMELOCK); + expect(await executor.proposalTimelocks(1)).equals(FAST_TRACK_TIMELOCK); + expect(await executor.proposalTimelocks(2)).equals(CRITICAL_TIMELOCK); + + // Check trusted remote + expect(await executor.trustedRemoteLookup(LzChainId.bscmainnet)).equals( + ethers.utils.solidityPack( + ["address", "address"], + [getOmnichainProposalSenderAddress(), basemainnet.OMNICHAIN_GOVERNANCE_EXECUTOR], + ), + ); + + // Check receiving limit + expect(await executor.maxDailyReceiveLimit()).equals(100); + expect(await executor.last24HourCommandsReceived()).equals(6); + + // Check function registry + const functionSignatures: string[] = [ + "forceResumeReceive(uint16,bytes)", + "pause()", + "unpause()", + "setSendVersion(uint16)", + "setReceiveVersion(uint16)", + "setMaxDailyReceiveLimit(uint256)", + "setTrustedRemoteAddress(uint16,bytes)", + "setPrecrime(address)", + "setMinDstGas(uint16,uint16,uint256)", + "setPayloadSizeLimit(uint16,uint256)", + "setConfig(uint16,uint16,uint256,bytes)", + "addTimelocks(ITimelock[])", + "setTimelockPendingAdmin(address,uint8)", + "retryMessage(uint16,bytes,uint64,bytes)", + "setGuardian(address)", + "setSrcChainId(uint16)", + ]; + const getFunctionSelector = (signature: string): string => { + return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).substring(0, 10); + }; + + for (const signature of functionSignatures) { + const selector = getFunctionSelector(signature); + expect(await executorOwner.functionRegistry(selector)).equals(signature); + } + }); + it("Default admin role must be revoked from ACMAggregator contract on base mainnet", async () => { + expect(await acm.hasRole(DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR)).to.be.false; + }); + it("Guardian and all timelocks are allowed to call retryMessage ", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "retryMessage(uint16,bytes,uint64,bytes)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basemainnet.GUARDIAN)).to.be.true; + expect(await acm.hasRole(roleHash, basemainnet.NORMAL_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.true; + }); + + it("Guardian is allowed to call forceResumeReceive but not timelocks", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "forceResumeReceive(uint16,bytes)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basemainnet.GUARDIAN)).to.be.true; + expect(await acm.hasRole(roleHash, basemainnet.NORMAL_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.false; + }); + it("Normal Timelock is allowed to call setSendVersion but not other timelocks and guardian", async () => { + const role = ethers.utils.solidityPack( + ["address", "string"], + [OMNICHAIN_EXECUTOR_OWNER, "setSendVersion(uint16)"], + ); + const roleHash = ethers.utils.keccak256(role); + expect(await acm.hasRole(roleHash, basemainnet.GUARDIAN)).to.be.false; + expect(await acm.hasRole(roleHash, basemainnet.NORMAL_TIMELOCK)).to.be.true; + expect(await acm.hasRole(roleHash, FAST_TRACK_TIMELOCK)).to.be.false; + expect(await acm.hasRole(roleHash, CRITICAL_TIMELOCK)).to.be.false; + }); + }); +}); diff --git a/simulations/vip-501/bscmainnet.ts b/simulations/vip-501/bscmainnet.ts new file mode 100644 index 000000000..520960f40 --- /dev/null +++ b/simulations/vip-501/bscmainnet.ts @@ -0,0 +1,55 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId } from "src/types"; +import { expectEvents } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import vip501, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-501/bscmainnet"; +import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; +import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; + +const { basemainnet } = NETWORK_ADDRESSES; +forking(44757538, async () => { + const provider = ethers.provider; + const omnichainProposalSender = new ethers.Contract( + OMNICHAIN_PROPOSAL_SENDER, + OMNICHAIN_PROPOSAL_SENDER_ABI, + provider, + ); + + describe("Pre-VIP behaviour", () => { + it("Daily limit should be 0", async () => { + expect(await omnichainProposalSender.chainIdToMaxDailyLimit(LzChainId.basemainnet)).to.equals(0); + }); + it("Trusted remote should not be set", async () => { + expect(await omnichainProposalSender.trustedRemoteLookup(LzChainId.basemainnet)).to.be.equals("0x"); + }); + }); + + testVip("vip501 give permissions to timelock", await vip501(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [ACCESS_CONTROL_MANAGER_ABI, OMNICHAIN_PROPOSAL_SENDER_ABI], + ["SetMaxDailyLimit", "SetTrustedRemoteAddress", "ExecuteRemoteProposal", "StorePayload"], + [1, 1, 1, 0], + ); + }, + }); + + describe("Post-VIP behavior", () => { + it("Daily limit should be 100 of basemainnet", async () => { + expect(await omnichainProposalSender.chainIdToMaxDailyLimit(LzChainId.basemainnet)).to.equals(MAX_DAILY_LIMIT); + }); + + it("Trusted remote should be set of basemainnet", async () => { + expect(await omnichainProposalSender.trustedRemoteLookup(LzChainId.basemainnet)).to.be.equals( + ethers.utils.solidityPack( + ["address", "address"], + [basemainnet.OMNICHAIN_GOVERNANCE_EXECUTOR, OMNICHAIN_PROPOSAL_SENDER], + ), + ); + }); + }); +}); diff --git a/src/networkAddresses.ts b/src/networkAddresses.ts index 50cab37f3..6400e6126 100644 --- a/src/networkAddresses.ts +++ b/src/networkAddresses.ts @@ -251,5 +251,9 @@ export const NETWORK_ADDRESSES = { XVS: "0xebB7873213c8d1d9913D8eA39Aa12d74cB107995", GENERIC_TEST_USER_ACCOUNT: "0x6f057A858171e187124ddEDF034dAc63De5dE5dB", POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F", + NORMAL_TIMELOCK: "0x21c12f2946a1a66cBFf7eb997022a37167eCf517", + OMNICHAIN_GOVERNANCE_EXECUTOR: "0xE7C56EaA4b6eafCe787B3E1AB8BCa0BC6CBDDb9e", + LZ_LIBRARY: "0x38dE71124f7a447a01D67945a51eDcE9FF491251", + ENDPOINT: "0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7", }, }; diff --git a/src/types.ts b/src/types.ts index 811aff5ac..f899b3596 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,7 +10,9 @@ export type SUPPORTED_NETWORKS = | "zksyncsepolia" | "zksyncmainnet" | "opsepolia" - | "opmainnet"; + | "opmainnet" + | "basesepolia" + | "basemainnet"; export type REMOTE_NETWORKS = Exclude; @@ -22,7 +24,14 @@ export const REMOTE_TESTNET_NETWORKS = [ "opsepolia", "basesepolia", ]; -export const REMOTE_MAINNET_NETWORKS = ["ethereum", "opbnbmainnet", "arbitrumone", "zksyncmainnet", "opmainnet"]; +export const REMOTE_MAINNET_NETWORKS = [ + "ethereum", + "opbnbmainnet", + "arbitrumone", + "zksyncmainnet", + "opmainnet", + "basemainnet", +]; export interface ProposalMeta { version: string; diff --git a/vips/vip-501/bscmainnet.ts b/vips/vip-501/bscmainnet.ts new file mode 100644 index 000000000..aad475a49 --- /dev/null +++ b/vips/vip-501/bscmainnet.ts @@ -0,0 +1,76 @@ +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { LzChainId, ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { basemainnet } = NETWORK_ADDRESSES; +export const OMNICHAIN_PROPOSAL_SENDER = "0x36a69dE601381be7b0DcAc5D5dD058825505F8f6"; + +export const OMNICHAIN_EXECUTOR_OWNER = "0x8BA591f72a90fb379b9a82087b190d51b226F0a9"; +export const ACM = "0x9E6CeEfDC6183e4D0DF8092A9B90cDF659687daB"; +export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; +export const ACM_AGGREGATOR = "0xB2770DBD5146f7ee0766Dc9E3931433bb697Aa06"; +export const MAX_DAILY_LIMIT = 100; + +const vip501 = () => { + const meta = { + version: "v2", + title: "VIP-501 Enable Multichain Governance on base mainnet", + description: `### Summary`, + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + return makeProposal( + [ + { + target: OMNICHAIN_PROPOSAL_SENDER, + signature: "setMaxDailyLimit(uint16,uint256)", + params: [LzChainId.basemainnet, MAX_DAILY_LIMIT], + }, + { + target: OMNICHAIN_PROPOSAL_SENDER, + signature: "setTrustedRemoteAddress(uint16,bytes)", + params: [LzChainId.basemainnet, basemainnet.OMNICHAIN_GOVERNANCE_EXECUTOR], + }, + { + target: OMNICHAIN_EXECUTOR_OWNER, + signature: "acceptOwnership()", + params: [], + dstChainId: LzChainId.basemainnet, + }, + { + target: ACM, + signature: "grantRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basemainnet, + }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [0], + dstChainId: LzChainId.basemainnet, + }, + { + target: ACM_AGGREGATOR, + signature: "executeGrantPermissions(uint256)", + params: [1], + dstChainId: LzChainId.basemainnet, + }, + { + target: ACM_AGGREGATOR, + signature: "executeRevokePermissions(uint256)", + params: [0], + dstChainId: LzChainId.basemainnet, + }, + { + target: ACM, + signature: "revokeRole(bytes32,address)", + params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], + dstChainId: LzChainId.basemainnet, + }, + ], + meta, + ProposalType.REGULAR, + ); +}; +export default vip501; From 395204061b7465e9b05e05622301420bcaed2fd1 Mon Sep 17 00:00:00 2001 From: web3rover Date: Mon, 16 Dec 2024 19:58:18 +0530 Subject: [PATCH 13/15] feat: refund venus stars account --- simulations/vip-501/abi/ERC20.json | 289 ++++++++++++++++++++++ simulations/vip-501/abi/VtreasuryAbi.json | 83 +++++++ simulations/vip-501/bscmainnet.ts | 24 +- vips/vip-501/bscmainnet.ts | 11 +- 4 files changed, 405 insertions(+), 2 deletions(-) create mode 100644 simulations/vip-501/abi/ERC20.json create mode 100644 simulations/vip-501/abi/VtreasuryAbi.json diff --git a/simulations/vip-501/abi/ERC20.json b/simulations/vip-501/abi/ERC20.json new file mode 100644 index 000000000..28715d783 --- /dev/null +++ b/simulations/vip-501/abi/ERC20.json @@ -0,0 +1,289 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_initialAmount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_tokenName", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimalUnits", + "type": "uint8" + }, + { + "internalType": "string", + "name": "_tokenSymbol", + "type": "string" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "allocateTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-501/abi/VtreasuryAbi.json b/simulations/vip-501/abi/VtreasuryAbi.json new file mode 100644 index 000000000..df5a655ee --- /dev/null +++ b/simulations/vip-501/abi/VtreasuryAbi.json @@ -0,0 +1,83 @@ +[ + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "tokenAddress", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "withdrawAmount", "type": "uint256" }, + { "indexed": false, "internalType": "address", "name": "withdrawAddress", "type": "address" } + ], + "name": "WithdrawTreasuryBEP20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "withdrawAmount", "type": "uint256" }, + { "indexed": false, "internalType": "address", "name": "withdrawAddress", "type": "address" } + ], + "name": "WithdrawTreasuryBNB", + "type": "event" + }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "tokenAddress", "type": "address" }, + { "internalType": "uint256", "name": "withdrawAmount", "type": "uint256" }, + { "internalType": "address", "name": "withdrawAddress", "type": "address" } + ], + "name": "withdrawTreasuryBEP20", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "uint256", "name": "withdrawAmount", "type": "uint256" }, + { "internalType": "address payable", "name": "withdrawAddress", "type": "address" } + ], + "name": "withdrawTreasuryBNB", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + } +] diff --git a/simulations/vip-501/bscmainnet.ts b/simulations/vip-501/bscmainnet.ts index 520960f40..e4e0ee1d0 100644 --- a/simulations/vip-501/bscmainnet.ts +++ b/simulations/vip-501/bscmainnet.ts @@ -1,13 +1,22 @@ import { expect } from "chai"; +import { BigNumber, Contract } from "ethers"; import { ethers } from "hardhat"; import { NETWORK_ADDRESSES } from "src/networkAddresses"; import { LzChainId } from "src/types"; import { expectEvents } from "src/utils"; import { forking, testVip } from "src/vip-framework"; -import vip501, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-501/bscmainnet"; +import vip501, { + MAX_DAILY_LIMIT, + OMNICHAIN_PROPOSAL_SENDER, + USDT, + USDT_AMOUNT, + VENUS_STARS_TREASURY, +} from "../../vips/vip-501/bscmainnet"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; +import ERC20_ABI from "./abi/ERC20.json"; import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; +import VTREASURY_ABI from "./abi/VtreasuryAbi.json"; const { basemainnet } = NETWORK_ADDRESSES; forking(44757538, async () => { @@ -17,8 +26,15 @@ forking(44757538, async () => { OMNICHAIN_PROPOSAL_SENDER_ABI, provider, ); + let usdt: Contract; + let balanceOfVenusStartsTreasury: BigNumber; describe("Pre-VIP behaviour", () => { + before(async () => { + usdt = new ethers.Contract(USDT, ERC20_ABI, provider); + balanceOfVenusStartsTreasury = await usdt.balanceOf(VENUS_STARS_TREASURY); + }); + it("Daily limit should be 0", async () => { expect(await omnichainProposalSender.chainIdToMaxDailyLimit(LzChainId.basemainnet)).to.equals(0); }); @@ -35,6 +51,7 @@ forking(44757538, async () => { ["SetMaxDailyLimit", "SetTrustedRemoteAddress", "ExecuteRemoteProposal", "StorePayload"], [1, 1, 1, 0], ); + await expectEvents(txResponse, [VTREASURY_ABI], ["WithdrawTreasuryBEP20"], [1]); }, }); @@ -51,5 +68,10 @@ forking(44757538, async () => { ), ); }); + + it("check usdt balance of VenusStartsTreasury", async () => { + const newBalanceOfVenusStartsTreasury = await usdt.balanceOf(VENUS_STARS_TREASURY); + expect(newBalanceOfVenusStartsTreasury).to.equals(balanceOfVenusStartsTreasury.add(USDT_AMOUNT)); + }); }); }); diff --git a/vips/vip-501/bscmainnet.ts b/vips/vip-501/bscmainnet.ts index aad475a49..3ef469836 100644 --- a/vips/vip-501/bscmainnet.ts +++ b/vips/vip-501/bscmainnet.ts @@ -1,8 +1,9 @@ +import { parseUnits } from "ethers/lib/utils"; import { NETWORK_ADDRESSES } from "src/networkAddresses"; import { LzChainId, ProposalType } from "src/types"; import { makeProposal } from "src/utils"; -const { basemainnet } = NETWORK_ADDRESSES; +const { basemainnet, bscmainnet } = NETWORK_ADDRESSES; export const OMNICHAIN_PROPOSAL_SENDER = "0x36a69dE601381be7b0DcAc5D5dD058825505F8f6"; export const OMNICHAIN_EXECUTOR_OWNER = "0x8BA591f72a90fb379b9a82087b190d51b226F0a9"; @@ -10,6 +11,9 @@ export const ACM = "0x9E6CeEfDC6183e4D0DF8092A9B90cDF659687daB"; export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000"; export const ACM_AGGREGATOR = "0xB2770DBD5146f7ee0766Dc9E3931433bb697Aa06"; export const MAX_DAILY_LIMIT = 100; +export const VENUS_STARS_TREASURY = "0xd7ca847Aa074b28A1DfeFfd3B2C3f9780cA96e1D"; +export const USDT = "0x55d398326f99059fF775485246999027B3197955"; +export const USDT_AMOUNT = parseUnits("19938.50", 18); const vip501 = () => { const meta = { @@ -68,6 +72,11 @@ const vip501 = () => { params: [DEFAULT_ADMIN_ROLE, ACM_AGGREGATOR], dstChainId: LzChainId.basemainnet, }, + { + target: bscmainnet.VTREASURY, + signature: "withdrawTreasuryBEP20(address,uint256,address)", + params: [USDT, USDT_AMOUNT, VENUS_STARS_TREASURY], + }, ], meta, ProposalType.REGULAR, From 948154d21fce6db95bcf9f2a7ec9107144dce6af Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Mon, 16 Dec 2024 19:34:40 +0300 Subject: [PATCH 14/15] feat: set id for VIP-408 --- simulations/{vip-501 => vip-408}/abi/ACMAggregator.json | 0 .../{vip-501 => vip-408}/abi/AccessControlManager_ABI.json | 0 simulations/{vip-501 => vip-408}/abi/ERC20.json | 0 .../abi/OmnichainExecutorOwner_ABI.json | 0 .../abi/OmnichainGovernanceExecutor_ABI.json | 0 .../{vip-501 => vip-408}/abi/OmnichainProposalSender.json | 0 simulations/{vip-501 => vip-408}/abi/VtreasuryAbi.json | 0 simulations/{vip-501 => vip-408}/basemainnet.ts | 6 +++--- simulations/{vip-501 => vip-408}/basesepolia.ts | 6 +++--- simulations/{vip-501 => vip-408}/bscmainnet.ts | 6 +++--- simulations/{vip-501 => vip-408}/bsctestnet.ts | 4 ++-- vips/{vip-501 => vip-408}/bscmainnet.ts | 6 +++--- vips/{vip-501 => vip-408}/bsctestnet.ts | 6 +++--- 13 files changed, 17 insertions(+), 17 deletions(-) rename simulations/{vip-501 => vip-408}/abi/ACMAggregator.json (100%) rename simulations/{vip-501 => vip-408}/abi/AccessControlManager_ABI.json (100%) rename simulations/{vip-501 => vip-408}/abi/ERC20.json (100%) rename simulations/{vip-501 => vip-408}/abi/OmnichainExecutorOwner_ABI.json (100%) rename simulations/{vip-501 => vip-408}/abi/OmnichainGovernanceExecutor_ABI.json (100%) rename simulations/{vip-501 => vip-408}/abi/OmnichainProposalSender.json (100%) rename simulations/{vip-501 => vip-408}/abi/VtreasuryAbi.json (100%) rename simulations/{vip-501 => vip-408}/basemainnet.ts (98%) rename simulations/{vip-501 => vip-408}/basesepolia.ts (98%) rename simulations/{vip-501 => vip-408}/bscmainnet.ts (95%) rename simulations/{vip-501 => vip-408}/bsctestnet.ts (92%) rename vips/{vip-501 => vip-408}/bscmainnet.ts (96%) rename vips/{vip-501 => vip-408}/bsctestnet.ts (95%) diff --git a/simulations/vip-501/abi/ACMAggregator.json b/simulations/vip-408/abi/ACMAggregator.json similarity index 100% rename from simulations/vip-501/abi/ACMAggregator.json rename to simulations/vip-408/abi/ACMAggregator.json diff --git a/simulations/vip-501/abi/AccessControlManager_ABI.json b/simulations/vip-408/abi/AccessControlManager_ABI.json similarity index 100% rename from simulations/vip-501/abi/AccessControlManager_ABI.json rename to simulations/vip-408/abi/AccessControlManager_ABI.json diff --git a/simulations/vip-501/abi/ERC20.json b/simulations/vip-408/abi/ERC20.json similarity index 100% rename from simulations/vip-501/abi/ERC20.json rename to simulations/vip-408/abi/ERC20.json diff --git a/simulations/vip-501/abi/OmnichainExecutorOwner_ABI.json b/simulations/vip-408/abi/OmnichainExecutorOwner_ABI.json similarity index 100% rename from simulations/vip-501/abi/OmnichainExecutorOwner_ABI.json rename to simulations/vip-408/abi/OmnichainExecutorOwner_ABI.json diff --git a/simulations/vip-501/abi/OmnichainGovernanceExecutor_ABI.json b/simulations/vip-408/abi/OmnichainGovernanceExecutor_ABI.json similarity index 100% rename from simulations/vip-501/abi/OmnichainGovernanceExecutor_ABI.json rename to simulations/vip-408/abi/OmnichainGovernanceExecutor_ABI.json diff --git a/simulations/vip-501/abi/OmnichainProposalSender.json b/simulations/vip-408/abi/OmnichainProposalSender.json similarity index 100% rename from simulations/vip-501/abi/OmnichainProposalSender.json rename to simulations/vip-408/abi/OmnichainProposalSender.json diff --git a/simulations/vip-501/abi/VtreasuryAbi.json b/simulations/vip-408/abi/VtreasuryAbi.json similarity index 100% rename from simulations/vip-501/abi/VtreasuryAbi.json rename to simulations/vip-408/abi/VtreasuryAbi.json diff --git a/simulations/vip-501/basemainnet.ts b/simulations/vip-408/basemainnet.ts similarity index 98% rename from simulations/vip-501/basemainnet.ts rename to simulations/vip-408/basemainnet.ts index e0567a56b..bdf71d845 100644 --- a/simulations/vip-501/basemainnet.ts +++ b/simulations/vip-408/basemainnet.ts @@ -7,12 +7,12 @@ import { expectEvents, getOmnichainProposalSenderAddress } from "src/utils"; import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/vip-framework"; import vip006 from "../../multisig/proposals/basemainnet/vip-006"; -import vip501, { +import vip408, { ACM, ACM_AGGREGATOR, DEFAULT_ADMIN_ROLE, OMNICHAIN_EXECUTOR_OWNER, -} from "../../vips/vip-501/bscmainnet"; +} from "../../vips/vip-408/bscmainnet"; import ACMAggregator_ABI from "./abi/ACMAggregator.json"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; @@ -47,7 +47,7 @@ forking(23531762, async () => { }); }); - testForkedNetworkVipCommands("vip501 configures bridge", await vip501(), { + testForkedNetworkVipCommands("vip408 configures bridge", await vip408(), { callbackAfterExecution: async txResponse => { await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [229]); await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); diff --git a/simulations/vip-501/basesepolia.ts b/simulations/vip-408/basesepolia.ts similarity index 98% rename from simulations/vip-501/basesepolia.ts rename to simulations/vip-408/basesepolia.ts index 92b4d1402..9eb78ffa4 100644 --- a/simulations/vip-501/basesepolia.ts +++ b/simulations/vip-408/basesepolia.ts @@ -7,12 +7,12 @@ import { expectEvents, getOmnichainProposalSenderAddress } from "src/utils"; import { forking, pretendExecutingVip, testForkedNetworkVipCommands } from "src/vip-framework"; import vip006 from "../../multisig/proposals/basesepolia/vip-006"; -import vip501, { +import vip408, { ACM, ACM_AGGREGATOR, DEFAULT_ADMIN_ROLE, OMNICHAIN_EXECUTOR_OWNER, -} from "../../vips/vip-501/bsctestnet"; +} from "../../vips/vip-408/bsctestnet"; import ACMAggregator_ABI from "./abi/ACMAggregator.json"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_EXECUTOR_OWNER_ABI from "./abi/OmnichainExecutorOwner_ABI.json"; @@ -47,7 +47,7 @@ forking(18783561, async () => { }); }); - testForkedNetworkVipCommands("vip501 configures bridge", await vip501(), { + testForkedNetworkVipCommands("vip408 configures bridge", await vip408(), { callbackAfterExecution: async txResponse => { await expectEvents(txResponse, [ACCESS_CONTROL_MANAGER_ABI], ["PermissionGranted"], [233]); await expectEvents(txResponse, [ACMAggregator_ABI], ["GrantPermissionsExecuted"], [2]); diff --git a/simulations/vip-501/bscmainnet.ts b/simulations/vip-408/bscmainnet.ts similarity index 95% rename from simulations/vip-501/bscmainnet.ts rename to simulations/vip-408/bscmainnet.ts index e4e0ee1d0..81b96e380 100644 --- a/simulations/vip-501/bscmainnet.ts +++ b/simulations/vip-408/bscmainnet.ts @@ -6,13 +6,13 @@ import { LzChainId } from "src/types"; import { expectEvents } from "src/utils"; import { forking, testVip } from "src/vip-framework"; -import vip501, { +import vip408, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER, USDT, USDT_AMOUNT, VENUS_STARS_TREASURY, -} from "../../vips/vip-501/bscmainnet"; +} from "../../vips/vip-408/bscmainnet"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import ERC20_ABI from "./abi/ERC20.json"; import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; @@ -43,7 +43,7 @@ forking(44757538, async () => { }); }); - testVip("vip501 give permissions to timelock", await vip501(), { + testVip("vip408 give permissions to timelock", await vip408(), { callbackAfterExecution: async txResponse => { await expectEvents( txResponse, diff --git a/simulations/vip-501/bsctestnet.ts b/simulations/vip-408/bsctestnet.ts similarity index 92% rename from simulations/vip-501/bsctestnet.ts rename to simulations/vip-408/bsctestnet.ts index dd5e3d6a9..4a3b6bc01 100644 --- a/simulations/vip-501/bsctestnet.ts +++ b/simulations/vip-408/bsctestnet.ts @@ -5,7 +5,7 @@ import { LzChainId } from "src/types"; import { expectEvents } from "src/utils"; import { forking, testVip } from "src/vip-framework"; -import vip501, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-501/bsctestnet"; +import vip408, { MAX_DAILY_LIMIT, OMNICHAIN_PROPOSAL_SENDER } from "../../vips/vip-408/bsctestnet"; import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager_ABI.json"; import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; @@ -27,7 +27,7 @@ forking(46020691, async () => { }); }); - testVip("vip501 give permissions to timelock", await vip501(), { + testVip("vip408 give permissions to timelock", await vip408(), { callbackAfterExecution: async txResponse => { await expectEvents( txResponse, diff --git a/vips/vip-501/bscmainnet.ts b/vips/vip-408/bscmainnet.ts similarity index 96% rename from vips/vip-501/bscmainnet.ts rename to vips/vip-408/bscmainnet.ts index 3ef469836..b5ab6b690 100644 --- a/vips/vip-501/bscmainnet.ts +++ b/vips/vip-408/bscmainnet.ts @@ -15,10 +15,10 @@ export const VENUS_STARS_TREASURY = "0xd7ca847Aa074b28A1DfeFfd3B2C3f9780cA96e1D" export const USDT = "0x55d398326f99059fF775485246999027B3197955"; export const USDT_AMOUNT = parseUnits("19938.50", 18); -const vip501 = () => { +const vip408 = () => { const meta = { version: "v2", - title: "VIP-501 Enable Multichain Governance on base mainnet", + title: "VIP-408 Enable Multichain Governance on base mainnet", description: `### Summary`, forDescription: "I agree that Venus Protocol should proceed with this proposal", againstDescription: "I do not think that Venus Protocol should proceed with this proposal", @@ -82,4 +82,4 @@ const vip501 = () => { ProposalType.REGULAR, ); }; -export default vip501; +export default vip408; diff --git a/vips/vip-501/bsctestnet.ts b/vips/vip-408/bsctestnet.ts similarity index 95% rename from vips/vip-501/bsctestnet.ts rename to vips/vip-408/bsctestnet.ts index 710538fa3..4fd793cff 100644 --- a/vips/vip-501/bsctestnet.ts +++ b/vips/vip-408/bsctestnet.ts @@ -11,10 +11,10 @@ export const DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000 export const ACM_AGGREGATOR = "0xd82A217713F6c61f3ed4199cdEEDfbB80e5E4562"; export const MAX_DAILY_LIMIT = 100; -const vip501 = () => { +const vip408 = () => { const meta = { version: "v2", - title: "VIP-501 Enable Multichain Governance on op sepolia", + title: "VIP-408 Enable Multichain Governance on base sepolia", description: `### Summary`, forDescription: "I agree that Venus Protocol should proceed with this proposal", againstDescription: "I do not think that Venus Protocol should proceed with this proposal", @@ -73,4 +73,4 @@ const vip501 = () => { ProposalType.REGULAR, ); }; -export default vip501; +export default vip408; From f7f352bcdcfd1ff2497b6d75021ac5f123aaabbf Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Mon, 16 Dec 2024 19:38:02 +0300 Subject: [PATCH 15/15] feat: add title and description for VIP-408 --- vips/vip-408/bscmainnet.ts | 132 +++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 5 deletions(-) diff --git a/vips/vip-408/bscmainnet.ts b/vips/vip-408/bscmainnet.ts index b5ab6b690..5876a89c0 100644 --- a/vips/vip-408/bscmainnet.ts +++ b/vips/vip-408/bscmainnet.ts @@ -18,11 +18,133 @@ export const USDT_AMOUNT = parseUnits("19938.50", 18); const vip408 = () => { const meta = { version: "v2", - title: "VIP-408 Enable Multichain Governance on base mainnet", - description: `### Summary`, - forDescription: "I agree that Venus Protocol should proceed with this proposal", - againstDescription: "I do not think that Venus Protocol should proceed with this proposal", - abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + title: "VIP-408 [Base] Markets, Prime and Omnichain Governance", + description: `#### Summary + +If passed, this VIP will perform the following actions: + +- Configure the Venus markets on Base, for [cbBTC](https://basescan.org/address/0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf), [WETH](https://basescan.org/address/0x4200000000000000000000000000000000000006) and [USDC](https://basescan.org/token/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) +- Configure the [ProtocolShareReserve](https://basescan.org/address/0x3565001d57c91062367C3792B74458e3c6eD910a) contract on Base +- Configure the [NativeTokenGateway](https://basescan.org/address/0x8e890ca3829c740895cdEACd4a3BE36ff9343643) contact for the Venus market of WETH, accepting deposits and withdrawals of ETH +- Configure the [Prime](https://basescan.org/address/0xD2e84244f1e9Fca03Ff024af35b8f9612D5d7a30) contract on Base, allowing users to stake XVS into the XVSVault to start their qualification period +- Enable the Omnichain Governance system on the Venus protocol, for Base. Omnichain Governance will allow the Venus Community to propose VIP’s on BNB Chain including commands to be executed on Base + +#### Description + +Following the [Chaos labs recommendations](https://community.venus.io/t/deploy-venus-on-base/4630/13), if passed, this VIP will enable the following Venus markets on Base: + +Underlying token: [cbBTC](https://basescan.org/address/0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf) + +- Borrow cap: 200 +- Supply cap: 400 +- Collateral factor: 0.73 +- Liquidation threshold: 0.78 +- Reserve factor: 0.2 +- Bootstrap liquidity: 0.05 cbBTC - provided by the Venus Treasury +- Interest rate curve: + - kink: 0.45 + - base (yearly): 0 + - multiplier (yearly): 0.15 + - jump multiplier (yearly): 2.5 + +Underlying token: [WETH](https://basescan.org/address/0x4200000000000000000000000000000000000006) + +- Borrow cap: 9,000 +- Supply cap: 10,000 +- Collateral factor: 0.8 +- Liquidation threshold: 0.83 +- Reserve factor: 0.15 +- Bootstrap liquidity: 2 WETH - provided by the Venus Treasury +- Interest rate curve: + - kink: 0.9 + - base (yearly): 0 + - multiplier (yearly): 0.03 + - jump multiplier (yearly): 4.5 + +Underlying token: [USDC](https://basescan.org/token/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) + +- Borrow cap: 27,000,000 +- Supply cap: 30,000,000 +- Collateral factor: 0.75 +- Liquidation threshold: 0.78 +- Reserve factor: 0.1 +- Bootstrap liquidity: 5,000 USDC - provided by the Venus Treasury +- Interest rate curve: + - kink: 0.8 + - base (yearly): 0 + - multiplier (yearly): 0.08 + - jump multiplier (yearly): 2.5 + +Initial risk parameters for the new pool: + +- Close factor: 50% +- Liquidation incentive: 10% + +Regarding the bootstrap liquidity for the new markets, this VIP will refund 0xd7ca847Aa074b28A1DfeFfd3B2C3f9780cA96e1D with $19,938.50 USDT on BNB Chain, to compensate the provision for [USDC](https://basescan.org/tx/0x84117a3a66a63ba784c07a096b51901eeb7bb0b0ba38f686ad1ab591218730c3), [cbBTC](https://basescan.org/tx/0x7e3021c203b8430d014e678094c59b4e3f7e00966cb241e1c684080c56bcba2c) and [WETH](https://basescan.org/tx/0x4d6fde66b30be733f643a3bebe60b102833160397bbfdeec1de1cdbcbf617c71) on Base and ETH on BNB Chain. + +This VIP will grant permissions to Normal, Fast-track and Critical timelocks on BNB chain to create remote VIP’s on Base. It also performs the necessary configuration of OmnichainProposalSender on BNB Chain and OmnichainProposalExecutor on Base (set the trustworthiness relationships, configure limits, accept ownerships). + +#### Security and additional considerations + +We applied the following security procedures for this upgrade: + +- **VIP execution simulation**: in a simulation environment, checking ownership of the contracts and validating the usual operations on the markets +- **Deployment on testnet**: the same contracts have been deployed to testnet, and used in the Venus Protocol testnet deployment +- **Audit:** [Certik](https://www.certik.com/), [Quantstamp](https://quantstamp.com/) and [Fairyproof](https://fairyproof.com/) have audited the code specific for Base. [OpenZeppelin](https://www.openzeppelin.com/), [Quantstamp](https://quantstamp.com/), [Cantina](https://cantina.xyz/) and [Certik](https://www.certik.com/) have audited the Omnichain Governance contracts. + +#### Audit reports + +- Time base contracts: + - [Certik audit audit report](https://github.com/VenusProtocol/isolated-pools/blob/aa1f7ae61b07839231ec16e9c4143905785d7aae/audits/088_timeBased_certik_20240117.pdf) (2024/01/17) + - [Quantstamp audit audit report](https://github.com/VenusProtocol/isolated-pools/blob/470416836922656783eab52ded54744489e8c345/audits/089_timeBased_quantstamp_20240319.pdf) (2024/03/19) + - [Fairyproof audit report](https://github.com/VenusProtocol/isolated-pools/blob/aa1f7ae61b07839231ec16e9c4143905785d7aae/audits/094_timeBased_fairyproof_20240304.pdf) (2024/03/04) +- Omnichain Governance: + - [Openzepplin audit report - 2024/01/19](https://github.com/VenusProtocol/governance-contracts/blob/feat/ven-1918/audits/084_multichainGovernance_openzeppelin_20240119.pdf) + - [Quantstamp audit report - 2024/04/29](https://github.com/VenusProtocol/governance-contracts/blob/feat/ven-1918/audits/106_multichainGovernance_quantstamp_20240429.pdf) + - [Cantina audit report - 2024/04/25](https://github.com/VenusProtocol/governance-contracts/blob/feat/ven-1918/audits/105_multichainGovernance_cantina_20240425.pdf) + - [Certik audit report - 2024/02/26](https://github.com/VenusProtocol/governance-contracts/blob/feat/ven-1918/audits/085_multichainGovernance_certik_20240226.pdf) + - [Certik audit report of ACMCommandsAggregator - 2024/10/07](https://github.com/VenusProtocol/governance-contracts/blob/3a5a2740e86c9137ab17f4f3939c97b145a22803/audits/118_ACMCommandsAggregator_certik_20241007.pdf) + +#### Deployed contracts on Base + +- Pool registry: [0xeef902918DdeCD773D4B422aa1C6e1673EB9136F](https://basescan.org/address/0xeef902918DdeCD773D4B422aa1C6e1673EB9136F) +- Comptroller: [0x0C7973F9598AA62f9e03B94E92C967fD5437426C](https://basescan.org/address/0x0C7973F9598AA62f9e03B94E92C967fD5437426C) +- Markets: + - vcbBTC_Core: [0x7bBd1005bB24Ec84705b04e1f2DfcCad533b6D72](https://basescan.org/address/0x7bBd1005bB24Ec84705b04e1f2DfcCad533b6D72) + - vWETH_Core: [0xEB8A79bD44cF4500943bf94a2b4434c95C008599](https://basescan.org/address/0xEB8A79bD44cF4500943bf94a2b4434c95C008599) + - vUSDC_Core: [0x3cb752d175740043Ec463673094e06ACDa2F9a2e](https://basescan.org/address/0x3cb752d175740043Ec463673094e06ACDa2F9a2e) +- [ProtocolShareReserve](https://basescan.org/address/0x3565001d57c91062367C3792B74458e3c6eD910a) +- [NativeTokenGateway](https://basescan.org/address/0x8e890ca3829c740895cdEACd4a3BE36ff9343643) +- [Prime](https://basescan.org/address/0xD2e84244f1e9Fca03Ff024af35b8f9612D5d7a30) +- [PrimeLiquidityProvider](https://basescan.org/address/0xcB293EB385dEFF2CdeDa4E7060974BB90ee0B208) +- Omnichain Governance: + - Normal Timelock: [0x21c12f2946a1a66cBFf7eb997022a37167eCf517](https://basescan.org/address/0x21c12f2946a1a66cBFf7eb997022a37167eCf517) + - FastTrack Timelock: [0x209F73Ee2Fa9A72aF3Fa6aF1933A3B58ed3De5D7](https://basescan.org/address/0x209F73Ee2Fa9A72aF3Fa6aF1933A3B58ed3De5D7) + - Critical Timelock: [0x47F65466392ff2aE825d7a170889F7b5b9D8e60D](https://basescan.org/address/0x47F65466392ff2aE825d7a170889F7b5b9D8e60D) + - Omnichain Governance Executor: [0xE7C56EaA4b6eafCe787B3E1AB8BCa0BC6CBDDb9e](https://basescan.org/address/0xE7C56EaA4b6eafCe787B3E1AB8BCa0BC6CBDDb9e) + - Omnichain Executor Owner Proxy: [0x8BA591f72a90fb379b9a82087b190d51b226F0a9](https://basescan.org/address/0x8BA591f72a90fb379b9a82087b190d51b226F0a9) + - ACMCommandsAggregator: [0xB2770DBD5146f7ee0766Dc9E3931433bb697Aa06](https://basescan.org/address/0xB2770DBD5146f7ee0766Dc9E3931433bb697Aa06) + +#### References + +- VIP simulations: + - [ProtocolShareReserve and NativeTokenGateway](https://github.com/VenusProtocol/vips/pull/426) + - [Markets](https://github.com/VenusProtocol/vips/pull/427) + - [Prime](https://github.com/VenusProtocol/vips/pull/432) + - [Omnichain Governance](https://github.com/VenusProtocol/vips/pull/433) +- [Deploy Venus on Base](https://community.venus.io/t/deploy-venus-on-base/4630) +- Snapshot ["Deploy Venus on Base"](https://snapshot.box/#/s:venus-xvs.eth/proposal/0x353f5fb23ff895d89c21271ea1904af65e60557aeec317b24ce56d728d29b8c1) +- [Code of Omnichain Governance](https://github.com/VenusProtocol/governance-contracts/pull/21) +- [Documentation - Technical article with more details of the Omnichain Governance feature](https://docs-v4.venus.io/technical-reference/reference-technical-articles/multichain-governance) +- [Documentation](https://docs-v4.venus.io/) + +#### Disclaimer for Base VIPs + +Privilege commands on Base will be executed by the [Guardian wallet](https://basescan.org/address/0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C), until the [Multichain Governance](https://docs-v4.venus.io/technical-reference/reference-technical-articles/multichain-governance) contracts are fully enabled. If this VIP passes, [this](https://app.safe.global/transactions/tx?safe=base:0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C&id=multisig_0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C_0x5514a6ee48bc5a0ab6db631bdc26d69fad62174905bf8f12580a1532c642b300), [this](https://app.safe.global/transactions/tx?safe=base:0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C&id=multisig_0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C_0xdf161ff5e3e1deef14f376ffb72bec2243cd8bf77589fa82290e439d09999aed), [this](https://app.safe.global/transactions/tx?safe=base:0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C&id=multisig_0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C_0xb5f6aaf6aae7b82536aadaac4c68e30a62afcfa51274921ffaabffef2eed2e97) and [this](https://app.safe.global/transactions/tx?safe=base:0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C&id=multisig_0x1803Cf1D3495b43cC628aa1d8638A981F8CD341C_0x532c631053e4f4e926ab78492f6b3263cd4f4785a7d4df2a667e80ae7e1fc65f) multisig transactions will be executed. Otherwise, they will be rejected. +`, + forDescription: "Execute this proposal", + againstDescription: "Do not execute this proposal", + abstainDescription: "Indifferent to execution", }; return makeProposal( [