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

feature(gas service): adding the gasOperator #149

Merged
merged 6 commits into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
16 changes: 14 additions & 2 deletions contracts/gas-service/AxelarGasService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ import '../util/Upgradable.sol';

// This should be owned by the microservice that is paying for gas.
contract AxelarGasService is Upgradable, IAxelarGasService {
address public immutable gasCollector;

constructor(address gasCollector_) {
gasCollector = gasCollector_;
}

modifier onlyCollector() {
if (msg.sender != gasCollector) revert NotCollector();

_;
}

// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForContractCall(
address sender,
Expand Down Expand Up @@ -117,7 +129,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService {
emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress);
}

function collectFees(address payable receiver, address[] calldata tokens) external onlyOwner {
function collectFees(address payable receiver, address[] calldata tokens) external onlyCollector {
if (receiver == address(0)) revert InvalidAddress();

for (uint256 i; i < tokens.length; i++) {
Expand All @@ -137,7 +149,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService {
address payable receiver,
address token,
uint256 amount
) external onlyOwner {
) external onlyCollector {
if (receiver == address(0)) revert InvalidAddress();

if (token == address(0)) {
Expand Down
3 changes: 3 additions & 0 deletions contracts/interfaces/IAxelarGasService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IAxelarGasService is IUpgradable {
error NothingReceived();
error TransferFailed();
error InvalidAddress();
error NotCollector();

event GasPaidForContractCall(
address indexed sourceAddress,
Expand Down Expand Up @@ -121,4 +122,6 @@ interface IAxelarGasService is IUpgradable {
address token,
uint256 amount
) external;

function gasCollector() external returns (address);
}
5 changes: 5 additions & 0 deletions info/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"chainId": 1,
"rpc": "https://mainnet.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605",
"gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5",
"gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2",
"gasReceiver": "0x4154CF6eea0633DD9c4933E76a077fD7E9260738",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Ether",
Expand All @@ -15,6 +16,7 @@
"chainId": 43114,
"rpc": "https://api.avax.network/ext/bc/C/rpc",
"gateway": "0x5029C0EFf6C34351a0CEc334542cDb22c7928f78",
"gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2",
"gasReceiver": "0xB53C693544363912D2A034f70D9d98808D5E192a",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Avax",
Expand All @@ -26,6 +28,7 @@
"chainId": 250,
"gateway": "0x304acf330bbE08d1e512eefaa92F6a57871fD895",
"rpc": "https://rpc.ftm.tools/",
"gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2",
"gasReceiver": "0x2879da536D9d107D6b92D95D7c4CFaA5De7088f4",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Fantom",
Expand All @@ -37,6 +40,7 @@
"chainId": 137,
"gateway": "0x6f015F16De9fC8791b234eF68D486d2bF203FBA8",
"rpc": "https://polygon-rpc.com/",
"gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2",
"gasReceiver": "0xc8E0b617c388c7E800a7643adDD01218E14a727a",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Matic",
Expand All @@ -48,6 +52,7 @@
"chainId": 1284,
"gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5",
"rpc": "https://rpc.api.moonbeam.network",
"gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2",
"gasReceiver": "0x27927CD55db998b720214205e598aA9AD614AEE3",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Glimmer",
Expand Down
6 changes: 6 additions & 0 deletions info/testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"chainId": 3,
"rpc": "https://ropsten.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605",
"gateway": "0xBC6fcce7c5487d43830a219CA6E7B83238B41e71",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Ether",
Expand All @@ -16,6 +17,7 @@
"chainId": 43113,
"rpc": "https://api.avax-test.network/ext/bc/C/rpc",
"gateway": "0xC249632c2D40b9001FE907806902f63038B737Ab",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Avax",
Expand All @@ -28,6 +30,7 @@
"chainId": 4002,
"gateway": "0x97837985Ec0494E7b9C71f5D3f9250188477ae14",
"rpc": "https://rpc.testnet.fantom.network",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Fantom",
Expand All @@ -40,6 +43,7 @@
"chainId": 80001,
"gateway": "0xBF62ef1486468a6bd26Dd669C06db43dEd5B849B",
"rpc": "https://polygon-mumbai.g.alchemy.com/v2/Ksd4J1QVWaOJAJJNbr_nzTcJBJU-6uP3",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Matic",
Expand All @@ -52,6 +56,7 @@
"chainId": 1287,
"gateway": "0x5769D84DD62a6fD969856c75c7D321b84d455929",
"rpc": "https://moonbeam-alpha.api.onfinality.io/public",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "DEV",
Expand All @@ -64,6 +69,7 @@
"chainId": 97,
"gateway": "0x4D147dCb984e6affEEC47e44293DA442580A3Ec0",
"rpc": "https://data-seed-prebsc-1-s1.binance.org:8545/",
"gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC",
"gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6",
"constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748",
"tokenName": "Binance Coin",
Expand Down
32 changes: 23 additions & 9 deletions scripts/deploy-upgradable.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ const readlineSync = require('readline-sync');
const { outputJsonSync } = require('fs-extra');
const { defaultAbiCoder } = require('ethers/lib/utils');

function getImplementationArgs(contractName, chain) {
if (contractName === 'AxelarGasService') return [chain.gasOperator];
if (contractName === 'AxelarDepositService') return [];
throw new Error(`${contractName} is not supported.`);
}

function getInitArgs(contractName, chain) {
if (contractName == 'AxelarGasService') return '0x';
if (contractName == 'AxelarDepositService') return defaultAbiCoder.encode(['address', 'string'], [chain.gateway, chain.wrappedSymbol]);
if (contractName === 'AxelarGasService') return '0x';
if (contractName === 'AxelarDepositService') return defaultAbiCoder.encode(['address', 'string'], [chain.gateway, chain.wrappedSymbol]);
throw new Error(`${contractName} is not supported.`);
}

function getUpgradeArgs(contractName, chain) {
if (contractName == 'AxelarGasService') return '0x';
if (contractName == 'AxelarDepositService') return '0x';
if (contractName === 'AxelarGasService') return '0x';
if (contractName === 'AxelarDepositService') return '0x';
throw new Error(`${contractName} is not supported.`);
}

Expand All @@ -30,19 +37,25 @@ async function deploy(env, chains, wallet, artifactPath, contractName, deployTo)
const implementationJson = require(implementationPath);
const proxyJson = require(proxyPath);
for (const chain of chains) {
if (deployTo.length > 0 && deployTo.find((name) => chain.name == name) == null) continue;
if (deployTo.length > 0 && deployTo.find((name) => chain.name === name) === null) continue;
const rpc = chain.rpc;
const provider = getDefaultProvider(rpc);
console.log(`Deployer has ${(await provider.getBalance(wallet.address)) / 1e18} ${chain.tokenSymbol} on ${chain.name}.`);
}
const anwser = readlineSync.question('Proceed with deployment? (y/n). ');
if (anwser != 'y') return;
if (anwser !== 'y') return;
for (const chain of chains) {
if (deployTo.length > 0 && deployTo.find((name) => chain.name == name) == null) continue;
if (deployTo.length > 0 && deployTo.find((name) => chain.name === name) === null) continue;
const rpc = chain.rpc;
const provider = getDefaultProvider(rpc);
if (chain[contractName]) {
await upgradeUpgradable(chain[contractName], implementationJson, getUpgradeArgs(contractName, chain), wallet.connect(provider));
await upgradeUpgradable(
wallet.connect(provider),
chain[contractName],
implementationJson,
getImplementationArgs(contractName, chain),
getUpgradeArgs(contractName, chain),
);
console.log(`${chain.name} | Upgraded.`);
} else {
const key = contractName;
Expand All @@ -51,6 +64,7 @@ async function deploy(env, chains, wallet, artifactPath, contractName, deployTo)
wallet.connect(provider),
implementationJson,
proxyJson,
getImplementationArgs(contractName, chain),
getInitArgs(contractName, chain),
key,
);
Expand All @@ -63,7 +77,7 @@ async function deploy(env, chains, wallet, artifactPath, contractName, deployTo)

if (require.main === module) {
const env = process.argv[2];
if (env == null || (env != 'testnet' && env != 'mainnet'))
if (env === null || (env !== 'testnet' && env !== 'mainnet'))
throw new Error('Need to specify tesntet or local as an argument to this script.');

const chains = require(`../info/${env}.json`);
Expand Down
4 changes: 2 additions & 2 deletions scripts/upgradable.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ async function deployUpgradable(
return new Contract(proxy.address, implementationJson.abi, wallet);
}

async function upgradeUpgradable(proxyAddress, contractJson, setupParams, wallet) {
async function upgradeUpgradable(wallet, proxyAddress, contractJson, implementationParams = [], setupParams = '0x') {
const proxy = new Contract(proxyAddress, IUpgradable.abi, wallet);

const implementationFactory = new ContractFactory(contractJson.abi, contractJson.bytecode, wallet);

const implementation = await implementationFactory.deploy();
const implementation = await implementationFactory.deploy(...implementationParams);
await implementation.deployed();

const implementationCode = await wallet.provider.getCode(implementation.address);
Expand Down
7 changes: 5 additions & 2 deletions test/gmp/AxelarGasService.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('AxelarGasService', () => {
beforeEach(async () => {
const constAddressDeployer = await deployContract(ownerWallet, ConstAddressDeployer);

gasService = await deployUpgradable(constAddressDeployer.address, ownerWallet, GasService, GasServiceProxy);
gasService = await deployUpgradable(constAddressDeployer.address, ownerWallet, GasService, GasServiceProxy, [ownerWallet.address]);

const name = 'testToken';
const symbol = 'testToken';
Expand Down Expand Up @@ -211,7 +211,10 @@ describe('AxelarGasService', () => {

it('should upgrade the gas receiver implementation', async () => {
const prevImpl = await gasService.implementation();
await expect(upgradeUpgradable(gasService.address, GasService, '0x', ownerWallet)).to.emit(gasService, 'Upgraded');
await expect(upgradeUpgradable(ownerWallet, gasService.address, GasService, [ownerWallet.address])).to.emit(
gasService,
'Upgraded',
);

const newImpl = await gasService.implementation();
expect(await gasService.owner()).to.be.equal(ownerWallet.address);
Expand Down
4 changes: 3 additions & 1 deletion test/gmp/GeneralMessagePassing.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ describe('GeneralMessagePassing', () => {
destinationChainGateway = await deployGateway();
const constAddressDeployer = await deployContract(ownerWallet, ConstAddressDeployer);

sourceChainGasService = await deployUpgradable(constAddressDeployer.address, ownerWallet, GasService, GasServiceProxy);
sourceChainGasService = await deployUpgradable(constAddressDeployer.address, ownerWallet, GasService, GasServiceProxy, [
ownerWallet.address,
]);
tokenA = await deployContract(ownerWallet, MintableCappedERC20, [nameA, symbolA, decimals, capacity]);

tokenB = await deployContract(ownerWallet, MintableCappedERC20, [nameB, symbolB, decimals, capacity]);
Expand Down