DutchAuction

DutchAuction is a SwapVM pre-swap price modifier that applies exponential, time-based price decay to virtual reserves before the swap formula runs. The longer the auction runs, the more the price improves for the taker.

Scope: DutchAuction is the Dutch-auction modifier that belongs to the Limit Order and Fusion opcode set (it is what distinguishes a Fusion order from a plain limit order). It is not part of the Aqua AMM router opcode set (Controls, XYCSwap, XYCConcentrate, Decay, Fee, PeggedSwap, Extruction). Both routers run on the same engine, SwapVM.

Source: src/instructions/DutchAuction.sol


Args encoding

Field Offset Size Type Description
startTime 0 5 bytes uint40 Auction start (Unix timestamp, seconds)
duration 5 2 bytes uint16 Auction length in seconds; expires at startTime + duration
decayFactor 7 8 bytes uint64 Per-second decay multiplier in 1e18 scale; must be < 1e18

Total: 15 bytes. Build with DutchAuctionArgsBuilder.build(uint40 startTime, uint16 duration, uint64 decayFactor).

Decay factor examples

decayFactor Effect per second
0.9999e18 0.01% decay/s
0.999e18 0.1% decay/s
0.99e18 ~1% decay/s
0.9e18 ~10% decay/s

Instructions

Both instructions must be placed before any swap formula instruction (balances must not have amounts computed yet). They modify balanceIn or balanceOut so the downstream swap formula sees the decayed value.

Decay is computed as decay = decayFactor ^ elapsed using fixed-point exponentiation.

_dutchAuctionBalanceIn1D

Solidity
1
function _dutchAuctionBalanceIn1D(Context memory ctx, bytes calldata args) internal view

Shrinks balanceIn by the decay factor. The downstream swap instruction prices the same amountOut against a smaller balanceIn, giving a lower effective price for the taker (the maker accepts less input).

ctx.swap.balanceIn = balanceIn * decay / 1e18

_dutchAuctionBalanceOut1D

Solidity
1
function _dutchAuctionBalanceOut1D(Context memory ctx, bytes calldata args) internal view

Expands balanceOut by the inverse of the decay factor. The downstream swap instruction computes a larger amountOut for the same amountIn (the taker receives more output over time).

ctx.swap.balanceOut = balanceOut * 1e18 / decay

Shared behavior and errors

Both instructions:

  • Revert if block.timestamp > startTime + duration.
  • Require that neither amountIn nor amountOut is set yet, so they must precede the swap formula.
  • Carry the 1D suffix, meaning they read dynamic chain state (block.timestamp) and are therefore declared view, not pure.
Error Condition
DutchAuctionExpired(currentTime, deadline) block.timestamp > startTime + duration
DutchAuctionShouldBeAppliedBeforeSwapAmountsComputed(amountIn, amountOut) Either amount already set

  • LimitSwap: typical predecessor that sets the base rate.
  • Balances: sets reserves before this instruction.

Did you find what you need?