Architektur

Das Protokoll lebt auf zwei Chains. Ethereum trägt das Launchpad, die Pools und die Vaults; Robinhood Chain trägt die tokenisierten Aktien.

graph TD subgraph ETH[Ethereum] F[StockFunFactory] -->|deployt| TK[StockFunToken] F -->|deployt| V[TreasuryVault] F --> LL[LiquidityLock] TK -->|jeder Transfer| HR[HoldingRecorder] LL -->|zwei gesperrte Positionen| PM[Uniswap v4 PoolManager] PM --> H[StockFunHook] H -->|2 %| V H -->|2 %| CR[Creator] H -->|0,5 %| TW[Team-Wallet] H -->|0,5 %| BB[BuybackBurner] BB -->|Kauf + Burn| SF[$STOCKFUN] V -->|ETH → USDC → USDG| BH[BridgeHub] V -->|sendToAirdrop, lokale Rail| AD[AirdropDistributor] AD -.liest.-> HR AD -->|Claims, pro rata| HO[Token-Holder] L[StockFunLens] -.liest.-> F O[TreasuryOracle] -.begrenzt.-> V end subgraph RH[Robinhood Chain] RH2[RemoteHub] --> MV[Spiegel-Vault pro Markt] MV -->|Sekundär-Pools| ST[Stock Tokens] end BH -->|LayerZero, USDG-OFT| RH2 ST -->|sendToAirdrop, Aktien-OFTs| AD K[Offchain-Keeper] -.löst aus.-> V K -.löst aus.-> BH

Die Contracts

Diese Tabelle beschreibt das Protokoll wie beschlossen. Der Launch-Teil ist seit dem 2026-09-28 im Code und die Airdrop-Distribution seit dem 2026-10-04, nicht deployt; die LayerZero-Adapter der Aktien sind nicht im Repository. Router und Adapter außer dem offiziellen Swap-Router sind nicht aufgeführt: UniswapV4StockRouter auf Ethereum, RobinhoodStockRouter auf Robinhood Chain und der UsdgOftAdapter. Siehe Status. Seit dem 2026-10-02 ist jeder Contract darin upgradebar, außer den Tokens, dem Liquiditäts-Lock und den Deployern: siehe unten. Die Prozentsätze im Diagramm sind die Standardeinstellungen der Tax.

