Die Dapp

Die App im Repository ist cairn-app/: ein Next.js-16-Frontend (App Router) mit Tailwind v4, und wagmi und viem für die Wallet, lokal auf Port 3100 ausgeliefert. Sie hat am 2026-10-02 die frühere React + Vite-Dapp ersetzt. Sie trägt den neuen Namen des Projekts, Cairn.fun, unter dem der Protokoll-Token $CAIRN heißt; dieses Buch behält den Namen StockFun.

Die App läuft mit Demo-Daten, gekennzeichnet als „Illustrative“, bis ein Deployment konfiguriert ist, und nichts ist deployt. Diese Seite beschreibt sie in ihrem aktuellen Zustand.

Die Ansichten

Route Ansicht
/ Landingpage: der nächste Drop, das Laufband der Märkte, die öffentliche Liste der Drops, der Gebührenrechner, die Baskets, der Protokoll-Token, die FAQ
/markets Entdecken: Treasury-Puls, die Leiste des Protokoll-Tokens, Filter, Sortierung und Suche, die Markttabelle
/market/[slug] Marktdetail: Chart, Drop-Panel, Trades, Trade-Panel mit der Gebührenaufteilung vor dem Signieren, Fortschritt von Band 1, Contracts, die Position der Wallet
/launch Launch-Formular: Identität, Basket-Auswahl, Live-Vorschau, Checkliste zur Unumkehrbarkeit. Seit der achten Audit-Schleife bietet es nur die von der Chain gelesenen Baskets an und prüft den gewählten vor dem Senden erneut gegen die Chain
/claim Der Airdrop-Claim der Holder, Zeitfenster für Zeitfenster, und die Creator-Gebühren
/drops Jeder Drop, Zeitfenster für Zeitfenster
/docs Mechanismus, Gebühren, Baskets, Drops, der Protokoll-Token, Grenzen

Die Treasury Ratio, seit der Airdrop-Entscheidung obsolet, die die frühere Dapp am 2026-09-28 noch anzeigte, erscheint nicht in der App im Repository. Die Metrik, die sie ersetzt, ist noch zu entscheiden.

Die Claim-Ansicht

Seit dem 2026-10-05 listet /claim jedes Zeitfenster, das die verbundene Wallet claimen kann, Markt für Markt: das Ende des Zeitfensters, seine Aktien, die Beträge und ihren Wert in Dollar. Die Beträge kommen allein vom Airdrop-Contract (claimable), alle 60 Sekunden neu gelesen, solange die Seite offen ist, und nach jeder Transaktion der Wallet. Eine Aktie, die dem Airdrop-Contract nach einem Notfall-Transfer fehlt, wird als „awaiting settlement“ markiert und aus dem Claim herausgelassen.

Unter der Liste folgen eine Summe und „Claim all“, das claimMany in Batches von fünf Zeitfenstern sendet (zehn, bis das Glamsterdam-Upgrade von Ethereum am 2026-10-06 Sepolia erreichte, siehe unten), sowie claim mit den anderen Aktien für ein Zeitfenster, das eine Aktie in Erwartung der Bereinigung enthält. Jeder Aufruf wird zuerst simuliert: Ein Batch, der fehlschlagen würde, wird in seine Zeitfenster aufgeteilt und ein Zeitfenster in seine anderen Aktien, sodass ein Zeitfenster oder eine Aktie, die jetzt nicht ausgezahlt werden kann, übersprungen und benannt wird und nie den Rest versenkt. Eine Transaktion, deren Receipt nicht gelesen werden kann, behält ihren Hash und erscheint als gesendet, ihre Bestätigung noch nicht gelesen; nichts wird erneut gesendet, und die Seite verfolgt sie, bis sie selbst oder eine Transaktion an ihrer Stelle gemint wird: Seit der zehnten Audit-Schleife gilt eine Beschleunigung in der Wallet als der Claim selbst, wobei „View tx“ auf sie zeigt, während ein Abbruch oder jede andere Ersetzung sie als nicht erfolgt beendet, mit „View tx“ auf dem, was gemint wurde (unten). Das Ergebnis nennt, was ausgezahlt wurde, die zurückgestellten Aktien, die geschuldet bleiben, und die übersprungenen Zeitfenster, mit ihrem Grund.

