diff --git a/src/adapters/circle/index.ts b/src/adapters/circle/index.ts new file mode 100644 index 00000000..b940455a --- /dev/null +++ b/src/adapters/circle/index.ts @@ -0,0 +1,79 @@ +import { Chain } from "@defillama/sdk/build/general"; +import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type"; +import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions"; + +/* +https://developers.circle.com/stablecoins/docs/evm-smart-contracts +*/ + +const contracts = { + ethereum: { TokenMessenger: "0xBd3fa81B58Ba92a82136038B25aDec7066af3155" }, + optimism: { TokenMessenger: "0x2B4069517957735bE00ceE0fadAE88a26365528f" }, + polygon: { TokenMessenger: "0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE" }, + base: { TokenMessenger: "0x1682Ae6375C4E4A97e4B583BC394c861A46D8962" }, + arbitrum: { TokenMessenger: "0x19330d10D9Cc8751218eaf51E8885D058642E08A" }, + avax: { TokenMessenger: "0x6B25532e1060CE10cc3B0A99e5683b91BFDe6982" }, +} as const; +type SupportedChains = keyof typeof contracts; + +const depositParams: PartialContractEventParams = { + target: "", + topic: "DepositForBurn(uint64,address,uint256,address,bytes32,uint32,bytes32,bytes32)", + abi: [ + "event DepositForBurn(uint64 indexed nonce, address indexed burnToken, uint256 amount, address indexed depositor, bytes32 mintRecipient, uint32 destinationDomain, bytes32 destinationTokenMessenger, bytes32 destinationCaller)", + ], + logKeys: { + blockNumber: "blockNumber", + txHash: "transactionHash", + }, + argKeys: { + amount: "amount", + from: "depositor", + to: "mintRecipient", + token: "burnToken", + }, + isDeposit: true, +}; + +const withdrawParams: PartialContractEventParams = { + target: "", + topic: "MintAndWithdraw(address,uint256,address)", + abi: [ + "event MintAndWithdraw(address indexed mintRecipient, uint256 amount, address indexed mintToken)", + ], + logKeys: { + blockNumber: "blockNumber", + txHash: "transactionHash", + }, + argKeys: { + amount: "amount", + to: "mintRecipient", + from: "mintRecipient", + token: "mintToken", + }, + isDeposit: false, +}; + +const constructParams = (chain: Chain) => { + + const chainConfig = contracts[chain as SupportedChains]; + + const eventParams: PartialContractEventParams[] = [ + { ...depositParams, target: chainConfig.TokenMessenger }, + { ...withdrawParams, target: chainConfig.TokenMessenger } + ]; + + return async (fromBlock: number, toBlock: number) => + getTxDataFromEVMEventLogs("circle", chain, fromBlock, toBlock, eventParams); +}; + +const adapter: BridgeAdapter = { + ethereum: constructParams("ethereum"), + optimism: constructParams("optimism"), + polygon: constructParams("polygon"), + base: constructParams("base"), + arbitrum: constructParams("arbitrum"), + avalanche: constructParams("avax") +}; + +export default adapter; diff --git a/src/adapters/index.ts b/src/adapters/index.ts index c62d8345..8093ea3b 100644 --- a/src/adapters/index.ts +++ b/src/adapters/index.ts @@ -44,9 +44,10 @@ import interport from "./interport-finance"; import shimmerbridge from "./shimmerbridge"; import butternetwork from "./butternetwork"; import xy from "./xy-finance"; +import circle from "./circle"; import garden from "./garden"; -import rootstock from './rootstock' -import mode from './mode' +import rootstock from "./rootstock"; +import mode from "./mode"; export default { polygon, @@ -96,6 +97,7 @@ export default { garden, rootstock, mode, + circle, } as { [bridge: string]: BridgeAdapter; }; diff --git a/src/data/bridgeNetworkData.ts b/src/data/bridgeNetworkData.ts index 7b70b4e7..6695f251 100644 --- a/src/data/bridgeNetworkData.ts +++ b/src/data/bridgeNetworkData.ts @@ -802,4 +802,16 @@ export default [ chains: ["Ethereum", "Mode"], destinationChain: "Mode", }, + { + id: 51, + displayName: "Circle CCTP", + bridgeDbName: "circle", + iconLink: "protocols:circle_cctp", + largeTxThreshold: 10000, + url: "", + chains: ["Ethereum", "Optimism", "Polygon", "Base", "Arbitrum", "Avalanche"], + chainMapping: { + avalanche: "avax", + }, + }, ] as BridgeNetwork[];