Overview

1inch Aqua is a programmable shared liquidity layer. It targets a structural inefficiency in decentralized finance: most capital locked in traditional AMM pools sits idle on any given day, earning no fees while still bearing impermanent loss risk. Aqua's approach is to keep capital in maker-controlled wallets and let the same assets back multiple swap strategies at once, with no pooled custody and no capital migration required.

Positions and strategies are the same thing. In the 1inch dApp you open a position. On-chain, and throughout the SDK, the API and these developer docs, that same object is called a strategy. The code identifiers are fixed and cannot be renamed: strategyHash, the Strategy struct/DTO, the /strategies endpoint and ship()/dock(). These docs use strategy so the prose matches the code you call. Read it as the dApp's position.

Aqua is self-custodial. Tokens stay in the maker's own wallet under a revocable, per-chain, per-token allowance and move only when a taker fills a swap atomically. The protocol holds 0 tokens; virtual balances are an internal accounting counter in Aqua.sol. Smart-contract risk and approval risk still apply.


The problem Aqua solves

Traditional AMMs achieve O(1) swap complexity by forcing all liquidity providers into an identical strategy: same fee tier, same pricing curve, same parameters. This standardization was the price of computational simplicity. It also locks capital in a single pool, making it unavailable for governance, money-market collateral, or any other DeFi use while deployed.

The consequences compound:

  • Idle capital. Most capital locked in AMM pools sits idle on any given day, earning no fees while still bearing impermanent loss risk.
  • Capital fragmentation. LPs must split finite capital across protocols, pairs, and price ranges, diluting depth everywhere.
  • Locked utility. Tokens committed to pools lose governance rights, staking rewards, and money-market composability.

Aqua addresses all three by separating the accounting layer (who has how much) from the strategy layer (how to price and execute), while leaving custody entirely with the maker.


How Aqua works

Virtual balances

Instead of taking custody, Aqua maintains a four-level nested mapping that tracks virtual token balances. These are authorizations, not deposits:

Solidity
1
2
3
4
Maker Address
    → Application Address
        → Strategy Hash (bytes32)
            → Token Address → Balance

A maker calls ship() to allocate a virtual balance to a strategy. No tokens move; only the accounting record is created. The strategy hash is derived from the strategy's immutable parameters (strategyHash = keccak256(abi.encode(strategy))), making each strategy a fixed, auditable artifact. If parameters need to change, the maker docks the old strategy and ships a new one.

The four lifecycle verbs

Operation Who calls it What it does
ship() Maker Allocates virtual balance to a strategy; no token transfer
dock() Maker Revokes virtual balance instantly; no token transfer
pull() AquaApp Decreases virtual balance; transfers tokens from the maker wallet to fill a swap
push() AquaApp Increases virtual balance; returns tokens to the maker; auto-compounds into available liquidity
  • pull() checks the maker's actual wallet balance at execution time and reverts if it is insufficient, so a fill is atomic with no partial fills, no bad debt, and no protocol insolvency.
  • push() immediately expands the strategy's usable balance, so earned tokens compound into productive liquidity without manual rebalancing.

A taker fill is atomic: swap() = pull() + push() in one transaction, all-or-nothing. Takers call swap() directly, and quote() is a static call for simulation. Aqua has no order-level partial fills.

Strategies are data, not contracts

A strategy is an ABI-encoded structure, opaque bytes from Aqua's perspective, that encodes all pricing parameters (price curves, fee tiers, concentration ranges, and so on). The swap logic lives in an AquaApp contract, not in the strategy itself. This separation means a single AquaApp can serve many strategies, and makers never need to deploy per-strategy contracts.

The full model is three layers: a Program (the instruction sequence) is encoded by SwapVM, the Aqua swap engine, into an Order, which is then registered on Aqua as a Strategy via ship(). Aqua treats the Order body as opaque bytes and only accounts for virtual balances; it does not interpret pricing logic. The chain is Program → Order → Strategy.


The two core contracts

Aqua is deployed on 13 EVM chains. Both core contracts are deployed at the same address on every chain by a nonce-synchronized deployer account (plain CREATE).

Contract Address (all 13 chains) Purpose
Aqua (a.k.a. Aqua registry; deployed on-chain as AquaRouter) 0x1111113ccf1426a8e30e2bff5e005d929bf6a90a Virtual-balance registry; lifecycle operations (ship, dock, pull, push)
AquaSwapVMRouter v1.0.2 0x111111338c5091e8440b67b168bae16a668ac0de The deployed SwapVM router; runs strategy programs at swap time

The Aqua registry is the settlement layer: it owns no tokens and enforces accounting invariants. It is deployed on-chain under the name AquaRouter, but it is the registry, not a swap router. AquaSwapVMRouter is the execution engine: it interprets the Program instructions inside a SwapVM Order at swap time. A single production router serves all strategy types; the strategy type is set by the instruction program inside the strategy bytes, not by the app address.

See Contract Addresses for the full chain matrix, the KycNFT taker credential, and Foundry setup.


The Shared Liquidity Ratio

Aqua's capital-efficiency model is expressed as the Shared Liquidity Ratio (SLR): the total notional liquidity a maker provisions across all of its strategies divided by the actual wallet equity backing it.

SLR = (total notional liquidity provisioned across all strategies)
      -------------------------------------------------------------  ≥ 1
                 (actual wallet equity backing it)

