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

Analysis Run

019be3d6-8320-73ba-a9ee-5904a566edeb

complete
Chain ID
1
Address
Block Number
Created
Thu, Jan 22, 2026 3:54 AM
Review Summary

What survived the funnel

Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?

Confirmed
0
Validated
0
Source
Bytecode only
Review Backing
Present
Best current signal
Untrusted 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
40792 artifact.fetch complete 1 / 3 2 months ago
40793 proxy.resolve complete 1 / 3 2 months ago
40794 tool.cast_disasm complete 1 / 3 2 months ago
40795 analysis.bundle complete 1 / 3 2 months ago
40796 capability.graph complete 1 / 3 2 months ago
40797 detector.run complete 1 / 3 2 months ago
40798 validation.fork complete 1 / 3 2 months ago
41314 report.consolidate complete 1 / 6 2 months ago

Artifact

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

Slither

tool.slither

No slither job recorded yet.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
2
No findings?
no
Summary
Bytecode exposes a public entrypoint (selector 0xf62d1888) that can perform computed CALL/DELEGATECALL operations; access-control guards are not detected in the artifacts, so verify that only authorized callers can reach these execution paths.
View stdout
{"no_findings":false,"summary":"Bytecode exposes a public entrypoint (selector 0xf62d1888) that can perform computed CALL/DELEGATECALL operations; access-control guards are not detected in the artifacts, so verify that only authorized callers can reach these execution paths.","findings":[{"severity":"medium","category":"access_control","title":"Computed DELEGATECALL target reachable via selector 0xf62d1888","exploit_scenario":"The function at selector 0xf62d1888 reaches a DELEGATECALL (pc:0x0e45) where the target is computed from calldata. If an untrusted caller can invoke this path without strict authorization, they can execute arbitrary code in the contract’s storage context, corrupting state or draining funds held by the proxy/implementation.","recommendation":"Ensure the DELEGATECALL path is gated by explicit authorization (owner/role/entrypoint) on all branches, or restrict the delegatecall target to a fixed allowlist (ideally self). Consider emitting explicit errors when unauthorized to make analysis/monitoring easier.","evidence":"detector_findings reports untrusted_delegatecall_count=1 with computed target at pc 3653 (0x0e45) and no guards detected; disassembly shows DELEGATECALL at pc 0x0e45 in selector 0xf62d1888.","locations":["selector:0xf62d1888","pc:0x0e45"]},{"severity":"medium","category":"access_control","title":"Arbitrary external CALL (with ETH value) reachable via selector 0xf62d1888","exploit_scenario":"Selector 0xf62d1888 reaches multiple CALL sites (pc:0x0865/0x138e/0x28d0/0x2b5d/0x2d46/0x304b) where both target and value are computed. If these paths are accessible to untrusted callers, they can initiate arbitrary external calls and transfer ETH or tokens, effectively turning the contract into a publicly callable execution proxy.","recommendation":"Confirm that all CALL paths are protected by strong authorization checks (owner/signature/role). If the intent is limited execution, validate targets/values and consider reentrancy protections around state updates that follow external calls.","evidence":"detector_findings show untrusted_call_count=7 and eth_value_calls=7 with computed targets/values; callsites include pc 2149 (0x0865), 5006 (0x138e), 10448 (0x28d0), 11101 (0x2b5d), 11590 (0x2d46), 12363 (0x304b).","locations":["selector:0xf62d1888","pc:0x0865","pc:0x138e","pc:0x28d0","pc:0x2b5d","pc:0x2d46","pc:0x304b"]}]}
View stderr
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-ylb6ajnl
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019be430-13d3-7f72-b257-377bc983c7d6
--------
user
Context: The user requested the proxy at 0xbcaf70ef342378755e82c9f374225604f04a36e3.
Audit the implementation at 0x62c9e5e52351e02635f48072fa20c03bb650f787.
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
**Choosing simple file read**

