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

Analysis Run

019b3836-22a9-708c-9e79-2665fbe783ab

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
333 artifact.fetch complete 1 / 3 3 months ago
334 tool.cast_disasm complete 1 / 3 3 months ago
43495 analysis.bundle complete 1 / 3 1 week ago
43496 capability.graph complete 1 / 3 1 week ago
43497 detector.run complete 1 / 3 1 week ago
43498 validation.fork complete 1 / 3 1 week ago
82459 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
Fallback-only bytecode with three ETH-bearing CALL sites, no detected auth guards, and state cleanup that occurs after external payouts. The strongest issue is reentrancy risk on the payout path; a secondary issue is unchecked CALL success on all outbound transfers.
View stdout
{"no_findings":false,"summary":"Fallback-only bytecode with three ETH-bearing CALL sites, no detected auth guards, and state cleanup that occurs after external payouts. The strongest issue is reentrancy risk on the payout path; a secondary issue is unchecked CALL success on all outbound transfers.","findings":[{"severity":"high","category":"reentrancy","title":"External payout calls occur before round state is cleared","exploit_scenario":"A prior participant can register a contract as one of the payout recipients via the fallback update path. When the expiry/payout branch executes, the contract performs value-bearing CALLs to stored recipient addresses at pc 0x6d and pc 0xac before clearing slot 2 and before wiping the recipient fields in slots 0/1. A malicious recipient can reenter the fallback during the first payout while the old state is still live, potentially triggering the payout logic repeatedly and draining more of the contract balance than intended. This is based on bytecode-only reasoning, so the exact branch condition is inferred rather than source-confirmed.","recommendation":"Apply checks-effects-interactions: fully clear or checkpoint the active round before any external CALL, or add an explicit reentrancy guard around the fallback payout path. If payouts must remain external, store owed balances and let recipients withdraw in a separate pull-payment flow.","evidence":"The artifact reports no detected guards (`auth.guards=[]`) and three CALL sites. The first two CALLs are at pc 109/0x6d and 172/0xac, both with `returndata_checked: null` and computed targets/values. State-reset writes happen only afterward at pc 185/0xb9 (slot 2), pc 215-216/0xd7-0xd8 and pc 224/0xe0 (slot 0/1 cleanup), and pc 236/0xec (slot 3 reset). Recipient addresses appear user-influenced because the fallback update routine writes slots 1 and 0 at pc 334/0x14e and pc 339/0x153. Detector finding `Untrusted CALL target/value reachable` is validated/confirmed.","locations":["pc:0x6d","pc:0xac","pc:0xb9","pc:0xd7","pc:0xe0","pc:0xec","pc:0x14e","pc:0x153"]},{"severity":"medium","category":"other","title":"Outbound ETH transfers ignore CALL success and continue","exploit_scenario":"If a payout recipient or refund recipient is a contract that reverts or otherwise makes the CALL fail, this bytecode does not check the returned success flag before continuing. On the payout path, the contract appears to proceed into state cleanup and round reset even when one or both payouts fail, which can skip owed payments and strand funds in the contract. On the refund-like path at pc 0x112, a failed ETH send to `CALLER` is also ignored.","recommendation":"Check the boolean result of each CALL and revert on failure, or convert the design to pull-based withdrawals so failed recipients cannot silently break accounting. If non-reverting behavior is required, record failed payouts as claimable balances instead of discarding the failure.","evidence":"All three callsites in the bundle have `returndata_checked: null`: pc 109/0x6d, 172/0xac, and 274/0x112. In the bytecode, each CALL is followed by POPs rather than a conditional revert path, so success is discarded. After the payout CALLs, execution continues into storage writes that clear/reset state (pc 0xb9, 0xd7, 0xe0, 0xec), which creates accounting risk if the transfer did not actually occur. Detector finding `ETH value transfer possible` is validated/confirmed.","locations":["pc:0x6d","pc:0xac","pc:0x112","pc:0xb9","pc:0xd7","pc:0xe0","pc:0xec"]}]}
View stderr
OpenAI Codex v0.118.0 (research preview)
--------
workdir: /tmp/codex-33obuzoq
model: gpt-5.4
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: none
session id: 019d5a82-7c39-78d1-929f-b2b094cb360f
--------
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 in /tmp/codex-33obuzoq
 succeeded in 0ms:
/tmp/codex-33obuzoq

exec
/bin/bash -lc 'rg --files' in /tmp/codex-33obuzoq
 succeeded in 0ms:
codex-output-schema.json
BYTECODE_BUNDLE.json

