From 2f6fed14e6ed5efca14175af32a18fb21877cf44 Mon Sep 17 00:00:00 2001 From: yarikMyroniuk Date: Fri, 4 Oct 2024 23:32:07 +0300 Subject: [PATCH 1/3] added-retrobridge-adapter --- .env.test | 3 +- package-lock.json | 2 +- src/adapters/index.ts | 2 + src/adapters/retrobridge/index.ts | 225 ++++++++++++++++++++++++++++++ src/data/bridgeNetworkData.ts | 53 +++++++ 5 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 src/adapters/retrobridge/index.ts diff --git a/.env.test b/.env.test index e6e7db20..25e818c3 100644 --- a/.env.test +++ b/.env.test @@ -1 +1,2 @@ -DB_URL="postgresql://postgres:password@localhost:5433/mydatabase" \ No newline at end of file +DB_URL="postgresql://postgres:password@localhost:5437/mydatabase" +ARBITRUM_RPC='https://palpable-shy-market.arbitrum-mainnet.quiknode.pro/b5717f910c08470e69aa9c8a9b1b540f9a29d47f' \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9784f4fc..ac2c7ac1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "bridges-server", + "name": "DefiLlamaIndexer", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/src/adapters/index.ts b/src/adapters/index.ts index 5c967eb1..490ca283 100644 --- a/src/adapters/index.ts +++ b/src/adapters/index.ts @@ -67,6 +67,7 @@ import minibridge from "./minibridge"; import cometbridge from "./cometbridge"; import fastbtc from "./rootstock-fastbtc-bridge" import crowdswap from "./crowdswap" +import retrobridge from "./retrobridge" export default { polygon, @@ -137,6 +138,7 @@ export default { cometbridge, fastbtc, crowdswap, + retrobridge, } as { [bridge: string]: BridgeAdapter; }; diff --git a/src/adapters/retrobridge/index.ts b/src/adapters/retrobridge/index.ts new file mode 100644 index 00000000..63c90dc1 --- /dev/null +++ b/src/adapters/retrobridge/index.ts @@ -0,0 +1,225 @@ +import { Chain } from "@defillama/sdk/build/general"; +import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type"; +import { constructTransferParams } from "../../helpers/eventParams"; +import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions"; +import { getTxsBlockRangeEtherscan, wait } from "../../helpers/etherscan"; +import { getTxsBlockRangeMerlinScan } from "../../helpers/merlin"; +import { getTxsBlockRangeBtrScan } from "../../helpers/btr"; +import { EventData } from "../../utils/types"; + +export const bridgesAddress = { + arbitrum: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + arbitrum_nova: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + ethereum: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + bsc: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + polygon: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + optimism: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + era: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + polygon_zkevm: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + base: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + linea: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + manta: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + scroll: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + mantle: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + metis: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + mode: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + blast: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + merlin: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + "b2-mainnet": ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + btr: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + xlayer: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + taiko: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + zklink: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + op_bnb: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + mint: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + avax: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + kroma: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + zora: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + gravity: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + zircuit: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + bob: ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + "rari_chain": ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], + "zeta_chain": ["0x817564ded16b378B0998a1880Cbb2B68c7886192"], +} as const; + +export const contractsAddress = { + arbitrum: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + arbitrum_nova: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + ethereum: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + bsc: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + polygon: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + optimism: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + era: ["0x22158e226D68D91378f30Ae42b6F6a039bcCACf8"], + polygon_zkevm: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + base: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + linea: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + manta: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + scroll: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + mantle: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + metis: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + mode: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + blast: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + merlin: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + "b2-mainnet": ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + btr: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + xlayer: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + taiko: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + zklink: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + op_bnb: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + mint: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + avax: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + kroma: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + zora: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + gravity: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + zircuit: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + bob: ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + "rari_chain": ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], + "zeta_chain": ["0xDcD3979c23B0A375e276f33c65c70b4199d0AF5A"], +} as const; + +const nativeTokens: Record = { + ethereum: "0x0000000000000000000000000000000000000000", + arbitrum: "0x0000000000000000000000000000000000000000", + optimism: "0x0000000000000000000000000000000000000000", + base: "0x0000000000000000000000000000000000000000", + linea: "0x0000000000000000000000000000000000000000", + blast: "0x0000000000000000000000000000000000000000", + scroll: "0x0000000000000000000000000000000000000000", + polygon: "0x0000000000000000000000000000000000000000", + bsc: "0x0000000000000000000000000000000000000000", + polygon_zkevm: "0x0000000000000000000000000000000000000000", + era: "0x0000000000000000000000000000000000000000", + arbitrum_nova: "0x0000000000000000000000000000000000000000", + merlin: "0x0000000000000000000000000000000000000000", + taiko: "0x0000000000000000000000000000000000000000", + btr: "0x0000000000000000000000000000000000000000", + zklink: "0x0000000000000000000000000000000000000000", +}; + +type SupportedChains = keyof typeof bridgesAddress; + +const constructParams = (chain: SupportedChains) => { + const bridgeAddress = bridgesAddress[chain]; + const contractAddress = contractsAddress[chain]; + + let eventParams = [] as any; + bridgeAddress.map((address: string) => { + const transferWithdrawalParams: PartialContractEventParams = constructTransferParams(address, false); + const transferDepositParams: PartialContractEventParams = constructTransferParams(address, true); + eventParams.push(transferWithdrawalParams, transferDepositParams); + }); + + if (nativeTokens.hasOwnProperty(chain)) { + return async (fromBlock: number, toBlock: number) => { + const eventLogData = await getTxDataFromEVMEventLogs("retrobridge", chain as Chain, fromBlock, toBlock, eventParams); + + const nativeEvents = await Promise.all([ + ...bridgeAddress.map(async (address: string, i: number) => { + await wait(300 * i); // for etherscan + let txs: any[] = []; + if (chain === "merlin") { + txs = await getTxsBlockRangeMerlinScan(address, fromBlock, toBlock, { + includeSignatures: ["0x"], + }); + } else if (chain === "btr") { + txs = await getTxsBlockRangeBtrScan(address, fromBlock, toBlock, { + includeSignatures: ["0x"], + }); + } else { + txs = await getTxsBlockRangeEtherscan(chain, address, fromBlock, toBlock, { + includeSignatures: ["0x"], + }); + } + const eventsRes: EventData[] = txs.map((tx: any) => { + const event: EventData = { + txHash: tx.hash, + blockNumber: +tx.blockNumber, + from: tx.from, + to: tx.to, + token: nativeTokens[chain], + amount: tx.value, + isDeposit: address.toLowerCase() === tx.to, + }; + return event; + }); + + return eventsRes; + }), + ...contractAddress.map(async (address: string, i: number) => { + await wait(300 * i); // for etherscan + let txs: any[] = []; + if (chain === "merlin") { + txs = await getTxsBlockRangeMerlinScan(address, fromBlock, toBlock, { + includeSignatures: ["0xddf252ad"], + }); + } else if (chain === "btr") { + txs = await getTxsBlockRangeBtrScan(address, fromBlock, toBlock, { + includeSignatures: ["0xddf252ad"], + }); + } else { + txs = await getTxsBlockRangeEtherscan(chain, address, fromBlock, toBlock, { + includeSignatures: ["0xddf252ad"], + }); + } + const eventsRes: EventData[] = txs.filter((tx: any) => String(tx.value) != "0").map((tx: any) => { + const event: EventData = { + txHash: tx.hash, + blockNumber: +tx.blockNumber, + from: tx.from, + to: tx.to, + token: nativeTokens[chain], + amount: tx.value, + isDeposit: address.toLowerCase() === tx.to, + }; + return event; + }); + + return eventsRes; + }) + ] + ); + const allEvents = [...eventLogData, ...nativeEvents.flat()]; + return allEvents; + }; + } else { + return async (fromBlock: number, toBlock: number) => + getTxDataFromEVMEventLogs("retrobridge", chain as Chain, fromBlock, toBlock, eventParams); + } +} + +const adapter: BridgeAdapter = { + ethereum: constructParams("ethereum"), + polygon: constructParams("polygon"), + avalanche: constructParams("avax"), + bsc: constructParams("bsc"), + arbitrum: constructParams("arbitrum"), + optimism: constructParams("optimism"), + "zksync era": constructParams("era"), + "polygon zkevm": constructParams("polygon_zkevm"), + "arbitrum nova": constructParams("arbitrum_nova"), + "x layer": constructParams("xlayer"), + opbnb: constructParams("op_bnb"), + linea: constructParams("linea"), + base: constructParams("base"), + metis: constructParams("metis"), + manta: constructParams("manta"), + mantle: constructParams("mantle"), + scroll: constructParams("scroll"), + merlin: constructParams("merlin"), + bsquared: constructParams("b2-mainnet"), + bitlayer: constructParams("btr"), + mint: constructParams("mint"), + kroma: constructParams("kroma"), + zora: constructParams("zora"), + gravity: constructParams("gravity"), + zircuit: constructParams("zircuit"), + bob: constructParams("bob"), + "rari chain": constructParams("rari_chain"), + "zeta chain": constructParams("zeta_chain"), + blast: constructParams("blast"), + taiko: constructParams("taiko"), + zklink: constructParams("zklink"), + mode: constructParams("mode"), +}; + +export default adapter; diff --git a/src/data/bridgeNetworkData.ts b/src/data/bridgeNetworkData.ts index cbe603d5..b5ec48e6 100644 --- a/src/data/bridgeNetworkData.ts +++ b/src/data/bridgeNetworkData.ts @@ -1484,4 +1484,57 @@ export default [ url: "https://scanner.crowdswap.org/", chains: ["Ethereum", "Arbitrum", "Optimism", "BSC", "Polygon"], }, + { + id: 72, + displayName: "RetroBridge", + bridgeDbName: "retrobridge", + iconLink: "icons:retrobridge", + largeTxThreshold: 10000, + url: 'https://retrobridge.io/?utm_source=defillama', + chains: [ + "Ethereum", + "Arbitrum", + "Arbitrum Nova", + "Optimism", + "Base", + "Linea", + "Blast", + "Scroll", + "BSC", + "X Layer", + "Taiko", + "ZkLink", + "ZKsync Era", + "Merlin", + "BSquared", + "Bitlayer", + "Mode", + "Manta", + "Polygon zkEVM", + "Polygon", + "Metis", + "Avalanche", + "opBNB", + "Gravity", + "Mint", + "Zora", + "Kroma", + "Zeta Chain", + "Rari Chain", + "Zircuit", + "BOB", + ], + chainMapping: { + "arbitrum nova": "arbitrum_nova", + "zksync era": "era", + "polygon zkevm": "polygon_zkevm", + bitlayer: "btr", + bsquared: "b2-mainnet", + "x layer": "xlayer", + opbnb: "op_bnb", + avalanche: "avax", + "zeta chain": "zeta_chain", + "rari chain": "rari_chain", + }, + }, ] as BridgeNetwork[]; From 0d504191c0fcc5059272ca1276b201d0dd2b280f Mon Sep 17 00:00:00 2001 From: yarikMyroniuk Date: Mon, 7 Oct 2024 23:37:15 +0300 Subject: [PATCH 2/3] feat/changed-retrobridge-adapter --- src/adapters/retrobridge/index.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/adapters/retrobridge/index.ts b/src/adapters/retrobridge/index.ts index 63c90dc1..7c09d3a8 100644 --- a/src/adapters/retrobridge/index.ts +++ b/src/adapters/retrobridge/index.ts @@ -150,15 +150,24 @@ const constructParams = (chain: SupportedChains) => { let txs: any[] = []; if (chain === "merlin") { txs = await getTxsBlockRangeMerlinScan(address, fromBlock, toBlock, { - includeSignatures: ["0xddf252ad"], + includeSignatures: [ + "0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3", + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + ], }); } else if (chain === "btr") { txs = await getTxsBlockRangeBtrScan(address, fromBlock, toBlock, { - includeSignatures: ["0xddf252ad"], + includeSignatures: [ + "0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3", + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + ], }); } else { txs = await getTxsBlockRangeEtherscan(chain, address, fromBlock, toBlock, { - includeSignatures: ["0xddf252ad"], + includeSignatures: [ + "0x769254a71d2f67d8ac6cb44f2803c0d05cfbcf9effadb6a984f10ff9de3df6c3", + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + ], }); } const eventsRes: EventData[] = txs.filter((tx: any) => String(tx.value) != "0").map((tx: any) => { From a901aefa642984b072ad1aaff6a2f30f8b4e5224 Mon Sep 17 00:00:00 2001 From: yarikMyroniuk Date: Mon, 7 Oct 2024 23:49:34 +0300 Subject: [PATCH 3/3] feat/changed-variables --- .env.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.env.test b/.env.test index 25e818c3..e6e7db20 100644 --- a/.env.test +++ b/.env.test @@ -1,2 +1 @@ -DB_URL="postgresql://postgres:password@localhost:5437/mydatabase" -ARBITRUM_RPC='https://palpable-shy-market.arbitrum-mainnet.quiknode.pro/b5717f910c08470e69aa9c8a9b1b540f9a29d47f' \ No newline at end of file +DB_URL="postgresql://postgres:password@localhost:5433/mydatabase" \ No newline at end of file