Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(scripts): add support for gateway v4.1.x deployment #129

Merged
merged 3 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions scripts/deploy-gateway-v4.1.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
'use strict';

require('dotenv').config();

const { printLog, printObj, confirm, getEVMAddresses, pubkeysToAddresses, parseWei, getTxOptions } = require('./utils');
const { ethers } = require('hardhat');
const {
getContractFactory,
Wallet,
providers: { JsonRpcProvider },
utils: { defaultAbiCoder, arrayify },
} = ethers;

// these environment variables should be defined in an '.env' file
const skipConfirm = process.env.SKIP_CONFIRM;
const prefix = process.env.PREFIX;
const chain = process.env.CHAIN;
const url = process.env.URL;
const privKey = process.env.PRIVATE_KEY;
const adminPubkeys = process.env.ADMIN_PUBKEYS;
const adminAddresses = process.env.ADMIN_ADDRESSES;
const adminThreshold = parseInt(process.env.ADMIN_THRESHOLD);
const gasPrice = parseWei(process.env.GAS_PRICE);
const maxFeePerGas = parseWei(process.env.MAX_FEE_PER_GAS);
const maxPriorityFeePerGas = parseWei(process.env.MAX_PRIORITY_FEE_PER_GAS);
const gasLimit = process.env.GAS_LIMIT ? Number(process.env.GAS_LIMIT) : Number(21000);

// main execution
confirm(
{
PREFIX: prefix || null,
CHAIN: chain || null,
URL: url || null,
PRIVATE_KEY: privKey ? '*****REDACTED*****' : null,
ADMIN_PUBKEYS: adminPubkeys || null,
ADMIN_ADDRESSES: adminAddresses || null,
ADMIN_THRESHOLD: adminThreshold || null,
MAX_FEE_PER_GAS: maxFeePerGas?.toString() || null,
MAX_PRIORITY_FEE_PER_GAS: maxPriorityFeePerGas?.toString() || null,
GAS_PRICE: gasPrice?.toString() || null,
GAS_LIMIT: gasLimit || null,
SKIP_CONFIRM: skipConfirm || null,
},
prefix && chain && url && privKey && adminThreshold && (adminPubkeys || adminAddresses),
);

const provider = new JsonRpcProvider(url);
const wallet = new Wallet(privKey, provider);


printLog('retrieving addresses');
const { addresses, weights, threshold } = getEVMAddresses(prefix, chain);
printObj({ addresses, weights, threshold });
const admins = adminAddresses ? JSON.parse(adminAddresses) : pubkeysToAddresses(JSON.parse(adminPubkeys));
printObj({ admins });

const contracts = {};
const paramsAuth = [defaultAbiCoder.encode(['address[]', 'uint256[]', 'uint256'], [addresses, weights, threshold])];
const paramsProxy = arrayify(defaultAbiCoder.encode(['address[]', 'uint8', 'bytes'], [admins, adminThreshold, '0x']));

