{
 "schema": "claus-shifts/controller-check-v1",
 "task": "5a743daa-b45c-418c-9741-c8ed3154329c",
 "target": "0x180eAE784dEe739FBab432B06f78bF9a98Aae334",
 "block": {
  "number": 26234212,
  "hash": "0x750385d5aecdc166bbb303343c57b2690aefb804384fa129819b6277d7dacf8c"
 },
 "runtimeKeccak256": "0x35a2813699a37cf6e2399d0522e1da15f4b37bf5fa43c7d624b823df9157d76f",
 "runtimeBytes": 6586,
 "functions": [
  {
   "selector": "0xdb2a4570",
   "name": "updateMetadata(string,string,string)",
   "name_basis": "keccak match (repo/verified ABI)",
   "access": "operator",
   "effect": "TOKEN.updateMetadata(name,symbol,uri) - rename token / change URI",
   "external_calls": [
    "TOKEN 0xdb2a4570"
   ]
  },
  {
   "selector": "0xd9cba399",
   "name": "acceptControl()",
   "name_basis": "keccak match",
   "access": "FOUNDER or operator",
   "effect": "requires TOKEN.pendingOwner()==this then TOKEN.acceptOwnership()",
   "external_calls": [
    "TOKEN.pendingOwner 0xe30c3978 (static)",
    "TOKEN.acceptOwnership 0x79ba5097"
   ]
  },
  {
   "selector": "0xb3ab15fb",
   "name": "setOperator(address)",
   "name_basis": "keccak match",
   "access": "FOUNDER",
   "effect": "slot0=new operator; emits OperatorChanged(address,address)",
   "external_calls": []
  },
  {
   "selector": "0x993c9ca9",
   "name": "returnControl()",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "FOUNDER",
   "effect": "TOKEN.transferOwnership(FOUNDER) (hardcoded recipient; founder then accepts on token, Ownable2Step)",
   "external_calls": [
    "TOKEN 0xf2fde38b"
   ]
  },
  {
   "selector": "0x47f543bc",
   "name": "setModule(address)",
   "name_basis": "keccak match",
   "access": "operator",
   "effect": "require module==compute (0xa25c) or approvedAdapter[module]; HOST.setModule(module)",
   "external_calls": [
    "HOST 0x47f543bc"
   ]
  },
  {
   "selector": "0xacf461f9",
   "name": "createAdapter(address)",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "anyone (permissionless)",
   "effect": "if adapterFor[p] exists return it; else require p!=compute, p!=this, !approvedAdapter[p]; CREATE ComputeProtectedProgram-variant(p, extcodehash(p), compute); approvedAdapter[adapter]=true; adapterFor[p]=adapter; emits AdapterCreated(address,address). Does NOT select it.",
   "external_calls": [
    "CREATE"
   ]
  },
  {
   "selector": "0x040dda0f",
   "name": "adapterFor(address)",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "view",
   "effect": "slot2 mapping read"
  },
  {
   "selector": "0x431a20ae",
   "name": "approvedAdapter(address)",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "view",
   "effect": "slot1 mapping read"
  },
  {
   "selector": "0x1a43c338",
   "name": "compute()",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "view",
   "effect": "returns 0xa25c\u2026768e"
  },
  {
   "selector": "0x570ca735",
   "name": "operator()",
   "access": "view",
   "effect": "slot0"
  },
  {
   "selector": "0xca58f2d3",
   "name": "FOUNDER()",
   "name_basis": "keccak match of guessed name (inferred)",
   "access": "view",
   "effect": "returns 0xBb14\u2026F1C5"
  },
  {
   "selector": "0x82bfefc8",
   "name": "TOKEN()",
   "access": "view"
  },
  {
   "selector": "0x49f289dc",
   "name": "HOST()",
   "access": "view"
  }
 ],
 "claims": [
  {
   "claim": "owns the CLAUS token",
   "verdict": "consistent",
   "evidence": "token.owner()==0x180e at block; pendingOwner 0"
  },
  {
   "claim": "selects hook trade programs through a fee-guarded factory",
   "verdict": "consistent (names inferred)",
   "evidence": "setModule only accepts compute program or adapters minted by its own createAdapter, whose code matches ComputeProtectedProgram (fixed 1.2%/0.1%); factory is permissionless to create but only operator selects"
  },
  {
   "claim": "cannot change the fixed 1.2% and 0.1% shares",
   "verdict": "consistent for the controller's own functions; NOT a permanent property",
   "evidence": "only selectable modules force 12000/1000; but FOUNDER can returnControl() then, as token owner, call HOST.setModule with any module, which can set any split"
  },
  {
   "claim": "cannot change their recipients",
   "verdict": "consistent",
   "evidence": "1.2% residual goes to ProjectRevenue 0x49A9 whose active=0xBb14 is immutable and pinned in hook; 0.1% goes to 0xa25c whose active=0xAB71 is immutable; controller has no recipient setter. (After returnControl, an arbitrary module could zero the compute bucket but cannot change ProjectRevenue recipient)"
  },
  {
   "claim": "cannot upgrade the token core",
   "verdict": "consistent",
   "evidence": "token proxy admin ProxyAdmin 0xfb4b\u2026 owner()==0; controller has no upgrade call"
  },
  {
   "claim": "cannot upgrade the hook core",
   "verdict": "consistent",
   "evidence": "hook proxy admin ProxyAdmin 0x1f22\u2026 owner()==0; controller makes no hook calls"
  },
  {
   "claim": "cannot freeze, blacklist, mint or confiscate holder tokens",
   "verdict": "consistent",
   "evidence": "controller only calls token.updateMetadata/acceptOwnership/transferOwnership; ProtectedToken owner powers are updateMetadata + ownership only; no mint/pause/blacklist; burn is self-only"
  }
 ],
 "keyRisks": [
  "operator (hot operating wallet) can select an adapter around ANY contract anyone deploys via createAdapter: inner program may set platform/burn/LP/NFT to 0 and module bucket up to 136000 pips -> total trade fee up to 14.9% (from 2.3%) with up to 13.6% to the inner program; 1.2% and 0.1% stay fixed",
  "FOUNDER can reclaim token ownership at any time (returnControl + token.acceptOwnership), no timelock, then has unrestricted HOST.setModule",
  "FOUNDER is hardcoded and cannot be rotated; operator rotation is single-step, immediate",
  "operator can change token name/symbol/URI"
 ],
 "relatedState": {
  "token.owner": "0x180e\u2026e334",
  "token.pendingOwner": "0x0",
  "token_proxy_admin": "0xfb4b9d2b\u20267a57 (ProxyAdmin, owner()=0x0)",
  "hook_proxy_admin": "0x1f22e4b0\u202629bc (ProxyAdmin, owner()=0x0)",
  "token_impl": "0x55d555bd\u202618a7 ProtectedToken",
  "hook_impl": "0xa62f9b59\u2026ce14 ProtectedHook",
  "host.activeModule": "0xa25c\u2026768e",
  "ProjectRevenue(0x49A9\u2026b9f3).active": "0xBb14 (immutable)",
  "hook.feeRecipient": "0xBb14",
  "ClausComputeFeeProgram.active": "0xAB71 (immutable)"
 },
 "roles": {
  "FOUNDER": {
   "value": "0xBb145cA83272c3806d4dDc75cA1D5514789cF1C5",
   "storage": "hardcoded PUSH20 constant (immutable forever)",
   "powers": [
    "setOperator",
    "returnControl",
    "acceptControl"
   ]
  },
  "operator": {
   "value": "0xAB716305E5A8854c0DD08397087dbDD56eA32073",
   "storage": "slot 0",
   "changeable_by": "FOUNDER only, single step, immediate, no timelock; cannot be 0, FOUNDER, controller, token or host",
   "powers": [
    "setModule",
    "updateMetadata",
    "acceptControl"
   ]
  },
  "anyone": {
   "powers": [
    "createAdapter",
    "all views"
   ]
  }
 },
 "adapter": {
  "embedded_init_offset": "0x992",
  "len": "0xff2",
  "match": "opcode diff vs reference/trade-programs ComputeProtectedProgram runtimeTemplate: 99.1% equal; only differences are COMPUTE constant 0x3dc1\u2026 -> immutable (set to 0xa25c by controller) and metadata hash; constructor takes 3 args",
  "enforces": "project pips forced to 12000, +1000 compute added to module bucket, sum<=149000 else defaults [12000,3000,1500,2000,3500,1000]; compute share sent to 0xa25c; remainder of module bucket to inner program; inner codehash pinned (proxy inner programs not frozen)"
 },
 "method": [
  "eth_getCode/eth_getStorageAt/eth_call at pinned block via ethereum-rpc.publicnode.com",
  "custom disassembler; manual dispatcher and control-flow reading",
  "selector names: keccak match against repo sources, verified ABIs of related contracts (Blockscout) and guessed names; openchain/4byte unreachable (proxy 403 / empty)",
  "eth_call simulations from random, 0xAB71, 0xBb14 (no state change)",
  "embedded child creation code extracted (offset 0x992, len 0xff2) and opcode-diffed against reference/trade-programs ComputeProtectedProgram runtimeTemplate (repo d09b900)",
  "verified sources (Blockscout) of ProtectedToken, ProtectedHook, TradeExtensionHost, ProxyAdmins, ClausComputeFeeProgram"
 ],
 "limits": [
  "no source; names marked inferred are keccak matches of guessed names, not confirmed",
  "constructor/init code not fully analysed (only runtime); operator initialised to 0xAB71 per state",
  "adapter equivalence is by opcode diff, not full compile-compare",
  "host/hook behaviour taken from Blockscout verified sources; not re-compiled",
  "the inner-program fee path analysis assumes verified sources are what is deployed"
 ]
}