Skip to content

Commit aae09d9

Browse files
theiceemanvrtnd
andauthored
feat: support assetchain bridge (#364)
* feat: support assetchain bridge * specify actual source chains * Update bridgeNetworkData.ts --------- Co-authored-by: vrotend <vrotend@proton.me>
1 parent 60a3d6f commit aae09d9

File tree

3 files changed

+362
-1
lines changed

3 files changed

+362
-1
lines changed
Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
2+
import { Chain } from "@defillama/sdk/build/general";
3+
import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
4+
import { ethers } from "ethers";
5+
6+
const nullAddress = "0x0000000000000000000000000000000000000000";
7+
8+
// Step 1: Define contract addresses for your chain
9+
const contractAddresses = {
10+
assetchain: {
11+
tokens: [
12+
{
13+
token: "0x2B7C1342Cc64add10B2a79C8f9767d2667DE64B2", // USDC
14+
bridgeContract: "0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d",
15+
},
16+
{
17+
token: "0xDBDc8c7B96286899aB624F6a59dd0250DD4Ce9bC", // BTC
18+
bridgeContract: "0x08d4a11Fb4fFE7022deBbBbcBb7444005B09a2FC",
19+
},
20+
{
21+
token: "0x26E490d30e73c36800788DC6d6315946C4BbEa24", // USDT
22+
bridgeContract: "0x196434734f09DFE6D479b5a248a45cfbe516382a",
23+
},
24+
{
25+
token: "0xEc6943BB984AED25eC96986898721a7f8aB6212E", // WNT
26+
bridgeContract: "0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02",
27+
},
28+
],
29+
},
30+
bsc: {
31+
tokens: [
32+
{
33+
token: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", // USDT
34+
bridgeContract: "0x55d398326f99059fF775485246999027B3197955",
35+
},
36+
],
37+
},
38+
arbitrum: {
39+
tokens: [
40+
{
41+
token: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", // WNT
42+
bridgeContract: "0xAD4b9c1FbF4923061814dD9d5732EB703FaA53D4",
43+
},
44+
{
45+
token: "0x5116990d844bda038DBD037D943FcB7481b5Fee7", // RWA
46+
bridgeContract: "0x3096e7BFd0878Cc65be71f8899Bc4CFB57187Ba3",
47+
},
48+
{
49+
token: "0x6377C8cC083d7CEB49fD3eE1244351BFB86C961e", // WETH
50+
bridgeContract: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
51+
},
52+
{
53+
token: "0x475d2Ff7955c5359D31B19DC275be3a466f035D5", // USDT
54+
bridgeContract: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
55+
},
56+
],
57+
},
58+
base: {
59+
tokens: [
60+
{
61+
token: "0x5E007f834b6Ee2fcdA41631AD444b4dAAEc372b0", // USDC
62+
bridgeContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
63+
},
64+
{
65+
token: "0xEd87e9170152A12a4D3904F5cdE323b35d880858", // WETH
66+
bridgeContract: "0x4200000000000000000000000000000000000006",
67+
},
68+
],
69+
},
70+
ethereum: {
71+
tokens: [
72+
{
73+
token: "0x85FCf4D25895Eeb5306643777F1205331415F51a", // USDC
74+
bridgeContract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
75+
},
76+
{
77+
token: "0x26fa2991f15473B3502D767b49e5805753b8F7F8", // USDT
78+
bridgeContract: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
79+
},
80+
{
81+
token: "0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119", // WETH
82+
bridgeContract: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
83+
},
84+
{
85+
token: "0xc415231cc96d20d99248706403B7580bE560c140", // WBTC
86+
bridgeContract: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
87+
},
88+
],
89+
},
90+
} as {
91+
[chain: string]: {
92+
bridgeToken?: string;
93+
tokens: { token: string; bridgeContract: string }[];
94+
nativeToken?: string;
95+
bridgeVault?: string;
96+
};
97+
};
98+
99+
/* // Step 2: Define event parameters for native token bridging
100+
const nativeDepositParams: PartialContractEventParams = {
101+
target: "",
102+
topic: "Transfer(address,address,uint256)",
103+
abi: ["event Transfer(address indexed src, address indexed dst, uint256 wad)"],
104+
logKeys: {
105+
blockNumber: "blockNumber",
106+
txHash: "transactionHash",
107+
},
108+
argKeys: {
109+
amount: "wad",
110+
},
111+
txKeys: {
112+
from: "from",
113+
},
114+
fixedEventData: {
115+
token: "",
116+
to: "",
117+
},
118+
isDeposit: true,
119+
};
120+
121+
const nativeWithdrawalParams: PartialContractEventParams = {
122+
target: "",
123+
topic: "Transfer(address,address,uint256)",
124+
abi: ["event Transfer(address indexed src, address indexed dst, uint256 wad)"],
125+
logKeys: {
126+
blockNumber: "blockNumber",
127+
txHash: "transactionHash",
128+
},
129+
argKeys: {
130+
amount: "wad",
131+
to: "dst",
132+
},
133+
fixedEventData: {
134+
token: "",
135+
from: "",
136+
},
137+
isDeposit: false,
138+
}; */
139+
140+
141+
142+
/* // Step 3: Define event parameters for bridge token (e.g., your protocol's token)
143+
const bridgeTokenDepositParams: PartialContractEventParams = {
144+
target: "",
145+
topic: "Transfer(address,address,uint256)",
146+
topics: [ethers.utils.id("Transfer(address,address,uint256)"), null, ethers.utils.hexZeroPad(nullAddress, 32)],
147+
abi: ["event Transfer(address indexed from, address indexed to, uint256 value)"],
148+
logKeys: {
149+
blockNumber: "blockNumber",
150+
txHash: "transactionHash",
151+
},
152+
argKeys: {
153+
from: "from",
154+
amount: "value",
155+
},
156+
fixedEventData: {
157+
token: "",
158+
},
159+
isDeposit: true,
160+
};
161+
162+
const bridgeTokenWithdrawalParams: PartialContractEventParams = {
163+
target: "",
164+
topic: "Transfer(address,address,uint256)",
165+
topics: [ethers.utils.id("Transfer(address,address,uint256)"), ethers.utils.hexZeroPad(nullAddress, 32)],
166+
abi: ["event Transfer(address indexed from, address indexed to, uint256 value)"],
167+
logKeys: {
168+
blockNumber: "blockNumber",
169+
txHash: "transactionHash",
170+
},
171+
argKeys: {
172+
to: "to",
173+
amount: "value",
174+
},
175+
fixedEventData: {
176+
token: "",
177+
from: "",
178+
},
179+
isDeposit: false,
180+
}; */
181+
182+
// Step 4: Define event parameters for ERC-20 token bridging
183+
const ercDepositParams: PartialContractEventParams = {
184+
target: "",
185+
topic: "FulfilledTokens(string,address,string,string,uint256,uint256)",
186+
abi: ["event FulfilledTokens(string indexed fromUser, address indexed toUser, string fromChain, string toChain, uint256 amount, uint256 exchangeRate)"],
187+
logKeys: {
188+
blockNumber: "blockNumber",
189+
txHash: "transactionHash",
190+
},
191+
argKeys: {
192+
from: "fromUser",
193+
amount: "amount",
194+
},
195+
fixedEventData: {
196+
token: "",
197+
to: "",
198+
},
199+
argGetters: {
200+
from: (args: any) => {
201+
const fromUser = args[0]?.hash;
202+
if (!fromUser || typeof fromUser !== "string") {
203+
throw new Error(`Invalid fromUser: ${fromUser}`);
204+
}
205+
return fromUser;
206+
},
207+
to: (args: any) => {
208+
const toUser = args[1]; // Address
209+
if (!toUser || typeof toUser !== "string") {
210+
throw new Error(`Invalid toUser: ${toUser}`);
211+
}
212+
return toUser;
213+
},
214+
amount: (args: any) => {
215+
const amount = args[4]; // BigNumber
216+
return amount;
217+
},
218+
},
219+
isDeposit: true,
220+
};
221+
222+
const ercWithdrawalParams: PartialContractEventParams = {
223+
target: "",
224+
topic: "SentTokens(address,string,string,string,uint256,uint256)",
225+
abi: ["event SentTokens(address fromUser, string indexed toUser, string fromChain, string toChain, uint256 amount, uint256 exchangeRate)"],
226+
logKeys: {
227+
blockNumber: "blockNumber",
228+
txHash: "transactionHash",
229+
},
230+
argKeys: {
231+
from: "fromUser",
232+
amount: "amount",
233+
to: "toUser",
234+
},
235+
fixedEventData: {
236+
token: "",
237+
},
238+
argGetters: {
239+
from: (args: any) => {
240+
const fromUser = args[0]; // Address
241+
if (!fromUser || typeof fromUser !== "string") {
242+
throw new Error(`Invalid fromUser: ${fromUser}`);
243+
}
244+
return fromUser;
245+
},
246+
to: (args: any) => {
247+
const toUser = args[1]?.hash;
248+
if (!toUser || typeof toUser !== "string") {
249+
throw new Error(`Invalid toUser: ${toUser}`);
250+
}
251+
return toUser;
252+
},
253+
amount: (args: any) => {
254+
const amount = args[4]; // BigNumber
255+
return amount;
256+
},
257+
},
258+
259+
isDeposit: false,
260+
};
261+
262+
263+
// Step 5: Construct event parameters for your chain
264+
const constructParams = (chain: string) => {
265+
let eventParams: PartialContractEventParams[] = [];
266+
267+
const contractAddressesForChain = contractAddresses[chain];
268+
const bridgeVault = contractAddressesForChain?.bridgeVault;
269+
const nativeToken = contractAddressesForChain?.nativeToken;
270+
// const ercs = contractAddressesForChain?.ercs || [];
271+
const bridgeToken = contractAddressesForChain?.bridgeToken;
272+
// const bridgeContract = contractAddressesForChain?.bridgeContract;
273+
const tokens = contractAddressesForChain?.tokens || [];
274+
275+
// Native token bridging (e.g., MyChain's native token)
276+
/* if (bridgeVault && nativeToken) {
277+
const finalNativeDepositParams: PartialContractEventParams = {
278+
...nativeDepositParams,
279+
target: bridgeVault,
280+
fixedEventData: {
281+
token: nativeToken,
282+
to: bridgeVault,
283+
},
284+
};
285+
const finalNativeWithdrawalParams: PartialContractEventParams = {
286+
...nativeWithdrawalParams,
287+
target: bridgeVault,
288+
fixedEventData: {
289+
token: nativeToken,
290+
from: bridgeVault,
291+
},
292+
};
293+
eventParams.push(finalNativeDepositParams, finalNativeWithdrawalParams);
294+
} */
295+
296+
// Bridge token bridging (e.g., your protocol's token)
297+
/* if (bridgeToken) {
298+
const finalBridgeTokenDepositParams: PartialContractEventParams = {
299+
...bridgeTokenDepositParams,
300+
target: bridgeToken,
301+
fixedEventData: {
302+
token: bridgeToken,
303+
to: bridgeToken,
304+
},
305+
};
306+
const finalBridgeTokenWithdrawalParams: PartialContractEventParams = {
307+
...bridgeTokenWithdrawalParams,
308+
target: bridgeToken,
309+
fixedEventData: {
310+
token: bridgeToken,
311+
from: bridgeToken,
312+
},
313+
};
314+
eventParams.push(finalBridgeTokenDepositParams, finalBridgeTokenWithdrawalParams);
315+
} */
316+
317+
// ERC-20 token bridging
318+
for (let { token, bridgeContract } of tokens) {
319+
const finalErcDepositParams: PartialContractEventParams = {
320+
...ercDepositParams,
321+
target: bridgeContract, // Bridge contract for this token
322+
fixedEventData: {
323+
token: token, // ERC-20 token
324+
to: bridgeContract, // Bridge contract as recipient
325+
},
326+
};
327+
const finalErcWithdrawalParams: PartialContractEventParams = {
328+
...ercWithdrawalParams,
329+
target: bridgeContract, // Bridge contract for this token
330+
fixedEventData: {
331+
token: token, // ERC-20 token
332+
from: bridgeContract, // Bridge contract as sender
333+
},
334+
};
335+
eventParams.push(
336+
finalErcDepositParams,
337+
finalErcWithdrawalParams);
338+
}
339+
340+
// Return a function to fetch transaction data from event logs
341+
return async (fromBlock: number, toBlock: number) =>
342+
getTxDataFromEVMEventLogs("assetchainbridge", chain as Chain, fromBlock, toBlock, eventParams);
343+
};
344+
345+
// Step 6: Export the adapter
346+
const adapter: BridgeAdapter = Object.fromEntries(
347+
Object.keys(contractAddresses).map((chain) => [chain, constructParams(chain)])
348+
);
349+
350+
export default adapter;

src/adapters/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import flyover from "./rootstock-flyover";
8080
import universalx from "./universalx";
8181
import eclipse from "./eclipse";
8282
import layerzero from "./layerzero";
83+
import assetchainbridge from "./assetchain-bridge"
8384
import train from "./train";
8485
import fuel from "./fuel";
8586
import lighter from "./lighter";
@@ -167,6 +168,7 @@ export default {
167168
eclipse,
168169
layerzero,
169170
train,
171+
assetchainbridge,
170172
fuel,
171173
lighter,
172174
movement,

src/data/bridgeNetworkData.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2106,5 +2106,14 @@ export default [
21062106
url: "https://bridge.movementnetwork.xyz/",
21072107
chains: ["Ethereum", "Movement"],
21082108
destinationChain: "Movement",
2109-
},
2109+
}, {
2110+
id: 89,
2111+
displayName: "Asset Chain Bridge",
2112+
bridgeDbName: "assetchainbridge",
2113+
iconLink: "chain:assetchain",
2114+
largeTxThreshold: 10000,
2115+
url: "https://bridge.assetchain.org/",
2116+
chains: ["Ethereum", "Arbitrum", "BSC", "Base", "Assetchain"],
2117+
destinationChain: "Assetchain",
2118+
}
21102119
] as BridgeNetwork[];

0 commit comments

Comments
 (0)