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

feat: supports gas payment for two-way calls #72

Merged
merged 17 commits into from
Apr 27, 2023
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
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ examples/metamask/abi/**.json
./test.js
./quick.json
local.json
temp.js
temp2.js
src/types

#Hardhat files
cache
Expand Down Expand Up @@ -136,4 +135,7 @@ target/
# Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
**/*.rs.bk

# Near wasm contract
*.wasm
10 changes: 7 additions & 3 deletions hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require('hardhat-gas-reporter');
require('solidity-coverage');

require('@typechain/hardhat');
/**
* @type import('hardhat/config').HardhatUserConfig
*/
Expand Down Expand Up @@ -29,9 +29,13 @@ module.exports = {
},
},
paths: {
sources: "./src/contracts",
sources: './src/contracts',
},
mocha: {
timeout: 200000
timeout: 200000,
},
typechain: {
outDir: 'src/types',
target: 'ethers-v5',
},
};
3,202 changes: 3,142 additions & 60 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axelar-network/axelar-local-dev",
"version": "1.4.2",
"version": "1.4.4",
"description": "",
"main": "dist/index.js",
"scripts": {
Expand Down Expand Up @@ -43,8 +43,7 @@
"fs-extra": "^10.1.0",
"ganache": "^7.1.0",
"lodash": "^4.17.21",
"near-workspaces": "^3.2.2",
"npm-run-all": "^4.1.5"
"near-workspaces": "^3.2.2"
},
"devDependencies": {
"@babel/eslint-parser": "^7.19.1",
Expand All @@ -68,6 +67,10 @@
"solhint": "^3.3.7",
"solidity-coverage": "^0.7.21",
"ts-jest": "^29.0.3",
"@typechain/hardhat": "^6.1.5",
"@typechain/ethers-v5": "^10.2.0",
"npm-run-all": "^4.1.5",
"typechain": "^8.1.1",
"typescript": "^4.7.4"
}
}
21 changes: 11 additions & 10 deletions src/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import { ethers, Wallet, Contract, providers } from 'ethers';
import { logger } from './utils';
import { getSignedExecuteInput, getRandomID, deployContract } from './utils';
import {
AxelarGateway,
AxelarGatewayProxy,
IAxelarGateway,
Auth,
TokenDeployer,
AxelarGasReceiver,
BurnableMintableCappedERC20,
AxelarGasReceiverProxy,
ConstAddressDeployer,
Create3Deployer,
GMPExpressService,
GMPExpressProxyDeployer,
} from './contracts';
import { AxelarGateway__factory as AxelarGatewayFactory } from './types/factories/@axelar-network/axelar-cgp-solidity/contracts/AxelarGateway__factory';
import { AxelarGateway } from './types/@axelar-network/axelar-cgp-solidity/contracts/AxelarGateway';
import { AxelarGasService__factory as AxelarGasServiceFactory } from './types/factories/@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService__factory';
import { AxelarGasService } from './types/@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService';
import http from 'http';