Seit dem 2026-10-06:

  • Nur die Ablehnung durch die Wallet stoppt einen Lauf, und seit der zehnten Audit-Schleife auch ein Abbruch oder eine Ersetzung in der Wallet. Eine Transaktion, die fehlschlägt, wird gezählt („did not go through“), was sie abdeckte, bleibt aufgeführt, und die anderen Transaktionen gehen raus
  • Spielraum für eine Aktie, die noch unterwegs ist. Ein claimMany zahlt jede Aktie aus, die ein Zeitfenster aufführt, wenn er läuft, und einem Zeitfenster, das noch für Zustellungen offen ist, kann zwischen der Schätzung und der Aufnahme in einen Block eine weitere Aktie gutgeschrieben werden: Die App schlägt 400.000 Gas pro Aktie des Baskets auf, die das Zeitfenster noch nicht aufführt (100.000 bis zum Glamsterdam-Upgrade). Nicht verbrauchtes Gas wird nicht berechnet
  • Gas, bemessen für Glamsterdam. Sepolia hat das Glamsterdam-Upgrade von Ethereum am 2026-10-06 aktiviert, das einen neuen Storage-Slot etwa das Fünffache seines früheren Gases kosten lässt; das Mainnet hatte noch kein Datum. Jede Aktie, die ein Claim auszahlt, kann drei neue Slots schreiben, daher lässt die App 400.000 Gas pro Aktie, die noch unterwegs ist, und claimt fünf Zeitfenster pro Transaktion, wo zehn Zeitfenster mit fünf Aktien bis zu etwa 14 Millionen Gas brauchen könnten
  • Das eigene Gas jedes Schreibvorgangs. Unter dem Upgrade kostet ein Storage-Slot, der von null aus geschrieben wird, etwa 110.000 Gas, und ein Trade kann auf Schreibvorgänge treffen, die seine Schätzung nie gesehen hat: die Gebührenansammlungen des Hooks, die ein Claim kurz zuvor geleert hat (zwei dieser Claims kann jeder aufrufen), die Supply-Marke der nächsten Stunde, der eigene Eintrag des Traders, im selben Block bewegt. Seit der neunten Audit-Schleife gibt die App jedem Schreibvorgang seine Schätzung plus 50.000 Gas und einem Trade, geschätzt am neuesten Block, außerdem das Gas jedes solchen Schreibvorgangs, der noch geschehen kann, gelesen an genau diesem Block (112.000 pro Ansammlung, 150.000 für die Marke, 135.000 für den Eintrag; alle, wenn ein Lesen fehlschlägt). Ein Schreibvorgang, dessen Schätzung fehlschlägt, geht mit einem festen Limit raus, das aus seinem schwersten Fall bemessen ist, nie mit der eigenen Schätzung der Wallet, die keine Marge hat; ein Launch wird dann nicht gesendet, und die Seite sagt, man solle es erneut versuchen. Bis dahin bekam jeder Schreibvorgang 150.000 Gas über seiner Schätzung (35.000 vor dem Upgrade). Eine Wallet legt vor dem Signieren das Limit mal ihrer Gebühr zurück; berechnet wird nur das verbrauchte Gas
  • Eine beim letzten Claim nicht ausgezahlte Aktie. Eine Aktie, die ein Claim zurückgestellt hat, weil ihr Token den Transfer an diese Wallet abgelehnt hat (etwa ein Einfrieren durch den Emittenten), merkt sich der Browser; sie wird als „not paid at your last claim“ angezeigt und aus „Claim all“ herausgelassen. Jeder Claim versucht sie zuerst allein und nimmt sie wieder auf, sobald ihr Claim durchgehen würde; wenn sonst nichts fällig ist, lautet die Schaltfläche „Try the assets not paid again“
  • Ungeprüft, nie abgelehnt. Eine Simulation zählt nur, wenn der Node sagt, warum der Aufruf fehlschlagen würde. Ein Zeitfenster, dessen Prüfung auf einen RPC-Fehler stieß, bleibt als noch nicht geprüft aufgeführt, und wenn überhaupt keine Simulation geantwortet hat, wird nichts gesendet
  • Ungelesen ist nicht nichts. Ein Markt, dessen Zahlen nicht gelesen werden konnten, wird benannt und nie so angezeigt, als schulde er nichts: „Nothing to claim“ erscheint nur, wenn jeder Markt gelesen wurde, und der Creator-Bereich sagt, dass seine Märkte nicht gelesen werden konnten, statt „You haven't launched a market“

