diff --git a/fern/docs.yml b/fern/docs.yml index e4e76436..eb5a8b24 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -214,6 +214,9 @@ navigation: - page: Handle Native Tokens slug: handling-native-tokens path: docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx + - page: Chain-Specific Native Tokens + slug: chain-specific-native-tokens + path: docs/pages/0x-swap-api/additional-topics/chain-specific-native-tokens.mdx - page: 0x Parser slug: 0x-parser path: docs/pages/0x-swap-api/additional-topics/0x-parser.mdx diff --git a/fern/docs/pages/0x-swap-api/additional-topics/chain-specific-native-tokens.mdx b/fern/docs/pages/0x-swap-api/additional-topics/chain-specific-native-tokens.mdx new file mode 100644 index 00000000..7aa75121 --- /dev/null +++ b/fern/docs/pages/0x-swap-api/additional-topics/chain-specific-native-tokens.mdx @@ -0,0 +1,74 @@ +--- +title: Chain-Specific Native Tokens +description: How to handle native tokens on Mantle and Arc, the chains that do not follow the standard placeholder-address convention. +--- + +Most chains we support represent their native token with the placeholder address `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`, and the flow described in [Handle Native Tokens](/evm/0x-swap-api/additional-topics/handling-native-tokens) applies without changes. This page covers the two chains that behave differently. + +## Mantle: MNT has a contract address + +Mantle’s native token, **MNT**, does not follow this convention. On the Mantle EVM chain, MNT has a designated contract address: `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000`. + +This address applies only to the native `MNT` token on Mantle and should not be used for wrapped or bridged versions on other networks. Refer to the linked guide for additional [differences between Ethereum and Mantle](https://docs.mantle.xyz/network/for-developers/difference-between-ethereum-and-mantle). + +## Arc: USDC is the native gas token + +USDC plays two roles on Arc at once. It is the native gas token, and it is also an ERC-20 token that the chain has built in at a fixed address. There is no wrapped-native token, and Circle does not plan to deploy one, so the [ETH/WETH wrapping pattern](/evm/0x-swap-api/additional-topics/handling-native-tokens#wrapping-and-unwrapping-between-eth-and-weth) does not apply. Refer to Arc's own guide for the full details of [USDC as the native gas token](https://docs.arc.io/arc/concepts/stablecoin-native-model#usdc-as-the-native-gas-token). + +### The two interfaces of USDC + +| | Native | ERC-20 | +| --------------------- | --------------------------------------------- | ------------------------------------------------------ | +| Address to pass to 0x | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` | `0x3600000000000000000000000000000000000000` | +| Decimals | 18 | 6 | +| Purpose | Gas accounting, native sends, and `msg.value` | Application-level transfers, approvals, and allowances | +| Allowance required | No | Yes | + +Both interfaces are backed by a **single balance**. Sending native USDC and transferring ERC-20 USDC move the same money, and the two forms are entangled at the protocol level: an ERC-20 transfer also emits a native transfer. + +### What this means for your integration + + + +Native USDC and ERC-20 USDC differ in scale by a factor of 10^12. One whole USDC ($1.00) is `1000000` in ERC-20 base units and `1000000000000000000` in native base units. Mixing the two misprices a swap by a factor of one trillion. + + + +The Swap API returns amounts in the base units of whichever interface you requested, and performs no conversion between them. Follow these rules: + + + + Use `0x3600000000000000000000000000000000000000` if you want to work in 6 + decimals, or `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` if you want to + work in 18 decimals. Do not mix the two within a single quote. + + + `sellAmount`, `buyAmount`, `minBuyAmount` and fee amounts are all + denominated in the base units of the address you passed. Balance checks, + allowance logic and any USD display must use the same decimals. + + + If you requested the ERC-20 interface, the standard ERC-20 flow applies, + including an allowance. If you requested the native interface, skip the + approval and set `transaction.value`, as described in [Handle Native + Tokens](/evm/0x-swap-api/additional-topics/handling-native-tokens#steps-for-handling-standard-native-tokens). + + + Arc enforces a 20 gwei floor on `maxFeePerGas`. Transactions submitted below + it can stay pending indefinitely or fail outright. A small tip (for example + 1 gwei) on `maxPriorityFeePerGas` improves inclusion during high + utilization. + + + + + +There is no wrap or unwrap step to build on Arc. A quote between the native and ERC-20 interfaces of USDC is not a supported swap; move between them by using the interface you need, since they share one balance. + + + +### Notes for wallets and analytics + +- **Show one USDC balance.** Displaying gas balance and USDC balance as separate rows suggests a user holds two assets when they hold one. +- **Expect duplicate transfer logs on ERC-20 moves only.** Moving USDC through the ERC-20 interface emits both a native transfer and an ERC-20 `Transfer` event, so indexers that count both will double-count USDC volume. Moving it through the native interface emits a single log. +- **Avoid `SELFDESTRUCT` patterns.** Arc forbids burning USDC, so a self-destructed account cannot receive value-bearing calls. Contracts that rely on `SELFDESTRUCT` can revert in ways that are hard for users to interpret. diff --git a/fern/docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx b/fern/docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx index 55547e03..a8fe9a1e 100644 --- a/fern/docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx +++ b/fern/docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx @@ -7,22 +7,27 @@ description: This guide explains how to properly handle native tokens properly i Native tokens are the base currencies of their blockchains—for example, ETH on Ethereum, BNB on BNB Chain, and POL on Polygon. Because native tokens do not have contract addresses like ERC-20 tokens, the placeholder address: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` is commonly used to represent native tokens in blockchain transactions. -### Notes on Native Token Representation +## Standard Native Token Representation For most of the EVM-compatible chains that we support, the native token is represented using the placeholder address `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. This convention exists because native assets (e.g., ETH on Ethereum) do not have contract addresses like ERC-20 tokens. -#### Mantle Network Exception +## Chain-Specific Exceptions -Mantle’s native token, **MNT**, does not follow this convention. On the Mantle EVM chain, MNT has a designated contract address: `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000`. +Two chains we support do not follow this convention: -This address applies only to the native `MNT` token on Mantle and should not be used for wrapped or bridged versions on other networks. Refer to the linked guide for additional [differences between Ethereum and Mantle](https://docs.mantle.xyz/network/for-developers/difference-between-ethereum-and-mantle). +- **Mantle** uses a designated contract address for its native token, **MNT**. +- **Arc** uses **USDC** as its native gas token, exposed through two interfaces that use different decimals. + +Before integrating on either, read [Chain-Specific Native Tokens](/evm/0x-swap-api/additional-topics/chain-specific-native-tokens). + +## Additional Resources For more context on native token addresses: - [Discussion on native token address](https://www.reddit.com/r/ethereum/comments/iatr1d/what_is_the_significance_of_this_address/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) - [Stack Exchange explanation](https://ethereum.stackexchange.com/a/87444/85979). -## Steps for Handling Native Tokens +## Steps for Handling Standard Native Tokens