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

add chain fusion adapter #276

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@graphql-typed-document-node/core": "^3.2.0",
"@solana/web3.js": "^1.87.3",
"async-retry": "^1.3.1",
"axios": "^0.21.0",
"axios": "^0.21.4",
"axios-rate-limit": "^1.3.0",
"bignumber.js": "^9.0.1",
"dotenv": "^8.2.0",
Expand Down
139 changes: 139 additions & 0 deletions src/adapters/chain-fusion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {
BridgeAdapter,
ContractEventParams,
PartialContractEventParams,
} from "../../helpers/bridgeAdapter.type";
import { getTxsBlockRangeEtherscan, wait } from "../../helpers/etherscan";
import { getTxsBlockRangeMerlinScan } from "../../helpers/merlin";
import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
import axios from 'axios';
import { EventData } from "../../utils/types";

async function get_erc2Contracts(){
let api_call = 'https://icrc-api.internetcomputer.org/api/v2/ledgers?network=mainnet&token_types=chain_key&sort_by=ledger_canister_id&include_total_supply_7d=false';
let response = await axios.get(api_call);
let erc20_contracts = [];
for (let i = 0; i < response.data.data.length; i++) {
let token_info = response.data.data[i];
if (token_info.token_type === 'chain_key') {
if (token_info.ckerc20_contract !== null) {
erc20_contracts.push(token_info.ckerc20_contract.address);
}
}
}
return erc20_contracts;
}

const eth_minter_address = "0xb25eA1D493B49a1DeD42aC5B1208cC618f9A9B80";
const eth_helper_contract = "0x7574eB42cA208A4f6960ECCAfDF186D627dCC175"
const erc20_helper_contract = "0x6abDA0438307733FC299e9C229FD3cc074bD8cC0"
const weth_contract_addresss = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"

const ercDepositEventParams: ContractEventParams = {
target: null,
topic: "ReceivedErc20(address, address, uint256, bytes32)",
abi: [
"event ReceivedErc20(address indexed erc20_contract_address, address indexed owner, uint256 amount, bytes32 indexed principal)",
],
argKeys: {
token: "erc20_contract_address",
from: "owner",
amount: "amount",
to: 'principal'
},
isDeposit: true,
};

const ercWithdrawalEventParams: ContractEventParams = {
target: null,
topic: "Transfer(address,address,uint256)",
abi: ["event Transfer(address indexed from, address indexed to, uint256 value)"],
argKeys: {
Copy link
Member

@vrtnd vrtnd Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. need to add token
  2. add import to /adapters/index.ts

u can run tests using npm run test chain-fusion 1000

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to add token for ETH as well, or should I use the WETH address?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the test, I am getting:

> test
> tsx ./src/adapters/test.ts chain-fusion 1000

Is there any specific output I should be looking for?

to: "to",
from: "from",
amount: "value",
},
isDeposit: false,
};

const ethDepositEventParams: ContractEventParams = {
target: null,
topic: "ReceivedEth(address, uint256, bytes32)",
abi: [
"event ReceivedEth(address indexed from, uint256 value, bytes32 indexed principal)",
],
argKeys: {
from: "from",
amount: "value",
to: 'principal'
},
isDeposit: true,
};

const nativeTokenTransferSignature = ["0x535741", "0x"];


function constructParams(chain: string) {
return async (fromBlock: number, toBlock: number) => {
const eventParams: PartialContractEventParams[] = [];

let ercContracts = await get_erc2Contracts();
for (let i = 0; i < ercContracts.length; i++) {
const ercContract = ercContracts[i];
// Erc20 deposits to the Erc20 helper contract
const ercDepositParams = {
...ercDepositEventParams,
target: erc20_helper_contract,
}
// Erc20 withdrawals through the Erc20 token contract
let ercWithdrawParams = {
...ercWithdrawalEventParams,
target: ercContract,
fixedEventData: {
from: eth_minter_address,
}
}
// We set the token address for the erc20 withdrawal event
if (ercWithdrawParams.argKeys) {
ercWithdrawParams.argKeys.token = ercContract;
}
eventParams.push(ercDepositParams, ercWithdrawParams);
}

// Eth deposits to the Ethereum helper contract
eventParams.push({
...ethDepositEventParams,
target: eth_helper_contract,
});

let eventLogData = await getTxDataFromEVMEventLogs("chain-fusion", chain, fromBlock, toBlock, eventParams);

// Eth withdrawals through native Eth transactions
const nativeEvents = await Promise.all(
(await getTxsBlockRangeEtherscan(chain, eth_minter_address, fromBlock, toBlock, {
includeSignatures: nativeTokenTransferSignature,
// Withdrawals are Eth native transfers where the from address is the minter
})).filter((tx:any) => {tx.from == eth_minter_address}).map((tx: any) => {
const event: EventData = {
txHash: tx.hash,
blockNumber: +tx.blockNumber,
from: tx.from,
to: tx.to,
token: weth_contract_addresss,
amount: tx.value,
isDeposit: false,
};
return event;
})
);
const allEvents = [...eventLogData, ...nativeEvents.flat()];
return allEvents;
};
}


const adapter: BridgeAdapter = {
ethereum: constructParams("ethereum"),
};

export default adapter;
2 changes: 2 additions & 0 deletions src/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import minibridge from "./minibridge";
import cometbridge from "./cometbridge";
import fastbtc from "./rootstock-fastbtc-bridge"
import crowdswap from "./crowdswap"
import chainfusion from "./chain-fusion"

export default {
polygon,
Expand Down Expand Up @@ -137,6 +138,7 @@ export default {
cometbridge,
fastbtc,
crowdswap,
chainfusion
} as {
[bridge: string]: BridgeAdapter;
};
13 changes: 13 additions & 0 deletions src/data/bridgeNetworkData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1485,4 +1485,17 @@ export default [
"Polygon"
]
},
{
id: 72,
displayName: "Chain-Fusion",
bridgeDbName: "chain-fusion",
iconLink: "icons:chain-fusion",
largeTxThreshold: 10000,
url: "https://dashboard.internetcomputer.org/",
chains: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u need to add at least 2 chains

"Ethereum",
],
chainMapping: {
},
},
] as BridgeNetwork[];