Die Creator-Gebühren werden auf derselben Seite geclaimt, Markt für Markt.

Zahlen nicht verfügbar

Seit dem 2026-10-05 zeigt eine Treasury, deren Vault auf seine eigenen Views nicht antwortet, etwa nach einem fehlerhaften Upgrade, „Figures unavailable“ statt ihrer Zahlen: in der Zeile und der Karte der Marktliste, im Banner des Protokoll-Tokens und auf der Marktseite. Ihre Aktien und ihr ETH werden weiterhin aufgeführt, und die Summe auf der Marktseite sagt, wie viele Treasuries sie auslässt. Die App erfährt es von der Lens, die jeden Vault in einem eigenen Aufruf liest: siehe Architektur.

Seit dem 2026-10-06 gehört das ETH, das der Hook und der Liquiditäts-Lock nach einer vom Vault abgelehnten Zahlung für einen Vault behalten, zu seiner Treasury, zu seinem Wert und zu den Summen: eine Zeile „ETH owed“, mit dem Hinweis, dass es noch nicht im Vault ist und in ihn übergeht, sobald der Vault es annimmt. Es wird auf dem Hook und dem Lock gelesen, bleibt also aktuell, auch während der Vault nicht antwortet. Ein Vault, der nicht antwortet und nie gelesen wurde, erhält die Rail, die die Bridge-Konfiguration des Protokolls nahelegt, und das Drop-Panel sagt das: Wo seine Aktien liegen, ist abgeleitet, und seine Bestände können unvollständig sein. Der Markt des Protokoll-Tokens bleibt mit den zuletzt gelesenen Werten auf dem Bildschirm, als veraltet markiert, wenn die Lens seine Treasury nicht lesen kann, statt als nicht gelauncht zu erscheinen.

Was die Marktseite zeigt