exec
/bin/bash -lc "sed -n '1,260p' BYTECODE_BUNDLE.json" in /tmp/codex-33obuzoq
 succeeded in 0ms:
{
  "analysis_artifact": {
    "address": "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4",
    "artifact_hash": "0x348ffa907b2a18715048f8e58e317370432ac5ba602ba11ec2617eb1f507f9a5",
    "artifact_json": {
      "auth": {
        "guards": []
      },
      "basic_blocks": [
        {
          "end_pc": 10,
          "hash": "0xac0bdec5d70ac003da16146b40dd072a1529c7207bdb7c1e984cda39da7e0897",
          "opcodes": [
            "PUSH1",
            "PUSH1",
            "MSTORE",
            "CALLDATASIZE",
            "ISZERO",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 0
        },
        {
          "end_pc": 31,
          "hash": "0x9eb4aa0f520a79a3f5e316d1e94ceb7c2c096c022b44d74b6e1fdcd385b4166d",
          "opcodes": [
            "JUMPDEST",
            "PUSH2",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "POP",
            "SLOAD",
            "GT",
            "OP_80",
            "ISZERO",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 11
        },
        {
          "end_pc": 45,
          "hash": "0x4b7468393bef1fc83071421d9f2df99457d9e3e5559bc21ff386d2023e45d0d4",
          "opcodes": [
            "POP",
            "PUSH3",
            "PUSH1",
            "PUSH1",
            "POP",
            "SLOAD",
            "TIMESTAMP",
            "SUB",
            "GT"
          ],
          "start_pc": 32
        },
        {
          "end_pc": 51,
          "hash": "0xdfe96000889c110656da416ef3ae7d6f29671d0b93bc0f7f8baa61c5239e6b6d",
          "opcodes": [
            "JUMPDEST",
            "ISZERO",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 46
        },
        {
          "end_pc": 78,
          "hash": "0xab22199b4d1941b724675f0ddad6aba2c2a017c5226af710ac2504285c6a934d",
          "opcodes": [
            "OP_80",
            "SLOAD",
            "CALLVALUE",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "ADDRESS",
            "OP_81",
            "AND",
            "BALANCE",
            "OP_91",
            "OP_90",
            "OP_91",
            "SUB",
            "OP_92",
            "OP_91",
            "AND",
            "EQ",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 52
        },
        {
          "end_pc": 114,
          "hash": "0x5e4abfbbf72adceeda93577a57e79dc20e8c248cbd5b9fa138b054859687a421",
          "opcodes": [
            "PUSH1",
            "OP_80",
            "SLOAD",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "AND",
            "OP_90",
            "PUSH1",
            "PUSH1",
            "OP_84",
            "MUL",
            "DIV",
            "PUSH1",
            "OP_82",
            "OP_81",
            "OP_81",
            "OP_81",
            "OP_85",
            "OP_88",
            "OP_83",
            "CALL",
            "POP",
            "POP",
            "POP",
            "POP",
            "POP"
          ],
          "start_pc": 79
        },
        {
          "end_pc": 134,
          "hash": "0x498a9a43a5498ab53607e59da45dbd714d8e898df7a294735c2b11593c39058f",
          "opcodes": [
            "JUMPDEST",
            "PUSH1",
            "SLOAD",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "AND",
            "PUSH1",
            "EQ",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 115
        },
        {
          "end_pc": 177,
          "hash": "0xda7b2e64112f3e307dfb8bbe6aa2f879c32a9ff0854aaed2e08307d041ccc677",
          "opcodes": [
            "PUSH1",
            "SLOAD",
            "PUSH1",
            "MLOAD",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "OP_91",
            "OP_90",
            "OP_91",
            "AND",
            "OP_90",
            "PUSH1",
            "OP_90",
            "PUSH1",
            "PUSH1",
            "OP_85",
            "MUL",
            "DIV",
            "OP_90",
            "OP_82",
            "OP_81",
            "OP_81",
            "OP_81",
            "OP_85",
            "OP_88",
            "OP_83",
            "CALL",
            "POP",
            "POP",
            "POP",
            "POP",
            "POP"
          ],
          "start_pc": 135
        },
        {
          "end_pc": 236,
          "hash": "0x2b424cad0b3eeeed88643f2db571b92b910affac2114c8b69f4e4772e3a096a0",
          "opcodes": [
            "JUMPDEST",
            "PUSH1",
            "PUSH1",
            "OP_81",
            "OP_90",
            "SSTORE",
            "OP_80",
            "SLOAD",
            "PUSH20",
            "NOT",
            "OP_90",
            "OP_81",
            "AND",
            "OP_90",
            "OP_91",
            "SSTORE",
            "PUSH1",
            "OP_80",
            "SLOAD",
            "OP_90",
            "OP_91",
            "AND",
            "OP_90",
            "SSTORE",
            "PUSH8",
            "PUSH1",
            "SSTORE"
          ],
          "start_pc": 178
        },
        {
          "end_pc": 247,
          "hash": "0x8af0acf29c292bf5a9ce46485cdd9a39f73d1bf0867eed51d979e0184dcfc8d0",
          "opcodes": [
            "JUMPDEST",
            "PUSH1",
            "SLOAD",
            "CALLVALUE",
            "LT",
            "ISZERO",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 237
        },
        {
          "end_pc": 284,
          "hash": "0x809361b977fdc151985ad0b6dcc6edbe3840b841c3e026dc4d5bc711be9f08ca",
          "opcodes": [
            "PUSH1",
            "MLOAD",
            "CALLER",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "AND",
            "OP_90",

exec
/bin/bash -lc "sed -n '261,520p' BYTECODE_BUNDLE.json" in /tmp/codex-33obuzoq
 succeeded in 0ms:
            "PUSH1",
            "OP_90",
            "CALLVALUE",
            "OP_90",
            "OP_82",
            "OP_81",
            "OP_81",
            "OP_81",
            "OP_85",
            "OP_88",
            "OP_83",
            "CALL",
            "OP_93",
            "POP",
            "POP",
            "POP",
            "POP",
            "POP",
            "PUSH2",
            "JUMP"
          ],
          "start_pc": 248
        },
        {
          "end_pc": 286,
          "hash": "0x9d1eb45248d1d499f3afcc0a801c2af0284d44907feaf3d11ea39dddd1e35a0e",
          "opcodes": [
            "JUMPDEST",
            "STOP"
          ],
          "start_pc": 285
        },
        {
          "end_pc": 347,
          "hash": "0xb0de7f3059f532f56a07da969a8904bda23682e0c10bc179ab577ab563eab121",
          "opcodes": [
            "JUMPDEST",
            "PUSH1",
            "OP_80",
            "SLOAD",
            "PUSH1",
            "OP_80",
            "SLOAD",
            "PUSH20",
            "NOT",
            "OP_90",
            "OP_81",
            "AND",
            "PUSH1",
            "PUSH1",
            "PUSH1",
            "EXP",
            "SUB",
            "OP_84",
            "AND",
            "OR",
            "OP_90",
            "OP_91",
            "SSTORE",
            "AND",
            "CALLER",
            "OR",
            "OP_90",
            "SSTORE",
            "CALLVALUE",
            "PUSH1",
            "SSTORE",
            "TIMESTAMP",
            "PUSH1",
            "SSTORE"
          ],
          "start_pc": 287
        },
        {
          "end_pc": 350,
          "hash": "0x3f2a62513986267f2204c579491db542e415c8fd39d211acc6a57cf2b8263f67",
          "opcodes": [
            "JUMPDEST",
            "POP",
            "JUMP"
          ],
          "start_pc": 348
        }
      ],
      "callsites": [
        {
          "opcode": "CALL",
          "pc": 109,
          "returndata_checked": null,
          "target_expression_category": "computed",
          "value_expression_category": "computed"
        },
        {
          "opcode": "CALL",
          "pc": 172,
          "returndata_checked": null,
          "target_expression_category": "computed",
          "value_expression_category": "computed"
        },
        {
          "opcode": "CALL",
          "pc": 274,
          "returndata_checked": null,
          "target_expression_category": "computed",
          "value_expression_category": "computed"
        }
      ],
      "cfg_edges": [
        {
          "from": "bb:0",
          "to": "bb:11",
          "type": "control_flow"
        },
        {
          "from": "bb:0",
          "to": "bb:11",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:11",
          "to": "bb:46",
          "type": "control_flow"
        },
        {
          "from": "bb:11",
          "to": "bb:32",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:32",
          "to": "bb:46",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:46",
          "to": "bb:237",
          "type": "control_flow"
        },
        {
          "from": "bb:46",
          "to": "bb:52",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:52",
          "to": "bb:115",
          "type": "control_flow"
        },
        {
          "from": "bb:52",
          "to": "bb:79",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:79",
          "to": "bb:115",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:115",
          "to": "bb:178",
          "type": "control_flow"
        },
        {
          "from": "bb:115",
          "to": "bb:135",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:135",
          "to": "bb:178",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:178",
          "to": "bb:237",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:237",
          "to": "bb:287",
          "type": "control_flow"
        },
        {
          "from": "bb:237",
          "to": "bb:248",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:248",
          "to": "bb:348",
          "type": "control_flow"
        },
        {
          "from": "bb:287",
          "to": "bb:348",
          "type": "control_flow_fallthrough"
        }
      ],
      "cfg_hash": "0x177b9ba39708b8831091738402bff1fa2eb63df16dd6c182093a332099aa04c4",
      "dispatcher_type": "fallback_only",
      "function_entries": [
        {
          "entry_pc": 0,
          "selector": "fallback"
        }
      ],
      "functions": [
        {
          "auth": {
            "guards": []
          },
          "entry_pc": 0,
          "selector": "fallback",
          "sinks": {
            "call": 3,
            "delegatecall": 0,
            "selfdestruct": 0,
            "staticcall": 0
          },
          "storage": {
            "reads": 11,
            "slots": [
              {
                "op": "SLOAD",
                "pc": 24,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
              },
              {
                "op": "SLOAD",
                "pc": 42,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
              },
              {
                "op": "SLOAD",
                "pc": 82,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
              },
              {
                "op": "SLOAD",
                "pc": 118,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
              },
              {
                "op": "SLOAD",
                "pc": 137,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
              },
              {
                "op": "SSTORE",
                "pc": 185,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
              },
              {
                "op": "SLOAD",
                "pc": 219,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
              },
              {
                "op": "SSTORE",

exec
/bin/bash -lc "sed -n '521,860p' BYTECODE_BUNDLE.json" in /tmp/codex-33obuzoq
 succeeded in 0ms:
                "pc": 236,
                "slot": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
              },
              {
                "op": "SLOAD",
                "pc": 240,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000003"
              },
              {
                "op": "SLOAD",
                "pc": 291,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
              },
              {
                "op": "SLOAD",
                "pc": 295,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
              }
            ],
            "writes": 8
          }
        }
      ],
      "selectors": [],
      "sinks": {
        "call": 3,
        "create": 0,
        "create2": 0,
        "delegatecall": 0,
        "selfdestruct": 0,
        "staticcall": 0,
        "upgrade_slot_write_suspected": false
      },
      "storage": {
        "keccak_count": 0,
        "reads": 11,
        "slots": [
          {
            "op": "SLOAD",
            "pc": 24,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
          },
          {
            "op": "SLOAD",
            "pc": 42,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
          },
          {
            "op": "SLOAD",
            "pc": 82,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
          },
          {
            "op": "SLOAD",
            "pc": 118,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
          },
          {
            "op": "SLOAD",
            "pc": 137,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
          },
          {
            "op": "SSTORE",
            "pc": 185,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
          },
          {
            "op": "SLOAD",
            "pc": 219,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
          },
          {
            "op": "SSTORE",
            "pc": 236,
            "slot": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
          },
          {
            "op": "SLOAD",
            "pc": 240,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000003"
          },
          {
            "op": "SLOAD",
            "pc": 291,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
          },
          {
            "op": "SLOAD",
            "pc": 295,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
          }
        ],
        "writes": 8
      },
      "version": "analysis_artifact_v1"
    },
    "block_number": null,
    "chain_id": 1,
    "codehash": "0x699872161ac66ed2937791f59bb932297779c0b234052c08949f3bd2548c58e3",
    "created_at": "2026-04-04T19:45:22.000000Z",
    "id": 1535,
    "updated_at": "2026-04-04T19:45:22.000000Z",
    "version": "analysis_artifact_v1"
  },
  "analysis_run": {
    "address": "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4",
    "block_number": null,
    "chain_id": 1,
    "child_links": [],
    "created_at": "2025-12-19T20:03:50.000000Z",
    "id": "019b3836-22a9-708c-9e79-2665fbe783ab",
    "parent_links": [],
    "status": "running",
    "updated_at": "2026-04-04T19:45:22.000000Z"
  },
  "artifact": {
    "codehash": "0x699872161ac66ed2937791f59bb932297779c0b234052c08949f3bd2548c58e3",
    "compiler_json": {
      "etherscan": {
        "skipped": true
      }
    },
    "implementation_address": null,
    "is_proxy": false,
    "runtime_bytecode": {
      "full": "0x6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056",
      "head": null,
      "length": 704,
      "tail": null,
      "truncated": false
    },
    "verified_source": false
  },
  "capability_graph": {
    "address": "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4",
    "block_number": null,
    "chain_id": 1,
    "codehash": "0x699872161ac66ed2937791f59bb932297779c0b234052c08949f3bd2548c58e3",
    "created_at": "2026-04-04T19:45:22.000000Z",
    "graph_hash": "0xacf5f16d36fe8363c25baaf31e30a4c0943a06e7e77227c13892aa2eb7c852d6",
    "graph_json": {
      "edges": [
        {
          "from": "bb:0",
          "to": "bb:11",
          "type": "control_flow"
        },
        {
          "from": "bb:0",
          "to": "bb:11",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:11",
          "to": "bb:46",
          "type": "control_flow"
        },
        {
          "from": "bb:11",
          "to": "bb:32",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:32",
          "to": "bb:46",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:46",
          "to": "bb:237",
          "type": "control_flow"
        },
        {
          "from": "bb:46",
          "to": "bb:52",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:52",
          "to": "bb:115",
          "type": "control_flow"
        },
        {
          "from": "bb:52",
          "to": "bb:79",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:79",
          "to": "bb:115",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:115",
          "to": "bb:178",
          "type": "control_flow"
        },
        {
          "from": "bb:115",
          "to": "bb:135",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:135",
          "to": "bb:178",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:178",
          "to": "bb:237",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:237",
          "to": "bb:287",
          "type": "control_flow"
        },
        {
          "from": "bb:237",
          "to": "bb:248",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:248",
          "to": "bb:348",
          "type": "control_flow"
        },
        {
          "from": "bb:287",
          "to": "bb:348",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "fn:fallback",
          "to": "bb:0",
          "type": "entry"
        },
        {
          "from": "bb:79",
          "to": "call:109",
          "type": "contains"
        },
        {
          "from": "call:109",
          "to": "sink:call",
          "type": "capability"
        },
        {
          "from": "bb:135",
          "to": "call:172",
          "type": "contains"
        },
        {
          "from": "call:172",
          "to": "sink:call",
          "type": "capability"
        },
        {
          "from": "bb:248",
          "to": "call:274",
          "type": "contains"
        },
        {
          "from": "call:274",
          "to": "sink:call",
          "type": "capability"
        }
      ],
      "nodes": [
        {
          "end_pc": 10,
          "hash": "0xac0bdec5d70ac003da16146b40dd072a1529c7207bdb7c1e984cda39da7e0897",
          "id": "bb:0",
          "start_pc": 0,
          "type": "basic_block"
        },
        {
          "end_pc": 31,
          "hash": "0x9eb4aa0f520a79a3f5e316d1e94ceb7c2c096c022b44d74b6e1fdcd385b4166d",
          "id": "bb:11",
          "start_pc": 11,
          "type": "basic_block"
        },
        {
          "end_pc": 45,
          "hash": "0x4b7468393bef1fc83071421d9f2df99457d9e3e5559bc21ff386d2023e45d0d4",
          "id": "bb:32",
          "start_pc": 32,
          "type": "basic_block"
        },
        {
          "end_pc": 51,
          "hash": "0xdfe96000889c110656da416ef3ae7d6f29671d0b93bc0f7f8baa61c5239e6b6d",
          "id": "bb:46",
          "start_pc": 46,
          "type": "basic_block"
        },
        {
          "end_pc": 78,
          "hash": "0xab22199b4d1941b724675f0ddad6aba2c2a017c5226af710ac2504285c6a934d",
          "id": "bb:52",
          "start_pc": 52,
          "type": "basic_block"
        },
        {
          "end_pc": 114,
          "hash": "0x5e4abfbbf72adceeda93577a57e79dc20e8c248cbd5b9fa138b054859687a421",
          "id": "bb:79",
          "start_pc": 79,
          "type": "basic_block"
        },
        {
          "end_pc": 134,
          "hash": "0x498a9a43a5498ab53607e59da45dbd714d8e898df7a294735c2b11593c39058f",
          "id": "bb:115",
          "start_pc": 115,
          "type": "basic_block"
        },
        {
          "end_pc": 177,
          "hash": "0xda7b2e64112f3e307dfb8bbe6aa2f879c32a9ff0854aaed2e08307d041ccc677",
          "id": "bb:135",
          "start_pc": 135,
          "type": "basic_block"
        },
        {
          "end_pc": 236,
          "hash": "0x2b424cad0b3eeeed88643f2db571b92b910affac2114c8b69f4e4772e3a096a0",
          "id": "bb:178",
          "start_pc": 178,
          "type": "basic_block"
        },
        {
          "end_pc": 247,
          "hash": "0x8af0acf29c292bf5a9ce46485cdd9a39f73d1bf0867eed51d979e0184dcfc8d0",
          "id": "bb:237",
          "start_pc": 237,
          "type": "basic_block"
        },

exec
/bin/bash -lc "sed -n '861,1200p' BYTECODE_BUNDLE.json" in /tmp/codex-33obuzoq
 succeeded in 0ms:
        {
          "end_pc": 284,
          "hash": "0x809361b977fdc151985ad0b6dcc6edbe3840b841c3e026dc4d5bc711be9f08ca",
          "id": "bb:248",
          "start_pc": 248,
          "type": "basic_block"
        },
        {
          "end_pc": 286,
          "hash": "0x9d1eb45248d1d499f3afcc0a801c2af0284d44907feaf3d11ea39dddd1e35a0e",
          "id": "bb:285",
          "start_pc": 285,
          "type": "basic_block"
        },
        {
          "end_pc": 347,
          "hash": "0xb0de7f3059f532f56a07da969a8904bda23682e0c10bc179ab577ab563eab121",
          "id": "bb:287",
          "start_pc": 287,
          "type": "basic_block"
        },
        {
          "end_pc": 350,
          "hash": "0x3f2a62513986267f2204c579491db542e415c8fd39d211acc6a57cf2b8263f67",
          "id": "bb:348",
          "start_pc": 348,
          "type": "basic_block"
        },
        {
          "id": "call:109",
          "opcode": "CALL",
          "pc": 109,
          "type": "callsite"
        },
        {
          "id": "call:172",
          "opcode": "CALL",
          "pc": 172,
          "type": "callsite"
        },
        {
          "id": "call:274",
          "opcode": "CALL",
          "pc": 274,
          "type": "callsite"
        },
        {
          "id": "sink:call",
          "type": "sink"
        },
        {
          "entry_pc": 0,
          "id": "fn:fallback",
          "selector": "fallback",
          "type": "function"
        }
      ],
      "version": "capability_graph_v1"
    },
    "id": 1535,
    "updated_at": "2026-04-04T19:45:22.000000Z",
    "version": "capability_graph_v1"
  },
  "detector_findings": [
    {
      "confidence": 60,
      "evidence_json": {
        "call_count": 3,
        "examples": [
          {
            "opcode": "CALL",
            "pc": 109,
            "returndata_checked": null,
            "target_expression_category": "computed",
            "value_expression_category": "computed"
          },
          {
            "opcode": "CALL",
            "pc": 172,
            "returndata_checked": null,
            "target_expression_category": "computed",
            "value_expression_category": "computed"
          },
          {
            "opcode": "CALL",
            "pc": 274,
            "returndata_checked": null,
            "target_expression_category": "computed",
            "value_expression_category": "computed"
          }
        ],
        "guards_detected": [],
        "untrusted_call_count": 3
      },
      "normalized_json": {
        "sink": "CALL"
      },
      "severity": "high",
      "title": "Untrusted CALL target/value reachable",
      "validated": true,
      "validation_json": {
        "attempts": 1,
        "call_targets": [
          "0x0000000000000000000000000000000000000001",
          "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4"
        ],
        "classification": "target_varies",
        "confirmed": true,
        "errors": 0,
        "matched_probe": null,
        "sink": "CALL",
        "status": "confirmed",
        "target_varies": true,
        "trace_id": "0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a",
        "trace_mode": "callTracer"
      }
    },
    {
      "confidence": 55,
      "evidence_json": {
        "eth_value_calls": 3,
        "examples": [
          {
            "opcode": "CALL",
            "pc": 109,
            "returndata_checked": null,
            "target_expression_category": "computed",
            "value_expression_category": "computed"
          },
          {
            "opcode": "CALL",
            "pc": 172,
            "returndata_checked": null,
            "target_expression_category": "computed",
            "value_expression_category": "computed"
          },
          {
            "opcode": "CALL",
            "pc": 274,
            "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": [
          "0x0000000000000000000000000000000000000001",
          "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4"
        ],
        "classification": "target_varies",
        "confirmed": true,
        "errors": 0,
        "matched_probe": null,
        "sink": "CALL",
        "status": "confirmed",
        "target_varies": true,
        "trace_id": "0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a",
        "trace_mode": "callTracer"
      }
    }
  ],
  "heuristics_summary": {
    "create2_count": 0,
    "delegatecall_count": 0,
    "flags": [],
    "selfdestruct_count": 0
  }
}
exec
/bin/bash -lc 'cat codex-output-schema.json' in /tmp/codex-33obuzoq
 succeeded in 0ms:
{"type": "object", "additionalProperties": false, "required": ["no_findings", "summary", "findings"], "properties": {"no_findings": {"type": "boolean"}, "summary": {"type": "string"}, "findings": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["severity", "category", "title", "evidence", "locations", "exploit_scenario", "recommendation"], "properties": {"severity": {"type": "string", "enum": ["info", "low", "medium", "high", "critical"]}, "category": {"type": "string", "enum": ["access_control", "reentrancy", "math", "oracle", "upgradeability", "auth", "other"]}, "title": {"type": "string"}, "exploit_scenario": {"type": "string"}, "recommendation": {"type": "string"}, "evidence": {"type": "string"}, "locations": {"type": "array", "items": {"type": "string"}}}}}}}
exec
/bin/bash -lc "node -e \"const b='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056\"; console.log(b.length/2);\"" in /tmp/codex-33obuzoq
 exited 2 in 0ms:
/bin/bash: -c: line 1: syntax error near unexpected token `b.length/2'
/bin/bash: -c: line 1: `node -e "const b='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056"; console.log(b.length/2);"'

exec
/bin/bash -lc "python3 - <<'PY'
code='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056'
ops={i:name for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND'])}
ops.update({0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',0x1a:'BYTE',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',0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',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 i in range(1,33): ops[0x5f+i]=f'PUSH{i}'
for i in range(1,17): ops[0x7f+i]=f'DUP{i}'
for i in range(1,17): ops[0x8f+i]=f'SWAP{i}'
for i in range(0,5): ops[0xa0+i]=f'LOG{i}'
b=bytes.fromhex(code)
pc=0
while pc < len(b):
    op=b[pc]
    name=ops.get(op,hex(op))
    if name.startswith('PUSH'):
        n=int(name[4:])
        data=b[pc+1:pc+1+n]
        print(f'{pc:04x}: {name} 0x{data.hex()}')
        pc+=1+n
    else:
        print(f'{pc:04x}: {name}')
        pc+=1
PY" in /tmp/codex-33obuzoq
 succeeded in 0ms:
0000: PUSH1 0x60
0002: PUSH1 0x40
0004: MSTORE
0005: CALLDATASIZE
0006: ISZERO
0007: PUSH2 0x000b
000a: JUMPI
000b: JUMPDEST
000c: PUSH2 0x011d
000f: PUSH1 0x00
0011: PUSH1 0x00
0013: PUSH1 0x02
0015: PUSH1 0x00
0017: POP
0018: SLOAD
0019: GT
001a: DUP1
001b: ISZERO
001c: PUSH2 0x002e
001f: JUMPI
0020: POP
0021: PUSH3 0x015180
0025: PUSH1 0x02
0027: PUSH1 0x00
0029: POP
002a: SLOAD
002b: TIMESTAMP
002c: SUB
002d: GT
002e: JUMPDEST
002f: ISZERO
0030: PUSH2 0x00ed
0033: JUMPI
0034: DUP1
0035: SLOAD
0036: CALLVALUE
0037: PUSH1 0x01
0039: PUSH1 0xa0
003b: PUSH1 0x02
003d: EXP
003e: SUB
003f: ADDRESS
0040: DUP2
0041: AND
0042: BALANCE
0043: SWAP2
0044: SWAP1
0045: SWAP2
0046: SUB
0047: SWAP3
0048: SWAP2
0049: AND
004a: EQ
004b: PUSH2 0x0073
004e: JUMPI
004f: PUSH1 0x00
0051: DUP1
0052: SLOAD
0053: PUSH1 0x01
0055: PUSH1 0xa0
0057: PUSH1 0x02
0059: EXP
005a: SUB
005b: AND
005c: SWAP1
005d: PUSH1 0x0a
005f: PUSH1 0x06
0061: DUP5
0062: MUL
0063: DIV
0064: PUSH1 0x60
0066: DUP3
0067: DUP2
0068: DUP2
0069: DUP2
006a: DUP6
006b: DUP9
006c: DUP4
006d: CALL
006e: POP
006f: POP
0070: POP
0071: POP
0072: POP
0073: JUMPDEST
0074: PUSH1 0x01
0076: SLOAD
0077: PUSH1 0x01
0079: PUSH1 0xa0
007b: PUSH1 0x02
007d: EXP
007e: SUB
007f: AND
0080: PUSH1 0x00
0082: EQ
0083: PUSH2 0x00b2
0086: JUMPI
0087: PUSH1 0x01
0089: SLOAD
008a: PUSH1 0x40
008c: MLOAD
008d: PUSH1 0x01
008f: PUSH1 0xa0
0091: PUSH1 0x02
0093: EXP
0094: SUB
0095: SWAP2
0096: SWAP1
0097: SWAP2
0098: AND
0099: SWAP1
009a: PUSH1 0x00
009c: SWAP1
009d: PUSH1 0x0a
009f: PUSH1 0x02
00a1: DUP6
00a2: MUL
00a3: DIV
00a4: SWAP1
00a5: DUP3
00a6: DUP2
00a7: DUP2
00a8: DUP2
00a9: DUP6
00aa: DUP9
00ab: DUP4
00ac: CALL
00ad: POP
00ae: POP
00af: POP
00b0: POP
00b1: POP
00b2: JUMPDEST
00b3: PUSH1 0x00
00b5: PUSH1 0x02
00b7: DUP2
00b8: SWAP1
00b9: SSTORE
00ba: DUP1
00bb: SLOAD
00bc: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00d1: NOT
00d2: SWAP1
00d3: DUP2
00d4: AND
00d5: SWAP1
00d6: SWAP2
00d7: SSTORE
00d8: PUSH1 0x01
00da: DUP1
00db: SLOAD
00dc: SWAP1
00dd: SWAP2
00de: AND
00df: SWAP1
00e0: SSTORE
00e1: PUSH8 0x0de0b6b3a7640000
00ea: PUSH1 0x03
00ec: SSTORE
00ed: JUMPDEST
00ee: PUSH1 0x03
00f0: SLOAD
00f1: CALLVALUE
00f2: LT
00f3: ISZERO
00f4: PUSH2 0x011f
00f7: JUMPI
00f8: PUSH1 0x40
00fa: MLOAD
00fb: CALLER
00fc: PUSH1 0x01
00fe: PUSH1 0xa0
0100: PUSH1 0x02
0102: EXP
0103: SUB
0104: AND
0105: SWAP1
0106: PUSH1 0x00
0108: SWAP1
0109: CALLVALUE
010a: SWAP1
010b: DUP3
010c: DUP2
010d: DUP2
010e: DUP2
010f: DUP6
0110: DUP9
0111: DUP4
0112: CALL
0113: SWAP4
0114: POP
0115: POP
0116: POP
0117: POP
0118: POP
0119: PUSH2 0x015c
011c: JUMP
011d: JUMPDEST
011e: STOP
011f: JUMPDEST
0120: PUSH1 0x00
0122: DUP1
0123: SLOAD
0124: PUSH1 0x01
0126: DUP1
0127: SLOAD
0128: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
013d: NOT
013e: SWAP1
013f: DUP2
0140: AND
0141: PUSH1 0x01
0143: PUSH1 0xa0
0145: PUSH1 0x02
0147: EXP
0148: SUB
0149: DUP5
014a: AND
014b: OR
014c: SWAP1
014d: SWAP2
014e: SSTORE
014f: AND
0150: CALLER
0151: OR
0152: SWAP1
0153: SSTORE
0154: CALLVALUE
0155: PUSH1 0x03
0157: SSTORE
0158: TIMESTAMP
0159: PUSH1 0x02
015b: SSTORE
015c: JUMPDEST
015d: POP
015e: JUMP

exec
/bin/bash -lc "python3 - <<'PY'
mods=['eth','ethereum','eth_utils','eth_abi','web3']
for m in mods:
  try:
    __import__(m)
    print(m,'ok')
  except Exception as e:
    print(m,'no')
PY" in /tmp/codex-33obuzoq
 succeeded in 639ms:
eth no
ethereum no
eth_utils ok
eth_abi ok
web3 ok

exec
/bin/bash -lc "python3 - <<'PY'
mods=['eth_tester','evmdasm','pyevmasm','ethereum_input_decoder']
for m in mods:
  try:
    __import__(m)
    print(m,'ok')
  except Exception:
    print(m,'no')
PY" in /tmp/codex-33obuzoq
 succeeded in 0ms:
eth_tester no
evmdasm no
pyevmasm no
ethereum_input_decoder no

exec
/bin/bash -lc "python3 - <<'PY'
code='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056'
ops={}
base=['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']
for i,n in enumerate(base): ops[i]=n
ops.update({0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',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',0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',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 i in range(1,33): ops[0x5f+i]=f'PUSH{i}'
for i in range(1,17): ops[0x7f+i]=f'DUP{i}'
for i in range(1,17): ops[0x8f+i]=f'SWAP{i}'
for i in range(0,5): ops[0xa0+i]=f'LOG{i}'
b=bytes.fromhex(code)
inst=[]
pc=0
while pc<len(b):
    op=b[pc]; name=ops.get(op,hex(op)); arg=None
    if name.startswith('PUSH'):
        n=int(name[4:]); arg='0x'+b[pc+1:pc+1+n].hex(); inst.append((pc,name,arg)); pc+=1+n
    else:
        inst.append((pc,name,None)); pc+=1
pc_to_i={pc:i for i,(pc,_,_) in enumerate(inst)}

def run(start_pc, stop_pcs=None, stack=None):
    if stack is None: stack=[]
    i=pc_to_i[start_pc]
    while i < len(inst):
        pc,name,arg=inst[i]
        print(f'{pc:04x} {name} {arg or \"\"} stack={stack}')
        if stop_pcs and pc in stop_pcs: break
        if name.startswith('PUSH'):
            stack.append(arg)
        elif name.startswith('DUP'):
            n=int(name[3:]); stack.append(stack[-n])
        elif name.startswith('SWAP'):
            n=int(name[4:]); stack[-1],stack[-1-n]=stack[-1-n],stack[-1]
        elif name=='POP':
            stack.pop()
        elif name=='SLOAD':
            k=stack.pop(); stack.append(f'SLOAD[{k}]')
        elif name=='SSTORE':
            k=stack.pop(); v=stack.pop(); print('   SSTORE',k,'=',v)
        elif name in ('ADD','SUB','MUL','DIV','EXP','AND','OR','XOR','EQ','LT','GT'):
            a=stack.pop(); b=stack.pop(); stack.append(f'({b} {name} {a})')
        elif name in ('ISZERO','NOT','BALANCE'):
            a=stack.pop(); stack.append(f'{name}({a})')
        elif name in ('ADDRESS','CALLER','CALLVALUE','TIMESTAMP','CALLDATASIZE','GAS'):
            stack.append(name)
        elif name=='MLOAD':
            off=stack.pop(); stack.append(f'MLOAD[{off}]')
        elif name=='MSTORE':
            off=stack.pop(); val=stack.pop(); print('   MSTORE',off,'=',val)
        elif name=='JUMPI':
            dest=stack.pop(); cond=stack.pop(); print('   JUMPI to',dest,'if',cond)
            break
        elif name=='JUMP':
            dest=stack.pop(); print('   JUMP to',dest); break
        elif name=='CALL':
            gas=stack.pop(); to=stack.pop(); value=stack.pop(); ino=stack.pop(); ins=stack.pop(); outo=stack.pop(); outs=stack.pop(); stack.append(f'CALL({to},value={value},gas={gas},in={ino}/{ins},out={outo}/{outs})')
        elif name=='JUMPDEST' or name=='STOP':
            pass
        else:
            print('unhandled',name); break
        i+=1
    print('final stack',stack)

print('--- start to first branch ---')
run(0)
print('--- at 0x34 ---')
run(0x34, stack=['RET'])
print('--- at 0x74 ---')
run(0x74, stack=['RET'])
print('--- at 0xee then jump path? ---')
run(0xee, stack=['RET'])
print('--- at 0x11f ---')
run(0x11f, stack=['RET','NEWADDR'])
PY" in /tmp/codex-33obuzoq
 succeeded in 0ms:
--- start to first branch ---
0000 PUSH1 0x60 stack=[]
0002 PUSH1 0x40 stack=['0x60']
0004 MSTORE  stack=['0x60', '0x40']
   MSTORE 0x40 = 0x60
0005 CALLDATASIZE  stack=[]
0006 ISZERO  stack=['CALLDATASIZE']
0007 PUSH2 0x000b stack=['ISZERO(CALLDATASIZE)']
000a JUMPI  stack=['ISZERO(CALLDATASIZE)', '0x000b']
   JUMPI to 0x000b if ISZERO(CALLDATASIZE)
final stack []
--- at 0x34 ---
0034 DUP1  stack=['RET']
0035 SLOAD  stack=['RET', 'RET']
0036 CALLVALUE  stack=['RET', 'SLOAD[RET]']
0037 PUSH1 0x01 stack=['RET', 'SLOAD[RET]', 'CALLVALUE']
0039 PUSH1 0xa0 stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '0x01']
003b PUSH1 0x02 stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '0x01', '0xa0']
003d EXP  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '0x01', '0xa0', '0x02']
003e SUB  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '0x01', '(0xa0 EXP 0x02)']
003f ADDRESS  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))']
0040 DUP2  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))', 'ADDRESS']
0041 AND  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))', 'ADDRESS', '(0x01 SUB (0xa0 EXP 0x02))']
0042 BALANCE  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))', '(ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))']
0043 SWAP2  stack=['RET', 'SLOAD[RET]', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))', 'BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02))))']
0044 SWAP1  stack=['RET', 'SLOAD[RET]', 'BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02))))', '(0x01 SUB (0xa0 EXP 0x02))', 'CALLVALUE']
0045 SWAP2  stack=['RET', 'SLOAD[RET]', 'BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02))))', 'CALLVALUE', '(0x01 SUB (0xa0 EXP 0x02))']
0046 SUB  stack=['RET', 'SLOAD[RET]', '(0x01 SUB (0xa0 EXP 0x02))', 'CALLVALUE', 'BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02))))']
0047 SWAP3  stack=['RET', 'SLOAD[RET]', '(0x01 SUB (0xa0 EXP 0x02))', '(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))']
0048 SWAP2  stack=['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))', 'SLOAD[RET]', '(0x01 SUB (0xa0 EXP 0x02))', 'RET']
0049 AND  stack=['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))', 'RET', '(0x01 SUB (0xa0 EXP 0x02))', 'SLOAD[RET]']
004a EQ  stack=['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))', 'RET', '((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[RET])']
004b PUSH2 0x0073 stack=['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))', '(RET EQ ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[RET]))']
004e JUMPI  stack=['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))', '(RET EQ ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[RET]))', '0x0073']
   JUMPI to 0x0073 if (RET EQ ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[RET]))
