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

Analysis Run

019bb50b-e183-704b-ae79-33466bc022ff

complete
Chain ID
1
Address
Block Number
Created
Tue, Jan 13, 2026 1:50 AM
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
0
Validated
0
Source
Bytecode only
Review Backing
Present
Best current signal
Untrusted CALL target/value reachable
crit 0 high 0 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
40401 artifact.fetch complete 1 / 3 3 months ago
40402 proxy.resolve complete 1 / 3 3 months ago
40403 tool.cast_disasm complete 1 / 3 3 months ago
40404 analysis.bundle complete 1 / 3 3 months ago
40405 capability.graph complete 1 / 3 3 months ago
40406 detector.run complete 1 / 3 3 months ago
40407 validation.fork complete 1 / 3 3 months ago
40497 report.consolidate complete 1 / 6 3 months ago

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: no not_proxy
Implementation:
Verified Source: no
Proxy evidence
{
    "status": "not_proxy"
}

Slither

tool.slither

No slither job recorded yet.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
1
No findings?
no
Summary
Detected fixed-stipend ETH transfers via low-level CALLs; this pattern can brick withdrawals for contract recipients or after gas schedule changes.
View stdout
{"no_findings":false,"summary":"Detected fixed-stipend ETH transfers via low-level CALLs; this pattern can brick withdrawals for contract recipients or after gas schedule changes.","findings":[{"severity":"low","category":"other","title":"Fixed 2300-gas ETH transfers can make withdrawals revert for contract recipients","exploit_scenario":"If the beneficiary/owner address is a contract with a receive/fallback that needs more than the 2300 gas stipend (or gas costs increase), the CALL will fail and revert the withdrawal, potentially leaving ETH locked. This is inferred from bytecode and could be a false positive if an alternate withdrawal path exists.","recommendation":"Use `call{value: amount}(\"\")` with full gas forwarding and protect with checks-effects-interactions or a reentrancy guard, or add an alternative withdrawal path / configurable gas stipend.","evidence":"Bytecode shows `PUSH2 0x08fc` (2300) immediately before low-level CALLs that transfer value; CALL opcodes at pc 0x3dd and 0x8af.","locations":["pc:0x3dd","pc:0x8af","pc:0x3ae","pc:0x897"]}]}
View stderr
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-qbgy8ng7
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019bb52f-8f6a-76c2-81c5-683ab0c4207b
--------
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.
mcp startup: no servers

