Skip to content

Every intent utilizes a two-segment curve to define the minimum required output at any given moment. This pricing mechanism is verified by IntentLib.requiredOut and enforced unconditionally during settlement.

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.
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.

announce, fill and the ERC-7683 resolver each run the same structural checks, in IntentLib.validate, before doing anything else. IntentLens.preview does not — it computes its 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.