019c0ea9-09b4-70d2-b921-de227abe0b6b
Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?
| ID | Type | Status | Attempts | Heartbeat |
|---|---|---|---|---|
| 42152 | artifact.fetch | complete | 1 / 3 | 2 months ago |
| 42153 | proxy.resolve | complete | 1 / 3 | 2 months ago |
| 42154 | tool.cast_disasm | complete | 1 / 3 | 2 months ago |
| 42155 | analysis.bundle | complete | 1 / 3 | 2 months ago |
| 42156 | capability.graph | complete | 1 / 3 | 2 months ago |
| 42157 | detector.run | complete | 1 / 3 | 2 months ago |
| 42158 | validation.fork | complete | 1 / 3 | 2 months ago |
| 42474 | report.consolidate | complete | 1 / 6 | 2 months ago |
{
"method": "beacon",
"status": "onchain_only",
"implementation": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538",
"onchain_method": "beacon"
}
No slither job recorded yet.
{"no_findings":false,"summary":"One low-severity issue identified: the external initializer can set the owner if the proxy is ever left uninitialized.","findings":[{"severity":"low","category":"access_control","title":"Initializer is externally callable; uninitialized proxy can be taken over","exploit_scenario":"If the beacon proxy is deployed without an initialization call, any account can invoke `initialize` (selector `0xc4d66de8`) and set itself as the owner. The new owner can then call owner‑only withdrawal functions to move ETH/tokens/NFTs held by the proxy.","recommendation":"Ensure the proxy is initialized atomically during deployment. Consider adding a constructor that calls `_disableInitializers()` in the implementation and/or enforce `onlyProxy`/deployer checks on initialization routines.","evidence":"The implementation exposes an initializer at `selector:0xc4d66de8` that writes the owner to storage slot `0x2` with only the Initializable guard (no caller restriction). Owner‑only checks compare `msg.sender` against slot `0x2` (e.g., in asset withdrawal paths).","locations":["selector:0xc4d66de8","pc:0x08cc"]}]}
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-i15plyr1
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019c0f8f-f23e-7bd1-8ebe-a707c348435e
--------
user
Context: The user requested the proxy at 0xb71125df00a98a671f82c7b2e70e646ea2fa5894.
Audit the implementation at 0x5018cc0d628fb322b2a040cfcd269a36c60b1538.
Findings should refer to the implementation unless explicitly about proxy mechanics.
You are a security auditor. You ONLY have runtime bytecode + analysis artifacts.
You MUST read `BYTECODE_BUNDLE.json` before concluding; it contains the bytecode summary,
evidence bundle, callsites, storage slots, and detector findings.
Special cases when reasoning from bytecode (be explicit about uncertainty):
- Selector inference is best-effort; missing selectors are common.
- Fallback/receive paths may be the only entrypoints.
- CALL vs DELEGATECALL semantics differ; DELEGATECALL executes in caller storage.
- Proxy patterns (EIP-1967, minimal proxies, beacon) change which storage is authoritative.
- Storage slots are raw; mappings/arrays appear via keccak patterns, names are unknown.
- Guard detection is heuristic; absence of guards does NOT mean unguarded.
- Returndata checking is unknown unless explicitly shown in evidence.
- Precompiles (0x1..0x9) and common ERC20 transfer selectors may appear; do not over-claim.
Output MUST be valid JSON matching the provided schema.
- If you find nothing meaningful: set no_findings=true and findings=[].
- Otherwise: set no_findings=false and include findings with severity/category/title.
- Locations can be pc references like "pc:0x123" or selectors like "selector:0xa9059cbb".
Focus on: reentrancy, access control, upgradeability/proxy issues, signature validation,
accounting/invariant breaks, dangerous delegatecall, and untrusted external calls.
Be conservative: if evidence is weak, mark severity low/medium and explain why.
mcp startup: no servers
exec
/bin/bash -lc ls in /tmp/codex-i15plyr1 succeeded in 8ms:
BYTECODE_BUNDLE.json
codex-output-schema.json
exec
/bin/bash -lc 'cat BYTECODE_BUNDLE.json' in /tmp/codex-i15plyr1 succeeded in 7ms:
{
"analysis_artifact": {
"address": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538",
"artifact_hash": "0x34f4107ed4c6e9c6513f97e9505ebdc3100fd27a870a227a5bc63f04ac0fa890",
"artifact_json": {
"auth": {
"guards": [
{
"pc": 1138,
"type": "msg_sender_eq_const",
"value": "0xffffffffffffffffffffffffffffffffffffffff"
},
{
"pc": 1642,
"type": "msg_sender_eq_const",
"value": "0xffffffffffffffffffffffffffffffffffffffff"
},
{
"pc": 2818,
"type": "msg_sender_eq_const",
exec
/bin/bash -lc 'rg -n "storage" BYTECODE_BUNDLE.json | head -n 20' in /tmp/codex-i15plyr1 succeeded in 20ms:
10424: "storage": {
10494: "storage": {
10564: "storage": {
10634: "storage": {
10704: "storage": {
10774: "storage": {
10844: "storage": {
10914: "storage": {
10984: "storage": {
11054: "storage": {
11124: "storage": {
11189: "storage": {
exec
/bin/bash -lc "sed -n '10380,10680p' BYTECODE_BUNDLE.json" in /tmp/codex-i15plyr1 succeeded in 8ms:
"selector": "0x150b7a02"
},
{
"entry_pc": 1140870337,
"selector": "0x4025feb2"
},
{
"entry_pc": 1872738698,
"selector": "0x44004cc1"
},
{
"entry_pc": null,
"selector": "0x6f9fb98a"
}
],
"functions": [
{
"auth": {
"guards": [
{
exec
/bin/bash -lc "sed -n '10680,10980p' BYTECODE_BUNDLE.json" in /tmp/codex-i15plyr1 succeeded in 6ms:
"pc": 1138,
"type": "msg_sender_eq_const",
"value": "0xffffffffffffffffffffffffffffffffffffffff"
},
{
"pc": 1642,
"type": "msg_sender_eq_const",
"value": "0xffffffffffffffffffffffffffffffffffffffff"
},
{
"pc": 2818,
"type": "msg_sender_eq_const",
"value": "0xffffffffffffffffffffffffffffffffffffffff"
}
]
},
"entry_pc": 4093572003,
"selector": "0xf23a6e61",
"sinks": {
"call": 3,
exec
/bin/bash -lc "sed -n '10980,11320p' BYTECODE_BUNDLE.json" in /tmp/codex-i15plyr1 succeeded in 10ms:
"delegatecall": 0,
"selfdestruct": 1,
"staticcall": 5
},
"storage": {
"reads": 11,
"slots": [
{
"op": "SLOAD",
"pc": 1086,
"slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
},
{
"op": "SLOAD",
"pc": 1590,
"slot": "0x0000000000000000000000000000000000000000000000000000000000000002"
},
{
"op": "SLOAD",
"pc": 2199,
exec
/bin/bash -lc 'rg -n "SELFDESTRUCT|selfdestruct" BYTECODE_BUNDLE.json | head -n 20' in /tmp/codex-i15plyr1 succeeded in 7ms:
8134: "SELFDESTRUCT"
10421: "selfdestruct": 1,
10491: "selfdestruct": 1,
10561: "selfdestruct": 1,
10631: "selfdestruct": 1,
10701: "selfdestruct": 1,
10771: "selfdestruct": 1,
10841: "selfdestruct": 1,
10911: "selfdestruct": 1,
10981: "selfdestruct": 1,
11051: "selfdestruct": 1,
11121: "selfdestruct": 1,
11185: "selfdestruct": 1,
17500: "selfdestruct_count": 1
17503: "sink": "SELFDESTRUCT"
17506: "title": "SELFDESTRUCT reachable",
17515: "sink": "SELFDESTRUCT",
17527: "selfdestruct_present"
17529: "selfdestruct_count": 1
exec
/bin/bash -lc "sed -n '8090,8160p' BYTECODE_BUNDLE.json" in /tmp/codex-i15plyr1 succeeded in 6ms:
"OP_90",
"POP",
"OP_92",
"OP_91",
"POP",
"POP",
"JUMP"
],
"start_pc": 8029
},
{
"end_pc": 8037,
"hash": "0xcc8de6ddc3dcba22c317ce845ec6683a3e0e40712645f00bb1418bc0369692ce",
"opcodes": [
"INVALID"
],
"start_pc": 8037
},
{
"end_pc": 8052,
codex
{"no_findings":false,"summary":"One low-severity issue identified: the external initializer can set the owner if the proxy is ever left uninitialized.","findings":[{"severity":"low","category":"access_control","title":"Initializer is externally callable; uninitialized proxy can be taken over","exploit_scenario":"If the beacon proxy is deployed without an initialization call, any account can invoke `initialize` (selector `0xc4d66de8`) and set itself as the owner. The new owner can then call owner‑only withdrawal functions to move ETH/tokens/NFTs held by the proxy.","recommendation":"Ensure the proxy is initialized atomically during deployment. Consider adding a constructor that calls `_disableInitializers()` in the implementation and/or enforce `onlyProxy`/deployer checks on initialization routines.","evidence":"The implementation exposes an initializer at `selector:0xc4d66de8` that writes the owner to storage slot `0x2` with only the Initializable guard (no caller restriction). Owner‑only checks compare `msg.sender` against slot `0x2` (e.g., in asset withdrawal paths).","locations":["selector:0xc4d66de8","pc:0x08cc"]}]}
tokens used
83,158
{
"codex": {
"ran_at": "2026-01-30T15:44:50.095408+00:00",
"returncode": 0
},
"project": {
"mode": "bytecode",
"bytecode_length": 16184,
"bytecode_truncated": false,
"capability_graph_present": true,
"analysis_artifact_present": true
},
"summary": "One low-severity issue identified: the external initializer can set the owner if the proxy is ever left uninitialized.",
"raw_final": {
"summary": "One low-severity issue identified: the external initializer can set the owner if the proxy is ever left uninitialized.",
"findings": [
{
"title": "Initializer is externally callable; uninitialized proxy can be taken over",
"category": "access_control",
"evidence": "The implementation exposes an initializer at `selector:0xc4d66de8` that writes the owner to storage slot `0x2` with only the Initializable guard (no caller restriction). Owner\u2011only checks compare `msg.sender` against slot `0x2` (e.g., in asset withdrawal paths).",
"severity": "low",
"locations": [
"selector:0xc4d66de8",
"pc:0x08cc"
],
"recommendation": "Ensure the proxy is initialized atomically during deployment. Consider adding a constructor that calls `_disableInitializers()` in the implementation and/or enforce `onlyProxy`/deployer checks on initialization routines.",
"exploit_scenario": "If the beacon proxy is deployed without an initialization call, any account can invoke `initialize` (selector `0xc4d66de8`) and set itself as the owner. The new owner can then call owner\u2011only withdrawal functions to move ETH/tokens/NFTs held by the proxy."
}
],
"no_findings": false
},
"no_findings": false,
"proxy_context": {
"proxy_run_id": "019c0ea9-09b4-70d2-b921-de227abe0b6b",
"proxy_address": "0xb71125df00a98a671f82c7b2e70e646ea2fa5894",
"implementation_run_id": "019c0eac-1141-73a4-bb86-3f06ad5c30a9",
"implementation_address": "0x5018cc0d628fb322b2a040cfcd269a36c60b1538"
},
"schema_version": 1
}
00000000: PUSH1 0x80 00000002: PUSH1 0x40 00000004: MSTORE 00000005: CALLDATASIZE 00000006: PUSH2 0x0013 00000009: JUMPI 0000000a: PUSH2 0x0011 0000000d: PUSH2 0x001d 00000010: JUMP 00000011: JUMPDEST 00000012: STOP 00000013: JUMPDEST 00000014: PUSH2 0x001b 00000017: PUSH2 0x001d 0000001a: JUMP 0000001b: JUMPDEST 0000001c: STOP 0000001d: JUMPDEST 0000001e: PUSH2 0x0025 00000021: PUSH2 0x0037 00000024: JUMP 00000025: JUMPDEST 00000026: PUSH2 0x0035 00000029: PUSH2 0x0030 0000002c: PUSH2 0x0039 0000002f: JUMP 00000030: JUMPDEST 00000031: PUSH2 0x00b6 00000034: JUMP 00000035: JUMPDEST 00000036: JUMP 00000037: JUMPDEST 00000038: JUMP 00000039: JUMPDEST 0000003a: PUSH1 0x00 0000003c: PUSH2 0x0043 0000003f: PUSH2 0x00dc 00000042: JUMP 00000043: JUMPDEST 00000044: PUSH20 0xffffffffffffffffffffffffffffffffffffffff 00000059: AND 0000005a: PUSH4 0x5c60da1b 0000005f: PUSH1 0x40 00000061: MLOAD 00000062: DUP2 00000063: PUSH4 0xffffffff 00000068: AND 00000069: PUSH1 0xe0 0000006b: SHL 0000006c: DUP2 0000006d: MSTORE 0000006e: PUSH1 0x04 00000070: ADD 00000071: PUSH1 0x20 00000073: PUSH1 0x40 00000075: MLOAD 00000076: DUP1 00000077: DUP4 00000078: SUB 00000079: DUP2 0000007a: DUP7 0000007b: GAS 0000007c: STATICCALL 0000007d: ISZERO 0000007e: DUP1 0000007f: ISZERO 00000080: PUSH2 0x008d 00000083: JUMPI 00000084: RETURNDATASIZE 00000085: PUSH1 0x00 00000087: DUP1 00000088: RETURNDATACOPY 00000089: RETURNDATASIZE 0000008a: PUSH1 0x00 0000008c: REVERT 0000008d: JUMPDEST 0000008e: POP 0000008f: POP 00000090: POP 00000091: POP 00000092: PUSH1 0x40 00000094: MLOAD 00000095: RETURNDATASIZE 00000096: PUSH1 0x1f 00000098: NOT 00000099: PUSH1 0x1f 0000009b: DUP3 0000009c: ADD 0000009d: AND 0000009e: DUP3 0000009f: ADD 000000a0: DUP1 000000a1: PUSH1 0x40 000000a3: MSTORE 000000a4: POP 000000a5: DUP2 000000a6: ADD 000000a7: SWAP1 000000a8: PUSH2 0x00b1 000000ab: SWAP2 000000ac: SWAP1 000000ad: PUSH2 0x01a0 000000b0: JUMP 000000b1: JUMPDEST 000000b2: SWAP1 000000b3: POP 000000b4: SWAP1 000000b5: JUMP 000000b6: JUMPDEST 000000b7: CALLDATASIZE 000000b8: PUSH1 0x00 000000ba: DUP1 000000bb: CALLDATACOPY 000000bc: PUSH1 0x00 000000be: DUP1 000000bf: CALLDATASIZE 000000c0: PUSH1 0x00 000000c2: DUP5 000000c3: GAS 000000c4: DELEGATECALL 000000c5: RETURNDATASIZE 000000c6: PUSH1 0x00 000000c8: DUP1 000000c9: RETURNDATACOPY 000000ca: DUP1 000000cb: PUSH1 0x00 000000cd: DUP2 000000ce: EQ 000000cf: PUSH2 0x00d7 000000d2: JUMPI 000000d3: RETURNDATASIZE 000000d4: PUSH1 0x00 000000d6: RETURN 000000d7: JUMPDEST 000000d8: RETURNDATASIZE 000000d9: PUSH1 0x00 000000db: REVERT 000000dc: JUMPDEST 000000dd: PUSH1 0x00 000000df: PUSH2 0x010a 000000e2: PUSH32 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50 00000103: PUSH1 0x00 00000105: SHL 00000106: PUSH2 0x0133 00000109: JUMP 0000010a: JUMPDEST 0000010b: PUSH1 0x00 0000010d: ADD 0000010e: PUSH1 0x00 00000110: SWAP1 00000111: SLOAD 00000112: SWAP1 00000113: PUSH2 0x0100 00000116: EXP 00000117: SWAP1 00000118: DIV 00000119: PUSH20 0xffffffffffffffffffffffffffffffffffffffff 0000012e: AND 0000012f: SWAP1 00000130: POP 00000131: SWAP1 00000132: JUMP 00000133: JUMPDEST 00000134: PUSH1 0x00 00000136: DUP2 00000137: SWAP1 00000138: POP 00000139: SWAP2 0000013a: SWAP1 0000013b: POP 0000013c: JUMP 0000013d: JUMPDEST 0000013e: PUSH1 0x00 00000140: DUP1 00000141: REVERT 00000142: JUMPDEST 00000143: PUSH1 0x00 00000145: PUSH20 0xffffffffffffffffffffffffffffffffffffffff 0000015a: DUP3 0000015b: AND 0000015c: SWAP1 0000015d: POP 0000015e: SWAP2 0000015f: SWAP1 00000160: POP 00000161: JUMP 00000162: JUMPDEST 00000163: PUSH1 0x00 00000165: PUSH2 0x016d 00000168: DUP3 00000169: PUSH2 0x0142 0000016c: JUMP 0000016d: JUMPDEST 0000016e: SWAP1 0000016f: POP 00000170: SWAP2 00000171: SWAP1 00000172: POP 00000173: JUMP 00000174: JUMPDEST 00000175: PUSH2 0x017d 00000178: DUP2 00000179: PUSH2 0x0162 0000017c: JUMP 0000017d: JUMPDEST 0000017e: DUP2 0000017f: EQ 00000180: PUSH2 0x0188 00000183: JUMPI 00000184: PUSH1 0x00 00000186: DUP1 00000187: REVERT 00000188: JUMPDEST 00000189: POP 0000018a: JUMP 0000018b: JUMPDEST 0000018c: PUSH1 0x00 0000018e: DUP2 0000018f: MLOAD 00000190: SWAP1 00000191: POP 00000192: PUSH2 0x019a 00000195: DUP2 00000196: PUSH2 0x0174 00000199: JUMP 0000019a: JUMPDEST 0000019b: SWAP3 0000019c: SWAP2 0000019d: POP 0000019e: POP 0000019f: JUMP 000001a0: JUMPDEST 000001a1: PUSH1 0x00 000001a3: PUSH1 0x20 000001a5: DUP3 000001a6: DUP5 000001a7: SUB 000001a8: SLT 000001a9: ISZERO 000001aa: PUSH2 0x01b6 000001ad: JUMPI 000001ae: PUSH2 0x01b5 000001b1: PUSH2 0x013d 000001b4: JUMP 000001b5: JUMPDEST 000001b6: JUMPDEST 000001b7: PUSH1 0x00 000001b9: PUSH2 0x01c4 000001bc: DUP5 000001bd: DUP3 000001be: DUP6 000001bf: ADD 000001c0: PUSH2 0x018b 000001c3: JUMP 000001c4: JUMPDEST 000001c5: SWAP2 000001c6: POP 000001c7: POP 000001c8: SWAP3 000001c9: SWAP2 000001ca: POP 000001cb: POP 000001cc: JUMP 000001cd: INVALID 000001ce: LOG2 000001cf: PUSH5 0x6970667358 000001d5: UNKNOWN(0x22) 000001d6: SLT 000001d7: KECCAK256 000001d8: UNKNOWN(0xC0) 000001d9: LOG1 000001da: SLT 000001db: UNKNOWN(0x0E) 000001dc: UNKNOWN(0x2C) 000001dd: SELFBALANCE 000001de: UNKNOWN(0xC1) 000001df: DUP15 000001e0: CALL 000001e1: SWAP10 000001e2: DUP12 000001e3: UNKNOWN(0x0E) 000001e4: UNKNOWN(0xD8) 000001e5: UNKNOWN(0x0D) 000001e6: UNKNOWN(0xF9) 000001e7: MUL 000001e8: UNKNOWN(0xEE) 000001e9: PUSH18 0x87bf8f379f83bf02a851cb9257a764736f6c 000001fc: PUSH4 0x43000813 00000201: STOP 00000202: CALLER
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| critical | upgradeability | detector | Untrusted DELEGATECALL target reachable | 70 | no | no |
viewtrace_id: 0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7
call_targets:
0x5018cc0d628fb322b2a040cfcd269a36c60b1538
target_varies:
no
classification:
constant_target
validation_json{
"sink": "DELEGATECALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0x5018cc0d628fb322b2a040cfcd269a36c60b1538"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 196,
"opcode": "DELEGATECALL",
"returndata_checked": null,
"value_expression_category": "n/a",
"target_expression_category": "computed"
}
],
"guards_detected": [],
"delegatecall_count": 1,
"untrusted_delegatecall_count": 1
}
|
| high | other | detector | Untrusted CALL target/value reachable | 60 | no | no |
viewtrace_id: 0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7
call_targets:
0xb71125df00a98a671f82c7b2e70e646ea2fa5894
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xb71125df00a98a671f82c7b2e70e646ea2fa5894"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 480,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"call_count": 1,
"guards_detected": [],
"untrusted_call_count": 1
}
|
| high | other | detector | ETH value transfer possible | 55 | no | no |
viewtrace_id: 0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7
call_targets:
0xb71125df00a98a671f82c7b2e70e646ea2fa5894
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0xdc0414effba419951098764ea382ce5da4e94efb327bd0c30ba502c9bbda53d7",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xb71125df00a98a671f82c7b2e70e646ea2fa5894"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 480,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"eth_value_calls": 1,
"guards_detected": []
}
|
| medium | upgradeability | cast | DELEGATECALL present | 80 | no | — |
viewevidence_json{
"notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
"delegatecall_count": 1
}
|
| low | access_control | codex | Initializer is externally callable; uninitialized proxy can be taken over | 65 | no | — |
viewevidence_json{
"evidence": "The implementation exposes an initializer at `selector:0xc4d66de8` that writes the owner to storage slot `0x2` with only the Initializable guard (no caller restriction). Owner\u2011only checks compare `msg.sender` against slot `0x2` (e.g., in asset withdrawal paths).",
"locations": [
"selector:0xc4d66de8",
"pc:0x08cc"
],
"recommendation": "Ensure the proxy is initialized atomically during deployment. Consider adding a constructor that calls `_disableInitializers()` in the implementation and/or enforce `onlyProxy`/deployer checks on initialization routines.",
"exploit_scenario": "If the beacon proxy is deployed without an initialization call, any account can invoke `initialize` (selector `0xc4d66de8`) and set itself as the owner. The new owner can then call owner\u2011only withdrawal functions to move ETH/tokens/NFTs held by the proxy."
}
|