Architektur
Das Protokoll lebt auf zwei Chains. Ethereum trägt das Launchpad, die Pools und die Vaults; Robinhood Chain trägt die tokenisierten Aktien.
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.
sendToAirdropdes 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.
sendToAirdropdes 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
rescuedes 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 desBuybackBurnernimmt 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 |