Router
One call to buy or sell any coin or leveraged token, paying in ETH or USDG.
SwapRouter assembles the whole route, so a caller passes an address and an amount and
nothing else. A coin never trades against ETH or USDG directly — it trades against a
leveraged token, which the quote book prices — so every trade is the same hops, hidden:
ETH --v3--> USDG --quote book (v4)--> leveraged token --v3 or v4--> COINThe last hop depends on where the coin currently lives: the v3 curve before graduation, the v4 pool after it. The router reads which from the launcher rather than keeping its own registry, so a coin that graduates mid-flight routes correctly on the very next block with nothing to update.
Launched coins
function buyWithUsdg(address coin, uint256 usdgIn, uint256 minCoinOut, address to)
external returns (uint256 coinOut);
function buyWithEth(address coin, uint256 minCoinOut, address to)
external payable returns (uint256 coinOut);
function sellForUsdg(address coin, uint256 coinIn, uint256 minUsdgOut, address to)
external returns (uint256 usdgOut);
function sellForEth(address coin, uint256 coinIn, uint256 minEthOut, address to)
external returns (uint256 ethOut);Selling pulls the coin, so it needs an allowance on the router first. Buying with USDG needs one on USDG; buying with ETH needs none.
A buy larger than the curve can absorb is trimmed rather than reverted. You receive what
the curve could sell and the remainder is refunded in whatever you paid with, with a
BuyResized event recording both figures.
Leveraged tokens
The same four, against the assets the quote book makes a market in:
function buyLtWithUsdg(address lt, uint256 usdgIn, uint256 minLtOut, address to)
external returns (uint256 ltOut);
function buyLtWithEth(address lt, uint256 minLtOut, address to)
external payable returns (uint256 ltOut);
function sellLtForUsdg(address lt, uint256 ltIn, uint256 minUsdgOut, address to)
external returns (uint256 usdgOut);
function sellLtForEth(address lt, uint256 ltIn, uint256 minEthOut, address to)
external returns (uint256 ethOut);One book hop, no curve and no graduated pool. Whether an asset is tradable is asked of the
hook itself rather than a list held by the router, so an asset it does not quote — or whose
book is switched off — is refused by name with NotQuoted(lt).
Launching
function launch(string calldata name, string calldata symbol, uint256 firstBuyNumeraire)
external returns (address token, address pool);firstBuyNumeraire is optional and denominated in the leveraged token. Anything the curve
cannot absorb is refunded.
Quoting a trade
Simulate the call you are about to send. Nothing else gives the same number: the book reprices every ten seconds and a fill executes at whatever quote is live when it lands, so a figure derived from an indexed price is a different figure from the one the caller gets.
For a payable call, a node rejects the simulation outright when the sender cannot cover
value + gas, before any contract logic runs. Quote it through eth_call with the caller's
balance overridden for that one call — what a buy returns does not depend on who is asking.
Errors worth decoding
Attach these to your ABI or a revert arrives as "unknown reason":
| Error | Meaning |
|---|---|
NotQuoted(lt) | The book does not quote that asset, or its book is off. |
CurveExhausted(coin) | The curve is fully bought and the coin has not graduated yet. Retry in a few seconds. |
QuoteStale() | The book's quote is older than its staleness window. |
InsufficientInventory(id, wanted, have) | The shared USDG reserve cannot cover that sell. |
Slippage(got, wanted) | The floor you passed was not met. |
UnknownCoin(coin) | Not a coin this launcher created. |