final stack ['(CALLVALUE SUB BALANCE((ADDRESS AND (0x01 SUB (0xa0 EXP 0x02)))))']
--- at 0x74 ---
0074 PUSH1 0x01 stack=['RET']
0076 SLOAD  stack=['RET', '0x01']
0077 PUSH1 0x01 stack=['RET', 'SLOAD[0x01]']
0079 PUSH1 0xa0 stack=['RET', 'SLOAD[0x01]', '0x01']
007b PUSH1 0x02 stack=['RET', 'SLOAD[0x01]', '0x01', '0xa0']
007d EXP  stack=['RET', 'SLOAD[0x01]', '0x01', '0xa0', '0x02']
007e SUB  stack=['RET', 'SLOAD[0x01]', '0x01', '(0xa0 EXP 0x02)']
007f AND  stack=['RET', 'SLOAD[0x01]', '(0x01 SUB (0xa0 EXP 0x02))']
0080 PUSH1 0x00 stack=['RET', '(SLOAD[0x01] AND (0x01 SUB (0xa0 EXP 0x02)))']
0082 EQ  stack=['RET', '(SLOAD[0x01] AND (0x01 SUB (0xa0 EXP 0x02)))', '0x00']
0083 PUSH2 0x00b2 stack=['RET', '((SLOAD[0x01] AND (0x01 SUB (0xa0 EXP 0x02))) EQ 0x00)']
0086 JUMPI  stack=['RET', '((SLOAD[0x01] AND (0x01 SUB (0xa0 EXP 0x02))) EQ 0x00)', '0x00b2']
   JUMPI to 0x00b2 if ((SLOAD[0x01] AND (0x01 SUB (0xa0 EXP 0x02))) EQ 0x00)
