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

# Swap USDC for DAI on Curve and deposit it into sDAI

> One Ethereum transaction that swaps USDC for DAI on Curve's 3pool and deposits the DAI into Maker's sDAI vault, with a minimum on the shares received.

The program swaps `amount` of the Pot's USDC for DAI on Curve's 3pool with `@sauce/router`'s `curve`, then deposits all the DAI received into `Maker.SDAI` for `receiver`. If the Pot holds less than `amount` USDC, the vault does not take all the DAI, or `receiver` gains fewer than `minShares` sDAI, the cook reverts and nothing moves.

**Target chains:** Ethereum. The example uses `USDC`, `Curve.ThreePool`, `Maker.Dai` and `Maker.SDAI`.

## 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 USDC 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 usdc-to-sdai.sauce.ts theme={null}
// Swaps `amount` of the Pot's USDC for DAI on Curve's 3pool, then deposits all the DAI received
// into Maker's sDAI vault for `receiver`. Both amounts are measured as balance changes. The cook
// reverts, and nothing moves, when the Pot holds less than `amount` USDC, the vault does not take
// all the DAI, or `receiver` gains fewer than `minShares` sDAI.
//
//   sauce simulate usdc-to-sdai.sauce.ts --chain ethereum --owner <address> \
//     --assume-balance USDC:<amount>n --args <amount> <minShares> <receiver>
//   sauce run usdc-to-sdai.sauce.ts --chain ethereum --wallet <name> \
//     --fund USDC:<amount>n --args <amount> <minShares> <receiver>
//
//   amount: Uint256     the USDC to swap, in USDC's base units (6 decimals):
//                       1000000000 is 1,000 USDC
//   minShares: Uint256  the fewest sDAI shares `receiver` must gain, in wei (18 decimals):
//                       800000000000000000000 is 800 sDAI
//   receiver: Address   the account the vault credits with the sDAI
//
// On Ethereum, turn 1,000 USDC into at least 800 sDAI for <receiver>:
//
//   sauce run usdc-to-sdai.sauce.ts --chain ethereum --wallet me --fund USDC:1000 \
//     --args 1000000000 800000000000000000000 <receiver>
import { curve } from "@sauce/router";

function main(
  amount: Uint256,
  minShares: Uint256,
  receiver: Address,
): { dai: Uint256; shares: Uint256 } {
  require(amount > 0, "amount is zero");
  require(receiver != 0, "no receiver");
  require(pot.USDC >= amount, "not enough USDC in the Pot");

  // 3pool's coins are DAI (0), USDC (1), USDT (2). DAI is not a token symbol on Ethereum;
  // Maker.Dai is its address. `curve` returns the DAI the Pot gained; minShares bounds the result.
  const daiBefore = Token(Maker.Dai).balanceOf(pot);
  const dai = curve(Curve.ThreePool, USDC, Maker.Dai, amount, 1, 0, false, 0, pot);

  const sharesBefore = Token(Maker.SDAI).balanceOf(receiver);
  Token(Maker.Dai).approve(Maker.SDAI, dai);
  Maker.SDAI.deposit(dai, receiver);
  require(Token(Maker.Dai).balanceOf(pot) == daiBefore, "vault did not take all the DAI");
  const shares = Token(Maker.SDAI).balanceOf(receiver) - sharesBefore;
  require(shares >= minShares, "shares below minShares");

  return { dai, shares };
}
```

## How it works

* DAI has no token symbol on Ethereum in the registry, so the program names it `Maker.Dai`: as `curve`'s output token, and as `Token(Maker.Dai)` for the balance read and the approval to the vault.
* `curve(Curve.ThreePool, USDC, Maker.Dai, amount, 1, 0, false, 0, pot)` swaps coin 1 (USDC) for coin 0 (DAI), with `false` for 3pool's `int128` indices. It approves the pool for exactly `amount` and returns the change in the Pot's DAI.
* The pool's minimum output is `0`, so `minShares` is the only bound on the swap price. Set it from a fresh simulation, minus the slippage you accept.
* `deposit`'s result is discarded, and a discarded result is neither decoded nor checked. `shares` is therefore the change in `receiver`'s sDAI balance.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile usdc-to-sdai.sauce.ts --chain ethereum
```

**2. Simulate**

```bash theme={null}
sauce simulate usdc-to-sdai.sauce.ts --chain ethereum --owner <your-address> \
  --assume-balance USDC:1000 --args 1000000000 800000000000000000000 <receiver>
```

`--assume-balance USDC:1000` gives the Pot 1,000 USDC for this simulation only. The result lists the DAI the swap delivered and the sDAI shares `receiver` gained.

**3. Send**

```bash theme={null}
sauce run usdc-to-sdai.sauce.ts --chain ethereum --wallet <name> \
  --fund USDC:1000 --args 1000000000 800000000000000000000 <receiver>
```

`--fund USDC:1000` pulls 1,000 USDC from your wallet into the Pot in the same cook. `sauce tx` prints the unsigned transactions instead, for your own signer: the Pot's deployment if it has no code yet, the transfer of the USDC into the Pot, then the cook.

```bash theme={null}
sauce tx usdc-to-sdai.sauce.ts --chain ethereum --owner <your-address> \
  --fund USDC:1000 --args 1000000000 800000000000000000000 <receiver>
```

## Simulation result

Simulated on a local fork of Ethereum at block 26252095 with the current contracts, with the command above. Nothing was signed or sent.

```text theme={null}
main returns { dai: Uint256, shares: Uint256 }: { dai: 999869412500378846204, shares: 845864860423695566047 }
...
What moved, in order:
...
  [3] Pot                -> Curve.ThreePool 0xbEbc…F1C7  1000 USDC
  [4] Curve.ThreePool    -> Pot                          999.869412500378846204 DAI
  [5] Pot                -> Maker.SDAI 0x83F2…BEeA       999.869412500378846204 DAI
  [6] Maker.SDAI         -> burn                         999.869412500378846204 DAI
```

1,000 USDC bought 999.869412500378846204 DAI on the 3pool. The vault took all of it, and `receiver` gained 845.864860423695566047 sDAI, above the 800 sDAI floor. The cook used 390,673 gas.

On the same fork, with `minShares` at 900 sDAI, the cook reverts:

```bash theme={null}
sauce simulate usdc-to-sdai.sauce.ts --chain ethereum --owner <your-address> \
  --assume-balance USDC:1000 \
  --args 1000000000 900000000000000000000 <receiver> \
  --expect-revert "shares below minShares"
```

```text theme={null}
As expected, the cook reverts: the program threw "shares below minShares"
```

## Next steps

* [Supply idle USDC](https://docs.eco.com/quickstarts/sauce/supply-idle.md): keeps a USDC reserve in the Pot and supplies the rest to Aave V3.
* [Quote, swap and supply](https://docs.eco.com/quickstarts/sauce/quote-swap-supply.md): compares two pools' quotes before a swap and supplies the output.
* [`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.