> ## 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.

# Quote two pools, swap on the better one, supply to Aave

> One Base transaction that quotes WETH to USDC on two Uniswap V3 pools, swaps on the one that quotes more, and supplies the USDC to Aave V3.

The program asks Uniswap's QuoterV2 what the 0.05% and the 0.3% WETH/USDC pools would pay for `amount` WETH. It swaps on the pool with the higher quote, then supplies every USDC the swap delivered to Aave V3 for `beneficiary`. If the better quote or the swap returns less than `minUsdc`, or the supply fails, the cook reverts and nothing moves.

**Target chains:** Base. The example uses `UniswapV3.QuoterV2`, `UniswapV3.Factory` and `AaveV3.Pool`.

## 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 WETH for the program and native coin for gas and the Kitchen fee.

## Program

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

```ts quote-swap-supply.sauce.ts theme={null}
// Sells `amount` of the Pot's WETH for USDC on whichever of Uniswap V3's 0.05% and 0.3% WETH/USDC
// pools quotes more, then supplies all the USDC received to Aave V3 for `beneficiary`.
// Both quotes come from Uniswap's QuoterV2 in the same transaction as the swap. The cook reverts,
// and nothing moves, when the better quote or the swap is below `minUsdc`, or the supply fails.
//
//   sauce simulate quote-swap-supply.sauce.ts --chain base --owner <address> \
//     --assume-balance WETH:<amount>n --args <amount> <minUsdc> <beneficiary>
//   sauce run quote-swap-supply.sauce.ts --chain base --wallet <name> \
//     --fund WETH:<amount>n --args <amount> <minUsdc> <beneficiary>
//
//   amount: Uint256       the WETH to sell, in wei (18 decimals): 1000000000000000000 is 1 WETH
//   minUsdc: Uint256      the least USDC the swap may return, in USDC's base units (6 decimals):
//                         2000000000 is 2,000 USDC
//   beneficiary: Address  the account Aave credits with the supplied USDC (it receives the aUSDC)
//
// On Base, sell 1 WETH for at least 2,000 USDC and supply it for <beneficiary>:
//
//   sauce run quote-swap-supply.sauce.ts --chain base --wallet me --fund WETH:1 \
//     --args 1000000000000000000 2000000000 <beneficiary>
import { uniswapV3 } from "@sauce/router";

function main(
  amount: Uint256,
  minUsdc: Uint256,
  beneficiary: Address,
): { quote500: Uint256; quote3000: Uint256; fee: Uint256; received: Uint256 } {
  require(amount > 0, "amount is zero");
  require(beneficiary != 0, "no beneficiary");
  require(pot.WETH >= amount, "not enough WETH in the Pot");

  // Quote both fee tiers. QuoterV2 runs the swap and reverts it, returning what it would deliver.
  const quote500 = UniswapV3.QuoterV2.quoteExactInputSingle({
    tokenIn: WETH,
    tokenOut: USDC,
    amountIn: amount,
    fee: 500,
    sqrtPriceLimitX96: 0,
  }).amountOut;
  const quote3000 = UniswapV3.QuoterV2.quoteExactInputSingle({
    tokenIn: WETH,
    tokenOut: USDC,
    amountIn: amount,
    fee: 3000,
    sqrtPriceLimitX96: 0,
  }).amountOut;

  const fee = quote500 >= quote3000 ? 500 : 3000;
  require((fee == 500 ? quote500 : quote3000) >= minUsdc, "best quote below minUsdc");

  // Swap on the chosen pool, output to the Pot. uniswapV3 reverts if it delivers under minUsdc.
  const pool = UniswapV3.Factory.getPool(WETH, USDC, fee);
  const usdcBefore = pot.USDC;
  uniswapV3(pool, WETH, USDC, amount, 0, minUsdc, pot);
  const received = pot.USDC - usdcBefore;

  // Supply exactly what the swap delivered, credited to the beneficiary.
  USDC.approve(AaveV3.Pool, received);
  AaveV3.Pool.supply(USDC, received, beneficiary, 0);
  require(pot.USDC == usdcBefore, "supply did not take all the USDC received");

  return { quote500, quote3000, fee, received };
}
```

