Skip to main content
The program sells amountIn of the Pot’s WETH for USDC on Uniswap V3’s 0.05% WETH/USDC pool, pays exactly due USDC to payee, and sends the USDC above due and any WETH the pool did not take to refundTo. It reverts when the swap returns less than due USDC, so the invoice is paid in full or not at all. Target chains: Base. The recorded simulation uses a Base fork.
With a floor set, the swap can stop before it sells all of amountIn. The invoice is still paid only when the USDC received covers due; the unsold WETH goes to refundTo, not back to the Pot.

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; WETH.balanceOf(pot) and USDC.balanceOf(pot) read its balances (Names).
swap-then-pay.sauce.ts

How it works

  • The pool comes from UniswapV3.Factory.getPool(WETH, USDC, 500), and the swap is uniswapV3 from @sauce/router, which swaps through the Pot’s Router into the Pot (pot as the recipient).
  • The minimum output passed to uniswapV3 is 0; the program enforces received >= due itself with a reason, so a short swap reverts with “the swap returned less USDC than due” rather than an unlabelled revert.
  • sqrtPriceLimitX96 is a floor because WETH sorts before USDC on Base (WETH is token0), and selling token0 lowers the price. When the floor is reached, the pool takes only part of amountIn; the program measures what it sold from the Pot’s WETH balance and returns the rest to refundTo as changeWeth.
  • Both sides of the swap are measured as balance changes of the Pot, and the payment is measured at the payee.

Run the example

1

Compile

2

Find the floor

The sqrtPriceLimitX96 printed under “Selling WETH” is the floor for 2,200 USDC per WETH: 3716130220787573219086287.
3

Simulate

--assume-balance WETH:0.5 gives the Pot 0.5 WETH for this simulation only; the invoice is 1,000 USDC.
4

Send

sauce tx prints the unsigned transaction instead, for your own signer:

Simulation result

Simulated on a local fork of Base at block 53159700 with the current contracts, with the command above, paying 0x7099…79C8 and refunding to 0x3C44…93BC. 0xd0b5…F224 is the Uniswap V3 0.05% WETH/USDC pool (sauce pools --chain base WETH USDC lists it). Nothing was signed or sent.
The pool took all 0.5 WETH for 1,162.989217 USDC without its price reaching the 2,200 floor. The payee received exactly 1,000 USDC and refundTo the other 162.989217 USDC; no WETH was left over. On the same fork, with a floor of 2,327.14 USDC per WETH (sauce price --chain base 2327.14 USDC per WETH gives 3822001377876224716099186, below the pool’s price of 2,327.20 before the fee as sauce pools read it) and a 100 USDC invoice:
The price reached the floor after 0.258037493841482263 WETH, so the pool stopped there. The program paid the 100 USDC invoice and sent 500.19743 USDC and the 0.241962506158517737 unsold WETH to refundTo. On the same fork, the guard, with a 5,000 USDC invoice:
0.5 WETH returned about 1,163 USDC, below the invoice, so the cook reverted and nothing moved.

Next steps