Seit dem 2026-10-06:

  • Ein recoverter Pool hat keinen Chart. Sobald der Endmodus des Locks die Liquidität eines Pools herausgenommen hat, kann jeder dessen Preis kostenlos bewegen. Die Seite zeigte für ihn bereits keinen Preis und keinen Handel; jetzt zeigt sie auch keine 24-Stunden-Veränderung und keinen Chart mehr und sagt, warum, und der Worker hört auf, seinen Preis abzutasten
  • Der Anteil eines Trades für die Aktien ist das, was die eigenen Tax-Posten dieses Trades an die Treasury gesendet haben, zu den Einstellungen, die er bezahlt hat, nie zu den heutigen; „—“, wenn er nicht bekannt ist
  • Die Marktkapitalisierung zählt das umlaufende Supply, die Gesamtmenge abzüglich dessen, was die Burn-Adresse hält, im Header wie im Chart; seit der siebten Audit-Schleife zeigt sie „—“, nie $0, wenn das Supply nicht gelesen werden konnte
  • Ein Saldo, der nicht gelesen werden konnte, ist nie null: Das Positions-Panel sagt, dass er nicht gelesen werden konnte, und das Trade-Panel zeigt den zuletzt gelesenen Saldo, markiert mit „last read“, ohne einen Verkauf darüber abzulehnen; die Simulation der Transaktion lehnt eine echte Überziehung ab
  • Der mit den zuletzt gelesenen Werten gehaltene Markt des Protokoll-Tokens sagt das. Solange die Lens seine Treasury nicht lesen kann, werden sein Preis und seine Marktkapitalisierung überall, wo sie erscheinen, mit „(last read)“ markiert, ohne 24-Stunden-Veränderung, und sein Chart zeigt „Last read“ statt „Now“. Der Worker zeichnet für ihn keinen Preis auf, bis die Lens wieder antwortet, sodass der Ausfall dem Chart keinen Punkt hinzufügt. Seine aktuelle Tax ist unbekannt: Die Seite zeigt keine Anti-Snipe-Markierung, und das Trade-Panel zeigt die geltende normale Tax, ohne Überschusszeile. Die eigenen Zahlen seines Tokens werden weiterhin auf dem Token gelesen, sodass „Burned by buyback“ auf der Landingpage aktuell bleibt; seine Marktkapitalisierung ist die zuletzt gelesene. Seit der siebten Audit-Schleife erscheint der Ausfall im Chart als Lücke, der zuletzt gelesene Preis mit seinem Alter datiert, und die Zahlen des Tokens, ob der Markt gelesen oder gehalten wird, nehmen die zuletzt gelesenen Werte an, wenn sie nicht antworten, nie Nullen oder einen leeren Namen; ein Contract des Protokolls, der nach einem kaputten Upgrade fehlschlägt, leert sie nicht mehr

Seit der siebten Audit-Schleife, am 2026-10-06:

  • Der Chart setzt jeden Punkt auf seine Zeit. Jede Preisprobe sitzt dort, wo ihre Zeit im Bereich liegt: 1H, 24H und 7D enden jetzt, und „All“ beginnt bei der ersten Probe, nie beim Alter des Marktes. Ein Punkt unter dem Mauszeiger sagt, wie alt er ist („3h 20m ago“), die Linie bricht ab, wo Proben fehlen (ein Ausfall, eine Nacht, in der niemand die Seite offen hatte), und im Ruhezustand zeigt der Chart den Preis des Marktes, „Now“, oder „Last read“ für einen Markt, der mit den zuletzt gelesenen Werten gehalten wird. Bis dahin waren die Punkte gleichmäßig verteilt und nach ihrer Position datiert, sodass der letzte vor einem Ausfall gelesene Preis als aktuell erschien
  • Das 24-Stunden-Volumen zeigt „—“, solange es nicht gezählt werden kann. Wenn die Lesevorgänge des Workers in den Trade-Logs weiter fehlschlagen, rückt sein Trade-Fenster nicht mehr vor; das Volumen, pro Markt und in den Summen, zeigt dann „—“ statt einer Zahl, die schrumpfen würde, als hätte der Handel aufgehört, und kommt mit dem ersten Lesen zurück, das aufholt

Seit der achten Audit-Schleife, am 2026-10-06:

  • Eine Wallet auf der Whitelist sieht die normale Tax. Während des Anti-Snipe-Fensters eines Marktes zahlt eine verbundene Wallet auf der Whitelist dieses Marktes die normale Tax über den StockFun-Router, über den das Trade-Panel handelt: Das Panel zeigt für sie jetzt keinen Anti-Snipe-Überschuss mehr und sagt in einem Hinweis, warum. Die Preisabfrage war bereits richtig; die Überschusszeile widersprach ihr. Solange die Whitelist oder die Wallet unbekannt ist, zeigt das Panel die Tax ohne die Ausnahmen
  • Warum eine Aktie keinen Preis hat. Auf Robinhood Chain hält das Oracle den Preis einer Aktie während einer Kapitalmaßnahme zurück, und den Preis jeder Aktie, solange der Sequencer ausgefallen oder gerade wieder da ist, eine Prüfung, die aus ist, bis Chainlink einen Uptime-Feed für die Chain veröffentlicht (siehe Die Robinhood-Rail). Wo der Wert einer Aktie aus diesem Grund fehlt, sagt die App das: „No price for NVDA right now: corporate action in progress“, oder der Sequencer von Robinhood Chain ausgefallen, in Erholung oder mit unbekanntem Status, unter der Basket-Tabelle des Drop-Panels und der Drop-Karte der Landingpage, und neben der Aktie auf der Claim-Seite. Die Karte der Landingpage zeigte eine solche Aktie mit $0.00; jetzt zeigt sie „—“
  • Das 24-Stunden-Volumen zählt jeden Block einmal. Ein Lesen des Workers, das ein Node beantwortet, der einige Blöcke hinter dem vorherigen liegt, lässt das Trade-Fenster nicht mehr dieselben Blöcke zweimal zählen. Für dieses eine Lesen können die neuesten Trades im Feed fehlen; das nächste Lesen stellt sie wieder her

