Skip to content

Every V6 intent utilizes a two-segment curve to define the signed floor at any given moment. This pricing mechanism is verified by IntentLib.requiredOut and enforced during settlement. The filler’s gross requirement also includes the protocol fee and, for outsiders at or before startTime, the exclusivity override.

The required output floor drops linearly and then rests flat.

  • Before or at startTime: The required output is strictly startAmountOut.
  • Between startTime and decayEndTime: The required output drops linearly from startAmountOut down to endAmountOut.
  • At or after decayEndTime: The required output rests at endAmountOut until the order completely expires at endTime.
The required output floor over time: flat at startAmountOut until startTime, a linear decay to endAmountOut, then a flat rest until endTime. startAmountOut endAmountOut startTime decayEndTime endTime time t ≤ startTime linear decay floor rests until endTime fills accepted through endTime signed floor — IntentLib.requiredOut outsider override at t ≤ startTime: floor + 25 bps
At or before startTime only SystemFillerGate may fill at the floor; an outsider fills that window at the dashed line. The 3 bps protocol fee is added on top of whichever floor applies and is paid by the filler.
nowTs <= startTime -> startAmountOut
nowTs >= decayEndTime -> endAmountOut
otherwise -> startAmountOut - mulDiv(startAmountOut - endAmountOut,
nowTs - startTime,
decayEndTime - startTime)

The resting stretch is the entire reason decayEndTime exists as a separate field from endTime. If the floor only existed for a single instant, a fast 30-second decay would create a tiny 30-second fill window. If a solver missed that specific block due to gas spikes or latency, the order could never fill. By separating the two, an order can decay rapidly to its final price and then remain safely open for solvers to take at the floor.

At or before startTime, the order is fillable at its startAmountOut floor. Only SystemFillerGate may fill at that floor. An outsider may still fill, but must pay floor + 25 bps to the recipient. After startTime, everyone fills at the curve floor. In every case, the filler also pays a 3 bps protocol fee on top of the applicable floor; the fee is sent to FeeVault and never reduces the owner’s proceeds.

announce and fill run the structural checks in IntentLib.validate before doing anything else. IntentLensV3.preview does not — it computes observations directly and never calls validate, so a screener cannot treat a successful preview as evidence that an order is well-formed.

Check Reverts with
owner != 0, recipient != 0 InvalidOrder
startTime < decayEndTime <= endTime InvalidOrder
startAmountOut >= endAmountOut, both non-zero InvalidOrder
amountIn != 0 InvalidOrder
Neither token is 0x0 or the native sentinel (0xEeee...) NativeNotSupportedInOrder
tokenIn != tokenOut SameToken

The startTime < decayEndTime check is strict to ensure the division denominator when calculating the curve decay can never be zero. decayEndTime == endTime is permitted to support single-deadline limit behaviors if desired.

The protocol requires ERC-20 tokens only. Native ETH is fundamentally unsupported on both the input and output legs.