> ## Documentation Index
> Fetch the complete documentation index at: https://developers.circle.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# USDC-backed stablecoin reference specification

This reference spec is for blockchain partners looking to develop and deploy a
USDC-backed stablecoin that integrates with xReserve. It describes the
recommended capabilities your smart contract should have, including the state to
track, the callable functions to expose, and the administrative functions
typically restricted to the contract owner.

This spec is a recommended reference implementation, not a mandatory template.
You should adapt the logic in this spec to your blockchain's smart contract
language and environment, and flag any notable deviations to Circle during
integration so both teams understand them.

<Info>
  View a
  [reference contract](https://github.com/circlefin/evm-xreserve-contracts/blob/master/src/examples/USDCx.sol)
  that mints and burns USDC-backed stablecoins in the
  [Circle xReserve Contracts](https://github.com/circlefin/evm-xreserve-contracts)
  GitHub repository.
</Info>

## Deployment requirements

USDC-backed stablecoins are backed 1:1 by an equivalent amount of USDC held in
Circle's xReserve contract. Your contract mints them after verifying a
[deposit attestation](/xreserve/concepts/technical-guide#deposit-attestation),
and users burn them when they want to withdraw USDC or other USDC-backed
stablecoins on a supported blockchain.

When implementing your USDC-backed stablecoin contract, ensure that you:

* Follow the decimal precision of native USDC, which is 6 decimal places. If
  your blockchain token standard uses a different decimal precision, you must
  handle the decimal conversion in the onchain contract so that it still aligns
  with 6-decimal USDC.
* Use `uint256` for balances and amounts by default. If your runtime forces a
  smaller width such as `uint128` or `uint64`, select the equivalent integer
  type and implement overflow and underflow safeguards for that width.

## State and configuration requirements

The following table lists the variables your token contract should track and the
invariants that must remain true after every call that changes state.

| Variable | Description | Required Invariant |
| - | - | - |
| `uint32 domain` | Circle-assigned identifier for your blockchain. | Value must match the domain ID that Circle assigned to your blockchain. It must be immutable after deployment. |
| `mapping(bytes32 => uint256) balances` | Tracks balances for each USDC-backed stablecoin account. | Must be non-negative. |
| `mapping(bytes32 => bool) usedNonces` | Tracks consumed deposit intents (for replay protection). | Must be `false` before mint and set `true` atomically during mint. |
| `mapping(address => bool) xReserveAttesters` | Allowlist of [xReserve attester](/xreserve/concepts/technical-guide#attesters) addresses (in bytes20 form). | Only the owner can configure this list. |
| `uint256 minBurnSize` | Minimum burn amount for withdrawals. | The owner must implement and configure this amount. |
| `uint256 totalSupply` (optional onchain) | Aggregate minted minus burned balance. | Must equal the sum of all account balances. Can be omitted if the complete USDC-backed token supply is indexed and exposed offchain through an API. |

## Core contract functions

Your USDC-backed stablecoin contract should expose these external functions.

### `mint(bytes depositIntent, bytes depositAttestation, uint256 feeAmount)`

Mints USDC-backed stablecoins after verifying a deposit attestation.

For the canonical `DepositIntent` message format, see the
[Technical guide](/xreserve/concepts/technical-guide#deposit-intent).

**Preconditions**

The following conditions must be met before you move state or the call will
revert:

* `ECDSA.recover(hash(payload), signature)` must resolve to an address whose
  `bytes20` is `true` in the `xReserveAttesters` allowlist.
* `depositIntent.magic` must be `0x5a2e0acd`.
* `depositIntent.version` must be `1`.
* `depositIntent.amount` must be greater than zero.
* `depositIntent.remoteDomain` must match this USDC-backed stablecoin contract's
  `domain`.
* `depositIntent.remoteToken` must match the identifier for this USDC-backed
  stablecoin contract.
* `depositIntent.localToken` and `depositIntent.localDepositor` must not be zero
  addresses.
* `depositIntent.amount` must be at least `depositIntent.maxFee`.
* `depositIntent.maxFee` must be greater than or equal to the `feeAmount` passed
  in.
* `usedNonces[depositIntent.nonce]` must be `false`.

**State transitions**

When all preconditions are met, state must be updated in this order:

1. Set `usedNonces[depositIntent.nonce]` = `true`.
2. Add `depositIntent.amount - feeAmount` to the recipient's balance.
3. Add `feeAmount` to the relayer's balance if a relayer is present.
4. Increase `totalSupply` by `depositIntent.amount`.

**Postconditions**

After the mint completes, make sure:

* `totalSupply` equals exactly the previous supply + `depositIntent.amount`.
* The sum of balances increased by exactly `depositIntent.amount`.
* Your contract emits a mint event:
  `mint(recipient, relayer, amount, feeAmount, remoteDomain, remoteToken)`.

### `burn(uint256 amount, uint32 destinationDomain, bytes32 destinationRecipient)`

Burns USDC-backed stablecoins so xReserve can release USDC on the destination.

<Tip>
  **Recommendation**: Keep this signature where possible. Using the same parameter
  order and types simplifies downstream integrations that expect this interface.
</Tip>

For information on withdrawals, burn intents, and burn intent signatures, see
the [Technical guide](/xreserve/concepts/technical-guide#withdrawals).

**Preconditions:**

The following conditions must be met before you move state or the call will
revert:

* `amount` must be greater than zero.
* The caller (`msg.sender`) must hold at least `amount`.
* `amount` must meet or exceed `minBurnSize`.

**State transitions:**

When all preconditions are met, state must be updated in this order:

1. Decrement the caller's balance by `amount`.
2. Decrement `totalSupply` by `amount`.

**Postconditions**

After the mint completes, make sure:

* Your contract emits a burn event:
  `burn(depositor, domain, amount, destinationDomain, destinationRecipient)`.

## Administrative functions

Access to these administrative functions should be restricted to the contract
owner or an equivalent privileged role controlled by your blockchain team.

### `setAttester(bytes32 attester, bool enabled)`

Enables or disables an attester address in the allowlist. Set `enabled` to
`true` to approve an
[xReserve attester](/xreserve/concepts/technical-guide#attesters). Configure
more than one approved attester so xReserve can rotate attester keys without
downtime.

### `setMinBurnSize(uint256 minBurnSize)`

Specifies the minimum amount to burn.
