Skip to content

Commit

Permalink
Change the default refund address (#217)
Browse files Browse the repository at this point in the history
* chore: refactor getGasReceiverContractAddress by removing duplicated functions and move to AxelarQueryAPI

* chore: throw if invalid chain id

* chore: refactor `getGasReceiverContractAddress` to `getContractAddressFromConfig`

* feat: change the default refundAddress to `default_refund_collector` from config

* chore: fix tests

* feat: add instruction about valid contractKey

* chore: fix wrong contractkey
  • Loading branch information
npty authored Dec 8, 2022
1 parent 8a169ce commit c8e70db
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 59 deletions.
39 changes: 14 additions & 25 deletions src/libs/AxelarAssetTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ export class AxelarAssetTransfer {
await throwIfInvalidChainIds([fromChain, toChain], this.environment);
await this.axelarQueryApi.throwIfInactiveChains([fromChain, toChain]);

refundAddress = refundAddress || (await this.getGasReceiverContractAddress(fromChain));
refundAddress =
refundAddress ||
(await this.axelarQueryApi.getContractAddressFromConfig(
fromChain,
"default_refund_collector"
));

const { address } = await this.getDepositAddressFromRemote(
"wrap",
fromChain,
Expand Down Expand Up @@ -113,7 +119,12 @@ export class AxelarAssetTransfer {
await throwIfInvalidChainIds([fromChain, toChain], this.environment);
await this.axelarQueryApi.throwIfInactiveChains([fromChain, toChain]);

refundAddress = refundAddress || (await this.getGasReceiverContractAddress(fromChain));
refundAddress =
refundAddress ||
(await this.axelarQueryApi.getContractAddressFromConfig(
fromChain,
"default_refund_collector"
));

const { address: unwrapAddress } = await this.getDepositAddressFromRemote(
"unwrap",
Expand Down Expand Up @@ -203,7 +214,7 @@ export class AxelarAssetTransfer {
]);

const address = getCreate2Address(
await this.getDepositServiceContractAddress(fromChain),
await this.axelarQueryApi.getContractAddressFromConfig(fromChain, "deposit_service"),
hexSalt,
keccak256(
solidityPack(
Expand Down Expand Up @@ -389,17 +400,6 @@ export class AxelarAssetTransfer {
return JSON.parse(roomId)?.depositAddress;
}

async getGasReceiverContractAddress(chainName: string): Promise<string> {
if (!this.gasReceiverContract[chainName]) {
this.gasReceiverContract[chainName] = await this.getStaticInfo()
.then((body) => {
return body.assets.network[chainName.toLowerCase()]?.gas_service;
})
.catch(() => undefined);
}
return this.gasReceiverContract[chainName];
}

async getERC20Denom(chainId: string): Promise<string> {
const chainList: ChainInfo[] = await loadChains({ environment: this.environment });
const chainName = chainList.find(
Expand All @@ -420,17 +420,6 @@ export class AxelarAssetTransfer {
return this.evmDenomMap[chainName.toLowerCase()];
}

async getDepositServiceContractAddress(chainName: string): Promise<string> {
if (!this.depositServiceContract[chainName]) {
this.depositServiceContract[chainName] = await this.getStaticInfo()
.then((body) => {
return body.assets.network[chainName.toLowerCase()]?.deposit_service;
})
.catch(() => undefined);
}
return this.depositServiceContract[chainName];
}

async getStaticInfo(): Promise<Record<string, any>> {
if (!this.staticInfo) {
this.staticInfo = await fetch(s3[this.environment])
Expand Down
23 changes: 22 additions & 1 deletion src/libs/AxelarQueryAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import { RestService } from "../services";
import { AxelarQueryAPIConfig, BaseFeeResponse, Environment, EvmChain, GasToken } from "./types";
import { DEFAULT_ESTIMATED_GAS } from "./TransactionRecoveryApi/constants/contract";
import { AxelarQueryClient, AxelarQueryClientType } from "./AxelarQueryClient";
import fetch from "cross-fetch";
import {
ChainStatus,
FeeInfoResponse,
TransferFeeResponse,
} from "@axelar-network/axelarjs-types/axelar/nexus/v1beta1/query";
import { throwIfInvalidChainIds } from "../utils";
import { loadChains } from "../chains";
import s3 from "./TransactionRecoveryApi/constants/s3";

export class AxelarQueryAPI {
readonly environment: Environment;
Expand Down Expand Up @@ -222,7 +225,7 @@ export class AxelarQueryAPI {
* Get the asset config for an asset on a given chain given its denom
* @param denom
* @param chainName
* @returns
* @returns asset config
*/
public async getAssetConfigFromDenom(denom: string, chainName: string) {
if (!this.allAssets) await this._initializeAssets();
Expand All @@ -237,6 +240,24 @@ export class AxelarQueryAPI {
return result;
}

/**
* Get the contract address from the chainId and the contractKey
* @param chainId - the chainId of the chain
* @param contractKey - the key of the contract in the config file.
* A valid contractKey can be found here https://github.com/axelarnetwork/chains/blob/790f08350e792e27412ded6721c13ce78267fd72/testnet-config.json#L1951-L1954 e.g. ("gas_service", "deposit_service", "default_refund_collector")
* @returns the contract address
*/
public async getContractAddressFromConfig(chainId: string, contractKey: string): Promise<string> {
const chains = await loadChains({ environment: this.environment });
const selectedChain = chains.find((chain) => chain.id === chainId);
if (!selectedChain) throw `getContractAddressFromConfig() ${chainId} not found`;
const { chainName } = selectedChain;
return await fetch(s3[this.environment])
.then((res) => res.json())
.then((body) => body.assets.network[chainName.toLowerCase()][contractKey])
.catch(() => undefined);
}

/**
* Get a list of active chains.
* @returns an array of active chains
Expand Down
23 changes: 8 additions & 15 deletions src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ import {
import { callExecute, CALL_EXECUTE_ERROR } from "./helpers";
import { asyncRetry, sleep, throwIfInvalidChainIds } from "../../utils";
import { BatchedCommandsResponse } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/query";
import s3 from "./constants/s3";
import { Interface } from "ethers/lib/utils";
import { loadChains } from "../../chains";

export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
axelarQueryApi: AxelarQueryAPI;
Expand Down Expand Up @@ -236,7 +234,10 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
const evmWalletDetails = options?.evmWalletDetails || { useWindowEthereum: true };
const signer = this.getSigner(chain, evmWalletDetails);
const signerAddress = await signer.getAddress();
const gasReceiverAddress = await this.getGasReceiverContractAddress(chain);
const gasReceiverAddress = await this.axelarQueryApi.getContractAddressFromConfig(
chain,
"gas_service"
);
const nativeGasTokenSymbol = NATIVE_GAS_TOKEN_SYMBOL[chain];
const receipt = await signer.provider.getTransactionReceipt(txHash);

Expand Down Expand Up @@ -309,7 +310,10 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
const evmWalletDetails = options?.evmWalletDetails || { useWindowEthereum: true };
const signer = this.getSigner(chain, evmWalletDetails);
const signerAddress = await signer.getAddress();
const gasReceiverAddress = await this.getGasReceiverContractAddress(chain);
const gasReceiverAddress = await this.axelarQueryApi.getContractAddressFromConfig(
chain,
"gas_service"
);
const gasTokenContract = new ethers.Contract(gasTokenAddress, Erc20, signer.provider);
const gasTokenSymbol = await gasTokenContract.symbol().catch(() => undefined);

Expand Down Expand Up @@ -479,15 +483,4 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
const evmClient = new EVMClient(evmClientConfig);
return evmClient.getSigner();
}

public async getGasReceiverContractAddress(chainId: string): Promise<string> {
const chains = await loadChains({ environment: this.environment });
const selectedChain = chains.find((chain) => chain.id === chainId);
if (!selectedChain) throw `getGasReceiverContractAddress() ${chainId} not found`;
const { chainName } = selectedChain;
return await fetch(s3[this.environment])
.then((res) => res.json())
.then((body) => body.assets.network[chainName.toLowerCase()]?.gas_service)
.catch(() => "");
}
}
6 changes: 3 additions & 3 deletions src/libs/test/AxelarAssetTransfer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ describe("AxelarAssetTransfer", () => {
beforeEach(async () => {
jest.clearAllMocks();
jest
.spyOn(bridge, "getDepositServiceContractAddress")
.spyOn(bridge.axelarQueryApi, "getContractAddressFromConfig")
.mockResolvedValue("0xc1DCb196BA862B337Aa23eDA1Cb9503C0801b955");
jest.spyOn(bridge.axelarQueryApi, "getActiveChains").mockResolvedValue(activeChainsStub());
});
Expand All @@ -391,7 +391,7 @@ describe("AxelarAssetTransfer", () => {
jest.clearAllMocks();
jest.spyOn(bridge, "getDepositAddressFromRemote").mockResolvedValue({ address });
jest
.spyOn(bridge, "getDepositServiceContractAddress")
.spyOn(bridge.axelarQueryApi, "getContractAddressFromConfig")
.mockResolvedValue("0xc1DCb196BA862B337Aa23eDA1Cb9503C0801b955");
jest.spyOn(bridge.axelarQueryApi, "getActiveChains").mockResolvedValue(activeChainsStub());
});
Expand Down Expand Up @@ -427,7 +427,7 @@ describe("AxelarAssetTransfer", () => {
.mockResolvedValue({ address: unwrapAddress });
jest.spyOn(bridge, "getDepositAddress").mockResolvedValue(unwrapAddress);
jest
.spyOn(bridge, "getDepositServiceContractAddress")
.spyOn(bridge.axelarQueryApi, "getContractAddressFromConfig")
.mockResolvedValue("0xc1DCb196BA862B337Aa23eDA1Cb9503C0801b955");
jest.spyOn(bridge, "getERC20Denom").mockResolvedValue("wavax-wei");
jest.spyOn(bridge.axelarQueryApi, "getActiveChains").mockResolvedValue(activeChainsStub());
Expand Down
14 changes: 14 additions & 0 deletions src/libs/test/AxelarQueryAPI.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,18 @@ describe("AxelarQueryAPI", () => {
await expect(api.throwIfInactiveChains(["avalanche"])).resolves.toBeUndefined();
});
});

describe("getContractAddressFromConfig", () => {
let api: AxelarQueryAPI;

beforeEach(async () => {
api = new AxelarQueryAPI({ environment: Environment.TESTNET });
});

test("it should retrieve the gas receiver address remotely", async () => {
await api.getContractAddressFromConfig(EvmChain.MOONBEAM, "gas_service").then((res) => {
expect(res).toBeDefined();
});
});
});
});
17 changes: 2 additions & 15 deletions src/libs/test/TransactionRecoveryAPI/AxelarGMPRecoveryAPI.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ describe("AxelarDepositRecoveryAPI", () => {
api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET });
jest.clearAllMocks();
jest
.spyOn(api, "getGasReceiverContractAddress")
.spyOn(api.axelarQueryApi, "getContractAddressFromConfig")
.mockResolvedValue(gasReceiverContract.address);

jest.spyOn(api.axelarQueryApi, "getActiveChains").mockResolvedValue(activeChainsStub());
Expand Down Expand Up @@ -692,7 +692,7 @@ describe("AxelarDepositRecoveryAPI", () => {
jest.clearAllMocks();
api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET });
jest
.spyOn(api, "getGasReceiverContractAddress")
.spyOn(api.axelarQueryApi, "getContractAddressFromConfig")
.mockResolvedValueOnce(gasReceiverContract.address);
jest.spyOn(api.axelarQueryApi, "getActiveChains").mockResolvedValue(activeChainsStub());
});
Expand Down Expand Up @@ -1205,17 +1205,4 @@ describe("AxelarDepositRecoveryAPI", () => {
expect(mockGMPApi).toHaveBeenCalledTimes(1);
});
});
describe("getGasReceiverContractAddress", () => {
let api: AxelarGMPRecoveryAPI;

beforeEach(async () => {
api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET });
});

test("it should retrieve the gas receiver address remotely", async () => {
await api.getGasReceiverContractAddress(EvmChain.MOONBEAM).then((res) => {
expect(res).toBeDefined();
});
});
});
});

0 comments on commit c8e70db

Please sign in to comment.