(async () => {
printLog('fetching fee data');
const feeData = await provider.getFeeData();
printObj({ feeData });
const options = getTxOptions(feeData, { maxFeePerGas, maxPriorityFeePerGas, gasPrice, gasLimit });
printObj({ tx_options: options });

printLog('loading contract factories');
// the ABIs for the contracts below must be manually downloaded/compiled
const gatewayFactory = await getContractFactory('AxelarGateway', wallet);
const authFactory = await getContractFactory('AxelarAuthWeighted', wallet);
const tokenDeployerFactory = await getContractFactory('TokenDeployer', wallet);
const gatewayProxyFactory = await getContractFactory('AxelarGatewayProxy', wallet);
printLog('contract factories loaded');

printLog(`deploying auth contract`);
const auth = await authFactory.deploy(paramsAuth).then((d) => d.deployed());
printLog(`deployed auth at address ${auth.address}`);
contracts.auth = auth.address;

printLog(`deploying token deployer contract`);
const tokenDeployer = await tokenDeployerFactory.deploy().then((d) => d.deployed());
printLog(`deployed token deployer at address ${tokenDeployer.address}`);
contracts.tokenDeployer = tokenDeployer.address;

printLog(`deploying gateway implementation contract`);
const gatewayImplementation = await gatewayFactory.deploy(auth.address, tokenDeployer.address).then((d) => d.deployed());
printLog(`deployed gateway implementation at address ${gatewayImplementation.address}`);
contracts.gatewayImplementation = gatewayImplementation.address;

printLog(`deploying gateway proxy contract`);
const gatewayProxy = await gatewayProxyFactory.deploy(gatewayImplementation.address, paramsProxy).then((d) => d.deployed());
printLog(`deployed gateway proxy at address ${gatewayProxy.address}`);
contracts.gatewayProxy = gatewayProxy.address;

printLog('transferring auth ownership');
await auth.transferOwnership(gatewayProxy.address, options);
printLog('transferred auth ownership. All done!');
})()
.catch((err) => {
console.error(err);
})
.finally(() => {
printObj({ contract_addresses: contracts });
});
24 changes: 24 additions & 0 deletions scripts/generate-admin-accounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

const { Wallet } = require('ethers');
const { printObj, printLog } = require('./utils');

const numKeys = process.argv[2] || 8;
printLog(`generating ${numKeys} admin accounts`);
generateAccounts(Number(numKeys));

async function generateAccounts(numKeys) {
var wallets = Array(numKeys);

for (let i = 0; i < numKeys; i++) {
wallets[i] = Wallet.createRandom();
const wallet = wallets[i];

printObj({"mnemonic": wallet.mnemonic["phrase"], "private_key": wallet.privateKey, "public_key": wallet.publicKey, "address": wallet.address});
}

const threshold = Math.floor(wallets.length / 2) + (wallets.length % 2);

printObj({"all_addresses": wallets.map(wallet => wallet.address)});
printObj({"threshold": threshold});
}
1 change: 0 additions & 1 deletion scripts/gmp-token-transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const transactions = {};
const options = getTxOptions(feeData, { maxFeePerGas, maxPriorityFeePerGas, gasPrice, gasLimit });
printObj({ tx_options: options });

printLog(`approving amount of ${amount}${symbol}`);
const gateway = await getContractAt('IAxelarGateway', gatewayAddress, wallet);
const tokenAddress = await gateway.tokenAddresses(symbol);
printLog(`token address for asset ${symbol} available at address ${tokenAddress}`);
Expand Down
22 changes: 20 additions & 2 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

const reader = require('readline-sync');
const { execSync } = require('child_process');
const { ethers } = require('hardhat');
const { sortBy } = require('lodash');
const {
utils: { computeAddress, parseUnits },
} = ethers;
} = require('ethers');

const getAddresses = (prefix, chain, role) => {
const keyID = execSync(`${prefix} "axelard q tss key-id ${chain} ${role}"`, {
Expand Down Expand Up @@ -77,6 +76,25 @@ module.exports = {
});
},

pubkeysToAddresses(pubkeys) {
return pubkeys.map(p => {
const pubkey = p.startsWith('0x') ? p : '0x' + p;
return computeAddress(pubkey);
});
},

getEVMAddresses(prefix, chain) {
const keyID = JSON.parse(execSync(`${prefix} "axelard q multisig key-id ${chain} --output json"`)).key_id;
const evmAddresses = JSON.parse(execSync(`${prefix} "axelard q evm address ${chain} --key-id ${keyID} --output json"`));
const sortedAddresses = sortBy(evmAddresses.addresses, (weightedAddress) => weightedAddress.address.toLowerCase());

const addresses = sortedAddresses.map(weightedAddress => weightedAddress.address);
const weights = sortedAddresses.map(weightedAddress => Number(weightedAddress.weight));
const threshold = Number(evmAddresses.threshold);

return { addresses, weights, threshold };
},

parseWei(str) {
if (!str) {
return;
Expand Down