thinking
**Reading BYTECODE_BUNDLE.json**
exec
/bin/bash -lc ls in /tmp/codex-qbgy8ng7 succeeded in 6ms:
BYTECODE_BUNDLE.json
codex-output-schema.json
exec
/bin/bash -lc 'cat BYTECODE_BUNDLE.json' in /tmp/codex-qbgy8ng7 succeeded in 32ms:
{
  "analysis_artifact": {
    "address": "0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5",
    "artifact_hash": "0x0130a0dc383ef1075821d32fc78764b732fafc238a74e0573b26e65e3b97b1bf",
    "artifact_json": {
      "auth": {
        "guards": [
          {
            "pc": 719,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
          },
          {
            "pc": 1102,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
          },
          {
            "pc": 1407,
            "type": "msg_sender_eq_const",

thinking
**Analyzing bytecode for call patterns and access controls**

I'm parsing bytecode to understand CALL and CALLCODE usage, noting legacy delegatecall patterns and unusual guards that restrict access to a hardcoded max address. This might represent an uninitialized admin, which isn't a direct vulnerability but could lead to stuck privileges. I’m focusing on identifying ownership functions, external calls that may allow reentrancy, and scanning for proxy upgrade patterns like EIP-1967, planning to search the storage slots in the evidence JSON using ripgrep next.
exec
/bin/bash -lc 'rg -n "storage" BYTECODE_BUNDLE.json' in /tmp/codex-qbgy8ng7 succeeded in 37ms:
2361:          "storage": {
2471:          "storage": {
2581:          "storage": {
2691:          "storage": {
2801:          "storage": {
2911:          "storage": {
3021:          "storage": {
3131:          "storage": {
3241:          "storage": {
3351:          "storage": {
3450:      "storage": {

thinking
**Checking storage-related sections**
exec
/bin/bash -lc "sed -n '3440,3520p' BYTECODE_BUNDLE.json" in /tmp/codex-qbgy8ng7 succeeded in 8ms:
      ],
      "sinks": {
        "call": 3,
        "create": 0,
        "create2": 0,
        "delegatecall": 0,
        "selfdestruct": 0,
        "staticcall": 0,
        "upgrade_slot_write_suspected": false
      },
      "storage": {
        "keccak_count": 6,
        "reads": 19,
        "slots": [
          {
            "op": "SLOAD",
            "pc": 667,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
          },
          {
exec
/bin/bash -lc "sed -n '3520,3600p' BYTECODE_BUNDLE.json" in /tmp/codex-qbgy8ng7 succeeded in 6ms:
            "op": "SLOAD",
            "pc": 2007,
            "slot": "0x0000000000000000000000000000000000000000000000000000000000000014"
          }
        ],
        "writes": 5
      },
      "version": "analysis_artifact_v1"
    },
    "block_number": null,
    "chain_id": 1,
    "codehash": "0x6c3033a50581715bc0c0994bfc99a9f8ed08266255de4fad01c0abfa2d784765",
    "created_at": "2026-01-13T01:50:51.000000Z",
    "id": 1118,
    "updated_at": "2026-01-13T01:50:51.000000Z",
    "version": "analysis_artifact_v1"
  },
  "analysis_run": {
    "address": "0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5",
    "block_number": null,

thinking
**Analyzing runtime bytecode for calls and ownership**

I'm examining the runtime bytecode to identify ownership patterns and call instructions, focusing on slots storing owner and status. I'm investigating whether CALL instructions target the contract itself, suggesting internal ETH transfers, and planning to parse the bytecode around CALL opcodes using Python tooling despite a limited environment.
exec
/bin/bash -lc "python - <<'PY'
import json, binascii
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json','r') as f:
    data=json.load(f)
bytecode=data['artifact']['runtime_bytecode']['full']
if bytecode.startswith('0x'):
    bytecode=bytecode[2:]
code=bytes.fromhex(bytecode)
# find CALL (0xf1) and CALLCODE (0xf2)
for opc,name in [(0xf1,'CALL'),(0xf2,'CALLCODE')]:
    idxs=[i for i,b in enumerate(code) if b==opc]
    print(name,idxs)
    for i in idxs:
        start=max(0,i-20)
        end=min(len(code), i+20)
        snippet=code[start:end]
        print(i, snippet.hex())
PY" in /tmp/codex-qbgy8ng7 succeeded in 26ms:
CALL [747, 989, 2223]
747 ffffffffffffffffffffffffffff161415156102f157600080fd5b600060028111156102fe57fe5b
989 9081150290604051600060405180830381858888f1935050505015156103ed57600080fd5b565b60
2223 9081150290604051600060405180830381858888f1935050505015156108bf57600080fd5b8173ff
CALLCODE [122, 1596, 2373]
122 93fb14610172578063cb13cddb146101a9578063f2fde38b146101f6578063f340fa011461022f57
1596 ffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06040
2373 65627a7a72305820932a3e029fc610e90985300bf26f653d2ece3258ea9eb306c2b0831c4f6fe796

thinking
**Planning precise EVM opcode detection**

I’m figuring out that raw searches for opcodes like 0xf2 can produce false positives since these bytes might appear inside PUSH data. To handle this, I want to build a minimal EVM disassembler that skips PUSH instructions properly so I can accurately identify real CALL and CALLCODE opcode positions rather than mistaken metadata or data bytes. This will help me verify the true locations of these opcodes in the bytecode.
exec
/bin/bash -lc "python - <<'PY'
import json
from collections import defaultdict
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
code=bytes.fromhex(code[2:])
ops=defaultdict(list)
i=0
while i < len(code):
    op=code[i]
    ops[op].append(i)
    if 0x60 <= op <= 0x7f:  # PUSH1..PUSH32
        n=op-0x5f
        i += 1+n
        continue
    i += 1

print('CALL', ops[0xf1])
print('CALLCODE', ops[0xf2])
PY" in /tmp/codex-qbgy8ng7 succeeded in 58ms:
CALL [989, 2223]
CALLCODE [2373]

thinking
**Analyzing CALL and CALLCODE opcodes**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
code=bytes.fromhex(code[2:])
# simple disassembler
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'}

# build mapping pc->(op,imm)
ins=[]

i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        name=f'PUSH{n}'
        ins.append((i,name,imm))
        i += 1+n
        continue
    name=opnames.get(op, f'OP_{op:02x}')
    ins.append((i,name,None))
    i += 1

# function to print window around pc
pc_targets=[989,2223,2373]
for target in pc_targets:
    print('\\n=== window around',target,'===')
    # find index in ins
    idx=None
    for j,(pc,name,imm) in enumerate(ins):
        if pc==target:
            idx=j
            break
    if idx is None:
        # find nearest
        for j,(pc,_,_) in enumerate(ins):
            if pc>target:
                idx=j
                break
    start=max(0,idx-20)
    end=min(len(ins), idx+20)
    for pc,name,imm in ins[start:end]:
        if imm is not None:
            print(f'{pc:04d}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 34ms:

=== window around 989 ===
0946: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0967: AND
0968: BALANCE
0969: OP_90
0970: OP_81
0971: ISZERO
0972: MUL
0973: OP_90
0974: PUSH1 0x40
0976: MLOAD
0977: PUSH1 0x00
0979: PUSH1 0x40
0981: MLOAD
0982: OP_80
0983: OP_83
0984: SUB
0985: OP_81
0986: OP_85

thinking
**Clarifying callcode presence in metadata**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])
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'}
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
        continue
    ins.append((i,opnames.get(op, f'OP_{op:02x}'),None))
    i += 1

# print window around 900-1020
for pc,name,imm in ins:
    if 880 <= pc <= 1020:
        if imm is not None:
            print(f'{pc:04d}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 27ms:
0880: OP_80
0881: OP_91
0882: SUB
0883: OP_90
0884: OP_a1
0885: PUSH1 0x02
0887: PUSH1 0x00
0889: OP_90
0890: SLOAD
0891: OP_90
0892: PUSH2 0x0100
0895: EXP
0896: OP_90
0897: DIV
0898: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0919: AND
0920: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0941: AND
0942: PUSH2 0x08fc
0945: ADDRESS

thinking
**Analyzing CALL and storage address extraction**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])
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'}
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
        continue
    ins.append((i,opnames.get(op, f'OP_{op:02x}'),None))
    i += 1

for pc,name,imm in ins:
    if 2140 <= pc <= 2265:
        if imm is not None:
            print(f'{pc:04d}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 29ms:
2157: AND
2158: OP_81
2159: MSTORE
2160: PUSH1 0x20
2162: ADD
2163: OP_90
2164: OP_81
2165: MSTORE
2166: PUSH1 0x20
2168: ADD
2169: PUSH1 0x00
2171: SHA3
2172: OP_81
2173: OP_90
2174: SSTORE
2175: POP
2176: OP_81
2177: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
2198: AND
2199: PUSH2 0x08fc

thinking
**Requesting earlier code lines**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])
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'}
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
        continue
    ins.append((i,opnames.get(op, f'OP_{op:02x}'),None))
    i += 1

for pc,name,imm in ins:
    if 2040 <= pc <= 2145:
        if imm is not None:
            print(f'{pc:04d}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 30ms:
2040: JUMPDEST
2041: PUSH1 0x01
2043: PUSH1 0x00
2045: OP_83
2046: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
2067: AND
2068: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
2089: AND
2090: OP_81
2091: MSTORE
2092: PUSH1 0x20
2094: ADD
2095: OP_90
2096: OP_81
2097: MSTORE
2098: PUSH1 0x20
2100: ADD
2101: PUSH1 0x00
2103: SHA3
2104: SLOAD

thinking
**Analyzing runtime bytecode structure**
exec
/bin/bash -lc 'which evm' in /tmp/codex-qbgy8ng7 exited 1 in 28ms:


thinking
**Analyzing potential reentrancy risks**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])
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'}
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
        continue
    ins.append((i,opnames.get(op, f'OP_{op:02x}'),None))
    i += 1

for pc,name,imm in ins:
    if 700 <= pc <= 900:
        if imm is not None:
            print(f'{pc:04d}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 29ms:
0718: AND
0719: CALLER
0720: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0741: AND
0742: EQ
0743: ISZERO
0744: ISZERO
0745: PUSH2 0x02f1
0748: JUMPI
0749: PUSH1 0x00
0751: OP_80
0752: REVERT
0753: JUMPDEST
0754: PUSH1 0x00
0756: PUSH1 0x02
0758: OP_81
0759: GT
0760: ISZERO
0761: PUSH2 0x02fe
0764: JUMPI


thinking
**Analyzing contract call and guard logic**
thinking
**Investigating withdrawal function logic and access checks**

I’m carefully thinking about how the withdraw function takes an address parameter and handles deposits and withdrawals, noting owner-only deposit rights versus public withdrawal. I’m considering how funds are sent strictly to the specified address, so callers can trigger withdrawals for others but cannot steal funds. Also, I’m examining gas stipend usage in calls (2300 gas), its implications on reentrancy and DoS, and planning a symbolic execution to validate call arguments and stack behavior for better understanding.
exec
/bin/bash -lc "python - <<'PY'
import json
from collections import defaultdict
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

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'}

# disassemble to list
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i, f'PUSH{n}', imm))
        i += 1+n
    else:
        ins.append((i, opnames.get(op,f'OP_{op:02x}'), None))
        i += 1
# map pc to index
pc_to_idx={pc:idx for idx,(pc,_,_) in enumerate(ins)}

# simple symbolic stack
class Sym(str):
    pass

def popn(stack,n):
    if len(stack)<n:
        raise Exception('stack underflow')
    vals=stack[-n:]
    del stack[-n:]
    return vals

def push(stack, val):
    stack.append(val)

# interpreter from pc 662 until CALL at 989
pc=662
stack=[]
visited=set()
steps=0
while True:
    if pc not in pc_to_idx:
        print('pc not found',pc);break
    idx=pc_to_idx[pc]
    op,imm = ins[idx][1], ins[idx][2]
    # print each step
    # print(f'{pc}: {op} {imm.hex() if imm else \"\"} stack size {len(stack)}')
    steps+=1
    if steps>2000:
        print('too many');break
    # handle ops
    if op.startswith('PUSH'):
        push(stack, f'0x{imm.hex()}')
        pc = ins[idx+1][0]
        continue
    if op=='JUMPDEST':
        pc = ins[idx+1][0]
        continue
    if op=='POP':
        popn(stack,1)
        pc = ins[idx+1][0]
        continue
    if op=='CALLER':
        push(stack,'CALLER')
        pc = ins[idx+1][0]
        continue
    if op=='ADDRESS':
        push(stack,'ADDRESS')
        pc = ins[idx+1][0]
        continue
    if op=='BALANCE':
        addr=popn(stack,1)[0]
        push(stack,f'BALANCE({addr})')
        pc = ins[idx+1][0]
        continue
    if op=='SLOAD':
        slot=popn(stack,1)[0]
        push(stack,f'SLOAD({slot})')
        pc = ins[idx+1][0]
        continue
    if op=='SSTORE':
        popn(stack,2)
        pc = ins[idx+1][0]
        continue
    if op in ('MLOAD','MSTORE','MSTORE8','CALLDATASIZE','CALLDATALOAD','CALLDATACOPY','CODECOPY','RETURNDATACOPY','RETURNDATASIZE','MSIZE'):
        # simplify
        if op in ('MSTORE','MSTORE8','CALLDATACOPY','CODECOPY','RETURNDATACOPY'):
            # consume args
            if op=='MSTORE': popn(stack,2)
            elif op=='MSTORE8': popn(stack,2)
            elif op=='CALLDATACOPY': popn(stack,3)
            elif op=='CODECOPY': popn(stack,3)
            elif op=='RETURNDATACOPY': popn(stack,3)
            pc = ins[idx+1][0]
            continue
        if op=='MLOAD':
            popn(stack,1)
            push(stack,'MLOAD')
            pc = ins[idx+1][0]
            continue
        if op=='CALLDATASIZE':
            push(stack,'CALLDATASIZE')
            pc = ins[idx+1][0]
            continue
        if op=='CALLDATALOAD':
            popn(stack,1)
            push(stack,'CALLDATALOAD')
            pc = ins[idx+1][0]
            continue
        if op=='RETURNDATASIZE':
            push(stack,'RETURNDATASIZE')
            pc = ins[idx+1][0]
            continue
        if op=='MSIZE':
            push(stack,'MSIZE')
            pc = ins[idx+1][0]
            continue
    # arithmetic/logic
    if op in ('ADD','SUB','MUL','DIV','AND','OR','XOR','EQ','LT','GT','ISZERO','EXP'):
        if op=='ISZERO':
            a=popn(stack,1)[0]
            push(stack,f'ISZERO({a})')
        else:
            b,a=popn(stack,2)
            push(stack,f'({a} {op} {b})')
        pc = ins[idx+1][0]
        continue
    if op.startswith('OP_'):
        # treat SWAP/DUP via hex? But opnames mapping didn't include DUP/SWAP. Need handle.
        # We'll decode dup/swap by opcode value from pc.
        opcode=code[pc]
        if 0x80 <= opcode <= 0x8f: # DUP1..DUP16
            n=opcode-0x7f
            if len(stack)<n:
                raise Exception('dup underflow')
            push(stack, stack[-n])
            pc = ins[idx+1][0]
            continue
        if 0x90 <= opcode <= 0x9f: # SWAP1..SWAP16
            n=opcode-0x8f
            if len(stack)<n+1:
                raise Exception('swap underflow')
            stack[-1], stack[-1-n] = stack[-1-n], stack[-1]
            pc = ins[idx+1][0]
            continue
    if op=='JUMPI':
        # pop dest and cond
        dest,cond=popn(stack,2)
        # assume jump taken
        try:
            pc=int(dest,16) if dest.startswith('0x') else int(dest)
        except Exception:
            # if dest symbolic, break
            print('symbolic dest',dest);break
        continue
    if op=='JUMP':
        dest=popn(stack,1)[0]
        try:
            pc=int(dest,16) if dest.startswith('0x') else int(dest)
        except Exception:
            print('symbolic jump dest',dest);break
        continue
    if op=='REVERT':
        break
    if op=='CALL':
        # print stack snapshot for call args
        print('CALL at',pc,'stack (top last):')
        for i,v in enumerate(stack[-10:]):
            print(i-len(stack), v)
        break
    # default: advance
    pc = ins[idx+1][0]

PY" in /tmp/codex-qbgy8ng7 succeeded in 29ms:
symbolic dest ISZERO(ISZERO(((0xffffffffffffffffffffffffffffffffffffffff AND CALLER) EQ (0xffffffffffffffffffffffffffffffffffffffff AND (0xffffffffffffffffffffffffffffffffffffffff AND (SLOAD(0x00) DIV (0x0100 EXP 0x00)))))))

thinking
**Analyzing JUMPI stack order confusion**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

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'}

# disassemble
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
    else:
        ins.append((i,opnames.get(op,f'OP_{op:02x}'),None))
        i += 1
pc_to_idx={pc:idx for idx,(pc,_,_) in enumerate(ins)}

# helper

def popn(stack,n):
    vals=stack[-n:]
    del stack[-n:]
    return vals

def run(start_pc, target_pc):
    pc=start_pc
    stack=[]
    steps=0
    while True:
        idx=pc_to_idx.get(pc)
        if idx is None:
            print('pc not found',pc);break
        op,imm=ins[idx][1], ins[idx][2]
        steps+=1
        if steps>3000:
            print('too many steps');break
        if op.startswith('PUSH'):
            stack.append(f'0x{imm.hex()}')
            pc=ins[idx+1][0]; continue
        if op=='JUMPDEST':
            pc=ins[idx+1][0]; continue
        if op=='POP':
            popn(stack,1); pc=ins[idx+1][0]; continue
        if op=='CALLER':
            stack.append('CALLER'); pc=ins[idx+1][0]; continue
        if op=='ADDRESS':
            stack.append('ADDRESS'); pc=ins[idx+1][0]; continue
        if op=='BALANCE':
            addr=popn(stack,1)[0]; stack.append(f'BALANCE({addr})'); pc=ins[idx+1][0]; continue
        if op=='SLOAD':
            slot=popn(stack,1)[0]; stack.append(f'SLOAD({slot})'); pc=ins[idx+1][0]; continue
        if op=='SSTORE':
            popn(stack,2); pc=ins[idx+1][0]; continue
        if op in ('MSTORE','MSTORE8','CALLDATACOPY','CODECOPY','RETURNDATACOPY'):
            if op=='MSTORE': popn(stack,2)
            elif op=='MSTORE8': popn(stack,2)
            elif op=='CALLDATACOPY': popn(stack,3)
            elif op=='CODECOPY': popn(stack,3)
            elif op=='RETURNDATACOPY': popn(stack,3)
            pc=ins[idx+1][0]; continue
        if op=='MLOAD':
            popn(stack,1); stack.append('MLOAD'); pc=ins[idx+1][0]; continue
        if op in ('CALLDATASIZE','CALLVALUE'):
            stack.append(op); pc=ins[idx+1][0]; continue
        if op=='CALLDATALOAD':
            popn(stack,1); stack.append('CALLDATALOAD'); pc=ins[idx+1][0]; continue
        if op=='RETURNDATASIZE':
            stack.append('RETURNDATASIZE'); pc=ins[idx+1][0]; continue
        if op=='SHA3':
            b,a=popn(stack,2); stack.append(f'SHA3({a},{b})'); pc=ins[idx+1][0]; continue
        if op in ('ADD','SUB','MUL','DIV','AND','OR','XOR','EQ','LT','GT','ISZERO','EXP'):
            if op=='ISZERO':
                a=popn(stack,1)[0]; stack.append(f'ISZERO({a})')
            else:
                b,a=popn(stack,2); stack.append(f'({a} {op} {b})')
            pc=ins[idx+1][0]; continue
        # dup/swap
        opcode=code[pc]
        if 0x80 <= opcode <= 0x8f:
            n=opcode-0x7f
            stack.append(stack[-n])
            pc=ins[idx+1][0]; continue
        if 0x90 <= opcode <= 0x9f:
            n=opcode-0x8f
            stack[-1], stack[-1-n] = stack[-1-n], stack[-1]
            pc=ins[idx+1][0]; continue
        if op=='JUMPI':
            dest_cond=popn(stack,2)
            dest=dest_cond[1]  # top is dest
            # jump taken
            try:
                pc=int(dest,16)
            except Exception:
                print('symbolic dest',dest); break
            continue
        if op=='JUMP':
            dest=popn(stack,1)[0]
            try:
                pc=int(dest,16)
            except Exception:
                print('symbolic dest',dest); break
            continue
        if op=='REVERT':
            print('revert'); break
        if op=='CALL':
            print('CALL at',pc)
            # print top 7 args
            args=stack[-7:]
            print('stack top 7 (bottom->top):', args)
            break
        # default
        pc=ins[idx+1][0]

run(662,989)
PY" in /tmp/codex-qbgy8ng7 succeeded in 35ms:
CALL at 989
stack top 7 (bottom->top): ['0x00', 'MLOAD', '(MLOAD SUB MLOAD)', 'MLOAD', 'BALANCE((0xffffffffffffffffffffffffffffffffffffffff AND ADDRESS))', '(0xffffffffffffffffffffffffffffffffffffffff AND (0xffffffffffffffffffffffffffffffffffffffff AND (SLOAD(0x02) DIV (0x0100 EXP 0x00))))', '(ISZERO(BALANCE((0xffffffffffffffffffffffffffffffffffffffff AND ADDRESS))) MUL 0x08fc)']

thinking
**Analyzing CALL argument stack and reentrancy risks**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

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'}

ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
    else:
        ins.append((i,opnames.get(op,f'OP_{op:02x}'),None))
        i += 1

for guard_pc in [1102,1407,1748]:
    print('\\n-- around',guard_pc,'--')
    for pc,name,imm in ins:
        if guard_pc-20 <= pc <= guard_pc+20:
            if imm is not None:
                print(f'{pc:04d}: {name} 0x{imm.hex()}')
            else:
                print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 45ms:

-- around 1102 --
1101: AND
1102: CALLER
1103: PUSH20 0xffffffffffffffffffffffffffffffffffffffff

-- around 1407 --
1406: AND
1407: CALLER
1408: PUSH20 0xffffffffffffffffffffffffffffffffffffffff

-- around 1748 --
1747: AND
1748: CALLER
1749: PUSH20 0xffffffffffffffffffffffffffffffffffffffff

thinking
**Summarizing contract call analysis and risks**

I'm working through the contract's CALL operations, especially low-level ETH transfers using a fixed 2300 gas stipend, which could cause denial-of-service if recipients are contracts needing more gas. I'm noting these transfers happen to computed addresses from storage slots with owner controls, so no clear vulnerability but some residual risk. I'll mention two low-severity findings: risk of stuck funds due to gas limit and potential reentrancy considerations, backing both with precise evidence from callsite locations and instruction patterns.
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

opnames={0x55:'SSTORE'}
# disassemble minimal
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        i += 1+n
    else:
        if op==0x55:
            ins.append(i)
        i += 1
print('SSTORE PCs:',ins)
PY" in /tmp/codex-qbgy8ng7 succeeded in 53ms:
SSTORE PCs: [839, 1223, 1687, 1982, 2174]

thinking
**Inspecting SSTORE instructions and surrounding code**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

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'}

ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
    else:
        ins.append((i,opnames.get(op,f'OP_{op:02x}'),None))
        i += 1

for target in [1223,1687,1982,2174,839]:
    print('\\n-- window around',target,'--')
    for pc,name,imm in ins:
        if target-12 <= pc <= target+12:
            if imm is not None:
                print(f'{pc:04d}: {name} 0x{imm.hex()}')
            else:
                print(f'{pc:04d}: {name}')
PY" in /tmp/codex-qbgy8ng7 succeeded in 47ms:

-- window around 1223 --
1211: OP_81
1212: GT
1213: ISZERO
1214: PUSH2 0x04c3
1217: JUMPI
1218: INVALID
1219: JUMPDEST
1220: MUL
1221: OR
1222: OP_90
1223: SSTORE
1224: POP
1225: PUSH32 0x599d8e5a83cffb867d051598c4d70e805d59802d8081c1c7d6dffc5b6aca2b89

-- window around 1687 --
1683: AND
1684: MUL
1685: OR

thinking
**Evaluating call arguments and gas constants**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

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'}

# disassemble
ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        ins.append((i,f'PUSH{n}',imm))
        i += 1+n
    else:
        ins.append((i,opnames.get(op,f'OP_{op:02x}'),None))
        i += 1
pc_to_idx={pc:idx for idx,(pc,_,_) in enumerate(ins)}

# interpreter similar to before

def popn(stack,n):
    vals=stack[-n:]
    del stack[-n:]
    return vals

pc=2040
stack=[]
steps=0
while True:
    idx=pc_to_idx.get(pc)
    if idx is None:
        print('pc not found',pc); break
    op,imm=ins[idx][1], ins[idx][2]
    steps+=1
    if steps>3000:
        print('too many steps'); break
    if op.startswith('PUSH'):
        stack.append(f'0x{imm.hex()}'); pc=ins[idx+1][0]; continue
    if op=='JUMPDEST':
        pc=ins[idx+1][0]; continue
    if op=='POP':
        popn(stack,1); pc=ins[idx+1][0]; continue
    if op=='CALLER':
        stack.append('CALLER'); pc=ins[idx+1][0]; continue
    if op=='ADDRESS':
        stack.append('ADDRESS'); pc=ins[idx+1][0]; continue
    if op=='BALANCE':
        addr=popn(stack,1)[0]; stack.append(f'BALANCE({addr})'); pc=ins[idx+1][0]; continue
    if op=='SLOAD':
        slot=popn(stack,1)[0]; stack.append(f'SLOAD({slot})'); pc=ins[idx+1][0]; continue
    if op=='SSTORE':
        popn(stack,2); pc=ins[idx+1][0]; continue
    if op in ('MSTORE','MSTORE8','CALLDATACOPY','CODECOPY','RETURNDATACOPY'):
        if op=='MSTORE': popn(stack,2)
        elif op=='MSTORE8': popn(stack,2)
        elif op=='CALLDATACOPY': popn(stack,3)
        elif op=='CODECOPY': popn(stack,3)
        elif op=='RETURNDATACOPY': popn(stack,3)
        pc=ins[idx+1][0]; continue
    if op=='MLOAD':
        popn(stack,1); stack.append('MLOAD'); pc=ins[idx+1][0]; continue
    if op in ('CALLDATASIZE','CALLVALUE'):
        stack.append(op); pc=ins[idx+1][0]; continue
    if op=='CALLDATALOAD':
        popn(stack,1); stack.append('CALLDATALOAD'); pc=ins[idx+1][0]; continue
    if op=='RETURNDATASIZE':
        stack.append('RETURNDATASIZE'); pc=ins[idx+1][0]; continue
    if op=='SHA3':
        b,a=popn(stack,2); stack.append(f'SHA3({a},{b})'); pc=ins[idx+1][0]; continue
    if op in ('ADD','SUB','MUL','DIV','AND','OR','XOR','EQ','LT','GT','ISZERO','EXP'):
        if op=='ISZERO':
            a=popn(stack,1)[0]; stack.append(f'ISZERO({a})')
        else:
            b,a=popn(stack,2); stack.append(f'({a} {op} {b})')
        pc=ins[idx+1][0]; continue
    opcode=code[pc]
    if 0x80 <= opcode <= 0x8f:
        n=opcode-0x7f; stack.append(stack[-n]); pc=ins[idx+1][0]; continue
    if 0x90 <= opcode <= 0x9f:
        n=opcode-0x8f; stack[-1], stack[-1-n] = stack[-1-n], stack[-1]; pc=ins[idx+1][0]; continue
    if op=='JUMPI':
        dest_cond=popn(stack,2)
        dest=dest_cond[1]
        try:
            pc=int(dest,16)
        except Exception:
            print('symbolic dest',dest); break
        continue
    if op=='JUMP':
        dest=popn(stack,1)[0]
        try:
            pc=int(dest,16)
        except Exception:
            print('symbolic dest',dest); break
        continue
    if op=='CALL':
        print('CALL at',pc)
        args=stack[-7:]
        print('stack top 7 (bottom->top):', args)
        break
    if op=='REVERT':
        print('revert'); break
    pc=ins[idx+1][0]
PY" in /tmp/codex-qbgy8ng7 exited 1 in 46ms:
Traceback (most recent call last):
  File "<stdin>", line 82, in <module>
IndexError: list index out of range

thinking
**Analyzing program counter references for calls**
exec
/bin/bash -lc "python - <<'PY'
import json
with open('/tmp/codex-qbgy8ng7/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=bytes.fromhex(data['artifact']['runtime_bytecode']['full'][2:])

ins=[]
i=0
while i < len(code):
    op=code[i]
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[i+1:i+1+n]
        if op==0x61 and imm==bytes.fromhex('08fc'):
            print('PUSH2 0x08fc at pc',i)
        i += 1+n
    else:
        i += 1
PY" in /tmp/codex-qbgy8ng7 succeeded in 29ms:
PUSH2 0x08fc at pc 942
PUSH2 0x08fc at pc 2199

thinking
**Composing vulnerability JSON report**
codex
{"no_findings":false,"summary":"Detected fixed-stipend ETH transfers via low-level CALLs; this pattern can brick withdrawals for contract recipients or after gas schedule changes.","findings":[{"severity":"low","category":"other","title":"Fixed 2300-gas ETH transfers can make withdrawals revert for contract recipients","exploit_scenario":"If the beneficiary/owner address is a contract with a receive/fallback that needs more than the 2300 gas stipend (or gas costs increase), the CALL will fail and revert the withdrawal, potentially leaving ETH locked. This is inferred from bytecode and could be a false positive if an alternate withdrawal path exists.","recommendation":"Use `call{value: amount}(\"\")` with full gas forwarding and protect with checks-effects-interactions or a reentrancy guard, or add an alternative withdrawal path / configurable gas stipend.","evidence":"Bytecode shows `PUSH2 0x08fc` (2300) immediately before low-level CALLs that transfer value; CALL opcodes at pc 0x3dd and 0x8af.","locations":["pc:0x3dd","pc:0x8af","pc:0x3ae","pc:0x897"]}]}
tokens used
99,309
Metadata
{
    "codex": {
        "ran_at": "2026-01-13T02:38:32.846096+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "bytecode",
        "bytecode_length": 4792,
        "bytecode_truncated": false,
        "capability_graph_present": true,
        "analysis_artifact_present": true
    },
    "summary": "Detected fixed-stipend ETH transfers via low-level CALLs; this pattern can brick withdrawals for contract recipients or after gas schedule changes.",
    "raw_final": {
        "summary": "Detected fixed-stipend ETH transfers via low-level CALLs; this pattern can brick withdrawals for contract recipients or after gas schedule changes.",
        "findings": [
            {
                "title": "Fixed 2300-gas ETH transfers can make withdrawals revert for contract recipients",
                "category": "other",
                "evidence": "Bytecode shows `PUSH2 0x08fc` (2300) immediately before low-level CALLs that transfer value; CALL opcodes at pc 0x3dd and 0x8af.",
                "severity": "low",
                "locations": [
                    "pc:0x3dd",
                    "pc:0x8af",
                    "pc:0x3ae",
                    "pc:0x897"
                ],
                "recommendation": "Use `call{value: amount}(\"\")` with full gas forwarding and protect with checks-effects-interactions or a reentrancy guard, or add an alternative withdrawal path / configurable gas stipend.",
                "exploit_scenario": "If the beneficiary/owner address is a contract with a receive/fallback that needs more than the 2300 gas stipend (or gas costs increase), the CALL will fail and revert the withdrawal, potentially leaving ETH locked. This is inferred from bytecode and could be a false positive if an alternate withdrawal path exists."
            }
        ],
        "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
1036
Flags
No heuristic flags raised.
View cast disassembly output
00000000: PUSH1 0x60
00000002: PUSH1 0x40
00000004: MSTORE
00000005: PUSH1 0x04
00000007: CALLDATASIZE
00000008: LT
00000009: PUSH2 0x0099
0000000c: JUMPI
0000000d: PUSH1 0x00
0000000f: CALLDATALOAD
00000010: PUSH29 0x0100000000000000000000000000000000000000000000000000000000
0000002e: SWAP1
0000002f: DIV
00000030: PUSH4 0xffffffff
00000035: AND
00000036: DUP1
00000037: PUSH4 0x43d726d6
0000003c: EQ
0000003d: PUSH2 0x009e
00000040: JUMPI
00000041: DUP1
00000042: PUSH4 0x521eb273
00000047: EQ
00000048: PUSH2 0x00b3
0000004b: JUMPI
0000004c: DUP1
0000004d: PUSH4 0x8c52dc41
00000052: EQ
00000053: PUSH2 0x0108
00000056: JUMPI
00000057: DUP1
00000058: PUSH4 0x8da5cb5b
0000005d: EQ
0000005e: PUSH2 0x011d
00000061: JUMPI
00000062: DUP1
00000063: PUSH4 0xc19d93fb
00000068: EQ
00000069: PUSH2 0x0172
0000006c: JUMPI
0000006d: DUP1
0000006e: PUSH4 0xcb13cddb
00000073: EQ
00000074: PUSH2 0x01a9
00000077: JUMPI
00000078: DUP1
00000079: PUSH4 0xf2fde38b
0000007e: EQ
0000007f: PUSH2 0x01f6
00000082: JUMPI
00000083: DUP1
00000084: PUSH4 0xf340fa01
00000089: EQ
0000008a: PUSH2 0x022f
0000008d: JUMPI
0000008e: DUP1
0000008f: PUSH4 0xfa89401a
00000094: EQ
00000095: PUSH2 0x025d
00000098: JUMPI
00000099: JUMPDEST
0000009a: PUSH1 0x00
0000009c: DUP1
0000009d: REVERT
0000009e: JUMPDEST
0000009f: CALLVALUE
000000a0: ISZERO
000000a1: PUSH2 0x00a9
000000a4: JUMPI
000000a5: PUSH1 0x00
000000a7: DUP1
000000a8: REVERT
000000a9: JUMPDEST
000000aa: PUSH2 0x00b1
000000ad: PUSH2 0x0296
000000b0: JUMP
000000b1: JUMPDEST
000000b2: STOP
000000b3: JUMPDEST
000000b4: CALLVALUE
000000b5: ISZERO
000000b6: PUSH2 0x00be
000000b9: JUMPI
000000ba: PUSH1 0x00
000000bc: DUP1
000000bd: REVERT
000000be: JUMPDEST
000000bf: PUSH2 0x00c6
000000c2: PUSH2 0x03ef
000000c5: JUMP
000000c6: JUMPDEST
000000c7: PUSH1 0x40
000000c9: MLOAD
000000ca: DUP1
000000cb: DUP3
000000cc: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000000e1: AND
000000e2: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000000f7: AND
000000f8: DUP2
000000f9: MSTORE
000000fa: PUSH1 0x20
000000fc: ADD
000000fd: SWAP2
000000fe: POP
000000ff: POP
00000100: PUSH1 0x40
00000102: MLOAD
00000103: DUP1
00000104: SWAP2
00000105: SUB
00000106: SWAP1
00000107: RETURN
00000108: JUMPDEST
00000109: CALLVALUE
0000010a: ISZERO
0000010b: PUSH2 0x0113
0000010e: JUMPI
0000010f: PUSH1 0x00
00000111: DUP1
00000112: REVERT
00000113: JUMPDEST
00000114: PUSH2 0x011b
00000117: PUSH2 0x0415
0000011a: JUMP
0000011b: JUMPDEST
0000011c: STOP
0000011d: JUMPDEST
0000011e: CALLVALUE
0000011f: ISZERO
00000120: PUSH2 0x0128
00000123: JUMPI
00000124: PUSH1 0x00
00000126: DUP1
00000127: REVERT
00000128: JUMPDEST
00000129: PUSH2 0x0130
0000012c: PUSH2 0x04f6
0000012f: JUMP
00000130: JUMPDEST
00000131: PUSH1 0x40
00000133: MLOAD
00000134: DUP1
00000135: DUP3
00000136: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000014b: AND
0000014c: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000161: AND
00000162: DUP2
00000163: MSTORE
00000164: PUSH1 0x20
00000166: ADD
00000167: SWAP2
00000168: POP
00000169: POP
0000016a: PUSH1 0x40
0000016c: MLOAD
0000016d: DUP1
0000016e: SWAP2
0000016f: SUB
00000170: SWAP1
00000171: RETURN
00000172: JUMPDEST
00000173: CALLVALUE
00000174: ISZERO
00000175: PUSH2 0x017d
00000178: JUMPI
00000179: PUSH1 0x00
0000017b: DUP1
0000017c: REVERT
0000017d: JUMPDEST
0000017e: PUSH2 0x0185
00000181: PUSH2 0x051b
00000184: JUMP
00000185: JUMPDEST
00000186: PUSH1 0x40
00000188: MLOAD
00000189: DUP1
0000018a: DUP3
0000018b: PUSH1 0x02
0000018d: DUP2
0000018e: GT
0000018f: ISZERO
00000190: PUSH2 0x0195
00000193: JUMPI
00000194: INVALID
00000195: JUMPDEST
00000196: PUSH1 0xff
00000198: AND
00000199: DUP2
0000019a: MSTORE
0000019b: PUSH1 0x20
0000019d: ADD
0000019e: SWAP2
0000019f: POP
000001a0: POP
000001a1: PUSH1 0x40
000001a3: MLOAD
000001a4: DUP1
000001a5: SWAP2
000001a6: SUB
000001a7: SWAP1
000001a8: RETURN
000001a9: JUMPDEST
000001aa: CALLVALUE
000001ab: ISZERO
000001ac: PUSH2 0x01b4
000001af: JUMPI
000001b0: PUSH1 0x00
000001b2: DUP1
000001b3: REVERT
000001b4: JUMPDEST
000001b5: PUSH2 0x01e0
000001b8: PUSH1 0x04
000001ba: DUP1
000001bb: DUP1
000001bc: CALLDATALOAD
000001bd: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000001d2: AND
000001d3: SWAP1
000001d4: PUSH1 0x20
000001d6: ADD
000001d7: SWAP1
000001d8: SWAP2
000001d9: SWAP1
000001da: POP
000001db: POP
000001dc: PUSH2 0x052e
000001df: JUMP
000001e0: JUMPDEST
000001e1: PUSH1 0x40
000001e3: MLOAD
000001e4: DUP1
000001e5: DUP3
000001e6: DUP2
000001e7: MSTORE
000001e8: PUSH1 0x20
000001ea: ADD
000001eb: SWAP2
000001ec: POP
000001ed: POP
000001ee: PUSH1 0x40
000001f0: MLOAD
000001f1: DUP1
000001f2: SWAP2
000001f3: SUB
000001f4: SWAP1
000001f5: RETURN
000001f6: JUMPDEST
000001f7: CALLVALUE
000001f8: ISZERO
000001f9: PUSH2 0x0201
000001fc: JUMPI
000001fd: PUSH1 0x00
000001ff: DUP1
00000200: REVERT
00000201: JUMPDEST
00000202: PUSH2 0x022d
00000205: PUSH1 0x04
00000207: DUP1
00000208: DUP1
00000209: CALLDATALOAD
0000020a: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000021f: AND
00000220: SWAP1
00000221: PUSH1 0x20
00000223: ADD
00000224: SWAP1
00000225: SWAP2
00000226: SWAP1
00000227: POP
00000228: POP
00000229: PUSH2 0x0546
0000022c: JUMP
0000022d: JUMPDEST
0000022e: STOP
0000022f: JUMPDEST
00000230: PUSH2 0x025b
00000233: PUSH1 0x04
00000235: DUP1
00000236: DUP1
00000237: CALLDATALOAD
00000238: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000024d: AND
0000024e: SWAP1
0000024f: PUSH1 0x20
00000251: ADD
00000252: SWAP1
00000253: SWAP2
00000254: SWAP1
00000255: POP
00000256: POP
00000257: PUSH2 0x069b
0000025a: JUMP
0000025b: JUMPDEST
0000025c: STOP
0000025d: JUMPDEST
0000025e: CALLVALUE
0000025f: ISZERO
00000260: PUSH2 0x0268
00000263: JUMPI
00000264: PUSH1 0x00
00000266: DUP1
00000267: REVERT
00000268: JUMPDEST
00000269: PUSH2 0x0294
0000026c: PUSH1 0x04
0000026e: DUP1
0000026f: DUP1
00000270: CALLDATALOAD
00000271: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000286: AND
00000287: SWAP1
00000288: PUSH1 0x20
0000028a: ADD
0000028b: SWAP1
0000028c: SWAP2
0000028d: SWAP1
0000028e: POP
0000028f: POP
00000290: PUSH2 0x07c2
00000293: JUMP
00000294: JUMPDEST
00000295: STOP
00000296: JUMPDEST
00000297: PUSH1 0x00
00000299: DUP1
0000029a: SWAP1
0000029b: SLOAD
0000029c: SWAP1
0000029d: PUSH2 0x0100
000002a0: EXP
000002a1: SWAP1
000002a2: DIV
000002a3: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000002b8: AND
000002b9: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000002ce: AND
000002cf: CALLER
000002d0: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000002e5: AND
000002e6: EQ
000002e7: ISZERO
000002e8: ISZERO
000002e9: PUSH2 0x02f1
000002ec: JUMPI
000002ed: PUSH1 0x00
000002ef: DUP1
000002f0: REVERT
000002f1: JUMPDEST
000002f2: PUSH1 0x00
000002f4: PUSH1 0x02
000002f6: DUP2
000002f7: GT
000002f8: ISZERO
000002f9: PUSH2 0x02fe
000002fc: JUMPI
000002fd: INVALID
000002fe: JUMPDEST
000002ff: PUSH1 0x02
00000301: PUSH1 0x14
00000303: SWAP1
00000304: SLOAD
00000305: SWAP1
00000306: PUSH2 0x0100
00000309: EXP
0000030a: SWAP1
0000030b: DIV
0000030c: PUSH1 0xff
0000030e: AND
0000030f: PUSH1 0x02
00000311: DUP2
00000312: GT
00000313: ISZERO
00000314: PUSH2 0x0319
00000317: JUMPI
00000318: INVALID
00000319: JUMPDEST
0000031a: EQ
0000031b: ISZERO
0000031c: ISZERO
0000031d: PUSH2 0x0325
00000320: JUMPI
00000321: PUSH1 0x00
00000323: DUP1
00000324: REVERT
00000325: JUMPDEST
00000326: PUSH1 0x02
00000328: DUP1
00000329: PUSH1 0x14
0000032b: PUSH2 0x0100
0000032e: EXP
0000032f: DUP2
00000330: SLOAD
00000331: DUP2
00000332: PUSH1 0xff
00000334: MUL
00000335: NOT
00000336: AND
00000337: SWAP1
00000338: DUP4
00000339: PUSH1 0x02
0000033b: DUP2
0000033c: GT
0000033d: ISZERO
0000033e: PUSH2 0x0343
00000341: JUMPI
00000342: INVALID
00000343: JUMPDEST
00000344: MUL
00000345: OR
00000346: SWAP1
00000347: SSTORE
00000348: POP
00000349: PUSH32 0x1cdde67b72a90f19919ac732a437ac2f7a10fc128d28c2a6e525d89ce5cd9d3a
0000036a: PUSH1 0x40
0000036c: MLOAD
0000036d: PUSH1 0x40
0000036f: MLOAD
00000370: DUP1
00000371: SWAP2
00000372: SUB
00000373: SWAP1
00000374: LOG1
00000375: PUSH1 0x02
00000377: PUSH1 0x00
00000379: SWAP1
0000037a: SLOAD
0000037b: SWAP1
0000037c: PUSH2 0x0100
0000037f: EXP
00000380: SWAP1
00000381: DIV
00000382: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000397: AND
00000398: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000003ad: AND
000003ae: PUSH2 0x08fc
000003b1: ADDRESS
000003b2: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000003c7: AND
000003c8: BALANCE
000003c9: SWAP1
000003ca: DUP2
000003cb: ISZERO
000003cc: MUL
000003cd: SWAP1
000003ce: PUSH1 0x40
000003d0: MLOAD
000003d1: PUSH1 0x00
000003d3: PUSH1 0x40
000003d5: MLOAD
000003d6: DUP1
000003d7: DUP4
000003d8: SUB
000003d9: DUP2
000003da: DUP6
000003db: DUP9
000003dc: DUP9
000003dd: CALL
000003de: SWAP4
000003df: POP
000003e0: POP
000003e1: POP
000003e2: POP
000003e3: ISZERO
000003e4: ISZERO
000003e5: PUSH2 0x03ed
000003e8: JUMPI
000003e9: PUSH1 0x00
000003eb: DUP1
000003ec: REVERT
000003ed: JUMPDEST
000003ee: JUMP
000003ef: JUMPDEST
000003f0: PUSH1 0x02
000003f2: PUSH1 0x00
000003f4: SWAP1
000003f5: SLOAD
000003f6: SWAP1
000003f7: PUSH2 0x0100
000003fa: EXP
000003fb: SWAP1
000003fc: DIV
000003fd: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000412: AND
00000413: DUP2
00000414: JUMP
00000415: JUMPDEST
00000416: PUSH1 0x00
00000418: DUP1
00000419: SWAP1
0000041a: SLOAD
0000041b: SWAP1
0000041c: PUSH2 0x0100
0000041f: EXP
00000420: SWAP1
00000421: DIV
00000422: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000437: AND
00000438: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000044d: AND
0000044e: CALLER
0000044f: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000464: AND
00000465: EQ
00000466: ISZERO
00000467: ISZERO
00000468: PUSH2 0x0470
0000046b: JUMPI
0000046c: PUSH1 0x00
0000046e: DUP1
0000046f: REVERT
00000470: JUMPDEST
00000471: PUSH1 0x00
00000473: PUSH1 0x02
00000475: DUP2
00000476: GT
00000477: ISZERO
00000478: PUSH2 0x047d
0000047b: JUMPI
0000047c: INVALID
0000047d: JUMPDEST
0000047e: PUSH1 0x02
00000480: PUSH1 0x14
00000482: SWAP1
00000483: SLOAD
00000484: SWAP1
00000485: PUSH2 0x0100
00000488: EXP
00000489: SWAP1
0000048a: DIV
0000048b: PUSH1 0xff
0000048d: AND
0000048e: PUSH1 0x02
00000490: DUP2
00000491: GT
00000492: ISZERO
00000493: PUSH2 0x0498
00000496: JUMPI
00000497: INVALID
00000498: JUMPDEST
00000499: EQ
0000049a: ISZERO
0000049b: ISZERO
0000049c: PUSH2 0x04a4
0000049f: JUMPI
000004a0: PUSH1 0x00
000004a2: DUP1
000004a3: REVERT
000004a4: JUMPDEST
000004a5: PUSH1 0x01
000004a7: PUSH1 0x02
000004a9: PUSH1 0x14
000004ab: PUSH2 0x0100
000004ae: EXP
000004af: DUP2
000004b0: SLOAD
000004b1: DUP2
000004b2: PUSH1 0xff
000004b4: MUL
000004b5: NOT
000004b6: AND
000004b7: SWAP1
000004b8: DUP4
000004b9: PUSH1 0x02
000004bb: DUP2
000004bc: GT
000004bd: ISZERO
000004be: PUSH2 0x04c3
000004c1: JUMPI
000004c2: INVALID
000004c3: JUMPDEST
000004c4: MUL
000004c5: OR
000004c6: SWAP1
000004c7: SSTORE
000004c8: POP
000004c9: PUSH32 0x599d8e5a83cffb867d051598c4d70e805d59802d8081c1c7d6dffc5b6aca2b89
000004ea: PUSH1 0x40
000004ec: MLOAD
000004ed: PUSH1 0x40
000004ef: MLOAD
000004f0: DUP1
000004f1: SWAP2
000004f2: SUB
000004f3: SWAP1
000004f4: LOG1
000004f5: JUMP
000004f6: JUMPDEST
000004f7: PUSH1 0x00
000004f9: DUP1
000004fa: SWAP1
000004fb: SLOAD
000004fc: SWAP1
000004fd: PUSH2 0x0100
00000500: EXP
00000501: SWAP1
00000502: DIV
00000503: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000518: AND
00000519: DUP2
0000051a: JUMP
0000051b: JUMPDEST
0000051c: PUSH1 0x02
0000051e: PUSH1 0x14
00000520: SWAP1
00000521: SLOAD
00000522: SWAP1
00000523: PUSH2 0x0100
00000526: EXP
00000527: SWAP1
00000528: DIV
00000529: PUSH1 0xff
0000052b: AND
0000052c: DUP2
0000052d: JUMP
0000052e: JUMPDEST
0000052f: PUSH1 0x01
00000531: PUSH1 0x20
00000533: MSTORE
00000534: DUP1
00000535: PUSH1 0x00
00000537: MSTORE
00000538: PUSH1 0x40
0000053a: PUSH1 0x00
0000053c: KECCAK256
0000053d: PUSH1 0x00
0000053f: SWAP2
00000540: POP
00000541: SWAP1
00000542: POP
00000543: SLOAD
00000544: DUP2
00000545: JUMP
00000546: JUMPDEST
00000547: PUSH1 0x00
00000549: DUP1
0000054a: SWAP1
0000054b: SLOAD
0000054c: SWAP1
0000054d: PUSH2 0x0100
00000550: EXP
00000551: SWAP1
00000552: DIV
00000553: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000568: AND
00000569: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000057e: AND
0000057f: CALLER
00000580: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000595: AND
00000596: EQ
00000597: ISZERO
00000598: ISZERO
00000599: PUSH2 0x05a1
0000059c: JUMPI
0000059d: PUSH1 0x00
0000059f: DUP1
000005a0: REVERT
000005a1: JUMPDEST
000005a2: PUSH1 0x00
000005a4: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000005b9: AND
000005ba: DUP2
000005bb: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000005d0: AND
000005d1: EQ
000005d2: ISZERO
000005d3: ISZERO
000005d4: ISZERO
000005d5: PUSH2 0x05dd
000005d8: JUMPI
000005d9: PUSH1 0x00
000005db: DUP1
000005dc: REVERT
000005dd: JUMPDEST
000005de: DUP1
000005df: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000005f4: AND
000005f5: PUSH1 0x00
000005f7: DUP1
000005f8: SWAP1
000005f9: SLOAD
000005fa: SWAP1
000005fb: PUSH2 0x0100
000005fe: EXP
000005ff: SWAP1
00000600: DIV
00000601: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000616: AND
00000617: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000062c: AND
0000062d: PUSH32 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
0000064e: PUSH1 0x40
00000650: MLOAD
00000651: PUSH1 0x40
00000653: MLOAD
00000654: DUP1
00000655: SWAP2
00000656: SUB
00000657: SWAP1
00000658: LOG3
00000659: DUP1
0000065a: PUSH1 0x00
0000065c: DUP1
0000065d: PUSH2 0x0100
00000660: EXP
00000661: DUP2
00000662: SLOAD
00000663: DUP2
00000664: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000679: MUL
0000067a: NOT
0000067b: AND
0000067c: SWAP1
0000067d: DUP4
0000067e: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000693: AND
00000694: MUL
00000695: OR
00000696: SWAP1
00000697: SSTORE
00000698: POP
00000699: POP
0000069a: JUMP
0000069b: JUMPDEST
0000069c: PUSH1 0x00
0000069e: DUP1
0000069f: SWAP1
000006a0: SLOAD
000006a1: SWAP1
000006a2: PUSH2 0x0100
000006a5: EXP
000006a6: SWAP1
000006a7: DIV
000006a8: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000006bd: AND
000006be: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000006d3: AND
000006d4: CALLER
000006d5: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000006ea: AND
000006eb: EQ
000006ec: ISZERO
000006ed: ISZERO
000006ee: PUSH2 0x06f6
000006f1: JUMPI
000006f2: PUSH1 0x00
000006f4: DUP1
000006f5: REVERT
000006f6: JUMPDEST
000006f7: PUSH1 0x00
000006f9: PUSH1 0x02
000006fb: DUP2
000006fc: GT
000006fd: ISZERO
000006fe: PUSH2 0x0703
00000701: JUMPI
00000702: INVALID
00000703: JUMPDEST
00000704: PUSH1 0x02
00000706: PUSH1 0x14
00000708: SWAP1
00000709: SLOAD
0000070a: SWAP1
0000070b: PUSH2 0x0100
0000070e: EXP
0000070f: SWAP1
00000710: DIV
00000711: PUSH1 0xff
00000713: AND
00000714: PUSH1 0x02
00000716: DUP2
00000717: GT
00000718: ISZERO
00000719: PUSH2 0x071e
0000071c: JUMPI
0000071d: INVALID
0000071e: JUMPDEST
0000071f: EQ
00000720: ISZERO
00000721: ISZERO
00000722: PUSH2 0x072a
00000725: JUMPI
00000726: PUSH1 0x00
00000728: DUP1
00000729: REVERT
0000072a: JUMPDEST
0000072b: PUSH2 0x077c
0000072e: CALLVALUE
0000072f: PUSH1 0x01
00000731: PUSH1 0x00
00000733: DUP5
00000734: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000749: AND
0000074a: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000075f: AND
00000760: DUP2
00000761: MSTORE
00000762: PUSH1 0x20
00000764: ADD
00000765: SWAP1
00000766: DUP2
00000767: MSTORE
00000768: PUSH1 0x20
0000076a: ADD
0000076b: PUSH1 0x00
0000076d: KECCAK256
0000076e: SLOAD
0000076f: PUSH2 0x0911
00000772: SWAP1
00000773: SWAP2
00000774: SWAP1
00000775: PUSH4 0xffffffff
0000077a: AND
0000077b: JUMP
0000077c: JUMPDEST
0000077d: PUSH1 0x01
0000077f: PUSH1 0x00
00000781: DUP4
00000782: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000797: AND
00000798: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000007ad: AND
000007ae: DUP2
000007af: MSTORE
000007b0: PUSH1 0x20
000007b2: ADD
000007b3: SWAP1
000007b4: DUP2
000007b5: MSTORE
000007b6: PUSH1 0x20
000007b8: ADD
000007b9: PUSH1 0x00
000007bb: KECCAK256
000007bc: DUP2
000007bd: SWAP1
000007be: SSTORE
000007bf: POP
000007c0: POP
000007c1: JUMP
000007c2: JUMPDEST
000007c3: PUSH1 0x00
000007c5: PUSH1 0x01
000007c7: PUSH1 0x02
000007c9: DUP2
000007ca: GT
000007cb: ISZERO
000007cc: PUSH2 0x07d1
000007cf: JUMPI
000007d0: INVALID
000007d1: JUMPDEST
000007d2: PUSH1 0x02
000007d4: PUSH1 0x14
000007d6: SWAP1
000007d7: SLOAD
000007d8: SWAP1
000007d9: PUSH2 0x0100
000007dc: EXP
000007dd: SWAP1
000007de: DIV
000007df: PUSH1 0xff
000007e1: AND
000007e2: PUSH1 0x02
000007e4: DUP2
000007e5: GT
000007e6: ISZERO
000007e7: PUSH2 0x07ec
000007ea: JUMPI
000007eb: INVALID
000007ec: JUMPDEST
000007ed: EQ
000007ee: ISZERO
000007ef: ISZERO
000007f0: PUSH2 0x07f8
000007f3: JUMPI
000007f4: PUSH1 0x00
000007f6: DUP1
000007f7: REVERT
000007f8: JUMPDEST
000007f9: PUSH1 0x01
000007fb: PUSH1 0x00
000007fd: DUP4
000007fe: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000813: AND
00000814: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000829: AND
0000082a: DUP2
0000082b: MSTORE
0000082c: PUSH1 0x20
0000082e: ADD
0000082f: SWAP1
00000830: DUP2
00000831: MSTORE
00000832: PUSH1 0x20
00000834: ADD
00000835: PUSH1 0x00
00000837: KECCAK256
00000838: SLOAD
00000839: SWAP1
0000083a: POP
0000083b: PUSH1 0x00
0000083d: PUSH1 0x01
0000083f: PUSH1 0x00
00000841: DUP5
00000842: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000857: AND
00000858: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000086d: AND
0000086e: DUP2
0000086f: MSTORE
00000870: PUSH1 0x20
00000872: ADD
00000873: SWAP1
00000874: DUP2
00000875: MSTORE
00000876: PUSH1 0x20
00000878: ADD
00000879: PUSH1 0x00
0000087b: KECCAK256
0000087c: DUP2
0000087d: SWAP1
0000087e: SSTORE
0000087f: POP
00000880: DUP2
00000881: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000896: AND
00000897: PUSH2 0x08fc
0000089a: DUP3
0000089b: SWAP1
0000089c: DUP2
0000089d: ISZERO
0000089e: MUL
0000089f: SWAP1
000008a0: PUSH1 0x40
000008a2: MLOAD
000008a3: PUSH1 0x00
000008a5: PUSH1 0x40
000008a7: MLOAD
000008a8: DUP1
000008a9: DUP4
000008aa: SUB
000008ab: DUP2
000008ac: DUP6
000008ad: DUP9
000008ae: DUP9
000008af: CALL
000008b0: SWAP4
000008b1: POP
000008b2: POP
000008b3: POP
000008b4: POP
000008b5: ISZERO
000008b6: ISZERO
000008b7: PUSH2 0x08bf
000008ba: JUMPI
000008bb: PUSH1 0x00
000008bd: DUP1
000008be: REVERT
000008bf: JUMPDEST
000008c0: DUP2
000008c1: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
000008d6: AND
000008d7: PUSH32 0xd7dee2702d63ad89917b6a4da9981c90c4d24f8c2bdfd64c604ecae57d8d0651
000008f8: DUP3
000008f9: PUSH1 0x40
000008fb: MLOAD
000008fc: DUP1
000008fd: DUP3
000008fe: DUP2
000008ff: MSTORE
00000900: PUSH1 0x20
00000902: ADD
00000903: SWAP2
00000904: POP
00000905: POP
00000906: PUSH1 0x40
00000908: MLOAD
00000909: DUP1
0000090a: SWAP2
0000090b: SUB
0000090c: SWAP1
0000090d: LOG2
0000090e: POP
0000090f: POP
00000910: JUMP
00000911: JUMPDEST
00000912: PUSH1 0x00
00000914: DUP1
00000915: DUP3
00000916: DUP5
00000917: ADD
00000918: SWAP1
00000919: POP
0000091a: DUP4
0000091b: DUP2
0000091c: LT
0000091d: ISZERO
0000091e: ISZERO
0000091f: ISZERO
00000920: PUSH2 0x0925
00000923: JUMPI
00000924: INVALID
00000925: JUMPDEST
00000926: DUP1
00000927: SWAP2
00000928: POP
00000929: POP
0000092a: SWAP3
0000092b: SWAP2
0000092c: POP
0000092d: POP
0000092e: JUMP
0000092f: STOP
00000930: LOG1
00000931: PUSH6 0x627a7a723058
00000938: KECCAK256
00000939: SWAP4
0000093a: UNKNOWN(0x2A)
0000093b: RETURNDATACOPY
0000093c: MUL
0000093d: SWAP16
0000093e: UNKNOWN(0xC6)
0000093f: LT
00000940: UNKNOWN(0xE9)
00000941: MULMOD
00000942: DUP6
00000943: ADDRESS
00000944: SIGNEXTEND
00000945: CALLCODE
00000946: PUSH16 0x653d2ece3258ea9eb306c2b0831c4f6f
00000957: UNKNOWN(0xE7)
00000958: SWAP7
00000959: STOP
0000095a: UNKNOWN(0x29)

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
medium other detector Untrusted CALL target/value reachable 45 no no
view
trace_id: 0xbe7fa21493096cb06f927dd3e6e7833dde89101c02664ed01f2e2b4edc01d401
call_targets: 0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xbe7fa21493096cb06f927dd3e6e7833dde89101c02664ed01f2e2b4edc01d401",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5"
    ],
    "matched_probe": null,
    "target_varies": false,
    "classification": "constant_target"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0xffffffff",
            "selector": "0xffffffff",
            "calldata_variants": [
                "0xffffffff",
                "0xffffffff0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x43d726d6",
            "selector": "0x43d726d6",
            "calldata_variants": [
                "0x43d726d6",
                "0x43d726d60000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x521eb273",
            "selector": "0x521eb273",
            "calldata_variants": [
                "0x521eb273",
                "0x521eb2730000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x8c52dc41",
            "selector": "0x8c52dc41",
            "calldata_variants": [
                "0x8c52dc41",
                "0x8c52dc410000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x8da5cb5b",
            "selector": "0x8da5cb5b",
            "calldata_variants": [
                "0x8da5cb5b",
                "0x8da5cb5b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xc19d93fb",
            "selector": "0xc19d93fb",
            "calldata_variants": [
                "0xc19d93fb",
                "0xc19d93fb0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xcb13cddb",
            "selector": "0xcb13cddb",
            "calldata_variants": [
                "0xcb13cddb",
                "0xcb13cddb0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xf2fde38b",
            "selector": "0xf2fde38b",
            "calldata_variants": [
                "0xf2fde38b",
                "0xf2fde38b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 989,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "constant",
            "target_expression_category": "computed"
        },
        {
            "pc": 2223,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 2373,
            "opcode": "CALLCODE",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "call_count": 3,
    "guards_detected": [
        {
            "pc": 719,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1102,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1407,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1748,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        }
    ],
    "untrusted_call_count": 3
}
medium other detector ETH value transfer possible 40 no no
view
trace_id: 0xbe7fa21493096cb06f927dd3e6e7833dde89101c02664ed01f2e2b4edc01d401
call_targets: 0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xbe7fa21493096cb06f927dd3e6e7833dde89101c02664ed01f2e2b4edc01d401",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x91bf99ca34268d407f3cc8d6525ce83c6ea7bcf5"
    ],
    "matched_probe": null,
    "target_varies": false,
    "classification": "constant_target"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0xffffffff",
            "selector": "0xffffffff",
            "calldata_variants": [
                "0xffffffff",
                "0xffffffff0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x43d726d6",
            "selector": "0x43d726d6",
            "calldata_variants": [
                "0x43d726d6",
                "0x43d726d60000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x521eb273",
            "selector": "0x521eb273",
            "calldata_variants": [
                "0x521eb273",
                "0x521eb2730000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x8c52dc41",
            "selector": "0x8c52dc41",
            "calldata_variants": [
                "0x8c52dc41",
                "0x8c52dc410000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x8da5cb5b",
            "selector": "0x8da5cb5b",
            "calldata_variants": [
                "0x8da5cb5b",
                "0x8da5cb5b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xc19d93fb",
            "selector": "0xc19d93fb",
            "calldata_variants": [
                "0xc19d93fb",
                "0xc19d93fb0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xcb13cddb",
            "selector": "0xcb13cddb",
            "calldata_variants": [
                "0xcb13cddb",
                "0xcb13cddb0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xf2fde38b",
            "selector": "0xf2fde38b",
            "calldata_variants": [
                "0xf2fde38b",
                "0xf2fde38b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 989,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "constant",
            "target_expression_category": "computed"
        },
        {
            "pc": 2223,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 2373,
            "opcode": "CALLCODE",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "eth_value_calls": 3,
    "guards_detected": [
        {
            "pc": 719,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1102,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1407,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        },
        {
            "pc": 1748,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
        }
    ]
}
low other codex Fixed 2300-gas ETH transfers can make withdrawals revert for contract recipients 65 no
view
evidence_json
{
    "evidence": "Bytecode shows `PUSH2 0x08fc` (2300) immediately before low-level CALLs that transfer value; CALL opcodes at pc 0x3dd and 0x8af.",
    "locations": [
        "pc:0x3dd",
        "pc:0x8af",
        "pc:0x3ae",
        "pc:0x897"
    ],
    "recommendation": "Use `call{value: amount}(\"\")` with full gas forwarding and protect with checks-effects-interactions or a reentrancy guard, or add an alternative withdrawal path / configurable gas stipend.",
    "exploit_scenario": "If the beneficiary/owner address is a contract with a receive/fallback that needs more than the 2300 gas stipend (or gas costs increase), the CALL will fail and revert the withdrawal, potentially leaving ETH locked. This is inferred from bytecode and could be a false positive if an alternate withdrawal path exists."
}