The SLR measures availability and capital efficiency, not leverage. Consider a maker with $1,000 of wallet equity. Because different strategies rarely need to fill at the same instant, the maker can make that same balance available to several strategies at once. If the balance backs three strategies, the total notional liquidity advertised is higher than the equity behind it, giving an SLR above 1. No tokens are borrowed and no collateral is created. Every fill is capped by the real wallet balance at execution time, because pull() reverts if the wallet cannot cover it. Any multiplier is therefore a ceiling on advertised depth, never a claim on funds the maker does not hold, and never a forecast of returns.

Because DEX utilization is asynchronous and low at any single moment, different strategies activate at different times, letting the same capital service several strategies' occasional swaps without collision. Higher aggregate utilization means a given balance has more opportunities to earn swap fees across strategies. Swap fees are not guaranteed and do not offset impermanent loss in every market.


Complexity trade-off

Aqua deliberately accepts O(n) swap complexity, where n is the number of makers or strategies accessed to fill an order, in exchange for true strategy specialization. Traditional AMMs achieve O(1) by homogenizing all LP behavior; Aqua lets each maker run a distinct formula.

This fragmentation from the taker's perspective is handled by the existing aggregation layer: DEX aggregators and solvers already maintain off-chain indexing and route across many sources. Aqua liquidity is off-chain discoverable and on-chain executable. Aggregators index available virtual balances off-chain, while settlement is trustless and atomic on-chain.


Security model

Aqua's security rests on three invariants:

  1. Self-custodial. Aqua never holds tokens. Maximum exposure equals the ERC-20 allowance a maker explicitly grants, and that allowance is revocable per chain and per token. Smart-contract risk and approval risk still apply.
  2. Allowance-bounded access. Each strategy's fills cannot exceed the maker's ERC-20 approval to Aqua, giving granular per-token and per-strategy risk control. One approval per chain can back many strategies on that chain.
  3. Atomic fills. pull() reverts if the maker's real wallet balance is insufficient, so a swap completes fully or fails cleanly.

Economic risks (impermanent loss, path-dependent losses in Dutch-auction strategies, and reduced fill availability when a wallet is underfunded) remain, but they are the same market-making risks present in any AMM. Aqua makes them transparent and bounded rather than introducing new protocol-level risk. There is no on-chain pause and no liquidation: an underfunded strategy simply stops filling until it is refunded or docked. Makers are advised to dock strategies that become chronically underfunded to avoid accumulating adverse price exposure during illiquid periods.

Choose your path

Ship your first strategy

  • Getting Started: install the SDK (@1inch/swap-vm-sdk and @1inch/aqua-sdk), compose an XYC program, ship liquidity, execute a swap, and dock.

Understand the protocol before building

  • Core Concepts: maker, taker, strategy, virtual balances, and the lifecycle verbs.
  • Strategy: the three-layer model in full detail.

Strategy author

  1. Core Concepts: the mental model.
  2. Strategy Lifecycle: ship / dock / pull / push and their events (Shipped, Docked, Pulled, Pushed, Swapped), documented on the Smart Contract reference.
  3. Strategy Patterns: pick a recipe (XYC AMM, Limit Order, Dutch Auction, and more).
  4. Build an AquaApp: implement swap logic in Solidity.

Router or aggregator integration

  • SwapVM Instructions: the deployed opcode set (Controls, XYCSwap, XYCConcentrate, Decay, Fee, PeggedSwap, Extruction) and how the swap engine runs a program.
  • Smart Contract reference: the AquaSwapVMRouter and Aqua registry ABIs, addresses, and event schemas.


Shared Liquidity Ratio: a worked example

The Shared Liquidity Ratio (SLR) measures how many times the same wallet balance is made available across strategies. It is an availability and efficiency figure, not leverage: nothing is borrowed, and any multiplier is a ceiling capped by the real wallet balance, never a forecast.

SLR = (total liquidity made available across all strategies) / (actual wallet balance backing it)   // >= 1

Example: 1,000 USDC referenced by 3 strategies  ->  SLR = 3
The 3 strategies share the same 1,000 USDC; a fill on one draws from that balance,
which then limits the others. No position can pull tokens the wallet does not hold.

1inch Aqua vs a traditional pooled AMM

Traditional pooled AMM 1inch Aqua
Custody Tokens deposited into the pool contract Self-custodial: tokens stay in the maker's wallet under a revocable allowance; the protocol holds 0 tokens
Capital One deposit backs one pool One wallet balance can back many strategies on a chain (Shared Liquidity Ratio)
Pricing Fixed curve per pool Programmable: SwapVM opcodes (xyc / concentrated / pegged / custom via Extruction)
Build effort Deploy a new pool/pair contract Compose existing opcodes (no new contract, Path B) or embed proprietary pricing (Path C)
Exit Withdraw liquidity dock() clears the allocation; no tokens ever moved to the protocol

Taker access gate (checked at swap time). At launch every dApp strategy carries the Controls opcode _onlyTxOriginTokenBalanceNonZero, which reverts TxOriginTokenBalanceIsZero unless balanceOf(tx.origin) > 0. It is evaluated at swap time, not ship time, so a strategy can be live yet untradeable until a permitted taker holds the credential. Because it reads tx.origin, smart-contract wallets, multisigs and ERC-4337 bundlers cannot pass it as takers today. Permitted takers at launch are KYB-verified 1inch Resolvers. See Access & resolvers.

Did you find what you need?