From 40b33bd4ae1b9842894edd2013486710e477594d Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Fri, 26 Aug 2022 18:57:53 -0400 Subject: [PATCH 1/6] feature(gas service): adding the gasOperator address for fees and refunds --- contracts/gas-service/AxelarGasService.sol | 14 ++++++++-- contracts/interfaces/IAxelarGasService.sol | 3 ++ info/mainnet.json | 5 ++++ info/testnet.json | 6 ++++ scripts/deploy-upgradable.js | 32 ++++++++++++++++------ scripts/upgradable.js | 4 +-- test/gmp/AxelarGasService.js | 7 +++-- 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/contracts/gas-service/AxelarGasService.sol b/contracts/gas-service/AxelarGasService.sol index 5b43efe5..77f05b65 100644 --- a/contracts/gas-service/AxelarGasService.sol +++ b/contracts/gas-service/AxelarGasService.sol @@ -8,6 +8,12 @@ import '../util/Upgradable.sol'; // This should be owned by the microservice that is paying for gas. contract AxelarGasService is Upgradable, IAxelarGasService { + address public immutable gasOperator; + + constructor(address gasOperator_) { + gasOperator = gasOperator_; + } + // This is called on the source chain before calling the gateway to execute a remote contract. function payGasForContractCall( address sender, @@ -117,7 +123,9 @@ 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 { + if (msg.sender != gasOperator) revert NotOperator(); + if (receiver == address(0)) revert InvalidAddress(); for (uint256 i; i < tokens.length; i++) { @@ -137,7 +145,9 @@ contract AxelarGasService is Upgradable, IAxelarGasService { address payable receiver, address token, uint256 amount - ) external onlyOwner { + ) external { + if (msg.sender != gasOperator) revert NotOperator(); + if (receiver == address(0)) revert InvalidAddress(); if (token == address(0)) { diff --git a/contracts/interfaces/IAxelarGasService.sol b/contracts/interfaces/IAxelarGasService.sol index d8d4b00c..08c55e2d 100644 --- a/contracts/interfaces/IAxelarGasService.sol +++ b/contracts/interfaces/IAxelarGasService.sol @@ -9,6 +9,7 @@ interface IAxelarGasService is IUpgradable { error NothingReceived(); error TransferFailed(); error InvalidAddress(); + error NotOperator(); event GasPaidForContractCall( address indexed sourceAddress, @@ -121,4 +122,6 @@ interface IAxelarGasService is IUpgradable { address token, uint256 amount ) external; + + function gasOperator() external returns (address); } diff --git a/info/mainnet.json b/info/mainnet.json index 8005a9e3..5611d16a 100644 --- a/info/mainnet.json +++ b/info/mainnet.json @@ -4,6 +4,7 @@ "chainId": 1, "rpc": "https://mainnet.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605", "gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5", + "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x4154CF6eea0633DD9c4933E76a077fD7E9260738", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Ether", @@ -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", @@ -26,6 +28,7 @@ "chainId": 250, "gateway": "0x304acf330bbE08d1e512eefaa92F6a57871fD895", "rpc": "https://rpc.ftm.tools/", + "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x2879da536D9d107D6b92D95D7c4CFaA5De7088f4", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Fantom", @@ -37,6 +40,7 @@ "chainId": 137, "gateway": "0x6f015F16De9fC8791b234eF68D486d2bF203FBA8", "rpc": "https://polygon-rpc.com/", + "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0xc8E0b617c388c7E800a7643adDD01218E14a727a", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Matic", @@ -48,6 +52,7 @@ "chainId": 1284, "gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5", "rpc": "https://rpc.api.moonbeam.network", + "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x27927CD55db998b720214205e598aA9AD614AEE3", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Glimmer", diff --git a/info/testnet.json b/info/testnet.json index b46539cc..f41443fb 100644 --- a/info/testnet.json +++ b/info/testnet.json @@ -4,6 +4,7 @@ "chainId": 3, "rpc": "https://ropsten.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605", "gateway": "0xBC6fcce7c5487d43830a219CA6E7B83238B41e71", + "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Ether", @@ -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", @@ -28,6 +30,7 @@ "chainId": 4002, "gateway": "0x97837985Ec0494E7b9C71f5D3f9250188477ae14", "rpc": "https://rpc.testnet.fantom.network", + "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Fantom", @@ -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", @@ -52,6 +56,7 @@ "chainId": 1287, "gateway": "0x5769D84DD62a6fD969856c75c7D321b84d455929", "rpc": "https://moonbeam-alpha.api.onfinality.io/public", + "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "DEV", @@ -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", diff --git a/scripts/deploy-upgradable.js b/scripts/deploy-upgradable.js index 98e738c0..8dec932f 100644 --- a/scripts/deploy-upgradable.js +++ b/scripts/deploy-upgradable.js @@ -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.`); } @@ -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; @@ -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, ); @@ -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`); diff --git a/scripts/upgradable.js b/scripts/upgradable.js index d35a6ba3..a897e99d 100644 --- a/scripts/upgradable.js +++ b/scripts/upgradable.js @@ -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); diff --git a/test/gmp/AxelarGasService.js b/test/gmp/AxelarGasService.js index 07e709c0..26f739ea 100644 --- a/test/gmp/AxelarGasService.js +++ b/test/gmp/AxelarGasService.js @@ -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'; @@ -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); From 359b4fa6c7399210d1706ac0fe4b1f953cc8e182 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Fri, 26 Aug 2022 19:04:42 -0400 Subject: [PATCH 2/6] feature(gas service): added onlyOperator modifier --- contracts/gas-service/AxelarGasService.sol | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/contracts/gas-service/AxelarGasService.sol b/contracts/gas-service/AxelarGasService.sol index 77f05b65..df6cce14 100644 --- a/contracts/gas-service/AxelarGasService.sol +++ b/contracts/gas-service/AxelarGasService.sol @@ -14,6 +14,12 @@ contract AxelarGasService is Upgradable, IAxelarGasService { gasOperator = gasOperator_; } + modifier onlyOperator() { + if (msg.sender != gasOperator) revert NotOperator(); + + _; + } + // This is called on the source chain before calling the gateway to execute a remote contract. function payGasForContractCall( address sender, @@ -123,9 +129,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService { emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress); } - function collectFees(address payable receiver, address[] calldata tokens) external { - if (msg.sender != gasOperator) revert NotOperator(); - + function collectFees(address payable receiver, address[] calldata tokens) external onlyOperator { if (receiver == address(0)) revert InvalidAddress(); for (uint256 i; i < tokens.length; i++) { @@ -145,9 +149,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService { address payable receiver, address token, uint256 amount - ) external { - if (msg.sender != gasOperator) revert NotOperator(); - + ) external onlyOperator { if (receiver == address(0)) revert InvalidAddress(); if (token == address(0)) { From d3dfc91076ea61be67850a5f788b249dcb3bfb5e Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Fri, 26 Aug 2022 19:12:15 -0400 Subject: [PATCH 3/6] fix(test): gas service deployment --- test/gmp/GeneralMessagePassing.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/gmp/GeneralMessagePassing.js b/test/gmp/GeneralMessagePassing.js index c1426095..d64ce48d 100644 --- a/test/gmp/GeneralMessagePassing.js +++ b/test/gmp/GeneralMessagePassing.js @@ -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]); From 6e9f76545902bfffc9140b24fe54f546d1cad427 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Fri, 26 Aug 2022 19:24:18 -0400 Subject: [PATCH 4/6] fix(gas-service): renaming to gasCollector --- contracts/gas-service/AxelarGasService.sol | 14 +++++++------- contracts/interfaces/IAxelarGasService.sol | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/gas-service/AxelarGasService.sol b/contracts/gas-service/AxelarGasService.sol index df6cce14..d64f9ec0 100644 --- a/contracts/gas-service/AxelarGasService.sol +++ b/contracts/gas-service/AxelarGasService.sol @@ -8,14 +8,14 @@ import '../util/Upgradable.sol'; // This should be owned by the microservice that is paying for gas. contract AxelarGasService is Upgradable, IAxelarGasService { - address public immutable gasOperator; + address public immutable gasCollector; - constructor(address gasOperator_) { - gasOperator = gasOperator_; + constructor(address gasCollector_) { + gasCollector = gasCollector_; } - modifier onlyOperator() { - if (msg.sender != gasOperator) revert NotOperator(); + modifier onlyCollector() { + if (msg.sender != gasCollector) revert NotCollector(); _; } @@ -129,7 +129,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService { emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress); } - function collectFees(address payable receiver, address[] calldata tokens) external onlyOperator { + function collectFees(address payable receiver, address[] calldata tokens) external onlyCollector { if (receiver == address(0)) revert InvalidAddress(); for (uint256 i; i < tokens.length; i++) { @@ -149,7 +149,7 @@ contract AxelarGasService is Upgradable, IAxelarGasService { address payable receiver, address token, uint256 amount - ) external onlyOperator { + ) external onlyCollector { if (receiver == address(0)) revert InvalidAddress(); if (token == address(0)) { diff --git a/contracts/interfaces/IAxelarGasService.sol b/contracts/interfaces/IAxelarGasService.sol index 08c55e2d..a934d23e 100644 --- a/contracts/interfaces/IAxelarGasService.sol +++ b/contracts/interfaces/IAxelarGasService.sol @@ -9,7 +9,7 @@ interface IAxelarGasService is IUpgradable { error NothingReceived(); error TransferFailed(); error InvalidAddress(); - error NotOperator(); + error NotCollector(); event GasPaidForContractCall( address indexed sourceAddress, @@ -123,5 +123,5 @@ interface IAxelarGasService is IUpgradable { uint256 amount ) external; - function gasOperator() external returns (address); + function gasCollector() external returns (address); } From 2e37adf0a26374d2fd0ce90c9b3e9fe69a96719c Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Fri, 26 Aug 2022 20:16:26 -0400 Subject: [PATCH 5/6] fix(scripts): renaming to gasCollector --- info/mainnet.json | 10 +++++----- info/testnet.json | 12 ++++++------ scripts/deploy-upgradable.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/info/mainnet.json b/info/mainnet.json index 5611d16a..3384676c 100644 --- a/info/mainnet.json +++ b/info/mainnet.json @@ -4,7 +4,7 @@ "chainId": 1, "rpc": "https://mainnet.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605", "gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5", - "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", + "gasCollector": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x4154CF6eea0633DD9c4933E76a077fD7E9260738", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Ether", @@ -16,7 +16,7 @@ "chainId": 43114, "rpc": "https://api.avax.network/ext/bc/C/rpc", "gateway": "0x5029C0EFf6C34351a0CEc334542cDb22c7928f78", - "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", + "gasCollector": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0xB53C693544363912D2A034f70D9d98808D5E192a", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Avax", @@ -28,7 +28,7 @@ "chainId": 250, "gateway": "0x304acf330bbE08d1e512eefaa92F6a57871fD895", "rpc": "https://rpc.ftm.tools/", - "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", + "gasCollector": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x2879da536D9d107D6b92D95D7c4CFaA5De7088f4", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Fantom", @@ -40,7 +40,7 @@ "chainId": 137, "gateway": "0x6f015F16De9fC8791b234eF68D486d2bF203FBA8", "rpc": "https://polygon-rpc.com/", - "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", + "gasCollector": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0xc8E0b617c388c7E800a7643adDD01218E14a727a", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Matic", @@ -52,7 +52,7 @@ "chainId": 1284, "gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5", "rpc": "https://rpc.api.moonbeam.network", - "gasOperator": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", + "gasCollector": "0xa57adce1d2fe72949e4308867d894cd7e7de0ef2", "gasReceiver": "0x27927CD55db998b720214205e598aA9AD614AEE3", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Glimmer", diff --git a/info/testnet.json b/info/testnet.json index f41443fb..ef27a360 100644 --- a/info/testnet.json +++ b/info/testnet.json @@ -4,7 +4,7 @@ "chainId": 3, "rpc": "https://ropsten.infura.io/v3/a4812158fbab4a2aaa849e6f4a6dc605", "gateway": "0xBC6fcce7c5487d43830a219CA6E7B83238B41e71", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Ether", @@ -17,7 +17,7 @@ "chainId": 43113, "rpc": "https://api.avax-test.network/ext/bc/C/rpc", "gateway": "0xC249632c2D40b9001FE907806902f63038B737Ab", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Avax", @@ -30,7 +30,7 @@ "chainId": 4002, "gateway": "0x97837985Ec0494E7b9C71f5D3f9250188477ae14", "rpc": "https://rpc.testnet.fantom.network", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Fantom", @@ -43,7 +43,7 @@ "chainId": 80001, "gateway": "0xBF62ef1486468a6bd26Dd669C06db43dEd5B849B", "rpc": "https://polygon-mumbai.g.alchemy.com/v2/Ksd4J1QVWaOJAJJNbr_nzTcJBJU-6uP3", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Matic", @@ -56,7 +56,7 @@ "chainId": 1287, "gateway": "0x5769D84DD62a6fD969856c75c7D321b84d455929", "rpc": "https://moonbeam-alpha.api.onfinality.io/public", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "DEV", @@ -69,7 +69,7 @@ "chainId": 97, "gateway": "0x4D147dCb984e6affEEC47e44293DA442580A3Ec0", "rpc": "https://data-seed-prebsc-1-s1.binance.org:8545/", - "gasOperator": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", + "gasCollector": "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", "constAddressDeployer": "0x617179a15fEAa53Fa82ae80b0fc3E85b7359a748", "tokenName": "Binance Coin", diff --git a/scripts/deploy-upgradable.js b/scripts/deploy-upgradable.js index 8dec932f..5b0b27b0 100644 --- a/scripts/deploy-upgradable.js +++ b/scripts/deploy-upgradable.js @@ -7,7 +7,7 @@ const { outputJsonSync } = require('fs-extra'); const { defaultAbiCoder } = require('ethers/lib/utils'); function getImplementationArgs(contractName, chain) { - if (contractName === 'AxelarGasService') return [chain.gasOperator]; + if (contractName === 'AxelarGasService') return [chain.gasCollector]; if (contractName === 'AxelarDepositService') return []; throw new Error(`${contractName} is not supported.`); } From 6771b648a6cc7e6bdd5a71d24ea39e5a115c1de2 Mon Sep 17 00:00:00 2001 From: Kiryl Yermakou Date: Sat, 27 Aug 2022 20:43:50 -0400 Subject: [PATCH 6/6] feature(gas-service): adding amounts to collecting fees --- contracts/gas-service/AxelarGasService.sol | 19 +++++++++++++------ contracts/interfaces/IAxelarGasService.sol | 7 ++++++- test/gmp/AxelarGasService.js | 12 ++++++++++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/contracts/gas-service/AxelarGasService.sol b/contracts/gas-service/AxelarGasService.sol index d64f9ec0..4c2d3abc 100644 --- a/contracts/gas-service/AxelarGasService.sol +++ b/contracts/gas-service/AxelarGasService.sol @@ -129,18 +129,25 @@ contract AxelarGasService is Upgradable, IAxelarGasService { emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress); } - function collectFees(address payable receiver, address[] calldata tokens) external onlyCollector { + function collectFees( + address payable receiver, + address[] calldata tokens, + uint256[] calldata amounts + ) external onlyCollector { if (receiver == address(0)) revert InvalidAddress(); - for (uint256 i; i < tokens.length; i++) { + uint256 tokensLength = tokens.length; + if (tokensLength != amounts.length) revert InvalidAmounts(); + + for (uint256 i; i < tokensLength; i++) { address token = tokens[i]; + uint256 amount = amounts[i]; + if (amount == 0) revert InvalidAmounts(); if (token == address(0)) { - uint256 amount = address(this).balance; - if (amount > 0) receiver.transfer(amount); + if (amount <= address(this).balance) receiver.transfer(amount); } else { - uint256 amount = IERC20(token).balanceOf(address(this)); - if (amount > 0) _safeTransfer(token, receiver, amount); + if (amount <= IERC20(token).balanceOf(address(this))) _safeTransfer(token, receiver, amount); } } } diff --git a/contracts/interfaces/IAxelarGasService.sol b/contracts/interfaces/IAxelarGasService.sol index a934d23e..33bd4646 100644 --- a/contracts/interfaces/IAxelarGasService.sol +++ b/contracts/interfaces/IAxelarGasService.sol @@ -10,6 +10,7 @@ interface IAxelarGasService is IUpgradable { error TransferFailed(); error InvalidAddress(); error NotCollector(); + error InvalidAmounts(); event GasPaidForContractCall( address indexed sourceAddress, @@ -115,7 +116,11 @@ interface IAxelarGasService is IUpgradable { address refundAddress ) external payable; - function collectFees(address payable receiver, address[] calldata tokens) external; + function collectFees( + address payable receiver, + address[] calldata tokens, + uint256[] calldata amounts + ) external; function refund( address payable receiver, diff --git a/test/gmp/AxelarGasService.js b/test/gmp/AxelarGasService.js index 26f739ea..7b3128f0 100644 --- a/test/gmp/AxelarGasService.js +++ b/test/gmp/AxelarGasService.js @@ -201,9 +201,17 @@ describe('AxelarGasService', () => { .and.to.emit(testToken, 'Transfer') .withArgs(gasService.address, userWallet.address, gasFeeAmount); - await expect(gasService.connect(userWallet).collectFees(ownerWallet.address, [ADDRESS_ZERO, testToken.address])).to.be.reverted; + await expect( + gasService + .connect(userWallet) + .collectFees(ownerWallet.address, [ADDRESS_ZERO, testToken.address], [nativeGasFeeAmount, gasFeeAmount]), + ).to.be.reverted; - await expect(await gasService.connect(ownerWallet).collectFees(ownerWallet.address, [ADDRESS_ZERO, testToken.address])) + await expect( + await gasService + .connect(ownerWallet) + .collectFees(ownerWallet.address, [ADDRESS_ZERO, testToken.address], [nativeGasFeeAmount, gasFeeAmount]), + ) .to.changeEtherBalance(ownerWallet, nativeGasFeeAmount) .and.to.emit(testToken, 'Transfer') .withArgs(gasService.address, ownerWallet.address, gasFeeAmount);