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

Analysis Run

019bab3b-ab58-7009-8f77-aa62cd038a53

complete
Chain ID
1
Address
Block Number
Created
Sun, Jan 11, 2026 4:06 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
Not yet
Best current signal
Untrusted DELEGATECALL target reachable
crit 0 high 0 proxy context implementation known
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
38527 artifact.fetch complete 1 / 3 3 months ago
38528 proxy.resolve complete 1 / 3 3 months ago
38529 tool.cast_disasm complete 1 / 3 3 months ago
38530 analysis.bundle complete 1 / 3 3 months ago
38531 capability.graph complete 1 / 3 3 months ago
38532 detector.run complete 1 / 3 3 months ago
38533 validation.fork complete 1 / 3 3 months ago
39053 report.consolidate complete 1 / 6 3 months ago

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: yes onchain_only
Verified Source: no
Proxy evidence
{
    "method": "beacon",
    "status": "onchain_only",
    "implementation": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538",
    "onchain_method": "beacon"
}

Slither

tool.slither

No slither job recorded yet.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
0
No findings?
yes
Summary
No material security issues were identified in the implementation bytecode. External CALLs appear limited to owner-gated asset withdrawal logic (ERC20/ERC721/ETH) and balance queries; no delegatecall or upgrade slot writes were found. The detected SELFDESTRUCT opcode sits inside the CBOR metadata region (pc:0x1f7a), so it is likely not reachable. Analysis is limited to runtime bytecode artifacts and selector inference.
View stdout
{"no_findings":true,"summary":"No material security issues were identified in the implementation bytecode. External CALLs appear limited to owner-gated asset withdrawal logic (ERC20/ERC721/ETH) and balance queries; no delegatecall or upgrade slot writes were found. The detected SELFDESTRUCT opcode sits inside the CBOR metadata region (pc:0x1f7a), so it is likely not reachable. Analysis is limited to runtime bytecode artifacts and selector inference.","findings":[]}
View stderr
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-2ful2int
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019bab9d-de01-76e0-9096-8a9142d8a4a3
--------
user
Context: The user requested the proxy at 0x39102c346731672cf013ccf96927bdd21c0419ef.
Audit the implementation at 0x5018cc0d628fb322b2a040cfcd269a36c60b1538.
Findings should refer to the implementation unless explicitly about proxy mechanics.

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
**Locating BYTECODE_BUNDLE.json**
exec
/bin/bash -lc ls in /tmp/codex-2ful2int succeeded in 7ms:
BYTECODE_BUNDLE.json
codex-output-schema.json