Seit der neunten Audit-Schleife, am 2026-10-06:

  • Ein Topf, der eine Schätzung ist, sagt das. Wenn ein Teil einer Treasury nicht gelesen oder bepreist werden kann (eine Aktie, deren Preis das Oracle zurückhält, ein veralteter ETH/USD-Feed, ein Spiegel-Vault, der mit den zuletzt gelesenen Werten gehalten wird), zählt seine Zahl, was bepreist werden konnte, und trägt jetzt überall, wo sie erscheint, ein „+“: in den Zeilen und Karten der Marktliste, der Karte des Protokoll-Tokens, dem Treasury-Puls, der Landingpage, dem Drop-Panel und dem Anteil eines Holders. Die Marktliste sagt, dass ein solcher Topf nach dem sortiert wird, was bepreist werden konnte, und der Puls sagt, wie viele Treasuries er so gezählt hat. Bis dahin sagte nur das Drop-Panel „an estimate“
  • Eine Freigabe, die nicht gelesen werden konnte, ist nicht null. Ein Verkauf über den StockFun-Router braucht zuerst die Allowance des Routers. Ein fehlgeschlagenes Lesen davon zählte früher als keine: Ein Holder, der bereits freigegeben hatte, wurde gebeten, erneut freizugeben, mit zwei Signaturen, und ein zweiter Fehlschlag sendete eine Freigabe für nichts. Das Trade-Panel sagt jetzt, dass die Freigabe nicht gelesen werden konnte, bepreist nichts und sendet weder eine Freigabe noch einen Verkauf, bis es sie liest. Seit der zehnten Audit-Schleife liest der Verkauf direkt nach einer Freigabe die Allowance, wird bepreist und geprüft an einem Block, der nicht vor dem der Freigabe liegt (unten), sodass ein Node, der einen Block zurückliegt, nicht mehr null antworten kann

