SwapVM, the Aqua swap engine, evaluates fee instructions as part of a strategy program. This page documents an experimental fee family that applies fees to amountOut, together with volume-sensitive (progressive) fee formulas. These instructions extend the base Fee instruction set.
Experimental: not part of the shipped v1 fee set. The instructions on this page live in FeeExperimental.sol and are not registered on the deployed AquaSwapVMRouter. The shipped Aqua opcode set is Controls, XYCSwap, XYCConcentrate, Decay, Fee, PeggedSwap, and Extruction; the production Fee opcode applies fees to amountIn only.
The amountOut and progressive (volume-based) variants below are not available in Aqua v1, and there is no "LP Progressive Fees" product feature. In v1 only the LP swap fee is non-zero; protocol fees are 0 and are not shown. Treat this reference as a design record for review, not a description of on-chain behavior.
Source: src/instructions/FeeExperimental.sol
Fee scale: BPS = 1e9 (1e9 = 100%). feeBps is expressed on this scale, so feeBps = 1e9 is 100%.
Constraint shared by all instructions
Must be placed before swap amounts are computed (both amountIn and amountOut must be zero). Violating this reverts with FeeShouldBeAppliedBeforeSwapAmountsComputation.
Quote and swap divergence: in quote mode, token transfers and Aqua pulls are skipped. Quotes may succeed while swaps revert due to insufficient balance or missing approval. Do not use backward jumps to any of these instructions.
Instructions
_flatFeeAmountOutXD
function _flatFeeAmountOutXD(Context memory ctx, bytes calldata args) internal
Flat proportional fee deducted from amountOut. No token transfer.
| Field | Offset | Size | Description |
|---|---|---|---|
feeBps |
0 | 4 bytes (uint32) |
Fee rate; max 1e9 |
| Mode | Behavior |
|---|---|
| exactIn | Runs swap formula, then deducts amountOut × feeBps / BPS from result |
| exactOut | Inflates amountOut by fee before passing to swap formula; restores taker-defined value after |
_progressiveFeeInXD
function _progressiveFeeInXD(Context memory ctx, bytes calldata args) internal
Volume-sensitive fee on amountIn. The effective fee increases as amountIn grows relative to balanceIn. Large swaps pay proportionally more.
| Field | Offset | Size | Description |
|---|---|---|---|
feeBps |
0 | 4 bytes (uint32) |
Base fee rate (λ); max 1e9 |
exactIn formula: amountIn_eff = (BPS × amountIn × balanceIn) / (BPS × balanceIn + feeBps × amountIn)
exactOut formula (inverse): amountIn = ⌈(BPS × amountIn_eff × balanceIn) / (BPS × balanceIn − feeBps × amountIn_eff)⌉
_progressiveFeeOutXD
function _progressiveFeeOutXD(Context memory ctx, bytes calldata args) internal
Volume-sensitive fee on amountOut. The effective fee increases as amountOut grows relative to balanceOut.
| Field | Offset | Size | Description |
|---|---|---|---|
feeBps |
0 | 4 bytes (uint32) |
Base fee rate (λ); max 1e9 |
exactIn formula: amountOut_eff = (BPS × amountOut × balanceOut) / (BPS × balanceOut + feeBps × amountOut)
exactOut formula (inverse): amountOut = ⌈(BPS × amountOut_eff × balanceOut) / (BPS × balanceOut − feeBps × amountOut_eff)⌉
_protocolFeeAmountOutXD
function _protocolFeeAmountOutXD(Context memory ctx, bytes calldata args) internal
Flat fee on amountOut with a live ERC-20 transfer from maker to a recipient.
Protocol fees are configured to 0 in Aqua v1, and this amountOut variant is not registered on the deployed router. It is documented here for design review only.
| Field | Offset | Size | Description |
|---|---|---|---|
feeBps |
0 | 4 bytes (uint32) |
Fee rate; max 1e9 |
to |
4 | 20 bytes (address) |
Fee recipient |
Runs the swap formula, deducts fee from amountOut, then calls safeTransferFrom(maker, to, feeAmount) on tokenOut.
_aquaProtocolFeeAmountOutXD
function _aquaProtocolFeeAmountOutXD(Context memory ctx, bytes calldata args) internal
Same as _protocolFeeAmountOutXD but uses IAqua.pull(maker, orderHash, tokenOut, feeAmount, to) instead of a direct ERC-20 transfer.
| Field | Offset | Size | Description |
|---|---|---|---|
feeBps |
0 | 4 bytes (uint32) |
Fee rate; max 1e9 |
to |
4 | 20 bytes (address) |
Fee recipient |
Related
- Fee: the shipped fee instructions, applied to
amountIn - XYCSwap: typical swap formula nested inside fee instructions
- LimitSwap: another common nested swap formula