James Bachini

Chainlink CCIP | Cross-Chain Interoperability Protocol

Chainlink CCIP

From all the announcements at ETHcc, the release of Chainlink CCIP as a direct competitor to LayerZero for cross-chain communications and bridging technology, is perhaps the most interesting.

The inherent security risks associated with bridging technology means that Chainlink are in a good position to leverage their brand and security record to gain traction in the bridging infrastructure sub-sector. Rumours are circling that Aave and Synthetix are already working on integrations.

What Is Chainlink CCIP?

The Chainlink Cross-Chain Interoperability Protocol (CCIP) has been designed as a secure bridge between blockchains. It allows smooth data transition between different blockchains. By deploying a CCIP sender contract and a CCIP receiver contract on two different blockchains, users can send data from the sender to the receiver.

Given the inherent risks of cross-chain interoperability, a security-first mindset is being applied to CCIP. Some security features include an Active Risk Management network that monitors for malicious activity, decentralized oracle computation from a wide range of high-quality node operators with verifiable on-chain performance histories, and the off-chain reporting (OCR) protocol, which already secures significant value on several mainnet blockchains.

From the docs @ https://docs.chain.link

CCIP has been designed around three core use cases:

  1. Arbitrary Messaging It allows sending of encoded data to a smart contract on a different blockchain. This data allows developers to build out custom solutions and communicate between different contracts across multiple chains.
  2. Token Transfer This feature allows users to efficiently transfer tokens across blockchains either to smart contracts or directly to another account.
  3. Programmable Token Transfer Users can transfer tokens and send encoded instructions within a single transaction, offering myriad uses and combining the arbitrary messaging with the token transfer functions.

Fees can be paid using LINK, the native token, or in selected native gas coins of the source blockchain including ERC20 wrapped versions such as ETH/WETH for Ethereum, and MATIC/WMATIC for Polygon. In conclusion, Chainlink CCIP provides a secure, efficient and economical solution for overcoming the blockchain oracle problem.

Chainlink CCIP Supported Chains

At time of writing not all chains are supported and functionality is a bit hit and miss. For example from Ethereum you can bridge to Optimism but not Arbitrum and Polygon is supported but not for token transfers at this time.

There are more testnet deployments than there are mainnet so I expect over the next few months we will see a whole host of additional networks and bridging routes enabled.

Check here for a complete list of the current routes available: https://docs.chain.link/ccip/supported-networks#ethereum

Use Cases For Chainlink CCIP

In the ever evolving blockchain sector cross chain communications are going to become more important as we build horizontally across layer 2’s and appChains.

Chainlink CCIP can be useful for various applications, such as:

  • It can be used to bridge ERC20 tokens such as governance tokens and memecoins between different chains
  • It can be used as a bridge for NFT’s where a NFT is deposited in one contract and then minted as a synthetic asset on a desitnation chain.
  • It can facilitate cross-chain overcollateralized lending, allowing users to lend and borrow different crypto assets across multiple DeFi platforms on different chains to get the best rates.
  • It can transfer messaging between chains allowing for staking yields to be distributed from a source to multiple desitinations opening up the possibility for omnichain yield farming.
  • It could be used to build a diversified liquid staking token that stakes MATIC and ETH on the different chains and bridges and averages returns back to a single token on each chain, autocompouding the yield.

Chainlink CCIP Solidity Example

This is a stripped down version of the contract in the docs to try and make it easier to understand. The full code is available in the Solidity Snippets github repo: https://github.com/jamesbachini/Solidity-Snippets/blob/main/contracts/ChainlinkCCIP.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {IRouterClient} from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol";
import {OwnerIsCreator} from "@chainlink/contracts-ccip/src/v0.8/shared/access/OwnerIsCreator.sol";
import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol";
import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";

contract ChainlinkCCIP is OwnerIsCreator {
    error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees);

    IRouterClient router;
    LinkTokenInterface linkToken;

    constructor(address _router, address _link) {
        router = IRouterClient(_router);
        linkToken = LinkTokenInterface(_link);
    }

    function transferTokens(
        uint64 _destinationChainSelector,
        address _receiver,
        address _token,
        uint256 _amount
    )
        external
        onlyOwner
        returns (bytes32 messageId)
    {
        Client.EVM2AnyMessage memory evm2AnyMessage = _buildCCIPMessage(
            _receiver,
            _token,
            _amount,
            address(0)
        );
        uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage);
        if (fees > address(this).balance)
            revert NotEnoughBalance(address(this).balance, fees);
        IERC20(_token).approve(address(router), _amount);
        messageId = router.ccipSend{value: fees}(
            _destinationChainSelector,
            evm2AnyMessage
        );
        return messageId;
    }

    function _buildCCIPMessage(
        address _receiver,
        address _token,
        uint256 _amount,
        address _feeTokenAddress
    ) internal pure returns (Client.EVM2AnyMessage memory) {
        Client.EVMTokenAmount[]
            memory tokenAmounts = new Client.EVMTokenAmount[](1);
        Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({
            token: _token,
            amount: _amount
        });
        tokenAmounts[0] = tokenAmount;
        Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
            receiver: abi.encode(_receiver),
            data: "",
            tokenAmounts: tokenAmounts,
            extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0, strict: false})),
            feeToken: _feeTokenAddress
        });
        return evm2AnyMessage;
    }

    function withdraw(address _beneficiary, address _token) public onlyOwner {
        uint256 amountToken = IERC20(_token).balanceOf(address(this));
        IERC20(_token).transfer(_beneficiary, amountToken);
    }

    receive() external payable {}
}

Code Explainer

The code uses two main functions to initiate a transfer and then an internal function to build a CCIP message.

transferTokens() This external function transfers tokens across blockchains while paying fees in the native asset of the source chain. It does this by creating a CCIP message, checking if the contract has enough ETH to cover the transfer fee, approving the router contract to use the required tokens and then sending the CCIP message. The fees will be paid in the native tokens of the blockchain on which this contract is deployed i.e. on Polygon it will be paid in MATIC etc.

_buildCCIPMessage() This function is an internal pure function that creates a CCIP message with the necessary details. The CCIP message requires details about the receiver, token(s) involved, the amount of token(s) and the fee token.

Conlcusion

Chainlink has been building its secure off-chain oracle solutions for some time. These solutions allow smart contracts on the network to interact with off-chain data and APIs, providing pathways to extend the utility and capabilities of DeFi apps. The development and launch of Chainlink CCIP further solidifies its position in the industry and opens up a new business avenue.

By facilitating seamless and secure interaction between blockchain networks, Chainlink is playing a crucial role in the push towards backend interoperability, a key component for the future adoption of blockchain technology.

CCIP will enable users and developers to transfer tokens, assets, and general data across different blockchain networks. This protocol positions Chainlink to compete effectively with LayerZero and other cross-chain technologies, and sets the stage for Chainlink to see new growth in an emerging sub-sector.


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.