thinking
**Reading BYTECODE_BUNDLE.json**
exec
/bin/bash -lc 'cat BYTECODE_BUNDLE.json' in /tmp/codex-2ful2int succeeded in 21ms:
{
  "analysis_artifact": {
    "address": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538",
    "artifact_hash": "0x34f4107ed4c6e9c6513f97e9505ebdc3100fd27a870a227a5bc63f04ac0fa890",
    "artifact_json": {
      "auth": {
        "guards": [
          {
            "pc": 1138,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
          },
          {
            "pc": 1642,
            "type": "msg_sender_eq_const",
            "value": "0xffffffffffffffffffffffffffffffffffffffff"
          },
          {
            "pc": 2818,
            "type": "msg_sender_eq_const",

thinking
**Searching for storage references**
exec
/bin/bash -lc 'rg -n "storage|slot|evidence|selector" BYTECODE_BUNDLE.json' in /tmp/codex-2ful2int succeeded in 8ms:
10348:      "dispatcher_type": "selector_jump_table",
10352:          "selector": "0x71629b97"
10356:          "selector": "0x8da5cb5b"
10360:          "selector": "0xbc197c81"
10364:          "selector": "0xc4d66de8"
10368:          "selector": "0xf23a6e61"
10372:          "selector": "0xf3fef3a3"
10376:          "selector": "0x01ffc9a7"
10380:          "selector": "0x150b7a02"
10384:          "selector": "0x4025feb2"
10388:          "selector": "0x44004cc1"
10392:          "selector": "0x6f9fb98a"
10417:          "selector": "0x71629b97",
10424:          "storage": {
10426:            "slots": [
10430:                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
10435:                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
10440:                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
10445:                "slot": "0x0000000000000000000000000000000000000000000000000000000000000001"
10450:                "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"

thinking
**Extracting evidence_json sections**
exec
/bin/bash -lc "sed -n '10320,10480p' BYTECODE_BUNDLE.json" in /tmp/codex-2ful2int succeeded in 22ms:
        },
        {
          "from": "bb:7946",
          "to": "bb:7935",
          "type": "control_flow"
        },
        {
          "from": "bb:7957",
          "to": "bb:6084",
          "type": "control_flow"
        },
        {
          "from": "bb:7967",
          "to": "bb:7713",
          "type": "control_flow"
        },
        {
          "from": "bb:7983",
          "to": "bb:4720",
          "type": "control_flow"

thinking
**Seeking evidence for proxy functions**
exec
/bin/bash -lc "sed -n '11160,11340p' BYTECODE_BUNDLE.json" in /tmp/codex-2ful2int succeeded in 6ms:
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
              }
            ],
            "writes": 4
          }
        }
      ],
      "selectors": [
        "0x71629b97",
        "0x8da5cb5b",
        "0xbc197c81",
        "0xc4d66de8",
        "0xf23a6e61",
        "0xf3fef3a3",
        "0x01ffc9a7",
        "0x150b7a02",
        "0x4025feb2",
        "0x44004cc1",
        "0x6f9fb98a"
      ],

thinking
**Analyzing runtime bytecode and callsites**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path

path=Path('BYTECODE_BUNDLE.json')
obj=json.loads(path.read_text())
bytecode=obj['artifact']['runtime_bytecode']['full']
if bytecode.startswith('0x'): bytecode=bytecode[2:]
code=bytes.fromhex(bytecode)
# opcode table
opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

# disassemble to list of (pc, op, imm)
ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next

# function to print around pc

def show(target, radius=12):
    # find index where pc==target
    idx=None
    for i,(pc,name,imm) in enumerate(ops):
        if pc==target:
            idx=i;break
    if idx is None:
        # find closest
        for i,(pc,name,imm) in enumerate(ops):
            if pc>target:
                idx=max(i-1,0);break
        else:
            idx=len(ops)-1
    start=max(0, idx-radius)
    end=min(len(ops), idx+radius)
    for pc,name,imm in ops[start:end]:
        if imm:
            print(f'{pc:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04x}: {name}')
    print('---')

for t in [0x613,0xc85,0xf72]:
    print('== around',hex(t))
    show(t, radius=20)

# locate SELFDESTRUCT pcs
sd=[pc for pc,name,_ in ops if name=='SELFDESTRUCT']
print('SELFDESTRUCT pcs', [hex(pc) for pc in sd])

PY" in /tmp/codex-2ful2int succeeded in 64ms:
== around 0x613
05fb: MLOAD
05fc: DUP1
05fd: DUP4
05fe: SUB
05ff: DUP2
0600: PUSH1 0x00
0602: DUP8
0603: DUP1
0604: EXTCODESIZE
0605: ISZERO
0606: DUP1
0607: ISZERO
0608: PUSH2 0x0610
060b: JUMPI
060c: PUSH1 0x00
060e: DUP1
060f: REVERT
0610: JUMPDEST
0611: POP

thinking
**Preparing context for disassembly**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
path=Path('BYTECODE_BUNDLE.json')
obj=json.loads(path.read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)
# opcodes mapping
opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}
ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next


def show(target, radius=20):
    idx=None
    for i,(pc,name,imm) in enumerate(ops):
        if pc==target:
            idx=i;break
    if idx is None:
        for i,(pc,name,imm) in enumerate(ops):
            if pc>target:
                idx=max(i-1,0);break
        else:
            idx=len(ops)-1
    start=max(0, idx-radius)
    end=min(len(ops), idx+radius)
    for pc,name,imm in ops[start:end]:
        if imm:
            print(f'{pc:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{pc:04x}: {name}')
    print('---')

show(0x1f7a, radius=30)
PY" in /tmp/codex-2ful2int succeeded in 40ms:
1f53: MSTORE
1f54: PUSH2 0x1f5d
1f57: DUP2
1f58: DUP5
1f59: PUSH2 0x1f0a
1f5c: JUMP
1f5d: JUMPDEST
1f5e: SWAP1
1f5f: POP
1f60: SWAP3
1f61: SWAP2
1f62: POP
1f63: POP
1f64: JUMP
1f65: INVALID
1f66: LOG2
1f67: PUSH5 0x6970667358
1f6d: OP_22
1f6e: SLT
1f6f: SHA3

thinking
**Analyzing SELFDESTRUCT position in bytecode**
exec
/bin/bash -lc "python - <<'PY'
import json, re
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
pattern='a264697066735822'
idx=code.find(pattern)
print('metadata hex index', idx)
if idx"'!=-1:
    print('"'byte offset', idx//2, 'hex', hex(idx//2))
PY" in /tmp/codex-2ful2int succeeded in 83ms:
metadata hex index 16076
byte offset 8038 hex 0x1f66

thinking
**Analyzing metadata and decoding selectors**

I'm confirming that the selfdestruct instruction is inside metadata, not executable code, so it's a false positive for vulnerabilities. Now I'm focused on decoding function selectors by parsing the dispatch table in bytecode, planning to scan for selector-to-JUMPDEST mappings via a specific opcode pattern using Python. Let's explore that approach!
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

# simple disassemble to list of (pc, op, imm)
opcodes={
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op)
    imm=b''
    pc_next=pc+1
    if name:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
        ops.append((pc,name,imm))
    else:
        ops.append((pc,op,imm))
    pc=pc_next

# scan for PUSH4 <sel> EQ PUSH2 <dest> JUMPI
sels={}
for i in range(len(ops)-4):
    pc,op,imm=ops[i]
    if op=='PUSH4':
        # next should be EQ (0x14) then PUSH2 then JUMPI (0x57)
        if ops[i+1][1]==0x14 and ops[i+2][1]=='PUSH2' and ops[i+3][1]==0x57:
            sel=int.from_bytes(imm,'big')
            dest=int.from_bytes(ops[i+2][2],'big')
            sels[f'0x{sel:08x}']=dest

print('selectors -> dest')
for k,v in sels.items():
    print(k, '->', hex(v))
PY" in /tmp/codex-2ful2int succeeded in 42ms:
selectors -> dest
0x71629b97 -> 0x1fb
0x8da5cb5b -> 0x238
0xbc197c81 -> 0x263
0xc4d66de8 -> 0x2a0
0xf23a6e61 -> 0x2bc
0xf3fef3a3 -> 0x2f9
0x01ffc9a7 -> 0xf0
0x150b7a02 -> 0x12d
0x4025feb2 -> 0x16a
0x44004cc1 -> 0x193
0x6f9fb98a -> 0x1d0

thinking
**Analyzing bytecode jump destinations**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next

# map pc->index
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}

sels={
'0x71629b97':0x1fb,
'0x8da5cb5b':0x238,
'0xbc197c81':0x263,
'0xc4d66de8':0x2a0,
'0xf23a6e61':0x2bc,
'0xf3fef3a3':0x2f9,
'0x01ffc9a7':0xf0,
'0x150b7a02':0x12d,
'0x4025feb2':0x16a,
'0x44004cc1':0x193,
'0x6f9fb98a':0x1d0,
}


def show(pc, count=25):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

for sel,dest in sels.items():
    print('selector',sel,'dest',hex(dest))
    show(dest, count=40)
PY" in /tmp/codex-2ful2int succeeded in 47ms:
selector 0x71629b97 dest 0x1fb
01fb: JUMPDEST
01fc: CALLVALUE
01fd: DUP1
01fe: ISZERO
01ff: PUSH2 0x0207
0202: JUMPI
0203: PUSH1 0x00
0205: DUP1
0206: REVERT
0207: JUMPDEST
0208: POP
0209: PUSH2 0x0222
020c: PUSH1 0x04
020e: DUP1
020f: CALLDATASIZE
0210: SUB
0211: DUP2
0212: ADD
0213: SWAP1

thinking
**Analyzing internal function jump destinations**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=60):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

internal_pcs=[0x0809,0x0891,0x08b7,0x08cc,0x0ab3,0x0ac8,0x03aa,0x0424,0x0438,0x062f,0x0801]
for pc in internal_pcs:
    print('function @',hex(pc))
    show(pc, count=80)
PY" in /tmp/codex-2ful2int succeeded in 39ms:
function @ 0x809
0809: JUMPDEST
080a: PUSH1 0x00
080c: DUP1
080d: DUP3
080e: SWAP1
080f: POP
0810: DUP1
0811: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0826: AND
0827: PUSH4 0x70a08231
082c: ADDRESS
082d: PUSH1 0x40
082f: MLOAD
0830: DUP3
0831: PUSH4 0xffffffff
0836: AND
0837: PUSH1 0xe0
0839: SHL
083a: DUP2

thinking
**Extending function view for more context**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=200):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x8cc, count=200)
PY" in /tmp/codex-2ful2int succeeded in 57ms:
08cc: JUMPDEST
08cd: PUSH1 0x00
08cf: DUP1
08d0: PUSH1 0x01
08d2: SWAP1
08d3: SLOAD
08d4: SWAP1
08d5: PUSH2 0x0100
08d8: EXP
08d9: SWAP1
08da: DIV
08db: PUSH1 0xff
08dd: AND
08de: ISZERO
08df: SWAP1
08e0: POP
08e1: DUP1
08e2: DUP1
08e3: ISZERO
08e4: PUSH2 0x08fd

