From e935abc88185f15fde4bf9cc179ecf4ff6f5e323 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:11:27 -0400 Subject: [PATCH 1/7] feat(AxelarServiceGovernance): transferign multisig by governance --- contracts/governance/AxelarServiceGovernance.sol | 12 +++++++++++- contracts/interfaces/IAxelarServiceGovernance.sol | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/contracts/governance/AxelarServiceGovernance.sol b/contracts/governance/AxelarServiceGovernance.sol index a5e53a45..158ee1bd 100644 --- a/contracts/governance/AxelarServiceGovernance.sol +++ b/contracts/governance/AxelarServiceGovernance.sol @@ -27,6 +27,11 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan _; } + modifier onlyMultisigOrSelf() { + if (msg.sender != multisig && msg.sender != address(this)) revert NotAuthorized(); + _; + } + /** * @notice Initializes the contract. * @param gateway_ The address of the Axelar gateway contract @@ -83,7 +88,12 @@ contract AxelarServiceGovernance is InterchainGovernance, IAxelarServiceGovernan _call(target, callData, nativeValue); } - function transferMultisig(address newMultisig) external onlyMultisig { + /** + * @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 + */ + function transferMultisig(address newMultisig) external onlyMultisigOrSelf { if (newMultisig == address(0)) revert InvalidMultisigAddress(); emit MultisigTransferred(multisig, newMultisig); diff --git a/contracts/interfaces/IAxelarServiceGovernance.sol b/contracts/interfaces/IAxelarServiceGovernance.sol index 913d0ba6..3d632a03 100644 --- a/contracts/interfaces/IAxelarServiceGovernance.sol +++ b/contracts/interfaces/IAxelarServiceGovernance.sol @@ -66,4 +66,11 @@ interface IAxelarServiceGovernance is IInterchainGovernance { bytes calldata callData, uint256 value ) 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 + */ + function transferMultisig(address newMultisig) external; } From 6535e5653d00706e3fe97567fbc798ee02c27dd3 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:39:31 -0400 Subject: [PATCH 2/7] test(AxelarServiceGovernance): transferign multisig by governance --- test/governance/AxelarServiceGovernance.js | 45 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index 3f348bcd..e96929b3 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -7,7 +7,7 @@ const { constants: { AddressZero }, } = ethers; const { expect } = chai; -const { isHardhat, getPayloadAndProposalHash, getEVMVersion, expectRevert } = require('../utils'); +const { isHardhat, getPayloadAndProposalHash, getEVMVersion, expectRevert, waitFor } = require('../utils'); describe('AxelarServiceGovernance', () => { let ownerWallet; @@ -366,12 +366,53 @@ describe('AxelarServiceGovernance', () => { ); }); + + it('should trasfer multisig by a governance proposal', async () => { + const govCommandID = formatBytes32String('10'); + const newMultisig = serviceGovernance.address; + const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferMultisig', [newMultisig]); + + const [payload, proposalHash, eta] = await getPayloadAndProposalHash( + ScheduleTimeLockProposal, + serviceGovernance.address, + 0, + transferCalldata, + timeDelay, + ); + + await expect(serviceGovernance.execute(govCommandID, governanceChain, governanceAddress.address, payload)) + .to.emit(serviceGovernance, 'ProposalScheduled') + .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, eta); + + await waitFor(timeDelay); + + const tx = await serviceGovernance.executeProposal(serviceGovernance.address, transferCalldata, 0); + + const block = await ethers.provider.getBlock(tx.blockNumber); + const executionTimestamp = block.timestamp; + + await expect(tx) + .to.emit(serviceGovernance, 'ProposalExecuted') + .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, executionTimestamp) + // .and.to.emit(serviceGovernance, 'MultisigTransferred') + // .withArgs(multisig.address, newMultisig); + + await expect(await serviceGovernance.multisig()).to.equal(newMultisig); + + await expectRevert( + async (gasOptions) => serviceGovernance.connect(multisig).transferMultisig(newMultisig, gasOptions), + serviceGovernance, + 'NotAuthorized', + ); + }); + + it('should preserve the bytecode [ @skip-on-coverage ]', async () => { const bytecode = serviceGovernanceFactory.bytecode; const bytecodeHash = keccak256(bytecode); const expected = { - london: '0xf5a298c73276406c136da5e9d6f102e5cbcc452376708b3864b6c0f0bf45d952', + london: '0x5e40ac38c1162aa207054ab1f4d6f9205cdde1627f644eb6dfdb0fbfe17445fd', }[getEVMVersion()]; expect(bytecodeHash).to.be.equal(expected); From 0126b8075cf2b1d8a0abd3d607c656341a2781c3 Mon Sep 17 00:00:00 2001 From: re1ro Date: Mon, 3 Jun 2024 20:45:55 -0400 Subject: [PATCH 3/7] Update test/governance/AxelarServiceGovernance.js Co-authored-by: Milap Sheth --- test/governance/AxelarServiceGovernance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index e96929b3..2b16a7ab 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -367,7 +367,7 @@ describe('AxelarServiceGovernance', () => { }); - it('should trasfer multisig by a governance proposal', async () => { + it('should transfer multisig by a governance proposal', async () => { const govCommandID = formatBytes32String('10'); const newMultisig = serviceGovernance.address; const transferCalldata = serviceGovernance.interface.encodeFunctionData('transferMultisig', [newMultisig]); From 8e865cd3c89dba5549a0be96b60143d6f2de4261 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:46:23 -0400 Subject: [PATCH 4/7] test(AxelarServiceGovernance): event check --- test/governance/AxelarServiceGovernance.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index 2b16a7ab..b7869582 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -352,7 +352,7 @@ describe('AxelarServiceGovernance', () => { expect(newBalance).to.equal(oldBalance.add(nativeValue)); }); - it('should trasfer multisig address to new address', async () => { + it('should transfer multisig address to new address', async () => { const newMultisig = governanceAddress.address; await expect(serviceGovernance.connect(multisig).transferMultisig(newMultisig)) .to.emit(serviceGovernance, 'MultisigTransferred') @@ -386,16 +386,20 @@ describe('AxelarServiceGovernance', () => { await waitFor(timeDelay); + + console.log(await serviceGovernance.multisig()); + const tx = await serviceGovernance.executeProposal(serviceGovernance.address, transferCalldata, 0); const block = await ethers.provider.getBlock(tx.blockNumber); const executionTimestamp = block.timestamp; + await expect(tx) .to.emit(serviceGovernance, 'ProposalExecuted') .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, executionTimestamp) - // .and.to.emit(serviceGovernance, 'MultisigTransferred') - // .withArgs(multisig.address, newMultisig); + .and.to.emit(serviceGovernance, 'MultisigTransferred') + .withArgs(governanceAddress.address, newMultisig); await expect(await serviceGovernance.multisig()).to.equal(newMultisig); From d7ca1a387f250ae85b5b7feab9028ddf5cb75e13 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:46:52 -0400 Subject: [PATCH 5/7] test(AxelarServiceGovernance): event check --- test/governance/AxelarServiceGovernance.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index b7869582..fcd83bb5 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -366,7 +366,6 @@ describe('AxelarServiceGovernance', () => { ); }); - it('should transfer multisig by a governance proposal', async () => { const govCommandID = formatBytes32String('10'); const newMultisig = serviceGovernance.address; @@ -386,15 +385,11 @@ describe('AxelarServiceGovernance', () => { await waitFor(timeDelay); - - console.log(await serviceGovernance.multisig()); - const tx = await serviceGovernance.executeProposal(serviceGovernance.address, transferCalldata, 0); const block = await ethers.provider.getBlock(tx.blockNumber); const executionTimestamp = block.timestamp; - await expect(tx) .to.emit(serviceGovernance, 'ProposalExecuted') .withArgs(proposalHash, serviceGovernance.address, transferCalldata, 0, executionTimestamp) @@ -410,7 +405,6 @@ describe('AxelarServiceGovernance', () => { ); }); - it('should preserve the bytecode [ @skip-on-coverage ]', async () => { const bytecode = serviceGovernanceFactory.bytecode; const bytecodeHash = keccak256(bytecode); From 965bb2c7e93153b2e544aeed10b80635b2b293da Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:49:26 -0400 Subject: [PATCH 6/7] test(AxelarServiceGovernance): event check --- test/governance/AxelarServiceGovernance.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index fcd83bb5..95a105fc 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -399,7 +399,8 @@ describe('AxelarServiceGovernance', () => { await expect(await serviceGovernance.multisig()).to.equal(newMultisig); await expectRevert( - async (gasOptions) => serviceGovernance.connect(multisig).transferMultisig(newMultisig, gasOptions), + async (gasOptions) => + serviceGovernance.connect(governanceAddress.address).transferMultisig(newMultisig, gasOptions), serviceGovernance, 'NotAuthorized', ); From 1356628fb522b6d520c9770d3eaeae8cf6933f17 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Mon, 3 Jun 2024 20:50:01 -0400 Subject: [PATCH 7/7] test(AxelarServiceGovernance): event check --- test/governance/AxelarServiceGovernance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/governance/AxelarServiceGovernance.js b/test/governance/AxelarServiceGovernance.js index 95a105fc..9b33503c 100644 --- a/test/governance/AxelarServiceGovernance.js +++ b/test/governance/AxelarServiceGovernance.js @@ -400,7 +400,7 @@ describe('AxelarServiceGovernance', () => { await expectRevert( async (gasOptions) => - serviceGovernance.connect(governanceAddress.address).transferMultisig(newMultisig, gasOptions), + serviceGovernance.connect(governanceAddress).transferMultisig(newMultisig, gasOptions), serviceGovernance, 'NotAuthorized', );