From d00f744d8b0776cc8e97c6d90e30be3e61233a15 Mon Sep 17 00:00:00 2001 From: Blockchain Guy Date: Fri, 27 Sep 2024 12:38:26 +0530 Subject: [PATCH 1/3] fix: contract verification for flow (#376) Co-authored-by: Milap Sheth --- evm/utils.js | 12 +++++ evm/verify-contract.js | 113 +++++++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 43 deletions(-) diff --git a/evm/utils.js b/evm/utils.js index 2cf54448..4e10d117 100644 --- a/evm/utils.js +++ b/evm/utils.js @@ -842,6 +842,11 @@ function getContractJSON(contractName, artifactPath) { } } +function getQualifiedContractName(contractName) { + const contractJSON = getContractJSON(contractName); + return `${contractJSON.sourceName}:${contractJSON.contractName}`; +} + /** * Retrieves gas options for contract interactions. * @@ -1017,6 +1022,11 @@ async function getWeightedSigners(config, chain, options) { return { signers: [signers], verifierSetId }; } +// Verify contract using it's source code path. The path is retrieved dynamically by the name. +const verifyContractByName = (env, chain, name, contract, args, options = {}) => { + verifyContract(env, chain, contract, args, { ...options, contractPath: getQualifiedContractName(name) }); +}; + module.exports = { ...require('../common/utils'), deployCreate, @@ -1055,4 +1065,6 @@ module.exports = { relayTransaction, getDeploymentTx, getWeightedSigners, + getQualifiedContractName, + verifyContractByName, }; diff --git a/evm/verify-contract.js b/evm/verify-contract.js index 84cf255f..472ac0dd 100644 --- a/evm/verify-contract.js +++ b/evm/verify-contract.js @@ -9,10 +9,69 @@ const { Contract, } = ethers; const { Command, Option } = require('commander'); -const { verifyContract, getEVMAddresses, printInfo, printError, mainProcessor, getContractJSON, validateParameters } = require('./utils'); +const { + verifyContract, + getEVMAddresses, + printInfo, + printError, + mainProcessor, + getContractJSON, + validateParameters, + verifyContractByName, +} = require('./utils'); const { addBaseOptions } = require('./cli-utils'); const { getTrustedChainsAndAddresses } = require('./its'); +async function verifyConsensusGateway(config, chain, contractConfig, env, wallet, verifyOptions, options) { + const contractJson = getContractJSON('AxelarGateway'); + const contractFactory = await getContractFactoryFromArtifact(contractJson, wallet); + + const gateway = contractFactory.attach(contractConfig.address); + const implementation = await gateway.implementation(); + const auth = await gateway.authModule(); + const tokenDeployer = await gateway.tokenDeployer(); + + const { addresses, weights, threshold } = await getEVMAddresses(config, chain.axelarId, { + keyID: chain.contracts.AxelarGateway.startingKeyIDs[0] || options.args || `evm-${chain.axelarId.toLowerCase()}-genesis`, + }); + const authParams = [defaultAbiCoder.encode(['address[]', 'uint256[]', 'uint256'], [addresses, weights, threshold])]; + const setupParams = defaultAbiCoder.encode(['address', 'address', 'bytes'], [contractConfig.deployer, contractConfig.deployer, '0x']); + + await verifyContract(env, chain.name, auth, [authParams], verifyOptions); + await verifyContract(env, chain.name, tokenDeployer, [], verifyOptions); + await verifyContract(env, chain.name, implementation, [auth, tokenDeployer], verifyOptions); + await verifyContract(env, chain.name, contractConfig.address, [implementation, setupParams], verifyOptions); +} + +async function verifyAmplifierGateway(chain, contractConfig, env, wallet, verifyOptions, options) { + const contractJson = getContractJSON('AxelarAmplifierGateway'); + const contractFactory = await getContractFactoryFromArtifact(contractJson, wallet); + + const amplifierGateway = contractFactory.attach(options.address || contractConfig.address); + const implementation = await amplifierGateway.implementation(); + const previousSignersRetention = (await amplifierGateway.previousSignersRetention()).toNumber(); + const domainSeparator = await amplifierGateway.domainSeparator(); + const minimumRotationDelay = (await amplifierGateway.minimumRotationDelay()).toNumber(); + + await verifyContractByName( + env, + chain.name, + 'AxelarGateway', + implementation, + [previousSignersRetention, domainSeparator, minimumRotationDelay], + verifyOptions, + ); + + await verifyContractByName( + env, + chain.name, + 'AxelarAmplifierGatewayProxy', + amplifierGateway.address, + contractConfig.proxyDeploymentArgs, + verifyOptions, + ); +} + async function processCommand(config, chain, options) { const { env, contractName, dir } = options; const provider = getDefaultProvider(chain.rpc); @@ -29,10 +88,11 @@ async function processCommand(config, chain, options) { } printInfo('Verifying contract', contractName); - printInfo('Contract address', options.address || chain.contracts[contractName]?.address); + + const contractAddress = options.address || chain.contracts[contractName]?.address; + printInfo('Contract address', contractAddress); const contractConfig = chain.contracts[contractName]; - const contractAddress = options.address || contractConfig.address; const contractJson = getContractJSON(contractName); const contractFactory = await getContractFactoryFromArtifact(contractJson, wallet); @@ -90,24 +150,13 @@ async function processCommand(config, chain, options) { } case 'AxelarGateway': { - const gateway = contractFactory.attach(contractAddress); - const implementation = await gateway.implementation(); - const auth = await gateway.authModule(); - const tokenDeployer = await gateway.tokenDeployer(); - - const { addresses, weights, threshold } = await getEVMAddresses(config, chain.axelarId, { - keyID: chain.contracts.AxelarGateway.startingKeyIDs[0] || options.args || `evm-${chain.axelarId.toLowerCase()}-genesis`, - }); - const authParams = [defaultAbiCoder.encode(['address[]', 'uint256[]', 'uint256'], [addresses, weights, threshold])]; - const setupParams = defaultAbiCoder.encode( - ['address', 'address', 'bytes'], - [contractConfig.deployer, contractConfig.deployer, '0x'], - ); - - await verifyContract(env, chain.name, auth, [authParams], verifyOptions); - await verifyContract(env, chain.name, tokenDeployer, [], verifyOptions); - await verifyContract(env, chain.name, implementation, [auth, tokenDeployer], verifyOptions); - await verifyContract(env, chain.name, contractAddress, [implementation, setupParams], verifyOptions); + if (contractConfig.connectionType === 'amplifier') { + verifyAmplifierGateway(chain, contractConfig, env, wallet, verifyOptions, options); + } else if (contractConfig.connectionType === 'consensus') { + verifyConsensusGateway(config, chain, contractConfig, env, wallet, verifyOptions, options); + } else { + throw new Error(`Incompatible Gateway connection type`); + } break; } @@ -265,28 +314,6 @@ async function processCommand(config, chain, options) { break; } - case 'AxelarAmplifierGateway': { - const contractConfig = chain.contracts.AxelarGateway; - const amplifierGateway = contractFactory.attach(options.address || contractConfig.address); - - const implementation = await amplifierGateway.implementation(); - const previousSignersRetention = (await amplifierGateway.previousSignersRetention()).toNumber(); - const domainSeparator = await amplifierGateway.domainSeparator(); - const minimumRotationDelay = (await amplifierGateway.minimumRotationDelay()).toNumber(); - - await verifyContract( - env, - chain.name, - implementation, - [previousSignersRetention, domainSeparator, minimumRotationDelay], - verifyOptions, - ); - - await verifyContract(env, chain.name, amplifierGateway.address, contractConfig.proxyDeploymentArgs, verifyOptions); - - break; - } - default: { throw new Error(`Contract ${contractName} is not supported`); } From ace4b81c291fd0dad7d03d766538e9c886b856cd Mon Sep 17 00:00:00 2001 From: Ayoub Dardory Date: Fri, 27 Sep 2024 14:43:58 +0100 Subject: [PATCH 2/3] ci: update the actions used in test-sui workflows (#391) --- .github/workflows/test-sui.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-sui.yaml b/.github/workflows/test-sui.yaml index 4286e804..522e6dc7 100644 --- a/.github/workflows/test-sui.yaml +++ b/.github/workflows/test-sui.yaml @@ -38,16 +38,24 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '18' # Hardcoded to ensure consistency. cache: 'npm' + registry-url: 'https://registry.npmjs.org' - name: Install dependencies + shell: bash run: npm ci + - name: Get Sui Version + shell: bash + run: | + SUI_VERSION=$(jq -r '.SUI_VERSION' "node_modules/@axelar-network/axelar-cgp-sui/version.json") + echo "SUI_VERSION=$SUI_VERSION" >> $GITHUB_ENV + - name: Setup Sui CLI - uses: axelarnetwork/axelar-cgp-sui/.github/actions/install-sui-cli@main + uses: axelarnetwork/axelar-cgp-sui/.github/actions/setup-sui@main with: - sui-version: $(jq -r '.SUI_VERSION' node_modules/@axelar-network/axelar-cgp-sui/version.json) + sui-version: ${{ env.SUI_VERSION }} - name: Setup Sui Wallet shell: bash From 74452c50614324c744365e4ed0e450876dfcf080 Mon Sep 17 00:00:00 2001 From: npty <78221556+npty@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:31:56 +0700 Subject: [PATCH 3/3] chore(sui): improve error message for deployment (#387) Co-authored-by: Milap Sheth --- sui/deploy-contract.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sui/deploy-contract.js b/sui/deploy-contract.js index 53e5d6a3..e298d4d3 100644 --- a/sui/deploy-contract.js +++ b/sui/deploy-contract.js @@ -241,6 +241,15 @@ async function deploy(keypair, client, supportedContract, config, chain, options // Print warning if version mismatch from defined version in version.json checkSuiVersionMatch(); + // Check if dependencies are deployed + const dependencies = getLocalDependencies(packageDir, `${__dirname}/../node_modules/@axelar-network/axelar-cgp-sui/move`); + + for (const { name } of dependencies) { + if (!chain.contracts[name]) { + throw new Error(`Contract ${name} needed to be deployed before deploying ${packageName}`); + } + } + // Deploy package const published = await deployPackage(packageDir, client, keypair, options);