## How it works

* The pool is chosen inside the transaction. Both quotes read the pools in the same state the swap then trades against, so no other transaction can land between the quote and the swap.
* `uniswapV3` gets a price limit of `0`, so `minUsdc` is the only bound on the price. Set it from a fresh quote, such as the simulation below, minus the slippage you accept.
* `received` is the change in the Pot's USDC balance, not a return value. The program approves and supplies exactly that amount, then checks that the Pot's USDC is back where it started.
* `supply` credits `beneficiary`, Aave's `onBehalfOf`, so the aUSDC belongs to that account. If it is an external account, a later cook on this Pot cannot withdraw it. If you pass the Pot's own address, the Pot holds the aUSDC and a later cook can withdraw it.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile quote-swap-supply.sauce.ts --chain base
```

**2. Simulate**

```bash theme={null}
sauce simulate quote-swap-supply.sauce.ts --chain base --owner <your-address> \
  --assume-balance WETH:1 --args 1000000000000000000 2000000000 <beneficiary>
```

`--assume-balance WETH:1` gives the Pot 1 WETH for this simulation only. If your Pot is not deployed yet, the simulation deploys it first.

**3. Send**

```bash theme={null}
sauce run quote-swap-supply.sauce.ts --chain base --wallet <name> \
  --fund WETH:1 --args 1000000000000000000 2000000000 <beneficiary>
```

`--fund WETH:1` pulls 1 WETH from your wallet into the Pot in the same cook. To sign with your own wallet instead, print the unsigned transactions: the Pot's deployment when it has no code yet, the WETH transfer into the Pot, then the cook.

```bash theme={null}
sauce tx quote-swap-supply.sauce.ts --chain base --owner <your-address> \
  --fund WETH:1 --args 1000000000000000000 2000000000 <beneficiary>
```

## Simulation result

Simulated on a local fork of Base at block 52965104 with the current contracts, with owner `0xf39F…2266` and beneficiary `0x7099…79C8`. Nothing was signed or sent; the numbers change with the block.

```text theme={null}
main returns { quote500: Uint256, quote3000: Uint256, fee: Uint256, received: Uint256 }: { quote500: 2380895733, quote3000: 2378922144, fee: 500, received: 2380895733 }
...
What moved, in order:
...
  [3] 0xd0b5…F224        -> Pot                   2380.895733 USDC
  [4] Pot                -> 0xd0b5…F224           1 WETH
  [5] Pot                -> aBasUSDC 0x4e65…c0AB  2380.895733 USDC
  [6] mint               -> 0x7099…79C8           2380.895732 aBasUSDC
```

The 0.05% pool quoted 2,380.895733 USDC and the 0.3% pool 2,378.922144, so the program swapped on the 0.05% pool (`0xd0b5…F224`). The swap delivered exactly the quoted amount, and all of it went to Aave. The beneficiary received 2,380.895732 aBasUSDC, one base unit less than the USDC supplied. The cook used 585,616 gas, and the cook's value paid the Kitchen's execution fee.

On the same fork, with `minUsdc` set to 2,500 USDC, the cook reverts before any swap:

```bash theme={null}
sauce simulate quote-swap-supply.sauce.ts --chain base --owner <your-address> \
  --assume-balance WETH:1 --args 1000000000000000000 2500000000 <beneficiary> \
  --expect-revert "best quote below minUsdc"
```

```text theme={null}
As expected, the cook reverts: the program threw "best quote below minUsdc"
```

## Next steps

* [The same flow as an actions document](https://docs.eco.com/quickstarts/sauce/actions-swap-supply.md): the swap and the supply written as JSON, without the comparison of two quotes.
* [Distributed swap](https://docs.eco.com/quickstarts/sauce/distributed-swap.md): one order split across several pools under a price limit.
* [Supply idle funds](https://docs.eco.com/quickstarts/sauce/supply-idle.md): keep a USDC reserve in the Pot and lend the rest on Aave V3.
* [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate), [Names](https://docs.eco.com/sauce/names.md), [Protocols reference](https://docs.eco.com/sauce-sdk/reference/protocols.md).


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