Skip to main content
This tutorial walks through redeeming C0 back to USDC using the SwapAdapter, which routes through Uniswap V3 in a single transaction.

View withdraw.ts on GitHub

Runnable script in the SDK repo.

1. Set up the config

Build a wagmi config with a private key account. (For browser/dApp usage, swap the private key for a connector like injected() from @wagmi/core.)
import { createConfig, http } from "@wagmi/core";
import { mainnet } from "@wagmi/core/chains";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const config = createConfig({
  chains: [mainnet],
  transports: { [mainnet.id]: http(process.env.ETH_RPC_URL) },
});

2. Read your C0 balance

Default to redeeming everything you hold.
import { addresses, readC0BalanceOf } from "@camino-treasury/sdk";

const { c0, swapAdapter } = addresses[mainnet.id];

const c0Balance = await readC0BalanceOf(config, {
  address: c0,
  args: [account.address],
});

3. Approve the SwapAdapter to spend C0

import { waitForTransactionReceipt } from "@wagmi/core";
import { writeC0Approve } from "@camino-treasury/sdk";

const approveHash = await writeC0Approve(config, {
  account,
  address: c0,
  args: [swapAdapter, c0Balance],
});
await waitForTransactionReceipt(config, { hash: approveHash });

4. Swap C0 → USDC

Call swapOut on the SwapAdapter to route C0 through Uniswap V3 to USDC in a single transaction. We apply a 0.25% slippage buffer based on the input amount (the C0/USDC pool tracks ~1:1, so this is a tight but safe floor).
import { writeSwapAdapterSwapOut } from "@camino-treasury/sdk";

const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;

const minAmountOut = (c0Balance * 9975n) / 10000n; // 0.25% slippage tolerance

const swapHash = await writeSwapAdapterSwapOut(config, {
  account,
  address: swapAdapter,
  args: [
    c0,                // extensionIn (the C0 you're selling)
    c0Balance,         // amountIn
    USDC,              // tokenOut
    minAmountOut,      // minAmountOut (slippage floor)
    account.address,   // recipient
    "0x",              // path (empty bytes → use the adapter's default Uniswap V3 route)
  ],
});
await waitForTransactionReceipt(config, { hash: swapHash });
The swap reverts on-chain if Uniswap routing produces less than minAmountOut, so you’re protected against slippage and front-running.

What’s next