Contract Rolle Kardinalität
StockFunFactory Erstellt Märkte, erhebt die Erstellungsgebühr, führt das Register und die Einstellungen des Owners für neue Märkte und für die Vaults; die Upgrade-Autorität jedes Ethereum-Moduls Einer
MarketDeployer · VaultDeployer Umgehen EIP-170, indem sie den Creation Code des Tokens und den des Vault-Proxys tragen; halten keinen Zustand, werden über die Factory ersetzt statt upgegradet Je einer
StockFunToken Einfacher ERC-20, nicht upgradebar, ohne Mint und ohne Burn; keine eigene Logik außer einem einzigen Setter, setRecorder, und seinen Rescues, für den Protokoll-Owner; meldet jede Saldoänderung an den Bestandsaufzeichner Einer pro Markt
HoldingRecorder Zeichnet für jeden Token die Bestände jeder Adresse im Zeitverlauf auf, ebenso die Supply außerhalb des PoolManager von Uniswap; ein Transfer schlägt fehl, wenn seine Aufzeichnung fehlschlägt, die einzige bewusste Ausnahme von der Isolationsregel unten Einer
TreasuryVault Hält ETH, USDC, dann Aktien; Konvertierung, jedes Kauf-Leg für sich, Übergabe seiner Aktien an den Airdrop auf der lokalen Rail (sendToAirdrop), jede Aktie für sich, und sofortige Notfall-Recovery Ein Proxy pro Markt
LiquidityLock Erstellt den Pool und zahlt beide Positionen ein, gesperrt, und hält die LP-Gebühr und das Tick-Spacing jedes Pools fest; behält einen abgelehnten Anteil einer Gebühreneinsammlung für seinen Empfänger; nicht upgradebar; sein einziger Ausgang ist der Endmodus, 30 Tage nach seiner Ankündigung Einer
StockFunHook Erhebt die Gebühr bei jedem Swap, wendet das Anti-Snipe an, führt die Tax-Einstellungen und die Whitelist jedes Pools, verweigert Liquidität von allen außer dem Lock, hält die Guthaben von Creator, Team und Buyback, bis sie geclaimt werden, und das, was einem Vault geschuldet ist, der seinen Anteil abgelehnt hat Einer
StockFunSwapRouter Der offizielle Router für Trades, der einzige, über den eine Adresse auf der Whitelist vom Anti-Snipe ausgenommen ist Einer, durch den Owner ersetzbar
StockFunLens Nur lesend; aggregiert den Zustand eines Marktes für die Dapp und liest dabei jeden Vault für sich; seit dem 2026-10-06 enthält ihre Seite außerdem die Rail des Vaults, seinen Pause-Status und das USDC, das er bisher über die Bridge gesendet hat, den Sperrstatus des Pools, den Bestandsaufzeichner des Tokens und das, was der Hook und der Lock dem Vault schulden Einer
TreasuryOracle Chainlink-Feeds, einmal geschrieben; ihre Heartbeats sind Einstellungen und, seit dem 2026-10-06, seine zwei Schutzmechanismen auf Robinhood Chain: die Sequencer-Prüfung, aus, bis Chainlink einen Uptime-Feed für diese Chain veröffentlicht, und die Oracle-Pause jeder Aktie, die den Preis dieser Aktie während einer Kapitalmaßnahme zurückhält Einer pro Chain
BuybackBurner Kauft $STOCKFUN und schickt ihn in den Burn. Solange der $STOCKFUN-Pool gesperrt ist, existiert kein anderer Pfad Einer
BridgeHub · RemoteHub · RemoteTreasuryVault Die Cross-Chain-Rail; der Remote-Hub ist die Upgrade-Autorität auf Robinhood Chain und benennt die Airdrop-Route und den Adapter jeder Aktie; der Spiegel-Vault sendet seine Aktien an den Airdrop (sendToAirdrop) Einer, einer, ein Proxy pro Markt
StockFunProtocolToken $STOCKFUN, wie ein Markt-Token nicht upgradebar; seine gesamte Supply geht in seine gesperrte Position Einer
AirdropDistributor Verteilt auf Ethereum die Aktien, die jede Treasury gekauft hat, an die Holder ihres Tokens, in täglichen Zyklen; schreibt nur den eigenen Vaults des Marktes gut; jeder Holder claimt, und ein Claim zahlt jede Aktie aus, die er kann; an die Factory gebunden, die ihn benennt Einer

Proxys und Upgrades

Seit dem 2026-10-02 ist jedes Modul ein ERC-1967-Proxy vor einer Implementierung, per UUPS upgegradet. Der Proxy hält die Adresse und den Zustand; die Implementierung hält den Code, und ein Upgrade ersetzt sie. Eine Implementierung kann nie initialisiert werden: Jeder Proxy wird in seinem eigenen Konstruktor initialisiert.

Jedes Modul fragt einen einzigen Contract, wer es upgraden darf, seine Upgrade-Autorität, die in seiner Implementierung festgelegt ist: die Factory auf Ethereum, die mit ihrem Owner antwortet, und den Remote-Hub auf Robinhood Chain, der mit seinem Notfall-Admin antwortet, dem Ethereum-Owner, wie ihn der letzte Bridge-Batch übermittelt hat. Eine Übertragung der Ownership der Factory verschiebt daher die Upgrade-Befugnis jedes Ethereum-Moduls auf einen Schlag, und die der Module auf Robinhood Chain mit dem nächsten Batch. Ein Upgrade wird abgelehnt, wenn die neue Implementierung eine andere Autorität benennt; die des Hooks und die des Bestandsaufzeichners müssen außerdem denselben PoolManager behalten.

Nicht upgradebar sind die Tokens, der Liquiditäts-Lock und, auf Robinhood Chain, der Deployer der Spiegel-Vaults, aus dessen Adresse die Adresse jedes Spiegel-Vaults abgeleitet wird. MarketDeployer und VaultDeployer halten keinen Zustand: Die Factory ersetzt sie (setDeployers), statt sie upzugraden.

