Summary
takeOrders4 gates the onTakeOrders2 callback only on config.data.length > 0 — not on whether any order actually filled. The IRaindexV6OrderTaker NatSpec documents the callback as firing "if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens." When non-empty data is passed but every order is dead/skipped (so totalTakerInput == 0), the callback still fires (with inputAmountSent == 0).
Observed (verified on current main)
Repro testCallbackDoesNotFireOnZeroInput: a single never-added (dead) order is taken with data = 0x01; totalTakerInput == 0 (asserted as a precondition). The test asserts — per the interface NatSpec — that the callback does not fire. It fails on main: the callback fired with inputAmountSent == 0. pushTokens(.., 0) is a no-op so no tokens move, but the external call to onTakeOrders2 still happens.
RaindexV6.sol gates the call at roughly L587–590; the NatSpec is in IRaindexV6OrderTaker (raindex-interface).
Why it matters / triage
A code-vs-documented-contract divergence — ambiguous which side is canonical:
- If the code is the bug: an unexpected external call to
msg.sender mid-takeOrders that an integrator relying on the documented "you received tokens" contract would not anticipate.
- If the NatSpec is stale: the interface doc should be corrected to match.
Either way, no existing test pins this gating in either direction (a coverage gap). Adjacent to I02 (#2625), which implicitly assumes the callback corresponds to a real settlement.
Provenance
Surfaced and verified by an adversarial review pass over current main. Repro on a throwaway scratch branch (uncommitted).
Summary
takeOrders4gates theonTakeOrders2callback only onconfig.data.length > 0— not on whether any order actually filled. TheIRaindexV6OrderTakerNatSpec documents the callback as firing "if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens." When non-emptydatais passed but every order is dead/skipped (sototalTakerInput == 0), the callback still fires (withinputAmountSent == 0).Observed (verified on current
main)Repro
testCallbackDoesNotFireOnZeroInput: a single never-added (dead) order is taken withdata = 0x01;totalTakerInput == 0(asserted as a precondition). The test asserts — per the interface NatSpec — that the callback does not fire. It fails onmain: the callback fired withinputAmountSent == 0.pushTokens(.., 0)is a no-op so no tokens move, but the external call toonTakeOrders2still happens.RaindexV6.solgates the call at roughly L587–590; the NatSpec is inIRaindexV6OrderTaker(raindex-interface).Why it matters / triage
A code-vs-documented-contract divergence — ambiguous which side is canonical:
msg.sendermid-takeOrdersthat an integrator relying on the documented "you received tokens" contract would not anticipate.Either way, no existing test pins this gating in either direction (a coverage gap). Adjacent to I02 (#2625), which implicitly assumes the callback corresponds to a real settlement.
Provenance
Surfaced and verified by an adversarial review pass over current
main. Repro on a throwaway scratch branch (uncommitted).