Cross Chain Swaps with Circle’s CCTP and Axelar
Circle has created CCTP to natively transfer USDC across supported blockchains. In this tutorial, we’ll learn how to build a cross-chain USDC dApp using Circle’s Cross-Chain Transfer Protocol (CCTP) and Axelar’s General Message Passing (GMP).
With this approach, your users will be able to issue a single transaction with a GMP payload. On the backend, the application takes care of USDC bridging, plus any other action that the user wishes — as indicated in the payload. Axelar services, also working on the backend, can handle conversion and payment for destination-chain gas fees, so the user only has to transact once, using one gas token.
In this example, we will build a cross-chain swap dApp. It converts a native token from one chain to another chain, using native USDC as a routing asset. For example: send ETH to a contract on Ethereum and receive AVAX on Avalanche, or vice versa.
There are two parts we have to learn to achieve this:
- Sending a native USDC token cross-chain.
- Sending a swap payload cross-chain.
Part 1: Sending a native USDC token cross-chain
There are three components from Circle that we’ll use in this part:
- MessageTransmitter contract – to mint USDC at the destination chain.
- CircleBridge contract – to burn USDC at the source chain.
- Attestation API – to retrieve attestation to be used for minting USDC at the destination chain.
Let’s take a look at how to implement this step-by-step:
- Burn the given amount of USDC by calling the function
depositForBurn
at theTokenMessenger
contract. The example Solidity code is below. At this step, the contract does nothing except provide a function to burn the USDC in_depositForBurn
function.
CrosschainNativeSwap.sol
ITokenMessenger.sol
That’s it for the initial contract using CCTP. We’ll continue to add our business logic. Let’s try to integrate this with Axelar network to complete our cross-chain swap dApp.
Part 2: Sending a swap payload cross-chain
In this part, we’ll add logic in our contract to send a payload cross-chain with Axelar network.
- Upgrade our contract to include business logic and integrate with Axelar network.
CrosschainNativeSwap.sol
There’s a lot of new code added here. Let’s try to understand it, step by step:
Step 1 — Add the gasReceiver
variable and initialize it in the constructor. This handles destination-chain gas token conversion and fee payment, so the user need not transact more than once.
Step 2 — Add the siblings
variable and related functions so the admin can define connected contract addresses on the other chains.
Step 3 — Add the nativeTradeSendTrade
function. The client will send a transaction to call this function. This is the most important function in our contract. Here are the implementation details:
- Swap native token to USDC with low-level contract call.
- Send the USDC to the destination chain via CCTP
- Construct the swap payload to send to the AxelarGateway contract. The payload will be relayed by Axelar Relayer service to the destination contract. The destination contract address is defined by
addSibling
function. - Pay gas to the AxelarGasService contract with the native token. The required amount will be calculated off-chain by using AxelarJS-SDK on the client side. See more information about it here.
- Send
destinationChain
,destinationContractAddress
andpayload
to the AxelarGateway contract.
Step 4 — Upgrade a contract to extend AxelarExecutable interface and override _execute
function, so the contract can be called by Axelar Executor service at the destination chain.
- The function decodes
payload
to retrieve all information it needs for swap. - We correct the amount in
tradeData
bytes before the swap. - Approve USDC to the router contract and call the swap function, and refund if it fails.
And we’re done! Here is the demo that communicates with the completed contract.
Resources
- CrosschainNativeSwap contract: link
- Running Crosschain USDC Example with Hardhat: link
- Axelar Cross-chain USDC Demo: link
About Circle
Circle is a global financial technology firm that enables businesses of all sizes to harness the power of digital currencies and public blockchains for payments, commerce and financial applications worldwide. Circle is the issuer of USD Coin (USDC), one of the fastest growing dollar digital currencies powering always-on internet-native commerce and payments. Today, Circle’s transactional services, business accounts, and platform APIs are giving rise to a new generation of financial services and commerce applications that hold the promise of raising global economic prosperity for all through the frictionless exchange of financial value. Additionally, Circle operates SeedInvest, a leading startup fundraising platform in the U.S. Learn more at https://circle.com.