TW
Tripwire
Find contracts. Test them. Review real vulns.

Analysis Run

019b3836-220c-72ad-99e1-0bffbd1dfee3

complete
Chain ID
1
Address
Block Number
Created
Fri, Dec 19, 2025 8:03 PM
Review Summary

What survived the funnel

Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?

Confirmed
2
Validated
2
Source
Bytecode only
Review Backing
Present
Best current signal
Untrusted CALL target/value reachable
crit 0 high 2 direct contract
Review Checklist
1. Read the findings table first. Ignore raw jobs until the result looks real.
2. Confirm attacker control, not just the existence of a sink.
3. Confirm money or privilege impact.
4. Keep it if the behavior is real. Kill it if this is normal proxy, admin, or upgrade plumbing.

Processing Jobs

Status & attempts
ID Type Status Attempts Heartbeat
213 artifact.fetch complete 1 / 3 3 months ago
214 tool.cast_disasm complete 1 / 3 3 months ago
43291 analysis.bundle complete 1 / 3 1 week ago
43292 capability.graph complete 1 / 3 1 week ago
43293 detector.run complete 1 / 3 1 week ago
43294 validation.fork complete 1 / 3 1 week ago
71435 report.consolidate complete 1 / 6 1 week ago

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: no
Implementation:
Verified Source: no

Slither

tool.slither

No slither job recorded yet.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
2
No findings?
no
Summary
Bytecode analysis found one clear fail-open accounting issue in the payable path and one lower-confidence unchecked external call/reentrancy surface. I did not find delegatecall/proxy behavior or upgrade-slot writes in the provided bundle.
View stdout
{"no_findings":false,"summary":"Bytecode analysis found one clear fail-open accounting issue in the payable path and one lower-confidence unchecked external call/reentrancy surface. I did not find delegatecall/proxy behavior or upgrade-slot writes in the provided bundle.","findings":[{"severity":"high","category":"math","title":"Payable path fails open and persists state even when its apparent eligibility/collateral checks fail","exploit_scenario":"Selector 0x1aa3a008 appears to be the only state-changing/payable entrypoint. It checks a caller-specific slot6 mapping entry and a balance-vs-5x-msg.value condition, but on the failing branch it does not revert; instead it jumps into the CALL helper and then resumes normal execution. An attacker can therefore call the function even when they already have a nonzero recorded amount, or when the contract balance is below the apparent 5x threshold, and still reach the later SSTOREs that record msg.value and append the caller to the slot list. If the intended invariant was one-time participation or 5x collateralization, that invariant is bypassable.","recommendation":"Replace the fail-open CALL helper path with an actual revert on failed predicates. In source terms, enforce the checks before any external interaction or state write, and only continue to the SSTOREs when the predicates are satisfied.","evidence":"At pc 0x170-0x177 the code loads keccak(caller, slot 6) and branches to pc 0x17f only when the stored value is zero; otherwise it falls through to the CALL helper at pc 0x00ed and then continues anyway. At pc 0x183-0x197 it compares contract balance against msg.value * 5; if the check fails it again routes through the CALL helper and then continues. The state write still happens afterward at pc 0x1bc (slot6[caller] = CALLVALUE), followed by slot-list writes at pc 0x1ea and pc 0x1f4.","locations":["selector:0x1aa3a008","pc:0x170","pc:0x192","pc:0x1bc","pc:0x1ea","pc:0x1f4"]},{"severity":"low","category":"reentrancy","title":"Unchecked external CALL forwards gas before bookkeeping","exploit_scenario":"The shared helper at pc 0x00ed performs a CALL at pc 0x0101 to the fixed address 0x0000000000000000000000000000000000000194, forwards essentially all remaining gas, ignores the success bit, and then jumps back into the caller. In selector 0x1aa3a008 this helper is reached before the later SSTOREs. If address 0x194 had executable code at the analyzed block, it could reenter before bookkeeping is updated. Because the target is hardcoded and runtime bytecode alone does not tell me whether that address actually had code, this is a lower-confidence surface rather than a confirmed exploit.","recommendation":"Avoid external interaction in this helper, or at minimum check CALL success and move all state updates ahead of the call if reentrancy is not intended. If the helper was meant to revert, replace it with explicit revert logic.","evidence":"The helper beginning at pc 0x00ed builds a CALL frame and executes CALL at pc 0x0101. The return value is immediately discarded with POPs at pc 0x0102-0x0104, and execution resumes via JUMP at pc 0x0105. This helper is reachable from selector 0x1aa3a008 before the later writes, and directly from selector 0x854ba99d.","locations":["pc:0x00ed","pc:0x0101","pc:0x0102","selector:0x1aa3a008","selector:0x854ba99d"]}]}
View stderr
OpenAI Codex v0.118.0 (research preview)
--------
workdir: /tmp/codex-vyere7o6
model: gpt-5.4
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: none
session id: 019d5a50-9280-7470-9261-9006955ea8c2
--------
user
You are a security auditor. You ONLY have runtime bytecode + analysis artifacts.
You MUST read `BYTECODE_BUNDLE.json` before concluding; it contains the bytecode summary,
evidence bundle, callsites, storage slots, and detector findings.

Special cases when reasoning from bytecode (be explicit about uncertainty):
- Selector inference is best-effort; missing selectors are common.
- Fallback/receive paths may be the only entrypoints.
- CALL vs DELEGATECALL semantics differ; DELEGATECALL executes in caller storage.
- Proxy patterns (EIP-1967, minimal proxies, beacon) change which storage is authoritative.
- Storage slots are raw; mappings/arrays appear via keccak patterns, names are unknown.
- Guard detection is heuristic; absence of guards does NOT mean unguarded.
- Returndata checking is unknown unless explicitly shown in evidence.
- Precompiles (0x1..0x9) and common ERC20 transfer selectors may appear; do not over-claim.

Output MUST be valid JSON matching the provided schema.
- If you find nothing meaningful: set no_findings=true and findings=[].
- Otherwise: set no_findings=false and include findings with severity/category/title.
- Locations can be pc references like "pc:0x123" or selectors like "selector:0xa9059cbb".

Focus on: reentrancy, access control, upgradeability/proxy issues, signature validation,
accounting/invariant breaks, dangerous delegatecall, and untrusted external calls.
Be conservative: if evidence is weak, mark severity low/medium and explain why.
warning: Codex could not find system bubblewrap on PATH. Please install bubblewrap with your package manager. Codex will use the vendored bubblewrap in the meantime.
exec
/bin/bash -lc "pwd && ls -la && rg --files -g 'BYTECODE_BUNDLE.json' -g 'AGENTS.md'" in /tmp/codex-vyere7o6
 succeeded in 0ms:
/tmp/codex-vyere7o6
total 80
drwx------   2 noahkuhn noahkuhn  4096 Apr  4 21:05 .
drwxrwxrwt 270 nobody   nogroup  24576 Apr  4 21:05 ..
-rw-rw-r--   1 noahkuhn noahkuhn 44625 Apr  4 21:05 BYTECODE_BUNDLE.json
-rw-rw-r--   1 noahkuhn noahkuhn   815 Apr  4 21:05 codex-output-schema.json
BYTECODE_BUNDLE.json

exec
/bin/bash -lc "jq 'keys' BYTECODE_BUNDLE.json && printf '\\n--- summary ---\\n' && jq '.summary // .bytecode_summary // .metadata // {}' BYTECODE_BUNDLE.json && printf '\\n--- detector findings ---\\n' && jq '.detector_findings // .detectors // .findings // []' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 103ms:
[
  {
    "confidence": 60,
    "evidence_json": {
      "call_count": 1,
      "examples": [
        {
          "opcode": "CALL",
          "pc": 257,
          "returndata_checked": null,
          "target_expression_category": "computed",
          "value_expression_category": "computed"
        }
      ],
      "guards_detected": [],
      "untrusted_call_count": 1
    },
    "normalized_json": {
      "sink": "CALL"
    },
    "severity": "high",
    "title": "Untrusted CALL target/value reachable",
    "validated": true,
    "validation_json": {
      "attempts": 1,
      "call_targets": [
        "0x0000000000000000000000000000000000000194",
        "0x8226891a383dc93da036274431aa9e00b47104d0"
      ],
      "classification": "target_varies",
      "confirmed": true,
      "errors": 0,
      "matched_probe": null,
      "sink": "CALL",
      "status": "confirmed",
      "target_varies": true,
      "trace_id": "0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f",
      "trace_mode": "callTracer"
    }
  },
  {
    "confidence": 55,
    "evidence_json": {
      "eth_value_calls": 1,
      "examples": [
        {
          "opcode": "CALL",
          "pc": 257,
          "returndata_checked": null,
          "target_expression_category": "computed",
          "value_expression_category": "computed"
        }
      ],
      "guards_detected": []
    },
    "normalized_json": {
      "sink": "CALL",
      "value": "nonzero"
    },
    "severity": "high",
    "title": "ETH value transfer possible",
    "validated": true,
    "validation_json": {
      "attempts": 1,
      "call_targets": [
        "0x0000000000000000000000000000000000000194",
        "0x8226891a383dc93da036274431aa9e00b47104d0"
      ],
      "classification": "target_varies",
      "confirmed": true,
      "errors": 0,
      "matched_probe": null,
      "sink": "CALL",
      "status": "confirmed",
      "target_varies": true,
      "trace_id": "0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f",
      "trace_mode": "callTracer"
    }
  }
]

exec
/bin/bash -lc "printf '%s\\n' 'Reading the bytecode bundle structure and evidence now. I need the control-flow, callsite, and storage details before I can decide whether the detector hits are real security findings.' && jq '.analysis_artifact | keys' BYTECODE_BUNDLE.json && printf '\\n--- heuristics ---\\n' && jq '.heuristics_summary' BYTECODE_BUNDLE.json && printf '\\n--- capability graph keys ---\\n' && jq '.capability_graph | keys' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
Reading the bytecode bundle structure and evidence now. I need the control-flow, callsite, and storage details before I can decide whether the detector hits are real security findings.
[
  "address",
  "artifact_hash",
  "artifact_json",
  "block_number",
  "chain_id",
  "codehash",
  "created_at",
  "id",
  "updated_at",
  "version"
]

--- heuristics ---
{
  "create2_count": 0,
  "delegatecall_count": 0,
  "flags": [],
  "selfdestruct_count": 0
}

--- capability graph keys ---
[
  "address",
  "block_number",
  "chain_id",
  "codehash",
  "created_at",
  "graph_hash",
  "graph_json",
  "id",
  "updated_at",
  "version"
]

exec
/bin/bash -lc "jq '.analysis_artifact.artifact_json | keys' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
[
  "auth",
  "basic_blocks",
  "callsites",
  "cfg_edges",
  "cfg_hash",
  "dispatcher_type",
  "function_entries",
  "functions",
  "selectors",
  "sinks",
  "storage",
  "version"
]

exec
/bin/bash -lc "jq '.capability_graph.graph_json | keys' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
[
  "edges",
  "nodes",
  "version"
]

exec
/bin/bash -lc "jq '.analysis_run | keys' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
[
  "address",
  "block_number",
  "chain_id",
  "child_links",
  "created_at",
  "id",
  "parent_links",
  "status",
  "updated_at"
]

exec
/bin/bash -lc "printf '%s\\n' '--- selectors ---' && jq '.analysis_artifact.artifact_json.selectors' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- selectors ---
[
  "0x1aa3a008",
  "0x437600bc",
  "0x444bdb1b",
  "0x6d4ce63c",
  "0x71ad7221",
  "0x854ba99d",
  "0xa32da9d1"
]

exec
/bin/bash -lc "printf '%s\\n' '--- function entries ---' && jq '.analysis_artifact.artifact_json.function_entries' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- function entries ---
[
  {
    "entry_pc": null,
    "selector": "0x1aa3a008"
  },
  {
    "entry_pc": 1145821979,
    "selector": "0x437600bc"
  },
  {
    "entry_pc": 1833756220,
    "selector": "0x444bdb1b"
  },
  {
    "entry_pc": 1907192353,
    "selector": "0x6d4ce63c"
  },
  {
    "entry_pc": 2236328349,
    "selector": "0x71ad7221"
  },
  {
    "entry_pc": 2737678801,
    "selector": "0x854ba99d"
  },
  {
    "entry_pc": null,
    "selector": "0xa32da9d1"
  }
]

