diff --git a/package-lock.json b/package-lock.json
index 1aae9176adf..4fc015e9534 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,7 @@
"focus-trap-react": "^10.2.3",
"github-slugger": "^2.0.0",
"lodash": "^4.17.21",
+ "marked": "^12.0.1",
"nanostores": "^0.9.5",
"preact": "^10.20.1",
"react-instantsearch": "^7.7.0",
@@ -17724,6 +17725,17 @@
"dev": true,
"peer": true
},
+ "node_modules/marked": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.1.tgz",
+ "integrity": "sha512-Y1/V2yafOcOdWQCX0XpAKXzDakPOpn6U0YLxTJs3cww6VxOzZV1BTOOYWLvH3gX38cq+iLwljHHTnMtlDfg01Q==",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
diff --git a/package.json b/package.json
index 89f578a9d83..75e9c415ed9 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"focus-trap-react": "^10.2.3",
"github-slugger": "^2.0.0",
"lodash": "^4.17.21",
+ "marked": "^12.0.1",
"nanostores": "^0.9.5",
"preact": "^10.20.1",
"react-instantsearch": "^7.7.0",
diff --git a/src/config/data/ccip/data.ts b/src/config/data/ccip/data.ts
index a11224a5378..ff338d3c88e 100644
--- a/src/config/data/ccip/data.ts
+++ b/src/config/data/ccip/data.ts
@@ -4,6 +4,7 @@ import {
TokensConfig,
Environment,
Version,
+ CCIPSendErrorEntry,
SupportedTokenConfig,
determineTokenMechanism,
TokenMechanism,
@@ -21,12 +22,26 @@ import chainsTestnetv120 from "@config/data/ccip/v1_2_0/testnet/chains.json"
import lanesTestnetv120 from "@config/data/ccip/v1_2_0/testnet/lanes.json"
import tokensTestnetv120 from "@config/data/ccip/v1_2_0/testnet/tokens.json"
+// errors
+
+import erc20CCIPSendErrors from "@config/data/ccip/errors/erc20.json"
+import routerCCIPSendErrors from "@config/data/ccip/errors/router.json"
+import onrampCCIPSendErrors from "@config/data/ccip/errors/onramp.json"
+import ratelimiterCCIPSendErrors from "@config/data/ccip/errors/ratelimiter.json"
+import priceregistryCCIPSendErrors from "@config/data/ccip/errors/priceregistry.json"
+
import { SupportedChain } from "@config/types"
import { directoryToSupportedChain, supportedChainToChainInRdd } from "@features/utils"
export const getAllEnvironments = () => [Environment.Mainnet, Environment.Testnet]
export const getAllVersions = () => [Version.V1_2_0]
+export const erc20Errors: CCIPSendErrorEntry[] = erc20CCIPSendErrors
+export const routerErrors: CCIPSendErrorEntry[] = routerCCIPSendErrors
+export const onrampErrors: CCIPSendErrorEntry[] = onrampCCIPSendErrors
+export const ratelimiterErrors: CCIPSendErrorEntry[] = ratelimiterCCIPSendErrors
+export const priceRegistryErrors: CCIPSendErrorEntry[] = priceregistryCCIPSendErrors
+
export const networkFees: NetworkFees = {
tokenTransfers: {
[TokenMechanism.LockAndUnlock]: {
diff --git a/src/config/data/ccip/errors/erc20.json b/src/config/data/ccip/errors/erc20.json
new file mode 100644
index 00000000000..43ea19415c2
--- /dev/null
+++ b/src/config/data/ccip/errors/erc20.json
@@ -0,0 +1,10 @@
+[
+ {
+ "error": "ERC20: burn amount exceeds balance",
+ "description": "Thrown when the amount to be burned exceeds the pool balance."
+ },
+ {
+ "error": "ERC20: transfer amount exceeds allowance",
+ "description": "Thrown when the transfer amount exceeds the allowance."
+ }
+]
diff --git a/src/config/data/ccip/errors/onramp.json b/src/config/data/ccip/errors/onramp.json
new file mode 100644
index 00000000000..ab2bf1797a2
--- /dev/null
+++ b/src/config/data/ccip/errors/onramp.json
@@ -0,0 +1,114 @@
+[
+ {
+ "error": "CannotSendZeroTokens",
+ "parameters": [],
+ "errorSelector": "0x5cf04449",
+ "description": "Thrown when the user tries to send a zero amount of tokens."
+ },
+ {
+ "error": "InvalidAddress",
+ "parameters": [
+ {
+ "type": "bytes",
+ "name": "encodedAddress"
+ }
+ ],
+ "errorSelector": "0x370d875f",
+ "description": "Thrown when the receiver address is invalid."
+ },
+ {
+ "error": "InvalidChainSelector",
+ "parameters": [
+ {
+ "type": "uint64",
+ "name": "chainSelector"
+ }
+ ],
+ "errorSelector": "0xd9a9cd68",
+ "description": "Thrown when an invalid destination chain selector is used."
+ },
+ {
+ "error": "InvalidExtraArgsTag",
+ "parameters": [],
+ "errorSelector": "0x5247fdce",
+ "description": "Thrown when an invalid extra arguments tag is used."
+ },
+ {
+ "error": "MaxFeeBalanceReached",
+ "parameters": [],
+ "errorSelector": "0xe5c7a491",
+ "description": "Thrown when the onRamp has reached its maximum fee storage capacity. If it is full, it cannot process new transactions."
+ },
+ {
+ "error": "MessageGasLimitTooHigh",
+ "parameters": [],
+ "errorSelector": "0x4c4fc93a",
+ "description": "Thrown when the gas limit is too high."
+ },
+ {
+ "error": "MessageTooLarge",
+ "parameters": [
+ {
+ "type": "uint256",
+ "name": "maxSize"
+ },
+ {
+ "type": "uint256",
+ "name": "actualSize"
+ }
+ ],
+ "errorSelector": "0x86933789",
+ "description": "Thrown when the message size exceeds the maximum allowed size."
+ },
+ {
+ "error": "MustBeCalledByRouter",
+ "parameters": [],
+ "errorSelector": "0x1c0a3529",
+ "description": "This error should never be thrown as the router always makes the call."
+ },
+ {
+ "error": "NotAFeeToken",
+ "parameters": [
+ {
+ "type": "address",
+ "name": "token"
+ }
+ ],
+ "errorSelector": "0xa7499d20",
+ "description": "Thrown when an unsupported fee token is used."
+ },
+ {
+ "error": "RouterMustSetOriginalSender",
+ "parameters": [],
+ "errorSelector": "0xa4ec7479",
+ "description": "This error should never be thrown as the router always sets the sender."
+ },
+ {
+ "error": "SenderNotAllowed",
+ "parameters": [
+ {
+ "type": "address",
+ "name": "sender"
+ }
+ ],
+ "errorSelector": "0xd0d25976",
+ "description": "Thrown when the sender is not allowlisted."
+ },
+ {
+ "error": "UnsupportedNumberOfTokens",
+ "parameters": [],
+ "errorSelector": "0x4c056b6a",
+ "description": "Thrown when too many tokens are involved in the transfer."
+ },
+ {
+ "error": "UnsupportedToken",
+ "parameters": [
+ {
+ "type": "IERC20",
+ "name": "token"
+ }
+ ],
+ "errorSelector": "0xbf16aab6",
+ "description": "Thrown when an unsupported transfer token is used."
+ }
+]
diff --git a/src/config/data/ccip/errors/priceregistry.json b/src/config/data/ccip/errors/priceregistry.json
new file mode 100644
index 00000000000..921014ec370
--- /dev/null
+++ b/src/config/data/ccip/errors/priceregistry.json
@@ -0,0 +1,62 @@
+[
+ {
+ "error": "ChainNotSupported",
+ "parameters": [
+ {
+ "type": "uint64",
+ "name": "chain"
+ }
+ ],
+ "errorSelector": "0x2e59db3a",
+ "description": "Thrown when a chain is not supported."
+ },
+ {
+ "error": "StaleGasPrice",
+ "parameters": [
+ {
+ "type": "uint64",
+ "name": "destChainSelector"
+ },
+ {
+ "type": "uint256",
+ "name": "threshold"
+ },
+ {
+ "type": "uint256",
+ "name": "timePassed"
+ }
+ ],
+ "errorSelector": "0xf08bcb3e",
+ "description": "Thrown when the gas price is stale."
+ },
+ {
+ "error": "TokenNotSupported",
+ "parameters": [
+ {
+ "type": "address",
+ "name": "token"
+ }
+ ],
+ "errorSelector": "0x06439c6b",
+ "description": "Thrown when a token is not supported."
+ },
+ {
+ "error": "StaleTokenPrice",
+ "parameters": [
+ {
+ "type": "address",
+ "name": "token"
+ },
+ {
+ "type": "uint256",
+ "name": "threshold"
+ },
+ {
+ "type": "uint256",
+ "name": "timePassed"
+ }
+ ],
+ "errorSelector": "0xc65fdfca",
+ "description": "Thrown when the price of a token is stale."
+ }
+]
diff --git a/src/config/data/ccip/errors/ratelimiter.json b/src/config/data/ccip/errors/ratelimiter.json
new file mode 100644
index 00000000000..edeeff5e13e
--- /dev/null
+++ b/src/config/data/ccip/errors/ratelimiter.json
@@ -0,0 +1,87 @@
+[
+ {
+ "error": "AggregateValueMaxCapacityExceeded",
+ "parameters": [
+ {
+ "type": "uint256",
+ "name": "capacity"
+ },
+ {
+ "type": "uint256",
+ "name": "requested"
+ }
+ ],
+ "errorSelector": "0xf94ebcd1",
+ "description": "Thrown when the user requests to transfer more value than the capacity of the aggregate rate limit bucket."
+ },
+ {
+ "error": "AggregateValueRateLimitReached",
+ "parameters": [
+ {
+ "type": "uint256",
+ "name": "minWaitInSeconds"
+ },
+ {
+ "type": "uint256",
+ "name": "available"
+ }
+ ],
+ "errorSelector": "0x15279c08",
+ "description": "Thrown when the user requests to transfer more value than currently available in the bucket. The user might have to wait for at least `minWaitInSeconds` for enough availability or transfer the currently `available` amount."
+ },
+ {
+ "error": "BucketOverfilled",
+ "parameters": [],
+ "errorSelector": "0x9725942a",
+ "description": "This error should never be thrown as it indicates an invalid bucket state."
+ },
+ {
+ "error": "PriceNotFoundForToken",
+ "parameters": [
+ {
+ "type": "address",
+ "name": "token"
+ }
+ ],
+ "errorSelector": "0x9a655f7b",
+ "description": "Thrown when a price cannot be found for a specific token."
+ },
+ {
+ "error": "TokenMaxCapacityExceeded",
+ "parameters": [
+ {
+ "type": "uint256",
+ "name": "capacity"
+ },
+ {
+ "type": "uint256",
+ "name": "requested"
+ },
+ {
+ "type": "address",
+ "name": "tokenAddress"
+ }
+ ],
+ "errorSelector": "0x1a76572a",
+ "description": "Thrown when the user requests to transfer more of a token than the capacity of the bucket."
+ },
+ {
+ "error": "TokenRateLimitReached",
+ "parameters": [
+ {
+ "type": "uint256",
+ "name": "minWaitInSeconds"
+ },
+ {
+ "type": "uint256",
+ "name": "available"
+ },
+ {
+ "type": "address",
+ "name": "tokenAddress"
+ }
+ ],
+ "errorSelector": "0xd0c8d23a",
+ "description": "Thrown when the user requests to transfer more of a token than currently available in the bucket. The user might have to wait at least `minWaitInSeconds` for enough availability, or transfer the currently `available` amount."
+ }
+]
diff --git a/src/config/data/ccip/errors/router.json b/src/config/data/ccip/errors/router.json
new file mode 100644
index 00000000000..6a92b759228
--- /dev/null
+++ b/src/config/data/ccip/errors/router.json
@@ -0,0 +1,25 @@
+[
+ {
+ "error": "UnsupportedDestinationChain",
+ "parameters": [
+ {
+ "type": "uint64",
+ "name": "destChainSelector"
+ }
+ ],
+ "errorSelector": "0xae236d9c",
+ "description": "Thrown when the destination chain is not supported."
+ },
+ {
+ "error": "InsufficientFeeTokenAmount",
+ "parameters": [],
+ "errorSelector": "0x07da6ee6",
+ "description": "Thrown when the CCIP fees are paid with native tokens, but not enough is sent with the transaction."
+ },
+ {
+ "error": "InvalidMsgValue",
+ "parameters": [],
+ "errorSelector": "0x1841b4e1",
+ "description": "Thrown when the CCIP fees are _not_ paid in native tokens, but `msg.value` is non-zero."
+ }
+]
diff --git a/src/config/data/ccip/types.ts b/src/config/data/ccip/types.ts
index de52eff11b6..8c634d874d8 100644
--- a/src/config/data/ccip/types.ts
+++ b/src/config/data/ccip/types.ts
@@ -98,3 +98,13 @@ export enum Environment {
export enum Version {
V1_2_0 = "1.2.0",
}
+
+export interface CCIPSendErrorEntry {
+ error: string
+ parameters?: Array<{
+ type: string
+ name: string
+ }>
+ errorSelector?: string
+ description: string
+}
diff --git a/src/content/ccip/api-reference/errors.mdx b/src/content/ccip/api-reference/errors.mdx
index 4e56e14f8c4..768f804b8df 100644
--- a/src/content/ccip/api-reference/errors.mdx
+++ b/src/content/ccip/api-reference/errors.mdx
@@ -5,6 +5,8 @@ title: "Errors API Reference"
---
import CcipCommon from "@features/ccip/CcipCommon.astro"
+import { CCIPSendError } from "@features/ccip/components/api-reference"
+import { Aside, CopyText } from "@components"
Error | + {hasParameters ?Parameters | : null} + {hasErrorSelector ?Error Selector | : null} +Description | +
---|---|---|---|
{error.error} | + {hasParameters ? ( +
+ {paramsLength > 0
+ ? params.map((param, index) => (
+ <>
+
+ {param.type} {param.name}
+
+ {index < paramsLength - 1 ? : null} + > + )) + : "-"} + |
+ ) : null}
+ {hasErrorSelector ? (
+ {error.errorSelector ? |
+ ) : null}
+ + |