Der Storage wird nur am Ende erweitert, nie umgeordnet: Das Layout jedes Moduls ist in contracts/storage-layouts/ festgehalten, und contracts/script/check-storage-layouts.sh vergleicht es vor jedem Upgrade. Seit dem 2026-10-05 vergleicht es jede Ebene jedes Structs, Größen eingeschlossen, und lehnt jede Änderung an einem Struct ab, das Element eines Storage-Arrays ist: Nur ein Struct, das Wert eines Mappings ist, oder die letzte Zustandsvariable darf wachsen, an ihrem Ende.

Ein Implementierungs-Contract wird nie direkt verwendet, aber auch für das, was versehentlich an seine eigene Adresse gesendet wird, gibt es einen Hebel. Die meisten Implementierungen lesen ihre Autorität aus einer Immutable, also holt der Protokoll-Owner es heraus; die der Factory und des Remote-Hubs halten ihren Admin im Storage des Proxys, daher ist auf ihren Implementierungen der Hebel die Adresse, die sie deployt hat.

Wer upgraden kann, und wie schnell: siehe Vertrauensmodell.

Der Airdrop-Contract

Seit dem 2026-10-04 verteilt AirdropDistributor die Aktien jeder Treasury auf Ethereum. Er ist ein upgradebares Modul wie die anderen, ein Proxy, dessen Upgrade-Autorität die Factory ist. Die Factory benennt ihn (setAirdropDistributor), und die Vaults lesen ihn live; ein ersetzter Distributor behält jeden Zyklus dort claimbar, wo er ist. Er liest die Bestände aus dem Bestandsaufzeichner, und seine Regeln stehen in Der Airdrop.

Zwei Wege führen zu ihm, und nichts anderes schreibt einem Zyklus etwas gut:

  • Die Bridge-Rail. sendToAirdrop des Spiegel-Vaults sendet jede gelistete Aktie über den LayerZero-Adapter dieser Aktie, den der Remote-Hub benennt (setStockAdapter), an den Distributor, den der Remote-Hub benennt (setAirdrop), mit der Kennung des Marktes als Payload. Auf Ethereum mintet das OFT der Aktie die gewrappte Aktie an den Distributor, und der Endpoint von LayerZero ruft ihn auf. Er schreibt die Zustellung nur gut, wenn sie von einem Aktien-OFT kommt, das der Owner registriert hat, von Robinhood Chain, gesendet vom Spiegel-Vault, den der Bridge-Hub für diesen Markt ableitet.
  • Die lokale Rail. sendToAirdrop des Vaults auf Ethereum erteilt Freigaben über die exakten Beträge, der Distributor zieht sie ein, nur vom eigenen Vault des Marktes, und schreibt gut, was er erhalten hat; die Freigaben werden wieder geschlossen. Ein Vault, der mit dem Bridge-Hub verdrahtet ist, verweigert diesen Aufruf.

Der Keeper löst beide aus und entscheidet nur, wann; auf der Bridge-Rail seit dem 2026-10-06 auch das Gas, das jede Zustellung auf Ethereum erhält, das der Remote-Hub innerhalb der Grenzen hält, die der Owner von StockFun dort festlegt.

Strukturelle Eigenschaften

Der Hook ist ein Singleton. Ein einziger Contract bedient jeden Pool, was das Mining einer Adresse pro Markt erspart — die Adresse eines v4-Hooks codiert seine Berechtigungen in ihren niederwertigen Bits, und eine zu finden kostet Rechenleistung. Seit dem 2026-10-02 ist er ein Proxy, dessen Adresse alle 14 v4-Berechtigungen trägt: Ein Upgrade behält diese Adresse, und eine spätere Implementierung kann jeden Callback nutzen.