exec
/bin/bash -lc "printf '%s\\n' '--- sinks ---' && jq '.analysis_artifact.artifact_json.sinks' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- sinks ---
{
  "call": 1,
  "create": 0,
  "create2": 0,
  "delegatecall": 0,
  "selfdestruct": 0,
  "staticcall": 0,
  "upgrade_slot_write_suspected": false
}

exec
/bin/bash -lc "printf '%s\\n' '--- auth ---' && jq '.analysis_artifact.artifact_json.auth' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- auth ---
{
  "guards": []
}

exec
/bin/bash -lc "printf '%s\\n' '--- storage ---' && jq '.analysis_artifact.artifact_json.storage' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- storage ---
{
  "keccak_count": 5,
  "reads": 9,
  "slots": [
    {
      "op": "SLOAD",
      "pc": 327,
      "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
    },
    {
      "op": "SSTORE",
      "pc": 444,
      "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
    },
    {
      "op": "SLOAD",
      "pc": 448,
      "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
    },
    {
      "op": "SLOAD",
      "pc": 495,
      "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
    }
  ],
  "writes": 3
}

exec
/bin/bash -lc "printf '%s\\n' '--- callsites ---' && jq '.analysis_artifact.artifact_json.callsites' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- callsites ---
[
  {
    "opcode": "CALL",
    "pc": 257,
    "returndata_checked": null,
    "target_expression_category": "computed",
    "value_expression_category": "computed"
  }
]

exec
/bin/bash -lc "printf '%s\\n' '--- functions ---' && jq '.analysis_artifact.artifact_json.functions' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- functions ---
[
  {
    "auth": {
      "guards": []
    },
    "entry_pc": null,
    "selector": "0x1aa3a008",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": 1145821979,
    "selector": "0x437600bc",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": 1833756220,
    "selector": "0x444bdb1b",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": 1907192353,
    "selector": "0x6d4ce63c",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": 2236328349,
    "selector": "0x71ad7221",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": 2737678801,
    "selector": "0x854ba99d",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  },
  {
    "auth": {
      "guards": []
    },
    "entry_pc": null,
    "selector": "0xa32da9d1",
    "sinks": {
      "call": 1,
      "delegatecall": 0,
      "selfdestruct": 0,
      "staticcall": 0
    },
    "storage": {
      "reads": 9,
      "slots": [
        {
          "op": "SLOAD",
          "pc": 327,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SSTORE",
          "pc": 444,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
        },
        {
          "op": "SLOAD",
          "pc": 448,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        },
        {
          "op": "SLOAD",
          "pc": 495,
          "slot": "0x0000000000000000000000000000000000000000000000000000000000000005"
        }
      ],
      "writes": 3
    }
  }
]