thinking
**Continuing exploration**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=120):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x0a56, count=120)
PY" in /tmp/codex-2ful2int succeeded in 50ms:
0a56: POP
0a57: DUP1
0a58: ISZERO
0a59: PUSH2 0x0aaf
0a5c: JUMPI
0a5d: PUSH1 0x00
0a5f: DUP1
0a60: PUSH1 0x01
0a62: PUSH2 0x0100
0a65: EXP
0a66: DUP2
0a67: SLOAD
0a68: DUP2
0a69: PUSH1 0xff
0a6b: MUL
0a6c: NOT
0a6d: AND
0a6e: SWAP1
0a6f: DUP4
0a70: ISZERO

thinking
**Analyzing smart contract functions and balances**

I'm examining functions that handle initialization, token balances, and withdrawals by parsing their use of storage slots, event logs, and external calls. I'm correlating address checks, balance queries, and token transfers to identify function roles like `initialize`, `getTokenBalance`, and token withdrawal, aiming to clarify their behavior by reviewing more code around key offsets.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=200):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x62f, count=220)
PY" in /tmp/codex-2ful2int succeeded in 57ms:
062f: JUMPDEST
0630: PUSH1 0x00
0632: DUP1
0633: PUSH1 0x02
0635: SWAP1
0636: SLOAD
0637: SWAP1
0638: PUSH2 0x0100
063b: EXP
063c: SWAP1
063d: DIV
063e: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0653: AND
0654: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0669: AND
066a: CALLER
066b: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0680: AND
0681: EQ
0682: PUSH2 0x06c0