Liquidität ist kein NFT. Sie wird direkt im PoolManager gehalten, mit der Adresse des Locks als Schlüssel. Es gibt keine Position zu übertragen, kein approve zu widerrufen, keine tokenId zu verlieren. Die einzigen Liquiditätsoperationen, die der Contract ausführen kann, sind ein modifyLiquidity mit einem Delta von exakt null, um Gebühren einzusammeln, und, über den Endmodus, das Entfernen jeder Position eines Pools, 30 Tage nachdem das Ende angekündigt wurde.

Nur der Lock fügt Liquidität hinzu. Seit dem 2026-10-01 verweigert der Hook jede andere Position auf einem StockFun-Pool, sodass jeder Trade ein Swap gegen die gesperrten Positionen ist und die Tax zahlt.

Vaults haben keine Abhebung. Keine Funktion erlaubt es irgendwem, die Assets eines Vaults an eine Adresse seiner Wahl zu senden. Die zwei Ausgänge sind der Airdrop, dessen einziges Ziel der Airdrop-Contract ist, den das Protokoll benennt und der die Holder des Tokens pro rata nach einer Regel auszahlt, die niemand wählt, und der Notfallmodus, durch den der Owner von StockFun ein Asset sofort an eine beliebige Adresse bewegt. Das sind die Regeln der aktuellen Implementierung: Der Owner von StockFun kann einen Vault upgraden, mit sofortiger Wirkung.

Die Grenzen sind Einstellungen, die Feeds nicht. Die Preisgrenzen der Vaults, standardmäßig 50 und 200 Basispunkte, sind Einstellungen des Owners von StockFun, die jeder Vault live liest; der Keeper kann sie nur verschärfen. Das Feed-Register schreibt jeden Feed einmal; die Heartbeats der Feeds sind Einstellungen, und seit dem 2026-10-06 auch seine zwei Schutzmechanismen, die einen Preis nur zurückhalten, nie ändern können: die Sequencer-Prüfung (auf Robinhood Chain aus, bis Chainlink einen Uptime-Feed dafür veröffentlicht) und die Oracle-Pause jeder Aktie (an für jede Aktie auf Robinhood Chain; siehe Die Robinhood-Rail). Der Notfallmodus berührt keines von beiden: Er bewegt Assets, er ändert keine Ausführungsregeln. Das Register kann, wie die Vaults, vom Owner von StockFun upgegradet werden.

Isolation und Hebel

Am 2026-10-05 hat der Gründer eine Designregel festgelegt: Wenn etwas eine Funktion fehlschlagen lässt, dürfen die anderen Funktionen nicht dafür zahlen; alles muss weiterlaufen können, und alles muss einen Hebel haben, um verlorene Gelder zurückzuholen und die Korrektur aufzunehmen. Die vierte Audit-Schleife dieses Tages hat sie in den Code gebracht, und seitdem zählen die Audit-Schleifen jeden Verstoß gegen ihre beiden Teile als Defekt.

Isolation. Ein Fehler in einer Funktion, einem Markt, einer Aktie, einem Zyklus, einem Eintrag oder bei einem Empfänger blockiert nie die anderen: Das Element wird übersprungen, als geschuldet behalten oder zurückgestellt, mit einem Event, und der Rest läuft weiter.

  • Ein Bridge-Batch lässt einen Markt aus, dessen Vault sein Cash nicht freigeben kann (MarketSkipped), und die anderen gehen hinüber. Eine Zustellung, die der Cash-Token einem Spiegel-Vault verweigert, bleibt auf dem Remote-Hub, diesem Markt geschuldet (DeliveryRefused), und die anderen Märkte werden ausgezahlt
  • Ein Kauf führt das Leg jeder Aktie für sich aus (LegFailed), und eine Sendung an den Airdrop jede Aktie für sich (AirdropSendFailed)
  • Ein Claim zahlt jede Aktie aus, die er kann, und stellt die anderen zurück (ClaimDeferred)
  • Ein Vault, der ETH ablehnt, legt den Handel seines Marktes nicht mehr still: Der Hook behält, was er nicht auszahlen konnte, als Schuld gegenüber diesem Vault (treasuryOwed), und der Lock behält einen abgelehnten Anteil einer Gebühreneinsammlung für seinen Empfänger (vaultOwed, creatorOwed). Jeder zahlt sie aus, sobald der Empfänger wieder ETH annimmt (payTreasury, payOwed), und der Keeper tut es in jedem Zyklus
  • Die Lens liest jeden Vault in einem eigenen Aufruf, sodass ein Vault, der nicht antworten kann, die anderen lesbar lässt (vaultReadable). Seit dem 2026-10-06 enthält dieser Aufruf außerdem die Rail des Vaults, seinen Pause-Status und das USDC, das er über die Bridge gesendet hat, und die Seite enthält, was der Hook und der Lock dem Vault schulden: Der Datendienst der App liest pro Markt nichts anderes, sodass ein Vault, der sein gesamtes Gas verbraucht, nur seine eigenen Zahlen fehlschlagen lässt. Seit der siebten Audit-Schleife liest dieser Dienst außerdem jedes upgradebare Modul (den Hook, das Oracle, den Airdrop-Contract, die beiden Bridge-Hubs) und den Protokoll-Token in einer eigenen Gruppe, sodass ein Modul, das nach einem kaputten Upgrade sein gesamtes Gas verbraucht, nur seine eigenen Zahlen fehlschlagen lässt