exec
/bin/bash -lc "printf '%s\\n' '--- basic blocks sample ---' && jq '.analysis_artifact.artifact_json.basic_blocks[:20]' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
--- basic blocks sample ---
[
  {
    "end_pc": 10,
    "hash": "0xf9379be67bf0d681af837933f0f4af1f87650997fa5ffba869eb61e5b6669abc",
    "opcodes": [
      "PUSH1",
      "PUSH1",
      "MSTORE",
      "CALLDATASIZE",
      "ISZERO",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 0
  },
  {
    "end_pc": 30,
    "hash": "0x22a5085fba77c6777c88cdd6a31289d1a430c87347632add96f32302d9d0e82e",
    "opcodes": [
      "PUSH1",
      "PUSH1",
      "EXP",
      "PUSH1",
      "CALLDATALOAD",
      "DIV",
      "PUSH4",
      "OP_81",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 11
  },
  {
    "end_pc": 41,
    "hash": "0xe7af49f8c15632229ba6c899c130610351d31e8429c33737b9692da0e67f3db9",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 31
  },
  {
    "end_pc": 52,
    "hash": "0xfd77ef5ad46455e5156f11b867f3d83d5ff2afe00f8f6ba016c972354dbeffc7",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 42
  },
  {
    "end_pc": 63,
    "hash": "0xb834ece24abfef89975071d1ec860c4344bc5b2876de313201268a25a18d8bee",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 53
  },
  {
    "end_pc": 74,
    "hash": "0xc144cdf722782881e18490e6865f7097ecc419d3b1e1f93012cd0fd5fdbffaee",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 64
  },
  {
    "end_pc": 85,
    "hash": "0x8914d9b6413c0749e109061495b581e717132ea4098d304738329365a123e0f1",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 75
  },
  {
    "end_pc": 96,
    "hash": "0xff500bd5e47312d4812c18df51e9c3e543b7aa72f581e8925322d699213f2d91",
    "opcodes": [
      "OP_80",
      "PUSH4",
      "EQ",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 86
  },
  {
    "end_pc": 98,
    "hash": "0x011d7733279593b193d892dad40bef80419b3811155f2f8f98f219cbc67bebd8",
    "opcodes": [
      "JUMPDEST",
      "STOP"
    ],
    "start_pc": 97
  },
  {
    "end_pc": 113,
    "hash": "0x496b6af778ef738a4f7ae51d4a35c5cd306d57a0da9b3d36f01d96ac3d52fcb9",
    "opcodes": [
      "JUMPDEST",
      "PUSH2",
      "PUSH1",
      "CALLVALUE",
      "PUSH1",
      "EQ",
      "ISZERO",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 99
  },
  {
    "end_pc": 120,
    "hash": "0x4781b821eeb30c4b16b8d969e97d5f072ba846d655e5ddba1e66f405664d5ea4",
    "opcodes": [
      "PUSH2",
      "PUSH2",
      "JUMP"
    ],
    "start_pc": 114
  },
  {
    "end_pc": 144,
    "hash": "0x72fabb46d22f252f6a4d38ab9cd1e29fff5b36c9f77ddb5e1d40ecd5a257df77",
    "opcodes": [
      "JUMPDEST",
      "PUSH2",
      "PUSH1",
      "CALLDATALOAD",
      "PUSH1",
      "PUSH1",
      "MSTORE",
      "PUSH1",
      "OP_90",
      "OP_81",
      "MSTORE",
      "PUSH1",
      "OP_90",
      "SHA3",
      "SLOAD",
      "OP_81",
      "JUMP"
    ],
    "start_pc": 121
  },
  {
    "end_pc": 149,
    "hash": "0x2ec530fb3cc8f13bcb2ced3df6fce262c99ee0763d1e7145b19ed31b0cb3aa92",
    "opcodes": [
      "JUMPDEST",
      "PUSH2",
      "PUSH1"
    ],
    "start_pc": 145
  },
  {
    "end_pc": 153,
    "hash": "0x05bf8168a90c40d5fb99b3b5c83425c57253e2ea7316cb92405a8d589dcb19fd",
    "opcodes": [
      "JUMPDEST",
      "OP_90",
      "JUMP"
    ],
    "start_pc": 151
  },
  {
    "end_pc": 186,
    "hash": "0xae3732a4d45d8bffbc048f75903662c2a489ab2faa8548790b29f37066da61ff",
    "opcodes": [
      "JUMPDEST",
      "PUSH2",
      "CALLER",
      "PUSH1",
      "PUSH1",
      "PUSH1",
      "EXP",
      "SUB",
      "AND",
      "PUSH1",
      "OP_90",
      "OP_81",
      "MSTORE",
      "PUSH1",
      "PUSH1",
      "MSTORE",
      "PUSH1",
      "OP_90",
      "SHA3",
      "SLOAD",
      "PUSH2",
      "JUMP"
    ],
    "start_pc": 154
  },
  {
    "end_pc": 214,
    "hash": "0xe9aaacff27b0312e7ec6d1efbc009bde3a332fb998a3374e6874a024faa3ab39",
    "opcodes": [
      "JUMPDEST",
      "PUSH1",
      "PUSH1",
      "PUSH1",
      "EXP",
      "SUB",
      "PUSH1",
      "CALLDATALOAD",
      "AND",
      "PUSH1",
      "OP_90",
      "OP_81",
      "MSTORE",
      "PUSH1",
      "PUSH1",
      "MSTORE",
      "PUSH1",
      "OP_90",
      "SHA3",
      "SLOAD"
    ],
    "start_pc": 187
  },
  {
    "end_pc": 232,
    "hash": "0x63e1f4336bc01bed5479e47cf297cb7ac7987c4c130b8d0c954b23facac4d6bb",
    "opcodes": [
      "JUMPDEST",
      "PUSH1",
      "OP_80",
      "MLOAD",
      "OP_91",
      "OP_82",
      "MSTORE",
      "MLOAD",
      "OP_90",
      "OP_81",
      "OP_90",
      "SUB",
      "PUSH1",
      "ADD",
      "OP_90",
      "RETURN"
    ],
    "start_pc": 215
  },
  {
    "end_pc": 234,
    "hash": "0xcf57c3a2043c4cfc69223097b0e774cf4544549a8bd7b7db8f4d705dd886910c",
    "opcodes": [
      "JUMPDEST",
      "PUSH2"
    ],
    "start_pc": 233
  },
  {
    "end_pc": 261,
    "hash": "0x26d1d17b784d378115903b90fdc2772f27d88c389eae5d66fb7cf5938f4c91d7",
    "opcodes": [
      "JUMPDEST",
      "PUSH1",
      "MLOAD",
      "PUSH2",
      "OP_90",
      "PUSH1",
      "OP_81",
      "OP_81",
      "OP_81",
      "OP_81",
      "OP_86",
      "PUSH2",
      "GAS",
      "SUB",
      "CALL",
      "POP",
      "POP",
      "POP",
      "JUMP"
    ],
    "start_pc": 237
  },
  {
    "end_pc": 280,
    "hash": "0xde9b91855cb5019cc56488b74c65e9e69ef058c5f9ce17fc53d7b96fd5caeebe",
    "opcodes": [
      "JUMPDEST",
      "PUSH2",
      "PUSH1",
      "CALLDATALOAD",
      "PUSH1",
      "OP_81",
      "PUSH1",
      "OP_81",
      "LT",
      "ISZERO",
      "PUSH2",
      "JUMPI"
    ],
    "start_pc": 262
  }
]

exec
/bin/bash -lc "jq '.artifact | keys' BYTECODE_BUNDLE.json && printf '\\n--- artifact preview ---\\n' && jq '.artifact' BYTECODE_BUNDLE.json | sed -n '1,120p'" in /tmp/codex-vyere7o6
 succeeded in 0ms:
[
  "codehash",
  "compiler_json",
  "implementation_address",
  "is_proxy",
  "runtime_bytecode",
  "verified_source"
]

--- artifact preview ---
{
  "codehash": "0x905dacc611c32b7c7f3aba69baf2519791520fb84422576aac281114686ea761",
  "compiler_json": {
    "etherscan": {
      "skipped": true
    }
  },
  "implementation_address": null,
  "is_proxy": false,
  "runtime_bytecode": {
    "full": "0x606060405236156100615760e060020a60003504631aa3a0088114610063578063437600bc14610079578063444bdb1b146100915780636d4ce63c1461009a57806371ad7221146100bb578063854ba99d146100e9578063a32da9d114610106575b005b61006160003460001415610144576101446100ed565b6100d760043560066020526000908152604090205481565b6100d760645b90565b6100d733600160a060020a0316600090815260066020526040902054610097565b600160a060020a03600435166000908152600660205260409020545b60408051918252519081900360200190f35b6100615b60405161019490600081818181866161da5a03f1505050565b610127600435600081600581101561000257505054600160a060020a031681565b60408051600160a060020a03929092168252519081900360200190f35b6005546004901115610158576101586100ed565b33600160a060020a0316600090815260066020526040812054111561017f5761017f6100ed565b5060003460050230600160a060020a031631101561019f5761019f6100ed565b6040600090812033600160a060020a0381168352600660205234909155600580549192919081101561000257805473ffffffffffffffffffffffffffffffffffffffff1916909217909155506005805460010190555056",
    "head": null,
    "length": 1008,
    "tail": null,
    "truncated": false
  },
  "verified_source": false
}

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const opnames = {};
for (let i=0;i<256;i++) opnames[i] = 'OP_'+i.toString(16).padStart(2,'0');
Object.assign(opnames, {
0x00:'STOP',0x01:'ADD',0x02:'MUL',0x03:'SUB',0x04:'DIV',0x05:'SDIV',0x06:'MOD',0x07:'SMOD',0x08:'ADDMOD',0x09:'MULMOD',0x0a:'EXP',0x0b:'SIGNEXTEND',
0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',0x1a:'BYTE',0x1b:'SHL',0x1c:'SHR',0x1d:'SAR',
0x20:'SHA3',0x30:'ADDRESS',0x31:'BALANCE',0x32:'ORIGIN',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x36:'CALLDATASIZE',0x37:'CALLDATACOPY',0x38:'CODESIZE',0x39:'CODECOPY',0x3a:'GASPRICE',0x3b:'EXTCODESIZE',0x3c:'EXTCODECOPY',0x3d:'RETURNDATASIZE',0x3e:'RETURNDATACOPY',0x3f:'EXTCODEHASH',
0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',0x46:'CHAINID',0x47:'SELFBALANCE',0x48:'BASEFEE',
0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x53:'MSTORE8',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x58:'PC',0x59:'MSIZE',0x5a:'GAS',0x5b:'JUMPDEST',
0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
});
for (let i=0x60;i<=0x7f;i++) opnames[i] = 'PUSH'+(i-0x5f);
for (let i=0x80;i<=0x8f;i++) opnames[i] = 'DUP'+(i-0x7f);
for (let i=0x90;i<=0x9f;i++) opnames[i] = 'SWAP'+(i-0x8f);
for (let i=0xa0;i<=0xa4;i++) opnames[i] = 'LOG'+(i-0x9f);
let pc=0;
while (pc < hex.length/2) {
  const op = parseInt(hex.slice(pc*2,pc*2+2),16);
  const name = opnames[op];
  let out = pc.toString(16).padStart(4,'0')+': '+name;
  pc++;
  if (op>=0x60 && op<=0x7f) {
    const n = op-0x5f;
    const data = hex.slice(pc*2, pc*2+n*2);
    out += ' 0x'+data;
    pc += n;
  }
  console.log(out);
}
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
0000: PUSH1 0x60
0002: PUSH1 0x40
0004: MSTORE
0005: CALLDATASIZE
0006: ISZERO
0007: PUSH2 0x0061
000a: JUMPI
000b: PUSH1 0xe0
000d: PUSH1 0x02
000f: EXP
0010: PUSH1 0x00
0012: CALLDATALOAD
0013: DIV
0014: PUSH4 0x1aa3a008
0019: DUP2
001a: EQ
001b: PUSH2 0x0063
001e: JUMPI
001f: DUP1
0020: PUSH4 0x437600bc
0025: EQ
0026: PUSH2 0x0079
0029: JUMPI
002a: DUP1
002b: PUSH4 0x444bdb1b
0030: EQ
0031: PUSH2 0x0091
0034: JUMPI
0035: DUP1
0036: PUSH4 0x6d4ce63c
003b: EQ
003c: PUSH2 0x009a
003f: JUMPI
0040: DUP1
0041: PUSH4 0x71ad7221
0046: EQ
0047: PUSH2 0x00bb
004a: JUMPI
004b: DUP1
004c: PUSH4 0x854ba99d
0051: EQ
0052: PUSH2 0x00e9
0055: JUMPI
0056: DUP1
0057: PUSH4 0xa32da9d1
005c: EQ
005d: PUSH2 0x0106
0060: JUMPI
0061: JUMPDEST
0062: STOP
0063: JUMPDEST
0064: PUSH2 0x0061
0067: PUSH1 0x00
0069: CALLVALUE
006a: PUSH1 0x00
006c: EQ
006d: ISZERO
006e: PUSH2 0x0144
0071: JUMPI
0072: PUSH2 0x0144
0075: PUSH2 0x00ed
0078: JUMP
0079: JUMPDEST
007a: PUSH2 0x00d7
007d: PUSH1 0x04
007f: CALLDATALOAD
0080: PUSH1 0x06
0082: PUSH1 0x20
0084: MSTORE
0085: PUSH1 0x00
0087: SWAP1
0088: DUP2
0089: MSTORE
008a: PUSH1 0x40
008c: SWAP1
008d: SHA3
008e: SLOAD
008f: DUP2
0090: JUMP
0091: JUMPDEST
0092: PUSH2 0x00d7
0095: PUSH1 0x64
0097: JUMPDEST
0098: SWAP1
0099: JUMP
009a: JUMPDEST
009b: PUSH2 0x00d7
009e: CALLER
009f: PUSH1 0x01
00a1: PUSH1 0xa0
00a3: PUSH1 0x02
00a5: EXP
00a6: SUB
00a7: AND
00a8: PUSH1 0x00
00aa: SWAP1
00ab: DUP2
00ac: MSTORE
00ad: PUSH1 0x06
00af: PUSH1 0x20
00b1: MSTORE
00b2: PUSH1 0x40
00b4: SWAP1
00b5: SHA3
00b6: SLOAD
00b7: PUSH2 0x0097
00ba: JUMP
00bb: JUMPDEST
00bc: PUSH1 0x01
00be: PUSH1 0xa0
00c0: PUSH1 0x02
00c2: EXP
00c3: SUB
00c4: PUSH1 0x04
00c6: CALLDATALOAD
00c7: AND
00c8: PUSH1 0x00
00ca: SWAP1
00cb: DUP2
00cc: MSTORE
00cd: PUSH1 0x06
00cf: PUSH1 0x20
00d1: MSTORE
00d2: PUSH1 0x40
00d4: SWAP1
00d5: SHA3
00d6: SLOAD
00d7: JUMPDEST
00d8: PUSH1 0x40
00da: DUP1
00db: MLOAD
00dc: SWAP2
00dd: DUP3
00de: MSTORE
00df: MLOAD
00e0: SWAP1
00e1: DUP2
00e2: SWAP1
00e3: SUB
00e4: PUSH1 0x20
00e6: ADD
00e7: SWAP1
00e8: RETURN
00e9: JUMPDEST
00ea: PUSH2 0x0061
00ed: JUMPDEST
00ee: PUSH1 0x40
00f0: MLOAD
00f1: PUSH2 0x0194
00f4: SWAP1
00f5: PUSH1 0x00
00f7: DUP2
00f8: DUP2
00f9: DUP2
00fa: DUP2
00fb: DUP7
00fc: PUSH2 0x61da
00ff: GAS
0100: SUB
0101: CALL
0102: POP
0103: POP
0104: POP
0105: JUMP
0106: JUMPDEST
0107: PUSH2 0x0127
010a: PUSH1 0x04
010c: CALLDATALOAD
010d: PUSH1 0x00
010f: DUP2
0110: PUSH1 0x05
0112: DUP2
0113: LT
0114: ISZERO
0115: PUSH2 0x0002
0118: JUMPI
0119: POP
011a: POP
011b: SLOAD
011c: PUSH1 0x01
011e: PUSH1 0xa0
0120: PUSH1 0x02
0122: EXP
0123: SUB
0124: AND
0125: DUP2
0126: JUMP
0127: JUMPDEST
0128: PUSH1 0x40
012a: DUP1
012b: MLOAD
012c: PUSH1 0x01
012e: PUSH1 0xa0
0130: PUSH1 0x02
0132: EXP
0133: SUB
0134: SWAP3
0135: SWAP1
0136: SWAP3
0137: AND
0138: DUP3
0139: MSTORE
013a: MLOAD
013b: SWAP1
013c: DUP2
013d: SWAP1
013e: SUB
013f: PUSH1 0x20
0141: ADD
0142: SWAP1
0143: RETURN
0144: JUMPDEST
0145: PUSH1 0x05
0147: SLOAD
0148: PUSH1 0x04
014a: SWAP1
014b: GT
014c: ISZERO
014d: PUSH2 0x0158
0150: JUMPI
0151: PUSH2 0x0158
0154: PUSH2 0x00ed
0157: JUMP
0158: JUMPDEST
0159: CALLER
015a: PUSH1 0x01
015c: PUSH1 0xa0
015e: PUSH1 0x02
0160: EXP
0161: SUB
0162: AND
0163: PUSH1 0x00
0165: SWAP1
0166: DUP2
0167: MSTORE
0168: PUSH1 0x06
016a: PUSH1 0x20
016c: MSTORE
016d: PUSH1 0x40
016f: DUP2
0170: SHA3
0171: SLOAD
0172: GT
0173: ISZERO
0174: PUSH2 0x017f
0177: JUMPI
0178: PUSH2 0x017f
017b: PUSH2 0x00ed
017e: JUMP
017f: JUMPDEST
0180: POP
0181: PUSH1 0x00
0183: CALLVALUE
0184: PUSH1 0x05
0186: MUL
0187: ADDRESS
0188: PUSH1 0x01
018a: PUSH1 0xa0
018c: PUSH1 0x02
018e: EXP
018f: SUB
0190: AND
0191: BALANCE
0192: LT
0193: ISZERO
0194: PUSH2 0x019f
0197: JUMPI
0198: PUSH2 0x019f
019b: PUSH2 0x00ed
019e: JUMP
019f: JUMPDEST
01a0: PUSH1 0x40
01a2: PUSH1 0x00
01a4: SWAP1
01a5: DUP2
01a6: SHA3
01a7: CALLER
01a8: PUSH1 0x01
01aa: PUSH1 0xa0
01ac: PUSH1 0x02
01ae: EXP
01af: SUB
01b0: DUP2
01b1: AND
01b2: DUP4
01b3: MSTORE
01b4: PUSH1 0x06
01b6: PUSH1 0x20
01b8: MSTORE
01b9: CALLVALUE
01ba: SWAP1
01bb: SWAP2
01bc: SSTORE
01bd: PUSH1 0x05
01bf: DUP1
01c0: SLOAD
01c1: SWAP2
01c2: SWAP3
01c3: SWAP2
01c4: SWAP1
01c5: DUP2
01c6: LT
01c7: ISZERO
01c8: PUSH2 0x0002
01cb: JUMPI
01cc: DUP1
01cd: SLOAD
01ce: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
01e3: NOT
01e4: AND
01e5: SWAP1
01e6: SWAP3
01e7: OR
01e8: SWAP1
01e9: SWAP2
01ea: SSTORE
01eb: POP
01ec: PUSH1 0x05
01ee: DUP1
01ef: SLOAD
01f0: PUSH1 0x01
01f2: ADD
01f3: SWAP1
01f4: SSTORE
01f5: POP
01f6: JUMP

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[];
let pc=0;
while(pc<hex.length/2){
  const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null;
  if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} 
  dis.push({pc,op,arg}); pc+=1+n;
}
const map=new Map(dis.map(x=>[x.pc,x]));
function run(start, initial){
  let stack=initial.slice();
  let cur=start;
  for(let steps=0;steps<80;steps++){
    const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); break;}
    const s=()=>JSON.stringify(stack);
    console.log(cur.toString(16).padStart(4,'0'), ins.op.toString(16), ins.arg||'', 'stack', s());
    const op=ins.op;
    const pop=()=>stack.pop();
    const push=v=>stack.push(v);
    if(op>=0x60&&op<=0x7f){push(ins.arg); cur+=1+(op-0x5f); continue;}
    if(op>=0x80&&op<=0x8f){const idx=op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
    if(op>=0x90&&op<=0x9f){const idx=op-0x8f; const a=stack.length-1; const b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
    switch(op){
      case 0x50: pop(); break;
      case 0x51: push("'`m[${pop()}]`); break;
      case 0x52: {const off=pop(), val=pop(); break;}
      case 0x54: push(`s[${pop()}]`); break;
      case 0x55: {const off=pop(), val=pop(); break;}
      case 0x5a: push('"'gas'); break;
      case 0x01: {const b=pop(), a=pop(); push("'`(${a}+${b})`); break;}
      case 0x03: {const b=pop(), a=pop(); push(`(${a}-${b})`); break;}
      case 0x0a: {const b=pop(), a=pop(); push(`exp(${a},${b})`); break;}
      case 0x14: {const b=pop(), a=pop(); push(`(${a}==${b})`); break;}
      case 0x15: {const a=pop(); push(`iszero(${a})`); break;}
      case 0x16: {const b=pop(), a=pop(); push(`(${a}&${b})`); break;}
      case 0x20: {const b=pop(), a=pop(); push(`keccak(${a},${b})`); break;}
      case 0x31: {const a=pop(); push(`balance(${a})`); break;}
      case 0x33: push('"'caller'); break;
      case 0x34: push('callvalue'); break;
      case 0x35: {const a=pop(); push("'`calldata[${a}]`); break;}
      case 0x56: console.log('"'JUMP to', pop()); return stack;
      case 0x57: {const dst=pop(), cond=pop(); console.log('JUMPI',dst,cond); return stack;}
      case 0xf1: {
        const gasv=pop(), to=pop(), value=pop(), inOff=pop(), inSize=pop(), outOff=pop(), outSize=pop();
        console.log('CALL args',{gas:gasv,to,value,inOff,inSize,outOff,outSize},'remaining',stack);
        push('callret');
        break;
      }
      default: console.log('stop unsupported',op.toString(16)); return stack;
    }
    cur++;
  }
}
console.log('path 0xe9');
run(0xe9,[]);
console.log('path 0xed with initial [0x61]');
run(0xed,['ret']);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
path 0xe9
00e9 5b  stack []
stop unsupported 5b
path 0xed with initial [0x61]
00ed 5b  stack ["ret"]
stop unsupported 5b

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[];
let pc=0;
while(pc<hex.length/2){
  const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null;
  if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} 
  dis.push({pc,op,arg}); pc+=1+n;
}
const map=new Map(dis.map(x=>[x.pc,x]));
function run(start, initial){
  let stack=initial.slice();
  let cur=start;
  for(let steps=0;steps<80;steps++){
    const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); break;}
    console.log(cur.toString(16).padStart(4,'0'), (ins.arg?ins.arg:''), 'stack', JSON.stringify(stack));
    const op=ins.op;
    const pop=()=>stack.pop();
    const push=v=>stack.push(v);
    if(op===0x5b){cur++; continue;}
    if(op>=0x60&&op<=0x7f){push(ins.arg); cur+=1+(op-0x5f); continue;}
    if(op>=0x80&&op<=0x8f){const idx=op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
    if(op>=0x90&&op<=0x9f){const idx=op-0x8f; const a=stack.length-1; const b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
    switch(op){
      case 0x50: pop(); break;
      case 0x51: push("'`m[${pop()}]`); break;
      case 0x52: {const off=pop(), val=pop(); break;}
      case 0x54: push(`s[${pop()}]`); break;
      case 0x55: {const off=pop(), val=pop(); break;}
      case 0x5a: push('"'gas'); break;
      case 0x01: {const b=pop(), a=pop(); push("'`(${a}+${b})`); break;}
      case 0x03: {const b=pop(), a=pop(); push(`(${a}-${b})`); break;}
      case 0x0a: {const b=pop(), a=pop(); push(`exp(${a},${b})`); break;}
      case 0x10: {const b=pop(), a=pop(); push(`(${a}<${b})`); break;}
      case 0x11: {const b=pop(), a=pop(); push(`(${a}>${b})`); break;}
      case 0x14: {const b=pop(), a=pop(); push(`(${a}==${b})`); break;}
      case 0x15: {const a=pop(); push(`iszero(${a})`); break;}
      case 0x16: {const b=pop(), a=pop(); push(`(${a}&${b})`); break;}
      case 0x20: {const b=pop(), a=pop(); push(`keccak(${a},${b})`); break;}
      case 0x31: {const a=pop(); push(`balance(${a})`); break;}
      case 0x33: push('"'caller'); break;
      case 0x34: push('callvalue'); break;
      case 0x35: {const a=pop(); push("'`calldata[${a}]`); break;}
      case 0x56: console.log('"'JUMP to', pop(),'remaining',stack); return stack;
      case 0x57: {const dst=pop(), cond=pop(); console.log('JUMPI dst',dst,'cond',cond,'remaining',stack); return stack;}
      case 0xf1: {
        const gasv=pop(), to=pop(), value=pop(), inOff=pop(), inSize=pop(), outOff=pop(), outSize=pop();
        console.log('CALL args',{gas:gasv,to,value,inOff,inSize,outOff,outSize},'remaining',stack);
        push('callret');
        break;
      }
      default: console.log('stop unsupported opcode',op.toString(16),'remaining',stack); return stack;
    }
    cur++;
  }
}
console.log('trace from 0xe9');
run(0xe9,[]);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
trace from 0xe9
00e9  stack []
00ea 0x0061 stack []
00ed  stack ["0x0061"]
00ee 0x40 stack ["0x0061"]
00f0  stack ["0x0061","0x40"]
00f1 0x0194 stack ["0x0061","m[0x40]"]
00f4  stack ["0x0061","m[0x40]","0x0194"]
00f5 0x00 stack ["0x0061","0x0194","m[0x40]"]
00f7  stack ["0x0061","0x0194","m[0x40]","0x00"]
00f8  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]"]
00f9  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00"]
00fa  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]"]
00fb  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]","0x00"]
00fc 0x61da stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]","0x00","0x0194"]
00ff  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]","0x00","0x0194","0x61da"]
0100  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]","0x00","0x0194","0x61da","gas"]
0101  stack ["0x0061","0x0194","m[0x40]","0x00","m[0x40]","0x00","m[0x40]","0x00","0x0194","(0x61da-gas)"]
CALL args {
  gas: '(0x61da-gas)',
  to: '0x0194',
  value: '0x00',
  inOff: 'm[0x40]',
  inSize: '0x00',
  outOff: 'm[0x40]',
  outSize: '0x00'
} remaining [ '0x0061', '0x0194', 'm[0x40]' ]
0102  stack ["0x0061","0x0194","m[0x40]","callret"]
0103  stack ["0x0061","0x0194","m[0x40]"]
0104  stack ["0x0061","0x0194"]
0105  stack ["0x0061"]
JUMP to 0x0061 remaining []

exec
/bin/bash -lc "jq '{chain_id: .artifact.chain_id // .analysis_artifact.chain_id // .analysis_run.chain_id, address: .analysis_artifact.address, block: .analysis_artifact.block_number}' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 exited 3 in 0ms:
jq: error: syntax error, unexpected //, expecting '}' (Unix shell quoting issues?) at <top-level>, line 1:
{chain_id: .artifact.chain_id // .analysis_artifact.chain_id // .analysis_run.chain_id, address: .analysis_artifact.address, block: .analysis_artifact.block_number}                              
jq: 1 compile error

exec
/bin/bash -lc "jq '{chain_id: (.analysis_artifact.chain_id // .analysis_run.chain_id), address: .analysis_artifact.address, block: .analysis_artifact.block_number}' BYTECODE_BUNDLE.json" in /tmp/codex-vyere7o6
 succeeded in 0ms:
{
  "chain_id": 1,
  "address": "0x8226891a383dc93da036274431aa9e00b47104d0",
  "block": null
}

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[];
let pc=0;
while(pc<hex.length/2){
  const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null;
  if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} 
  dis.push({pc,op,arg}); pc+=1+n;
}
const map=new Map(dis.map(x=>[x.pc,x]));
const names={0x00:'STOP',0x01:'ADD',0x03:'SUB',0x0a:'EXP',0x10:'LT',0x11:'GT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x20:'SHA3',0x31:'BALANCE',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x5a:'GAS',0x5b:'JUMPDEST',0xf1:'CALL'};
for(let i=0x60;i<=0x7f;i++) names[i]='PUSH'+(i-0x5f);
for(let i=0x80;i<=0x8f;i++) names[i]='DUP'+(i-0x7f);
for(let i=0x90;i<=0x9f;i++) names[i]='SWAP'+(i-0x8f);
for(let i=0xa0;i<=0xa4;i++) names[i]='LOG'+(i-0x9f);
function show(stack){return '['+stack.join(', ')+']'}
function run(start, initial=[]){
 let stack=initial.slice();
 let cur=start;
 for(let steps=0;steps<120;steps++){
  const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); return;}
  const nm=names[ins.op]||('OP_'+ins.op.toString(16));
  console.log(cur.toString(16).padStart(4,'0'), nm, ins.arg||'', show(stack));
  const pop=()=>stack.pop(); const push=v=>stack.push(v);
  const bin=(sym)=>{const a=pop(), b=pop(); push("'`(${b}${sym}${a})`)};
  if(ins.op===0x5b){cur++; continue;}
  if(ins.op>=0x60&&ins.op<=0x7f){push(ins.arg); cur+=1+(ins.op-0x5f); continue;}
  if(ins.op>=0x80&&ins.op<=0x8f){const idx=ins.op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
  if(ins.op>=0x90&&ins.op<=0x9f){const idx=ins.op-0x8f; const a=stack.length-1, b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
  switch(ins.op){
   case 0x00: return;
   case 0x01: bin('"'+'); break;
   case 0x02: bin('*'); break;
   case 0x03: bin('-'); break;
   case 0x0a: {const a=pop(), b=pop(); push("'`exp(${b},${a})`); break;}
   case 0x10: bin('"'<'); break;
   case 0x11: bin('>'); break;
   case 0x14: bin('=='); break;
   case 0x15: push("'`iszero(${pop()})`); break;
   case 0x16: bin('"'&'); break;
   case 0x20: {const a=pop(), b=pop(); push("'`keccak(${b},${a})`); break;}
   case 0x31: push(`balance(${pop()})`); break;
   case 0x33: push('"'caller'); break;
   case 0x34: push('callvalue'); break;
   case 0x35: push("'`calldata[${pop()}]`); break;
   case 0x50: pop(); break;
   case 0x51: push(`m[${pop()}]`); break;
   case 0x52: {const a=pop(),b=pop(); console.log('"'  MSTORE',a,'=',b); break;}
   case 0x54: push("'`s[${pop()}]`); break;
   case 0x55: {const a=pop(),b=pop(); console.log('"'  SSTORE',a,'=',b); break;}
   case 0x56: console.log('  JUMP',pop(),'remain',show(stack)); return;
   case 0x57: {const dest=pop(), cond=pop(); console.log('  JUMPI dest',dest,'cond',cond,'remain',show(stack)); return;}
   case 0xf1: {const gas=pop(),to=pop(),value=pop(),inOff=pop(),inSize=pop(),outOff=pop(),outSize=pop(); console.log('  CALL',{gas,to,value,inOff,inSize,outOff,outSize},'remain',show(stack)); push('callret'); break;}
   default: console.log('stop unsupported',nm); return;
  }
  cur++;
 }
}
run(0x144,[]);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
0144 JUMPDEST  []
0145 PUSH1 0x05 []
0147 SLOAD  [0x05]
0148 PUSH1 0x04 [s[0x05]]
014a SWAP1  [s[0x05], 0x04]
014b GT  [0x04, s[0x05]]
014c ISZERO  [(0x04>s[0x05])]
014d PUSH2 0x0158 [iszero((0x04>s[0x05]))]
0150 JUMPI  [iszero((0x04>s[0x05])), 0x0158]
  JUMPI dest 0x0158 cond iszero((0x04>s[0x05])) remain []

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[]; let pc=0;
while(pc<hex.length/2){ const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null; if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} dis.push({pc,op,arg}); pc+=1+n; }
const map=new Map(dis.map(x=>[x.pc,x]));
const names={0x00:'STOP',0x01:'ADD',0x02:'MUL',0x03:'SUB',0x0a:'EXP',0x10:'LT',0x11:'GT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x20:'SHA3',0x31:'BALANCE',0x30:'ADDRESS',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x5a:'GAS',0x5b:'JUMPDEST',0x19:'NOT',0xf1:'CALL'};
for(let i=0x60;i<=0x7f;i++) names[i]='PUSH'+(i-0x5f);
for(let i=0x80;i<=0x8f;i++) names[i]='DUP'+(i-0x7f);
for(let i=0x90;i<=0x9f;i++) names[i]='SWAP'+(i-0x8f);
function show(stack){return '['+stack.join(', ')+']'}
function run(start, initial=[]){
 let stack=initial.slice(); let cur=start;
 for(let steps=0;steps<220;steps++){
  const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); return;}
  const nm=names[ins.op]||('OP_'+ins.op.toString(16));
  console.log(cur.toString(16).padStart(4,'0'), nm, ins.arg||'', show(stack));
  const pop=()=>stack.pop(); const push=v=>stack.push(v);
  const bin=(sym)=>{const a=pop(), b=pop(); push("'`(${b}${sym}${a})`)};
  if(ins.op===0x5b){cur++; continue;}
  if(ins.op>=0x60&&ins.op<=0x7f){push(ins.arg); cur+=1+(ins.op-0x5f); continue;}
  if(ins.op>=0x80&&ins.op<=0x8f){const idx=ins.op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
  if(ins.op>=0x90&&ins.op<=0x9f){const idx=ins.op-0x8f; const a=stack.length-1, b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
  switch(ins.op){
   case 0x00: return;
   case 0x01: bin('"'+'); break;
   case 0x02: bin('*'); break;
   case 0x03: bin('-'); break;
   case 0x0a: {const a=pop(), b=pop(); push("'`exp(${b},${a})`); break;}
   case 0x10: bin('"'<'); break;
   case 0x11: bin('>'); break;
   case 0x14: bin('=='); break;
   case 0x15: push("'`iszero(${pop()})`); break;
   case 0x16: bin('"'&'); break;
   case 0x19: push("'`~${pop()}`); break;
   case 0x20: {const a=pop(), b=pop(); push(`keccak(${b},${a})`); break;}
   case 0x30: push('"'address(this)'); break;
   case 0x31: push("'`balance(${pop()})`); break;
   case 0x33: push('"'caller'); break;
   case 0x34: push('callvalue'); break;
   case 0x35: push("'`calldata[${pop()}]`); break;
   case 0x50: pop(); break;
   case 0x51: push(`m[${pop()}]`); break;
   case 0x52: {const off=pop(), val=pop(); console.log('"'  MSTORE',off,'=',val); break;}
   case 0x54: push("'`s[${pop()}]`); break;
   case 0x55: {const off=pop(), val=pop(); console.log('"'  SSTORE',off,'=',val); break;}
   case 0x56: console.log('  JUMP',pop(),'remain',show(stack)); return;
   case 0x57: {const dest=pop(), cond=pop(); console.log('  JUMPI dest',dest,'cond',cond,'remain',show(stack)); return;}
   case 0xf1: {const gas=pop(),to=pop(),value=pop(),inOff=pop(),inSize=pop(),outOff=pop(),outSize=pop(); console.log('  CALL',{gas,to,value,inOff,inSize,outOff,outSize},'remain',show(stack)); push('callret'); break;}
   default: console.log('stop unsupported',nm); return;
  }
  cur++;
 }
}
run(0x158,[]);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
0158 JUMPDEST  []
0159 CALLER  []
015a PUSH1 0x01 [caller]
015c PUSH1 0xa0 [caller, 0x01]
015e PUSH1 0x02 [caller, 0x01, 0xa0]
0160 EXP  [caller, 0x01, 0xa0, 0x02]
0161 SUB  [caller, 0x01, exp(0xa0,0x02)]
0162 AND  [caller, (0x01-exp(0xa0,0x02))]
0163 PUSH1 0x00 [(caller&(0x01-exp(0xa0,0x02)))]
0165 SWAP1  [(caller&(0x01-exp(0xa0,0x02))), 0x00]
0166 DUP2  [0x00, (caller&(0x01-exp(0xa0,0x02)))]
0167 MSTORE  [0x00, (caller&(0x01-exp(0xa0,0x02))), 0x00]
  MSTORE 0x00 = (caller&(0x01-exp(0xa0,0x02)))
0168 PUSH1 0x06 [0x00]
016a PUSH1 0x20 [0x00, 0x06]
016c MSTORE  [0x00, 0x06, 0x20]
  MSTORE 0x20 = 0x06
016d PUSH1 0x40 [0x00]
016f DUP2  [0x00, 0x40]
0170 SHA3  [0x00, 0x40, 0x00]
0171 SLOAD  [0x00, keccak(0x40,0x00)]
0172 GT  [0x00, s[keccak(0x40,0x00)]]
0173 ISZERO  [(0x00>s[keccak(0x40,0x00)])]
0174 PUSH2 0x017f [iszero((0x00>s[keccak(0x40,0x00)]))]
0177 JUMPI  [iszero((0x00>s[keccak(0x40,0x00)])), 0x017f]
  JUMPI dest 0x017f cond iszero((0x00>s[keccak(0x40,0x00)])) remain []

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[]; let pc=0;
while(pc<hex.length/2){ const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null; if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} dis.push({pc,op,arg}); pc+=1+n; }
const map=new Map(dis.map(x=>[x.pc,x]));
const names={0x00:'STOP',0x01:'ADD',0x02:'MUL',0x03:'SUB',0x0a:'EXP',0x10:'LT',0x11:'GT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x19:'NOT',0x20:'SHA3',0x30:'ADDRESS',0x31:'BALANCE',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x5a:'GAS',0x5b:'JUMPDEST',0xf1:'CALL'};
for(let i=0x60;i<=0x7f;i++) names[i]='PUSH'+(i-0x5f); for(let i=0x80;i<=0x8f;i++) names[i]='DUP'+(i-0x7f); for(let i=0x90;i<=0x9f;i++) names[i]='SWAP'+(i-0x8f);
function show(stack){return '['+stack.join(', ')+']'}
function run(start, initial=[]){
 let stack=initial.slice(); let cur=start;
 for(let steps=0;steps<220;steps++){
  const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); return;}
  const nm=names[ins.op]||('OP_'+ins.op.toString(16));
  console.log(cur.toString(16).padStart(4,'0'), nm, ins.arg||'', show(stack));
  const pop=()=>stack.pop(); const push=v=>stack.push(v);
  const bin=(sym)=>{const x=pop(), y=pop(); push("'`(${x}${sym}${y})`)};
  if(ins.op===0x5b){cur++; continue;}
  if(ins.op>=0x60&&ins.op<=0x7f){push(ins.arg); cur+=1+(ins.op-0x5f); continue;}
  if(ins.op>=0x80&&ins.op<=0x8f){const idx=ins.op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
  if(ins.op>=0x90&&ins.op<=0x9f){const idx=ins.op-0x8f; const a=stack.length-1, b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
  switch(ins.op){
   case 0x00: return;
   case 0x01: bin('"'+'); break;
   case 0x02: bin('*'); break;
   case 0x03: bin('-'); break;
   case 0x0a: {const x=pop(), y=pop(); push("'`exp(${x},${y})`); break;}
   case 0x10: bin('"'<'); break;
   case 0x11: bin('>'); break;
   case 0x14: bin('=='); break;
   case 0x15: push("'`iszero(${pop()})`); break;
   case 0x16: bin('"'&'); break;
   case 0x19: push("'`~${pop()}`); break;
   case 0x20: {const x=pop(), y=pop(); push(`keccak(${x},${y})`); break;}
   case 0x30: push('"'address(this)'); break;
   case 0x31: push("'`balance(${pop()})`); break;
   case 0x33: push('"'caller'); break;
   case 0x34: push('callvalue'); break;
   case 0x35: push("'`calldata[${pop()}]`); break;
   case 0x50: pop(); break;
   case 0x51: push(`m[${pop()}]`); break;
   case 0x52: {const off=pop(), val=pop(); console.log('"'  MSTORE',off,'=',val); break;}
   case 0x54: push("'`s[${pop()}]`); break;
   case 0x55: {const off=pop(), val=pop(); console.log('"'  SSTORE',off,'=',val); break;}
   case 0x56: console.log('  JUMP',pop(),'remain',show(stack)); return;
   case 0x57: {const dest=pop(), cond=pop(); console.log('  JUMPI dest',dest,'cond',cond,'remain',show(stack)); return;}
   case 0xf1: {const gas=pop(),to=pop(),value=pop(),inOff=pop(),inSize=pop(),outOff=pop(),outSize=pop(); console.log('  CALL',{gas,to,value,inOff,inSize,outOff,outSize},'remain',show(stack)); push('callret'); break;}
   default: console.log('stop unsupported',nm); return;
  }
  cur++;
 }
}
console.log('0x144'); run(0x144,[]); console.log('0x158'); run(0x158,[]); console.log('0x19f'); run(0x19f,[]);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
0x144
0144 JUMPDEST  []
0145 PUSH1 0x05 []
0147 SLOAD  [0x05]
0148 PUSH1 0x04 [s[0x05]]
014a SWAP1  [s[0x05], 0x04]
014b GT  [0x04, s[0x05]]
014c ISZERO  [(s[0x05]>0x04)]
014d PUSH2 0x0158 [iszero((s[0x05]>0x04))]
0150 JUMPI  [iszero((s[0x05]>0x04)), 0x0158]
  JUMPI dest 0x0158 cond iszero((s[0x05]>0x04)) remain []
0x158
0158 JUMPDEST  []
0159 CALLER  []
015a PUSH1 0x01 [caller]
015c PUSH1 0xa0 [caller, 0x01]
015e PUSH1 0x02 [caller, 0x01, 0xa0]
0160 EXP  [caller, 0x01, 0xa0, 0x02]
0161 SUB  [caller, 0x01, exp(0x02,0xa0)]
0162 AND  [caller, (exp(0x02,0xa0)-0x01)]
0163 PUSH1 0x00 [((exp(0x02,0xa0)-0x01)&caller)]
0165 SWAP1  [((exp(0x02,0xa0)-0x01)&caller), 0x00]
0166 DUP2  [0x00, ((exp(0x02,0xa0)-0x01)&caller)]
0167 MSTORE  [0x00, ((exp(0x02,0xa0)-0x01)&caller), 0x00]
  MSTORE 0x00 = ((exp(0x02,0xa0)-0x01)&caller)
0168 PUSH1 0x06 [0x00]
016a PUSH1 0x20 [0x00, 0x06]
016c MSTORE  [0x00, 0x06, 0x20]
  MSTORE 0x20 = 0x06
016d PUSH1 0x40 [0x00]
016f DUP2  [0x00, 0x40]
0170 SHA3  [0x00, 0x40, 0x00]
0171 SLOAD  [0x00, keccak(0x00,0x40)]
0172 GT  [0x00, s[keccak(0x00,0x40)]]
0173 ISZERO  [(s[keccak(0x00,0x40)]>0x00)]
0174 PUSH2 0x017f [iszero((s[keccak(0x00,0x40)]>0x00))]
0177 JUMPI  [iszero((s[keccak(0x00,0x40)]>0x00)), 0x017f]
  JUMPI dest 0x017f cond iszero((s[keccak(0x00,0x40)]>0x00)) remain []
0x19f
019f JUMPDEST  []
01a0 PUSH1 0x40 []
01a2 PUSH1 0x00 [0x40]
01a4 SWAP1  [0x40, 0x00]
01a5 DUP2  [0x00, 0x40]
01a6 SHA3  [0x00, 0x40, 0x00]
01a7 CALLER  [0x00, keccak(0x00,0x40)]
01a8 PUSH1 0x01 [0x00, keccak(0x00,0x40), caller]
01aa PUSH1 0xa0 [0x00, keccak(0x00,0x40), caller, 0x01]
01ac PUSH1 0x02 [0x00, keccak(0x00,0x40), caller, 0x01, 0xa0]
01ae EXP  [0x00, keccak(0x00,0x40), caller, 0x01, 0xa0, 0x02]
01af SUB  [0x00, keccak(0x00,0x40), caller, 0x01, exp(0x02,0xa0)]
01b0 DUP2  [0x00, keccak(0x00,0x40), caller, (exp(0x02,0xa0)-0x01)]
01b1 AND  [0x00, keccak(0x00,0x40), caller, (exp(0x02,0xa0)-0x01), caller]
01b2 DUP4  [0x00, keccak(0x00,0x40), caller, (caller&(exp(0x02,0xa0)-0x01))]
01b3 MSTORE  [0x00, keccak(0x00,0x40), caller, (caller&(exp(0x02,0xa0)-0x01)), 0x00]
  MSTORE 0x00 = (caller&(exp(0x02,0xa0)-0x01))
01b4 PUSH1 0x06 [0x00, keccak(0x00,0x40), caller]
01b6 PUSH1 0x20 [0x00, keccak(0x00,0x40), caller, 0x06]
01b8 MSTORE  [0x00, keccak(0x00,0x40), caller, 0x06, 0x20]
  MSTORE 0x20 = 0x06
01b9 CALLVALUE  [0x00, keccak(0x00,0x40), caller]
01ba SWAP1  [0x00, keccak(0x00,0x40), caller, callvalue]
01bb SWAP2  [0x00, keccak(0x00,0x40), callvalue, caller]
01bc SSTORE  [0x00, caller, callvalue, keccak(0x00,0x40)]
  SSTORE keccak(0x00,0x40) = callvalue
01bd PUSH1 0x05 [0x00, caller]
01bf DUP1  [0x00, caller, 0x05]
01c0 SLOAD  [0x00, caller, 0x05, 0x05]
01c1 SWAP2  [0x00, caller, 0x05, s[0x05]]
01c2 SWAP3  [0x00, s[0x05], 0x05, caller]
01c3 SWAP2  [caller, s[0x05], 0x05, 0x00]
01c4 SWAP1  [caller, 0x00, 0x05, s[0x05]]
01c5 DUP2  [caller, 0x00, s[0x05], 0x05]
01c6 LT  [caller, 0x00, s[0x05], 0x05, s[0x05]]
01c7 ISZERO  [caller, 0x00, s[0x05], (s[0x05]<0x05)]
01c8 PUSH2 0x0002 [caller, 0x00, s[0x05], iszero((s[0x05]<0x05))]
01cb JUMPI  [caller, 0x00, s[0x05], iszero((s[0x05]<0x05)), 0x0002]
  JUMPI dest 0x0002 cond iszero((s[0x05]<0x05)) remain [caller, 0x00, s[0x05]]

exec
/bin/bash -lc "node - <<'NODE'
const fs = require('fs');
const obj = JSON.parse(fs.readFileSync('BYTECODE_BUNDLE.json','utf8'));
const hex = obj.artifact.runtime_bytecode.full.slice(2);
const dis=[]; let pc=0;
while(pc<hex.length/2){ const op=parseInt(hex.slice(pc*2,pc*2+2),16); let n=0,arg=null; if(op>=0x60&&op<=0x7f){n=op-0x5f; arg='0x'+hex.slice((pc+1)*2,(pc+1+n)*2);} dis.push({pc,op,arg}); pc+=1+n; }
const map=new Map(dis.map(x=>[x.pc,x]));
const names={0x00:'STOP',0x01:'ADD',0x02:'MUL',0x03:'SUB',0x0a:'EXP',0x10:'LT',0x11:'GT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x19:'NOT',0x20:'SHA3',0x30:'ADDRESS',0x31:'BALANCE',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x5a:'GAS',0x5b:'JUMPDEST',0xf1:'CALL'};
for(let i=0x60;i<=0x7f;i++) names[i]='PUSH'+(i-0x5f); for(let i=0x80;i<=0x8f;i++) names[i]='DUP'+(i-0x7f); for(let i=0x90;i<=0x9f;i++) names[i]='SWAP'+(i-0x8f);
function show(stack){return '['+stack.join(', ')+']'}
function run(start, initial=[]){
 let stack=initial.slice(); let cur=start;
 for(let steps=0;steps<120;steps++){
  const ins=map.get(cur); if("'!ins){console.log('"'no ins',cur); return;}
  const nm=names[ins.op]||('OP_'+ins.op.toString(16));
  console.log(cur.toString(16).padStart(4,'0'), nm, ins.arg||'', show(stack));
  const pop=()=>stack.pop(); const push=v=>stack.push(v);
  const bin=(sym)=>{const x=pop(), y=pop(); push("'`(${x}${sym}${y})`)};
  if(ins.op===0x5b){cur++; continue;}
  if(ins.op>=0x60&&ins.op<=0x7f){push(ins.arg); cur+=1+(ins.op-0x5f); continue;}
  if(ins.op>=0x80&&ins.op<=0x8f){const idx=ins.op-0x7f; push(stack[stack.length-idx]); cur++; continue;}
  if(ins.op>=0x90&&ins.op<=0x9f){const idx=ins.op-0x8f; const a=stack.length-1, b=stack.length-1-idx; [stack[a],stack[b]]=[stack[b],stack[a]]; cur++; continue;}
  switch(ins.op){
   case 0x00: return;
   case 0x01: bin('"'+'); break;
   case 0x02: bin('*'); break;
   case 0x03: bin('-'); break;
   case 0x0a: {const x=pop(), y=pop(); push("'`exp(${x},${y})`); break;}
   case 0x10: bin('"'<'); break;
   case 0x11: bin('>'); break;
   case 0x14: bin('=='); break;
   case 0x15: push("'`iszero(${pop()})`); break;
   case 0x16: bin('"'&'); break;
   case 0x19: push("'`~${pop()}`); break;
   case 0x20: {const x=pop(), y=pop(); push(`keccak(${x},${y})`); break;}
   case 0x30: push('"'address(this)'); break;
   case 0x31: push("'`balance(${pop()})`); break;
   case 0x33: push('"'caller'); break;
   case 0x34: push('callvalue'); break;
   case 0x35: push("'`calldata[${pop()}]`); break;
   case 0x50: pop(); break;
   case 0x51: push(`m[${pop()}]`); break;
   case 0x52: {const off=pop(), val=pop(); console.log('"'  MSTORE',off,'=',val); break;}
   case 0x54: push("'`s[${pop()}]`); break;
   case 0x55: {const off=pop(), val=pop(); console.log('"'  SSTORE',off,'=',val); break;}
   case 0x56: console.log('  JUMP',pop(),'remain',show(stack)); return;
   case 0x57: {const dest=pop(), cond=pop(); console.log('  JUMPI dest',dest,'cond',cond,'remain',show(stack)); return;}
   case 0xf1: {const gas=pop(),to=pop(),value=pop(),inOff=pop(),inSize=pop(),outOff=pop(),outSize=pop(); console.log('  CALL',{gas,to,value,inOff,inSize,outOff,outSize},'remain',show(stack)); push('callret'); break;}
   default: console.log('stop unsupported',nm); return;
  }
  cur++;
 }
}
run(0x1cc,['caller','0x00','s[0x05]']);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
01cc DUP1  [caller, 0x00, s[0x05]]
01cd SLOAD  [caller, 0x00, s[0x05], s[0x05]]
01ce PUSH20 0xffffffffffffffffffffffffffffffffffffffff [caller, 0x00, s[0x05], s[s[0x05]]]
01e3 NOT  [caller, 0x00, s[0x05], s[s[0x05]], 0xffffffffffffffffffffffffffffffffffffffff]
01e4 AND  [caller, 0x00, s[0x05], s[s[0x05]], ~0xffffffffffffffffffffffffffffffffffffffff]
01e5 SWAP1  [caller, 0x00, s[0x05], (~0xffffffffffffffffffffffffffffffffffffffff&s[s[0x05]])]
01e6 SWAP3  [caller, 0x00, (~0xffffffffffffffffffffffffffffffffffffffff&s[s[0x05]]), s[0x05]]
01e7 OP_17  [s[0x05], 0x00, (~0xffffffffffffffffffffffffffffffffffffffff&s[s[0x05]]), caller]
stop unsupported OP_17

exec
/bin/bash -lc "jq '.capability_graph.graph_json' BYTECODE_BUNDLE.json | sed -n '1,240p'" in /tmp/codex-vyere7o6
 succeeded in 0ms:
{
  "edges": [
    {
      "from": "bb:0",
      "to": "bb:97",
      "type": "control_flow"
    },
    {
      "from": "bb:0",
      "to": "bb:11",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:11",
      "to": "bb:99",
      "type": "control_flow"
    },
    {
      "from": "bb:11",
      "to": "bb:31",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:31",
      "to": "bb:121",
      "type": "control_flow"
    },
    {
      "from": "bb:31",
      "to": "bb:42",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:42",
      "to": "bb:145",
      "type": "control_flow"
    },
    {
      "from": "bb:42",
      "to": "bb:53",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:53",
      "to": "bb:154",
      "type": "control_flow"
    },
    {
      "from": "bb:53",
      "to": "bb:64",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:64",
      "to": "bb:187",
      "type": "control_flow"
    },
    {
      "from": "bb:64",
      "to": "bb:75",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:75",
      "to": "bb:233",
      "type": "control_flow"
    },
    {
      "from": "bb:75",
      "to": "bb:86",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:86",
      "to": "bb:262",
      "type": "control_flow"
    },
    {
      "from": "bb:86",
      "to": "bb:97",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:99",
      "to": "bb:324",
      "type": "control_flow"
    },
    {
      "from": "bb:99",
      "to": "bb:114",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:114",
      "to": "bb:237",
      "type": "control_flow"
    },
    {
      "from": "bb:145",
      "to": "bb:151",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:154",
      "to": "bb:151",
      "type": "control_flow"
    },
    {
      "from": "bb:187",
      "to": "bb:215",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:233",
      "to": "bb:237",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:262",
      "to": "bb:281",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:324",
      "to": "bb:344",
      "type": "control_flow"
    },
    {
      "from": "bb:324",
      "to": "bb:337",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:337",
      "to": "bb:237",
      "type": "control_flow"
    },
    {
      "from": "bb:344",
      "to": "bb:383",
      "type": "control_flow"
    },
    {
      "from": "bb:344",
      "to": "bb:376",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:376",
      "to": "bb:237",
      "type": "control_flow"
    },
    {
      "from": "bb:383",
      "to": "bb:415",
      "type": "control_flow"
    },
    {
      "from": "bb:383",
      "to": "bb:408",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "bb:408",
      "to": "bb:237",
      "type": "control_flow"
    },
    {
      "from": "bb:415",
      "to": "bb:460",
      "type": "control_flow_fallthrough"
    },
    {
      "from": "fn:0x437600bc",
      "to": "bb:1145821979",
      "type": "entry"
    },
    {
      "from": "fn:0x444bdb1b",
      "to": "bb:1833756220",
      "type": "entry"
    },
    {
      "from": "fn:0x6d4ce63c",
      "to": "bb:1907192353",
      "type": "entry"
    },
    {
      "from": "fn:0x71ad7221",
      "to": "bb:2236328349",
      "type": "entry"
    },
    {
      "from": "fn:0x854ba99d",
      "to": "bb:2737678801",
      "type": "entry"
    },
    {
      "from": "bb:237",
      "to": "call:257",
      "type": "contains"
    },
    {
      "from": "call:257",
      "to": "sink:call",
      "type": "capability"
    }
  ],
  "nodes": [
    {
      "end_pc": 10,
      "hash": "0xf9379be67bf0d681af837933f0f4af1f87650997fa5ffba869eb61e5b6669abc",
      "id": "bb:0",
      "start_pc": 0,
      "type": "basic_block"
    },
    {
      "end_pc": 30,
      "hash": "0x22a5085fba77c6777c88cdd6a31289d1a430c87347632add96f32302d9d0e82e",
      "id": "bb:11",
      "start_pc": 11,
      "type": "basic_block"
    },
    {
      "end_pc": 41,
      "hash": "0xe7af49f8c15632229ba6c899c130610351d31e8429c33737b9692da0e67f3db9",
      "id": "bb:31",
      "start_pc": 31,
      "type": "basic_block"
    },
    {
      "end_pc": 52,
      "hash": "0xfd77ef5ad46455e5156f11b867f3d83d5ff2afe00f8f6ba016c972354dbeffc7",
      "id": "bb:42",
      "start_pc": 42,
      "type": "basic_block"
    },
    {
      "end_pc": 63,
      "hash": "0xb834ece24abfef89975071d1ec860c4344bc5b2876de313201268a25a18d8bee",

exec
/bin/bash -lc "node - <<'NODE'
function sim(initial){
  let s=initial.slice();
  const push=v=>s.push(v), pop=()=>s.pop();
  const dup=n=>push(s[s.length-n]); const swap=n=>{const a=s.length-1,b=s.length-1-n; [s[a],s[b]]=[s[b],s[a]]};
  push('0x40'); pop(); push('m[0x40]'); // push1 40; mload
  push('0x0194'); swap(1); push('0x00'); dup(2); dup(2); dup(2); dup(2); dup(7); push('0x61da'); push('gas');
  // SUB x-y with x=top gas, y=next 0x61da
  const x=pop(), y=pop(); push("'`(${x}-${y})`);
  const gas=pop(), to=pop(), value=pop(), inOff=pop(), inSize=pop(), outOff=pop(), outSize=pop();
  console.log('"'initial',initial,'call',{gas,to,value,inOff,inSize,outOff,outSize},'remaining before pops',s);
  push('callret'); pop(); pop(); pop(); console.log('jump',pop(),'final',s);
}
sim(['R']);
sim(['R1','R2']);
sim(['R1','R2','X']);
NODE" in /tmp/codex-vyere7o6
 succeeded in 0ms:
initial [ 'R' ] call {
  gas: '(gas-0x61da)',
  to: '0x0194',
  value: '0x00',
  inOff: 'm[0x40]',
  inSize: '0x00',
  outOff: 'm[0x40]',
  outSize: '0x00'
} remaining before pops [ 'R', '0x0194', 'm[0x40]' ]
jump R final []
initial [ 'R1', 'R2' ] call {
  gas: '(gas-0x61da)',
  to: '0x0194',
  value: '0x00',
  inOff: 'm[0x40]',
  inSize: '0x00',
  outOff: 'm[0x40]',
  outSize: '0x00'
} remaining before pops [ 'R1', 'R2', '0x0194', 'm[0x40]' ]
jump R2 final [ 'R1' ]
initial [ 'R1', 'R2', 'X' ] call {
  gas: '(gas-0x61da)',
  to: '0x0194',
  value: '0x00',
  inOff: 'm[0x40]',
  inSize: '0x00',
  outOff: 'm[0x40]',
  outSize: '0x00'
} remaining before pops [ 'R1', 'R2', 'X', '0x0194', 'm[0x40]' ]
jump X final [ 'R1', 'R2' ]

codex
{"no_findings":false,"summary":"Bytecode analysis found one clear fail-open accounting issue in the payable path and one lower-confidence unchecked external call/reentrancy surface. I did not find delegatecall/proxy behavior or upgrade-slot writes in the provided bundle.","findings":[{"severity":"high","category":"math","title":"Payable path fails open and persists state even when its apparent eligibility/collateral checks fail","exploit_scenario":"Selector 0x1aa3a008 appears to be the only state-changing/payable entrypoint. It checks a caller-specific slot6 mapping entry and a balance-vs-5x-msg.value condition, but on the failing branch it does not revert; instead it jumps into the CALL helper and then resumes normal execution. An attacker can therefore call the function even when they already have a nonzero recorded amount, or when the contract balance is below the apparent 5x threshold, and still reach the later SSTOREs that record msg.value and append the caller to the slot list. If the intended invariant was one-time participation or 5x collateralization, that invariant is bypassable.","recommendation":"Replace the fail-open CALL helper path with an actual revert on failed predicates. In source terms, enforce the checks before any external interaction or state write, and only continue to the SSTOREs when the predicates are satisfied.","evidence":"At pc 0x170-0x177 the code loads keccak(caller, slot 6) and branches to pc 0x17f only when the stored value is zero; otherwise it falls through to the CALL helper at pc 0x00ed and then continues anyway. At pc 0x183-0x197 it compares contract balance against msg.value * 5; if the check fails it again routes through the CALL helper and then continues. The state write still happens afterward at pc 0x1bc (slot6[caller] = CALLVALUE), followed by slot-list writes at pc 0x1ea and pc 0x1f4.","locations":["selector:0x1aa3a008","pc:0x170","pc:0x192","pc:0x1bc","pc:0x1ea","pc:0x1f4"]},{"severity":"low","category":"reentrancy","title":"Unchecked external CALL forwards gas before bookkeeping","exploit_scenario":"The shared helper at pc 0x00ed performs a CALL at pc 0x0101 to the fixed address 0x0000000000000000000000000000000000000194, forwards essentially all remaining gas, ignores the success bit, and then jumps back into the caller. In selector 0x1aa3a008 this helper is reached before the later SSTOREs. If address 0x194 had executable code at the analyzed block, it could reenter before bookkeeping is updated. Because the target is hardcoded and runtime bytecode alone does not tell me whether that address actually had code, this is a lower-confidence surface rather than a confirmed exploit.","recommendation":"Avoid external interaction in this helper, or at minimum check CALL success and move all state updates ahead of the call if reentrancy is not intended. If the helper was meant to revert, replace it with explicit revert logic.","evidence":"The helper beginning at pc 0x00ed builds a CALL frame and executes CALL at pc 0x0101. The return value is immediately discarded with POPs at pc 0x0102-0x0104, and execution resumes via JUMP at pc 0x0105. This helper is reachable from selector 0x1aa3a008 before the later writes, and directly from selector 0x854ba99d.","locations":["pc:0x00ed","pc:0x0101","pc:0x0102","selector:0x1aa3a008","selector:0x854ba99d"]}]}
tokens used
134,681
Metadata
{
    "codex": {
        "ran_at": "2026-04-04T21:12:25.808151+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "bytecode",
        "bytecode_length": 1008,
        "bytecode_truncated": false,
        "capability_graph_present": true,
        "analysis_artifact_present": true
    },
    "summary": "Bytecode analysis found one clear fail-open accounting issue in the payable path and one lower-confidence unchecked external call/reentrancy surface. I did not find delegatecall/proxy behavior or upgrade-slot writes in the provided bundle.",
    "raw_final": {
        "summary": "Bytecode analysis found one clear fail-open accounting issue in the payable path and one lower-confidence unchecked external call/reentrancy surface. I did not find delegatecall/proxy behavior or upgrade-slot writes in the provided bundle.",
        "findings": [
            {
                "title": "Payable path fails open and persists state even when its apparent eligibility/collateral checks fail",
                "category": "math",
                "evidence": "At pc 0x170-0x177 the code loads keccak(caller, slot 6) and branches to pc 0x17f only when the stored value is zero; otherwise it falls through to the CALL helper at pc 0x00ed and then continues anyway. At pc 0x183-0x197 it compares contract balance against msg.value * 5; if the check fails it again routes through the CALL helper and then continues. The state write still happens afterward at pc 0x1bc (slot6[caller] = CALLVALUE), followed by slot-list writes at pc 0x1ea and pc 0x1f4.",
                "severity": "high",
                "locations": [
                    "selector:0x1aa3a008",
                    "pc:0x170",
                    "pc:0x192",
                    "pc:0x1bc",
                    "pc:0x1ea",
                    "pc:0x1f4"
                ],
                "recommendation": "Replace the fail-open CALL helper path with an actual revert on failed predicates. In source terms, enforce the checks before any external interaction or state write, and only continue to the SSTOREs when the predicates are satisfied.",
                "exploit_scenario": "Selector 0x1aa3a008 appears to be the only state-changing/payable entrypoint. It checks a caller-specific slot6 mapping entry and a balance-vs-5x-msg.value condition, but on the failing branch it does not revert; instead it jumps into the CALL helper and then resumes normal execution. An attacker can therefore call the function even when they already have a nonzero recorded amount, or when the contract balance is below the apparent 5x threshold, and still reach the later SSTOREs that record msg.value and append the caller to the slot list. If the intended invariant was one-time participation or 5x collateralization, that invariant is bypassable."
            },
            {
                "title": "Unchecked external CALL forwards gas before bookkeeping",
                "category": "reentrancy",
                "evidence": "The helper beginning at pc 0x00ed builds a CALL frame and executes CALL at pc 0x0101. The return value is immediately discarded with POPs at pc 0x0102-0x0104, and execution resumes via JUMP at pc 0x0105. This helper is reachable from selector 0x1aa3a008 before the later writes, and directly from selector 0x854ba99d.",
                "severity": "low",
                "locations": [
                    "pc:0x00ed",
                    "pc:0x0101",
                    "pc:0x0102",
                    "selector:0x1aa3a008",
                    "selector:0x854ba99d"
                ],
                "recommendation": "Avoid external interaction in this helper, or at minimum check CALL success and move all state updates ahead of the call if reentrancy is not intended. If the helper was meant to revert, replace it with explicit revert logic.",
                "exploit_scenario": "The shared helper at pc 0x00ed performs a CALL at pc 0x0101 to the fixed address 0x0000000000000000000000000000000000000194, forwards essentially all remaining gas, ignores the success bit, and then jumps back into the caller. In selector 0x1aa3a008 this helper is reached before the later SSTOREs. If address 0x194 had executable code at the analyzed block, it could reenter before bookkeeping is updated. Because the target is hardcoded and runtime bytecode alone does not tell me whether that address actually had code, this is a lower-confidence surface rather than a confirmed exploit."
            }
        ],
        "no_findings": false
    },
    "no_findings": false,
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
0
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
1
EXT*/BALANCE
1
Total opcodes
326
Flags
No heuristic flags raised.
View cast disassembly output
00000000: PUSH1 0x60
00000002: PUSH1 0x40
00000004: MSTORE
00000005: CALLDATASIZE
00000006: ISZERO
00000007: PUSH2 0x0061
0000000a: JUMPI
0000000b: PUSH1 0xe0
0000000d: PUSH1 0x02
0000000f: EXP
00000010: PUSH1 0x00
00000012: CALLDATALOAD
00000013: DIV
00000014: PUSH4 0x1aa3a008
00000019: DUP2
0000001a: EQ
0000001b: PUSH2 0x0063
0000001e: JUMPI
0000001f: DUP1
00000020: PUSH4 0x437600bc
00000025: EQ
00000026: PUSH2 0x0079
00000029: JUMPI
0000002a: DUP1
0000002b: PUSH4 0x444bdb1b
00000030: EQ
00000031: PUSH2 0x0091
00000034: JUMPI
00000035: DUP1
00000036: PUSH4 0x6d4ce63c
0000003b: EQ
0000003c: PUSH2 0x009a
0000003f: JUMPI
00000040: DUP1
00000041: PUSH4 0x71ad7221
00000046: EQ
00000047: PUSH2 0x00bb
0000004a: JUMPI
0000004b: DUP1
0000004c: PUSH4 0x854ba99d
00000051: EQ
00000052: PUSH2 0x00e9
00000055: JUMPI
00000056: DUP1
00000057: PUSH4 0xa32da9d1
0000005c: EQ
0000005d: PUSH2 0x0106
00000060: JUMPI
00000061: JUMPDEST
00000062: STOP
00000063: JUMPDEST
00000064: PUSH2 0x0061
00000067: PUSH1 0x00
00000069: CALLVALUE
0000006a: PUSH1 0x00
0000006c: EQ
0000006d: ISZERO
0000006e: PUSH2 0x0144
00000071: JUMPI
00000072: PUSH2 0x0144
00000075: PUSH2 0x00ed
00000078: JUMP
00000079: JUMPDEST
0000007a: PUSH2 0x00d7
0000007d: PUSH1 0x04
0000007f: CALLDATALOAD
00000080: PUSH1 0x06
00000082: PUSH1 0x20
00000084: MSTORE
00000085: PUSH1 0x00
00000087: SWAP1
00000088: DUP2
00000089: MSTORE
0000008a: PUSH1 0x40
0000008c: SWAP1
0000008d: KECCAK256
0000008e: SLOAD
0000008f: DUP2
00000090: JUMP
00000091: JUMPDEST
00000092: PUSH2 0x00d7
00000095: PUSH1 0x64
00000097: JUMPDEST
00000098: SWAP1
00000099: JUMP
0000009a: JUMPDEST
0000009b: PUSH2 0x00d7
0000009e: CALLER
0000009f: PUSH1 0x01
000000a1: PUSH1 0xa0
000000a3: PUSH1 0x02
000000a5: EXP
000000a6: SUB
000000a7: AND
000000a8: PUSH1 0x00
000000aa: SWAP1
000000ab: DUP2
000000ac: MSTORE
000000ad: PUSH1 0x06
000000af: PUSH1 0x20
000000b1: MSTORE
000000b2: PUSH1 0x40
000000b4: SWAP1
000000b5: KECCAK256
000000b6: SLOAD
000000b7: PUSH2 0x0097
000000ba: JUMP
000000bb: JUMPDEST
000000bc: PUSH1 0x01
000000be: PUSH1 0xa0
000000c0: PUSH1 0x02
000000c2: EXP
000000c3: SUB
000000c4: PUSH1 0x04
000000c6: CALLDATALOAD
000000c7: AND
000000c8: PUSH1 0x00
000000ca: SWAP1
000000cb: DUP2
000000cc: MSTORE
000000cd: PUSH1 0x06
000000cf: PUSH1 0x20
000000d1: MSTORE
000000d2: PUSH1 0x40
000000d4: SWAP1
000000d5: KECCAK256
000000d6: SLOAD
000000d7: JUMPDEST
000000d8: PUSH1 0x40
000000da: DUP1
000000db: MLOAD
000000dc: SWAP2
000000dd: DUP3
000000de: MSTORE
000000df: MLOAD
000000e0: SWAP1
000000e1: DUP2
000000e2: SWAP1
000000e3: SUB
000000e4: PUSH1 0x20
000000e6: ADD
000000e7: SWAP1
000000e8: RETURN
000000e9: JUMPDEST
000000ea: PUSH2 0x0061
000000ed: JUMPDEST
000000ee: PUSH1 0x40
000000f0: MLOAD
000000f1: PUSH2 0x0194
000000f4: SWAP1
000000f5: PUSH1 0x00
000000f7: DUP2
000000f8: DUP2
000000f9: DUP2
000000fa: DUP2
000000fb: DUP7
000000fc: PUSH2 0x61da
000000ff: GAS
00000100: SUB
00000101: CALL
00000102: POP
00000103: POP
00000104: POP
00000105: JUMP
00000106: JUMPDEST
00000107: PUSH2 0x0127
0000010a: PUSH1 0x04
0000010c: CALLDATALOAD
0000010d: PUSH1 0x00
0000010f: DUP2
00000110: PUSH1 0x05
00000112: DUP2
00000113: LT
00000114: ISZERO
00000115: PUSH2 0x0002
00000118: JUMPI
00000119: POP
0000011a: POP
0000011b: SLOAD
0000011c: PUSH1 0x01
0000011e: PUSH1 0xa0
00000120: PUSH1 0x02
00000122: EXP
00000123: SUB
00000124: AND
00000125: DUP2
00000126: JUMP
00000127: JUMPDEST
00000128: PUSH1 0x40
0000012a: DUP1
0000012b: MLOAD
0000012c: PUSH1 0x01
0000012e: PUSH1 0xa0
00000130: PUSH1 0x02
00000132: EXP
00000133: SUB
00000134: SWAP3
00000135: SWAP1
00000136: SWAP3
00000137: AND
00000138: DUP3
00000139: MSTORE
0000013a: MLOAD
0000013b: SWAP1
0000013c: DUP2
0000013d: SWAP1
0000013e: SUB
0000013f: PUSH1 0x20
00000141: ADD
00000142: SWAP1
00000143: RETURN
00000144: JUMPDEST
00000145: PUSH1 0x05
00000147: SLOAD
00000148: PUSH1 0x04
0000014a: SWAP1
0000014b: GT
0000014c: ISZERO
0000014d: PUSH2 0x0158
00000150: JUMPI
00000151: PUSH2 0x0158
00000154: PUSH2 0x00ed
00000157: JUMP
00000158: JUMPDEST
00000159: CALLER
0000015a: PUSH1 0x01
0000015c: PUSH1 0xa0
0000015e: PUSH1 0x02
00000160: EXP
00000161: SUB
00000162: AND
00000163: PUSH1 0x00
00000165: SWAP1
00000166: DUP2
00000167: MSTORE
00000168: PUSH1 0x06
0000016a: PUSH1 0x20
0000016c: MSTORE
0000016d: PUSH1 0x40
0000016f: DUP2
00000170: KECCAK256
00000171: SLOAD
00000172: GT
00000173: ISZERO
00000174: PUSH2 0x017f
00000177: JUMPI
00000178: PUSH2 0x017f
0000017b: PUSH2 0x00ed
0000017e: JUMP
0000017f: JUMPDEST
00000180: POP
00000181: PUSH1 0x00
00000183: CALLVALUE
00000184: PUSH1 0x05
00000186: MUL
00000187: ADDRESS
00000188: PUSH1 0x01
0000018a: PUSH1 0xa0
0000018c: PUSH1 0x02
0000018e: EXP
0000018f: SUB
00000190: AND
00000191: BALANCE
00000192: LT
00000193: ISZERO
00000194: PUSH2 0x019f
00000197: JUMPI
00000198: PUSH2 0x019f
0000019b: PUSH2 0x00ed
0000019e: JUMP
0000019f: JUMPDEST
000001a0: PUSH1 0x40
000001a2: PUSH1 0x00
000001a4: SWAP1
000001a5: DUP2
000001a6: KECCAK256
000001a7: CALLER
000001a8: PUSH1 0x01
000001aa: PUSH1 0xa0
000001ac: PUSH1 0x02
000001ae: EXP
000001af: SUB
000001b0: DUP2
000001b1: AND
000001b2: DUP4
000001b3: MSTORE
000001b4: PUSH1 0x06
000001b6: PUSH1 0x20
000001b8: MSTORE
000001b9: CALLVALUE
000001ba: SWAP1
000001bb: SWAP2
000001bc: SSTORE
000001bd: PUSH1 0x05
000001bf: DUP1
000001c0: SLOAD
000001c1: SWAP2
000001c2: SWAP3
000001c3: SWAP2
000001c4: SWAP1
000001c5: DUP2
000001c6: LT
000001c7: ISZERO
000001c8: PUSH2 0x0002
000001cb: JUMPI
000001cc: DUP1
000001cd: SLOAD
000001ce: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000001e3: NOT
000001e4: AND
000001e5: SWAP1
000001e6: SWAP3
000001e7: OR
000001e8: SWAP1
000001e9: SWAP2
000001ea: SSTORE
000001eb: POP
000001ec: PUSH1 0x05
000001ee: DUP1
000001ef: SLOAD
000001f0: PUSH1 0x01
000001f2: ADD
000001f3: SWAP1
000001f4: SSTORE
000001f5: POP
000001f6: JUMP
View stderr
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set `FOUNDRY_DISABLE_NIGHTLY_WARNING` in your environment.

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
high other detector Untrusted CALL target/value reachable 60 yes yes
view
trace_id: 0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f
call_targets: 0x0000000000000000000000000000000000000194, 0x8226891a383dc93da036274431aa9e00b47104d0
target_varies: yes
classification: target_varies
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "confirmed",
    "attempts": 1,
    "trace_id": "0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f",
    "confirmed": true,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x0000000000000000000000000000000000000194",
        "0x8226891a383dc93da036274431aa9e00b47104d0"
    ],
    "matched_probe": null,
    "target_varies": true,
    "classification": "target_varies"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0x1aa3a008",
            "selector": "0x1aa3a008",
            "calldata_variants": [
                "0x1aa3a008",
                "0x1aa3a0080000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x437600bc",
            "selector": "0x437600bc",
            "calldata_variants": [
                "0x437600bc",
                "0x437600bc0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x444bdb1b",
            "selector": "0x444bdb1b",
            "calldata_variants": [
                "0x444bdb1b",
                "0x444bdb1b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x6d4ce63c",
            "selector": "0x6d4ce63c",
            "calldata_variants": [
                "0x6d4ce63c",
                "0x6d4ce63c0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x71ad7221",
            "selector": "0x71ad7221",
            "calldata_variants": [
                "0x71ad7221",
                "0x71ad72210000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x854ba99d",
            "selector": "0x854ba99d",
            "calldata_variants": [
                "0x854ba99d",
                "0x854ba99d0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xa32da9d1",
            "selector": "0xa32da9d1",
            "calldata_variants": [
                "0xa32da9d1",
                "0xa32da9d10000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 257,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "call_count": 1,
    "guards_detected": [],
    "untrusted_call_count": 1
}
high other detector ETH value transfer possible 55 yes yes
view
trace_id: 0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f
call_targets: 0x0000000000000000000000000000000000000194, 0x8226891a383dc93da036274431aa9e00b47104d0
target_varies: yes
classification: target_varies
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "confirmed",
    "attempts": 1,
    "trace_id": "0xdd5be1d085edb952f5815aab0552c215618c60000bcb0f87f87c67f52078803f",
    "confirmed": true,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x0000000000000000000000000000000000000194",
        "0x8226891a383dc93da036274431aa9e00b47104d0"
    ],
    "matched_probe": null,
    "target_varies": true,
    "classification": "target_varies"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0x1aa3a008",
            "selector": "0x1aa3a008",
            "calldata_variants": [
                "0x1aa3a008",
                "0x1aa3a0080000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x437600bc",
            "selector": "0x437600bc",
            "calldata_variants": [
                "0x437600bc",
                "0x437600bc0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x444bdb1b",
            "selector": "0x444bdb1b",
            "calldata_variants": [
                "0x444bdb1b",
                "0x444bdb1b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x6d4ce63c",
            "selector": "0x6d4ce63c",
            "calldata_variants": [
                "0x6d4ce63c",
                "0x6d4ce63c0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x71ad7221",
            "selector": "0x71ad7221",
            "calldata_variants": [
                "0x71ad7221",
                "0x71ad72210000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x854ba99d",
            "selector": "0x854ba99d",
            "calldata_variants": [
                "0x854ba99d",
                "0x854ba99d0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xa32da9d1",
            "selector": "0xa32da9d1",
            "calldata_variants": [
                "0xa32da9d1",
                "0xa32da9d10000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 257,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "eth_value_calls": 1,
    "guards_detected": []
}
high math codex Payable path fails open and persists state even when its apparent eligibility/collateral checks fail 85 no
view
evidence_json
{
    "evidence": "At pc 0x170-0x177 the code loads keccak(caller, slot 6) and branches to pc 0x17f only when the stored value is zero; otherwise it falls through to the CALL helper at pc 0x00ed and then continues anyway. At pc 0x183-0x197 it compares contract balance against msg.value * 5; if the check fails it again routes through the CALL helper and then continues. The state write still happens afterward at pc 0x1bc (slot6[caller] = CALLVALUE), followed by slot-list writes at pc 0x1ea and pc 0x1f4.",
    "locations": [
        "selector:0x1aa3a008",
        "pc:0x170",
        "pc:0x192",
        "pc:0x1bc",
        "pc:0x1ea",
        "pc:0x1f4"
    ],
    "recommendation": "Replace the fail-open CALL helper path with an actual revert on failed predicates. In source terms, enforce the checks before any external interaction or state write, and only continue to the SSTOREs when the predicates are satisfied.",
    "exploit_scenario": "Selector 0x1aa3a008 appears to be the only state-changing/payable entrypoint. It checks a caller-specific slot6 mapping entry and a balance-vs-5x-msg.value condition, but on the failing branch it does not revert; instead it jumps into the CALL helper and then resumes normal execution. An attacker can therefore call the function even when they already have a nonzero recorded amount, or when the contract balance is below the apparent 5x threshold, and still reach the later SSTOREs that record msg.value and append the caller to the slot list. If the intended invariant was one-time participation or 5x collateralization, that invariant is bypassable."
}
low reentrancy codex Unchecked external CALL forwards gas before bookkeeping 65 no
view
evidence_json
{
    "evidence": "The helper beginning at pc 0x00ed builds a CALL frame and executes CALL at pc 0x0101. The return value is immediately discarded with POPs at pc 0x0102-0x0104, and execution resumes via JUMP at pc 0x0105. This helper is reachable from selector 0x1aa3a008 before the later writes, and directly from selector 0x854ba99d.",
    "locations": [
        "pc:0x00ed",
        "pc:0x0101",
        "pc:0x0102",
        "selector:0x1aa3a008",
        "selector:0x854ba99d"
    ],
    "recommendation": "Avoid external interaction in this helper, or at minimum check CALL success and move all state updates ahead of the call if reentrancy is not intended. If the helper was meant to revert, replace it with explicit revert logic.",
    "exploit_scenario": "The shared helper at pc 0x00ed performs a CALL at pc 0x0101 to the fixed address 0x0000000000000000000000000000000000000194, forwards essentially all remaining gas, ignores the success bit, and then jumps back into the caller. In selector 0x1aa3a008 this helper is reached before the later SSTOREs. If address 0x194 had executable code at the analyzed block, it could reenter before bookkeeping is updated. Because the target is hardcoded and runtime bytecode alone does not tell me whether that address actually had code, this is a lower-confidence surface rather than a confirmed exploit."
}