From 9fd975ad5bd20312ca8008c7ebce6a1c2c24eabd Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 08:06:16 +0200 Subject: [PATCH 01/39] update billing --- src/content/ccip/billing.mdx | 24 ++++--- src/features/ccip/components/Billing.astro | 83 +++++++++++++++++++--- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/content/ccip/billing.mdx b/src/content/ccip/billing.mdx index a7485b65173..5e0b38c20ee 100644 --- a/src/content/ccip/billing.mdx +++ b/src/content/ccip/billing.mdx @@ -73,18 +73,24 @@ This cost is only relevant if the destination blockchain is a [L2 layer](https:/ The premium paid to CCIP service providers, including node operators running the [Decentralized Oracle Network](/ccip/concepts#decentralized-oracle-network-don) and [Risk Management Network](/ccip/concepts#risk-management-network) is calculated as follows: -- For token transfers or programmable transfers (token + data), the fee uses a percentage-based premium. For each token, the premium is calculated using the following expression: +- For token transfers or programmable transfers (token + data), the fees vary based on the [token pool type](/ccip/architecture#token-pools) and the [lanes](/ccip/concepts#lane): - ``` - tokenAmount * price * percentage - ``` + - **Lock and Unlock** token pools: Fees are based on a percentage-based premium. For each token, the premium is calculated using the following expression: - Where: + ``` + tokenAmount * price * percentage + ``` + + Where: + + - `tokenAmount`: The amount of tokens being transferred. + - `price`: Initially priced in USD and converted into the `feeToken`. + - `percentage`: The values are provided in the table below. + + - **Lock and Mint** and **Burn and Mint** token pools: The fee is a static amount for each transferred token. The values denominated in USD are provided in the table below. - - `tokenAmount`: The amount of tokens. - - `price`: Initially denominated in USD and translated into the `feeToken`. - - `percentage`: The values are listed in the table below. + **Note**: To determine the token pool type, refer to the CCIP supported networks on the [mainnet](/ccip/supported-networks/v1_2_0/mainnet) or [testnet](/ccip/supported-networks/v1_2_0/testnet) pages. -- For messaging (only data): The fee is a static amount. The values denominated in USD are listed in the table below. +- For messaging (only data): The fee is a static amount. The values denominated in USD are provided in the table below. diff --git a/src/features/ccip/components/Billing.astro b/src/features/ccip/components/Billing.astro index 3a80abbff9e..702badc55fe 100644 --- a/src/features/ccip/components/Billing.astro +++ b/src/features/ccip/components/Billing.astro @@ -3,30 +3,83 @@ Service Lanes - - Fee Token - - (Wrapped) Gas Token - LINK - - + Token Pool Type + Fee Token + + + + (Wrapped) Gas Token + LINK + - Token Transfers with/without messaging - All lanes + Token Transfers with/without messaging + Source: Ethereum + Lock and Unlock 0.07 % 0.063 % - Messaging - Ethereum + Lock and Mint + 0.50 USD + 0.45 USD + + + Burn and Mint + 0.50 USD + 0.45 USD + + + Destination: Ethereum + Lock and Unlock + 0.07 % + 0.063 % + + + Lock and Mint + 5.00 USD + 4.50 USD + + + Burn and Mint + 5.00 USD + 4.50 USD + + + Non-Ethereum + Lock and Unlock + 0.07 % + 0.063 % + + + Lock and Mint + 0.25 USD + 0.225 USD + + + Burn and Mint + 0.25 USD + 0.225 USD + + + + Messaging + Source: Ethereum + N/A + 0.50 USD + 0.45 USD + + + Destination: Ethereum + N/A 0.50 USD 0.45 USD Non-Ethereum + N/A 0.10 USD 0.09 USD @@ -34,8 +87,16 @@ From e257479923b00905b2fbaa717ad380cdd32a5d2f Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 08:18:39 +0200 Subject: [PATCH 02/39] add pool type --- .../ccip/components/supported-networks/LaneConfig.astro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/features/ccip/components/supported-networks/LaneConfig.astro b/src/features/ccip/components/supported-networks/LaneConfig.astro index 1da7ed89d77..9d3ccb01c97 100644 --- a/src/features/ccip/components/supported-networks/LaneConfig.astro +++ b/src/features/ccip/components/supported-networks/LaneConfig.astro @@ -90,6 +90,7 @@ let tokensWithExtraInfo: { rateLimiterConfig: { capacity: string; isEnabled: boolean; rate: string } name?: string decimals: number + poolType?: string }[] = [] const tokensReferenceData = loadReferenceData({ environment, version }).tokensReferenceData @@ -111,12 +112,14 @@ if (supportedTokens) { return !tokenData[sourceChainRefId].allowListEnabled }) .map((supportedToken) => { - const { tokenAddress, decimals } = tokensReferenceData[supportedToken][sourceChainRefId] + const tokenData = tokensReferenceData[supportedToken] + const { tokenAddress, decimals, poolType } = tokenData[sourceChainRefId] return { token: supportedToken, address: tokenAddress, rateLimiterConfig: supportedTokens[supportedToken].rateLimiterConfig, decimals: decimals, + poolType: poolType, } }) } @@ -204,6 +207,7 @@ if (supportedTokens) { Symbol Token Address Decimals + Token Pool Type {tokenWithExtraInfo.decimals} + {tokenWithExtraInfo.poolType} {tokenWithExtraInfo.rateLimiterConfig?.isEnabled ? display(tokenWithExtraInfo.rateLimiterConfig.capacity, tokenWithExtraInfo.decimals) + From 04bab7393fbfca033095b0304a9685bd2e28ea2f Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 08:31:21 +0200 Subject: [PATCH 03/39] WETH --- .../data/ccip/v1_2_0/mainnet/lanes.json | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/config/data/ccip/v1_2_0/mainnet/lanes.json b/src/config/data/ccip/v1_2_0/mainnet/lanes.json index b88547f0af1..1838452615b 100644 --- a/src/config/data/ccip/v1_2_0/mainnet/lanes.json +++ b/src/config/data/ccip/v1_2_0/mainnet/lanes.json @@ -424,6 +424,13 @@ "isEnabled": false, "rate": "0" } + }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } } }, "rateLimiterConfig": { @@ -519,6 +526,13 @@ "rate": "56000000000000000" } }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } + }, "rsETH": { "rateLimiterConfig": { "capacity": "500000000000000000000", @@ -822,6 +836,13 @@ "isEnabled": false, "rate": "0" } + }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } } }, "rateLimiterConfig": { @@ -864,6 +885,13 @@ "rate": "56000000000000000" } }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } + }, "rsETH": { "rateLimiterConfig": { "capacity": "500000000000000000000", @@ -1077,6 +1105,13 @@ "rate": "56000000000000000" } }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } + }, "rsETH": { "rateLimiterConfig": { "capacity": "500000000000000000000", @@ -1181,6 +1216,13 @@ "rate": "56000000000000000" } }, + "WETH": { + "rateLimiterConfig": { + "capacity": "114000000000000000000", + "isEnabled": true, + "rate": "32000000000000000" + } + }, "rsETH": { "rateLimiterConfig": { "capacity": "500000000000000000000", From f385a3375fcf6adef0867d3622be52844f4245b1 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 08:59:28 +0200 Subject: [PATCH 04/39] nit --- src/content/ccip/billing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/ccip/billing.mdx b/src/content/ccip/billing.mdx index 5e0b38c20ee..2e3f0992910 100644 --- a/src/content/ccip/billing.mdx +++ b/src/content/ccip/billing.mdx @@ -87,7 +87,7 @@ The premium paid to CCIP service providers, including node operators running the - `price`: Initially priced in USD and converted into the `feeToken`. - `percentage`: The values are provided in the table below. - - **Lock and Mint** and **Burn and Mint** token pools: The fee is a static amount for each transferred token. The values denominated in USD are provided in the table below. + - **Lock and Mint** and **Burn and Mint** token pools: The fee is a static amount. The values denominated in USD are provided in the table below. **Note**: To determine the token pool type, refer to the CCIP supported networks on the [mainnet](/ccip/supported-networks/v1_2_0/mainnet) or [testnet](/ccip/supported-networks/v1_2_0/testnet) pages. From c259ad0f1c8365475a75f2b97df8c64ed09f9d3e Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 16:03:55 +0200 Subject: [PATCH 05/39] add mechanism --- src/config/data/ccip/types.ts | 9 +- .../supported-networks/ChainConfig.astro | 1 + .../supported-networks/LaneConfig.astro | 96 ++++++++++++++----- 3 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/config/data/ccip/types.ts b/src/config/data/ccip/types.ts index 30fe35d01bb..3497a90ca34 100644 --- a/src/config/data/ccip/types.ts +++ b/src/config/data/ccip/types.ts @@ -20,10 +20,7 @@ export type DestinationsLaneConfig = { [destinationChain: string]: LaneConfig } -enum PoolType { - LockRelease = "lockRelease", - BurnMint = "burnMint", -} +export type PoolType = "lockRelease" | "burnMint" | "usdc" type PoolInfo = { tokenAddress: string @@ -50,7 +47,9 @@ export type LanesConfig = { } export type TokensConfig = { - [token: string]: PoolInfo + [token: string]: { + [chain: string]: PoolInfo + } } export enum Environment { diff --git a/src/features/ccip/components/supported-networks/ChainConfig.astro b/src/features/ccip/components/supported-networks/ChainConfig.astro index ea7fd3d8748..8dcf8f4d6f9 100644 --- a/src/features/ccip/components/supported-networks/ChainConfig.astro +++ b/src/features/ccip/components/supported-networks/ChainConfig.astro @@ -135,6 +135,7 @@ const laneReferenceData = loadReferenceData({ environment, version }).lanesRefer laneConfig={laneConfig} sourceChain={sourceChainKey} sourceChainRefId={sourceChainRefId} + destinationChainRefId={destinationChainRefId} destinationChainSelector={destinationChainSelector} environment={environment} version={version} diff --git a/src/features/ccip/components/supported-networks/LaneConfig.astro b/src/features/ccip/components/supported-networks/LaneConfig.astro index 9d3ccb01c97..f3d8da66e8c 100644 --- a/src/features/ccip/components/supported-networks/LaneConfig.astro +++ b/src/features/ccip/components/supported-networks/LaneConfig.astro @@ -1,6 +1,5 @@ --- -import { LaneConfig } from "@config/data/ccip/types" -import { loadReferenceData, Environment, Version } from "@config/data/ccip/" +import { loadReferenceData, Environment, Version, PoolType, LaneConfig } from "@config/data/ccip/" import { SupportedChain } from "@config" import { Address, Aside, CopyText } from "@components" import BigNumber from "bignumber.js" @@ -12,14 +11,22 @@ type ConfigProps = { laneConfig: LaneConfig sourceChain: SupportedChain // key in SupportedChain sourceChainRefId: string // id in reference directory + destinationChainRefId: string // id in reference directory destinationChainSelector: string environment: Environment version: Version } const contactUrl = "https://chainlinkcommunity.typeform.com/ccip-form?typeform-source=docs.chain.link#ref_id=ccip_docs" -const { laneConfig, sourceChain, environment, sourceChainRefId, version, destinationChainSelector } = - Astro.props as ConfigProps +const { + laneConfig, + sourceChain, + environment, + sourceChainRefId, + destinationChainRefId, + version, + destinationChainSelector, +} = Astro.props as ConfigProps const { rateLimiterConfig, supportedTokens, onRamp } = laneConfig const normalizeNumber = (bigNum: BigNumber, decimals: number = 18) => { @@ -84,44 +91,74 @@ if (!explorerUrl) throw Error(`Explorer url not found for ${sourceChain}`) const onRampExplorerUrl = getExplorerAddressUrl(explorerUrl)(onRamp) -let tokensWithExtraInfo: { +interface TokenExtraInfo { token: string - address: any + address: string rateLimiterConfig: { capacity: string; isEnabled: boolean; rate: string } name?: string decimals: number - poolType?: string -}[] = [] + poolMechanism?: string +} + +let tokensWithExtraInfo: TokenExtraInfo[] = [] + +const determineMechanism = ( + sourcePoolType: PoolType | undefined, + destinationPoolType: PoolType | undefined +): string => { + if (!sourcePoolType || !destinationPoolType) { + console.error(`Pool types not found for token on ${sourceChainRefId} to ${destinationChainRefId}`) + return "" + } else if (sourcePoolType === "lockRelease" && destinationPoolType === "burnMint") { + return "Lock & Mint" + } else if (sourcePoolType === "lockRelease" && destinationPoolType === "lockRelease") { + return "Lock & Unlock" + } else if ( + (sourcePoolType === "burnMint" && destinationPoolType === "burnMint") || + (sourcePoolType === "usdc" && destinationPoolType === "usdc") + ) { + return "Burn & Mint" + } else { + console.error( + `Unsupported pool mechanism ${sourcePoolType}-${destinationPoolType} on ${sourceChainRefId} to ${destinationChainRefId}` + ) + return "" + } +} const tokensReferenceData = loadReferenceData({ environment, version }).tokensReferenceData if (supportedTokens) { - tokensWithExtraInfo = Object.keys(supportedTokens) - .filter((supportedToken) => { + tokensWithExtraInfo = Object.entries(supportedTokens) + .filter(([supportedToken]) => { const tokenData = tokensReferenceData[supportedToken] - if (!tokenData) { - console.error(`Token data not found for supportedToken: ${supportedToken}`) - return false - } - if (!tokenData[sourceChainRefId]) { - console.error( - `Chain reference data not found for supportedToken: ${supportedToken}, chainRefId: ${sourceChainRefId}` - ) + if (!tokenData || !tokenData[sourceChainRefId]) { + console.error(`Data not found for supportedToken: ${supportedToken}, chainRefId: ${sourceChainRefId}`) return false } return !tokenData[sourceChainRefId].allowListEnabled }) - .map((supportedToken) => { + .map(([supportedToken, { rateLimiterConfig }]): TokenExtraInfo | null => { const tokenData = tokensReferenceData[supportedToken] - const { tokenAddress, decimals, poolType } = tokenData[sourceChainRefId] + const sourceData = tokenData[sourceChainRefId] + const destinationData = tokenData[destinationChainRefId] + + if (!sourceData || !destinationData) { + console.error(`Pool type not found for token: ${supportedToken}`) + return null + } + + const mechanism = determineMechanism(sourceData.poolType, destinationData.poolType) + return { token: supportedToken, - address: tokenAddress, - rateLimiterConfig: supportedTokens[supportedToken].rateLimiterConfig, - decimals: decimals, - poolType: poolType, + address: sourceData.tokenAddress, + rateLimiterConfig: rateLimiterConfig, + decimals: sourceData.decimals, + poolMechanism: mechanism, } }) + .filter((item): item is TokenExtraInfo => item !== null && item.token !== undefined) } --- @@ -207,7 +244,14 @@ if (supportedTokens) { Symbol Token Address Decimals - Token Pool Type + + + {tokenWithExtraInfo.decimals} - {tokenWithExtraInfo.poolType} + {tokenWithExtraInfo.poolMechanism} {tokenWithExtraInfo.rateLimiterConfig?.isEnabled ? display(tokenWithExtraInfo.rateLimiterConfig.capacity, tokenWithExtraInfo.decimals) + From 18d37af6c30d81e7ab9c81c5c67508e4f0bd23c2 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 16:19:28 +0200 Subject: [PATCH 06/39] add mechanism --- .../components/supported-networks/LaneConfig.astro | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/features/ccip/components/supported-networks/LaneConfig.astro b/src/features/ccip/components/supported-networks/LaneConfig.astro index f3d8da66e8c..602f7ae2bc2 100644 --- a/src/features/ccip/components/supported-networks/LaneConfig.astro +++ b/src/features/ccip/components/supported-networks/LaneConfig.astro @@ -103,14 +103,19 @@ interface TokenExtraInfo { let tokensWithExtraInfo: TokenExtraInfo[] = [] const determineMechanism = ( + supportedToken: string, sourcePoolType: PoolType | undefined, destinationPoolType: PoolType | undefined ): string => { if (!sourcePoolType || !destinationPoolType) { - console.error(`Pool types not found for token on ${sourceChainRefId} to ${destinationChainRefId}`) + console.error( + `Pool types not found for token on ${sourceChainRefId} to ${destinationChainRefId} for token ${supportedToken}` + ) return "" } else if (sourcePoolType === "lockRelease" && destinationPoolType === "burnMint") { return "Lock & Mint" + } else if (sourcePoolType === "burnMint" && destinationPoolType === "lockRelease") { + return "Burn & Unlock" } else if (sourcePoolType === "lockRelease" && destinationPoolType === "lockRelease") { return "Lock & Unlock" } else if ( @@ -120,7 +125,7 @@ const determineMechanism = ( return "Burn & Mint" } else { console.error( - `Unsupported pool mechanism ${sourcePoolType}-${destinationPoolType} on ${sourceChainRefId} to ${destinationChainRefId}` + `Unsupported pool mechanism ${sourcePoolType}-${destinationPoolType} on ${sourceChainRefId} to ${destinationChainRefId} for token ${supportedToken}` ) return "" } @@ -148,7 +153,7 @@ if (supportedTokens) { return null } - const mechanism = determineMechanism(sourceData.poolType, destinationData.poolType) + const mechanism = determineMechanism(supportedToken, sourceData.poolType, destinationData.poolType) return { token: supportedToken, From df2284c98026a72c4b2f158bca684f4302e67ce3 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 17:04:18 +0200 Subject: [PATCH 07/39] add mechanism --- .../ccip/components/supported-networks/LaneConfig.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/ccip/components/supported-networks/LaneConfig.astro b/src/features/ccip/components/supported-networks/LaneConfig.astro index 602f7ae2bc2..327a78e9c24 100644 --- a/src/features/ccip/components/supported-networks/LaneConfig.astro +++ b/src/features/ccip/components/supported-networks/LaneConfig.astro @@ -115,7 +115,7 @@ const determineMechanism = ( } else if (sourcePoolType === "lockRelease" && destinationPoolType === "burnMint") { return "Lock & Mint" } else if (sourcePoolType === "burnMint" && destinationPoolType === "lockRelease") { - return "Burn & Unlock" + return "Lock & Mint" } else if (sourcePoolType === "lockRelease" && destinationPoolType === "lockRelease") { return "Lock & Unlock" } else if ( From 96ce2b2d03582126018cdbd84ff9d08a190c117f Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Wed, 3 Apr 2024 17:06:06 +0200 Subject: [PATCH 08/39] add mechanism --- .../ccip/components/supported-networks/LaneConfig.astro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/ccip/components/supported-networks/LaneConfig.astro b/src/features/ccip/components/supported-networks/LaneConfig.astro index 327a78e9c24..8ea09029e83 100644 --- a/src/features/ccip/components/supported-networks/LaneConfig.astro +++ b/src/features/ccip/components/supported-networks/LaneConfig.astro @@ -115,7 +115,7 @@ const determineMechanism = ( } else if (sourcePoolType === "lockRelease" && destinationPoolType === "burnMint") { return "Lock & Mint" } else if (sourcePoolType === "burnMint" && destinationPoolType === "lockRelease") { - return "Lock & Mint" + return "Burn & Unlock" } else if (sourcePoolType === "lockRelease" && destinationPoolType === "lockRelease") { return "Lock & Unlock" } else if ( @@ -251,7 +251,7 @@ if (supportedTokens) { Decimals Date: Wed, 3 Apr 2024 18:48:09 +0200 Subject: [PATCH 09/39] enhance arhcitecture --- src/content/ccip/architecture.mdx | 37 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/content/ccip/architecture.mdx b/src/content/ccip/architecture.mdx index 77929412a6a..876d9953f91 100644 --- a/src/content/ccip/architecture.mdx +++ b/src/content/ccip/architecture.mdx @@ -27,8 +27,9 @@ Below is a diagram displaying the basic architecture of CCIP. Routers are smart @@ -59,7 +60,7 @@ The figure below outlines the different components involved in a cross-chain tra #### Router -The Router is the primary contract CCIP users interface with. This contract is responsible for initiating cross-chain interactions. One router contract exists per chain. When transferring tokens, callers have to approve tokens for the router contract. +The Router is the primary contract CCIP users interface with. This contract is responsible for initiating cross-chain interactions. One router contract exists per blockchain. When transferring tokens, callers have to approve tokens for the router contract. The router contract routes the instruction to the destination-specific [OnRamp](#onramp). When a message is received on the destination chain, the router is the contract that “delivers” tokens to the user's account or the message to the receiver's smart contract. @@ -89,14 +90,28 @@ One OffRamp contract per [lane](/ccip/concepts#lane) exists. This contract perfo #### Token pools -Each token has its own token pool, an abstraction layer over ERC-20 tokens that facilitates OnRamp and OffRamp token-related operations. Token pools are configurable to `lock` or `burn` at the source blockchain and `unlock` or `mint` at the destination blockchain. The mechanism for handling tokens depends on the characteristics of the token in question. Here are a few examples: +Each token is associated with its own token pool, an abstraction layer over ERC-20 tokens designed to facilitate token-related operations for OnRamping and OffRamping. Token pools provide rate limiting, a security feature enabling token issuers to set a maximum rate at which their token can be transferred. Token pools are configured to `lock` or `burn` tokens on the source blockchain and `unlock` or `mint` tokens on the destination blockchain. This setup results in four primary mechanisms: -- Blockchain-native gas tokens, such as ETH, MATIC, and AVAX, can only be minted on their native chains. These tokens cannot be burned on the source and minted at the destination to transfer these tokens between chains. Instead, the linked token pool uses a "Lock and Mint" approach that locks the token at its source and then mints a wrapped or synthetic asset on the destination blockchain. This synthetic asset represents the locked asset and is essential for redeeming the locked asset. -- A token like LINK is minted on a single chain (Ethereum mainnet) with a fixed total supply. CCIP cannot natively mint it on another chain. In this case, the "Lock and Mint" approach is required. -- Some tokens can be minted on multiple chains. Examples of such tokens include stablecoins like USDC, TUSD, USDT, and FRAX. The linked token pools use a "Burn and Mint" method to burn the token at its source and then mint it natively on the destination blockchain. Wrapped assets such as WBTC or WETH are other examples that use the "Burn and Mint" approach. -- A token with a Proof Of Reserve (PoR) feed on a specific chain poses a challenge for the "Burn and Mint" method when applied to other chains because it conflicts with the PoR feed. For these tokens, "Lock and Mint" is the preferred approach. +- **Burn and Mint**: Tokens are burned on the source blockchain, and an equivalent amount of tokens are minted on the destination blockchain. +- **Lock and Mint**: Tokens are locked on their issuing blockchain, and fully collateralized "wrapped" tokens are minted on the destination blockchain. These wrapped tokens can be transferred across non-issuing blockchains using the _Burn and Mint_ mechanism. +- **Lock and Unlock**: Tokens are locked on the source blockchain, and an equivalent amount of tokens are released on the destination blockchain. +- **Burn and Unlock**: Tokens are burned on the source blockchain, and an equivalent amount of tokens are released on the destination blockchain. This mechanism is the inverse of the _Lock and Mint_ mechanism. It applies when you send tokens to their issuing source blockchain. -Token pools provide rate limiting, which is a security feature enabling token issuers to set a maximum rate at which their token can be transferred. +The mechanism for handling tokens varies depending on the characteristics of each token. Below are several examples to illustrate this: + +- LINK Token is minted on a single blockchain (Ethereum mainnet) and has a fixed total supply. Consequently, CCIP cannot natively mint it on another blockchain. For LINK, the token pool is configured to lock tokens on Ethereum mainnet (the issuing blockchain) and mint them on the destination blockchain. Conversely, when transferring from a non-issuing blockchain to Ethereum mainnet, the LINK token pool is set to burn the tokens on the source (non-issuing) blockchain and unlock them on Ethereum Mainnet (issuing). +- Wrapped native Assets (e.g., WETH) utilize a _Lock and Unlock_ mechanism. For instance, when transferring 10 WETH from Ethereum mainnet to Optimism mainnet, the WETH token pool will lock 10 WETH on Ethereum mainnet and unlock 10 WETH on Optimism mainnet. Conversely, transferring from Optimism mainnet back to Ethereum mainnet involves the WETH token pool locking 10 WETH on Optimism mainnet and unlocking 10 WETH on the Ethereum mainnet. +- Stablecoins (e.g., USDC) can be minted natively on multiple blockchains. Their respective token pools employ a _Burn and Mint_ mechanism, burning the token on the source blockchain and then minting it natively on the destination blockchain. +- Tokens with a Proof Of Reserve (PoR) with a PoR feed on a specific blockchain present a challenge for the _Burn and Mint_ mechanism when applied across other blockchains due to conflicts with the PoR feed. For such tokens, the _Lock and Mint_ approach is preferred. + +{/* prettier-ignore */} +