thinking
**Analyzing owner-only token and NFT withdrawal functions**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=250):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x438, count=250)
PY" in /tmp/codex-2ful2int succeeded in 148ms:
0438: JUMPDEST
0439: PUSH1 0x00
043b: PUSH1 0x02
043d: SWAP1
043e: SLOAD
043f: SWAP1
0440: PUSH2 0x0100
0443: EXP
0444: SWAP1
0445: DIV
0446: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
045b: AND
045c: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0471: AND
0472: CALLER
0473: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0488: AND
0489: EQ
048a: PUSH2 0x04c8
048d: JUMPI

thinking
**Analyzing contract ownership and withdrawal functions**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=80):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x0d04, count=80)
PY" in /tmp/codex-2ful2int succeeded in 74ms:
0d04: JUMPDEST
0d05: PUSH1 0x00
0d07: PUSH32 0x01ffc9a700000000000000000000000000000000000000000000000000000000
0d28: PUSH28 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff
0d45: NOT
0d46: AND
0d47: DUP3
0d48: PUSH28 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff
0d65: NOT
0d66: AND
0d67: EQ
0d68: SWAP1
0d69: POP
0d6a: SWAP2
0d6b: SWAP1
0d6c: POP
0d6d: JUMP
0d6e: JUMPDEST
0d6f: PUSH2 0x0def
0d72: DUP4

