019b3836-220c-72ad-99e1-0bffbd1dfee3
Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?
| 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 |
No slither job recorded yet.
{"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"]}]}
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
{
"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
}
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
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.
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| high | other | detector | Untrusted CALL target/value reachable | 60 | yes | yes |
viewtrace_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 |
viewtrace_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 | — |
viewevidence_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 | — |
viewevidence_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."
}
|