Skip to main content

Universal Router

The Universal Router is a single smart contract that can execute swaps across both V2 and V3 pools. It serves as the unified entry point for all trading operations on Kroko DEX.

Why a Universal Router?

Without it, swapping through V2 and V3 would require separate contracts and separate transactions. The Universal Router:
  • Unifies execution — One contract handles V2, V3, and mixed-protocol swaps
  • Enables complex routes — Multi-hop swaps that cross between V2 and V3 pools
  • Reduces gas — Batches operations in a single transaction
  • Integrates Permit2 — Pulls tokens via Permit2 for streamlined approvals

How It Works

The Universal Router receives encoded commands and inputs via its execute() function:
function execute(
    bytes calldata commands,
    bytes[] calldata inputs,
    uint256 deadline
) external payable;
  • commands: A byte string where each byte is a command code (e.g., V2_SWAP_EXACT_IN, V3_SWAP_EXACT_IN, WRAP_ETH, UNWRAP_WETH, etc.)
  • inputs: ABI-encoded parameters for each command
  • deadline: Unix timestamp after which the transaction reverts

Typical Swap Flow

1. Swap API finds the optimal route
2. Swap API encodes the route as Universal Router commands
3. Frontend receives { to, data, value } from the API
4. User signs and sends the transaction
5. Universal Router executes the commands sequentially
Developers do not need to encode commands manually — the Swap API handles this. You simply forward the response:
const tx = await signer.sendTransaction({
  to: swapData.to,      // Universal Router address
  data: swapData.data,  // Encoded execute() calldata
  value: swapData.value // Native KAS amount (0 for ERC-20 to ERC-20)
});

Slippage Protection

The encoded calldata includes on-chain slippage checks:
Trade TypeProtectionDescription
Exact InputminAmountOutReverts if output is below minimum
Exact OutputmaxAmountInReverts if input exceeds maximum
These checks are enforced by the Universal Router on-chain, not just the API.

Native KAS Handling

When a swap involves native KAS (not WKAS), the Universal Router automatically:
  • Selling KAS: Wraps the KAS sent as msg.value into WKAS before the swap
  • Buying KAS: Unwraps WKAS to KAS and sends it to the recipient after the swap
The value field in the Swap API response is non-zero when native KAS is the input token.