thinking
**Analyzing internal function addresses**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=obj['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
code=bytes.fromhex(code)

opcodes={
    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',
    0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',
    0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
    0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
    0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
    0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
    0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
}

ops=[]
pc=0
while pc < len(code):
    op=code[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    imm=b''
    pc_next=pc+1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        imm=code[pc_next:pc_next+n]
        pc_next+=n
    ops.append((pc,name,imm))
    pc=pc_next
idx_map={pc:i for i,(pc,_,_) in enumerate(ops)}


def show(pc, count=120):
    i=idx_map.get(pc)
    if i is None:
        print('no pc',pc)
        return
    for j in range(i, min(len(ops), i+count)):
        p,name,imm=ops[j]
        if imm:
            print(f'{p:04x}: {name} 0x{imm.hex()}')
        else:
            print(f'{p:04x}: {name}')
    print('---')

show(0x0df4, count=120)
PY" in /tmp/codex-2ful2int succeeded in 42ms:
0df4: JUMPDEST
0df5: PUSH1 0x00
0df7: DUP1
0df8: DUP3
0df9: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0e0e: AND
0e0f: EXTCODESIZE
0e10: GT
0e11: SWAP1
0e12: POP
0e13: SWAP2
0e14: SWAP1
0e15: POP
0e16: JUMP
0e17: JUMPDEST
0e18: PUSH1 0x00
0e1a: PUSH2 0x0e79
0e1d: DUP3
0e1e: PUSH1 0x40
0e20: MLOAD

thinking
**Evaluating contract initialization and token handling risks**

I'm piecing together how the contract uses `Address.isContract` to manage initialization and owner setting, noting the public initializer exposes a typical proxy risk if uninitialized. I see no outright security flaws but spot functional issues like missing ERC721Receiver checks in `supportsInterface`, unrestricted acceptance but no withdrawal of ERC1155 tokens causing potential asset lock, and owner-only external calls without reentrancy guards that mostly reduce risk. Overall, I’m balancing deployment risks, design choices, and standard patterns while preparing to report these with cautious severity.
exec
/bin/bash -lc 'rg -n "f242432a|2eb2c2d6" BYTECODE_BUNDLE.json' in /tmp/codex-2ful2int exited 1 in 7ms:


thinking
**Assessing ERC1155 asset handling and initialization risks**

I see the contract implements ERC1155 receiver functions but lacks withdrawal methods for those tokens, meaning ERC1155 assets could get stuck. There’s also a possible risk if the proxy isn’t properly initialized, allowing ownership takeover. Overall, I’m leaning toward reporting no critical findings but including these functional and initialization considerations in the summary.
codex
{"no_findings":true,"summary":"No material security issues were identified in the implementation bytecode. External CALLs appear limited to owner-gated asset withdrawal logic (ERC20/ERC721/ETH) and balance queries; no delegatecall or upgrade slot writes were found. The detected SELFDESTRUCT opcode sits inside the CBOR metadata region (pc:0x1f7a), so it is likely not reachable. Analysis is limited to runtime bytecode artifacts and selector inference.","findings":[]}
tokens used
107,910
Metadata
{
    "codex": {
        "ran_at": "2026-01-11T06:02:22.187048+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "bytecode",
        "bytecode_length": 16184,
        "bytecode_truncated": false,
        "capability_graph_present": true,
        "analysis_artifact_present": true
    },
    "summary": "No material security issues were identified in the implementation bytecode. External CALLs appear limited to owner-gated asset withdrawal logic (ERC20/ERC721/ETH) and balance queries; no delegatecall or upgrade slot writes were found. The detected SELFDESTRUCT opcode sits inside the CBOR metadata region (pc:0x1f7a), so it is likely not reachable. Analysis is limited to runtime bytecode artifacts and selector inference.",
    "raw_final": {
        "summary": "No material security issues were identified in the implementation bytecode. External CALLs appear limited to owner-gated asset withdrawal logic (ERC20/ERC721/ETH) and balance queries; no delegatecall or upgrade slot writes were found. The detected SELFDESTRUCT opcode sits inside the CBOR metadata region (pc:0x1f7a), so it is likely not reachable. Analysis is limited to runtime bytecode artifacts and selector inference.",
        "findings": [],
        "no_findings": true
    },
    "no_findings": true,
    "proxy_context": {
        "proxy_run_id": "019bab3b-ab58-7009-8f77-aa62cd038a53",
        "proxy_address": "0x39102c346731672cf013ccf96927bdd21c0419ef",
        "implementation_run_id": "019bab3d-0c7e-71f2-bf8e-4275a4cf132f",
        "implementation_address": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538"
    },
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
1
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
2
EXT*/BALANCE
0
Total opcodes
290
Flags
delegatecall_present
View cast disassembly output
00000000: PUSH1 0x80
00000002: PUSH1 0x40
00000004: MSTORE
00000005: CALLDATASIZE
00000006: PUSH2 0x0013
00000009: JUMPI
0000000a: PUSH2 0x0011
0000000d: PUSH2 0x001d
00000010: JUMP
00000011: JUMPDEST
00000012: STOP
00000013: JUMPDEST
00000014: PUSH2 0x001b
00000017: PUSH2 0x001d
0000001a: JUMP
0000001b: JUMPDEST
0000001c: STOP
0000001d: JUMPDEST
0000001e: PUSH2 0x0025
00000021: PUSH2 0x0037
00000024: JUMP
00000025: JUMPDEST
00000026: PUSH2 0x0035
00000029: PUSH2 0x0030
0000002c: PUSH2 0x0039
0000002f: JUMP
00000030: JUMPDEST
00000031: PUSH2 0x00b6
00000034: JUMP
00000035: JUMPDEST
00000036: JUMP
00000037: JUMPDEST
00000038: JUMP
00000039: JUMPDEST
0000003a: PUSH1 0x00
0000003c: PUSH2 0x0043
0000003f: PUSH2 0x00dc
00000042: JUMP
00000043: JUMPDEST
00000044: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
00000059: AND
0000005a: PUSH4 0x5c60da1b
0000005f: PUSH1 0x40
00000061: MLOAD
00000062: DUP2
00000063: PUSH4 0xffffffff
00000068: AND
00000069: PUSH1 0xe0
0000006b: SHL
0000006c: DUP2
0000006d: MSTORE
0000006e: PUSH1 0x04
00000070: ADD
00000071: PUSH1 0x20
00000073: PUSH1 0x40
00000075: MLOAD
00000076: DUP1
00000077: DUP4
00000078: SUB
00000079: DUP2
0000007a: DUP7
0000007b: GAS
0000007c: STATICCALL
0000007d: ISZERO
0000007e: DUP1
0000007f: ISZERO
00000080: PUSH2 0x008d
00000083: JUMPI
00000084: RETURNDATASIZE
00000085: PUSH1 0x00
00000087: DUP1
00000088: RETURNDATACOPY
00000089: RETURNDATASIZE
0000008a: PUSH1 0x00
0000008c: REVERT
0000008d: JUMPDEST
0000008e: POP
0000008f: POP
00000090: POP
00000091: POP
00000092: PUSH1 0x40
00000094: MLOAD
00000095: RETURNDATASIZE
00000096: PUSH1 0x1f
00000098: NOT
00000099: PUSH1 0x1f
0000009b: DUP3
0000009c: ADD
0000009d: AND
0000009e: DUP3
0000009f: ADD
000000a0: DUP1
000000a1: PUSH1 0x40
000000a3: MSTORE
000000a4: POP
000000a5: DUP2
000000a6: ADD
000000a7: SWAP1
000000a8: PUSH2 0x00b1
000000ab: SWAP2
000000ac: SWAP1
000000ad: PUSH2 0x01a0
000000b0: JUMP
000000b1: JUMPDEST
000000b2: SWAP1
000000b3: POP
000000b4: SWAP1
000000b5: JUMP
000000b6: JUMPDEST
000000b7: CALLDATASIZE
000000b8: PUSH1 0x00
000000ba: DUP1
000000bb: CALLDATACOPY
000000bc: PUSH1 0x00
000000be: DUP1
000000bf: CALLDATASIZE
000000c0: PUSH1 0x00
000000c2: DUP5
000000c3: GAS
000000c4: DELEGATECALL
000000c5: RETURNDATASIZE
000000c6: PUSH1 0x00
000000c8: DUP1
000000c9: RETURNDATACOPY
000000ca: DUP1
000000cb: PUSH1 0x00
000000cd: DUP2
000000ce: EQ
000000cf: PUSH2 0x00d7
000000d2: JUMPI
000000d3: RETURNDATASIZE
000000d4: PUSH1 0x00
000000d6: RETURN
000000d7: JUMPDEST
000000d8: RETURNDATASIZE
000000d9: PUSH1 0x00
000000db: REVERT
000000dc: JUMPDEST
000000dd: PUSH1 0x00
000000df: PUSH2 0x010a
000000e2: PUSH32 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50
00000103: PUSH1 0x00
00000105: SHL
00000106: PUSH2 0x0133
00000109: JUMP
0000010a: JUMPDEST
0000010b: PUSH1 0x00
0000010d: ADD
0000010e: PUSH1 0x00
00000110: SWAP1
00000111: SLOAD
00000112: SWAP1
00000113: PUSH2 0x0100
00000116: EXP
00000117: SWAP1
00000118: DIV
00000119: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000012e: AND
0000012f: SWAP1
00000130: POP
00000131: SWAP1
00000132: JUMP
00000133: JUMPDEST
00000134: PUSH1 0x00
00000136: DUP2
00000137: SWAP1
00000138: POP
00000139: SWAP2
0000013a: SWAP1
0000013b: POP
0000013c: JUMP
0000013d: JUMPDEST
0000013e: PUSH1 0x00
00000140: DUP1
00000141: REVERT
00000142: JUMPDEST
00000143: PUSH1 0x00
00000145: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
0000015a: DUP3
0000015b: AND
0000015c: SWAP1
0000015d: POP
0000015e: SWAP2
0000015f: SWAP1
00000160: POP
00000161: JUMP
00000162: JUMPDEST
00000163: PUSH1 0x00
00000165: PUSH2 0x016d
00000168: DUP3
00000169: PUSH2 0x0142
0000016c: JUMP
0000016d: JUMPDEST
0000016e: SWAP1
0000016f: POP
00000170: SWAP2
00000171: SWAP1
00000172: POP
00000173: JUMP
00000174: JUMPDEST
00000175: PUSH2 0x017d
00000178: DUP2
00000179: PUSH2 0x0162
0000017c: JUMP
0000017d: JUMPDEST
0000017e: DUP2
0000017f: EQ
00000180: PUSH2 0x0188
00000183: JUMPI
00000184: PUSH1 0x00
00000186: DUP1
00000187: REVERT
00000188: JUMPDEST
00000189: POP
0000018a: JUMP
0000018b: JUMPDEST
0000018c: PUSH1 0x00
0000018e: DUP2
0000018f: MLOAD
00000190: SWAP1
00000191: POP
00000192: PUSH2 0x019a
00000195: DUP2
00000196: PUSH2 0x0174
00000199: JUMP
0000019a: JUMPDEST
0000019b: SWAP3
0000019c: SWAP2
0000019d: POP
0000019e: POP
0000019f: JUMP
000001a0: JUMPDEST
000001a1: PUSH1 0x00
000001a3: PUSH1 0x20
000001a5: DUP3
000001a6: DUP5
000001a7: SUB
000001a8: SLT
000001a9: ISZERO
000001aa: PUSH2 0x01b6
000001ad: JUMPI
000001ae: PUSH2 0x01b5
000001b1: PUSH2 0x013d
000001b4: JUMP
000001b5: JUMPDEST
000001b6: JUMPDEST
000001b7: PUSH1 0x00
000001b9: PUSH2 0x01c4
000001bc: DUP5
000001bd: DUP3
000001be: DUP6
000001bf: ADD
000001c0: PUSH2 0x018b
000001c3: JUMP
000001c4: JUMPDEST
000001c5: SWAP2
000001c6: POP
000001c7: POP
000001c8: SWAP3
000001c9: SWAP2
000001ca: POP
000001cb: POP
000001cc: JUMP
000001cd: INVALID
000001ce: LOG2
000001cf: PUSH5 0x6970667358
000001d5: UNKNOWN(0x22)
000001d6: SLT
000001d7: KECCAK256
000001d8: UNKNOWN(0xC0)
000001d9: LOG1
000001da: SLT
000001db: UNKNOWN(0x0E)
000001dc: UNKNOWN(0x2C)
000001dd: SELFBALANCE
000001de: UNKNOWN(0xC1)
000001df: DUP15
000001e0: CALL
000001e1: SWAP10
000001e2: DUP12
000001e3: UNKNOWN(0x0E)
000001e4: UNKNOWN(0xD8)
000001e5: UNKNOWN(0x0D)
000001e6: UNKNOWN(0xF9)
000001e7: MUL
000001e8: UNKNOWN(0xEE)
000001e9: PUSH18 0x87bf8f379f83bf02a851cb9257a764736f6c
000001fc: PUSH4 0x43000813
00000201: STOP
00000202: CALLER

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
critical upgradeability detector Untrusted DELEGATECALL target reachable 70 no no
view
trace_id: 0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2
call_targets: 0x5018cc0d628fb322b2a040cfcd269a36c60b1538
target_varies: no
classification: constant_target
validation_json
{
    "sink": "DELEGATECALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x5018cc0d628fb322b2a040cfcd269a36c60b1538"
    ],
    "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": "0x",
            "selector": "fallback",
            "calldata_variants": [
                "0x"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 196,
            "opcode": "DELEGATECALL",
            "returndata_checked": null,
            "value_expression_category": "n/a",
            "target_expression_category": "computed"
        }
    ],
    "guards_detected": [],
    "delegatecall_count": 1,
    "untrusted_delegatecall_count": 1
}
high other detector Untrusted CALL target/value reachable 60 no no
view
trace_id: 0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2
call_targets: 0x39102c346731672cf013ccf96927bdd21c0419ef
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x39102c346731672cf013ccf96927bdd21c0419ef"
    ],
    "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": "0x",
            "selector": "fallback",
            "calldata_variants": [
                "0x"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 480,
            "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 no no
view
trace_id: 0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2
call_targets: 0x39102c346731672cf013ccf96927bdd21c0419ef
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xaca6b629d0706a91d55aa0ee19f1dafa1b04a0fe4e7d992076ca41ad9bb218a2",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x39102c346731672cf013ccf96927bdd21c0419ef"
    ],
    "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": "0x",
            "selector": "fallback",
            "calldata_variants": [
                "0x"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 480,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "eth_value_calls": 1,
    "guards_detected": []
}
medium upgradeability cast DELEGATECALL present 80 no
view
evidence_json
{
    "notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
    "delegatecall_count": 1
}