Seit der zehnten Audit-Schleife, am 2026-10-06:

  • Eine Transaktion, die die Wallet abbricht, wird nie als erledigt angezeigt. Eine Wallet kann eine ausstehende Transaktion abbrechen (ein Transfer von nichts an sich selbst mit derselben Nonce) oder beschleunigen (derselbe Aufruf mit einer höheren Gebühr). Die App liest jetzt, was an ihrer Stelle gemint wurde: Eine Beschleunigung gilt als die Aktion selbst, wobei „View tx“ auf sie zeigt; ein Abbruch oder jede andere Ersetzung beendet den Ablauf als nicht erledigt, mit „Cancelled in your wallet.“ oder „Replaced by another transaction in your wallet.“ und „View tx“ auf dem, was gemint wurde, und stoppt einen Claim-Lauf so, wie es die Ablehnung durch die Wallet tut. Bis dahin zeigte ein abgebrochener Trade „Done“, eine abgebrochene Freigabe galt als erteilt, ein abgebrochener Claim der Creator-Gebühren zeigte „Claimed“ und verbarg das ETH für die Sitzung, und ein abgebrochener Launch zeigte „$TICKER is live.“ mit der erfundenen Token-Adresse der Demo; eine Transaktion, die nach der üblichen Wartezeit von drei Minuten beschleunigt wurde, wurde nie bestätigt, und das Panel blieb gesperrt, bis die Seite neu geladen wurde
  • Verfolgt nach der Wartezeit. Sobald die übliche Wartezeit nach drei Minuten abgelaufen ist, verfolgt die App die Transaktion über ihre Nonce: Wenn der Zähler der gesendeten Transaktionen der Wallet über sie hinausgegangen ist und die Transaktion kein Receipt hat, sucht sie, was an dieser Nonce gemint wurde, nie in einem Block von vor dem Senden, und wendet dieselbe Regel an. Ein Abbruch oder eine Ersetzung wird immer nur an einer tatsächlich in einem Block gefundenen Transaktion abgelesen, nie an einem fehlenden Receipt
  • Ein Launch ist erst live, wenn die Chain es sagt. Der Launch liest die Erstellung des Marktes aus dem eigenen Event der Factory; ohne dieses geht er mit dem Link der Transaktion zum Formular zurück, und die Adresse der Demo erscheint nie außerhalb der Demo
  • Der Block Ihrer letzten Transaktion, eine Minute lang. 60 Sekunden lang, nachdem eine ihrer eigenen Transaktionen gemint wurde, prüft, schätzt und bepreist die App, was sie als Nächstes auf dieser Chain sendet, an einem Block, der nicht vor diesem liegt, und liest dort die Allowance eines Verkaufs. Ein lastverteilter Endpoint kann von einem Node antworten, der einen Block zurückliegt: Der Verkauf direkt nach seiner Freigabe wurde dort früher abgelehnt („Approve it first“), und ein zweiter Versuch konnte eine zweite Freigabe senden. Ein Node, der diesen Block nicht erreicht hat, gilt jetzt als verspätet und wird erneut gefragt; erreicht ihn binnen weniger Sekunden keiner, wird nichts gesendet. Bei einem Verkauf direkt nach seiner Freigabe sagt die Seite dann „Your approval went through, but no quote could be read from the pool, so the sale was not sent…“ (seine Preisabfrage ist der erste Lesevorgang dort); ein Schreibvorgang, dessen eigene Prüfung den Block nicht erreichen kann (eine Freigabe, ein Claim, ein Launch), sagt „This could not be checked against the block of your last transaction just now, so nothing was sent. Try again in a moment.“
  • Was bleibt. Ein falsches „Replaced“ bleibt in einem engen Fall möglich, wenn all dies zutrifft: Kein Node zeigte den Verkauf, sodass die App seine Nonce aus dem Zähler der Wallet erschloss; ein Node, der hinter den anderen lag, wenn auch nicht hinter dem vor dem Senden gelesenen Block, beantwortete den Zähler; eine andere Transaktion derselben Wallet, die dieser Node nicht gesehen hatte, nahm die erschlossene Nonce; und der Verkauf, über ein privates Relay gesendet, war nach den drei Minuten und einer Karenzzeit von etwa 36 Sekunden noch nicht gemint. Ein Abbruch wird nie als erledigt angezeigt, und nichts bleibt gesperrt

Der Launch

Das Launch-Formular bietet nur die Baskets an, die aus dem Register der Chain gelesen wurden, unter der eigenen Nummerierung des Registers: Vor dem ersten Lesen bietet es keinen an („Reading the baskets from the chain…“), und bevor die Contracts deployt sind, sagt es, dass der Launch öffnet, sobald sie live sind. Kurz vor dem Senden liest es von der Factory sowohl die Erstellungsgebühr als auch den gewählten Basket erneut, seinen Namen und seine Aktien mit ihren Gewichtungen, und verweigert das Senden, ohne etwas zu senden, wenn eines davon von dem abweicht, was es zeigt; die Meldung nennt den Basket, den die Chain unter dieser Nummer hält. Bis zur achten Audit-Schleife bot das Formular vor seinem ersten Lesen die konfigurierten Baskets mit ihren konfigurierten Nummern an, und ein Deployment, dessen Register seine Baskets anders nummeriert, hätte einen Markt auf einem anderen Basket als dem angezeigten launchen können. Das Formular zahlt nur die Erstellungsgebühr: Es hat keinen eigenen Kauf des Creators und nennt keine Anti-Snipe-Whitelist, was es sagt (die Factory akzeptiert beides bei einem direkten Aufruf: siehe Einen Markt launchen). Die Bestätigung nennt den beim Senden geprüften Basket.

