019bb490-f395-7383-8ffe-d86692ad0013
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 |
|---|---|---|---|---|
| 40123 | artifact.fetch | complete | 1 / 3 | 3 months ago |
| 40124 | proxy.resolve | complete | 1 / 3 | 3 months ago |
| 40125 | tool.cast_disasm | complete | 1 / 3 | 3 months ago |
| 40126 | analysis.bundle | complete | 1 / 3 | 3 months ago |
| 40127 | capability.graph | complete | 1 / 3 | 3 months ago |
| 40128 | detector.run | complete | 1 / 3 | 3 months ago |
| 40129 | validation.fork | complete | 1 / 3 | 3 months ago |
| 40245 | report.consolidate | complete | 1 / 6 | 3 months ago |
{
"method": "etherscan+onchain",
"status": "confirmed",
"etherscan_hint": {
"source": "etherscan",
"etherscan": {
"proxy_flag": true,
"implementation": "0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49"
}
},
"implementation": "0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49",
"onchain_method": "eip1967"
}
No slither job recorded yet.
{"no_findings":true,"summary":"Reviewed the implementation bytecode and analysis artifacts. The contract appears to be an ERC20-style token with initializer logic and several external calls (staticcall/call) to configured contracts; the only CALLCODE/CREATE2 opcodes observed are in unreachable metadata. Based on available bytecode-only evidence, no concrete exploitable issues were identified. Uncertainty remains due to selector inference limits and lack of source-level context.","findings":[]}
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-09ha3ooo
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019bb4b4-163e-7ba3-98b6-be76b32e9050
--------
user
Context: The user requested the proxy at 0x3c3e283353f4349f6424151583a8353e8f40f2b1.
Audit the implementation at 0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49.
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
**Preparing to read BYTECODE_BUNDLE.json**
exec
/bin/bash -lc 'rg --files' in /tmp/codex-09ha3ooo succeeded in 9ms:
codex-output-schema.json
BYTECODE_BUNDLE.json
thinking
**Reading BYTECODE_BUNDLE.json**
exec
/bin/bash -lc 'cat BYTECODE_BUNDLE.json' in /tmp/codex-09ha3ooo succeeded in 8ms:
{
"analysis_artifact": {
"address": "0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49",
"artifact_hash": "0xd95224d9165c21378f48102ac040d6801a70237ea082c4d4a88a38808ec6af76",
"artifact_json": {
"auth": {
"guards": []
},
"basic_blocks": [
{
"end_pc": 11,
"hash": "0x7ba4403ad8c2da27f36a99883d9bd6831f00a99722adb0e607c72478344873a4",
"opcodes": [
"PUSH1",
"PUSH1",
"MSTORE",
"CALLVALUE",
"OP_80",
"ISZERO",
"PUSH2",
thinking
**Searching for evidence and detector details**
exec
/bin/bash -lc 'rg -n "storage|slot|proxy|implementation|admin|owner|upgrade" BYTECODE_BUNDLE.json' in /tmp/codex-09ha3ooo succeeded in 7ms:
11531: "storage": {
11533: "slots": [
11537: "slot": "0x0000000000000000000000000000000000000000000000000000000000000065"
11542: "slot": "0x0000000000000000000000000000000000000000000000000000000000000094"
11547: "slot": "0x0000000000000000000000000000000000000000000000000000000000000095"
11552: "slot": "0x0000000000000000000000000000000000000000000000000000000000000036"
11557: "slot": "0x0000000000000000000000000000000000000000000000000000000000000100"
11562: "slot": "0x0000000000000000000000000000000000000000000000000000000000000035"
11567: "slot": "0x0000000000000000000000000000000000000000000000000000000000000035"
11572: "slot": "0x0000000000000000000000000000000000000000000000000000000000000095"
11577: "slot": "0x0000000000000000000000000000000000000000000000000000000000000094"
11582: "slot": "0x0000000000000000000000000000000000000000000000000000000000000094"
11587: "slot": "0x0000000000000000000000000000000000000000000000000000000000000095"
11592: "slot": "0x0000000000000000000000000000000000000000000000000000000000000095"
11597: "slot": "0x0000000000000000000000000000000000000000000000000000000000000095"
11602: "slot": "0x0000000000000000000000000000000000000000000000000000000000000094"
11607: "slot": "0x0000000000000000000000000000000000000000000000000000000000000037"
11612: "slot": "0x0000000000000000000000000000000000000000000000000000000000000035"
11617: "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
11622: "slot": "0x0000000000000000000000000000000000000000000000000000000000000000"
thinking
**Planning focused data extraction**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
p=Path('BYTECODE_BUNDLE.json')
obj=json.loads(p.read_text())
print(obj.keys())
print('detector_findings', len(obj.get('detector_findings',[])))
print('heuristics_summary', obj.get('heuristics_summary'))
# find top-level analysis_artifact->artifact_json keys
art=obj['analysis_artifact']['artifact_json']
print('artifact_json keys', art.keys())
print('auth', art.get('auth'))
print('version', art.get('version'))
# find if has 'evidence_bundle' or 'storage' etc
for k in art.keys():
if 'evidence' in k or 'bundle' in k or 'storage' in k or 'calls' in k or 'selector' in k:
print('key', k)
PY" in /tmp/codex-09ha3ooo succeeded in 36ms:
dict_keys(['analysis_artifact', 'analysis_run', 'artifact', 'capability_graph', 'detector_findings', 'heuristics_summary'])
detector_findings 3
heuristics_summary {'create2_count': 2, 'delegatecall_count': 0, 'flags': ['create_opcodes_present', 'heavy_ext_balance_usage', 'call_family_heavy'], 'selfdestruct_count': 0}
artifact_json keys dict_keys(['auth', 'basic_blocks', 'callsites', 'cfg_edges', 'cfg_hash', 'dispatcher_type', 'function_entries', 'functions', 'selectors', 'sinks', 'storage', 'version'])
auth {'guards': []}
version analysis_artifact_v1
key callsites
key selectors
key storage
thinking
**Extracting selectors and functions**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
art=obj['analysis_artifact']['artifact_json']
print('dispatcher_type', art.get('dispatcher_type'))
print('selectors count', len(art.get('selectors',[])))
print('selectors sample', art.get('selectors',[])[:20])
print('functions count', len(art.get('functions',[])))
print('function_entries count', len(art.get('function_entries',[])))
# print function entries with selectors
entries=art.get('function_entries',[])
print('function entries sample', entries[:10])
# find callsites
calls=art.get('callsites',[])
print('callsites', len(calls))
print(calls[:20])
# storage slots
storage=art.get('storage',{})
print('storage keys', storage.keys())
print('storage slots count', len(storage.get('slots',[])))
print('storage slots sample', storage.get('slots',[])[:10])
PY" in /tmp/codex-09ha3ooo succeeded in 37ms:
dispatcher_type selector_jump_table
selectors count 24
selectors sample ['0xae167335', '0xb16a19de', '0xb1bf962d', '0xd3b1e9a4', '0xd7020d0a', '0xdd62ed3e', '0x7535d246', '0x75d26413', '0x7df5bd3b', '0x95d89b41', '0xa457c2d7', '0xa9059cbb', '0x23b872dd', '0x313ce567', '0x39509351', '0x4819128a', '0x4efecaa5', '0x70a08231', '0x06fdde03', '0x095ea7b3']
functions count 24
function_entries count 24
function entries sample [{'entry_pc': 2920706869, 'selector': '0xae167335'}, {'entry_pc': 2982123053, 'selector': '0xb16a19de'}, {'entry_pc': 3551652260, 'selector': '0xb1bf962d'}, {'entry_pc': 3607235850, 'selector': '0xd3b1e9a4'}, {'entry_pc': 3714247998, 'selector': '0xd7020d0a'}, {'entry_pc': None, 'selector': '0xdd62ed3e'}, {'entry_pc': 1976722451, 'selector': '0x7535d246'}, {'entry_pc': 2113256763, 'selector': '0x75d26413'}, {'entry_pc': 2514000705, 'selector': '0x7df5bd3b'}, {'entry_pc': 2757214935, 'selector': '0x95d89b41'}]
callsites 13
[{'opcode': 'STATICCALL', 'pc': 1456, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'STATICCALL', 'pc': 2182, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'STATICCALL', 'pc': 3041, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'STATICCALL', 'pc': 3228, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'STATICCALL', 'pc': 4021, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'CALL', 'pc': 4452, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}, {'opcode': 'STATICCALL', 'pc': 5315, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'STATICCALL', 'pc': 5561, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'n/a'}, {'opcode': 'CALL', 'pc': 6433, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}, {'opcode': 'CALL', 'pc': 6573, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}, {'opcode': 'CALL', 'pc': 7398, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}, {'opcode': 'CALLCODE', 'pc': 8878, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}, {'opcode': 'CALL', 'pc': 8896, 'returndata_checked': None, 'target_expression_category': 'computed', 'value_expression_category': 'computed'}]
storage keys dict_keys(['keccak_count', 'reads', 'slots', 'writes'])
storage slots count 43
storage slots sample [{'op': 'SLOAD', 'pc': 536, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000065'}, {'op': 'SLOAD', 'pc': 740, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 757, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 880, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000036'}, {'op': 'SLOAD', 'pc': 953, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000100'}, {'op': 'SLOAD', 'pc': 1058, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 1349, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 1380, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 1856, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 1944, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}]
thinking
**Investigating contract call behaviors and selectors**
I’m gathering evidence on function selectors that mostly match standard ERC20 methods, alongside additional unknown selectors to analyze further. The findings show suspicious call patterns like calls to the same contract address, possible self-calls with value that might trigger fallback functions or reentrancy, plus the use of CALLCODE—an old but risky opcode that executes external code within the caller’s storage context. I’m looking to verify callcode targets and search analysis artifacts like capability graphs to get a clearer picture of these complex behaviors.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
print('analysis_run keys', obj['analysis_run'].keys())
print('artifact keys', obj['artifact'].keys())
print('capability_graph keys', obj['capability_graph'].keys())
PY" in /tmp/codex-09ha3ooo succeeded in 37ms:
analysis_run keys dict_keys(['address', 'block_number', 'chain_id', 'child_links', 'created_at', 'id', 'parent_links', 'status', 'updated_at'])
artifact keys dict_keys(['codehash', 'compiler_json', 'implementation_address', 'is_proxy', 'runtime_bytecode', 'verified_source'])
capability_graph keys dict_keys(['address', 'block_number', 'chain_id', 'codehash', 'created_at', 'graph_hash', 'graph_json', 'id', 'updated_at', 'version'])
thinking
**Inspecting graph_json keys**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
cap=obj['capability_graph']['graph_json']
print('graph_json keys', cap.keys())
# check if includes 'nodes','edges'
print('nodes', len(cap.get('nodes',[])))
print('edges', len(cap.get('edges',[])))
# maybe 'evidence'
for k in cap.keys():
if 'evidence' in k or 'bundle' in k:
print('graph key', k)
PY" in /tmp/codex-09ha3ooo succeeded in 70ms:
graph_json keys dict_keys(['edges', 'nodes', 'version'])
nodes 501
edges 529
thinking
**Inspecting callsite nodes for CALLCODE analysis**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
cap=obj['capability_graph']['graph_json']
# find callsite nodes
call_nodes=[n for n in cap['nodes'] if n.get('type')=='callsite']
print('callsite nodes', len(call_nodes))
print(call_nodes[:5])
# find callcode nodes
callcode=[n for n in call_nodes if n.get('opcode')=='CALLCODE']
print('callcode nodes', callcode)
# find create/create2 nodes
create=[n for n in call_nodes if n.get('opcode') in ('CREATE','CREATE2')]
print('create nodes', create)
PY" in /tmp/codex-09ha3ooo succeeded in 38ms:
callsite nodes 13
[{'id': 'call:1456', 'opcode': 'STATICCALL', 'pc': 1456, 'type': 'callsite'}, {'id': 'call:2182', 'opcode': 'STATICCALL', 'pc': 2182, 'type': 'callsite'}, {'id': 'call:3041', 'opcode': 'STATICCALL', 'pc': 3041, 'type': 'callsite'}, {'id': 'call:3228', 'opcode': 'STATICCALL', 'pc': 3228, 'type': 'callsite'}, {'id': 'call:4021', 'opcode': 'STATICCALL', 'pc': 4021, 'type': 'callsite'}]
callcode nodes [{'id': 'call:8878', 'opcode': 'CALLCODE', 'pc': 8878, 'type': 'callsite'}]
create nodes []
thinking
**Investigating CREATE opcode presence**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
blocks=obj['analysis_artifact']['artifact_json']['basic_blocks']
create_blocks=[b for b in blocks if any(op in ('CREATE','CREATE2') for op in b.get('opcodes',[]))]
print('create blocks', len(create_blocks))
print(create_blocks[:5])
PY" in /tmp/codex-09ha3ooo succeeded in 34ms:
create blocks 1
[{'end_pc': 8947, 'hash': '0x65050a22285e2e4f9a975d38c4015aab27e911a2b522bc6e5896c568a4739a45', 'opcodes': ['OP_DD', 'CALLCODE', 'MSTORE', 'OP_AD', 'SHL', 'OP_E2', 'OP_C8', 'OP_9B', 'PUSH10', 'CALL', 'PUSH4', 'CREATE2', 'GAS', 'OP_4D', 'CREATE2', 'OP_23', 'OP_B3', 'OP_EF', 'OP_A2', 'PUSH5', 'OP_22', 'SLT', 'SHA3', 'PUSH24', 'EXP', 'OP_96', 'OP_BC', 'OP_DA'], 'start_pc': 8877}]
thinking
**Analyzing opcode reachability**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
cap=obj['capability_graph']['graph_json']
# build edges from nodes id to id
edges=cap['edges']
# find incoming edges to call:8878
incoming=[e for e in edges if e.get('to')=='call:8878']
print('incoming to call:8878', incoming[:10], 'count', len(incoming))
# find incoming to call:8896 etc
for cid in ['call:4452','call:6433','call:6573','call:7398','call:8896','call:8878']:
incoming=[e for e in edges if e.get('to')==cid]
print(cid, 'incoming', len(incoming))
PY" in /tmp/codex-09ha3ooo succeeded in 47ms:
incoming to call:8878 [{'from': 'bb:8877', 'to': 'call:8878', 'type': 'contains'}] count 1
call:4452 incoming 1
call:6433 incoming 1
call:6573 incoming 1
call:7398 incoming 1
call:8896 incoming 1
call:8878 incoming 1
thinking
**Checking basic block connectivity**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
cap=obj['capability_graph']['graph_json']
edges=cap['edges']
# find incoming edges to bb:8877
incoming=[e for e in edges if e.get('to')=='bb:8877']
print('incoming to bb:8877', incoming[:10], 'count', len(incoming))
# show from nodes ids
# check if any from function entry or other bb
from_ids=set(e['from'] for e in incoming)
print('from ids sample', list(from_ids)[:10])
PY" in /tmp/codex-09ha3ooo succeeded in 36ms:
incoming to bb:8877 [] count 0
from ids sample []
thinking
**Analyzing callsite reachability and guards**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
cap=obj['capability_graph']['graph_json']
from collections import Counter
cnt=Counter(n.get('type') for n in cap['nodes'])
print(cnt)
# show some node examples for storage and function
for t in ['function','storage','literal','calldata','memory','basic_block','callsite']:
nodes=[n for n in cap['nodes'] if n.get('type')==t]
print(t, 'count', len(nodes))
print(nodes[:3])
PY" in /tmp/codex-09ha3ooo succeeded in 75ms:
Counter({'basic_block': 461, 'function': 24, 'callsite': 13, 'sink': 3})
function count 24
[{'entry_pc': 2920706869, 'id': 'fn:0xae167335', 'selector': '0xae167335', 'type': 'function'}, {'entry_pc': 2982123053, 'id': 'fn:0xb16a19de', 'selector': '0xb16a19de', 'type': 'function'}, {'entry_pc': 3551652260, 'id': 'fn:0xb1bf962d', 'selector': '0xb1bf962d', 'type': 'function'}]
storage count 0
[]
literal count 0
[]
calldata count 0
[]
memory count 0
[]
basic_block count 461
[{'end_pc': 11, 'hash': '0x7ba4403ad8c2da27f36a99883d9bd6831f00a99722adb0e607c72478344873a4', 'id': 'bb:0', 'start_pc': 0, 'type': 'basic_block'}, {'end_pc': 15, 'hash': '0x412723d00960af0c233b4b89f310c1b830c1242f4aa620daca380320dcfe8246', 'id': 'bb:12', 'start_pc': 12, 'type': 'basic_block'}, {'end_pc': 25, 'hash': '0x0740e6c7eb18031d603f0e4248a402b24e706b12d660b8dd0c3094fd5b6601af', 'id': 'bb:16', 'start_pc': 16, 'type': 'basic_block'}]
callsite count 13
[{'id': 'call:1456', 'opcode': 'STATICCALL', 'pc': 1456, 'type': 'callsite'}, {'id': 'call:2182', 'opcode': 'STATICCALL', 'pc': 2182, 'type': 'callsite'}, {'id': 'call:3041', 'opcode': 'STATICCALL', 'pc': 3041, 'type': 'callsite'}]
thinking
**Evaluating capability graph limitations**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
rt=obj['artifact'].get('runtime_bytecode')
print('runtime_bytecode length', len(rt) if rt else None)
print('runtime_bytecode prefix', rt[:40] if rt else None)
PY" in /tmp/codex-09ha3ooo exited 1 in 41ms:
runtime_bytecode length 5
Traceback (most recent call last):
File "<stdin>", line 6, in <module>
KeyError: slice(None, 40, None)
thinking
**Inspecting runtime_bytecode type**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
rt=obj['artifact'].get('runtime_bytecode')
print(type(rt), rt)
PY" in /tmp/codex-09ha3ooo succeeded in 48ms:
<class 'dict'> {'full': '0x608060405234801561001057600080fd5b50600436106101585760003560e01c80637535d246116100c3578063ae1673351161007c578063ae167335146102e1578063b16a19de146102f2578063b1bf962d14610303578063d3b1e9a41461030b578063d7020d0a1461031e578063dd62ed3e1461033157600080fd5b80637535d2461461027657806375d26413146102965780637df5bd3b1461029e57806395d89b41146102b3578063a457c2d7146102bb578063a9059cbb146102ce57600080fd5b806323b872dd1161011557806323b872dd14610202578063313ce56714610215578063395093511461022a5780634819128a1461023d5780634efecaa51461025057806370a082311461026357600080fd5b806306fdde031461015d578063095ea7b31461017b5780630afbcdc91461019e578063156e29f6146101c657806318160ddd146101d95780631da24f3e146101ef575b600080fd5b61016561036a565b60405161017291906120e3565b60405180910390f35b61018e610189366004611f3b565b6103fc565b6040519015158152602001610172565b6101b16101ac366004611e46565b610413565b60408051928352602083019190915201610172565b61018e6101d4366004611f66565b61042b565b6101e161053c565b604051908152602001610172565b6101e16101fd366004611e46565b6105f3565b61018e610210366004611eb6565b6105fe565b60655460405160ff9091168152602001610172565b61018e610238366004611f3b565b6106a8565b6101e161024b366004612076565b6106e4565b6101e161025e366004611f3b565b6107b6565b6101e1610271366004611e46565b61082c565b61027e6108ca565b6040516001600160a01b039091168152602001610172565b61027e6108d9565b6102b16102ac3660046120a6565b6108e3565b005b6101656109db565b61018e6102c9366004611f3b565b6109ea565b61018e6102dc366004611f3b565b610a83565b6094546001600160a01b031661027e565b6095546001600160a01b031661027e565b6101e1610a90565b6102b1610319366004611fba565b610a9b565b6102b161032c366004611ef6565b610d11565b6101e161033f366004611e7e565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b60606036805461037990612249565b80601f01602080910402602001604051908101604052809291908181526020018280546103a590612249565b80156103f25780601f106103c7576101008083540402835291602001916103f2565b820191906000526020600020905b8154815290600101906020018083116103d557829003601f168201915b5050505050905090565b6000610409338484610e2e565b5060015b92915050565b60008061041f83610f52565b60355491509150915091565b6000610435610f6d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b8152509061048c5760405162461bcd60e51b815260040161048391906120e3565b60405180910390fd5b50600061049885610f52565b905060006104a68585610fea565b60408051808201909152600381526235303160e81b6020820152909150816104e15760405162461bcd60e51b815260040161048391906120e3565b506104ec86826110ca565b60408051868152602081018690526001600160a01b038816917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a2501590505b9392505050565b60008061054860355490565b90508061055757600091505090565b6000610561610f6d565b60955460405163d15e005360e01b81526001600160a01b0391821660048201529192506105ec919083169063d15e00539060240160206040518083038186803b1580156105ad57600080fd5b505afa1580156105c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e5919061208e565b8390611180565b9250505090565b600061040d82610f52565b600061060b84848461123c565b6001600160a01b0384166000908152603460209081526040808320338452909152902054828110156106905760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610483565b61069d8533858403610e2e565b506001949350505050565b3360008181526034602090815260408083206001600160a01b038716845290915281205490916104099185906106df9086906121af565b610e2e565b60006106ee610f6d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b8152509061073c5760405162461bcd60e51b815260040161048391906120e3565b506094546001600160a01b03166107955760405162461bcd60e51b815260206004820152601960248201527f5f7472656173757279206973207a65726f2061646472657373000000000000006044820152606401610483565b6094546095546107b2916001600160a01b0391821691168461124e565b5090565b60006107c0610f6d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b8152509061080e5760405162461bcd60e51b815260040161048391906120e3565b50609554610826906001600160a01b0316848461124e565b50919050565b600080610837610f6d565b60955460405163d15e005360e01b81526001600160a01b039182166004820152919250610535919083169063d15e00539060240160206040518083038186803b15801561088357600080fd5b505afa158015610897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bb919061208e565b6108c485610f52565b90611180565b60006108d4610f6d565b905090565b60006108d46112a0565b6108eb610f6d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906109395760405162461bcd60e51b815260040161048391906120e3565b5081610943575050565b6094546001600160a01b03166109628161095d8585610fea565b6110ca565b6040518381526001600160a01b038216906000906000805160206122ad8339815191529060200160405180910390a360408051848152602081018490526001600160a01b038316917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a2505b5050565b60606037805461037990612249565b3360009081526034602090815260408083206001600160a01b038616845290915281205482811015610a6c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610483565b610a793385858403610e2e565b5060019392505050565b600061040933848461123c565b60006108d460355490565b600054610100900460ff16610ab65760005460ff1615610aba565b303b155b610ad65760405162461bcd60e51b815260040161048390612116565b600054610100900460ff16158015610af8576000805461ffff19166101011790555b610b6d85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815292508791508690819084018382808284376000920191909152508b92506112e5915050565b609480546001600160a01b03808b166001600160a01b031992831617909255609580548a841690831617905560938054928c169290911682179055604080516311ead9ef60e31b81529051638f56cf7891600480820192602092909190829003018186803b158015610bde57600080fd5b505afa158015610bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c169190611e62565b6001600160a01b0316876001600160a01b03167f3514319b7a526ad5f1f42edf0c1df25fa0ea2ae054779987fbe636f164515e2f8a609360009054906101000a90046001600160a01b03166001600160a01b03166375d264136040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9957600080fd5b505afa158015610cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd19190611e62565b604080516001600160a01b0393841681529290911660208301520160405180910390a38015610d06576000805461ff00191690555b505050505050505050565b610d19610f6d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b81525090610d675760405162461bcd60e51b815260040161048391906120e3565b506000610d748383610fea565b6040805180820190915260038152621a981960e91b602082015290915081610daf5760405162461bcd60e51b815260040161048391906120e3565b50610dba8582611372565b609554610dd1906001600160a01b0316858561124e565b836001600160a01b0316856001600160a01b03167f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa28585604051610e1f929190918252602082015260400190565b60405180910390a35050505050565b6001600160a01b038316610e905760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610483565b6001600160a01b038216610ef15760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610483565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b031660009081526033602052604090205490565b609354604080516311ead9ef60e31b815290516000926001600160a01b031691638f56cf78916004808301926020929190829003018186803b158015610fb257600080fd5b505afa158015610fc6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d49190611e62565b60408051808201909152600381526219181960e91b6020820152600090826110255760405162461bcd60e51b815260040161048391906120e3565b5060006110336002846121c7565b90506b033b2e3c9fd0803ce800000061104e82600019612206565b61105891906121c7565b8411156040518060400160405280600381526020016203230360ec1b815250906110955760405162461bcd60e51b815260040161048391906120e3565b5082816110ae6b033b2e3c9fd0803ce8000000876121e7565b6110b891906121af565b6110c291906121c7565b949350505050565b60006110d560355490565b905060006110e284610f52565b90506110ee8484611396565b60006110f86112a0565b6001600160a01b03161461117a5761110e6112a0565b6040516318c39f1760e11b81526001600160a01b038681166004830152602482018590526044820184905291909116906331873e2e90606401600060405180830381600087803b15801561116157600080fd5b505af1158015611175573d6000803e3d6000fd5b505050505b50505050565b600082158061118d575081155b1561119a5750600061040d565b816111b260026b033b2e3c9fd0803ce80000006121c7565b6111be90600019612206565b6111c891906121c7565b8311156040518060400160405280600381526020016203230360ec1b815250906112055760405162461bcd60e51b815260040161048391906120e3565b506b033b2e3c9fd0803ce800000061121e6002826121c7565b61122884866121e7565b61123291906121af565b61053591906121c7565b6112498383836001611463565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611249908490611632565b609354604080516375d2641360e01b815290516000926001600160a01b0316916375d26413916004808301926020929190829003018186803b158015610fb257600080fd5b600054610100900460ff166113005760005460ff1615611304565b303b155b6113205760405162461bcd60e51b815260040161048390612116565b600054610100900460ff16158015611342576000805461ffff19166101011790555b61134c8484611704565b6065805460ff191660ff8416179055801561117a576000805461ff001916905550505050565b600061137d60355490565b9050600061138a84610f52565b90506110ee848461173d565b6001600160a01b0382166113ec5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610483565b80603560008282546113fe91906121af565b90915550506001600160a01b0382166000908152603360205260408120805483929061142b9084906121af565b90915550506040518181526001600160a01b038316906000906000805160206122ad8339815191529060200160405180910390a35050565b6095546001600160a01b03166000611479610f6d565b60405163d15e005360e01b81526001600160a01b03848116600483015291925060009183169063d15e00539060240160206040518083038186803b1580156114c057600080fd5b505afa1580156114d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f8919061208e565b9050600061150588610f52565b905060006115138284611180565b90506000611524846108c48b610f52565b905060006115328986610fea565b90508084101561153f5750825b61154a8b8b83611879565b87156115cf5760405163d5ed393360e01b81526001600160a01b0388811660048301528c811660248301528b81166044830152606482018b90526084820185905260a4820184905287169063d5ed39339060c40160006040518083038186803b1580156115b657600080fd5b505afa1580156115ca573d6000803e3d6000fd5b505050505b896001600160a01b03168b6001600160a01b03167f4beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda86668b8860405161161d929190918252602082015260400190565b60405180910390a35050505050505050505050565b6000611687826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119cc9092919063ffffffff16565b80519091501561124957808060200190518101906116a59190611f9a565b6112495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610483565b600054610100900460ff1661172b5760405162461bcd60e51b815260040161048390612164565b6117336119db565b6109d78282611a04565b6001600160a01b03821661179d5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610483565b6001600160a01b038216600090815260336020526040902054818110156118115760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610483565b6001600160a01b0383166000908152603360205260408120838303905560358054849290611840908490612206565b90915550506040518281526000906001600160a01b038516906000805160206122ad8339815191529060200160405180910390a3505050565b600061188484610f52565b9050600061189184610f52565b905061189e858585611a52565b60006118a86112a0565b6001600160a01b0316146119c55760006118c160355490565b90506118cb6112a0565b6040516318c39f1760e11b81526001600160a01b038881166004830152602482018490526044820186905291909116906331873e2e90606401600060405180830381600087803b15801561191e57600080fd5b505af1158015611932573d6000803e3d6000fd5b50505050846001600160a01b0316866001600160a01b0316146119c3576119576112a0565b6040516318c39f1760e11b81526001600160a01b038781166004830152602482018490526044820185905291909116906331873e2e90606401600060405180830381600087803b1580156119aa57600080fd5b505af11580156119be573d6000803e3d6000fd5b505050505b505b5050505050565b60606110c28484600085611c0e565b600054610100900460ff16611a025760405162461bcd60e51b815260040161048390612164565b565b600054610100900460ff16611a2b5760405162461bcd60e51b815260040161048390612164565b8151611a3e906036906020850190611d6f565b508051611249906037906020840190611d6f565b6001600160a01b038316611ab65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610483565b6001600160a01b038216611b185760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610483565b6001600160a01b03831660009081526033602052604090205481811015611b905760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610483565b6001600160a01b03808516600090815260336020526040808220858503905591851681529081208054849290611bc79084906121af565b92505081905550826001600160a01b0316846001600160a01b03166000805160206122ad83398151915284604051611c0191815260200190565b60405180910390a361117a565b606082471015611c6f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610483565b843b611cbd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610483565b600080866001600160a01b03168587604051611cd991906120c7565b60006040518083038185875af1925050503d8060008114611d16576040519150601f19603f3d011682016040523d82523d6000602084013e611d1b565b606091505b5091509150611d2b828286611d36565b979650505050505050565b60608315611d45575081610535565b825115611d555782518084602001fd5b8160405162461bcd60e51b815260040161048391906120e3565b828054611d7b90612249565b90600052602060002090601f016020900481019282611d9d5760008555611de3565b82601f10611db657805160ff1916838001178555611de3565b82800160010185558215611de3579182015b82811115611de3578251825591602001919060010190611dc8565b506107b29291505b808211156107b25760008155600101611deb565b60008083601f840112611e10578182fd5b50813567ffffffffffffffff811115611e27578182fd5b602083019150836020828501011115611e3f57600080fd5b9250929050565b600060208284031215611e57578081fd5b813561053581612294565b600060208284031215611e73578081fd5b815161053581612294565b60008060408385031215611e90578081fd5b8235611e9b81612294565b91506020830135611eab81612294565b809150509250929050565b600080600060608486031215611eca578081fd5b8335611ed581612294565b92506020840135611ee581612294565b929592945050506040919091013590565b60008060008060808587031215611f0b578081fd5b8435611f1681612294565b93506020850135611f2681612294565b93969395505050506040820135916060013590565b60008060408385031215611f4d578182fd5b8235611f5881612294565b946020939093013593505050565b600080600060608486031215611f7a578283fd5b8335611f8581612294565b95602085013595506040909401359392505050565b600060208284031215611fab578081fd5b81518015158114610535578182fd5b60008060008060008060008060c0898b031215611fd5578384fd5b8835611fe081612294565b97506020890135611ff081612294565b9650604089013561200081612294565b9550606089013560ff81168114612015578485fd5b9450608089013567ffffffffffffffff80821115612031578586fd5b61203d8c838d01611dff565b909650945060a08b0135915080821115612055578384fd5b506120628b828c01611dff565b999c989b5096995094979396929594505050565b600060208284031215612087578081fd5b5035919050565b60006020828403121561209f578081fd5b5051919050565b600080604083850312156120b8578182fd5b50508035926020909101359150565b600082516120d981846020870161221d565b9190910192915050565b602081526000825180602084015261210281604085016020870161221d565b601f01601f19169190910160400192915050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082198211156121c2576121c261227e565b500190565b6000826121e257634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156122015761220161227e565b500290565b6000828210156122185761221861227e565b500390565b60005b83811015612238578181015183820152602001612220565b8381111561117a5750506000910152565b600181811c9082168061225d57607f821691505b6020821081141561082657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146122a957600080fd5b5056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220775e6a7a6640218b8229ca46418c7f8dbfa030a3322cc706220a96bcda5b760f64736f6c63430008040033', 'head': None, 'length': 17926, 'tail': None, 'truncated': False}
thinking
**Analyzing runtime bytecode for external calls and storage layout**
I'm examining the runtime bytecode to understand this ERC20-like contract's storage slots, function selectors, and external calls. There are calls to addresses stored in high slots like 0x93–0x95 with function selectors like d15e0053 that might relate to liquidity or treasury interactions. I’m also investigating if external calls handle return data properly and if state updates protect against reentrancy, planning to parse opcode sequences around call instructions to verify.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
hexcode=obj['artifact']['runtime_bytecode']['full']
assert hexcode.startswith('0x')
code=bytes.fromhex(hexcode[2:])
# opcode map
opnames = {i: f'OP_{i:02x}' for i in range(256)}
# fill known
opnames.update({
0x00:'STOP',0x01:'ADD',0x02:'MUL',0x03:'SUB',0x04:'DIV',0x05:'SDIV',0x06:'MOD',0x07:'SMOD',0x08:'ADDMOD',0x09:'MULMOD',0x0a:'EXP',0x0b:'SIGNEXTEND',
0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',0x1a:'BYTE',0x1b:'SHL',0x1c:'SHR',0x1d:'SAR',
0x20:'SHA3',
0x30:'ADDRESS',0x31:'BALANCE',0x32:'ORIGIN',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x36:'CALLDATASIZE',0x37:'CALLDATACOPY',0x38:'CODESIZE',0x39:'CODECOPY',0x3a:'GASPRICE',0x3b:'EXTCODESIZE',0x3c:'EXTCODECOPY',0x3d:'RETURNDATASIZE',0x3e:'RETURNDATACOPY',0x3f:'EXTCODEHASH',
0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',0x46:'CHAINID',0x47:'SELFBALANCE',0x48:'BASEFEE',
0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x53:'MSTORE8',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x58:'PC',0x59:'MSIZE',0x5a:'GAS',0x5b:'JUMPDEST',
0x60:'PUSH1',0x61:'PUSH2',0x62:'PUSH3',0x63:'PUSH4',0x64:'PUSH5',0x65:'PUSH6',0x66:'PUSH7',0x67:'PUSH8',0x68:'PUSH9',0x69:'PUSH10',0x6a:'PUSH11',0x6b:'PUSH12',0x6c:'PUSH13',0x6d:'PUSH14',0x6e:'PUSH15',0x6f:'PUSH16',0x70:'PUSH17',0x71:'PUSH18',0x72:'PUSH19',0x73:'PUSH20',0x74:'PUSH21',0x75:'PUSH22',0x76:'PUSH23',0x77:'PUSH24',0x78:'PUSH25',0x79:'PUSH26',0x7a:'PUSH27',0x7b:'PUSH28',0x7c:'PUSH29',0x7d:'PUSH30',0x7e:'PUSH31',0x7f:'PUSH32',
0x80:'DUP1',0x81:'DUP2',0x82:'DUP3',0x83:'DUP4',0x84:'DUP5',0x85:'DUP6',0x86:'DUP7',0x87:'DUP8',0x88:'DUP9',0x89:'DUP10',0x8a:'DUP11',0x8b:'DUP12',0x8c:'DUP13',0x8d:'DUP14',0x8e:'DUP15',0x8f:'DUP16',
0x90:'SWAP1',0x91:'SWAP2',0x92:'SWAP3',0x93:'SWAP4',0x94:'SWAP5',0x95:'SWAP6',0x96:'SWAP7',0x97:'SWAP8',0x98:'SWAP9',0x99:'SWAP10',0x9a:'SWAP11',0x9b:'SWAP12',0x9c:'SWAP13',0x9d:'SWAP14',0x9e:'SWAP15',0x9f:'SWAP16',
0xa0:'LOG0',0xa1:'LOG1',0xa2:'LOG2',0xa3:'LOG3',0xa4:'LOG4',
0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT',0xfe:'INVALID',0xff:'SELFDESTRUCT'
})
# disassemble to list of (pc, opcode, immed)
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# create index for quick lookup
ops_by_pc={pc:(name,data) for pc,name,data in ops}
# print context around callsites
calls=[4452,6433,6573,7398,8878,8896]
for c in calls:
print('--- callsite pc', c, '---')
# show 10 instructions before and after
# find index of op with pc==c
idx = next(i for i,(pc,_,_) in enumerate(ops) if pc==c)
start=max(0, idx-10)
end=min(len(ops), idx+11)
for pc,name,data in ops[start:end]:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 46ms:
--- callsite pc 4452 ---
4439: DUP1
4440: ISZERO
4441: PUSH2 0x1161
4444: JUMPI
4445: PUSH1 0x00
4447: DUP1
4448: REVERT
4449: JUMPDEST
4450: POP
4451: GAS
4452: CALL
4453: ISZERO
4454: DUP1
4455: ISZERO
4456: PUSH2 0x1175
4459: JUMPI
4460: RETURNDATASIZE
4461: PUSH1 0x00
4463: DUP1
thinking
**Analyzing function dispatch and callsites**
I’m observing that some callsites involve revert checks, but certain CALLCODE and CREATE2 instructions occur only in unreachable metadata regions, so they’re likely irrelevant. Since this is an ERC20 token with external contract calls, I want to decode function selectors by parsing the dispatcher jump table in the bytecode, identifying selectors via their PUSH4/EQ/JUMPI patterns, and mapping them to jump destinations to understand access control and function restrictions. I’ll use a script to extract this mapping from the runtime bytecode.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
hexcode=obj['artifact']['runtime_bytecode']['full']
code=bytes.fromhex(hexcode[2:])
# disassemble simple
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']):
opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find dispatcher entries pattern: PUSH4 <sel> EQ PUSH2 <dest> JUMPI
entries=[]
for i in range(len(ops)-4):
pc,op,data = ops[i]
if op=='PUSH4' and data:
# next op should be EQ or GT? but pattern uses EQ then PUSH2 dest then JUMPI
if ops[i+1][1]=='EQ' and ops[i+2][1].startswith('PUSH') and ops[i+3][1]=='JUMPI':
sel='0x'+data
dest=int(ops[i+2][2],16)
entries.append((sel,dest,pc))
# filter entries within first 300 bytes maybe
entries=[e for e in entries if e[2] < 400]
print('dispatcher entries', len(entries))
for sel,dest,pc in entries:
print(sel, '->', dest, 'at pc', pc)
PY" in /tmp/codex-09ha3ooo succeeded in 58ms:
dispatcher entries 24
0xae167335 -> 737 at pc 55
0xb16a19de -> 754 at pc 66
0xb1bf962d -> 771 at pc 77
0xd3b1e9a4 -> 779 at pc 88
0xd7020d0a -> 798 at pc 99
0xdd62ed3e -> 817 at pc 110
0x7535d246 -> 630 at pc 126
0x75d26413 -> 662 at pc 137
0x7df5bd3b -> 670 at pc 148
0x95d89b41 -> 691 at pc 159
0xa457c2d7 -> 699 at pc 170
0xa9059cbb -> 718 at pc 181
0x23b872dd -> 514 at pc 208
0x313ce567 -> 533 at pc 219
0x39509351 -> 554 at pc 230
0x4819128a -> 573 at pc 241
0x4efecaa5 -> 592 at pc 252
0x70a08231 -> 611 at pc 263
0x06fdde03 -> 349 at pc 279
thinking
**Mapping functions to selectors with disassembly**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
hexcode=obj['artifact']['runtime_bytecode']['full']
code=bytes.fromhex(hexcode[2:])
# disassembler
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']):
opnames[i]=name
opnames.update({0x10:'LT',0x11:'GT',0x12:'SLT',0x13:'SGT',0x14:'EQ',0x15:'ISZERO',0x16:'AND',0x17:'OR',0x18:'XOR',0x19:'NOT',0x1a:'BYTE',0x1b:'SHL',0x1c:'SHR',0x1d:'SAR',0x20:'SHA3',0x30:'ADDRESS',0x31:'BALANCE',0x32:'ORIGIN',0x33:'CALLER',0x34:'CALLVALUE',0x35:'CALLDATALOAD',0x36:'CALLDATASIZE',0x37:'CALLDATACOPY',0x38:'CODESIZE',0x39:'CODECOPY',0x3a:'GASPRICE',0x3b:'EXTCODESIZE',0x3c:'EXTCODECOPY',0x3d:'RETURNDATASIZE',0x3e:'RETURNDATACOPY',0x3f:'EXTCODEHASH',0x40:'BLOCKHASH',0x41:'COINBASE',0x42:'TIMESTAMP',0x43:'NUMBER',0x44:'DIFFICULTY',0x45:'GASLIMIT',0x46:'CHAINID',0x47:'SELFBALANCE',0x48:'BASEFEE',0x50:'POP',0x51:'MLOAD',0x52:'MSTORE',0x53:'MSTORE8',0x54:'SLOAD',0x55:'SSTORE',0x56:'JUMP',0x57:'JUMPI',0x58:'PC',0x59:'MSIZE',0x5a:'GAS',0x5b:'JUMPDEST',0xf0:'CREATE',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
# disassemble to list
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# function entries from dispatcher
entries=[
('0x06fdde03',349),('0x095ea7b3',379),('0x0afbcdc9',414),('0x156e29f6',454),('0x18160ddd',473),('0x1da24f3e',495),
('0x23b872dd',514),('0x313ce567',533),('0x39509351',554),('0x4819128a',573),('0x4efecaa5',592),('0x70a08231',611),
('0x7535d246',630),('0x75d26413',662),('0x7df5bd3b',670),('0x95d89b41',691),('0xa457c2d7',699),('0xa9059cbb',718),
('0xae167335',737),('0xb16a19de',754),('0xb1bf962d',771),('0xd3b1e9a4',779),('0xd7020d0a',798),('0xdd62ed3e',817)
]
# build index for ops for easy slicing by pc
pc_to_index={pc:i for i,(pc,_,_) in enumerate(ops)}
for sel,pc in entries:
idx=pc_to_index.get(pc)
if idx is None:
print(sel, 'pc not found')
continue
print('\\n===', sel, 'entry', pc, '===')
for pc,name,data in ops[idx:idx+40]:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 53ms:
=== 0x06fdde03 entry 349 ===
349: JUMPDEST
350: PUSH2 0x0165
353: PUSH2 0x036a
356: JUMP
357: JUMPDEST
358: PUSH1 0x40
360: MLOAD
361: PUSH2 0x0172
364: SWAP2
365: SWAP1
366: PUSH2 0x20e3
369: JUMP
370: JUMPDEST
371: PUSH1 0x40
373: MLOAD
374: DUP1
375: SWAP2
376: SUB
thinking
**Identifying internal function entry points**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
hexcode=obj['artifact']['runtime_bytecode']['full']
code=bytes.fromhex(hexcode[2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
pc_to_index={pc:i for i,(pc,_,_) in enumerate(ops)}
entries=[
('0x06fdde03',349),('0x095ea7b3',379),('0x0afbcdc9',414),('0x156e29f6',454),('0x18160ddd',473),('0x1da24f3e',495),
('0x23b872dd',514),('0x313ce567',533),('0x39509351',554),('0x4819128a',573),('0x4efecaa5',592),('0x70a08231',611),
('0x7535d246',630),('0x75d26413',662),('0x7df5bd3b',670),('0x95d89b41',691),('0xa457c2d7',699),('0xa9059cbb',718),
('0xae167335',737),('0xb16a19de',754),('0x0xb1bf962d',771),('0xd3b1e9a4',779),('0xd7020d0a',798),('0xdd62ed3e',817)
]
for sel,pc in entries:
idx=pc_to_index[pc]
# scan forward for first unconditional JUMP preceded by PUSH2
target=None
for j in range(idx, min(idx+60, len(ops)-1)):
op=ops[j]
if op[1]=='JUMP' and ops[j-1][1].startswith('PUSH'):
# use immediate as target
data=ops[j-1][2]
if data:
target=int(data,16)
break
print(sel, 'entry', pc, 'first_jump_target', target)
PY" in /tmp/codex-09ha3ooo succeeded in 54ms:
0x06fdde03 entry 349 first_jump_target 874
0x095ea7b3 entry 379 first_jump_target 7995
0x0afbcdc9 entry 414 first_jump_target 7750
0x156e29f6 entry 454 first_jump_target 8038
0x18160ddd entry 473 first_jump_target 1340
0x1da24f3e entry 495 first_jump_target 7750
0x23b872dd entry 514 first_jump_target 7862
0x313ce567 entry 533 first_jump_target 370
0x39509351 entry 554 first_jump_target 7995
0x4819128a entry 573 first_jump_target 8310
0x4efecaa5 entry 592 first_jump_target 7995
0x70a08231 entry 611 first_jump_target 7750
0x7535d246 entry 630 first_jump_target 2250
0x75d26413 entry 662 first_jump_target 2265
0x7df5bd3b entry 670 first_jump_target 8358
0x95d89b41 entry 691 first_jump_target 2523
0xa457c2d7 entry 699 first_jump_target 7995
0xa9059cbb entry 718 first_jump_target 7995
0xae167335 entry 737 first_jump_target 638
0xb16a19de entry 754 first_jump_target 638
thinking
**Analyzing initializer function heuristics**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
storage=obj['analysis_artifact']['artifact_json']['storage']
print('writes count', len(storage.get('writes',[])))
print(storage.get('writes',[])[:20])
PY" in /tmp/codex-09ha3ooo exited 1 in 58ms:
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
TypeError: object of type 'int' has no len()
thinking
**Checking storage type**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
storage=obj['analysis_artifact']['artifact_json']['storage']
print(storage)
PY" in /tmp/codex-09ha3ooo succeeded in 80ms:
{'keccak_count': 20, 'reads': 55, 'slots': [{'op': 'SLOAD', 'pc': 536, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000065'}, {'op': 'SLOAD', 'pc': 740, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 757, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 880, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000036'}, {'op': 'SLOAD', 'pc': 953, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000100'}, {'op': 'SLOAD', 'pc': 1058, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 1349, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 1380, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 1856, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 1944, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 1947, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 2066, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 2106, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 2374, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 2529, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000037'}, {'op': 'SLOAD', 'pc': 2712, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 2718, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 2733, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 2777, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 2796, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 2929, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000094'}, {'op': 'SLOAD', 'pc': 2960, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 2973, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000093'}, {'op': 'SLOAD', 'pc': 3153, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 3326, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 3517, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 3952, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000093'}, {'op': 'SLOAD', 'pc': 4306, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 4771, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000093'}, {'op': 'SLOAD', 'pc': 4840, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 4855, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 4899, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 4918, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 4944, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000065'}, {'op': 'SLOAD', 'pc': 4965, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 4986, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 5108, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 5222, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000095'}, {'op': 'SLOAD', 'pc': 5895, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 6194, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 6334, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000035'}, {'op': 'SLOAD', 'pc': 6622, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}, {'op': 'SLOAD', 'pc': 6663, 'slot': '0x0000000000000000000000000000000000000000000000000000000000000000'}], 'writes': 20}
thinking
**Analyzing SSTORE operations in disassembly**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find SSTORE ops
sstore_indices=[i for i,(pc,name,data) in enumerate(ops) if name=='SSTORE']
print('SSTORE count', len(sstore_indices))
# print context around each
for idx in sstore_indices:
pc=ops[idx][0]
print('\\n-- SSTORE at pc', pc, '--')
for pc,name,data in ops[max(0, idx-5): idx+6]:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 57ms:
SSTORE count 20
-- SSTORE at pc 2807 --
2800: NOT
2801: AND
2802: PUSH2 0x0101
2805: OR
2806: SWAP1
2807: SSTORE
2808: JUMPDEST
2809: PUSH2 0x0b6d
2812: DUP6
2813: DUP6
2814: DUP1
-- SSTORE at pc 2956 --
2951: DUP4
2952: AND
2953: OR
2954: SWAP1
thinking
**Investigating initialization SSTOREs**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=2680; end=3050
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 41ms:
2680: JUMP
2681: JUMPDEST
2682: POP
2683: PUSH1 0x01
2685: SWAP4
2686: SWAP3
2687: POP
2688: POP
2689: POP
2690: JUMP
2691: JUMPDEST
2692: PUSH1 0x00
2694: PUSH2 0x0409
2697: CALLER
2698: DUP5
2699: DUP5
2700: PUSH2 0x123c
2703: JUMP
2704: JUMPDEST
2705: PUSH1 0x00
thinking
**Analyzing initializer and external calls**
I'm examining the initializer guard logic that relies on slot0 flags to ensure it runs only once, with no explicit access control but expected in upgradeable contracts. I'm also investigating external calls to possibly untrusted addresses stored in specific slots, focusing on potential reentrancy risks by checking if state updates precede these external calls around instruction address 4452. Let's look deeper into the disassembly near these callsites to understand the context better.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=4300; end=4550
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 45ms:
4301: PUSH2 0x10d5
4304: PUSH1 0x35
4306: SLOAD
4307: SWAP1
4308: JUMP
4309: JUMPDEST
4310: SWAP1
4311: POP
4312: PUSH1 0x00
4314: PUSH2 0x10e2
4317: DUP5
4318: PUSH2 0x0f52
4321: JUMP
4322: JUMPDEST
4323: SWAP1
4324: POP
4325: PUSH2 0x10ee
4328: DUP5
4329: DUP5
4330: PUSH2 0x1396
thinking
**Analyzing low-level contract calls**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=7330; end=7435
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 43ms:
7345: PUSH1 0x44
7347: DUP3
7348: ADD
7349: MSTORE
7350: PUSH1 0x64
7352: ADD
7353: PUSH2 0x0483
7356: JUMP
7357: JUMPDEST
7358: PUSH1 0x00
7360: DUP1
7361: DUP7
7362: PUSH1 0x01
7364: PUSH1 0x01
7366: PUSH1 0xa0
7368: SHL
7369: SUB
7370: AND
7371: DUP6
7372: DUP8
thinking
**Analyzing CALL instructions with stack arguments**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find push4 d15e0053
for i,(pc,name,data) in enumerate(ops):
if name=='PUSH4' and data=='d15e0053':
print('found at pc', pc)
# show context
for pc2,name2,data2 in ops[i-5:i+15]:
if data2 is None:
print(f'{pc2:5d}: {name2}')
else:
print(f'{pc2:5d}: {name2} 0x{data2}')
print('---')
PY" in /tmp/codex-09ha3ooo succeeded in 40ms:
found at pc 1384
1377: JUMPDEST
1378: PUSH1 0x95
1380: SLOAD
1381: PUSH1 0x40
1383: MLOAD
1384: PUSH4 0xd15e0053
1389: PUSH1 0xe0
1391: SHL
1392: DUP2
1393: MSTORE
1394: PUSH1 0x01
1396: PUSH1 0x01
1398: PUSH1 0xa0
1400: SHL
1401: SUB
1402: SWAP2
1403: DUP3
1404: AND
1405: PUSH1 0x04
thinking
**Analyzing staticcall to contract address**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble mapping
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=1330; end=1480
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 38ms:
1330: ISZERO
1331: SWAP1
1332: POP
1333: JUMPDEST
1334: SWAP4
1335: SWAP3
1336: POP
1337: POP
1338: POP
1339: JUMP
1340: JUMPDEST
1341: PUSH1 0x00
1343: DUP1
1344: PUSH2 0x0548
1347: PUSH1 0x35
1349: SLOAD
1350: SWAP1
1351: JUMP
1352: JUMPDEST
1353: SWAP1
thinking
**Analyzing external calls in transfer function**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
obj=json.loads(Path('BYTECODE_BUNDLE.json').read_text())
code=bytes.fromhex(obj['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=0x1200; end=0x1400
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 39ms:
4608: SWAP1
4609: PUSH2 0x20e3
4612: JUMP
4613: JUMPDEST
4614: POP
4615: PUSH12 0x033b2e3c9fd0803ce8000000
4628: PUSH2 0x121e
4631: PUSH1 0x02
4633: DUP3
4634: PUSH2 0x21c7
4637: JUMP
4638: JUMPDEST
4639: PUSH2 0x1228
4642: DUP5
4643: DUP7
4644: PUSH2 0x21e7
4647: JUMP
4648: JUMPDEST
4649: PUSH2 0x1232
4652: SWAP2
thinking
**Analyzing external token transfer logic**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# find ascii strings in bytecode
s=[]
cur=b''
start=0
for i,b in enumerate(code):
if 32 <= b < 127:
if not cur:
start=i
cur+=bytes([b])
else:
if len(cur)>=8:
s.append((start,cur.decode('ascii',errors='ignore')))
cur=b''
if len(cur)>=8:
s.append((start,cur.decode('ascii',errors='ignore')))
for off,strv in s:
if 'owner' in strv.lower() or 'admin' in strv.lower() or 'caller' in strv.lower():
print(hex(off), strv)
PY" in /tmp/codex-09ha3ooo succeeded in 43ms:
thinking
**Investigating Access Control Mechanism**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=4800; end=4895
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 41ms:
4800: SWAP2
4801: PUSH4 0x75d26413
4806: SWAP2
4807: PUSH1 0x04
4809: DUP1
4810: DUP4
4811: ADD
4812: SWAP3
4813: PUSH1 0x20
4815: SWAP3
4816: SWAP2
4817: SWAP1
4818: DUP3
4819: SWAP1
4820: SUB
4821: ADD
4822: DUP2
4823: DUP7
4824: DUP1
4825: EXTCODESIZE
thinking
**Searching for push4 75d26413 calls**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find push4 75d26413 and show next CALL/STATICCALL
for i,(pc,name,data) in enumerate(ops):
if name=='PUSH4' and data=='75d26413':
print('push4 75d26413 at', pc)
for pc2,name2,data2 in ops[i-5:i+15]:
if data2 is None:
print(f'{pc2:5d}: {name2}')
else:
print(f'{pc2:5d}: {name2} 0x{data2}')
print('---')
PY" in /tmp/codex-09ha3ooo succeeded in 59ms:
push4 75d26413 at 137
126: PUSH4 0x7535d246
131: EQ
132: PUSH2 0x0276
135: JUMPI
136: DUP1
137: PUSH4 0x75d26413
142: EQ
143: PUSH2 0x0296
146: JUMPI
147: DUP1
148: PUSH4 0x7df5bd3b
153: EQ
154: PUSH2 0x029e
157: JUMPI
158: DUP1
159: PUSH4 0x95d89b41
164: EQ
165: PUSH2 0x02b3
168: JUMPI
thinking
**Inspecting usage around address 3179**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=3140; end=3245
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 48ms:
3147: DUP11
3148: PUSH1 0x93
3150: PUSH1 0x00
3152: SWAP1
3153: SLOAD
3154: SWAP1
3155: PUSH2 0x0100
3158: EXP
3159: SWAP1
3160: DIV
3161: PUSH1 0x01
3163: PUSH1 0x01
3165: PUSH1 0xa0
3167: SHL
3168: SUB
3169: AND
3170: PUSH1 0x01
3172: PUSH1 0x01
3174: PUSH1 0xa0
3176: SHL
thinking
**Analyzing external calls and access control patterns**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find patterns of CALLER with EQ
for i,(pc,name,data) in enumerate(ops):
if name=='CALLER':
# look ahead 10 instructions for EQ or ISZERO
window=ops[i:i+12]
if any(op[1]=='EQ' for op in window):
print('\\nCALLER pattern around pc', pc)
for pc2,name2,data2 in ops[i-5:i+12]:
if data2 is None:
print(f'{pc2:5d}: {name2}')
else:
print(f'{pc2:5d}: {name2} 0x{data2}')
PY" in /tmp/codex-09ha3ooo succeeded in 49ms:
CALLER pattern around pc 1087
1080: PUSH1 0x01
1082: PUSH1 0xa0
1084: SHL
1085: SUB
1086: AND
1087: CALLER
1088: PUSH1 0x01
1090: PUSH1 0x01
1092: PUSH1 0xa0
1094: SHL
1095: SUB
1096: AND
1097: EQ
1098: PUSH1 0x40
1100: MLOAD
1101: DUP1
1102: PUSH1 0x40
thinking
**Analyzing address origin in bytecode**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
def disassemble(code):
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
return ops
ops=disassemble(code)
start=1040; end=1125
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 53ms:
1040: POP
1041: POP
1042: JUMP
1043: JUMPDEST
1044: PUSH1 0x00
1046: DUP1
1047: PUSH2 0x041f
1050: DUP4
1051: PUSH2 0x0f52
1054: JUMP
1055: JUMPDEST
1056: PUSH1 0x35
1058: SLOAD
1059: SWAP2
1060: POP
1061: SWAP2
1062: POP
1063: SWAP2
1064: POP
1065: SWAP2
thinking
**Analyzing access control check in bytecode**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=0x0f50; end=0x0fa0
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 42ms:
3920: POP
3921: JUMP
3922: JUMPDEST
3923: PUSH1 0x01
3925: PUSH1 0x01
3927: PUSH1 0xa0
3929: SHL
3930: SUB
3931: AND
3932: PUSH1 0x00
3934: SWAP1
3935: DUP2
3936: MSTORE
3937: PUSH1 0x33
3939: PUSH1 0x20
3941: MSTORE
3942: PUSH1 0x40
3944: SWAP1
3945: SHA3
3946: SLOAD
thinking
**Analyzing external call for access control**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=6360; end=6625
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 80ms:
6360: MSTORE
6361: PUSH1 0x01
6363: PUSH1 0x01
6365: PUSH1 0xa0
6367: SHL
6368: SUB
6369: DUP9
6370: DUP2
6371: AND
6372: PUSH1 0x04
6374: DUP4
6375: ADD
6376: MSTORE
6377: PUSH1 0x24
6379: DUP3
6380: ADD
6381: DUP5
6382: SWAP1
6383: MSTORE
6384: PUSH1 0x44
thinking
**Analyzing external calls and function mappings**
I'm examining external calls, especially those to dynamic addresses for token transfers or verifications, and trying to determine if reentrancy risks exist based on call and state update order. Also, I’m decoding function 0x7df5bd3b by tracing its internal jump to 0x08e3 to check for access control at the start of that internal function.
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=0x08e3; end=0x09a0
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 53ms:
2275: JUMPDEST
2276: PUSH2 0x08eb
2279: PUSH2 0x0f6d
2282: JUMP
2283: JUMPDEST
2284: PUSH1 0x01
2286: PUSH1 0x01
2288: PUSH1 0xa0
2290: SHL
2291: SUB
2292: AND
2293: CALLER
2294: PUSH1 0x01
2296: PUSH1 0x01
2298: PUSH1 0xa0
2300: SHL
2301: SUB
2302: AND
2303: EQ
2304: PUSH1 0x40
thinking
**Analyzing potential access control and reentrancy risks**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=6240; end=6360
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 57ms:
6240: PUSH2 0x22ad
6243: DUP4
6244: CODECOPY
6245: DUP2
6246: MLOAD
6247: SWAP2
6248: MSTORE
6249: SWAP1
6250: PUSH1 0x20
6252: ADD
6253: PUSH1 0x40
6255: MLOAD
6256: DUP1
6257: SWAP2
6258: SUB
6259: SWAP1
6260: LOG3
6261: POP
6262: POP
6263: POP
thinking
**Summarizing potential external call risks**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
start=6960; end=7145
for pc,name,data in ops:
if start <= pc <= end:
if data is None:
print(f'{pc:5d}: {name}')
else:
print(f'{pc:5d}: {name} 0x{data}')
PY" in /tmp/codex-09ha3ooo succeeded in 53ms:
6960: SHA3
6961: SLOAD
6962: DUP2
6963: DUP2
6964: LT
6965: ISZERO
6966: PUSH2 0x1b90
6969: JUMPI
6970: PUSH1 0x40
6972: MLOAD
6973: PUSH3 0x461bcd
6977: PUSH1 0xe5
6979: SHL
6980: DUP2
6981: MSTORE
6982: PUSH1 0x20
6984: PUSH1 0x04
6986: DUP3
6987: ADD
6988: MSTORE
thinking
**Analyzing internal mint access and external call risks**
exec
/bin/bash -lc "python - <<'PY'
import json
from pathlib import Path
code=bytes.fromhex(json.loads(Path('BYTECODE_BUNDLE.json').read_text())['artifact']['runtime_bytecode']['full'][2:])
# disassemble
opnames={i: f'OP_{i:02x}' for i in range(256)}
for i,name in enumerate(['STOP','ADD','MUL','SUB','DIV','SDIV','MOD','SMOD','ADDMOD','MULMOD','EXP','SIGNEXTEND']): opnames[i]=name
opnames.update({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',0xf1:'CALL',0xf2:'CALLCODE',0xf3:'RETURN',0xf4:'DELEGATECALL',0xf5:'CREATE2',0xfa:'STATICCALL',0xfd:'REVERT'})
for op in range(0x60,0x80): opnames[op]=f'PUSH{op-0x5f}'
for op in range(0x80,0x90): opnames[op]=f'DUP{op-0x7f}'
for op in range(0x90,0xa0): opnames[op]=f'SWAP{op-0x8f}'
for op in range(0xa0,0xa5): opnames[op]=f'LOG{op-0xa0}'
ops=[]
pc=0
while pc < len(code):
op=code[pc]
name=opnames.get(op, f'OP_{op:02x}')
if 0x60 <= op <= 0x7f:
n=op-0x5f
data=code[pc+1:pc+1+n]
ops.append((pc,name,data.hex()))
pc += 1+n
else:
ops.append((pc,name,None))
pc += 1
# find PUSH2 0x137d
for i,(pc,name,data) in enumerate(ops):
if name=='PUSH2' and data=='137d':
print('found PUSH2 0x137d at pc', pc)
for pc2,name2,data2 in ops[i-5:i+10]:
if data2 is None:
print(f'{pc2:5d}: {name2}')
else:
print(f'{pc2:5d}: {name2} 0x{data2}')
print('---')
PY" in /tmp/codex-09ha3ooo succeeded in 56ms:
found PUSH2 0x137d at pc 4981
4975: POP
4976: POP
4977: JUMP
4978: JUMPDEST
4979: PUSH1 0x00
4981: PUSH2 0x137d
4984: PUSH1 0x35
4986: SLOAD
4987: SWAP1
4988: JUMP
4989: JUMPDEST
4990: SWAP1
4991: POP
4992: PUSH1 0x00
4994: PUSH2 0x138a
---
thinking
**Evaluating mint and upgradeability concerns**
codex
{"no_findings":true,"summary":"Reviewed the implementation bytecode and analysis artifacts. The contract appears to be an ERC20-style token with initializer logic and several external calls (staticcall/call) to configured contracts; the only CALLCODE/CREATE2 opcodes observed are in unreachable metadata. Based on available bytecode-only evidence, no concrete exploitable issues were identified. Uncertainty remains due to selector inference limits and lack of source-level context.","findings":[]}
tokens used
163,527
{
"codex": {
"ran_at": "2026-01-13T00:26:58.629373+00:00",
"returncode": 0
},
"project": {
"mode": "bytecode",
"bytecode_length": 17926,
"bytecode_truncated": false,
"capability_graph_present": true,
"analysis_artifact_present": true
},
"summary": "Reviewed the implementation bytecode and analysis artifacts. The contract appears to be an ERC20-style token with initializer logic and several external calls (staticcall/call) to configured contracts; the only CALLCODE/CREATE2 opcodes observed are in unreachable metadata. Based on available bytecode-only evidence, no concrete exploitable issues were identified. Uncertainty remains due to selector inference limits and lack of source-level context.",
"raw_final": {
"summary": "Reviewed the implementation bytecode and analysis artifacts. The contract appears to be an ERC20-style token with initializer logic and several external calls (staticcall/call) to configured contracts; the only CALLCODE/CREATE2 opcodes observed are in unreachable metadata. Based on available bytecode-only evidence, no concrete exploitable issues were identified. Uncertainty remains due to selector inference limits and lack of source-level context.",
"findings": [],
"no_findings": true
},
"no_findings": true,
"proxy_context": {
"proxy_run_id": "019bb490-f395-7383-8ffe-d86692ad0013",
"proxy_address": "0x3c3e283353f4349f6424151583a8353e8f40f2b1",
"implementation_run_id": "019bb491-966d-7208-a0e1-502697e2a9ca",
"implementation_address": "0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49"
},
"schema_version": 1
}
00000000: PUSH1 0x80 00000002: PUSH1 0x40 00000004: MSTORE 00000005: PUSH1 0x04 00000007: CALLDATASIZE 00000008: LT 00000009: PUSH2 0x0059 0000000c: JUMPI 0000000d: PUSH1 0x00 0000000f: CALLDATALOAD 00000010: PUSH1 0xe0 00000012: SHR 00000013: DUP1 00000014: PUSH4 0x3659cfe6 00000019: EQ 0000001a: PUSH2 0x0070 0000001d: JUMPI 0000001e: DUP1 0000001f: PUSH4 0x4f1ef286 00000024: EQ 00000025: PUSH2 0x0090 00000028: JUMPI 00000029: DUP1 0000002a: PUSH4 0x5c60da1b 0000002f: EQ 00000030: PUSH2 0x00a3 00000033: JUMPI 00000034: DUP1 00000035: PUSH4 0x8f283970 0000003a: EQ 0000003b: PUSH2 0x00d4 0000003e: JUMPI 0000003f: DUP1 00000040: PUSH4 0xaaf10f42 00000045: EQ 00000046: PUSH2 0x00f4 00000049: JUMPI 0000004a: DUP1 0000004b: PUSH4 0xf851a440 00000050: EQ 00000051: PUSH2 0x0109 00000054: JUMPI 00000055: PUSH2 0x0068 00000058: JUMP 00000059: JUMPDEST 0000005a: CALLDATASIZE 0000005b: PUSH2 0x0068 0000005e: JUMPI 0000005f: PUSH2 0x0066 00000062: PUSH2 0x011e 00000065: JUMP 00000066: JUMPDEST 00000067: STOP 00000068: JUMPDEST 00000069: PUSH2 0x0066 0000006c: PUSH2 0x011e 0000006f: JUMP 00000070: JUMPDEST 00000071: CALLVALUE 00000072: DUP1 00000073: ISZERO 00000074: PUSH2 0x007c 00000077: JUMPI 00000078: PUSH1 0x00 0000007a: DUP1 0000007b: REVERT 0000007c: JUMPDEST 0000007d: POP 0000007e: PUSH2 0x0066 00000081: PUSH2 0x008b 00000084: CALLDATASIZE 00000085: PUSH1 0x04 00000087: PUSH2 0x075b 0000008a: JUMP 0000008b: JUMPDEST 0000008c: PUSH2 0x0138 0000008f: JUMP 00000090: JUMPDEST 00000091: PUSH2 0x0066 00000094: PUSH2 0x009e 00000097: CALLDATASIZE 00000098: PUSH1 0x04 0000009a: PUSH2 0x0775 0000009d: JUMP 0000009e: JUMPDEST 0000009f: PUSH2 0x017f 000000a2: JUMP 000000a3: JUMPDEST 000000a4: CALLVALUE 000000a5: DUP1 000000a6: ISZERO 000000a7: PUSH2 0x00af 000000aa: JUMPI 000000ab: PUSH1 0x00 000000ad: DUP1 000000ae: REVERT 000000af: JUMPDEST 000000b0: POP 000000b1: PUSH2 0x00b8 000000b4: PUSH2 0x01f0 000000b7: JUMP 000000b8: JUMPDEST 000000b9: PUSH1 0x40 000000bb: MLOAD 000000bc: PUSH1 0x01 000000be: PUSH1 0x01 000000c0: PUSH1 0xa0 000000c2: SHL 000000c3: SUB 000000c4: SWAP1 000000c5: SWAP2 000000c6: AND 000000c7: DUP2 000000c8: MSTORE 000000c9: PUSH1 0x20 000000cb: ADD 000000cc: PUSH1 0x40 000000ce: MLOAD 000000cf: DUP1 000000d0: SWAP2 000000d1: SUB 000000d2: SWAP1 000000d3: RETURN 000000d4: JUMPDEST 000000d5: CALLVALUE 000000d6: DUP1 000000d7: ISZERO 000000d8: PUSH2 0x00e0 000000db: JUMPI 000000dc: PUSH1 0x00 000000de: DUP1 000000df: REVERT 000000e0: JUMPDEST 000000e1: POP 000000e2: PUSH2 0x0066 000000e5: PUSH2 0x00ef 000000e8: CALLDATASIZE 000000e9: PUSH1 0x04 000000eb: PUSH2 0x075b 000000ee: JUMP 000000ef: JUMPDEST 000000f0: PUSH2 0x022b 000000f3: JUMP 000000f4: JUMPDEST 000000f5: CALLVALUE 000000f6: DUP1 000000f7: ISZERO 000000f8: PUSH2 0x0100 000000fb: JUMPI 000000fc: PUSH1 0x00 000000fe: DUP1 000000ff: REVERT 00000100: JUMPDEST 00000101: POP 00000102: PUSH2 0x00b8 00000105: PUSH2 0x0255 00000108: JUMP 00000109: JUMPDEST 0000010a: CALLVALUE 0000010b: DUP1 0000010c: ISZERO 0000010d: PUSH2 0x0115 00000110: JUMPI 00000111: PUSH1 0x00 00000113: DUP1 00000114: REVERT 00000115: JUMPDEST 00000116: POP 00000117: PUSH2 0x00b8 0000011a: PUSH2 0x02bf 0000011d: JUMP 0000011e: JUMPDEST 0000011f: PUSH2 0x0126 00000122: PUSH2 0x031c 00000125: JUMP 00000126: JUMPDEST 00000127: PUSH2 0x0136 0000012a: PUSH2 0x0131 0000012d: PUSH2 0x03b6 00000130: JUMP 00000131: JUMPDEST 00000132: PUSH2 0x03c0 00000135: JUMP 00000136: JUMPDEST 00000137: JUMP 00000138: JUMPDEST 00000139: PUSH2 0x0140 0000013c: PUSH2 0x03e4 0000013f: JUMP 00000140: JUMPDEST 00000141: PUSH1 0x01 00000143: PUSH1 0x01 00000145: PUSH1 0xa0 00000147: SHL 00000148: SUB 00000149: AND 0000014a: CALLER 0000014b: PUSH1 0x01 0000014d: PUSH1 0x01 0000014f: PUSH1 0xa0 00000151: SHL 00000152: SUB 00000153: AND 00000154: EQ 00000155: ISZERO 00000156: PUSH2 0x0177 00000159: JUMPI 0000015a: PUSH2 0x0174 0000015d: DUP2 0000015e: PUSH1 0x40 00000160: MLOAD 00000161: DUP1 00000162: PUSH1 0x20 00000164: ADD 00000165: PUSH1 0x40 00000167: MSTORE 00000168: DUP1 00000169: PUSH1 0x00 0000016b: DUP2 0000016c: MSTORE 0000016d: POP 0000016e: PUSH1 0x00 00000170: PUSH2 0x0417 00000173: JUMP 00000174: JUMPDEST 00000175: POP 00000176: JUMP 00000177: JUMPDEST 00000178: PUSH2 0x0174 0000017b: PUSH2 0x011e 0000017e: JUMP 0000017f: JUMPDEST 00000180: PUSH2 0x0187 00000183: PUSH2 0x03e4 00000186: JUMP 00000187: JUMPDEST 00000188: PUSH1 0x01 0000018a: PUSH1 0x01 0000018c: PUSH1 0xa0 0000018e: SHL 0000018f: SUB 00000190: AND 00000191: CALLER 00000192: PUSH1 0x01 00000194: PUSH1 0x01 00000196: PUSH1 0xa0 00000198: SHL 00000199: SUB 0000019a: AND 0000019b: EQ 0000019c: ISZERO 0000019d: PUSH2 0x01e8 000001a0: JUMPI 000001a1: PUSH2 0x01e3 000001a4: DUP4 000001a5: DUP4 000001a6: DUP4 000001a7: DUP1 000001a8: DUP1 000001a9: PUSH1 0x1f 000001ab: ADD 000001ac: PUSH1 0x20 000001ae: DUP1 000001af: SWAP2 000001b0: DIV 000001b1: MUL 000001b2: PUSH1 0x20 000001b4: ADD 000001b5: PUSH1 0x40 000001b7: MLOAD 000001b8: SWAP1 000001b9: DUP2 000001ba: ADD 000001bb: PUSH1 0x40 000001bd: MSTORE 000001be: DUP1 000001bf: SWAP4 000001c0: SWAP3 000001c1: SWAP2 000001c2: SWAP1 000001c3: DUP2 000001c4: DUP2 000001c5: MSTORE 000001c6: PUSH1 0x20 000001c8: ADD 000001c9: DUP4 000001ca: DUP4 000001cb: DUP1 000001cc: DUP3 000001cd: DUP5 000001ce: CALLDATACOPY 000001cf: PUSH1 0x00 000001d1: SWAP3 000001d2: ADD 000001d3: SWAP2 000001d4: SWAP1 000001d5: SWAP2 000001d6: MSTORE 000001d7: POP 000001d8: PUSH1 0x01 000001da: SWAP3 000001db: POP 000001dc: PUSH2 0x0417 000001df: SWAP2 000001e0: POP 000001e1: POP 000001e2: JUMP 000001e3: JUMPDEST 000001e4: POP 000001e5: POP 000001e6: POP 000001e7: JUMP 000001e8: JUMPDEST 000001e9: PUSH2 0x01e3 000001ec: PUSH2 0x011e 000001ef: JUMP 000001f0: JUMPDEST 000001f1: PUSH1 0x00 000001f3: PUSH2 0x01fa 000001f6: PUSH2 0x03e4 000001f9: JUMP 000001fa: JUMPDEST 000001fb: PUSH1 0x01 000001fd: PUSH1 0x01 000001ff: PUSH1 0xa0 00000201: SHL 00000202: SUB 00000203: AND 00000204: CALLER 00000205: PUSH1 0x01 00000207: PUSH1 0x01 00000209: PUSH1 0xa0 0000020b: SHL 0000020c: SUB 0000020d: AND 0000020e: EQ 0000020f: ISZERO 00000210: PUSH2 0x0220 00000213: JUMPI 00000214: PUSH2 0x021b 00000217: PUSH2 0x03b6 0000021a: JUMP 0000021b: JUMPDEST 0000021c: SWAP1 0000021d: POP 0000021e: SWAP1 0000021f: JUMP 00000220: JUMPDEST 00000221: PUSH2 0x0228 00000224: PUSH2 0x011e 00000227: JUMP 00000228: JUMPDEST 00000229: SWAP1 0000022a: JUMP 0000022b: JUMPDEST 0000022c: PUSH2 0x0233 0000022f: PUSH2 0x03e4 00000232: JUMP 00000233: JUMPDEST 00000234: PUSH1 0x01 00000236: PUSH1 0x01 00000238: PUSH1 0xa0 0000023a: SHL 0000023b: SUB 0000023c: AND 0000023d: CALLER 0000023e: PUSH1 0x01 00000240: PUSH1 0x01 00000242: PUSH1 0xa0 00000244: SHL 00000245: SUB 00000246: AND 00000247: EQ 00000248: ISZERO 00000249: PUSH2 0x0177 0000024c: JUMPI 0000024d: PUSH2 0x0174 00000250: DUP2 00000251: PUSH2 0x0442 00000254: JUMP 00000255: JUMPDEST 00000256: PUSH1 0x00 00000258: PUSH2 0x025f 0000025b: PUSH2 0x03e4 0000025e: JUMP 0000025f: JUMPDEST 00000260: PUSH1 0x01 00000262: PUSH1 0x01 00000264: PUSH1 0xa0 00000266: SHL 00000267: SUB 00000268: AND 00000269: CALLER 0000026a: PUSH1 0x01 0000026c: PUSH1 0x01 0000026e: PUSH1 0xa0 00000270: SHL 00000271: SUB 00000272: AND 00000273: EQ 00000274: PUSH1 0x40 00000276: MLOAD 00000277: DUP1 00000278: PUSH1 0x40 0000027a: ADD 0000027b: PUSH1 0x40 0000027d: MSTORE 0000027e: DUP1 0000027f: PUSH1 0x03 00000281: DUP2 00000282: MSTORE 00000283: PUSH1 0x20 00000285: ADD 00000286: PUSH3 0x031303 0000028a: PUSH1 0xec 0000028c: SHL 0000028d: DUP2 0000028e: MSTORE 0000028f: POP 00000290: SWAP1 00000291: PUSH2 0x02b6 00000294: JUMPI 00000295: PUSH1 0x40 00000297: MLOAD 00000298: PUSH3 0x461bcd 0000029c: PUSH1 0xe5 0000029e: SHL 0000029f: DUP2 000002a0: MSTORE 000002a1: PUSH1 0x04 000002a3: ADD 000002a4: PUSH2 0x02ad 000002a7: SWAP2 000002a8: SWAP1 000002a9: PUSH2 0x080f 000002ac: JUMP 000002ad: JUMPDEST 000002ae: PUSH1 0x40 000002b0: MLOAD 000002b1: DUP1 000002b2: SWAP2 000002b3: SUB 000002b4: SWAP1 000002b5: REVERT 000002b6: JUMPDEST 000002b7: POP 000002b8: PUSH2 0x021b 000002bb: PUSH2 0x0496 000002be: JUMP 000002bf: JUMPDEST 000002c0: PUSH1 0x00 000002c2: PUSH2 0x02c9 000002c5: PUSH2 0x03e4 000002c8: JUMP 000002c9: JUMPDEST 000002ca: PUSH1 0x01 000002cc: PUSH1 0x01 000002ce: PUSH1 0xa0 000002d0: SHL 000002d1: SUB 000002d2: AND 000002d3: CALLER 000002d4: PUSH1 0x01 000002d6: PUSH1 0x01 000002d8: PUSH1 0xa0 000002da: SHL 000002db: SUB 000002dc: AND 000002dd: EQ 000002de: ISZERO 000002df: PUSH2 0x0220 000002e2: JUMPI 000002e3: PUSH2 0x021b 000002e6: PUSH2 0x03e4 000002e9: JUMP 000002ea: JUMPDEST 000002eb: PUSH1 0x60 000002ed: PUSH2 0x030f 000002f0: DUP4 000002f1: DUP4 000002f2: PUSH1 0x40 000002f4: MLOAD 000002f5: DUP1 000002f6: PUSH1 0x60 000002f8: ADD 000002f9: PUSH1 0x40 000002fb: MSTORE 000002fc: DUP1 000002fd: PUSH1 0x27 000002ff: DUP2 00000300: MSTORE 00000301: PUSH1 0x20 00000303: ADD 00000304: PUSH2 0x086f 00000307: PUSH1 0x27 00000309: SWAP2 0000030a: CODECOPY 0000030b: PUSH2 0x04be 0000030e: JUMP 0000030f: JUMPDEST 00000310: SWAP4 00000311: SWAP3 00000312: POP 00000313: POP 00000314: POP 00000315: JUMP 00000316: JUMPDEST 00000317: EXTCODESIZE 00000318: ISZERO 00000319: ISZERO 0000031a: SWAP1 0000031b: JUMP 0000031c: JUMPDEST 0000031d: PUSH2 0x0324 00000320: PUSH2 0x03e4 00000323: JUMP 00000324: JUMPDEST 00000325: PUSH1 0x01 00000327: PUSH1 0x01 00000329: PUSH1 0xa0 0000032b: SHL 0000032c: SUB 0000032d: AND 0000032e: CALLER 0000032f: PUSH1 0x01 00000331: PUSH1 0x01 00000333: PUSH1 0xa0 00000335: SHL 00000336: SUB 00000337: AND 00000338: EQ 00000339: ISZERO 0000033a: PUSH2 0x0136 0000033d: JUMPI 0000033e: PUSH1 0x40 00000340: MLOAD 00000341: PUSH3 0x461bcd 00000345: PUSH1 0xe5 00000347: SHL 00000348: DUP2 00000349: MSTORE 0000034a: PUSH1 0x20 0000034c: PUSH1 0x04 0000034e: DUP3 0000034f: ADD 00000350: MSTORE 00000351: PUSH1 0x42 00000353: PUSH1 0x24 00000355: DUP3 00000356: ADD 00000357: MSTORE 00000358: PUSH32 0x5472616e73706172656e745570677261646561626c6550726f78793a2061646d 00000379: PUSH1 0x44 0000037b: DUP3 0000037c: ADD 0000037d: MSTORE 0000037e: PUSH32 0x696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267 0000039f: PUSH1 0x64 000003a1: DUP3 000003a2: ADD 000003a3: MSTORE 000003a4: PUSH2 0x195d 000003a7: PUSH1 0xf2 000003a9: SHL 000003aa: PUSH1 0x84 000003ac: DUP3 000003ad: ADD 000003ae: MSTORE 000003af: PUSH1 0xa4 000003b1: ADD 000003b2: PUSH2 0x02ad 000003b5: JUMP 000003b6: JUMPDEST 000003b7: PUSH1 0x00 000003b9: PUSH2 0x021b 000003bc: PUSH2 0x0496 000003bf: JUMP 000003c0: JUMPDEST 000003c1: CALLDATASIZE 000003c2: PUSH1 0x00 000003c4: DUP1 000003c5: CALLDATACOPY 000003c6: PUSH1 0x00 000003c8: DUP1 000003c9: CALLDATASIZE 000003ca: PUSH1 0x00 000003cc: DUP5 000003cd: GAS 000003ce: DELEGATECALL 000003cf: RETURNDATASIZE 000003d0: PUSH1 0x00 000003d2: DUP1 000003d3: RETURNDATACOPY 000003d4: DUP1 000003d5: DUP1 000003d6: ISZERO 000003d7: PUSH2 0x03df 000003da: JUMPI 000003db: RETURNDATASIZE 000003dc: PUSH1 0x00 000003de: RETURN 000003df: JUMPDEST 000003e0: RETURNDATASIZE 000003e1: PUSH1 0x00 000003e3: REVERT 000003e4: JUMPDEST 000003e5: PUSH1 0x00 000003e7: PUSH32 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 00000408: JUMPDEST 00000409: SLOAD 0000040a: PUSH1 0x01 0000040c: PUSH1 0x01 0000040e: PUSH1 0xa0 00000410: SHL 00000411: SUB 00000412: AND 00000413: SWAP2 00000414: SWAP1 00000415: POP 00000416: JUMP 00000417: JUMPDEST 00000418: PUSH2 0x0420 0000041b: DUP4 0000041c: PUSH2 0x0592 0000041f: JUMP 00000420: JUMPDEST 00000421: PUSH1 0x00 00000423: DUP3 00000424: MLOAD 00000425: GT 00000426: DUP1 00000427: PUSH2 0x042d 0000042a: JUMPI 0000042b: POP 0000042c: DUP1 0000042d: JUMPDEST 0000042e: ISZERO 0000042f: PUSH2 0x01e3 00000432: JUMPI 00000433: PUSH2 0x043c 00000436: DUP4 00000437: DUP4 00000438: PUSH2 0x02ea 0000043b: JUMP 0000043c: JUMPDEST 0000043d: POP 0000043e: POP 0000043f: POP 00000440: POP 00000441: JUMP 00000442: JUMPDEST 00000443: PUSH32 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f 00000464: PUSH2 0x046b 00000467: PUSH2 0x03e4 0000046a: JUMP 0000046b: JUMPDEST 0000046c: PUSH1 0x40 0000046e: DUP1 0000046f: MLOAD 00000470: PUSH1 0x01 00000472: PUSH1 0x01 00000474: PUSH1 0xa0 00000476: SHL 00000477: SUB 00000478: SWAP3 00000479: DUP4 0000047a: AND 0000047b: DUP2 0000047c: MSTORE 0000047d: SWAP2 0000047e: DUP5 0000047f: AND 00000480: PUSH1 0x20 00000482: DUP4 00000483: ADD 00000484: MSTORE 00000485: ADD 00000486: PUSH1 0x40 00000488: MLOAD 00000489: DUP1 0000048a: SWAP2 0000048b: SUB 0000048c: SWAP1 0000048d: LOG1 0000048e: PUSH2 0x0174 00000491: DUP2 00000492: PUSH2 0x05d2 00000495: JUMP 00000496: JUMPDEST 00000497: PUSH1 0x00 00000499: PUSH32 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc 000004ba: PUSH2 0x0408 000004bd: JUMP 000004be: JUMPDEST 000004bf: PUSH1 0x60 000004c1: DUP4 000004c2: EXTCODESIZE 000004c3: PUSH2 0x051d 000004c6: JUMPI 000004c7: PUSH1 0x40 000004c9: MLOAD 000004ca: PUSH3 0x461bcd 000004ce: PUSH1 0xe5 000004d0: SHL 000004d1: DUP2 000004d2: MSTORE 000004d3: PUSH1 0x20 000004d5: PUSH1 0x04 000004d7: DUP3 000004d8: ADD 000004d9: MSTORE 000004da: PUSH1 0x26 000004dc: PUSH1 0x24 000004de: DUP3 000004df: ADD 000004e0: MSTORE 000004e1: PUSH32 0x416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f 00000502: PUSH1 0x44 00000504: DUP3 00000505: ADD 00000506: MSTORE 00000507: PUSH6 0x1b9d1c9858dd 0000050e: PUSH1 0xd2 00000510: SHL 00000511: PUSH1 0x64 00000513: DUP3 00000514: ADD 00000515: MSTORE 00000516: PUSH1 0x84 00000518: ADD 00000519: PUSH2 0x02ad 0000051c: JUMP 0000051d: JUMPDEST 0000051e: PUSH1 0x00 00000520: DUP1 00000521: DUP6 00000522: PUSH1 0x01 00000524: PUSH1 0x01 00000526: PUSH1 0xa0 00000528: SHL 00000529: SUB 0000052a: AND 0000052b: DUP6 0000052c: PUSH1 0x40 0000052e: MLOAD 0000052f: PUSH2 0x0538 00000532: SWAP2 00000533: SWAP1 00000534: PUSH2 0x07f3 00000537: JUMP 00000538: JUMPDEST 00000539: PUSH1 0x00 0000053b: PUSH1 0x40 0000053d: MLOAD 0000053e: DUP1 0000053f: DUP4 00000540: SUB 00000541: DUP2 00000542: DUP6 00000543: GAS 00000544: DELEGATECALL 00000545: SWAP2 00000546: POP 00000547: POP 00000548: RETURNDATASIZE 00000549: DUP1 0000054a: PUSH1 0x00 0000054c: DUP2 0000054d: EQ 0000054e: PUSH2 0x0573 00000551: JUMPI 00000552: PUSH1 0x40 00000554: MLOAD 00000555: SWAP2 00000556: POP 00000557: PUSH1 0x1f 00000559: NOT 0000055a: PUSH1 0x3f 0000055c: RETURNDATASIZE 0000055d: ADD 0000055e: AND 0000055f: DUP3 00000560: ADD 00000561: PUSH1 0x40 00000563: MSTORE 00000564: RETURNDATASIZE 00000565: DUP3 00000566: MSTORE 00000567: RETURNDATASIZE 00000568: PUSH1 0x00 0000056a: PUSH1 0x20 0000056c: DUP5 0000056d: ADD 0000056e: RETURNDATACOPY 0000056f: PUSH2 0x0578 00000572: JUMP 00000573: JUMPDEST 00000574: PUSH1 0x60 00000576: SWAP2 00000577: POP 00000578: JUMPDEST 00000579: POP 0000057a: SWAP2 0000057b: POP 0000057c: SWAP2 0000057d: POP 0000057e: PUSH2 0x0588 00000581: DUP3 00000582: DUP3 00000583: DUP7 00000584: PUSH2 0x067b 00000587: JUMP 00000588: JUMPDEST 00000589: SWAP7 0000058a: SWAP6 0000058b: POP 0000058c: POP 0000058d: POP 0000058e: POP 0000058f: POP 00000590: POP 00000591: JUMP 00000592: JUMPDEST 00000593: PUSH2 0x059b 00000596: DUP2 00000597: PUSH2 0x06b4 0000059a: JUMP 0000059b: JUMPDEST 0000059c: PUSH1 0x40 0000059e: MLOAD 0000059f: PUSH1 0x01 000005a1: PUSH1 0x01 000005a3: PUSH1 0xa0 000005a5: SHL 000005a6: SUB 000005a7: DUP3 000005a8: AND 000005a9: SWAP1 000005aa: PUSH32 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b 000005cb: SWAP1 000005cc: PUSH1 0x00 000005ce: SWAP1 000005cf: LOG2 000005d0: POP 000005d1: JUMP 000005d2: JUMPDEST 000005d3: PUSH1 0x01 000005d5: PUSH1 0x01 000005d7: PUSH1 0xa0 000005d9: SHL 000005da: SUB 000005db: DUP2 000005dc: AND 000005dd: PUSH2 0x0637 000005e0: JUMPI 000005e1: PUSH1 0x40 000005e3: MLOAD 000005e4: PUSH3 0x461bcd 000005e8: PUSH1 0xe5 000005ea: SHL 000005eb: DUP2 000005ec: MSTORE 000005ed: PUSH1 0x20 000005ef: PUSH1 0x04 000005f1: DUP3 000005f2: ADD 000005f3: MSTORE 000005f4: PUSH1 0x26 000005f6: PUSH1 0x24 000005f8: DUP3 000005f9: ADD 000005fa: MSTORE 000005fb: PUSH32 0x455243313936373a206e65772061646d696e20697320746865207a65726f2061 0000061c: PUSH1 0x44 0000061e: DUP3 0000061f: ADD 00000620: MSTORE 00000621: PUSH6 0x646472657373 00000628: PUSH1 0xd0 0000062a: SHL 0000062b: PUSH1 0x64 0000062d: DUP3 0000062e: ADD 0000062f: MSTORE 00000630: PUSH1 0x84 00000632: ADD 00000633: PUSH2 0x02ad 00000636: JUMP 00000637: JUMPDEST 00000638: DUP1 00000639: PUSH32 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 0000065a: JUMPDEST 0000065b: DUP1 0000065c: SLOAD 0000065d: PUSH1 0x01 0000065f: PUSH1 0x01 00000661: PUSH1 0xa0 00000663: SHL 00000664: SUB 00000665: NOT 00000666: AND 00000667: PUSH1 0x01 00000669: PUSH1 0x01 0000066b: PUSH1 0xa0 0000066d: SHL 0000066e: SUB 0000066f: SWAP3 00000670: SWAP1 00000671: SWAP3 00000672: AND 00000673: SWAP2 00000674: SWAP1 00000675: SWAP2 00000676: OR 00000677: SWAP1 00000678: SSTORE 00000679: POP 0000067a: JUMP 0000067b: JUMPDEST 0000067c: PUSH1 0x60 0000067e: DUP4 0000067f: ISZERO 00000680: PUSH2 0x068a 00000683: JUMPI 00000684: POP 00000685: DUP2 00000686: PUSH2 0x030f 00000689: JUMP 0000068a: JUMPDEST 0000068b: DUP3 0000068c: MLOAD 0000068d: ISZERO 0000068e: PUSH2 0x069a 00000691: JUMPI 00000692: DUP3 00000693: MLOAD 00000694: DUP1 00000695: DUP5 00000696: PUSH1 0x20 00000698: ADD 00000699: REVERT 0000069a: JUMPDEST 0000069b: DUP2 0000069c: PUSH1 0x40 0000069e: MLOAD 0000069f: PUSH3 0x461bcd 000006a3: PUSH1 0xe5 000006a5: SHL 000006a6: DUP2 000006a7: MSTORE 000006a8: PUSH1 0x04 000006aa: ADD 000006ab: PUSH2 0x02ad 000006ae: SWAP2 000006af: SWAP1 000006b0: PUSH2 0x080f 000006b3: JUMP 000006b4: JUMPDEST 000006b5: DUP1 000006b6: EXTCODESIZE 000006b7: PUSH2 0x0718 000006ba: JUMPI 000006bb: PUSH1 0x40 000006bd: MLOAD 000006be: PUSH3 0x461bcd 000006c2: PUSH1 0xe5 000006c4: SHL 000006c5: DUP2 000006c6: MSTORE 000006c7: PUSH1 0x20 000006c9: PUSH1 0x04 000006cb: DUP3 000006cc: ADD 000006cd: MSTORE 000006ce: PUSH1 0x2d 000006d0: PUSH1 0x24 000006d2: DUP3 000006d3: ADD 000006d4: MSTORE 000006d5: PUSH32 0x455243313936373a206e657720696d706c656d656e746174696f6e206973206e 000006f6: PUSH1 0x44 000006f8: DUP3 000006f9: ADD 000006fa: MSTORE 000006fb: PUSH13 0x1bdd08184818dbdb9d1c9858dd 00000709: PUSH1 0x9a 0000070b: SHL 0000070c: PUSH1 0x64 0000070e: DUP3 0000070f: ADD 00000710: MSTORE 00000711: PUSH1 0x84 00000713: ADD 00000714: PUSH2 0x02ad 00000717: JUMP 00000718: JUMPDEST 00000719: DUP1 0000071a: PUSH32 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc 0000073b: PUSH2 0x065a 0000073e: JUMP 0000073f: JUMPDEST 00000740: DUP1 00000741: CALLDATALOAD 00000742: PUSH1 0x01 00000744: PUSH1 0x01 00000746: PUSH1 0xa0 00000748: SHL 00000749: SUB 0000074a: DUP2 0000074b: AND 0000074c: DUP2 0000074d: EQ 0000074e: PUSH2 0x0756 00000751: JUMPI 00000752: PUSH1 0x00 00000754: DUP1 00000755: REVERT 00000756: JUMPDEST 00000757: SWAP2 00000758: SWAP1 00000759: POP 0000075a: JUMP 0000075b: JUMPDEST 0000075c: PUSH1 0x00 0000075e: PUSH1 0x20 00000760: DUP3 00000761: DUP5 00000762: SUB 00000763: SLT 00000764: ISZERO 00000765: PUSH2 0x076c 00000768: JUMPI 00000769: DUP1 0000076a: DUP2 0000076b: REVERT 0000076c: JUMPDEST 0000076d: PUSH2 0x030f 00000770: DUP3 00000771: PUSH2 0x073f 00000774: JUMP 00000775: JUMPDEST 00000776: PUSH1 0x00 00000778: DUP1 00000779: PUSH1 0x00 0000077b: PUSH1 0x40 0000077d: DUP5 0000077e: DUP7 0000077f: SUB 00000780: SLT 00000781: ISZERO 00000782: PUSH2 0x0789 00000785: JUMPI 00000786: DUP2 00000787: DUP3 00000788: REVERT 00000789: JUMPDEST 0000078a: PUSH2 0x0792 0000078d: DUP5 0000078e: PUSH2 0x073f 00000791: JUMP 00000792: JUMPDEST 00000793: SWAP3 00000794: POP 00000795: PUSH1 0x20 00000797: DUP5 00000798: ADD 00000799: CALLDATALOAD 0000079a: PUSH8 0xffffffffffffffff 000007a3: DUP1 000007a4: DUP3 000007a5: GT 000007a6: ISZERO 000007a7: PUSH2 0x07ae 000007aa: JUMPI 000007ab: DUP4 000007ac: DUP5 000007ad: REVERT 000007ae: JUMPDEST 000007af: DUP2 000007b0: DUP7 000007b1: ADD 000007b2: SWAP2 000007b3: POP 000007b4: DUP7 000007b5: PUSH1 0x1f 000007b7: DUP4 000007b8: ADD 000007b9: SLT 000007ba: PUSH2 0x07c1 000007bd: JUMPI 000007be: DUP4 000007bf: DUP5 000007c0: REVERT 000007c1: JUMPDEST 000007c2: DUP2 000007c3: CALLDATALOAD 000007c4: DUP2 000007c5: DUP2 000007c6: GT 000007c7: ISZERO 000007c8: PUSH2 0x07cf 000007cb: JUMPI 000007cc: DUP5 000007cd: DUP6 000007ce: REVERT 000007cf: JUMPDEST 000007d0: DUP8 000007d1: PUSH1 0x20 000007d3: DUP3 000007d4: DUP6 000007d5: ADD 000007d6: ADD 000007d7: GT 000007d8: ISZERO 000007d9: PUSH2 0x07e0 000007dc: JUMPI 000007dd: DUP5 000007de: DUP6 000007df: REVERT 000007e0: JUMPDEST 000007e1: PUSH1 0x20 000007e3: DUP4 000007e4: ADD 000007e5: SWAP5 000007e6: POP 000007e7: DUP1 000007e8: SWAP4 000007e9: POP 000007ea: POP 000007eb: POP 000007ec: POP 000007ed: SWAP3 000007ee: POP 000007ef: SWAP3 000007f0: POP 000007f1: SWAP3 000007f2: JUMP 000007f3: JUMPDEST 000007f4: PUSH1 0x00 000007f6: DUP3 000007f7: MLOAD 000007f8: PUSH2 0x0805 000007fb: DUP2 000007fc: DUP5 000007fd: PUSH1 0x20 000007ff: DUP8 00000800: ADD 00000801: PUSH2 0x0842 00000804: JUMP 00000805: JUMPDEST 00000806: SWAP2 00000807: SWAP1 00000808: SWAP2 00000809: ADD 0000080a: SWAP3 0000080b: SWAP2 0000080c: POP 0000080d: POP 0000080e: JUMP 0000080f: JUMPDEST 00000810: PUSH1 0x20 00000812: DUP2 00000813: MSTORE 00000814: PUSH1 0x00 00000816: DUP3 00000817: MLOAD 00000818: DUP1 00000819: PUSH1 0x20 0000081b: DUP5 0000081c: ADD 0000081d: MSTORE 0000081e: PUSH2 0x082e 00000821: DUP2 00000822: PUSH1 0x40 00000824: DUP6 00000825: ADD 00000826: PUSH1 0x20 00000828: DUP8 00000829: ADD 0000082a: PUSH2 0x0842 0000082d: JUMP 0000082e: JUMPDEST 0000082f: PUSH1 0x1f 00000831: ADD 00000832: PUSH1 0x1f 00000834: NOT 00000835: AND 00000836: SWAP2 00000837: SWAP1 00000838: SWAP2 00000839: ADD 0000083a: PUSH1 0x40 0000083c: ADD 0000083d: SWAP3 0000083e: SWAP2 0000083f: POP 00000840: POP 00000841: JUMP 00000842: JUMPDEST 00000843: PUSH1 0x00 00000845: JUMPDEST 00000846: DUP4 00000847: DUP2 00000848: LT 00000849: ISZERO 0000084a: PUSH2 0x085d 0000084d: JUMPI 0000084e: DUP2 0000084f: DUP2 00000850: ADD 00000851: MLOAD 00000852: DUP4 00000853: DUP3 00000854: ADD 00000855: MSTORE 00000856: PUSH1 0x20 00000858: ADD 00000859: PUSH2 0x0845 0000085c: JUMP 0000085d: JUMPDEST 0000085e: DUP4 0000085f: DUP2 00000860: GT 00000861: ISZERO 00000862: PUSH2 0x043c 00000865: JUMPI 00000866: POP 00000867: POP 00000868: PUSH1 0x00 0000086a: SWAP2 0000086b: ADD 0000086c: MSTORE 0000086d: JUMP 0000086e: INVALID 0000086f: COINBASE 00000870: PUSH5 0x6472657373 00000876: GASPRICE 00000877: KECCAK256 00000878: PUSH13 0x6f772d6c6576656c2064656c65 00000886: PUSH8 0x6174652063616c6c 0000088f: KECCAK256 00000890: PUSH7 0x61696c6564a264 00000898: PUSH10 0x70667358221220e4fae5 000008a3: DUP5 000008a4: SWAP9 000008a5: BYTE 000008a6: DUP3 000008a7: PUSH13 0x661bc1d96a4769a99ec48d94a0 000008b5: PUSH26
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| critical | upgradeability | detector | Untrusted DELEGATECALL target reachable | 70 | no | no |
viewtrace_id: 0x18e1bad70039d909ebb03bd15cfb17680ed09f1035bef1e69d3416d84310c7cf
call_targets:
0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49
target_varies:
no
classification:
constant_target
validation_json{
"sink": "DELEGATECALL",
"errors": 0,
"status": "sink_reached",
"attempts": 2,
"trace_id": "0x18e1bad70039d909ebb03bd15cfb17680ed09f1035bef1e69d3416d84310c7cf",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xed38db26a3a7643f4ea274c3e6139eb3d3a13d49"
],
"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": "0xaaf10f42",
"selector": "0xaaf10f42",
"calldata_variants": [
"0xaaf10f42",
"0xaaf10f420000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xf851a440",
"selector": "0xf851a440",
"calldata_variants": [
"0xf851a440",
"0xf851a4400000000000000000000000000000000000000000000000000000000000000000"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 974,
"opcode": "DELEGATECALL",
"returndata_checked": null,
"value_expression_category": "n/a",
"target_expression_category": "computed"
},
{
"pc": 1348,
"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 | — |
viewevidence_json{
"notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
"delegatecall_count": 2
}
|