StopLoss

Verified · Ion Swap Dark Contract · DSOL · Phase D
Contract ID
dc1_ec7d358d18d1ce6289dcf49be42a064d11ceeadf39255ed7f560f9e09b24
Code hash
cc17098ba384721d103f45e31a33ee59effe3b7d83155d59523c21b50643e80d
Deployer
Deploy tx
78c3e61f88ae88e19a055992dc4c9b26…
Created at block
Source
View .dsol source →
Wallet: detecting…

Entrypoints

Each form below maps directly to a contract entrypoint. Filling it in and clicking Call constructs a typed-argv DSOL call. Your wallet shows an approval modal before broadcasting; nothing fires without your explicit click.

place

trigger

Public state

loading…

Contract source Verified

Compiler
build-1261/dark-contracts/compiler v1
Source SHA-256
008c19c8bfc44c7f0faa60621e7e4e45b7c94c561db53f18cc0fc83377fc791b
Bytecode hash
cc17098ba384721d103f45e31a33ee59effe3b7d83155d59523c21b50643e80d
Verified by
auto (canonical mirror)
Verified at
Thu, 30 Apr 2026 03:20:40 GMT

The on-chain bytecode hash matches the SHA-256 of StopLoss's compiled output. This means the source below was the exact input the deployer used. Anyone can re-derive the same bytecode by compiling the source through build-1261/dark-contracts/compiler.

// 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);
  }
}
Download .dsol