Hebel. Jeder Contract, der ETH oder Tokens halten kann, auch nur vorübergehend oder versehentlich, hat einen Hebel, um herauszuholen, was feststeckt, und jedes Modul kann eine Korrektur aufnehmen: ein Upgrade oder einen Setter, der das Modul austauscht.

  • Die Module, die zwischen Transaktionen nichts von irgendwem behalten — die Factory, die Lens, die Oracles, der Bestandsaufzeichner, die Aktien-Router, der offizielle Swap-Router und die Bridge-Adapter —, haben das rescue(asset, amount, to) des Protokoll-Owners
  • Die Module, die eigene Bücher führen — die Vaults, die beiden Hubs und der Airdrop-Contract —, haben den Notfallmodus
  • Das rescue des Hooks nimmt nur, was versehentlich an ihn gesendet wurde, nie das, was er schuldet. Das des Locks nimmt nie die Anteile, die er behält, und auch nicht die Positionen, die nur der Endmodus erreicht. Das des BuybackBurner nimmt sein ETH erst, wenn kein Burn es mehr ausgeben könnte. Die Tokens, die nicht upgradebar sind, können herausholen, was an ihre eigene Adresse gesendet wurde
  • Ohne Hebel, bewusst: die beiden Deployer auf Ethereum und der Deployer der Spiegel-Vaults, die keinen Zustand halten, kein ETH annehmen und keinen Owner haben

Details in Notfallmodus.

Die einzige bewusste Ausnahme. Die Meldung eines Tokens an seinen Bestandsaufzeichner bleibt blockierend: Schlägt die Meldung fehl, schlägt der Transfer fehl. Eine Meldung, die fehlschlagen dürfte, ließe einen Holder ihr bei seinem eigenen Transfer das Gas entziehen, sodass die Aufzeichnung die Bewegung überspringt und sein Airdrop-Anteil wächst. Der Hebel wirkt sofort, je eine Transaktion: setRecorder(0) auf dem Token, das seine Aufzeichnung stoppt, oder ein Upgrade des Bestandsaufzeichners an derselben Adresse. Siehe Der Airdrop.

Offchain-Pakete

Paket Rolle
shared/ Generierte ABIs, Protokollkonstanten, Formatierung. Eine einzige Quelle, die von allem anderen geteilt wird
backend/ Preisservice. Isoliert die einzige externe Abhängigkeit der Dapp
keeper/ Konvertierung, Bridge-Batches, Remote-Routing, Überwachung der Zustellungen und, seit dem 2026-10-05, der Airdrop-Schritt, die Auszahlung dessen, was der Hook und der Lock für einen Empfänger behalten, und die Einsammlung der LP-Gebühren
cairn-app/ Die App, ein Next.js-Frontend, neben projet/ seit dem 2026-10-02, als sie die React + Vite-Dapp ersetzt hat: siehe Die Dapp
cairn-worker/ Die Datenschicht der App am Edge: liest das Protokoll einmal für alle offenen Seiten und pusht die Änderungen