Skip to main content

Overview

The Swap Adapter is a thin wrapper over Uniswap V3 that redeems C0 to USDC or USDT in a single transaction. It routes C0 through Uniswap V3, so users get a market price net of pool fees. This is the canonical user-facing path for withdrawals from C0. For deposits (USDC/USDT → C0), use the Swap Facility directly — see the deposit tutorial.

Writes

For server-side / Node.js usage, build a config with a private key account. For browser/dApp usage, build the config with a connector.
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) },
});

swapOut (C0 → USDC/USDT)

import { parseUnits } from "viem";
import {
  writeSwapAdapterSwapOut,
  addresses,
} from "@camino-treasury/sdk";

const adapter = addresses[mainnet.id].swapAdapter;
const c0 = addresses[mainnet.id].c0;
const usdc = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const amountIn = parseUnits("100", 6);          // 100 C0
const minAmountOut = (amountIn * 9975n) / 10000n; // 0.25% slippage

await writeSwapAdapterSwapOut(config, {
  account,
  address: adapter,
  args: [
    c0,               // extensionIn (the C0 you're selling)
    amountIn,         // amountIn
    usdc,             // tokenOut
    minAmountOut,     // minAmountOut
    account.address,  // recipient
    "0x",             // path (empty bytes → adapter's default Uniswap V3 route)
  ],
});
The user must approve the adapter to spend C0 first via writeC0Approve. See the withdraw tutorial for the full end-to-end flow.

Slippage protection

minAmountOut is enforced on-chain — the swap reverts if Uniswap routing produces less. Always set this to a sensible lower bound. Because C0 and USDC/USDT track ~1:1, a tight buffer based on the input amount works well in practice:
const minAmountOut = (amountIn * 9975n) / 10000n; // 0.25% slippage tolerance
For larger sizes or volatile market conditions, simulate first to get the routed output and base the floor on that:
import { simulateSwapAdapterSwapOut } from "@camino-treasury/sdk";

const { result: simulatedOut } = await simulateSwapAdapterSwapOut(config, {
  account,
  address: adapter,
  args: [c0, amountIn, usdc, 0n, account.address, "0x"],
});

const minAmountOut = (simulatedOut * 9970n) / 10000n; // 0.30% off the simulated output

Path routing

The path argument is a Uniswap V3 path-encoded bytes value. Pass "0x" (empty) to let the adapter use its default routing. Override it only if you need to force a specific multi-hop path.