Skip to main content
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 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.

Program

pot is the Pot the program runs on, available without declaring it (Names).
arc-native-payment.sauce.ts

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

2

Simulate

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

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:

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.
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:
1000000 of native value is 10^-12 USDC, below one base unit of the token, so the guard reverted the cook.

Next steps