VimenZap API
The external interface of the VimenZap2 router.
The live router is VimenZap2
(0x99c8…12c1).
Stateless: no owner, no admin, no pause, no upgradeability; it holds nothing
between transactions. Design rationale:
VimenZap internals.
Types
/// One pool traversal. zeroForOne = true consumes key.currency0, produces key.currency1.
struct Hop {
PoolKey key;
bool zeroForOne;
}
/// One Rialto-filled leg. `data` is the Rialto quote API's tx.data verbatim;
/// the call target is always resolved from Rialto's on-chain router registry,
/// never taken from the quote.
struct RialtoCall {
uint256 legIndex; // which constituent this call fills (mint) / sells (redeem)
uint256 sellAmount; // exact input from the quote
address spender; // allowance spender from the quote
bytes data; // tx.data from the quote, unmodified
}legs is always Hop[][]: one swap path per constituent, in
constituents() order. The contract validates path endpoints and
connectivity per leg (PathDiscontinuous, PathInputMismatch,
PathOutputMismatch).
Mint
zapMint
function zapMint(
address basket,
uint256 basketAmount,
address paymentCurrency, // address(0) = native ETH (sent as msg.value)
uint256 maxSpend,
Hop[][] calldata legs,
address to,
uint256 deadline
) external payable nonReentrant returns (uint256 spent)Buys every constituent for exactly basketAmount with exact-output Uniswap
v4 swaps, mints, and sends the basket to to. Spends at most maxSpend;
unspent native ETH is refunded. Requires a prior ERC-20 approval of
paymentCurrency to the router (or use the Permit2 variant).
zapMintPermit2
function zapMintPermit2(
address basket, uint256 basketAmount, address paymentCurrency,
uint256 maxSpend, Hop[][] calldata legs, address to, uint256 deadline,
Permit2Data calldata permit
) external nonReentrant returns (uint256 spent)zapMint without the approve transaction: the payer signs a Permit2
SignatureTransfer for (paymentCurrency, maxSpend, spender = router) and
funds flow straight into the PoolManager. One signature, one transaction, no
allowance left behind. Requires the once-ever approval of the payment token
to canonical Permit2 (0x0000…78BA3). Nonce replay is rejected.
zapMint2
function zapMint2(
address basket, uint256 basketAmount, address paymentCurrency,
uint256 maxSpend, Hop[][] calldata legs, RialtoCall[] calldata rialtoCalls,
address to, uint256 deadline, Permit2Data calldata permit
) external nonReentrant returns (uint256 spent)Mixed-venue mint: each constituent is filled either by a Uniswap v4 path
or a Rialto call; coverage is verified exactly once per leg
(LegNotCovered / LegDoublyCovered). Rialto approvals are exact and reset
to zero around each call, the call target is resolved from Rialto's on-chain
router registry (never from user data), and if a constituent balance doesn't
grow by the required amount the whole zap reverts. permit with an empty
signature falls back to a standard allowance pull. Native ETH is not
supported on this path (NativeNotSupported).
Redeem
zapRedeem
function zapRedeem(
address basket, uint256 basketAmount, address outputCurrency,
uint256 minOut, Hop[][] calldata legs, address to, uint256 deadline
) external nonReentrant returns (uint256 received)Pulls the basket, redeems in-kind, sells every constituent on Uniswap v4,
and pays outputCurrency to to. Reverts MinOutNotMet below your floor.
zapRedeem2
The mixed-venue mirror of zapMint2: Rialto legs sell the exact redeemed
amounts (RialtoSellMismatch otherwise), minOut is enforced on the
combined total, and any leftover constituent dust is swept to the recipient
rather than stranded.
Quotes (eth_call only)
function quoteZapMint(address basket, uint256 basketAmount, address paymentCurrency, Hop[][] calldata legs)
external returns (uint256 totalIn, uint256[] memory legIn);
function quoteZapRedeem(address basket, uint256 basketAmount, address outputCurrency, Hop[][] calldata legs)
external returns (uint256 totalOut, uint256[] memory legOut);
/// Basket-free exact-output quote for arbitrary legs (prices the Uniswap side
/// of a mixed-venue mint; Rialto legs are quoted by Rialto's API).
function quoteLegs(address[] calldata tokens, uint256[] calldata amounts, address paymentCurrency, Hop[][] calldata legs)
external returns (uint256 totalIn, uint256[] memory legIn);These run the real swaps inside a v4 unlock and revert with the
amounts (QuoteResult), so an eth_call returns exact execution numbers:
same math, same pools, same block. They are not view (they would mutate if
broadcast); call them, never send them.
Events
event ZapMinted(address indexed sender, address indexed basket, address inputCurrency, uint256 basketAmount, uint256 spent);
event ZapRedeemed(address indexed sender, address indexed basket, address outputCurrency, uint256 basketAmount, uint256 received);Errors worth handling
| Error | Meaning |
|---|---|
Expired | deadline passed |
LegUnderfilled(leg) | Range liquidity ran out mid-swap (v4 exact-output fills partially instead of reverting; the router rejects it) |
MaxSpendExceeded(required, maxSpend) | Execution would cost more than your cap |
MinOutNotMet(out, minOut) | Redeem output below your floor |
PathDiscontinuous / PathInputMismatch / PathOutputMismatch | Malformed swap path for a leg |
LegNotCovered / LegDoublyCovered | Mixed-venue coverage must be exactly one venue per leg |
RialtoSellMismatch(leg) | Rialto call's sell amount ≠ the leg's exact requirement |
RialtoRouterPaused | Rialto's registry reports its router paused |
WrongMsgValue | msg.value inconsistent with paymentCurrency/maxSpend |
NativeNotSupported | ETH input/output on the *2 mixed-venue paths |