Key custody · asset-touch map · cross-system interaction · upgradability — 3-model security-audited
Antilles / Shyft — Custody & Security Design
The exact breakdown before wiring the deployed stack into more complex systems: which keys sign what & when, which contracts touch value, how everything interconnects, what's immutable vs repointable, and where the risks are. Ground-truthed from source; reviewed by Grok + Gemini (+ Codex deep audit).
1 · Custody tiers — who holds the keys, when they're used
Operator directive: the Shyft threshold-2 keys are break-glass / emergency only, used rarely — routine work runs on automated keys. (Resolved by a small anchor set: threshold-2 onboards a few anchors once; anchors + auto-runner attest agents routinely.)
COLD · break-glass · multisig+timelockWARM · anchor operatorsHOT · automated · KMS/HSM + caps
| Key / role | Tier | Where held | When used | Signs for |
| Shyft Administrable threshold-2 (TAM/TAS/SCG/TCM) | COLD | Multisig (2-of-3/3-of-5) + timelock | RARE — onboard the few Trust Anchors, channel setup, emergency | onboard/verify anchor, channel admin, core wiring |
| Contract owners (FeeRouter, Resolver, ReputationEngine, ERC8004Bridge…) | COLD | Same multisig + timelock | RARE — config, repoint, pause, set fees | setCitationFee, setPaymentReceiver, pause, repoint |
| PageRankOracle multisig (score submitter) | COLD→multisig | Multisig (NOT a single hot key — panel fix) | Periodic score submission | submitScores, setReputationEngine, pause |
| Trust-Anchor attesting keys | WARM | Anchor operators (HSM-backed) | Routine — attest agent identities | setAttestation (as the anchor) |
| Auto-runner aux-signer (MCH machine-consent) | HOT | KMS/HSM · least-priv · rotated · + daily caps + monitoring | Routine — per agent onboarding consent | machine-consent signature (bounded: registered agents only) |
| batchAnchor (batch citations) | HOT | KMS/HSM · + rate-limit + monitoring | Routine — batch citation recording | batchRecordCitations |
| Deployer seed | COLD | Testnet=disposable; mainnet=fresh HW/multisig | Deploy / migrate only | contract creation |
2 · Asset-touch map — only 4 contracts touch value
Your hypothesis confirmed: the vast majority hold data/state, not assets. Focus custody + audit rigor on the four that move value.
◆ TOUCHES / HOLDS VALUE○ data & logic only
| ◆ Asset-touching (rigor here) | What value | ○ Data/logic only (no value) |
| FeeRouter | holds + splits fees {treasury/burn/receiver} | TrustAnchorManager TrustAnchorStorage ShyftCacheGraph MachineConsentHelper TrustChannelManager EAS SchemaRegistry ReputationEngine PageRankOracle CitationCounters Erc8004Registry ERC8004Bridge DomainRegistry DomainFactory — these store identity/route/score/agent state; they never custody funds. |
| PaymentModule | receives attestation fee → receiver |
| RMTToken | the ERC-20 itself (balances) |
| ShyftGatedResolver | RMT citation-fee transfer (attester→toBot) |
3 · Cross-system interaction — what calls what, where keys gate
blue = COLD-key gate · orange = HOT/automated-key gate. The four value/data flows:
① Identity attestation
[threshold-2] TrustAnchorManager → onboard/verify Anchor · [anchor key + aux-signer] Anchor → TrustAnchorStorage.setAttestation(agent) ⇢ MachineConsentHelper(consent) ⇢ ShyftCacheGraph.reconstruct → route live
② Citation → reputation
[attester / batchAnchor] ShyftGatedResolver.attest ⇢ gates: verified-TA + channel route ⇢ CitationCounters.record · [oracle multisig] off-chain PageRank → PageRankOracle.submitScores → ReputationEngine (tier-capped score)
③ Fee / value value
setAttestation ⇢ PaymentModule (mode=BASE/USDT) → FeeRouter → split {treasury / burn 0x…dEaD / receiver} · citation ⇢ Resolver moves RMTToken attester→toBot
④ Agent identity
Erc8004Registry (agent card) ⇄ ERC8004Bridge ⇄ ReputationEngine · DomainRegistry/Factory (namespaces)
4 · Upgradability — none upgradable; pause + repoint are the levers
No proxy/UUPS anywhere, no selfdestruct → bytecode is immutable (deliberate, no upgrade-rug). "Fix/remove" = pause, repoint, or redeploy+rewire.
| Contract | Upgradable? | Pause? | Repointable? | Incident response |
| ReputationEngine | no (immutable) | yes — Pausable | setPageRankOracle | pause → fix → repoint oracle |
| PageRankOracle | no | yes (multisig) | setReputationEngine | pause submissions; redeploy + repoint |
| ERC8004Bridge | no | yes | partial | pause; redeploy |
| ShyftGatedResolver | no | no pause | setCitationCounters/Fee/batchAnchor — but reputationEngine is SET-ONCE | setCitationFee=0; ⚠ brick-risk: redeploy resolver if RE must change |
| FeeRouter | no | no pause (cut) | via PaymentModule receiver | PaymentMode=NONE (stop source) + repoint receiver away |
| PaymentModule | no | mode=NONE = off | setPaymentReceiver/Mode | mode=NONE disables fees instantly |
| Shyft TAM/TAS/SCG/TCM | no | no | cross-wiring setters | repoint (not delete); threshold-2 gated |
5 · Panel-found risks → fixes (before complex wiring)
HIGHOracle score-submitter as a single hot key — a compromised submitter profitably inflates scores once a consumer exists. Fix: keep it on the multisig (already onlyMultisig); never a lone hot key. — Grok b4f9595a + Gemini 5da30ea8
HIGHFeeRouter has no pause + no native-asset rescue — it holds value with no off-switch. Fix: add Pausable + emergency-halt + native rescue (new FeeRouter version), or rely on PaymentMode=NONE + repoint-receiver as the interim stop. — Grok + Gemini
HIGHResolver reputationEngine is SET-ONCE → brick risk — if ReputationEngine is paused/compromised, the asset-touching resolver is permanently stuck. Fix: a timelocked repoint path on the resolver, or guarantee the RE is itself non-brickable (don't pause it without a successor wired). — Gemini (Codex adjudicating)
MEDaux-signer + batchAnchor hot single-keys — no caps/monitoring on consent + citation-fee paths. Fix: daily on-chain limits + off-chain anomaly monitoring + rotation.
GATEBreak-glass only holds if onboard/verify-anchor isn't per-agent — Fix (design): small anchor set — threshold-2 onboards a few anchors (rare); anchors + auto-runner attest agents routinely, so threshold-2 stays cold.
New contracts to build inherit the model: MCH forwarder (holds consent-power → Ownable2Step + Pausable + scoped aux-signers), attestor-staking (holds staked value → Pausable + timelocked params + clear withdraw path), escrow/holdback (holds value → Pausable + dispute/timeout path). All Ownable2Step + Pausable + explicit repoint/disable — and they EXPAND the asset-touching set, so each gets full audit + red-team before wiring.