019bab3b-ab58-7009-8f77-aa62cd038a53
Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?
| ID | Type | Status | Attempts | Heartbeat |
|---|---|---|---|---|
| 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 |
{
"method": "beacon",
"status": "onchain_only",
"implementation": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538",
"onchain_method": "beacon"
}
No slither job recorded yet.
{"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":[]}
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
{
"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
}
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
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| critical | upgradeability | detector | Untrusted DELEGATECALL target reachable | 70 | no | no |
viewtrace_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 |
viewtrace_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 |
viewtrace_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 | — |
viewevidence_json{
"notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
"delegatecall_count": 1
}
|