Deciding to use plain file read (like cat) for BYTECODE_BUNDLE.json since it’s read-only and straightforward, avoiding more complex tools.
exec
/bin/bash -lc ls in /tmp/codex-ylb6ajnl succeeded in 7ms:
BYTECODE_BUNDLE.json
codex-output-schema.json
exec
/bin/bash -lc 'cat BYTECODE_BUNDLE.json' in /tmp/codex-ylb6ajnl succeeded in 8ms:
{
  "analysis_artifact": {
    "address": "0x62c9e5e52351e02635f48072fa20c03bb650f787",
    "artifact_hash": "0x77b379e7186a6b5eb9963cb81f2925a57aa78bdb84bded332186f09e1a5c6ab0",
    "artifact_json": {
      "auth": {
        "guards": []
      },
      "basic_blocks": [
        {
          "end_pc": 12,
          "hash": "0xc5a3c3aa00eba015ed0720784b5e3e794ef56cfc83f359a7d27a5ecb05fc4ca7",
          "opcodes": [
            "PUSH1",
            "PUSH1",
            "MSTORE",
            "PUSH1",
            "CALLDATASIZE",
            "LT",
            "PUSH2",

thinking
**Searching evidence bundle references**

I'm using ripgrep to locate key terms like evidence_bundle, selector mapping, and storage slots within the large file to pinpoint relevant sections for bytecode analysis.
exec
/bin/bash -lc 'rg -n "evidence|storage|selector|proxy|implementation|admin|owner|upgrade|EIP" BYTECODE_BUNDLE.json | head -n 200' in /tmp/codex-ylb6ajnl succeeded in 11ms:
25318:      "dispatcher_type": "selector_jump_table",
25322:          "selector": "0xcb1eec6d"
25326:          "selector": "0xdb6b5246"
25330:          "selector": "0xed24911d"
25334:          "selector": "0xf2fde38b"
25338:          "selector": "0xf62d1888"
25342:          "selector": "0x8c42f5aa"
25346:          "selector": "0x8da5cb5b"
25350:          "selector": "0xac9650d8"
25354:          "selector": "0xb52c14f4"
25358:          "selector": "0xc8b2feb2"
25362:          "selector": "0x58b8dc6c"
25366:          "selector": "0x69328dec"
25370:          "selector": "0x71061398"
25374:          "selector": "0x72403331"
25378:          "selector": "0x84b0196e"
25382:          "selector": "0x150b7a02"
25386:          "selector": "0x1626ba7e"
25390:          "selector": "0x39f02d6d"
25394:          "selector": "0x46739e73"

thinking
**Extracting storage and selector sections**
exec
/bin/bash -lc "sed -n '25290,25580p' BYTECODE_BUNDLE.json" in /tmp/codex-ylb6ajnl succeeded in 14ms:
        },
        {
          "from": "bb:17236",
          "to": "bb:17247",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:17250",
          "to": "bb:17262",
          "type": "control_flow"
        },
        {
          "from": "bb:17250",
          "to": "bb:17259",
          "type": "control_flow_fallthrough"
        },
        {
          "from": "bb:17275",
          "to": "bb:17291",
          "type": "control_flow"

thinking
**Investigating delegatecall and access controls**

Found potential delegatecall/call usage near a main execute function indicating proxy or plugin behavior; lacking explicit auth guards suggests careful auditing of access controls is needed. Next, I'll analyze evidence around the indicated offsets to clarify safeguards and verify untrusted calls.
exec
/bin/bash -lc "sed -n '45620,45940p' BYTECODE_BUNDLE.json" in /tmp/codex-ylb6ajnl succeeded in 11ms:
        {
          "id": "call:12135",
          "opcode": "STATICCALL",
          "pc": 12135,
          "type": "callsite"
        },
        {
          "id": "call:12363",
          "opcode": "CALL",
          "pc": 12363,
          "type": "callsite"
        },
        {
          "id": "call:17315",
          "opcode": "CALLCODE",
          "pc": 17315,
          "type": "callsite"
        },
        {
          "id": "sink:staticcall",

thinking
**Planning function access control inspection**

I'm examining function sections for selectors, storage, and callsites to gather evidence on access control, including owner checks and delegatecall usage without guards. Next, I'll search for "callsites" in these sections to detect relevant calls and verify guard presence.
exec
/bin/bash -lc 'rg -n "callsites|callsite|call_paths|delegatecall|CALLCODE" BYTECODE_BUNDLE.json | head -n 200' in /tmp/codex-ylb6ajnl succeeded in 12ms:
19240:            "CALLCODE",
19268:      "callsites": [
19508:          "opcode": "CALLCODE",
25410:            "delegatecall": 1,
25709:            "delegatecall": 1,
26008:            "delegatecall": 1,
26307:            "delegatecall": 1,
26606:            "delegatecall": 1,
26905:            "delegatecall": 1,
27204:            "delegatecall": 1,
27503:            "delegatecall": 1,
27802:            "delegatecall": 1,
28101:            "delegatecall": 1,
28400:            "delegatecall": 1,
28699:            "delegatecall": 1,
28998:            "delegatecall": 1,
29297:            "delegatecall": 1,
29596:            "delegatecall": 1,
29895:            "delegatecall": 1,
30194:            "delegatecall": 1,

thinking
**Planning inspection of callsites and function sections**
exec
/bin/bash -lc "sed -n '19180,19560p' BYTECODE_BUNDLE.json" in /tmp/codex-ylb6ajnl succeeded in 14ms:
            "JUMPDEST",
            "PUSH0",
            "PUSH1",
            "OP_82",
            "OP_84",
            "SUB",
            "SLT",
            "ISZERO",
            "PUSH2",
            "JUMPI"
          ],
          "start_pc": 17275
        },
        {
          "end_pc": 17290,
          "hash": "0xd572833224d16610c76c47cb7946cfcedd66c55050fca3c2631db0de6353beeb",
          "opcodes": [
            "PUSH0",
            "OP_80",
            "REVERT"

thinking
**Planning inspection of function-specific call paths**

I'm considering analyzing per-function storage and call patterns to reveal main flows, focusing on call paths or sink paths likely under "function_summary". Next, I'll search for relevant "paths" data across functions to guide parsing.
exec
/bin/bash -lc 'rg -n "call_paths|sink_paths|paths" BYTECODE_BUNDLE.json | head -n 200' in /tmp/codex-ylb6ajnl succeeded in 9ms:


thinking
**Inspecting nearby evidence bundle sections**

I'm checking lines around 31360-31780 for function-related data like "function_summaries" to better understand the structure beyond the function list.
exec
/bin/bash -lc "sed -n '31360,31840p' BYTECODE_BUNDLE.json" in /tmp/codex-ylb6ajnl succeeded in 19ms:
                "pc": 10776,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
              },
              {
                "op": "SLOAD",
                "pc": 12071,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000006"
              },
              {
                "op": "SLOAD",
                "pc": 16449,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000004046"
              },
              {
                "op": "SLOAD",
                "pc": 16605,
                "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
              }
            ],
            "writes": 22


thinking
**Mapping runtime selectors and access controls**

I'm identifying function selectors from the runtime bytecode, including known ones like owner() and transferOwnership(), to analyze key functions for missing access controls, especially around delegatecalls that may be exposed to untrusted callers.
thinking
**Planning manual disassembly for critical opcodes**

I'm preparing to write a Python script to disassemble the large runtime bytecode manually, focusing on locating CALL, DELEGATECALL, and CALLCODE opcodes near key program counters to analyze access controls around potentially dangerous external calls.
exec
/bin/bash -lc "python3 - <<'PY'
import json
import sys
from pathlib import Path

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json','r') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'):
    code=code[2:]
bytecode=bytes.fromhex(code)

# opcode map
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 and index by pc
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,op,name,data))
    pc+=size

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

def context(pc,back=8,forward=8):
    if pc not in idx:
        # find nearest
        keys=[p for p in idx if p<=pc]
        if not keys:
            return []
        pc=max(keys)
    i=idx[pc]
    start=max(0,i-back)
    end=min(len(insts),i+forward+1)
    out=[]
    for j in range(start,end):
        p,op,name,data=insts[j]
        if data is None:
            out.append(f\"{p:05d}: {name}\")
        else:
            out.append(f\"{p:05d}: {name} 0x{data.hex()}\")
    return out

# find all CALL/DELEGATECALL/CALLCODE
call_pcs=[p for p,op,name,_ in insts if name in ('CALL','DELEGATECALL','CALLCODE')]
print('call pcs',call_pcs[:20], 'total', len(call_pcs))
for target in [2149,3653,5006,10448,11101,11590,12363,17315]:
    print('\\n== context around pc', target)
    for line in context(target,back=10,forward=10):
        print(line)
PY" in /tmp/codex-ylb6ajnl succeeded in 50ms:
call pcs [2149, 3653, 5006, 10448, 11101, 11590, 12363, 17315] total 8

== context around pc 2149
02138: OP_5f
02139: PUSH1 0x40
02141: MLOAD
02142: DUP1
02143: DUP4
02144: SUB
02145: DUP2
02146: DUP6
02147: DUP8
02148: GAS
02149: CALL
02150: SWAP3
02151: POP
02152: POP
02153: POP
02154: RETURNDATASIZE
02155: DUP1

thinking
**Planning function selector parsing**

I'm preparing to parse the early bytecode (500 bytes) to identify function selectors by detecting patterns like PUSH4 selector, EQ, PUSH2 dest, and JUMPI, enabling mapping of selectors to jump destinations within the dispatch code.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=bytes.fromhex(code)

# opcode map
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
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

# find selector patterns in first 400 bytes
selectors=[]
for i in range(len(insts)-4):
    pc,name,data=insts[i]
    if name=='PUSH4' and data is not None:
        # look ahead for EQ and JUMPI with PUSH2 dest
        if insts[i+1][1]=='EQ' and insts[i+2][1] in ('PUSH2','PUSH1','PUSH3','PUSH4') and insts[i+3][1]=='JUMPI':
            dest=int.from_bytes(insts[i+2][2],'big')
            sel='0x'+data.hex()
            selectors.append((sel,dest,pc))

# also handle pattern DUP1 PUSH4 EQ PUSH2 JUMPI; find PUSH4 with later EQ? but above maybe not; we can just print all push4 in first 300 bytes.

print('Found selector patterns:',len(selectors))
for sel,dest,pc in selectors:
    print(f'{sel} -> 0x{dest:04x} (pc {pc})')

# print first 200 instructions to see dispatch
print('\\nFirst 120 instructions:')
for pc,name,data in insts[:120]:
    if data is None:
        print(f'{pc:04d}: {name}')
    else:
        print(f'{pc:04d}: {name} 0x{data.hex()}')

PY" in /tmp/codex-ylb6ajnl succeeded in 64ms:
Found selector patterns: 20
0xcb1eec6d -> 0x0350 (pc 41)
0xdb6b5246 -> 0x0363 (pc 52)
0xed24911d -> 0x036b (pc 63)
0xf2fde38b -> 0x038d (pc 74)
0xf62d1888 -> 0x03ac (pc 85)
0x8c42f5aa -> 0x02d9 (pc 98)
0x8da5cb5b -> 0x02ec (pc 109)
0xac9650d8 -> 0x0309 (pc 120)
0xb52c14f4 -> 0x031c (pc 131)
0xc8b2feb2 -> 0x033c (pc 142)
0x58b8dc6c -> 0x0231 (pc 166)
0x69328dec -> 0x0251 (pc 177)
0x71061398 -> 0x0270 (pc 188)
0x72403331 -> 0x0291 (pc 199)
0x84b0196e -> 0x02b2 (pc 210)
0x150b7a02 -> 0x0154 (pc 223)
0x1626ba7e -> 0x019d (pc 234)
0x39f02d6d -> 0x01bc (pc 245)
0x46739e73 -> 0x01f3 (pc 256)

thinking
**Planning function-callsite mapping**

I'm outlining an approach to map callsites to functions by using jump destinations as function entry points and assigning callsite PCs to the nearest preceding function start to identify which functions contain delegatecall instructions.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

# disassemble
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

# find selector->dest patterns
selectors=[]
for i in range(len(insts)-4):
    pc,name,data=insts[i]
    if name=='PUSH4' and data is not None:
        if insts[i+1][1]=='EQ' and insts[i+2][1].startswith('PUSH') and insts[i+3][1]=='JUMPI':
            dest=int.from_bytes(insts[i+2][2],'big')
            selectors.append((data.hex(),dest,pc))

# map callsite to containing function based on dest ordering
func_entries=sorted([(dest,sel) for sel,dest,_ in selectors])

# callsites of interest
call_pcs=[p for p,op,name,_ in [(pc,bytecode[pc],opcodes.get(bytecode[pc]),None) for pc in range(len(bytecode))] if False]

# we already know call pcs from earlier: 2149,3653,5006,10448,11101,11590,12363
call_pcs=[2149,3653,5006,10448,11101,11590,12363]

for cp in call_pcs:
    # find last entry <= cp
    entry_sel=None
    entry_pc=None
    for dest,sel in func_entries:
        if dest<=cp:
            entry_pc=dest
            entry_sel=sel
        else:
            break
    print(f'call pc {cp} -> function selector 0x{entry_sel} entry {entry_pc}')

# show function entry addresses
print('Function entries:')
for dest,sel in func_entries:
    print(f'0x{sel} at 0x{dest:04x}')
PY" in /tmp/codex-ylb6ajnl succeeded in 53ms:
call pc 2149 -> function selector 0xf62d1888 entry 940
call pc 3653 -> function selector 0xf62d1888 entry 940
call pc 5006 -> function selector 0xf62d1888 entry 940
call pc 10448 -> function selector 0xf62d1888 entry 940
call pc 11101 -> function selector 0xf62d1888 entry 940
call pc 11590 -> function selector 0xf62d1888 entry 940
call pc 12363 -> function selector 0xf62d1888 entry 940
Function entries:
0x150b7a02 at 0x0154
0x1626ba7e at 0x019d
0x39f02d6d at 0x01bc
0x46739e73 at 0x01f3
0x47e7ef24 at 0x0212
0x58b8dc6c at 0x0231
0x69328dec at 0x0251
0x71061398 at 0x0270
0x72403331 at 0x0291
0x84b0196e at 0x02b2
0x8c42f5aa at 0x02d9
0x8da5cb5b at 0x02ec

thinking
**Disassembling function with multiple calls**

Planning to disassemble and annotate the instructions around the function entry at 0x03ac (selector 0xf62d1888) to understand its logic, access control checks, and the external calls it makes including delegatecall.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

# disassemble
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

# get instructions from entry 0x03ac until maybe 0x0600
start=0x03ac
end=0x0600
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 74ms:
03ac: JUMPDEST
03ad: CALLVALUE
03ae: DUP1
03af: ISZERO
03b0: PUSH2 0x03b7
03b3: JUMPI
03b4: OP_5f
03b5: DUP1
03b6: REVERT
03b7: JUMPDEST
03b8: POP
03b9: PUSH2 0x0152
03bc: PUSH2 0x03c6
03bf: CALLDATASIZE
03c0: PUSH1 0x04
03c2: PUSH2 0x3725
03c5: JUMP
03c6: JUMPDEST
03c7: PUSH2 0x17ca
03ca: JUMP

thinking
**Mapping complex function and access control**

The large function includes an owner check via slot 0x06 and extensive internal logic, suggesting it’s a multi-purpose executor or upgrade function with access control. Next, I'll verify known selectors like owner() by inspecting their related code sections.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

# disassemble
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

# function entry mapping from earlier
entries={
    0x0154:'0x150b7a02',
    0x019d:'0x1626ba7e',
    0x01bc:'0x39f02d6d',
    0x01f3:'0x46739e73',
    0x0212:'0x47e7ef24',
    0x0231:'0x58b8dc6c',
    0x0251:'0x69328dec',
    0x0270:'0x71061398',
    0x0291:'0x72403331',
    0x02b2:'0x84b0196e',
    0x02d9:'0x8c42f5aa',
    0x02ec:'0x8da5cb5b',
    0x0309:'0xac9650d8',
    0x031c:'0xb52c14f4',
    0x033c:'0xc8b2feb2',
    0x0350:'0xcb1eec6d',
    0x0363:'0xdb6b5246',
    0x036b:'0xed24911d',
    0x038d:'0xf2fde38b',
    0x03ac:'0xf62d1888'
}

def dump(start,end):
    for pc,name,data in insts:
        if pc<start: continue
        if pc>end: break
        if data is None:
            print(f'{pc:04x}: {name}')
        else:
            print(f'{pc:04x}: {name} 0x{data.hex()}')

# dump around owner() at 0x02ec
print('--- function 0x8da5cb5b at 0x02ec ---')
dump(0x02ec,0x0308)

print('\\n--- function 0xf2fde38b at 0x038d ---')
dump(0x038d,0x03ab)
PY" in /tmp/codex-ylb6ajnl succeeded in 65ms:
--- function 0x8da5cb5b at 0x02ec ---
02ec: JUMPDEST
02ed: CALLVALUE
02ee: DUP1
02ef: ISZERO
02f0: PUSH2 0x02f7
02f3: JUMPI
02f4: OP_5f
02f5: DUP1
02f6: REVERT
02f7: JUMPDEST
02f8: POP
02f9: PUSH1 0x02
02fb: SLOAD
02fc: PUSH1 0x01
02fe: PUSH1 0x01
0300: PUSH1 0xa0
0302: SHL
0303: SUB
0304: AND

thinking
**Inspecting delegatecall access control**

I'm focusing on the delegatecall at pc 3653 inside the function at 0xf62d1888 to verify if proper owner or signature checks precede it, examining surrounding instructions for critical access control.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

# disassemble
insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

start=0x0e10
end=0x0ee0
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 62ms:
0e12: JUMPI
0e13: PUSH2 0x0e1a
0e16: PUSH2 0x37ee
0e19: JUMP
0e1a: JUMPDEST
0e1b: SWAP1
0e1c: POP
0e1d: PUSH1 0x20
0e1f: MUL
0e20: DUP2
0e21: ADD
0e22: SWAP1
0e23: PUSH2 0x0e2c
0e26: SWAP2
0e27: SWAP1
0e28: PUSH2 0x383a
0e2b: JUMP
0e2c: JUMPDEST
0e2d: PUSH1 0x40
0e2f: MLOAD


thinking
**Tracing delegatecall target source**

I’m tracing how the delegatecall target is set since it’s likely loaded from calldata or stack earlier; the function’s use of call vs. delegatecall hints at a parameter controlling operation type, similar to Gnosis Safe patterns, but selectors don’t match exactly, suggesting this might be a different account model like ERC-4337 or ERC-6551.
thinking
**Analyzing access checks and selector matching**

I’m mapping storage slots to owner and entryPoint roles, seeing dual access checks that may guard delegatecall operations, suggesting proper authorization; next, I’ll compute function selectors locally to confirm if observed selectors match ERC-4337 execute/executeBatch signatures.
exec
/bin/bash -lc "python3 - <<'PY'
try:
    import sha3
    print('sha3 module available')
except Exception as e:
    print('sha3 not available', e)
try:
    from eth_hash.auto import keccak
    print('eth_hash available')
except Exception as e:
    print('eth_hash not available', e)
PY" in /tmp/codex-ylb6ajnl succeeded in 87ms:
sha3 not available No module named 'sha3'
eth_hash available

thinking
**Computing keccak for candidate signatures**

I'll compute keccak hashes for typical function signatures to map them to selectors and compare against the selectors list, using Python for the calculations.
exec
/bin/bash -lc "python3 - <<'PY'
from eth_hash.auto import keccak

selectors=[
    '0x150b7a02','0x1626ba7e','0x39f02d6d','0x46739e73','0x47e7ef24','0x58b8dc6c','0x69328dec','0x71061398','0x72403331','0x84b0196e','0x8c42f5aa','0x8da5cb5b','0xac9650d8','0xb52c14f4','0xc8b2feb2','0xcb1eec6d','0xdb6b5246','0xed24911d','0xf2fde38b','0xf62d1888']

candidates=[
    'execute(address,uint256,bytes)',
    'executeBatch(address[],uint256[],bytes[])',
    'executeBatch(address[],bytes[])',
    'executeCall(address,uint256,bytes)',
    'executeCall(address,uint256,bytes,bytes)',
    'executeCall(address,uint256,bytes,uint8)',
    'validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)',
    'validateUserOp(bytes32,bytes,uint256)',
    'entryPoint()',
    'getNonce()',
    'nonce()',
    'getDeposit()',
    'addDeposit()',
    'withdrawDepositTo(address,uint256)',
    'transferOwnership(address)',
    'owner()',
    'isValidSignature(bytes32,bytes)',
    'supportsInterface(bytes4)',
    'onERC721Received(address,address,uint256,bytes)',
    'onERC1155Received(address,address,uint256,uint256,bytes)',
    'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)',
    'upgradeTo(address)',
    'upgradeToAndCall(address,bytes)',
    'initialize(address)',
    'initialize(address,address)',
    'initialize(address,uint256)',
    'initialize(address,address,address)',
    'setOwner(address)',
    'setEntryPoint(address)',
    'getImplementation()',
    'implementation()',
    'proxiableUUID()',
    'version()',
    'name()',
    'symbol()',
    'token()',
    'accountVersion()',
    'execute(address,uint256,bytes,uint8)',
    'execute(address,uint256,bytes,bool)',
    'execute(address,uint256,bytes,uint8,bool)',
    'execute(address,uint256,bytes,uint8,bytes)',
]

cand_map={}
for sig in candidates:
    sel=keccak(sig.encode())[:4].hex()
    if '0x'+sel in selectors:
        cand_map[sig]='0x'+sel

print('Matches:')
for sig,sel in cand_map.items():
    print(sig, sel)

# also compute selectors for all candidates to see if any close
print('\\nAll candidate selectors:')
for sig in candidates:
    sel='0x'+keccak(sig.encode())[:4].hex()
    print(sig, sel, 'MATCH' if sel in selectors else '')
PY" in /tmp/codex-ylb6ajnl succeeded in 95ms:
Matches:
transferOwnership(address) 0xf2fde38b
owner() 0x8da5cb5b
isValidSignature(bytes32,bytes) 0x1626ba7e
onERC721Received(address,address,uint256,bytes) 0x150b7a02

All candidate selectors:
execute(address,uint256,bytes) 0xb61d27f6 
executeBatch(address[],uint256[],bytes[]) 0x47e1da2a 
executeBatch(address[],bytes[]) 0x18dfb3c7 
executeCall(address,uint256,bytes) 0x9e5d4c49 
executeCall(address,uint256,bytes,bytes) 0x268cab12 
executeCall(address,uint256,bytes,uint8) 0xe8ccaa0b 
validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256) 0x3a871cdd 
validateUserOp(bytes32,bytes,uint256) 0x636cbe46 
entryPoint() 0xb0d691fe 
getNonce() 0xd087d288 
nonce() 0xaffed0e0 
getDeposit() 0xc399ec88 
addDeposit() 0x4a58db19 


thinking
**Analyzing custom contract selectors and storage**

The contract uses nonstandard selectors suggesting a custom interface, possibly an EIP-1271 wallet with unique errors and mappings. I'll focus on runtime code patterns, storage slot usage, and access control checks near key functions to support a security review with clear evidence.
thinking
**Investigating signature validation logic**

I spotted storage checks potentially gating functions and am focusing on detecting ECDSA signature validation around the isValidSignature selector. I'll disassemble relevant sections to confirm if the contract calls the ecrecover precompile for signature verification.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

start=0x019d
end=0x01bc-1
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 66ms:
019d: JUMPDEST
019e: CALLVALUE
019f: DUP1
01a0: ISZERO
01a1: PUSH2 0x01a8
01a4: JUMPI
01a5: OP_5f
01a6: DUP1
01a7: REVERT
01a8: JUMPDEST
01a9: POP
01aa: PUSH2 0x017f
01ad: PUSH2 0x01b7
01b0: CALLDATASIZE
01b1: PUSH1 0x04
01b3: PUSH2 0x32f6
01b6: JUMP
01b7: JUMPDEST
01b8: PUSH2 0x03cb
01bb: JUMP


thinking
**Identifying shared signature validation logic**

The function for signature validation jumps to the same internal code used by the main execute-like function, indicating shared verification logic. This suggests that although access control checks exist, the execute function allows arbitrary external calls, which could pose reentrancy risks if protections are insufficient.
thinking
**Investigating call sites and potential reentrancy**

I'm analyzing call instructions near key bytecode positions to check if state updates like nonce changes occur after external calls, which could enable reentrancy. The signature validation function may invoke external validators via CALL or STATICCALL, but delegatecall use appears elsewhere, so I'll disassemble around specific call sites to clarify how calls and state updates interact.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

start=0x0830
end=0x0900
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 45ms:
0833: EQ
0834: DUP1
0835: PUSH2 0x0845
0838: JUMPI
0839: POP
083a: PUSH1 0x01
083c: PUSH1 0x01
083e: PUSH1 0xa0
0840: SHL
0841: SUB
0842: DUP4
0843: AND
0844: ISZERO
0845: JUMPDEST
0846: ISZERO
0847: PUSH2 0x0916
084a: JUMPI
084b: OP_5f
084c: DUP2
084d: PUSH1 0x01


thinking
**Identifying delegatecall and external call risks**

The contract uses an ETH sentinel constant and safeERC20 transfers, suggesting it manages swaps or token routing, possibly as an aggregator module. It includes untrusted delegatecall and external calls with value that could allow arbitrary external calls if access control is insufficient, so clarifying entry-point guards and authorization enforcement is critical next.
thinking
**Flagging unclear access control and signature validation**

The delegatecall function lacks detected standard guards though a custom caller check exists, leaving access control uncertain. Next, I'll investigate signature validation by searching for the ERC-1271 magic value to assess its correctness and potential bypass risks.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=bytes.fromhex(code)

# find occurrences of bytes of 0x1626ba7e
needle=bytes.fromhex('1626ba7e')
positions=[i for i in range(len(bytecode)-4) if bytecode[i:i+4]==needle]
print('positions', positions[:20], 'count', len(positions))
PY" in /tmp/codex-ylb6ajnl succeeded in 51ms:
positions [235] count 1


thinking
**Assessing signature validation and reentrancy risks**

The signature validation may rely on constant return values elsewhere, complicating direct checks. There's a notable external delegatecall with computed targets and no access guards, risking storage corruption and fund loss if exposed to untrusted callers. Potential reentrancy is uncertain since state updates after external calls are unclear, and no evident reentrancy lock is detected.
thinking
**Confirming high delegatecall risk with unclear access control**

The delegatecall uses a calldata-derived target with no detected guards, and the function is externally callable, making access control unclear but potentially absent. Call success is checked properly via returndata handling, reducing concern there. Ownership updates and storage slots show typical patterns, but authorization logic remains non-obvious, supporting a high-severity finding for arbitrary delegatecall access.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

start=0x0291
end=0x02b1
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 79ms:
0291: JUMPDEST
0292: CALLVALUE
0293: DUP1
0294: ISZERO
0295: PUSH2 0x029c
0298: JUMPI
0299: OP_5f
029a: DUP1
029b: REVERT
029c: JUMPDEST
029d: POP
029e: PUSH2 0x02a5
02a1: PUSH2 0x0b71
02a4: JUMP
02a5: JUMPDEST
02a6: PUSH1 0x40
02a8: MLOAD
02a9: PUSH2 0x0194
02ac: SWAP2
02ad: SWAP1

thinking
**Analyzing fallback and receive functions**

I'm focusing on the fallback/receive area around 0x0116 since calldata size <4 jumps there, possibly indicating a payable fallback or receive that emits events without restrictions, which could reveal untrusted external call or delegatecall risks.
exec
/bin/bash -lc "python3 - <<'PY'
import json

with open('/tmp/codex-ylb6ajnl/BYTECODE_BUNDLE.json') as f:
    data=json.load(f)
code=data['artifact']['runtime_bytecode']['full']
if code.startswith('0x'): code=code[2:]
bytecode=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'
}

insts=[]
pc=0
while pc < len(bytecode):
    op=bytecode[pc]
    name=opcodes.get(op, f'OP_{op:02x}')
    data=None
    size=1
    if 0x60 <= op <= 0x7f:
        n=op-0x5f
        data=bytecode[pc+1:pc+1+n]
        size=1+n
    insts.append((pc,name,data))
    pc+=size

start=0x0116
end=0x0153
for pc,name,data in insts:
    if pc<start: continue
    if pc>end: break
    if data is None:
        print(f'{pc:04x}: {name}')
    else:
        print(f'{pc:04x}: {name} 0x{data.hex()}')
PY" in /tmp/codex-ylb6ajnl succeeded in 46ms:
0116: JUMPDEST
0117: CALLDATASIZE
0118: PUSH2 0x0152
011b: JUMPI
011c: PUSH1 0x40
011e: MLOAD
011f: CALLVALUE
0120: DUP2
0121: MSTORE
0122: CALLER
0123: SWAP1
0124: PUSH32 0x410eba6f268aeb1b263fbec6294fd6b86a7289f0a1b4afd5dd325c89ade8565c
0145: SWAP1
0146: PUSH1 0x20
0148: ADD
0149: PUSH1 0x40
014b: MLOAD
014c: DUP1
014d: SWAP2
014e: SUB


thinking
**Summarizing fallback and delegatecall risks**

The fallback with non-empty calldata simply stops, while empty calldata logs a deposit event. There’s a critical risk from an unguarded delegatecall target derived from calldata, allowing arbitrary storage writes or execution. Also, an untrusted external call with ETH transfer is reachable, posing a high-severity risk; these issues need separate findings with access control recommendations.
thinking
**Refining severity and findings with evidence**

I'm setting two medium-severity findings for the externally callable function selector performing computed delegatecall and external call with ETH, citing detector evidence and bytecode PCs. The analysis notes no detected access control guards but acknowledges uncertainty, recommending strict authorization or call restrictions and adding reentrancy guards if needed. I'll compile these details into a structured JSON output with clear summaries, evidence references, and actionable recommendations.
codex
{"no_findings":false,"summary":"Bytecode exposes a public entrypoint (selector 0xf62d1888) that can perform computed CALL/DELEGATECALL operations; access-control guards are not detected in the artifacts, so verify that only authorized callers can reach these execution paths.","findings":[{"severity":"medium","category":"access_control","title":"Computed DELEGATECALL target reachable via selector 0xf62d1888","exploit_scenario":"The function at selector 0xf62d1888 reaches a DELEGATECALL (pc:0x0e45) where the target is computed from calldata. If an untrusted caller can invoke this path without strict authorization, they can execute arbitrary code in the contract’s storage context, corrupting state or draining funds held by the proxy/implementation.","recommendation":"Ensure the DELEGATECALL path is gated by explicit authorization (owner/role/entrypoint) on all branches, or restrict the delegatecall target to a fixed allowlist (ideally self). Consider emitting explicit errors when unauthorized to make analysis/monitoring easier.","evidence":"detector_findings reports untrusted_delegatecall_count=1 with computed target at pc 3653 (0x0e45) and no guards detected; disassembly shows DELEGATECALL at pc 0x0e45 in selector 0xf62d1888.","locations":["selector:0xf62d1888","pc:0x0e45"]},{"severity":"medium","category":"access_control","title":"Arbitrary external CALL (with ETH value) reachable via selector 0xf62d1888","exploit_scenario":"Selector 0xf62d1888 reaches multiple CALL sites (pc:0x0865/0x138e/0x28d0/0x2b5d/0x2d46/0x304b) where both target and value are computed. If these paths are accessible to untrusted callers, they can initiate arbitrary external calls and transfer ETH or tokens, effectively turning the contract into a publicly callable execution proxy.","recommendation":"Confirm that all CALL paths are protected by strong authorization checks (owner/signature/role). If the intent is limited execution, validate targets/values and consider reentrancy protections around state updates that follow external calls.","evidence":"detector_findings show untrusted_call_count=7 and eth_value_calls=7 with computed targets/values; callsites include pc 2149 (0x0865), 5006 (0x138e), 10448 (0x28d0), 11101 (0x2b5d), 11590 (0x2d46), 12363 (0x304b).","locations":["selector:0xf62d1888","pc:0x0865","pc:0x138e","pc:0x28d0","pc:0x2b5d","pc:0x2d46","pc:0x304b"]}]}
tokens used
166,822
Metadata
{
    "codex": {
        "ran_at": "2026-01-22T05:40:38.693954+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "bytecode",
        "bytecode_length": 34706,
        "bytecode_truncated": false,
        "capability_graph_present": true,
        "analysis_artifact_present": true
    },
    "summary": "Bytecode exposes a public entrypoint (selector 0xf62d1888) that can perform computed CALL/DELEGATECALL operations; access-control guards are not detected in the artifacts, so verify that only authorized callers can reach these execution paths.",
    "raw_final": {
        "summary": "Bytecode exposes a public entrypoint (selector 0xf62d1888) that can perform computed CALL/DELEGATECALL operations; access-control guards are not detected in the artifacts, so verify that only authorized callers can reach these execution paths.",
        "findings": [
            {
                "title": "Computed DELEGATECALL target reachable via selector 0xf62d1888",
                "category": "access_control",
                "evidence": "detector_findings reports untrusted_delegatecall_count=1 with computed target at pc 3653 (0x0e45) and no guards detected; disassembly shows DELEGATECALL at pc 0x0e45 in selector 0xf62d1888.",
                "severity": "medium",
                "locations": [
                    "selector:0xf62d1888",
                    "pc:0x0e45"
                ],
                "recommendation": "Ensure the DELEGATECALL path is gated by explicit authorization (owner/role/entrypoint) on all branches, or restrict the delegatecall target to a fixed allowlist (ideally self). Consider emitting explicit errors when unauthorized to make analysis/monitoring easier.",
                "exploit_scenario": "The function at selector 0xf62d1888 reaches a DELEGATECALL (pc:0x0e45) where the target is computed from calldata. If an untrusted caller can invoke this path without strict authorization, they can execute arbitrary code in the contract\u2019s storage context, corrupting state or draining funds held by the proxy/implementation."
            },
            {
                "title": "Arbitrary external CALL (with ETH value) reachable via selector 0xf62d1888",
                "category": "access_control",
                "evidence": "detector_findings show untrusted_call_count=7 and eth_value_calls=7 with computed targets/values; callsites include pc 2149 (0x0865), 5006 (0x138e), 10448 (0x28d0), 11101 (0x2b5d), 11590 (0x2d46), 12363 (0x304b).",
                "severity": "medium",
                "locations": [
                    "selector:0xf62d1888",
                    "pc:0x0865",
                    "pc:0x138e",
                    "pc:0x28d0",
                    "pc:0x2b5d",
                    "pc:0x2d46",
                    "pc:0x304b"
                ],
                "recommendation": "Confirm that all CALL paths are protected by strong authorization checks (owner/signature/role). If the intent is limited execution, validate targets/values and consider reentrancy protections around state updates that follow external calls.",
                "exploit_scenario": "Selector 0xf62d1888 reaches multiple CALL sites (pc:0x0865/0x138e/0x28d0/0x2b5d/0x2d46/0x304b) where both target and value are computed. If these paths are accessible to untrusted callers, they can initiate arbitrary external calls and transfer ETH or tokens, effectively turning the contract into a publicly callable execution proxy."
            }
        ],
        "no_findings": false
    },
    "no_findings": false,
    "proxy_context": {
        "proxy_run_id": "019be3d6-8320-73ba-a9ee-5904a566edeb",
        "proxy_address": "0xbcaf70ef342378755e82c9f374225604f04a36e3",
        "implementation_run_id": "019be3d7-e47d-7320-ae56-01c14905ff89",
        "implementation_address": "0x62c9e5e52351e02635f48072fa20c03bb650f787"
    },
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
2
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
0
EXT*/BALANCE
2
Total opcodes
1123
Flags
delegatecall_present
View cast disassembly output
00000000: PUSH1 0x80
00000002: PUSH1 0x40
00000004: MSTORE
00000005: PUSH1 0x04
00000007: CALLDATASIZE
00000008: LT
00000009: PUSH2 0x004d
0000000c: JUMPI
0000000d: PUSH0
0000000e: CALLDATALOAD
0000000f: PUSH1 0xe0
00000011: SHR
00000012: DUP1
00000013: PUSH4 0x3659cfe6
00000018: EQ
00000019: PUSH2 0x0064
0000001c: JUMPI
0000001d: DUP1
0000001e: PUSH4 0x4f1ef286
00000023: EQ
00000024: PUSH2 0x0077
00000027: JUMPI
00000028: DUP1
00000029: PUSH4 0x5c60da1b
0000002e: EQ
0000002f: PUSH2 0x008a
00000032: JUMPI
00000033: DUP1
00000034: PUSH4 0x8f283970
00000039: EQ
0000003a: PUSH2 0x00ae
0000003d: JUMPI
0000003e: DUP1
0000003f: PUSH4 0xf851a440
00000044: EQ
00000045: PUSH2 0x00c1
00000048: JUMPI
00000049: PUSH2 0x005c
0000004c: JUMP
0000004d: JUMPDEST
0000004e: CALLDATASIZE
0000004f: PUSH2 0x005c
00000052: JUMPI
00000053: PUSH2 0x005a
00000056: PUSH2 0x00c9
00000059: JUMP
0000005a: JUMPDEST
0000005b: STOP
0000005c: JUMPDEST
0000005d: PUSH2 0x005a
00000060: PUSH2 0x00c9
00000063: JUMP
00000064: JUMPDEST
00000065: PUSH2 0x005a
00000068: PUSH2 0x0072
0000006b: CALLDATASIZE
0000006c: PUSH1 0x04
0000006e: PUSH2 0x0692
00000071: JUMP
00000072: JUMPDEST
00000073: PUSH2 0x00e3
00000076: JUMP
00000077: JUMPDEST
00000078: PUSH2 0x005a
0000007b: PUSH2 0x0085
0000007e: CALLDATASIZE
0000007f: PUSH1 0x04
00000081: PUSH2 0x06ab
00000084: JUMP
00000085: JUMPDEST
00000086: PUSH2 0x0126
00000089: JUMP
0000008a: JUMPDEST
0000008b: PUSH2 0x0092
0000008e: PUSH2 0x018c
00000091: JUMP
00000092: JUMPDEST
00000093: PUSH1 0x40
00000095: MLOAD
00000096: PUSH1 0x01
00000098: PUSH1 0x01
0000009a: PUSH1 0xa0
0000009c: SHL
0000009d: SUB
0000009e: SWAP1
0000009f: SWAP2
000000a0: AND
000000a1: DUP2
000000a2: MSTORE
000000a3: PUSH1 0x20
000000a5: ADD
000000a6: PUSH1 0x40
000000a8: MLOAD
000000a9: DUP1
000000aa: SWAP2
000000ab: SUB
000000ac: SWAP1
000000ad: RETURN
000000ae: JUMPDEST
000000af: PUSH2 0x005a
000000b2: PUSH2 0x00bc
000000b5: CALLDATASIZE
000000b6: PUSH1 0x04
000000b8: PUSH2 0x0692
000000bb: JUMP
000000bc: JUMPDEST
000000bd: PUSH2 0x01c4
000000c0: JUMP
000000c1: JUMPDEST
000000c2: PUSH2 0x0092
000000c5: PUSH2 0x01ec
000000c8: JUMP
000000c9: JUMPDEST
000000ca: PUSH2 0x00d1
000000cd: PUSH2 0x0214
000000d0: JUMP
000000d1: JUMPDEST
000000d2: PUSH2 0x00e1
000000d5: PUSH2 0x00dc
000000d8: PUSH2 0x02a9
000000db: JUMP
000000dc: JUMPDEST
000000dd: PUSH2 0x02b2
000000e0: JUMP
000000e1: JUMPDEST
000000e2: JUMP
000000e3: JUMPDEST
000000e4: PUSH2 0x00eb
000000e7: PUSH2 0x02d0
000000ea: JUMP
000000eb: JUMPDEST
000000ec: PUSH1 0x01
000000ee: PUSH1 0x01
000000f0: PUSH1 0xa0
000000f2: SHL
000000f3: SUB
000000f4: AND
000000f5: CALLER
000000f6: SUB
000000f7: PUSH2 0x011e
000000fa: JUMPI
000000fb: PUSH2 0x0102
000000fe: PUSH2 0x0302
00000101: JUMP
00000102: JUMPDEST
00000103: PUSH2 0x011b
00000106: DUP2
00000107: PUSH1 0x40
00000109: MLOAD
0000010a: DUP1
0000010b: PUSH1 0x20
0000010d: ADD
0000010e: PUSH1 0x40
00000110: MSTORE
00000111: DUP1
00000112: PUSH0
00000113: DUP2
00000114: MSTORE
00000115: POP
00000116: PUSH0
00000117: PUSH2 0x030c
0000011a: JUMP
0000011b: JUMPDEST
0000011c: POP
0000011d: JUMP
0000011e: JUMPDEST
0000011f: PUSH2 0x011b
00000122: PUSH2 0x00c9
00000125: JUMP
00000126: JUMPDEST
00000127: PUSH2 0x012e
0000012a: PUSH2 0x02d0
0000012d: JUMP
0000012e: JUMPDEST
0000012f: PUSH1 0x01
00000131: PUSH1 0x01
00000133: PUSH1 0xa0
00000135: SHL
00000136: SUB
00000137: AND
00000138: CALLER
00000139: SUB
0000013a: PUSH2 0x0184
0000013d: JUMPI
0000013e: PUSH2 0x017f
00000141: DUP4
00000142: DUP4
00000143: DUP4
00000144: DUP1
00000145: DUP1
00000146: PUSH1 0x1f
00000148: ADD
00000149: PUSH1 0x20
0000014b: DUP1
0000014c: SWAP2
0000014d: DIV
0000014e: MUL
0000014f: PUSH1 0x20
00000151: ADD
00000152: PUSH1 0x40
00000154: MLOAD
00000155: SWAP1
00000156: DUP2
00000157: ADD
00000158: PUSH1 0x40
0000015a: MSTORE
0000015b: DUP1
0000015c: SWAP4
0000015d: SWAP3
0000015e: SWAP2
0000015f: SWAP1
00000160: DUP2
00000161: DUP2
00000162: MSTORE
00000163: PUSH1 0x20
00000165: ADD
00000166: DUP4
00000167: DUP4
00000168: DUP1
00000169: DUP3
0000016a: DUP5
0000016b: CALLDATACOPY
0000016c: PUSH0
0000016d: SWAP3
0000016e: ADD
0000016f: SWAP2
00000170: SWAP1
00000171: SWAP2
00000172: MSTORE
00000173: POP
00000174: PUSH1 0x01
00000176: SWAP3
00000177: POP
00000178: PUSH2 0x030c
0000017b: SWAP2
0000017c: POP
0000017d: POP
0000017e: JUMP
0000017f: JUMPDEST
00000180: POP
00000181: POP
00000182: POP
00000183: JUMP
00000184: JUMPDEST
00000185: PUSH2 0x017f
00000188: PUSH2 0x00c9
0000018b: JUMP
0000018c: JUMPDEST
0000018d: PUSH0
0000018e: PUSH2 0x0195
00000191: PUSH2 0x02d0
00000194: JUMP
00000195: JUMPDEST
00000196: PUSH1 0x01
00000198: PUSH1 0x01
0000019a: PUSH1 0xa0
0000019c: SHL
0000019d: SUB
0000019e: AND
0000019f: CALLER
000001a0: SUB
000001a1: PUSH2 0x01b9
000001a4: JUMPI
000001a5: PUSH2 0x01ac
000001a8: PUSH2 0x0302
000001ab: JUMP
000001ac: JUMPDEST
000001ad: PUSH2 0x01b4
000001b0: PUSH2 0x02a9
000001b3: JUMP
000001b4: JUMPDEST
000001b5: SWAP1
000001b6: POP
000001b7: SWAP1
000001b8: JUMP
000001b9: JUMPDEST
000001ba: PUSH2 0x01c1
000001bd: PUSH2 0x00c9
000001c0: JUMP
000001c1: JUMPDEST
000001c2: SWAP1
000001c3: JUMP
000001c4: JUMPDEST
000001c5: PUSH2 0x01cc
000001c8: PUSH2 0x02d0
000001cb: JUMP
000001cc: JUMPDEST
000001cd: PUSH1 0x01
000001cf: PUSH1 0x01
000001d1: PUSH1 0xa0
000001d3: SHL
000001d4: SUB
000001d5: AND
000001d6: CALLER
000001d7: SUB
000001d8: PUSH2 0x011e
000001db: JUMPI
000001dc: PUSH2 0x01e3
000001df: PUSH2 0x0302
000001e2: JUMP
000001e3: JUMPDEST
000001e4: PUSH2 0x011b
000001e7: DUP2
000001e8: PUSH2 0x0336
000001eb: JUMP
000001ec: JUMPDEST
000001ed: PUSH0
000001ee: PUSH2 0x01f5
000001f1: PUSH2 0x02d0
000001f4: JUMP
000001f5: JUMPDEST
000001f6: PUSH1 0x01
000001f8: PUSH1 0x01
000001fa: PUSH1 0xa0
000001fc: SHL
000001fd: SUB
000001fe: AND
000001ff: CALLER
00000200: SUB
00000201: PUSH2 0x01b9
00000204: JUMPI
00000205: PUSH2 0x020c
00000208: PUSH2 0x0302
0000020b: JUMP
0000020c: JUMPDEST
0000020d: PUSH2 0x01b4
00000210: PUSH2 0x02d0
00000213: JUMP
00000214: JUMPDEST
00000215: PUSH2 0x021c
00000218: PUSH2 0x02d0
0000021b: JUMP
0000021c: JUMPDEST
0000021d: PUSH1 0x01
0000021f: PUSH1 0x01
00000221: PUSH1 0xa0
00000223: SHL
00000224: SUB
00000225: AND
00000226: CALLER
00000227: SUB
00000228: PUSH2 0x00e1
0000022b: JUMPI
0000022c: PUSH1 0x40
0000022e: MLOAD
0000022f: PUSH3 0x461bcd
00000233: PUSH1 0xe5
00000235: SHL
00000236: DUP2
00000237: MSTORE
00000238: PUSH1 0x20
0000023a: PUSH1 0x04
0000023c: DUP3
0000023d: ADD
0000023e: MSTORE
0000023f: PUSH1 0x42
00000241: PUSH1 0x24
00000243: DUP3
00000244: ADD
00000245: MSTORE
00000246: PUSH32 0x5472616e73706172656e745570677261646561626c6550726f78793a2061646d
00000267: PUSH1 0x44
00000269: DUP3
0000026a: ADD
0000026b: MSTORE
0000026c: PUSH32 0x696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267
0000028d: PUSH1 0x64
0000028f: DUP3
00000290: ADD
00000291: MSTORE
00000292: PUSH2 0x195d
00000295: PUSH1 0xf2
00000297: SHL
00000298: PUSH1 0x84
0000029a: DUP3
0000029b: ADD
0000029c: MSTORE
0000029d: PUSH1 0xa4
0000029f: ADD
000002a0: JUMPDEST
000002a1: PUSH1 0x40
000002a3: MLOAD
000002a4: DUP1
000002a5: SWAP2
000002a6: SUB
000002a7: SWAP1
000002a8: REVERT
000002a9: JUMPDEST
000002aa: PUSH0
000002ab: PUSH2 0x01b4
000002ae: PUSH2 0x038a
000002b1: JUMP
000002b2: JUMPDEST
000002b3: CALLDATASIZE
000002b4: PUSH0
000002b5: DUP1
000002b6: CALLDATACOPY
000002b7: PUSH0
000002b8: DUP1
000002b9: CALLDATASIZE
000002ba: PUSH0
000002bb: DUP5
000002bc: GAS
000002bd: DELEGATECALL
000002be: RETURNDATASIZE
000002bf: PUSH0
000002c0: DUP1
000002c1: RETURNDATACOPY
000002c2: DUP1
000002c3: DUP1
000002c4: ISZERO
000002c5: PUSH2 0x02cc
000002c8: JUMPI
000002c9: RETURNDATASIZE
000002ca: PUSH0
000002cb: RETURN
000002cc: JUMPDEST
000002cd: RETURNDATASIZE
000002ce: PUSH0
000002cf: REVERT
000002d0: JUMPDEST
000002d1: PUSH0
000002d2: PUSH32 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103
000002f3: JUMPDEST
000002f4: SLOAD
000002f5: PUSH1 0x01
000002f7: PUSH1 0x01
000002f9: PUSH1 0xa0
000002fb: SHL
000002fc: SUB
000002fd: AND
000002fe: SWAP2
000002ff: SWAP1
00000300: POP
00000301: JUMP
00000302: JUMPDEST
00000303: CALLVALUE
00000304: ISZERO
00000305: PUSH2 0x00e1
00000308: JUMPI
00000309: PUSH0
0000030a: DUP1
0000030b: REVERT
0000030c: JUMPDEST
0000030d: PUSH2 0x0315
00000310: DUP4
00000311: PUSH2 0x03b1
00000314: JUMP
00000315: JUMPDEST
00000316: PUSH0
00000317: DUP3
00000318: MLOAD
00000319: GT
0000031a: DUP1
0000031b: PUSH2 0x0321
0000031e: JUMPI
0000031f: POP
00000320: DUP1
00000321: JUMPDEST
00000322: ISZERO
00000323: PUSH2 0x017f
00000326: JUMPI
00000327: PUSH2 0x0330
0000032a: DUP4
0000032b: DUP4
0000032c: PUSH2 0x03f0
0000032f: JUMP
00000330: JUMPDEST
00000331: POP
00000332: POP
00000333: POP
00000334: POP
00000335: JUMP
00000336: JUMPDEST
00000337: PUSH32 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f
00000358: PUSH2 0x035f
0000035b: PUSH2 0x02d0
0000035e: JUMP
0000035f: JUMPDEST
00000360: PUSH1 0x40
00000362: DUP1
00000363: MLOAD
00000364: PUSH1 0x01
00000366: PUSH1 0x01
00000368: PUSH1 0xa0
0000036a: SHL
0000036b: SUB
0000036c: SWAP3
0000036d: DUP4
0000036e: AND
0000036f: DUP2
00000370: MSTORE
00000371: SWAP2
00000372: DUP5
00000373: AND
00000374: PUSH1 0x20
00000376: DUP4
00000377: ADD
00000378: MSTORE
00000379: ADD
0000037a: PUSH1 0x40
0000037c: MLOAD
0000037d: DUP1
0000037e: SWAP2
0000037f: SUB
00000380: SWAP1
00000381: LOG1
00000382: PUSH2 0x011b
00000385: DUP2
00000386: PUSH2 0x041c
00000389: JUMP
0000038a: JUMPDEST
0000038b: PUSH0
0000038c: PUSH32 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
000003ad: PUSH2 0x02f3
000003b0: JUMP
000003b1: JUMPDEST
000003b2: PUSH2 0x03ba
000003b5: DUP2
000003b6: PUSH2 0x04c5
000003b9: JUMP
000003ba: JUMPDEST
000003bb: PUSH1 0x40
000003bd: MLOAD
000003be: PUSH1 0x01
000003c0: PUSH1 0x01
000003c2: PUSH1 0xa0
000003c4: SHL
000003c5: SUB
000003c6: DUP3
000003c7: AND
000003c8: SWAP1
000003c9: PUSH32 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b
000003ea: SWAP1
000003eb: PUSH0
000003ec: SWAP1
000003ed: LOG2
000003ee: POP
000003ef: JUMP
000003f0: JUMPDEST
000003f1: PUSH1 0x60
000003f3: PUSH2 0x0415
000003f6: DUP4
000003f7: DUP4
000003f8: PUSH1 0x40
000003fa: MLOAD
000003fb: DUP1
000003fc: PUSH1 0x60
000003fe: ADD
000003ff: PUSH1 0x40
00000401: MSTORE
00000402: DUP1
00000403: PUSH1 0x27
00000405: DUP2
00000406: MSTORE
00000407: PUSH1 0x20
00000409: ADD
0000040a: PUSH2 0x0799
0000040d: PUSH1 0x27
0000040f: SWAP2
00000410: CODECOPY
00000411: PUSH2 0x0559
00000414: JUMP
00000415: JUMPDEST
00000416: SWAP4
00000417: SWAP3
00000418: POP
00000419: POP
0000041a: POP
0000041b: JUMP
0000041c: JUMPDEST
0000041d: PUSH1 0x01
0000041f: PUSH1 0x01
00000421: PUSH1 0xa0
00000423: SHL
00000424: SUB
00000425: DUP2
00000426: AND
00000427: PUSH2 0x0481
0000042a: JUMPI
0000042b: PUSH1 0x40
0000042d: MLOAD
0000042e: PUSH3 0x461bcd
00000432: PUSH1 0xe5
00000434: SHL
00000435: DUP2
00000436: MSTORE
00000437: PUSH1 0x20
00000439: PUSH1 0x04
0000043b: DUP3
0000043c: ADD
0000043d: MSTORE
0000043e: PUSH1 0x26
00000440: PUSH1 0x24
00000442: DUP3
00000443: ADD
00000444: MSTORE
00000445: PUSH32 0x455243313936373a206e65772061646d696e20697320746865207a65726f2061
00000466: PUSH1 0x44
00000468: DUP3
00000469: ADD
0000046a: MSTORE
0000046b: PUSH6 0x646472657373
00000472: PUSH1 0xd0
00000474: SHL
00000475: PUSH1 0x64
00000477: DUP3
00000478: ADD
00000479: MSTORE
0000047a: PUSH1 0x84
0000047c: ADD
0000047d: PUSH2 0x02a0
00000480: JUMP
00000481: JUMPDEST
00000482: DUP1
00000483: PUSH32 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103
000004a4: JUMPDEST
000004a5: DUP1
000004a6: SLOAD
000004a7: PUSH1 0x01
000004a9: PUSH1 0x01
000004ab: PUSH1 0xa0
000004ad: SHL
000004ae: SUB
000004af: NOT
000004b0: AND
000004b1: PUSH1 0x01
000004b3: PUSH1 0x01
000004b5: PUSH1 0xa0
000004b7: SHL
000004b8: SUB
000004b9: SWAP3
000004ba: SWAP1
000004bb: SWAP3
000004bc: AND
000004bd: SWAP2
000004be: SWAP1
000004bf: SWAP2
000004c0: OR
000004c1: SWAP1
000004c2: SSTORE
000004c3: POP
000004c4: JUMP
000004c5: JUMPDEST
000004c6: PUSH1 0x01
000004c8: PUSH1 0x01
000004ca: PUSH1 0xa0
000004cc: SHL
000004cd: SUB
000004ce: DUP2
000004cf: AND
000004d0: EXTCODESIZE
000004d1: PUSH2 0x0532
000004d4: JUMPI
000004d5: PUSH1 0x40
000004d7: MLOAD
000004d8: PUSH3 0x461bcd
000004dc: PUSH1 0xe5
000004de: SHL
000004df: DUP2
000004e0: MSTORE
000004e1: PUSH1 0x20
000004e3: PUSH1 0x04
000004e5: DUP3
000004e6: ADD
000004e7: MSTORE
000004e8: PUSH1 0x2d
000004ea: PUSH1 0x24
000004ec: DUP3
000004ed: ADD
000004ee: MSTORE
000004ef: PUSH32 0x455243313936373a206e657720696d706c656d656e746174696f6e206973206e
00000510: PUSH1 0x44
00000512: DUP3
00000513: ADD
00000514: MSTORE
00000515: PUSH13 0x1bdd08184818dbdb9d1c9858dd
00000523: PUSH1 0x9a
00000525: SHL
00000526: PUSH1 0x64
00000528: DUP3
00000529: ADD
0000052a: MSTORE
0000052b: PUSH1 0x84
0000052d: ADD
0000052e: PUSH2 0x02a0
00000531: JUMP
00000532: JUMPDEST
00000533: DUP1
00000534: PUSH32 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
00000555: PUSH2 0x04a4
00000558: JUMP
00000559: JUMPDEST
0000055a: PUSH1 0x60
0000055c: PUSH0
0000055d: DUP1
0000055e: DUP6
0000055f: PUSH1 0x01
00000561: PUSH1 0x01
00000563: PUSH1 0xa0
00000565: SHL
00000566: SUB
00000567: AND
00000568: DUP6
00000569: PUSH1 0x40
0000056b: MLOAD
0000056c: PUSH2 0x0575
0000056f: SWAP2
00000570: SWAP1
00000571: PUSH2 0x074b
00000574: JUMP
00000575: JUMPDEST
00000576: PUSH0
00000577: PUSH1 0x40
00000579: MLOAD
0000057a: DUP1
0000057b: DUP4
0000057c: SUB
0000057d: DUP2
0000057e: DUP6
0000057f: GAS
00000580: DELEGATECALL
00000581: SWAP2
00000582: POP
00000583: POP
00000584: RETURNDATASIZE
00000585: DUP1
00000586: PUSH0
00000587: DUP2
00000588: EQ
00000589: PUSH2 0x05ad
0000058c: JUMPI
0000058d: PUSH1 0x40
0000058f: MLOAD
00000590: SWAP2
00000591: POP
00000592: PUSH1 0x1f
00000594: NOT
00000595: PUSH1 0x3f
00000597: RETURNDATASIZE
00000598: ADD
00000599: AND
0000059a: DUP3
0000059b: ADD
0000059c: PUSH1 0x40
0000059e: MSTORE
0000059f: RETURNDATASIZE
000005a0: DUP3
000005a1: MSTORE
000005a2: RETURNDATASIZE
000005a3: PUSH0
000005a4: PUSH1 0x20
000005a6: DUP5
000005a7: ADD
000005a8: RETURNDATACOPY
000005a9: PUSH2 0x05b2
000005ac: JUMP
000005ad: JUMPDEST
000005ae: PUSH1 0x60
000005b0: SWAP2
000005b1: POP
000005b2: JUMPDEST
000005b3: POP
000005b4: SWAP2
000005b5: POP
000005b6: SWAP2
000005b7: POP
000005b8: PUSH2 0x05c3
000005bb: DUP7
000005bc: DUP4
000005bd: DUP4
000005be: DUP8
000005bf: PUSH2 0x05cd
000005c2: JUMP
000005c3: JUMPDEST
000005c4: SWAP7
000005c5: SWAP6
000005c6: POP
000005c7: POP
000005c8: POP
000005c9: POP
000005ca: POP
000005cb: POP
000005cc: JUMP
000005cd: JUMPDEST
000005ce: PUSH1 0x60
000005d0: DUP4
000005d1: ISZERO
000005d2: PUSH2 0x063b
000005d5: JUMPI
000005d6: DUP3
000005d7: MLOAD
000005d8: PUSH0
000005d9: SUB
000005da: PUSH2 0x0634
000005dd: JUMPI
000005de: PUSH1 0x01
000005e0: PUSH1 0x01
000005e2: PUSH1 0xa0
000005e4: SHL
000005e5: SUB
000005e6: DUP6
000005e7: AND
000005e8: EXTCODESIZE
000005e9: PUSH2 0x0634
000005ec: JUMPI
000005ed: PUSH1 0x40
000005ef: MLOAD
000005f0: PUSH3 0x461bcd
000005f4: PUSH1 0xe5
000005f6: SHL
000005f7: DUP2
000005f8: MSTORE
000005f9: PUSH1 0x20
000005fb: PUSH1 0x04
000005fd: DUP3
000005fe: ADD
000005ff: MSTORE
00000600: PUSH1 0x1d
00000602: PUSH1 0x24
00000604: DUP3
00000605: ADD
00000606: MSTORE
00000607: PUSH32 0x416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000
00000628: PUSH1 0x44
0000062a: DUP3
0000062b: ADD
0000062c: MSTORE
0000062d: PUSH1 0x64
0000062f: ADD
00000630: PUSH2 0x02a0
00000633: JUMP
00000634: JUMPDEST
00000635: POP
00000636: DUP2
00000637: PUSH2 0x0645
0000063a: JUMP
0000063b: JUMPDEST
0000063c: PUSH2 0x0645
0000063f: DUP4
00000640: DUP4
00000641: PUSH2 0x064d
00000644: JUMP
00000645: JUMPDEST
00000646: SWAP5
00000647: SWAP4
00000648: POP
00000649: POP
0000064a: POP
0000064b: POP
0000064c: JUMP
0000064d: JUMPDEST
0000064e: DUP2
0000064f: MLOAD
00000650: ISZERO
00000651: PUSH2 0x065d
00000654: JUMPI
00000655: DUP2
00000656: MLOAD
00000657: DUP1
00000658: DUP4
00000659: PUSH1 0x20
0000065b: ADD
0000065c: REVERT
0000065d: JUMPDEST
0000065e: DUP1
0000065f: PUSH1 0x40
00000661: MLOAD
00000662: PUSH3 0x461bcd
00000666: PUSH1 0xe5
00000668: SHL
00000669: DUP2
0000066a: MSTORE
0000066b: PUSH1 0x04
0000066d: ADD
0000066e: PUSH2 0x02a0
00000671: SWAP2
00000672: SWAP1
00000673: PUSH2 0x0766
00000676: JUMP
00000677: JUMPDEST
00000678: DUP1
00000679: CALLDATALOAD
0000067a: PUSH1 0x01
0000067c: PUSH1 0x01
0000067e: PUSH1 0xa0
00000680: SHL
00000681: SUB
00000682: DUP2
00000683: AND
00000684: DUP2
00000685: EQ
00000686: PUSH2 0x068d
00000689: JUMPI
0000068a: PUSH0
0000068b: DUP1
0000068c: REVERT
0000068d: JUMPDEST
0000068e: SWAP2
0000068f: SWAP1
00000690: POP
00000691: JUMP
00000692: JUMPDEST
00000693: PUSH0
00000694: PUSH1 0x20
00000696: DUP3
00000697: DUP5
00000698: SUB
00000699: SLT
0000069a: ISZERO
0000069b: PUSH2 0x06a2
0000069e: JUMPI
0000069f: PUSH0
000006a0: DUP1
000006a1: REVERT
000006a2: JUMPDEST
000006a3: PUSH2 0x0415
000006a6: DUP3
000006a7: PUSH2 0x0677
000006aa: JUMP
000006ab: JUMPDEST
000006ac: PUSH0
000006ad: DUP1
000006ae: PUSH0
000006af: PUSH1 0x40
000006b1: DUP5
000006b2: DUP7
000006b3: SUB
000006b4: SLT
000006b5: ISZERO
000006b6: PUSH2 0x06bd
000006b9: JUMPI
000006ba: PUSH0
000006bb: DUP1
000006bc: REVERT
000006bd: JUMPDEST
000006be: PUSH2 0x06c6
000006c1: DUP5
000006c2: PUSH2 0x0677
000006c5: JUMP
000006c6: JUMPDEST
000006c7: SWAP3
000006c8: POP
000006c9: PUSH1 0x20
000006cb: DUP5
000006cc: ADD
000006cd: CALLDATALOAD
000006ce: PUSH8 0xffffffffffffffff
000006d7: DUP2
000006d8: GT
000006d9: ISZERO
000006da: PUSH2 0x06e1
000006dd: JUMPI
000006de: PUSH0
000006df: DUP1
000006e0: REVERT
000006e1: JUMPDEST
000006e2: DUP5
000006e3: ADD
000006e4: PUSH1 0x1f
000006e6: DUP2
000006e7: ADD
000006e8: DUP7
000006e9: SGT
000006ea: PUSH2 0x06f1
000006ed: JUMPI
000006ee: PUSH0
000006ef: DUP1
000006f0: REVERT
000006f1: JUMPDEST
000006f2: DUP1
000006f3: CALLDATALOAD
000006f4: PUSH8 0xffffffffffffffff
000006fd: DUP2
000006fe: GT
000006ff: ISZERO
00000700: PUSH2 0x0707
00000703: JUMPI
00000704: PUSH0
00000705: DUP1
00000706: REVERT
00000707: JUMPDEST
00000708: DUP7
00000709: PUSH1 0x20
0000070b: DUP3
0000070c: DUP5
0000070d: ADD
0000070e: ADD
0000070f: GT
00000710: ISZERO
00000711: PUSH2 0x0718
00000714: JUMPI
00000715: PUSH0
00000716: DUP1
00000717: REVERT
00000718: JUMPDEST
00000719: SWAP4
0000071a: SWAP7
0000071b: PUSH1 0x20
0000071d: SWAP2
0000071e: SWAP1
0000071f: SWAP2
00000720: ADD
00000721: SWAP6
00000722: POP
00000723: SWAP3
00000724: SWAP4
00000725: POP
00000726: POP
00000727: POP
00000728: JUMP
00000729: JUMPDEST
0000072a: PUSH0
0000072b: JUMPDEST
0000072c: DUP4
0000072d: DUP2
0000072e: LT
0000072f: ISZERO
00000730: PUSH2 0x0743
00000733: JUMPI
00000734: DUP2
00000735: DUP2
00000736: ADD
00000737: MLOAD
00000738: DUP4
00000739: DUP3
0000073a: ADD
0000073b: MSTORE
0000073c: PUSH1 0x20
0000073e: ADD
0000073f: PUSH2 0x072b
00000742: JUMP
00000743: JUMPDEST
00000744: POP
00000745: POP
00000746: PUSH0
00000747: SWAP2
00000748: ADD
00000749: MSTORE
0000074a: JUMP
0000074b: JUMPDEST
0000074c: PUSH0
0000074d: DUP3
0000074e: MLOAD
0000074f: PUSH2 0x075c
00000752: DUP2
00000753: DUP5
00000754: PUSH1 0x20
00000756: DUP8
00000757: ADD
00000758: PUSH2 0x0729
0000075b: JUMP
0000075c: JUMPDEST
0000075d: SWAP2
0000075e: SWAP1
0000075f: SWAP2
00000760: ADD
00000761: SWAP3
00000762: SWAP2
00000763: POP
00000764: POP
00000765: JUMP
00000766: JUMPDEST
00000767: PUSH1 0x20
00000769: DUP2
0000076a: MSTORE
0000076b: PUSH0
0000076c: DUP3
0000076d: MLOAD
0000076e: DUP1
0000076f: PUSH1 0x20
00000771: DUP5
00000772: ADD
00000773: MSTORE
00000774: PUSH2 0x0784
00000777: DUP2
00000778: PUSH1 0x40
0000077a: DUP6
0000077b: ADD
0000077c: PUSH1 0x20
0000077e: DUP8
0000077f: ADD
00000780: PUSH2 0x0729
00000783: JUMP
00000784: JUMPDEST
00000785: PUSH1 0x1f
00000787: ADD
00000788: PUSH1 0x1f
0000078a: NOT
0000078b: AND
0000078c: SWAP2
0000078d: SWAP1
0000078e: SWAP2
0000078f: ADD
00000790: PUSH1 0x40
00000792: ADD
00000793: SWAP3
00000794: SWAP2
00000795: POP
00000796: POP
00000797: JUMP
00000798: INVALID
00000799: COINBASE
0000079a: PUSH5 0x6472657373
000007a0: GASPRICE
000007a1: KECCAK256
000007a2: PUSH13 0x6f772d6c6576656c2064656c65
000007b0: PUSH8 0x6174652063616c6c
000007b9: KECCAK256
000007ba: PUSH7 0x61696c6564a264
000007c2: PUSH10 0x706673582212200877dd
000007cd: SELFBALANCE
000007ce: BASEFEE
000007cf: ADDRESS
000007d0: UNKNOWN(0xF7)
000007d1: ADD
000007d2: PUSH4 0xc455fb72
000007d7: JUMPDEST
000007d8: SWAP12
000007d9: UNKNOWN(0xE6)
000007da: LOG4
000007db: PUSH15 0x5898136c0dea5007a60f1c01544a64
000007eb: PUSH20

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: 0x1bfc246ef69e1617b5b75cb156a7c2ed64440b69b36a72cc977aee5983a41c88
call_targets: 0x62c9e5e52351e02635f48072fa20c03bb650f787
target_varies: no
classification: constant_target
validation_json
{
    "sink": "DELEGATECALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 2,
    "trace_id": "0x1bfc246ef69e1617b5b75cb156a7c2ed64440b69b36a72cc977aee5983a41c88",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x62c9e5e52351e02635f48072fa20c03bb650f787"
    ],
    "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": "0x3659cfe6",
            "selector": "0x3659cfe6",
            "calldata_variants": [
                "0x3659cfe6",
                "0x3659cfe60000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x4f1ef286",
            "selector": "0x4f1ef286",
            "calldata_variants": [
                "0x4f1ef286",
                "0x4f1ef2860000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x5c60da1b",
            "selector": "0x5c60da1b",
            "calldata_variants": [
                "0x5c60da1b",
                "0x5c60da1b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0x8f283970",
            "selector": "0x8f283970",
            "calldata_variants": [
                "0x8f283970",
                "0x8f2839700000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xf851a440",
            "selector": "0xf851a440",
            "calldata_variants": [
                "0xf851a440",
                "0xf851a4400000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 701,
            "opcode": "DELEGATECALL",
            "returndata_checked": null,
            "value_expression_category": "n/a",
            "target_expression_category": "computed"
        },
        {
            "pc": 1408,
            "opcode": "DELEGATECALL",
            "returndata_checked": null,
            "value_expression_category": "n/a",
            "target_expression_category": "computed"
        }
    ],
    "guards_detected": [],
    "delegatecall_count": 2,
    "untrusted_delegatecall_count": 2
}
medium upgradeability cast DELEGATECALL present 80 no
view
evidence_json
{
    "notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
    "delegatecall_count": 2
}
medium access_control codex Computed DELEGATECALL target reachable via selector 0xf62d1888 75 no
view
evidence_json
{
    "evidence": "detector_findings reports untrusted_delegatecall_count=1 with computed target at pc 3653 (0x0e45) and no guards detected; disassembly shows DELEGATECALL at pc 0x0e45 in selector 0xf62d1888.",
    "locations": [
        "selector:0xf62d1888",
        "pc:0x0e45"
    ],
    "recommendation": "Ensure the DELEGATECALL path is gated by explicit authorization (owner/role/entrypoint) on all branches, or restrict the delegatecall target to a fixed allowlist (ideally self). Consider emitting explicit errors when unauthorized to make analysis/monitoring easier.",
    "exploit_scenario": "The function at selector 0xf62d1888 reaches a DELEGATECALL (pc:0x0e45) where the target is computed from calldata. If an untrusted caller can invoke this path without strict authorization, they can execute arbitrary code in the contract\u2019s storage context, corrupting state or draining funds held by the proxy/implementation."
}
medium access_control codex Arbitrary external CALL (with ETH value) reachable via selector 0xf62d1888 75 no
view
evidence_json
{
    "evidence": "detector_findings show untrusted_call_count=7 and eth_value_calls=7 with computed targets/values; callsites include pc 2149 (0x0865), 5006 (0x138e), 10448 (0x28d0), 11101 (0x2b5d), 11590 (0x2d46), 12363 (0x304b).",
    "locations": [
        "selector:0xf62d1888",
        "pc:0x0865",
        "pc:0x138e",
        "pc:0x28d0",
        "pc:0x2b5d",
        "pc:0x2d46",
        "pc:0x304b"
    ],
    "recommendation": "Confirm that all CALL paths are protected by strong authorization checks (owner/signature/role). If the intent is limited execution, validate targets/values and consider reentrancy protections around state updates that follow external calls.",
    "exploit_scenario": "Selector 0xf62d1888 reaches multiple CALL sites (pc:0x0865/0x138e/0x28d0/0x2b5d/0x2d46/0x304b) where both target and value are computed. If these paths are accessible to untrusted callers, they can initiate arbitrary external calls and transfer ETH or tokens, effectively turning the contract into a publicly callable execution proxy."
}