const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000';
Expand Down Expand Up @@ -76,8 +77,8 @@ export class Network {
adminWallets: Wallet[];
threshold: number;
lastRelayedBlock: number;
gateway: Contract;
gasService: Contract;
gateway: AxelarGateway;
gasService: AxelarGasService;
constAddressDeployer: Contract;
create3Deployer: Contract;
expressService: Contract;
Expand Down Expand Up @@ -122,10 +123,10 @@ export class Network {
[defaultAbiCoder.encode(['address[]', 'uint256[]', 'uint256'], [[this.operatorWallet.address], [1], 1])],
]);
const tokenDeployer = await deployContract(this.ownerWallet, TokenDeployer);
const gateway = await deployContract(this.ownerWallet, AxelarGateway, [auth.address, tokenDeployer.address]);
const gateway = await deployContract(this.ownerWallet, AxelarGatewayFactory, [auth.address, tokenDeployer.address]);
const proxy = await deployContract(this.ownerWallet, AxelarGatewayProxy, [gateway.address, params]);
await (await auth.transferOwnership(proxy.address)).wait();
this.gateway = new Contract(proxy.address, IAxelarGateway.abi, this.provider);
this.gateway = AxelarGatewayFactory.connect(proxy.address, this.provider);
logger.log(`Deployed at ${this.gateway.address}`);
return this.gateway;
}
Expand All @@ -148,7 +149,7 @@ export class Network {
[defaultAbiCoder.encode(['address[]', 'uint256[]', 'uint256'], [[this.operatorWallet.address], [1], 1])],
]);
const tokenDeployer = await deployContract(this.ownerWallet, TokenDeployer);
const gateway = await deployContract(this.ownerWallet, AxelarGateway, [auth.address, tokenDeployer.address]);
const gateway = await deployContract(this.ownerWallet, AxelarGatewayFactory, [auth.address, tokenDeployer.address]);
const implementationCode = await this.provider.getCode(gateway.address);
const implementationCodeHash = keccak256(implementationCode);
for (let i = 0; i < oldThreshold; i++) {
Expand All @@ -160,11 +161,11 @@ export class Network {
}
async deployGasReceiver(): Promise<Contract> {
logger.log(`Deploying the Axelar Gas Receiver for ${this.name}... `);
const gasService = await deployContract(this.ownerWallet, AxelarGasReceiver, [this.ownerWallet.address]);
const gasService = await deployContract(this.ownerWallet, AxelarGasServiceFactory, [this.ownerWallet.address]);
const gasReceiverProxy = await deployContract(this.ownerWallet, AxelarGasReceiverProxy);
await gasReceiverProxy.init(gasService.address, this.ownerWallet.address, '0x');

this.gasService = new Contract(gasReceiverProxy.address, AxelarGasReceiver.abi, this.provider);
this.gasService = AxelarGasServiceFactory.connect(gasReceiverProxy.address, this.provider);
logger.log(`Deployed at ${this.gasService.address}`);
return this.gasService;
}
Expand Down
24 changes: 9 additions & 15 deletions src/networkUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@ import { ethers, Wallet, Contract, providers, getDefaultProvider } from 'ethers'
import { merge } from 'lodash';
import { defaultAccounts, setJSON, httpGet, logger } from './utils';
import { Network, networks, NetworkOptions, NetworkInfo, NetworkSetup } from './Network';
import {
IAxelarGateway,
IAxelarGasService,
GMPExpressService,
AxelarGateway,
ConstAddressDeployer,
GMPExpressProxyDeployer,
Create3Deployer,
} from './contracts';
import { AxelarGateway__factory as AxelarGatewayFactory } from './types/factories/@axelar-network/axelar-cgp-solidity/contracts/AxelarGateway__factory';
import { AxelarGasService__factory as AxelarGasServiceFactory } from './types/factories/@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService__factory';
import { GMPExpressService, ConstAddressDeployer, GMPExpressProxyDeployer, Create3Deployer } from './contracts';

const { keccak256, id, solidityPack, toUtf8Bytes } = ethers.utils;

Expand Down Expand Up @@ -154,8 +148,8 @@ export async function getNetwork(urlOrProvider: string | providers.Provider, inf

chain.constAddressDeployer = new Contract(info.constAddressDeployerAddress, ConstAddressDeployer.abi, chain.provider);
chain.create3Deployer = new Contract(info.create3DeployerAddress, Create3Deployer.abi, chain.provider);
chain.gateway = new Contract(info.gatewayAddress, IAxelarGateway.abi, chain.provider);
chain.gasService = new Contract(info.gasReceiverAddress, IAxelarGasService.abi, chain.provider);
chain.gateway = AxelarGatewayFactory.connect(info.gatewayAddress, chain.provider);
chain.gasService = AxelarGasServiceFactory.connect(info.gasReceiverAddress, chain.provider);
chain.expressService = new Contract(info.expressServiceAddress, GMPExpressService.abi, chain.provider);
chain.expressProxyDeployer = new Contract(info.expressProxyDeployerAddress, GMPExpressProxyDeployer.abi, chain.provider);
//chain.usdc = await chain.getTokenContract('aUSDC');
Expand Down Expand Up @@ -223,12 +217,12 @@ export async function forkNetwork(chainInfo: ChainCloneData, options: NetworkOpt

//This section gets the admin accounts so we can unlock them in our fork to upgrade the gateway to a 'localized' version
const forkProvider = getDefaultProvider(chainInfo.rpc);
const gateway = new Contract(chainInfo.gateway, AxelarGateway.abi, forkProvider);
const gateway = AxelarGatewayFactory.connect(chainInfo.gateway, forkProvider);
const KEY_ADMIN_EPOCH = keccak256(toUtf8Bytes('admin-epoch'));
const adminEpoch = await gateway.getUint(KEY_ADMIN_EPOCH);
const PREFIX_ADMIN_THRESHOLD = keccak256(toUtf8Bytes('admin-threshold'));
const thresholdKey = keccak256(solidityPack(['bytes32', 'uint256'], [PREFIX_ADMIN_THRESHOLD, adminEpoch]));
const oldThreshold = await gateway.getUint(thresholdKey);
const oldThreshold = await gateway.getUint(thresholdKey).then((x) => x.toNumber());
const oldAdminAddresses: string[] = [];
for (let i = 0; i < oldThreshold; i++) {
const PREFIX_ADMIN = keccak256(toUtf8Bytes('admin'));
Expand Down Expand Up @@ -266,9 +260,9 @@ export async function forkNetwork(chainInfo: ChainCloneData, options: NetworkOpt
// Delete the line below and uncomment the line after when we deploy create3Deployer
await chain.deployCreate3Deployer();
//chain.create3Deployer = new Contract(chainInfo.create3Deployer, Create3Deployer.abi, chain.provider);
chain.gateway = new Contract(chainInfo.gateway, AxelarGateway.abi, chain.provider);
chain.gateway = AxelarGatewayFactory.connect(chainInfo.gateway, chain.provider);
await chain._upgradeGateway(oldAdminAddresses, oldThreshold);
chain.gasService = new Contract(chainInfo.AxelarGasService.address, IAxelarGasService.abi, chain.provider);
chain.gasService = AxelarGasServiceFactory.connect(chainInfo.AxelarGasService.address, chain.provider);

chain.tokens = {
uusdc: chain.name === 'Ethereum' ? 'USDC' : 'axlUSDC',
Expand Down
25 changes: 16 additions & 9 deletions src/relay/Command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

import { ethers, Contract } from 'ethers';
import { ethers, Contract, BigNumber, ContractReceipt } from 'ethers';
const { defaultAbiCoder } = ethers.utils;
import { networks } from '../Network';
import { CallContractArgs, CallContractWithTokenArgs, RelayData } from './types';
Expand All @@ -15,14 +15,15 @@ export class Command {
name: string;
data: any[];
encodedData: string;
post: ((options: any) => Promise<void>) | undefined;
post: ((options: any) => Promise<any>) | undefined;

constructor(
commandId: string,
name: string,
data: any[],
dataSignature: string[],
post: ((options: any) => Promise<void>) | undefined = undefined,
chain: string | null = null
post: ((options: any) => Promise<any>) | undefined = undefined,
chain: string | null = null,
) {
this.commandId = commandId;
this.name = name;
Expand All @@ -39,15 +40,16 @@ export class Command {
['string', 'string', 'address', 'bytes32'],
async (options: any) => {
const to = networks.find((chain) => chain.name == args.to);
if (!to) return;
if (!to) return undefined;

const contract = new Contract(args.destinationContractAddress, IAxelarExecutable.abi, to.relayerWallet);
const tx = await contract
const receipt: ContractReceipt = await contract
.execute(commandId, args.from, args.sourceAddress, args.payload, options)
.then((tx: any) => tx.wait());
relayData.callContract[commandId].execution = tx.transactionHash;
relayData.callContract[commandId].execution = receipt.transactionHash;
return receipt;
},
'evm'
'evm',
);
};

Expand All @@ -74,7 +76,9 @@ export class Command {
)
.then((tx: any) => tx.wait());
relayData.callContractWithToken[commandId].execution = receipt.transactionHash;
}
return receipt;
},
'evm'
);
};

Expand All @@ -92,6 +96,7 @@ export class Command {
);

relayData.callContract[commandId].execution = tx.hash;
return tx;
},
'aptos'
);
Expand All @@ -113,6 +118,8 @@ export class Command {
);

relayData.callContract[commandId].execution = tx.transactionReceipt.hash;

return tx;
},
'near'
);
Expand Down
Loading