From 23ea544c29c9fc07ad606e8f58bfa9be85af7b19 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 20:28:35 -0700 Subject: [PATCH 1/4] fix(governance): replace multisig to operator --- .../governance/AxelarServiceGovernance.sol | 34 ++++++------ .../interfaces/IAxelarServiceGovernance.sol | 12 ++--- test/governance/AxelarServiceGovernance.js | 54 +++++++++---------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/contracts/governance/AxelarServiceGovernance.sol b/contracts/governance/AxelarServiceGovernance.sol index 158ee1bd..24405513 100644 --- a/contracts/governance/AxelarServiceGovernance.sol +++ b/contracts/governance/AxelarServiceGovernance.sol @@ -18,17 +18,17 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan CancelMultisigApproval } - address public multisig; + address public operator; mapping(bytes32 => bool) public multisigApprovals; - modifier onlyMultisig() { - if (msg.sender != multisig) revert NotAuthorized(); + modifier onlyOperator() { + if (msg.sender != operator) revert NotAuthorized(); _; } - modifier onlyMultisigOrSelf() { - if (msg.sender != multisig && msg.sender != address(this)) revert NotAuthorized(); + modifier onlyOperatorOrSelf() { + if (msg.sender != operator && msg.sender != address(this)) revert NotAuthorized(); _; } @@ -38,17 +38,17 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan * @param governanceChain_ The name of the governance chain * @param governanceAddress_ The address of the governance contract * @param minimumTimeDelay The minimum time delay for timelock operations - * @param multisig_ The multisig contract address + * @param operator_ The operator address */ constructor( address gateway_, string memory governanceChain_, string memory governanceAddress_, uint256 minimumTimeDelay, - address multisig_ + address operator_ ) InterchainGovernance(gateway_, governanceChain_, governanceAddress_, minimumTimeDelay) { - if (multisig_ == address(0)) revert InvalidMultisigAddress(); - multisig = multisig_; + if (operator_ == address(0)) revert InvalidOperatorAddress(); + operator = operator_; } /** @@ -76,7 +76,7 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan address target, bytes calldata callData, uint256 nativeValue - ) external payable onlyMultisig { + ) external payable onlyOperator { bytes32 proposalHash = _getProposalHash(target, callData, nativeValue); if (!multisigApprovals[proposalHash]) revert NotApproved(); @@ -89,16 +89,16 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan } /** - * @notice Transfers the multisig address to a new address - * @dev Only the current multisig or the governance can call this function - * @param newMultisig The new multisig address + * @notice Transfers the operator address to a new address + * @dev Only the current operator or the governance can call this function + * @param newOperator The new operator address */ - function transferMultisig(address newMultisig) external onlyMultisigOrSelf { - if (newMultisig == address(0)) revert InvalidMultisigAddress(); + function transferOperator(address newOperator) external onlyOperatorOrSelf { + if (newOperator == address(0)) revert InvalidOperatorAddress(); - emit MultisigTransferred(multisig, newMultisig); + emit OperatorTransferred(operator, newOperator); - multisig = newMultisig; + operator = newOperator; } /** diff --git a/contracts/interfaces/IAxelarServiceGovernance.sol b/contracts/interfaces/IAxelarServiceGovernance.sol index 3d632a03..b3708a4f 100644 --- a/contracts/interfaces/IAxelarServiceGovernance.sol +++ b/contracts/interfaces/IAxelarServiceGovernance.sol @@ -9,7 +9,7 @@ import { IInterchainGovernance } from './IInterchainGovernance.sol'; * @dev This interface extends IInterchainGovernance and IMultisigBase for multisig proposal actions */ interface IAxelarServiceGovernance is IInterchainGovernance { - error InvalidMultisigAddress(); + error InvalidOperatorAddress(); error NotApproved(); error NotAuthorized(); @@ -34,7 +34,7 @@ interface IAxelarServiceGovernance is IInterchainGovernance { uint256 nativeValue ); - event MultisigTransferred(address indexed oldMultisig, address indexed newMultisig); + event OperatorTransferred(address indexed oldOperator, address indexed newOperator); /** * @notice Returns whether a multisig proposal has been approved @@ -68,9 +68,9 @@ interface IAxelarServiceGovernance is IInterchainGovernance { ) external payable; /** - * @notice Transfers the multisig address to a new address - * @dev Only the current multisig or the governance can call this function - * @param newMultisig The new multisig address + * @notice Transfers the operator address to a new address + * @dev Only the current operator or the governance can call this function + * @param newOperator The new operator address */ - function transferMultisig(address newMultisig) external; + function transferOperator(address newOperator) external; } diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index e4ddb38a..3a7caf6a 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -13,7 +13,7 @@ describe('AxelarServiceGovernance', () => { let ownerWallet; let governanceAddress; let gateway; - let multisig; + let operator; let serviceGovernanceFactory; let serviceGovernance; @@ -36,7 +36,7 @@ describe('AxelarServiceGovernance', () => { const InvalidCommand = 4; before(async () => { - [ownerWallet, governanceAddress, multisig] = await ethers.getSigners(); + [ownerWallet, governanceAddress, operator] = await ethers.getSigners(); serviceGovernanceFactory = await ethers.getContractFactory('AxelarServiceGovernance', ownerWallet); targetFactory = await ethers.getContractFactory('Target', ownerWallet); @@ -51,7 +51,7 @@ describe('AxelarServiceGovernance', () => { calldata = targetInterface.encodeFunctionData('callTarget'); serviceGovernance = await serviceGovernanceFactory - .deploy(gateway.address, governanceChain, governanceAddress.address, minimumTimeDelay, multisig.address) + .deploy(gateway.address, governanceChain, governanceAddress.address, minimumTimeDelay, operator.address) .then((d) => d.deployed()); }); @@ -59,10 +59,10 @@ describe('AxelarServiceGovernance', () => { expect(await serviceGovernance.gateway()).to.equal(gateway.address); expect(await serviceGovernance.governanceChain()).to.equal(governanceChain); expect(await serviceGovernance.governanceAddress()).to.equal(governanceAddress.address); - expect(await serviceGovernance.multisig()).to.equal(multisig.address); + expect(await serviceGovernance.operator()).to.equal(operator.address); }); - it('should revert on invalid multisig address', async () => { + it('should revert on invalid operator address', async () => { await expectRevert( async (gasOptions) => serviceGovernanceFactory.deploy( @@ -74,15 +74,15 @@ describe('AxelarServiceGovernance', () => { gasOptions, ), serviceGovernanceFactory, - 'InvalidMultisigAddress', + 'InvalidOperatorAddress', ); }); - it('should revert on invalid multisig transfer', async () => { + it('should revert on invalid operator transfer', async () => { await expectRevert( - async (gasOptions) => serviceGovernance.connect(multisig).transferMultisig(AddressZero, gasOptions), + async (gasOptions) => serviceGovernance.connect(operator).transferOperator(AddressZero, gasOptions), serviceGovernance, - 'InvalidMultisigAddress', + 'InvalidOperatorAddress', ); }); @@ -228,7 +228,7 @@ describe('AxelarServiceGovernance', () => { it('should revert on executing a multisig proposal if proposal is not approved', async () => { await expectRevert( async (gasOptions) => - serviceGovernance.connect(multisig).executeMultisigProposal(target, calldata, 0, gasOptions), + serviceGovernance.connect(operator).executeMultisigProposal(target, calldata, 0, gasOptions), serviceGovernance, 'NotApproved', ); @@ -256,7 +256,7 @@ describe('AxelarServiceGovernance', () => { await expectRevert( async (gasOptions) => - serviceGovernance.connect(multisig).executeMultisigProposal(target, invalidCalldata, nativeValue, { + serviceGovernance.connect(operator).executeMultisigProposal(target, invalidCalldata, nativeValue, { value: nativeValue, ...gasOptions, }), @@ -282,7 +282,7 @@ describe('AxelarServiceGovernance', () => { await expect( serviceGovernance - .connect(multisig) + .connect(operator) .executeMultisigProposal(target, calldata, nativeValue, { value: nativeValue }), ) .to.emit(serviceGovernance, 'MultisigExecuted') @@ -341,7 +341,7 @@ describe('AxelarServiceGovernance', () => { const oldBalance = await ethers.provider.getBalance(target); - const tx = await serviceGovernance.connect(multisig).executeMultisigProposal(target, calldata, nativeValue); + const tx = await serviceGovernance.connect(operator).executeMultisigProposal(target, calldata, nativeValue); await expect(tx) .to.emit(serviceGovernance, 'MultisigExecuted') @@ -352,15 +352,15 @@ describe('AxelarServiceGovernance', () => { expect(newBalance).to.equal(oldBalance.add(nativeValue)); }); - it('should transfer multisig address to new address', async () => { - const newMultisig = governanceAddress.address; - await expect(serviceGovernance.connect(multisig).transferMultisig(newMultisig)) - .to.emit(serviceGovernance, 'MultisigTransferred') - .withArgs(multisig.address, newMultisig); - await expect(await serviceGovernance.multisig()).to.equal(newMultisig); + it('should transfer operator address to new address', async () => { + const newOperator = governanceAddress.address; + await expect(serviceGovernance.connect(operator).transferOperator(newOperator)) + .to.emit(serviceGovernance, 'OperatorTransferred') + .withArgs(operator.address, newOperator); + await expect(await serviceGovernance.operator()).to.equal(newOperator); await expectRevert( - async (gasOptions) => serviceGovernance.connect(multisig).transferMultisig(newMultisig, gasOptions), + async (gasOptions) => serviceGovernance.connect(operator).transferOperator(newOperator, gasOptions), serviceGovernance, 'NotAuthorized', ); @@ -368,8 +368,8 @@ describe('AxelarServiceGovernance', () => { it('should transfer multisig by a governance proposal', async () => { const govCommandID = formatBytes32String('10'); - const newMultisig = serviceGovernance.address; - const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferMultisig', [newMultisig]); + const newOperator = serviceGovernance.address; + const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferOperator', [newOperator]); const [payload, proposalHash, eta] = await getPayloadAndProposalHash( ScheduleTimeLockProposal, @@ -393,14 +393,14 @@ describe('AxelarServiceGovernance', () => { await expect(tx) .to.emit(serviceGovernance, 'ProposalExecuted') .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, executionTimestamp) - .and.to.emit(serviceGovernance, 'MultisigTransferred') - .withArgs(governanceAddress.address, newMultisig); + .and.to.emit(serviceGovernance, 'OperatorTransferred') + .withArgs(governanceAddress.address, newOperator); - await expect(await serviceGovernance.multisig()).to.equal(newMultisig); + await expect(await serviceGovernance.operator()).to.equal(newOperator); await expectRevert( async (gasOptions) => - serviceGovernance.connect(governanceAddress).transferMultisig(newMultisig, gasOptions), + serviceGovernance.connect(governanceAddress).transferOperator(newOperator, gasOptions), serviceGovernance, 'NotAuthorized', ); @@ -411,7 +411,7 @@ describe('AxelarServiceGovernance', () => { const bytecodeHash = keccak256(bytecode); const expected = { - london: '0x4ee32f41f8ec59746ff29e3e6c4f9e3a291868f98caeb21b87de446c3655ce78', + london: '0x49dc6dac6da0ef91eb578121106c9524e0cc3b9b7643f6e2d8cfc758e258bfec', }[getEVMVersion()]; expect(bytecodeHash).to.be.equal(expected); From a035528014d02c86626e6d8fe64b1f014c6baf74 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 21:17:50 -0700 Subject: [PATCH 2/4] updated --- .../governance/AxelarServiceGovernance.sol | 24 ++++++++--------- .../interfaces/IAxelarServiceGovernance.sol | 8 +++--- test/governance/AxelarServiceGovernance.js | 26 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/contracts/governance/AxelarServiceGovernance.sol b/contracts/governance/AxelarServiceGovernance.sol index 24405513..ee8a4dd2 100644 --- a/contracts/governance/AxelarServiceGovernance.sol +++ b/contracts/governance/AxelarServiceGovernance.sol @@ -15,12 +15,12 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan ScheduleTimeLockProposal, CancelTimeLockProposal, ApproveMultisigProposal, - CancelMultisigApproval + CancelOperatorApproval } address public operator; - mapping(bytes32 => bool) public multisigApprovals; + mapping(bytes32 => bool) public operatorApprovals; modifier onlyOperator() { if (msg.sender != operator) revert NotAuthorized(); @@ -47,7 +47,7 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan uint256 minimumTimeDelay, address operator_ ) InterchainGovernance(gateway_, governanceChain_, governanceAddress_, minimumTimeDelay) { - if (operator_ == address(0)) revert InvalidOperatorAddress(); + if (operator_ == address(0)) revert InvalidOperator(); operator = operator_; } @@ -63,7 +63,7 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan bytes calldata callData, uint256 nativeValue ) external view returns (bool) { - return multisigApprovals[_getProposalHash(target, callData, nativeValue)]; + return operatorApprovals[_getProposalHash(target, callData, nativeValue)]; } /** @@ -79,9 +79,9 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan ) external payable onlyOperator { bytes32 proposalHash = _getProposalHash(target, callData, nativeValue); - if (!multisigApprovals[proposalHash]) revert NotApproved(); + if (!operatorApprovals[proposalHash]) revert NotApproved(); - multisigApprovals[proposalHash] = false; + operatorApprovals[proposalHash] = false; emit MultisigExecuted(proposalHash, target, callData, nativeValue); @@ -93,10 +93,10 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan * @dev Only the current operator or the governance can call this function * @param newOperator The new operator address */ - function transferOperator(address newOperator) external onlyOperatorOrSelf { - if (newOperator == address(0)) revert InvalidOperatorAddress(); + function transferOperatorship(address newOperator) external onlyOperatorOrSelf { + if (newOperator == address(0)) revert InvalidOperator(); - emit OperatorTransferred(operator, newOperator); + emit OperatorshipTransferred(operator, newOperator); operator = newOperator; } @@ -129,12 +129,12 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan emit ProposalCancelled(proposalHash, target, callData, nativeValue, eta); return; } else if (commandType == uint256(ServiceGovernanceCommand.ApproveMultisigProposal)) { - multisigApprovals[proposalHash] = true; + operatorApprovals[proposalHash] = true; emit MultisigApproved(proposalHash, target, callData, nativeValue); return; - } else if (commandType == uint256(ServiceGovernanceCommand.CancelMultisigApproval)) { - multisigApprovals[proposalHash] = false; + } else if (commandType == uint256(ServiceGovernanceCommand.CancelOperatorApproval)) { + operatorApprovals[proposalHash] = false; emit MultisigCancelled(proposalHash, target, callData, nativeValue); return; diff --git a/contracts/interfaces/IAxelarServiceGovernance.sol b/contracts/interfaces/IAxelarServiceGovernance.sol index b3708a4f..7918df72 100644 --- a/contracts/interfaces/IAxelarServiceGovernance.sol +++ b/contracts/interfaces/IAxelarServiceGovernance.sol @@ -9,7 +9,7 @@ import { IInterchainGovernance } from './IInterchainGovernance.sol'; * @dev This interface extends IInterchainGovernance and IMultisigBase for multisig proposal actions */ interface IAxelarServiceGovernance is IInterchainGovernance { - error InvalidOperatorAddress(); + error InvalidOperator(); error NotApproved(); error NotAuthorized(); @@ -34,14 +34,14 @@ interface IAxelarServiceGovernance is IInterchainGovernance { uint256 nativeValue ); - event OperatorTransferred(address indexed oldOperator, address indexed newOperator); + event OperatorshipTransferred(address indexed oldOperator, address indexed newOperator); /** * @notice Returns whether a multisig proposal has been approved * @param proposalHash The hash of the proposal * @return bool True if the proposal has been approved, False otherwise */ - function multisigApprovals(bytes32 proposalHash) external view returns (bool); + function operatorApprovals(bytes32 proposalHash) external view returns (bool); /** * @notice Returns whether a multisig proposal has been approved @@ -72,5 +72,5 @@ interface IAxelarServiceGovernance is IInterchainGovernance { * @dev Only the current operator or the governance can call this function * @param newOperator The new operator address */ - function transferOperator(address newOperator) external; + function transferOperatorship(address newOperator) external; } diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index 3a7caf6a..be3aadc1 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -32,7 +32,7 @@ describe('AxelarServiceGovernance', () => { const ScheduleTimeLockProposal = 0; const CancelTimeLockProposal = 1; const ApproveMultisigProposal = 2; - const CancelMultisigApproval = 3; + const CancelOperatorApproval = 3; const InvalidCommand = 4; before(async () => { @@ -74,15 +74,15 @@ describe('AxelarServiceGovernance', () => { gasOptions, ), serviceGovernanceFactory, - 'InvalidOperatorAddress', + 'InvalidOperator', ); }); it('should revert on invalid operator transfer', async () => { await expectRevert( - async (gasOptions) => serviceGovernance.connect(operator).transferOperator(AddressZero, gasOptions), + async (gasOptions) => serviceGovernance.connect(operator).transferOperatorship(AddressZero, gasOptions), serviceGovernance, - 'InvalidOperatorAddress', + 'InvalidOperator', ); }); @@ -200,7 +200,7 @@ describe('AxelarServiceGovernance', () => { const payloadCancel = defaultAbiCoder.encode( ['uint256', 'address', 'bytes', 'uint256', 'uint256'], - [CancelMultisigApproval, target, calldata, nativeValue, 0], + [CancelOperatorApproval, target, calldata, nativeValue, 0], ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) @@ -306,7 +306,7 @@ describe('AxelarServiceGovernance', () => { .withArgs(proposalHash, target, calldata, nativeValue); [payload, proposalHash] = await getPayloadAndProposalHash( - CancelMultisigApproval, + CancelOperatorApproval, target, nativeValue, calldata, @@ -354,13 +354,13 @@ describe('AxelarServiceGovernance', () => { it('should transfer operator address to new address', async () => { const newOperator = governanceAddress.address; - await expect(serviceGovernance.connect(operator).transferOperator(newOperator)) - .to.emit(serviceGovernance, 'OperatorTransferred') + await expect(serviceGovernance.connect(operator).transferOperatorship(newOperator)) + .to.emit(serviceGovernance, 'OperatorshipTransferred') .withArgs(operator.address, newOperator); await expect(await serviceGovernance.operator()).to.equal(newOperator); await expectRevert( - async (gasOptions) => serviceGovernance.connect(operator).transferOperator(newOperator, gasOptions), + async (gasOptions) => serviceGovernance.connect(operator).transferOperatorship(newOperator, gasOptions), serviceGovernance, 'NotAuthorized', ); @@ -369,7 +369,7 @@ describe('AxelarServiceGovernance', () => { it('should transfer multisig by a governance proposal', async () => { const govCommandID = formatBytes32String('10'); const newOperator = serviceGovernance.address; - const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferOperator', [newOperator]); + const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferOperatorship', [newOperator]); const [payload, proposalHash, eta] = await getPayloadAndProposalHash( ScheduleTimeLockProposal, @@ -393,14 +393,14 @@ describe('AxelarServiceGovernance', () => { await expect(tx) .to.emit(serviceGovernance, 'ProposalExecuted') .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, executionTimestamp) - .and.to.emit(serviceGovernance, 'OperatorTransferred') + .and.to.emit(serviceGovernance, 'OperatorshipTransferred') .withArgs(governanceAddress.address, newOperator); await expect(await serviceGovernance.operator()).to.equal(newOperator); await expectRevert( async (gasOptions) => - serviceGovernance.connect(governanceAddress).transferOperator(newOperator, gasOptions), + serviceGovernance.connect(governanceAddress).transferOperatorship(newOperator, gasOptions), serviceGovernance, 'NotAuthorized', ); @@ -411,7 +411,7 @@ describe('AxelarServiceGovernance', () => { const bytecodeHash = keccak256(bytecode); const expected = { - london: '0x49dc6dac6da0ef91eb578121106c9524e0cc3b9b7643f6e2d8cfc758e258bfec', + london: '0x451263411dea09e2958967d2d392fa8b91236e0101856a25b0bb90c892e90fe3', }[getEVMVersion()]; expect(bytecodeHash).to.be.equal(expected); From 3b4312f8beee00bc36fc3001cefa67d14c51319e Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 6 Sep 2024 00:07:32 -0700 Subject: [PATCH 3/4] updated --- DESIGN.md | 10 +-- .../governance/AxelarServiceGovernance.sol | 20 ++--- .../interfaces/IAxelarServiceGovernance.sol | 18 ++--- test/governance/AxelarServiceGovernance.js | 78 +++++++++---------- 4 files changed, 63 insertions(+), 63 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index befb175c..5ec610b8 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -56,7 +56,7 @@ Multisig operations demand multi-signatory authorization for proposal execution. ## Axelar Service Governance -Building upon the Interchain Governance Contract, the Service Governance Contract is specifically designed to manage operations that require coordination. By incorporating `MultisigBase`, it introduces the functionality to approve, execute, and cancel multisig proposals, in addition to schedule and cancel TimeLock proposals. This is intended to be used as the owner for services such as the Interchain token service contract, allowing Axelar governance to manage it. +Building upon the Interchain Governance Contract, the Service Governance Contract is specifically designed to manage operations that require coordination. Axelar Service Governance introduces the functionality to approve, execute, and cancel operator proposals, in addition to schedule and cancel TimeLock proposals. This is intended to be used as the owner for services such as the Interchain token service contract, allowing Axelar governance to manage it. ### Service Governance Operations @@ -66,10 +66,10 @@ The contract orchestrates four governance operations: - **Cancel TimeLock Proposal**: Again, similar to Interchain Governance, it cancels an existing governance proposal. -- **Approve Multisig Proposal**: This function enables multisig proposal approval by setting the proposal's approval status to true. It resets any previous voting and signals successful approval via a MultisigApproved event. +- **Approve Operator Proposal**: This function enables operator proposal approval by setting the proposal's approval status to true. It resets any previous voting and signals successful approval via a OperatorApproved event. -- **Cancel Multisig Approval**: Cancels an approved multisig proposal, setting the approval status of the proposal to false and indicating successful cancellation through a `MultisigCancelled` event. +- **Cancel Operator Approval**: Cancels an approved operator proposal, setting the approval status of the proposal to false and indicating successful cancellation through a `OperatorCancelled` event. -### Secure Execution of Multisig Proposals +### Secure Execution of Operator Proposals -Each time a new multisig proposal receives approval from governance, the multisig voting count is reset to 0. This ensures that any previous votes on similar proposals will not affect the new proposal. When a multisig proposal gathers the required number of signatory approvals, it becomes ready for execution. Before execution, the contract verifies the proposal's approval status. If the status is set to false, the transaction is reverted. Once executed successfully, the approval status of the proposal is reset, and a MultisigExecuted event gets emitted. +Each time a new operator proposal receives approval from governance, the operator voting count is reset to 0. This ensures that any previous votes on similar proposals will not affect the new proposal. When a operator proposal gathers the required number of signatory approvals, it becomes ready for execution. Before execution, the contract verifies the proposal's approval status. If the status is set to false, the transaction is reverted. Once executed successfully, the approval status of the proposal is reset, and a OperatorExecuted event gets emitted. diff --git a/contracts/governance/AxelarServiceGovernance.sol b/contracts/governance/AxelarServiceGovernance.sol index ee8a4dd2..8655c53a 100644 --- a/contracts/governance/AxelarServiceGovernance.sol +++ b/contracts/governance/AxelarServiceGovernance.sol @@ -8,13 +8,13 @@ import { InterchainGovernance } from './InterchainGovernance.sol'; /** * @title AxelarServiceGovernance Contract * @dev This contract is part of the Axelar Governance system, it inherits the Interchain Governance contract - * with added functionality to approve and execute multisig proposals. + * with added functionality to approve and execute operator proposals. */ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernance { enum ServiceGovernanceCommand { ScheduleTimeLockProposal, CancelTimeLockProposal, - ApproveMultisigProposal, + ApproveOperatorProposal, CancelOperatorApproval } @@ -52,13 +52,13 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan } /** - * @notice Returns whether a multisig proposal has been approved + * @notice Returns whether an operator proposal has been approved * @param target The address of the contract targeted by the proposal * @param callData The call data to be sent to the target contract * @param nativeValue The amount of native tokens to be sent to the target contract * @return bool True if the proposal has been approved, False otherwise */ - function isMultisigProposalApproved( + function isOperatorProposalApproved( address target, bytes calldata callData, uint256 nativeValue @@ -67,12 +67,12 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan } /** - * @notice Executes a multisig proposal. + * @notice Executes an operator proposal. * @param target The target address the proposal will call * @param callData The data that encodes the function and arguments to call on the target contract * @param nativeValue The value of native token to be sent to the target contract */ - function executeMultisigProposal( + function executeOperatorProposal( address target, bytes calldata callData, uint256 nativeValue @@ -83,7 +83,7 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan operatorApprovals[proposalHash] = false; - emit MultisigExecuted(proposalHash, target, callData, nativeValue); + emit OperatorExecuted(proposalHash, target, callData, nativeValue); _call(target, callData, nativeValue); } @@ -128,15 +128,15 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan emit ProposalCancelled(proposalHash, target, callData, nativeValue, eta); return; - } else if (commandType == uint256(ServiceGovernanceCommand.ApproveMultisigProposal)) { + } else if (commandType == uint256(ServiceGovernanceCommand.ApproveOperatorProposal)) { operatorApprovals[proposalHash] = true; - emit MultisigApproved(proposalHash, target, callData, nativeValue); + emit OperatorApproved(proposalHash, target, callData, nativeValue); return; } else if (commandType == uint256(ServiceGovernanceCommand.CancelOperatorApproval)) { operatorApprovals[proposalHash] = false; - emit MultisigCancelled(proposalHash, target, callData, nativeValue); + emit OperatorCancelled(proposalHash, target, callData, nativeValue); return; } else { revert InvalidCommand(); diff --git a/contracts/interfaces/IAxelarServiceGovernance.sol b/contracts/interfaces/IAxelarServiceGovernance.sol index 7918df72..33d13932 100644 --- a/contracts/interfaces/IAxelarServiceGovernance.sol +++ b/contracts/interfaces/IAxelarServiceGovernance.sol @@ -6,28 +6,28 @@ import { IInterchainGovernance } from './IInterchainGovernance.sol'; /** * @title IAxelarServiceGovernance Interface - * @dev This interface extends IInterchainGovernance and IMultisigBase for multisig proposal actions + * @dev This interface extends IInterchainGovernance for operator proposal actions */ interface IAxelarServiceGovernance is IInterchainGovernance { error InvalidOperator(); error NotApproved(); error NotAuthorized(); - event MultisigApproved( + event OperatorApproved( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, uint256 nativeValue ); - event MultisigCancelled( + event OperatorCancelled( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, uint256 nativeValue ); - event MultisigExecuted( + event OperatorExecuted( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, @@ -37,31 +37,31 @@ interface IAxelarServiceGovernance is IInterchainGovernance { event OperatorshipTransferred(address indexed oldOperator, address indexed newOperator); /** - * @notice Returns whether a multisig proposal has been approved + * @notice Returns whether an operator proposal has been approved * @param proposalHash The hash of the proposal * @return bool True if the proposal has been approved, False otherwise */ function operatorApprovals(bytes32 proposalHash) external view returns (bool); /** - * @notice Returns whether a multisig proposal has been approved + * @notice Returns whether an operator proposal has been approved * @param target The address of the contract targeted by the proposal * @param callData The call data to be sent to the target contract * @param nativeValue The amount of native tokens to be sent to the target contract * @return bool True if the proposal has been approved, False otherwise */ - function isMultisigProposalApproved( + function isOperatorProposalApproved( address target, bytes calldata callData, uint256 nativeValue ) external view returns (bool); /** - * @notice Executes a multisig proposal + * @notice Executes an operator proposal * @param targetContract The target address the proposal will call * @param callData The data that encodes the function and arguments to call on the target contract */ - function executeMultisigProposal( + function executeOperatorProposal( address targetContract, bytes calldata callData, uint256 value diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index be3aadc1..113d938d 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -31,7 +31,7 @@ describe('AxelarServiceGovernance', () => { const ScheduleTimeLockProposal = 0; const CancelTimeLockProposal = 1; - const ApproveMultisigProposal = 2; + const ApproveOperatorProposal = 2; const CancelOperatorApproval = 3; const InvalidCommand = 4; @@ -149,50 +149,50 @@ describe('AxelarServiceGovernance', () => { .withArgs(proposalHash, target, calldata, nativeValue, eta); }); - it('should approve a multisig proposal', async () => { + it('should approve a operator proposal', async () => { const govCommandID = formatBytes32String('4'); const nativeValue = 400; const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); }); - it('should return whether or not a multisig proposal is approved', async () => { + it('should return whether or not a operator proposal is approved', async () => { const govCommandID = formatBytes32String('5'); const nativeValue = 500; const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, ); - let isApproved = await serviceGovernance.isMultisigProposalApproved(target, calldata, nativeValue); + let isApproved = await serviceGovernance.isOperatorProposalApproved(target, calldata, nativeValue); expect(isApproved).to.be.false; await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); - isApproved = await serviceGovernance.isMultisigProposalApproved(target, calldata, nativeValue); + isApproved = await serviceGovernance.isOperatorProposalApproved(target, calldata, nativeValue); expect(isApproved).to.be.true; }); - it('should re-approve a multisig proposal after cancelling it', async () => { + it('should re-approve a operator proposal after cancelling it', async () => { const govCommandID = formatBytes32String('6'); const nativeValue = 600; const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, @@ -204,38 +204,38 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payloadCancel)) - .to.emit(serviceGovernance, 'MultisigCancelled') + .to.emit(serviceGovernance, 'OperatorCancelled') .withArgs(proposalHash, target, calldata, nativeValue); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); }); - it('should revert on executing a multisig proposal if called by non-multisig', async () => { + it('should revert on executing a operator proposal if called by non-operator', async () => { await expectRevert( async (gasOptions) => - serviceGovernance.connect(ownerWallet).executeMultisigProposal(target, calldata, 0, gasOptions), + serviceGovernance.connect(ownerWallet).executeOperatorProposal(target, calldata, 0, gasOptions), serviceGovernance, 'NotAuthorized', ); }); - it('should revert on executing a multisig proposal if proposal is not approved', async () => { + it('should revert on executing a operator proposal if proposal is not approved', async () => { await expectRevert( async (gasOptions) => - serviceGovernance.connect(operator).executeMultisigProposal(target, calldata, 0, gasOptions), + serviceGovernance.connect(operator).executeOperatorProposal(target, calldata, 0, gasOptions), serviceGovernance, 'NotApproved', ); }); - it('should revert on executing a multisig proposal if call to target fails', async () => { - const ApproveMultisigProposal = 2; + it('should revert on executing a operator proposal if call to target fails', async () => { + const ApproveOperatorProposal = 2; const govCommandID = formatBytes32String('7'); const nativeValue = 700; @@ -244,19 +244,19 @@ describe('AxelarServiceGovernance', () => { const invalidCalldata = invalidTargetInterface.encodeFunctionData('set'); const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, invalidCalldata, ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, invalidCalldata, nativeValue); await expectRevert( async (gasOptions) => - serviceGovernance.connect(operator).executeMultisigProposal(target, invalidCalldata, nativeValue, { + serviceGovernance.connect(operator).executeOperatorProposal(target, invalidCalldata, nativeValue, { value: nativeValue, ...gasOptions, }), @@ -265,44 +265,44 @@ describe('AxelarServiceGovernance', () => { ); }); - it('should execute a multisig proposal', async () => { + it('should execute a operator proposal', async () => { const govCommandID = formatBytes32String('8'); const nativeValue = 800; const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); await expect( serviceGovernance .connect(operator) - .executeMultisigProposal(target, calldata, nativeValue, { value: nativeValue }), + .executeOperatorProposal(target, calldata, nativeValue, { value: nativeValue }), ) - .to.emit(serviceGovernance, 'MultisigExecuted') + .to.emit(serviceGovernance, 'OperatorExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(targetContract, 'TargetCalled'); }); - it('should cancel an approved multisig proposal', async () => { + it('should cancel an approved operator proposal', async () => { const govCommandID = formatBytes32String('9'); const nativeValue = 900; let [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); [payload, proposalHash] = await getPayloadAndProposalHash( @@ -313,23 +313,23 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigCancelled') + .to.emit(serviceGovernance, 'OperatorCancelled') .withArgs(proposalHash, target, calldata, nativeValue); }); - it('should execute a multisig proposal and increase balance of target', async () => { + it('should execute a operator proposal and increase balance of target', async () => { const govCommandID = formatBytes32String('10'); const nativeValue = 1000; const [payload, proposalHash] = await getPayloadAndProposalHash( - ApproveMultisigProposal, + ApproveOperatorProposal, target, nativeValue, calldata, ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'MultisigApproved') + .to.emit(serviceGovernance, 'OperatorApproved') .withArgs(proposalHash, target, calldata, nativeValue); await ownerWallet @@ -341,10 +341,10 @@ describe('AxelarServiceGovernance', () => { const oldBalance = await ethers.provider.getBalance(target); - const tx = await serviceGovernance.connect(operator).executeMultisigProposal(target, calldata, nativeValue); + const tx = await serviceGovernance.connect(operator).executeOperatorProposal(target, calldata, nativeValue); await expect(tx) - .to.emit(serviceGovernance, 'MultisigExecuted') + .to.emit(serviceGovernance, 'OperatorExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(targetContract, 'TargetCalled'); @@ -366,7 +366,7 @@ describe('AxelarServiceGovernance', () => { ); }); - it('should transfer multisig by a governance proposal', async () => { + it('should transfer operatorship by a governance proposal', async () => { const govCommandID = formatBytes32String('10'); const newOperator = serviceGovernance.address; const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferOperatorship', [newOperator]); @@ -411,7 +411,7 @@ describe('AxelarServiceGovernance', () => { const bytecodeHash = keccak256(bytecode); const expected = { - london: '0x451263411dea09e2958967d2d392fa8b91236e0101856a25b0bb90c892e90fe3', + london: '0x887cfc32099cde0389bc1f3f134f808dcdd51e718194ace8d423f5270f36f6fd', }[getEVMVersion()]; expect(bytecodeHash).to.be.equal(expected); From 283041af2b0a76a95e595ed05a3071acf9144341 Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 6 Sep 2024 00:52:52 -0700 Subject: [PATCH 4/4] updated --- DESIGN.md | 6 ++--- .../governance/AxelarServiceGovernance.sol | 6 ++--- .../interfaces/IAxelarServiceGovernance.sol | 6 ++--- test/governance/AxelarServiceGovernance.js | 26 +++++++++---------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 5ec610b8..15d3519b 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -66,10 +66,10 @@ The contract orchestrates four governance operations: - **Cancel TimeLock Proposal**: Again, similar to Interchain Governance, it cancels an existing governance proposal. -- **Approve Operator Proposal**: This function enables operator proposal approval by setting the proposal's approval status to true. It resets any previous voting and signals successful approval via a OperatorApproved event. +- **Approve Operator Proposal**: This function enables operator proposal approval by setting the proposal's approval status to true. It resets any previous voting and signals successful approval via a OperatorProposalApproved event. -- **Cancel Operator Approval**: Cancels an approved operator proposal, setting the approval status of the proposal to false and indicating successful cancellation through a `OperatorCancelled` event. +- **Cancel Operator Approval**: Cancels an approved operator proposal, setting the approval status of the proposal to false and indicating successful cancellation through a `OperatorProposalCancelled` event. ### Secure Execution of Operator Proposals -Each time a new operator proposal receives approval from governance, the operator voting count is reset to 0. This ensures that any previous votes on similar proposals will not affect the new proposal. When a operator proposal gathers the required number of signatory approvals, it becomes ready for execution. Before execution, the contract verifies the proposal's approval status. If the status is set to false, the transaction is reverted. Once executed successfully, the approval status of the proposal is reset, and a OperatorExecuted event gets emitted. +Each time a new operator proposal receives approval from governance, the operator voting count is reset to 0. This ensures that any previous votes on similar proposals will not affect the new proposal. When a operator proposal gathers the required number of signatory approvals, it becomes ready for execution. Before execution, the contract verifies the proposal's approval status. If the status is set to false, the transaction is reverted. Once executed successfully, the approval status of the proposal is reset, and a OperatorProposalExecuted event gets emitted. diff --git a/contracts/governance/AxelarServiceGovernance.sol b/contracts/governance/AxelarServiceGovernance.sol index 8655c53a..4b5a5cde 100644 --- a/contracts/governance/AxelarServiceGovernance.sol +++ b/contracts/governance/AxelarServiceGovernance.sol @@ -83,7 +83,7 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan operatorApprovals[proposalHash] = false; - emit OperatorExecuted(proposalHash, target, callData, nativeValue); + emit OperatorProposalExecuted(proposalHash, target, callData, nativeValue); _call(target, callData, nativeValue); } @@ -131,12 +131,12 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan } else if (commandType == uint256(ServiceGovernanceCommand.ApproveOperatorProposal)) { operatorApprovals[proposalHash] = true; - emit OperatorApproved(proposalHash, target, callData, nativeValue); + emit OperatorProposalApproved(proposalHash, target, callData, nativeValue); return; } else if (commandType == uint256(ServiceGovernanceCommand.CancelOperatorApproval)) { operatorApprovals[proposalHash] = false; - emit OperatorCancelled(proposalHash, target, callData, nativeValue); + emit OperatorProposalCancelled(proposalHash, target, callData, nativeValue); return; } else { revert InvalidCommand(); diff --git a/contracts/interfaces/IAxelarServiceGovernance.sol b/contracts/interfaces/IAxelarServiceGovernance.sol index 33d13932..d658374b 100644 --- a/contracts/interfaces/IAxelarServiceGovernance.sol +++ b/contracts/interfaces/IAxelarServiceGovernance.sol @@ -13,21 +13,21 @@ interface IAxelarServiceGovernance is IInterchainGovernance { error NotApproved(); error NotAuthorized(); - event OperatorApproved( + event OperatorProposalApproved( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, uint256 nativeValue ); - event OperatorCancelled( + event OperatorProposalCancelled( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, uint256 nativeValue ); - event OperatorExecuted( + event OperatorProposalExecuted( bytes32 indexed proposalHash, address indexed targetContract, bytes callData, diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index 113d938d..eecee8e6 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -161,7 +161,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); }); @@ -180,7 +180,7 @@ describe('AxelarServiceGovernance', () => { expect(isApproved).to.be.false; await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); isApproved = await serviceGovernance.isOperatorProposalApproved(target, calldata, nativeValue); @@ -204,15 +204,15 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payloadCancel)) - .to.emit(serviceGovernance, 'OperatorCancelled') + .to.emit(serviceGovernance, 'OperatorProposalCancelled') .withArgs(proposalHash, target, calldata, nativeValue); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); }); @@ -251,7 +251,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, invalidCalldata, nativeValue); await expectRevert( @@ -277,7 +277,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); await expect( @@ -285,7 +285,7 @@ describe('AxelarServiceGovernance', () => { .connect(operator) .executeOperatorProposal(target, calldata, nativeValue, { value: nativeValue }), ) - .to.emit(serviceGovernance, 'OperatorExecuted') + .to.emit(serviceGovernance, 'OperatorProposalExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(targetContract, 'TargetCalled'); }); @@ -302,7 +302,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); [payload, proposalHash] = await getPayloadAndProposalHash( @@ -313,7 +313,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorCancelled') + .to.emit(serviceGovernance, 'OperatorProposalCancelled') .withArgs(proposalHash, target, calldata, nativeValue); }); @@ -329,7 +329,7 @@ describe('AxelarServiceGovernance', () => { ); await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) - .to.emit(serviceGovernance, 'OperatorApproved') + .to.emit(serviceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); await ownerWallet @@ -344,7 +344,7 @@ describe('AxelarServiceGovernance', () => { const tx = await serviceGovernance.connect(operator).executeOperatorProposal(target, calldata, nativeValue); await expect(tx) - .to.emit(serviceGovernance, 'OperatorExecuted') + .to.emit(serviceGovernance, 'OperatorProposalExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(targetContract, 'TargetCalled'); @@ -411,7 +411,7 @@ describe('AxelarServiceGovernance', () => { const bytecodeHash = keccak256(bytecode); const expected = { - london: '0x887cfc32099cde0389bc1f3f134f808dcdd51e718194ace8d423f5270f36f6fd', + london: '0x87891d8e17e62bddae5afa47c6231b236207b7c9cfff0810bc62b226a3765600', }[getEVMVersion()]; expect(bytecodeHash).to.be.equal(expected);