Art Direction

Die Designregeln der App stehen in ihrer eigenen DESIGN.md: ein warmes helles Theme auf weißer Fläche, Terracotta für die Drops und die Schlüsselzahlen, Poppins für das Interface und Instrument Serif für große Finanzzahlen, tabellarische Ziffern in den Tabellen.

Woher die Werte kommen

Gebühren, Launch-Parameter, Supply und Zusammensetzung der Baskets werden nie in einer Komponente geschrieben: Sie stehen in der Konfiguration der App oder kommen von der Chain, und die Gebührenposten werden beim Start gegen die aus @stockfun/shared generierten Konstanten geprüft, das die Contracts spiegelt. Ein in eine Seite getippter Prozentsatz ist der Weg, auf dem ein Produkt am Ende ein Gebührenschema bewirbt, das die Contracts nicht implementieren. Seit dem 2026-10-05 sind die Zahlen Einstellungen des Owners: Das Shared-Paket hält ihre Standardwerte, und ein Live-Wert wird aus dem Contract gelesen, der ihn hält.

Der Zustand des Protokolls kommt von der Chain; es gibt keinen Indexer. Ein Worker, cairn-worker/, liest ihn einmal für alle offenen Seiten: einen Snapshot, dann einen WebSocket, der nur die Änderungen pusht. Fällt der Worker aus, liest die Seite die Chain selbst über einen öffentlichen RPC. Die eigenen Daten der Wallet, von ihren Salden bis zu dem, was sie claimen kann, liest der Browser. Seit der siebten Audit-Schleife liest der Worker nur Endpoints, die angeben, seine Chain zu bedienen: einer auf einer anderen Chain zählt als ausgefallen, sodass ein Backup im falschen Netzwerk nie alle Märkte verschwinden lassen kann. Seit der achten veröffentlicht er sein achtes Datenschema, das den Grund ergänzt, warum der Preis einer Aktie fehlt; eine App, die ein älteres Schema liest, funktioniert weiterhin, ohne diesen Grund. Seit der neunten Audit-Schleife behält der Watcher des Workers, was er über seine RPCs gelernt hat (welcher Endpoint seit wann fehlschlägt, wie lange er zurückweichen soll, welche Chain jeder bedient), über die Momente hinweg, in denen sein Cloudflare-Objekt zwischen zwei Lesevorgängen schläft, ohne je die Adresse eines Endpoints zu speichern: Ein Ausfall des primären RPC kostet eine Probe pro sich verdoppelnder Pause statt drei Anfragen bei jedem Lesen, und ein gesundes Lesen fragt nichts zweimal. Er zeichnet außerdem die eigene Blocknummer von Robinhood Chain auf, wo er früher den Block der Chain aufzeichnete, auf der Robinhood Chain abrechnet.

Das Copy-Audit

pnpm audit:copy scannt die Quellen von Backend, Keeper, Shared und Contracts. Es schlägt schon bei einem einzigen verbotenen Wort oder statisch prüfbaren visuellen Verbot fehl. Es wird bei Bedarf ausgeführt; es ist nicht Teil von pnpm build. Seit die frühere Dapp das Repository verlassen hat, scannt es kein Frontend: In der App ist das verbotene Vokabular eine Review-Regel, festgehalten in ihrer PRODUCT.md.

Es ist kein Stil-Linter: Das verbotene Vokabular ist eine rechtliche Vorgabe.