From 23ea544c29c9fc07ad606e8f58bfa9be85af7b19 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 20:28:35 -0700 Subject: [PATCH] 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);