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

# Pay native USDC on Arc

> One Arc transaction that reads the Pot's USDC as native value with `pot.balance` and as the ERC-20 with `pot.USDC`, checks the two agree, pays native value, and measures the recipient's USDC balance at both scales.

On Arc the gas coin is USDC. The program reads the Pot's balance as native value (18 decimals) and through the `USDC` token (6 decimals), requires the two to agree, pays `amountNative` to `to` as native value, and measures what arrived at both scales. It reverts when the readings disagree, when `amountNative` is not a whole number of USDC base units, when the Pot holds less, or when `to` receives a different amount.

**Target chains:** Arc. This program treats native value as USDC and must not be reused unchanged on a chain with another native coin.

## Prerequisites

Install the [Sauce CLI](https://docs.eco.com/sauce-sdk/installation.md) to compile and simulate. To send the transaction, configure a wallet with funds for gas and the Kitchen fee. Provide the required tokens in your Pot once it is deployed, or through `--fund`; see [funding](https://docs.eco.com/sauce-sdk/cli/funding.md).

## Program

`pot` is the Pot the program runs on, available without declaring it ([Names](https://docs.eco.com/sauce/names.md#balances)).

```ts arc-native-payment.sauce.ts theme={null}
// Pays USDC on Arc as native value. Arc's gas coin is USDC: the native balance has 18 decimals and
// the ERC-20 `USDC` has 6, and both read one balance. The program reads the Pot's native balance
// (`pot.balance`) and its token balance (`pot.USDC`), requires the token reading to equal the native
// reading divided by 10^12, sends `amountNative` to `to` with `evm.call`, and measures what `to`
// received at both scales. The cook reverts, and nothing moves, when `amountNative` is zero or not
// a whole number of USDC base units (a multiple of 10^12), when `to` is the zero address or the
// Pot, when the Pot holds less, when the two readings disagree, or when `to` receives a different
// amount.
//
//   sauce simulate arc-native-payment.sauce.ts --chain arc --owner <address> \
//     --assume-balance USDC:<whole-tokens> --args <amountNative> <to>
//   sauce run arc-native-payment.sauce.ts --chain arc --wallet <name> --args <amountNative> <to>
//
//   amountNative: Uint256  the USDC to pay as native value, in 18 decimals:
//                          1000000000000000000 is 1 USDC; a multiple of 10^12
//   to: Address            who is paid
//
// On Arc, pay 1.5 USDC to 0x2154…676d:
//
//   sauce run arc-native-payment.sauce.ts --chain arc --wallet me \
//     --args 1500000000000000000 0x21543327A3f4282A3649a7b1AAe499fdCaB3676d
function main(
  amountNative: Uint256,
  to: Address,
): {
  potNative: Uint256;
  potUsdc: Uint256;
  receivedNative: Uint256;
  receivedUsdc: Uint256;
} {
  const scale = 10 ** 12;
  require(amountNative > 0, "amountNative is zero");
  require(amountNative % scale == 0, "amountNative is not a whole number of USDC base units");
  require(to != 0 && to != pot, "to is the zero address or the Pot");

  // One balance, two readings: 18 decimals natively, 6 through the token.
  const potNative = pot.balance;
  const potUsdc = pot.USDC;
  require(potUsdc == potNative / scale, "the native and token readings disagree");
  require(potNative >= amountNative, "not enough USDC in the Pot");

  // Pay as native value: evm.call is the only call that sends value; empty calldata.
  const empty = hex``;
  const nativeBefore = ctx.balance(to);
  const usdcBefore = USDC.balanceOf(to);
  evm.call(to, amountNative, empty);
  const receivedNative = ctx.balance(to) - nativeBefore;
  const receivedUsdc = USDC.balanceOf(to) - usdcBefore;
  require(receivedNative == amountNative, "to received a different native amount");
  require(receivedUsdc == amountNative / scale, "to's USDC balance moved a different amount");

  return { potNative, potUsdc, receivedNative, receivedUsdc };
}
```

## How it works

* One balance, two scales. `pot.balance` returns native value with 18 decimals and `pot.USDC` the same money with 6, rounded down: the token reading is the native reading divided by 10^12. The program requires exactly that equality.
* `amountNative` has 18 decimals: `1500000000000000000` is 1.5 USDC, and `1000000` is 10^-12 USDC, not 1 USDC. The program requires a multiple of 10^12 so the token-scale amount is exact; the second result below is that guard.
* The payment is `evm.call(to, amountNative, empty)` with empty calldata. The recipient's change is read twice, with `ctx.balance(to)` and `USDC.balanceOf(to)`, and both must match the amount sent.
* On Arc `pot.USDC` is the six-decimal token and `pot.balance` the 18-decimal native coin. For another address, `USDC.balanceOf(<holder>)` reads the token and `ctx.balance(<holder>)` the coin.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile arc-native-payment.sauce.ts --chain arc
```

**2. Simulate**

```bash theme={null}
sauce simulate arc-native-payment.sauce.ts --chain arc --owner <your-address> \
  --assume-balance USDC:5 --args 1500000000000000000 <recipient>
```

On Arc, `--assume-balance USDC:5` sets the Pot's native balance to 5 USDC for this simulation only, since no token storage holds the native coin. The result lists both readings and both measured amounts.

**3. Send**

```bash theme={null}
sauce run arc-native-payment.sauce.ts --chain arc --wallet <name> \
  --args 1500000000000000000 <recipient>
```

The Pot must hold the USDC: deploy it first with `sauce pot --chain arc --wallet <name> --deploy`, then send it the USDC. `sauce tx` prints the unsigned transaction instead, for your own signer:

```bash theme={null}
sauce tx arc-native-payment.sauce.ts --chain arc --owner <your-address> \
  --args 1500000000000000000 <recipient>
```

## Simulation result

Simulated on a local fork of Arc at block 27999097 with the current contracts, with the command above, paying `0x2154…676d`. Nothing was signed or sent.

```text theme={null}
The cook succeeds from 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: gas used 118396 for the cook, after the Pot's deploy (1. below), returns 0x0000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000014d1120d7b160000000000000000000000000000000000000000000000000000000000000016e360
main returns { potNative: Uint256, potUsdc: Uint256, receivedNative: Uint256, receivedUsdc: Uint256 }: { potNative: 5000000000000000000, potUsdc: 5000000, receivedNative: 1500000000000000000, receivedUsdc: 1500000 }
Left in the Pot, not in the owner's wallet:
  3.5 USDC (it held 5 USDC before)
...
  2. the cook, from the owner 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, gas used 118396
Assumed for this simulation only, by state override:
  the Pot holds 5 USDC: --assume-balance
What moved, in order:
...
  [3] Pot                -> 0x2154…676d          1.5 USDC
Net balance changes:
  0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (owner): -0.01 USDC
  0xDcFCc75A3C9a0EC798CAf81B6C84D4c5d5988c49 (the Pot): -1.5 USDC
...
  0x21543327A3f4282A3649a7b1AAe499fdCaB3676d: +1.5 USDC
```

The Pot's 5 USDC read as `5000000000000000000` natively and `5000000` through the token. The recipient's balance rose by `1500000000000000000` and `1500000`: the same 1.5 USDC. The owner's wallet paid 0.01 USDC of cook value, the Kitchen's fee, in native USDC.

On the same fork, the guard, with `1000000` as `amountNative`:

```bash theme={null}
sauce simulate arc-native-payment.sauce.ts --chain arc --owner <your-address> \
  --assume-balance USDC:5 --args 1000000 <recipient> \
  --expect-revert "not a whole number of USDC base units"
```

```text theme={null}
As expected, the cook reverts: the program threw "amountNative is not a whole number of USDC base units"
The cook reverts: the program threw "amountNative is not a whole number of USDC base units"
```

`1000000` of native value is 10^-12 USDC, below one base unit of the token, so the guard reverted the cook.

## Next steps

* [Pay USDC from the Pot](https://docs.eco.com/quickstarts/sauce/pay.md): the ERC-20 payment, which also compiles for Arc
* [Sweep the Pot](https://docs.eco.com/quickstarts/sauce/sweep-pot.md): send native value with `evm.call` on Base or Ethereum
* [Chains](https://docs.eco.com/sauce-sdk/reference/chains.md), [Builtins](https://docs.eco.com/sauce/builtins.md), [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.