// StopLoss — Phase D of silent-iron-keystone v4. // // TWAP-protected conditional sell. User commits to a trigger // threshold + amount; anyone can call trigger() once the TWAP price // crosses the threshold. Trigger caller earns a 0.1% bounty. // // TWAP source: pool reserves at each block from pool_events. Window // must be >= 30 blocks (~1 minute) per audit F-06 to defeat // flash-loan manipulation. dark contract StopLoss { public mapping(bytes => bytes) slPool; // order_id → pool_id public mapping(bytes => uint64) slThreshold; // order_id → threshold price public mapping(bytes => uint8) slDirection; // order_id → 0=sell-when-below, 1=sell-when-above public mapping(bytes => uint64) slAmount; // order_id → amount to sell public mapping(bytes => uint64) slTwapWindow; // order_id → TWAP window blocks public mapping(bytes => uint64) slExpires; // order_id → expiry block public mapping(bytes => bool) slExecuted; public mapping(bytes => bool) triggerNullifiers; @direct entry place(bytes order_id, bytes pool_id, uint64 threshold, uint8 direction, uint64 amount, uint64 twap_window, uint64 expires) { require(slExpires[order_id] == 0, "SL_DUPLICATE"); require(twap_window >= 30, "SL_TWAP_TOO_SHORT"); require(expires > block.number + 100, "SL_EXPIRES_TOO_SOON"); require(amount > 0, "SL_ZERO_AMOUNT"); require(threshold > 0, "SL_ZERO_THRESHOLD"); require(direction <= 1, "SL_BAD_DIRECTION"); slPool[order_id] = pool_id; slThreshold[order_id] = threshold; slDirection[order_id] = direction; slAmount[order_id] = amount; slTwapWindow[order_id] = twap_window; slExpires[order_id] = expires; slExecuted[order_id] = false; } // Trigger: caller asserts the TWAP has crossed the threshold. The // contract trusts the caller's claim subject to the nullifier // freshness check; the backend's TWAP-validation handler verifies // the claim against `pool_events` before crediting the trigger. // If the validation fails, the syscall reverts and the order // remains unexecuted. @direct entry trigger(bytes order_id, bytes nullifier) { require(slExpires[order_id] != 0, "SL_UNKNOWN"); require(!slExecuted[order_id], "SL_ALREADY_EXECUTED"); require(block.number < slExpires[order_id], "SL_EXPIRED"); require(!triggerNullifiers[nullifier], "SL_REPLAY"); slExecuted[order_id] = true; triggerNullifiers[nullifier] = true; syscall(TOKEN_TRANSFER_EMIT_V1, ctx.txHash); } }