final stack ['RET']
--- at 0xee then jump path? ---
00ee PUSH1 0x03 stack=['RET']
00f0 SLOAD  stack=['RET', '0x03']
00f1 CALLVALUE  stack=['RET', 'SLOAD[0x03]']
00f2 LT  stack=['RET', 'SLOAD[0x03]', 'CALLVALUE']
00f3 ISZERO  stack=['RET', '(SLOAD[0x03] LT CALLVALUE)']
00f4 PUSH2 0x011f stack=['RET', 'ISZERO((SLOAD[0x03] LT CALLVALUE))']
00f7 JUMPI  stack=['RET', 'ISZERO((SLOAD[0x03] LT CALLVALUE))', '0x011f']
   JUMPI to 0x011f if ISZERO((SLOAD[0x03] LT CALLVALUE))
final stack ['RET']
--- at 0x11f ---
011f JUMPDEST  stack=['RET', 'NEWADDR']
0120 PUSH1 0x00 stack=['RET', 'NEWADDR']
0122 DUP1  stack=['RET', 'NEWADDR', '0x00']
0123 SLOAD  stack=['RET', 'NEWADDR', '0x00', '0x00']
0124 PUSH1 0x01 stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]']
0126 DUP1  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01']
0127 SLOAD  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', '0x01']
0128 PUSH20 0xffffffffffffffffffffffffffffffffffffffff stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'SLOAD[0x01]']
013d NOT  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'SLOAD[0x01]', '0xffffffffffffffffffffffffffffffffffffffff']
013e SWAP1  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'SLOAD[0x01]', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)']
013f DUP2  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', 'SLOAD[0x01]']
0140 AND  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', 'SLOAD[0x01]', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)']
0141 PUSH1 0x01 stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))']
0143 PUSH1 0xa0 stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '0x01']
0145 PUSH1 0x02 stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '0x01', '0xa0']
0147 EXP  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '0x01', '0xa0', '0x02']
0148 SUB  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '0x01', '(0xa0 EXP 0x02)']
0149 DUP5  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '(0x01 SUB (0xa0 EXP 0x02))']
014a AND  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '(0x01 SUB (0xa0 EXP 0x02))', 'SLOAD[0x00]']
014b OR  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '(SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', '((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[0x00])']
014c SWAP1  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '((SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[0x00]))']
014d SWAP2  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', '0x01', '((SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[0x00]))', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)']
014e SSTORE  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)', '((SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[0x00]))', '0x01']
   SSTORE 0x01 = ((SLOAD[0x01] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR ((0x01 SUB (0xa0 EXP 0x02)) AND SLOAD[0x00]))
014f AND  stack=['RET', 'NEWADDR', '0x00', 'SLOAD[0x00]', 'NOT(0xffffffffffffffffffffffffffffffffffffffff)']
0150 CALLER  stack=['RET', 'NEWADDR', '0x00', '(SLOAD[0x00] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))']
0151 OR  stack=['RET', 'NEWADDR', '0x00', '(SLOAD[0x00] AND NOT(0xffffffffffffffffffffffffffffffffffffffff))', 'CALLER']
0152 SWAP1  stack=['RET', 'NEWADDR', '0x00', '((SLOAD[0x00] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR CALLER)']
0153 SSTORE  stack=['RET', 'NEWADDR', '((SLOAD[0x00] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR CALLER)', '0x00']
   SSTORE 0x00 = ((SLOAD[0x00] AND NOT(0xffffffffffffffffffffffffffffffffffffffff)) OR CALLER)
0154 CALLVALUE  stack=['RET', 'NEWADDR']
0155 PUSH1 0x03 stack=['RET', 'NEWADDR', 'CALLVALUE']
0157 SSTORE  stack=['RET', 'NEWADDR', 'CALLVALUE', '0x03']
   SSTORE 0x03 = CALLVALUE
0158 TIMESTAMP  stack=['RET', 'NEWADDR']
0159 PUSH1 0x02 stack=['RET', 'NEWADDR', 'TIMESTAMP']
015b SSTORE  stack=['RET', 'NEWADDR', 'TIMESTAMP', '0x02']
   SSTORE 0x02 = TIMESTAMP
015c JUMPDEST  stack=['RET', 'NEWADDR']
015d POP  stack=['RET', 'NEWADDR']
015e JUMP  stack=['RET']
   JUMP to RET
final stack []

exec
/bin/bash -lc "python3 - <<'PY'
# symbolic path to inspect stack entering 0xed and 0x34/0x74
code='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056'
ops={}
base=['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']
for i,n in enumerate(base): ops[i]=n
ops.update({0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',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',0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',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 i in range(1,33): ops[0x5f+i]=f'PUSH{i}'
for i in range(1,17): ops[0x7f+i]=f'DUP{i}'
for i in range(1,17): ops[0x8f+i]=f'SWAP{i}'
for i in range(0,5): ops[0xa0+i]=f'LOG{i}'
b=bytes.fromhex(code)
inst=[]
pc=0
while pc<len(b):
    op=b[pc]; name=ops.get(op,hex(op)); arg=None
    if name.startswith('PUSH'):
        n=int(name[4:]); arg='0x'+b[pc+1:pc+1+n].hex(); inst.append((pc,name,arg)); pc+=1+n
    else:
        inst.append((pc,name,None)); pc+=1
pc_to_i={pc:i for i,(pc,_,_) in enumerate(inst)}


def step(i,stack):
    pc,name,arg=inst[i]
    if name.startswith('PUSH'): stack.append(arg); return i+1
    if name.startswith('DUP'): n=int(name[3:]); stack.append(stack[-n]); return i+1
    if name.startswith('SWAP'): n=int(name[4:]); stack[-1],stack[-1-n]=stack[-1-n],stack[-1]; return i+1
    if name=='POP': stack.pop(); return i+1
    if name=='SLOAD': k=stack.pop(); stack.append(f'SLOAD[{k}]'); return i+1
    if name=='SSTORE': k=stack.pop(); v=stack.pop(); print(f'{pc:04x} SSTORE {k}={v}'); return i+1
    if name in ('ADD','SUB','MUL','DIV','EXP','AND','OR','XOR','EQ','LT','GT'): a=stack.pop(); b=stack.pop(); stack.append(f'({b} {name} {a})'); return i+1
    if name in ('ISZERO','NOT','BALANCE'): a=stack.pop(); stack.append(f'{name}({a})'); return i+1
    if name in ('ADDRESS','CALLER','CALLVALUE','TIMESTAMP','CALLDATASIZE','GAS'): stack.append(name); return i+1
    if name=='MLOAD': off=stack.pop(); stack.append(f'MLOAD[{off}]'); return i+1
    if name=='MSTORE': off=stack.pop(); val=stack.pop(); return i+1
    if name=='JUMPI': dest=stack.pop(); cond=stack.pop(); print(f'{pc:04x} JUMPI {dest} if {cond} stack_after={stack}'); return ('JUMPI',dest,cond)
    if name=='JUMP': dest=stack.pop(); print(f'{pc:04x} JUMP {dest} stack_after={stack}'); return ('JUMP',dest)
    if name=='CALL': gas=stack.pop(); to=stack.pop(); value=stack.pop(); ino=stack.pop(); ins=stack.pop(); outo=stack.pop(); outs=stack.pop(); stack.append(f'CALL({to},value={value},gas={gas},in={ino}/{ins},out={outo}/{outs})'); print(f'{pc:04x} CALL to={to} value={value} stack_after={stack}'); return i+1
    return i+1

# simulate from 0x0b to 0x33 then take jump to 0xed
stack=[]
i=pc_to_i[0x0b]
while True:
    pc,name,arg=inst[i]
    print(f'{pc:04x} {name} {arg or \"\"} stack={stack}')
    r=step(i,stack)
    if isinstance(r,tuple):
        print('branch tuple',r)
        break
    i=r
print('stack before branching',stack)
# continue as if jumped to 0xed
print('enter 0xed stack',stack)
PY" in /tmp/codex-33obuzoq
 succeeded in 0ms:
000b JUMPDEST  stack=[]
000c PUSH2 0x011d stack=[]
000f PUSH1 0x00 stack=['0x011d']
0011 PUSH1 0x00 stack=['0x011d', '0x00']
0013 PUSH1 0x02 stack=['0x011d', '0x00', '0x00']
0015 PUSH1 0x00 stack=['0x011d', '0x00', '0x00', '0x02']
0017 POP  stack=['0x011d', '0x00', '0x00', '0x02', '0x00']
0018 SLOAD  stack=['0x011d', '0x00', '0x00', '0x02']
0019 GT  stack=['0x011d', '0x00', '0x00', 'SLOAD[0x02]']
001a DUP1  stack=['0x011d', '0x00', '(0x00 GT SLOAD[0x02])']
001b ISZERO  stack=['0x011d', '0x00', '(0x00 GT SLOAD[0x02])', '(0x00 GT SLOAD[0x02])']
001c PUSH2 0x002e stack=['0x011d', '0x00', '(0x00 GT SLOAD[0x02])', 'ISZERO((0x00 GT SLOAD[0x02]))']
001f JUMPI  stack=['0x011d', '0x00', '(0x00 GT SLOAD[0x02])', 'ISZERO((0x00 GT SLOAD[0x02]))', '0x002e']
001f JUMPI 0x002e if ISZERO((0x00 GT SLOAD[0x02])) stack_after=['0x011d', '0x00', '(0x00 GT SLOAD[0x02])']
branch tuple ('JUMPI', '0x002e', 'ISZERO((0x00 GT SLOAD[0x02]))')
stack before branching ['0x011d', '0x00', '(0x00 GT SLOAD[0x02])']
enter 0xed stack ['0x011d', '0x00', '(0x00 GT SLOAD[0x02])']

exec
/bin/bash -lc "python3 - <<'PY'
# simulate path from 0x0b to 0x34 taking payout branch fallthroughs
code='6060604052361561000b575b61011d6000600060026000505411801561002e5750620151806002600050544203115b156100ed57805434600160a060020a033081163191909103929116146100735760008054600160a060020a031690600a6006840204606082818181858883f150505050505b600154600160a060020a03166000146100b257600154604051600160a060020a039190911690600090600a60028502049082818181858883f150505050505b60006002819055805473ffffffffffffffffffffffffffffffffffffffff19908116909155600180549091169055670de0b6b3a76400006003555b60035434101561011f5760405133600160a060020a031690600090349082818181858883f193505050505061015c565b005b600080546001805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155163317905534600355426002555b5056'
ops={}
base=['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']
for i,n in enumerate(base): ops[i]=n
ops.update({0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',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',0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',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 i in range(1,33): ops[0x5f+i]=f'PUSH{i}'
for i in range(1,17): ops[0x7f+i]=f'DUP{i}'
for i in range(1,17): ops[0x8f+i]=f'SWAP{i}'
b=bytes.fromhex(code)
inst=[]; pc=0
while pc<len(b):
    op=b[pc]; name=ops.get(op,hex(op)); arg=None
    if name.startswith('PUSH'):
        n=int(name[4:]); arg='0x'+b[pc+1:pc+1+n].hex(); inst.append((pc,name,arg)); pc+=1+n
    else:
        inst.append((pc,name,None)); pc+=1
pc_to_i={pc:i for i,(pc,_,_) in enumerate(inst)}
stack=[]
i=pc_to_i[0x0b]
branch_choices={0x1f:'fallthrough',0x33:'fallthrough',0x4e:'jump'}
while True:
    pc,name,arg=inst[i]
    print(f'{pc:04x} {name} {arg or \"\"} stack={stack}')
    if name.startswith('PUSH'): stack.append(arg); i+=1; continue
    if name.startswith('DUP'): stack.append(stack[-int(name[3:])]); i+=1; continue
    if name.startswith('SWAP'):
        n=int(name[4:]); stack[-1],stack[-1-n]=stack[-1-n],stack[-1]; i+=1; continue
    if name=='POP': stack.pop(); i+=1; continue
    if name=='SLOAD': k=stack.pop(); stack.append(f'SLOAD[{k}]'); i+=1; continue
    if name in ('ADD','SUB','MUL','DIV','EXP','AND','OR','XOR','EQ','LT','GT'):
        a=stack.pop(); b=stack.pop(); stack.append(f'({b} {name} {a})'); i+=1; continue
    if name in ('ISZERO','NOT','BALANCE'):
        a=stack.pop(); stack.append(f'{name}({a})'); i+=1; continue
    if name in ('ADDRESS','CALLER','CALLVALUE','TIMESTAMP','CALLDATASIZE','GAS'): stack.append(name); i+=1; continue
    if name=='JUMPI':
        dest=stack.pop(); cond=stack.pop(); print('  JUMPI',dest,'if',cond,'remaining',stack)
        choice=branch_choices.get(pc,'fallthrough')
        if choice=='jump': i=pc_to_i[int(dest,16)]
        else: i+=1
        continue
    if name=='JUMPDEST': i+=1; continue
    if pc==0x73:
        print('entry stack at 0x73',stack); break
    if name=='CALL': print('CALL stack',stack); break
PY" in /tmp/codex-33obuzoq
2026-04-04T22:03:40.379817Z ERROR codex_core::tools::router: error=write_stdin failed: stdin is closed for this session; rerun exec_command with tty=true to keep stdin open
codex
{"no_findings":false,"summary":"Fallback-only bytecode with three ETH-bearing CALL sites, no detected auth guards, and state cleanup that occurs after external payouts. The strongest issue is reentrancy risk on the payout path; a secondary issue is unchecked CALL success on all outbound transfers.","findings":[{"severity":"high","category":"reentrancy","title":"External payout calls occur before round state is cleared","exploit_scenario":"A prior participant can register a contract as one of the payout recipients via the fallback update path. When the expiry/payout branch executes, the contract performs value-bearing CALLs to stored recipient addresses at pc 0x6d and pc 0xac before clearing slot 2 and before wiping the recipient fields in slots 0/1. A malicious recipient can reenter the fallback during the first payout while the old state is still live, potentially triggering the payout logic repeatedly and draining more of the contract balance than intended. This is based on bytecode-only reasoning, so the exact branch condition is inferred rather than source-confirmed.","recommendation":"Apply checks-effects-interactions: fully clear or checkpoint the active round before any external CALL, or add an explicit reentrancy guard around the fallback payout path. If payouts must remain external, store owed balances and let recipients withdraw in a separate pull-payment flow.","evidence":"The artifact reports no detected guards (`auth.guards=[]`) and three CALL sites. The first two CALLs are at pc 109/0x6d and 172/0xac, both with `returndata_checked: null` and computed targets/values. State-reset writes happen only afterward at pc 185/0xb9 (slot 2), pc 215-216/0xd7-0xd8 and pc 224/0xe0 (slot 0/1 cleanup), and pc 236/0xec (slot 3 reset). Recipient addresses appear user-influenced because the fallback update routine writes slots 1 and 0 at pc 334/0x14e and pc 339/0x153. Detector finding `Untrusted CALL target/value reachable` is validated/confirmed.","locations":["pc:0x6d","pc:0xac","pc:0xb9","pc:0xd7","pc:0xe0","pc:0xec","pc:0x14e","pc:0x153"]},{"severity":"medium","category":"other","title":"Outbound ETH transfers ignore CALL success and continue","exploit_scenario":"If a payout recipient or refund recipient is a contract that reverts or otherwise makes the CALL fail, this bytecode does not check the returned success flag before continuing. On the payout path, the contract appears to proceed into state cleanup and round reset even when one or both payouts fail, which can skip owed payments and strand funds in the contract. On the refund-like path at pc 0x112, a failed ETH send to `CALLER` is also ignored.","recommendation":"Check the boolean result of each CALL and revert on failure, or convert the design to pull-based withdrawals so failed recipients cannot silently break accounting. If non-reverting behavior is required, record failed payouts as claimable balances instead of discarding the failure.","evidence":"All three callsites in the bundle have `returndata_checked: null`: pc 109/0x6d, 172/0xac, and 274/0x112. In the bytecode, each CALL is followed by POPs rather than a conditional revert path, so success is discarded. After the payout CALLs, execution continues into storage writes that clear/reset state (pc 0xb9, 0xd7, 0xe0, 0xec), which creates accounting risk if the transfer did not actually occur. Detector finding `ETH value transfer possible` is validated/confirmed.","locations":["pc:0x6d","pc:0xac","pc:0x112","pc:0xb9","pc:0xd7","pc:0xe0","pc:0xec"]}]}
tokens used
80,855
Metadata
{
    "codex": {
        "ran_at": "2026-04-04T22:04:05.323372+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "bytecode",
        "bytecode_length": 704,
        "bytecode_truncated": false,
        "capability_graph_present": true,
        "analysis_artifact_present": true
    },
    "summary": "Fallback-only bytecode with three ETH-bearing CALL sites, no detected auth guards, and state cleanup that occurs after external payouts. The strongest issue is reentrancy risk on the payout path; a secondary issue is unchecked CALL success on all outbound transfers.",
    "raw_final": {
        "summary": "Fallback-only bytecode with three ETH-bearing CALL sites, no detected auth guards, and state cleanup that occurs after external payouts. The strongest issue is reentrancy risk on the payout path; a secondary issue is unchecked CALL success on all outbound transfers.",
        "findings": [
            {
                "title": "External payout calls occur before round state is cleared",
                "category": "reentrancy",
                "evidence": "The artifact reports no detected guards (`auth.guards=[]`) and three CALL sites. The first two CALLs are at pc 109/0x6d and 172/0xac, both with `returndata_checked: null` and computed targets/values. State-reset writes happen only afterward at pc 185/0xb9 (slot 2), pc 215-216/0xd7-0xd8 and pc 224/0xe0 (slot 0/1 cleanup), and pc 236/0xec (slot 3 reset). Recipient addresses appear user-influenced because the fallback update routine writes slots 1 and 0 at pc 334/0x14e and pc 339/0x153. Detector finding `Untrusted CALL target/value reachable` is validated/confirmed.",
                "severity": "high",
                "locations": [
                    "pc:0x6d",
                    "pc:0xac",
                    "pc:0xb9",
                    "pc:0xd7",
                    "pc:0xe0",
                    "pc:0xec",
                    "pc:0x14e",
                    "pc:0x153"
                ],
                "recommendation": "Apply checks-effects-interactions: fully clear or checkpoint the active round before any external CALL, or add an explicit reentrancy guard around the fallback payout path. If payouts must remain external, store owed balances and let recipients withdraw in a separate pull-payment flow.",
                "exploit_scenario": "A prior participant can register a contract as one of the payout recipients via the fallback update path. When the expiry/payout branch executes, the contract performs value-bearing CALLs to stored recipient addresses at pc 0x6d and pc 0xac before clearing slot 2 and before wiping the recipient fields in slots 0/1. A malicious recipient can reenter the fallback during the first payout while the old state is still live, potentially triggering the payout logic repeatedly and draining more of the contract balance than intended. This is based on bytecode-only reasoning, so the exact branch condition is inferred rather than source-confirmed."
            },
            {
                "title": "Outbound ETH transfers ignore CALL success and continue",
                "category": "other",
                "evidence": "All three callsites in the bundle have `returndata_checked: null`: pc 109/0x6d, 172/0xac, and 274/0x112. In the bytecode, each CALL is followed by POPs rather than a conditional revert path, so success is discarded. After the payout CALLs, execution continues into storage writes that clear/reset state (pc 0xb9, 0xd7, 0xe0, 0xec), which creates accounting risk if the transfer did not actually occur. Detector finding `ETH value transfer possible` is validated/confirmed.",
                "severity": "medium",
                "locations": [
                    "pc:0x6d",
                    "pc:0xac",
                    "pc:0x112",
                    "pc:0xb9",
                    "pc:0xd7",
                    "pc:0xe0",
                    "pc:0xec"
                ],
                "recommendation": "Check the boolean result of each CALL and revert on failure, or convert the design to pull-based withdrawals so failed recipients cannot silently break accounting. If non-reverting behavior is required, record failed payouts as claimable balances instead of discarding the failure.",
                "exploit_scenario": "If a payout recipient or refund recipient is a contract that reverts or otherwise makes the CALL fail, this bytecode does not check the returned success flag before continuing. On the payout path, the contract appears to proceed into state cleanup and round reset even when one or both payouts fail, which can skip owed payments and strand funds in the contract. On the refund-like path at pc 0x112, a failed ETH send to `CALLER` is also ignored."
            }
        ],
        "no_findings": false
    },
    "no_findings": false,
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
0
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
3
EXT*/BALANCE
1
Total opcodes
236
Flags
No heuristic flags raised.
View cast disassembly output
00000000: PUSH1 0x60
00000002: PUSH1 0x40
00000004: MSTORE
00000005: CALLDATASIZE
00000006: ISZERO
00000007: PUSH2 0x000b
0000000a: JUMPI
0000000b: JUMPDEST
0000000c: PUSH2 0x011d
0000000f: PUSH1 0x00
00000011: PUSH1 0x00
00000013: PUSH1 0x02
00000015: PUSH1 0x00
00000017: POP
00000018: SLOAD
00000019: GT
0000001a: DUP1
0000001b: ISZERO
0000001c: PUSH2 0x002e
0000001f: JUMPI
00000020: POP
00000021: PUSH3 0x015180
00000025: PUSH1 0x02
00000027: PUSH1 0x00
00000029: POP
0000002a: SLOAD
0000002b: TIMESTAMP
0000002c: SUB
0000002d: GT
0000002e: JUMPDEST
0000002f: ISZERO
00000030: PUSH2 0x00ed
00000033: JUMPI
00000034: DUP1
00000035: SLOAD
00000036: CALLVALUE
00000037: PUSH1 0x01
00000039: PUSH1 0xa0
0000003b: PUSH1 0x02
0000003d: EXP
0000003e: SUB
0000003f: ADDRESS
00000040: DUP2
00000041: AND
00000042: BALANCE
00000043: SWAP2
00000044: SWAP1
00000045: SWAP2
00000046: SUB
00000047: SWAP3
00000048: SWAP2
00000049: AND
0000004a: EQ
0000004b: PUSH2 0x0073
0000004e: JUMPI
0000004f: PUSH1 0x00
00000051: DUP1
00000052: SLOAD
00000053: PUSH1 0x01
00000055: PUSH1 0xa0
00000057: PUSH1 0x02
00000059: EXP
0000005a: SUB
0000005b: AND
0000005c: SWAP1
0000005d: PUSH1 0x0a
0000005f: PUSH1 0x06
00000061: DUP5
00000062: MUL
00000063: DIV
00000064: PUSH1 0x60
00000066: DUP3
00000067: DUP2
00000068: DUP2
00000069: DUP2
0000006a: DUP6
0000006b: DUP9
0000006c: DUP4
0000006d: CALL
0000006e: POP
0000006f: POP
00000070: POP
00000071: POP
00000072: POP
00000073: JUMPDEST
00000074: PUSH1 0x01
00000076: SLOAD
00000077: PUSH1 0x01
00000079: PUSH1 0xa0
0000007b: PUSH1 0x02
0000007d: EXP
0000007e: SUB
0000007f: AND
00000080: PUSH1 0x00
00000082: EQ
00000083: PUSH2 0x00b2
00000086: JUMPI
00000087: PUSH1 0x01
00000089: SLOAD
0000008a: PUSH1 0x40
0000008c: MLOAD
0000008d: PUSH1 0x01
0000008f: PUSH1 0xa0
00000091: PUSH1 0x02
00000093: EXP
00000094: SUB
00000095: SWAP2
00000096: SWAP1
00000097: SWAP2
00000098: AND
00000099: SWAP1
0000009a: PUSH1 0x00
0000009c: SWAP1
0000009d: PUSH1 0x0a
0000009f: PUSH1 0x02
000000a1: DUP6
000000a2: MUL
000000a3: DIV
000000a4: SWAP1
000000a5: DUP3
000000a6: DUP2
000000a7: DUP2
000000a8: DUP2
000000a9: DUP6
000000aa: DUP9
000000ab: DUP4
000000ac: CALL
000000ad: POP
000000ae: POP
000000af: POP
000000b0: POP
000000b1: POP
000000b2: JUMPDEST
000000b3: PUSH1 0x00
000000b5: PUSH1 0x02
000000b7: DUP2
000000b8: SWAP1
000000b9: SSTORE
000000ba: DUP1
000000bb: SLOAD
000000bc: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000000d1: NOT
000000d2: SWAP1
000000d3: DUP2
000000d4: AND
000000d5: SWAP1
000000d6: SWAP2
000000d7: SSTORE
000000d8: PUSH1 0x01
000000da: DUP1
000000db: SLOAD
000000dc: SWAP1
000000dd: SWAP2
000000de: AND
000000df: SWAP1
000000e0: SSTORE
000000e1: PUSH8 0x0de0b6b3a7640000
000000ea: PUSH1 0x03
000000ec: SSTORE
000000ed: JUMPDEST
000000ee: PUSH1 0x03
000000f0: SLOAD
000000f1: CALLVALUE
000000f2: LT
000000f3: ISZERO
000000f4: PUSH2 0x011f
000000f7: JUMPI
000000f8: PUSH1 0x40
000000fa: MLOAD
000000fb: CALLER
000000fc: PUSH1 0x01
000000fe: PUSH1 0xa0
00000100: PUSH1 0x02
00000102: EXP
00000103: SUB
00000104: AND
00000105: SWAP1
00000106: PUSH1 0x00
00000108: SWAP1
00000109: CALLVALUE
0000010a: SWAP1
0000010b: DUP3
0000010c: DUP2
0000010d: DUP2
0000010e: DUP2
0000010f: DUP6
00000110: DUP9
00000111: DUP4
00000112: CALL
00000113: SWAP4
00000114: POP
00000115: POP
00000116: POP
00000117: POP
00000118: POP
00000119: PUSH2 0x015c
0000011c: JUMP
0000011d: JUMPDEST
0000011e: STOP
0000011f: JUMPDEST
00000120: PUSH1 0x00
00000122: DUP1
00000123: SLOAD
00000124: PUSH1 0x01
00000126: DUP1
00000127: SLOAD
00000128: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000013d: NOT
0000013e: SWAP1
0000013f: DUP2
00000140: AND
00000141: PUSH1 0x01
00000143: PUSH1 0xa0
00000145: PUSH1 0x02
00000147: EXP
00000148: SUB
00000149: DUP5
0000014a: AND
0000014b: OR
0000014c: SWAP1
0000014d: SWAP2
0000014e: SSTORE
0000014f: AND
00000150: CALLER
00000151: OR
00000152: SWAP1
00000153: SSTORE
00000154: CALLVALUE
00000155: PUSH1 0x03
00000157: SSTORE
00000158: TIMESTAMP
00000159: PUSH1 0x02
0000015b: SSTORE
0000015c: JUMPDEST
0000015d: POP
0000015e: 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: 0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a
call_targets: 0x0000000000000000000000000000000000000001, 0xfc67bd301a4c698b461e5e9f26eab60d230b77a4
target_varies: yes
classification: target_varies
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "confirmed",
    "attempts": 1,
    "trace_id": "0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a",
    "confirmed": true,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x0000000000000000000000000000000000000001",
        "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4"
    ],
    "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": "0x",
            "selector": "fallback",
            "calldata_variants": [
                "0x"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 109,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 172,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 274,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "call_count": 3,
    "guards_detected": [],
    "untrusted_call_count": 3
}
high other detector ETH value transfer possible 55 yes yes
view
trace_id: 0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a
call_targets: 0x0000000000000000000000000000000000000001, 0xfc67bd301a4c698b461e5e9f26eab60d230b77a4
target_varies: yes
classification: target_varies
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "confirmed",
    "attempts": 1,
    "trace_id": "0xcec881074db4fc85d9d1a11d2957b033a783502954d378179861cb6ee186543a",
    "confirmed": true,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x0000000000000000000000000000000000000001",
        "0xfc67bd301a4c698b461e5e9f26eab60d230b77a4"
    ],
    "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": "0x",
            "selector": "fallback",
            "calldata_variants": [
                "0x"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 109,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 172,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 274,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "eth_value_calls": 3,
    "guards_detected": []
}
high reentrancy codex External payout calls occur before round state is cleared 85 no
view
evidence_json
{
    "evidence": "The artifact reports no detected guards (`auth.guards=[]`) and three CALL sites. The first two CALLs are at pc 109/0x6d and 172/0xac, both with `returndata_checked: null` and computed targets/values. State-reset writes happen only afterward at pc 185/0xb9 (slot 2), pc 215-216/0xd7-0xd8 and pc 224/0xe0 (slot 0/1 cleanup), and pc 236/0xec (slot 3 reset). Recipient addresses appear user-influenced because the fallback update routine writes slots 1 and 0 at pc 334/0x14e and pc 339/0x153. Detector finding `Untrusted CALL target/value reachable` is validated/confirmed.",
    "locations": [
        "pc:0x6d",
        "pc:0xac",
        "pc:0xb9",
        "pc:0xd7",
        "pc:0xe0",
        "pc:0xec",
        "pc:0x14e",
        "pc:0x153"
    ],
    "recommendation": "Apply checks-effects-interactions: fully clear or checkpoint the active round before any external CALL, or add an explicit reentrancy guard around the fallback payout path. If payouts must remain external, store owed balances and let recipients withdraw in a separate pull-payment flow.",
    "exploit_scenario": "A prior participant can register a contract as one of the payout recipients via the fallback update path. When the expiry/payout branch executes, the contract performs value-bearing CALLs to stored recipient addresses at pc 0x6d and pc 0xac before clearing slot 2 and before wiping the recipient fields in slots 0/1. A malicious recipient can reenter the fallback during the first payout while the old state is still live, potentially triggering the payout logic repeatedly and draining more of the contract balance than intended. This is based on bytecode-only reasoning, so the exact branch condition is inferred rather than source-confirmed."
}
medium other codex Outbound ETH transfers ignore CALL success and continue 75 no
view
evidence_json
{
    "evidence": "All three callsites in the bundle have `returndata_checked: null`: pc 109/0x6d, 172/0xac, and 274/0x112. In the bytecode, each CALL is followed by POPs rather than a conditional revert path, so success is discarded. After the payout CALLs, execution continues into storage writes that clear/reset state (pc 0xb9, 0xd7, 0xe0, 0xec), which creates accounting risk if the transfer did not actually occur. Detector finding `ETH value transfer possible` is validated/confirmed.",
    "locations": [
        "pc:0x6d",
        "pc:0xac",
        "pc:0x112",
        "pc:0xb9",
        "pc:0xd7",
        "pc:0xe0",
        "pc:0xec"
    ],
    "recommendation": "Check the boolean result of each CALL and revert on failure, or convert the design to pull-based withdrawals so failed recipients cannot silently break accounting. If non-reverting behavior is required, record failed payouts as claimable balances instead of discarding the failure.",
    "exploit_scenario": "If a payout recipient or refund recipient is a contract that reverts or otherwise makes the CALL fail, this bytecode does not check the returned success flag before continuing. On the payout path, the contract appears to proceed into state cleanup and round reset even when one or both payouts fail, which can skip owed payments and strand funds in the contract. On the refund-like path at pc 0x112, a failed ETH send to `CALLER` is also ignored."
}