Der Keeper

Ein Offchain-Worker, der einmal alle 24 Stunden die Konvertierung jeder Treasury auslöst und danach ihren Airdrop. Er entscheidet nichts. Seine Schleife macht standardmäßig alle fünf Minuten einen Durchlauf, und seit dem 2026-10-06 konvertiert er das ETH eines Vaults einmal pro Airdrop-Zeitfenster, bei seinem ersten Durchlauf nach dem Schließen des Zeitfensters: siehe „Der Konvertierungsrhythmus“ unten. Sein Airdrop-Schritt ist seit dem 2026-10-05 geschrieben: siehe unten.

Was er tut

  • Erkennt einmal alle 24 Stunden, nachdem das Zeitfenster geschlossen hat, standardmäßig um 13:00 UTC, das ganze Jahr über vor der Eröffnung der US-Börse, die Vaults, die mindestens die Konvertierungsschwelle halten, standardmäßig 0,1 ETH, bei seinem ersten Durchlauf nach dem Schließen; ein Vault darunter wartet dann auf das nächste Zeitfenster, auch wenn Trades ihn später am Tag über die Schwelle bringen. Die Käufe des Zyklus laufen während der folgenden Handelszeit, und seine Sendungen standardmäßig, sobald diese Handelszeit vorbei ist. Cash, das ein Vault noch aus einem früheren Zyklus hält, USDC oder USDG, geht weiter, ob die Schwelle erreicht ist oder nicht: seit der sechsten Audit-Schleife, am 2026-10-06, das USDC eines Vaults einmal nach jeder seiner ETH-Konvertierungen und sonst höchstens einmal pro Zeitfenster, das USDG eines Spiegel-Vaults bei jedem Durchlauf (siehe „Der Konvertierungsrhythmus“)
  • Schlägt Swap-Routen vor und berechnet Mindestbeträge anhand einer aktuellen Preisabfrage; seit dem 2026-10-05 wenden die Vaults diese Mindestbeträge auf das an, was tatsächlich ankommt. Seit dem 2026-10-06 wird jeder Vault auf Ethereum auf seinem eigenen Router bepreist, dem, mit dem er erstellt wurde
  • Bemisst jeden Schritt so, dass der Handelsplatz ihn innerhalb der Grenze des Vaults ausführen kann (siehe unten)
  • Ruft die Konvertierung auf, den Bridge-Batch, dann den Kauf auf der Remote-Chain; seit dem 2026-10-05 ist er der Einzige, der den Bridge-Batch senden kann (bridgeReady). Auf der kanonischen Rail fragt er die Gebühr des Batches beim Doppelten der letzten Basisgebühr ab (quoteBridgeAt), und der Überschuss geht an ihn zurück. Seit der neunten Audit-Schleife greift er nur dann auf die Preisabfrage eines älteren Hubs zurück, wenn der Hub selbst antwortet, dass er keine hat, nie, wenn ein Node schweigt: Ein Schweigen hält den Batch einen Durchlauf zurück, auf der kanonischen Rail, deren Gebühr der Basisgebühr folgt, mit einem Alert, auf der USDG-Rail nur mit einer Warnung. Seit der zehnten Audit-Schleife, am 2026-10-06, trägt ein Batch auf der USDG-Rail höchstens die Obergrenze des Adapters an Märkten, standardmäßig 17, die er bei jedem Batch liest: Die am längsten wartenden Märkte gehen zuerst, und die anderen behalten ihr USDC in ihren Vaults für seinen nächsten Durchlauf, sodass keiner auf Dauer wartet (siehe Die Robinhood-Rail). Bis dahin ging jeder bereite Markt in den einen Batch, dessen festes Compose-Gas ein großer Batch erschöpfen konnte
  • Deployt den Spiegel-Vault jedes neuen Marktes auf Robinhood Chain vorab, vor seinem ersten Batch (predeploy), was seit dem 2026-10-05 nur er und der Owner von StockFun können. Der Remote-Hub erfährt aus einem Batch, wer der Keeper ist, daher deployt der Owner von StockFun vor dem ersten den Vault des ersten Marktes vorab. Der Keeper deployt nur dann vorab, wenn sein Key auf Robinhood Chain derjenige ist, den der Remote-Hub als Keeper kennt, oder der seines Admins. Ein Markt, dessen Vault der Keeper nicht vorab deployen kann (vor dem ersten Batch, nach einem Wechsel des Keepers, von dem der Remote-Hub noch nicht erfahren hat, oder wenn das Vorab-Deployment fehlschlägt), wird mit einer Warnung aus dem Batch herausgehalten, und die anderen Märkte gehen hinüber. Ein Markt, dessen Spiegel-Vault er an diesem Tag nicht auslesen kann, wartet auf den nächsten Zyklus, da ein blind gesendeter den ganzen Batch fehlschlagen lassen könnte
  • Überwacht Zustellungen: einen Transfer, der nicht angekommen ist, ein Ticket, das erneut ausgeführt werden muss, einen noch nicht deployten Spiegel-Vault. Ein Transfer, den er beim Absenden nicht auf Robinhood Chain messen konnte, wird nur durch die eigenen Events des Remote-Hubs bestätigt, nie durch einen später ausgelesenen Saldo, und auf der kanonischen Rail gilt das seit dem 2026-10-06 für jeden Transfer: Der Remote-Hub zahlt seine Einträge aus gemeinsamem Cash aus, sodass ein Saldo mit dem Geld eines anderen Batches wachsen kann. Er liest diese Events in wenigen Abschnitten auf einmal, ab der Stelle, an der die Suche jedes Transfers stehen geblieben ist; seit der siebten Audit-Schleife, am 2026-10-06, nur bis einige Blöcke unter dem neuesten der Chain, sodass ein Event in den neuesten Blöcken in einem späteren Zyklus gelesen wird, statt hinter einem Node verpasst zu werden, der einen oder zwei Blöcke zurückliegt. Seit der achten Audit-Schleife verfolgt er einen Bridge-Batch erst, wenn der Block, der ihn enthält, ebenso viele Blöcke tief liegt (KEEPER_LOG_LAG_BLOCKS), anhand seines dann erneut gelesenen Receipts: Die Kennungen eines Batches auf Robinhood Chain stammen aus diesem Block, und eine Reorganisation der neuesten Blöcke von Ethereum, die den Batch verschob, ließ den Keeper Kennungen beobachten, die nie existieren. Seit der zehnten Audit-Schleife sagt sein Alert für einen nicht rechtzeitig gutgeschriebenen Transfer auf der USDG-Rail, wo die Nachricht des Batches am Endpoint von Robinhood Chain steht: dort noch nicht zugestellt; Compose ausgeführt, die Gutschrift folgt; oder gespeichert, ihr USDG auf dem Remote-Hub und nirgends verbucht, bis jemand den letzten Schritt von Hand mit mehr Gas erneut ausführt, wobei der Alert den Hash der gespeicherten Nachricht nennt. Bis dahin nannte er nur, was der Remote-Hub verbucht, dessen Null sich als „nichts angekommen“ las, wenn ein letzter Schritt mit zu wenig Gas das Cash auf dem Hub gelassen hatte
  • Leitet jeden Notfall-Transfer, den er sieht, sofort an seinen Alert-Webhook weiter, auf jedem Vault, dem Bridge-Hub, dem Airdrop-Contract, dem Remote-Hub und jedem Spiegel-Vault. Seit der zehnten Audit-Schleife nennt er die Contracts, die er überwacht, in Gruppen, eine Log-Anfrage pro Gruppe, die jeweils höchstens KEEPER_LOG_MAX_SELECTORS Adressen und Event-Werte nennt (standardmäßig 1.000), und geht über einen Abschnitt von Blöcken erst hinaus, wenn jede seiner Gruppen gelesen ist. Bis dahin nannte eine einzige Anfrage sie alle: Sobald das Marktregister über das hinausgewachsen war, was ein Endpoint akzeptiert (2.000 Adressen und Event-Werte bei den Nodes von Robinhood Chain, neun Adressen beim öffentlichen Endpoint von Sepolia), wurde jede Anfrage abgelehnt und kein Notfall-Transfer mehr weitergeleitet
  • Liest seit der zehnten Audit-Schleife, was jeder Durchlauf von jedem Markt braucht (das ETH eines Vaults, sein USDC und sein Zeitfenster, die Schulden, den letzten Airdrop), über Multicall3, hundert Märkte pro Aufruf, am selben Block, den jeder Lesevorgang allein verwendete; ein Lesevorgang, der nicht zurückkommt, wird wie zuvor allein ausgeführt und nie für eine Null gehalten. Bis dahin kostete jeder jemals erstellte Markt seine Lesevorgänge einzeln bei jedem Durchlauf, ob inaktiv oder nicht, und 2.000 inaktive Märkte ließen einen Durchlauf so lange dauern wie das Intervall zwischen zweien
  • Verfolgt auf der kanonischen Rail seit der sechsten Audit-Schleife beide Tickets jedes Batches, bis er weiß, dass jedes ausgeführt wurde, unabhängig von der Gutschrift seines Transfers, in jedem Zyklus, ob Handelszeit ist oder nicht, und führt eines, das noch lebt, erneut aus. Ein Ticket, das sechs Stunden nach dem Abgang seines Batches nicht als ausgeführt bekannt ist, standardmäßig (KEEPER_TICKET_ALERT_HOURS), wird einmal gemeldet, ebenso eines, das an oder nach seiner Frist ohne gesehene Ausführung verschwunden ist oder dessen Erstellung fehlschlug. Bis dahin hörte der Keeper auf, die Tickets eines Batches zu verfolgen, sobald dessen Märkten gutgeschrieben war, wodurch eine Einzahlung, die ihre automatische Ausführung verpasst hatte, verfallen konnte. Seit der siebten Audit-Schleife liest er jedes Ticket in der Reihenfolge, in der das Arbitrum SDK es tut: zuerst das Receipt seiner Erstellung, dann seine automatische Ausführung, dann, ob es an einem Block, der nicht vor seiner Erstellung liegt, noch existiert; seit der achten Audit-Schleife an einem Block einige unter dem neuesten (KEEPER_REMOTE_LOG_LAG_BLOCKS), oder an seinem Erstellungsblock, wenn dieser später liegt, einem Block, den jeder Node eines Endpoints hat. Eine Einzahlung, die zwischen zwei seiner Lesevorgänge erstellt oder von zwei Nodes mit einem Block Abstand gesehen wird, gilt nie als ausgeführt, solange sie noch lebt
  • Warnt nach wiederholten Fehlschlägen bei einem Vault und zählt dabei dessen Schritt auf Ethereum und dessen Schritt auf Robinhood Chain getrennt, sodass ein Vault, der jeden Tag auf einer Seite fehlschlägt, gemeldet wird. Seit der siebten Audit-Schleife wartet er höchstens zehn Sekunden auf seinen Alert-Webhook und liest dessen Antwort: Ein Alert, den der Webhook nicht annimmt, wird behalten, höchstens hundert, in seiner Zustandsdatei, und in den nächsten Zyklen erneut gesendet, sodass er verspätet statt nie ankommt. Die Nachricht enthält die Felder, die Slack und Discord jeweils lesen. Seit der achten Audit-Schleife wird pro unterschiedlichem Alert ein Eintrag behalten: Ein Alert, der erneut ausgelöst wird, während er wartet (ein Vault, der in jedem Zyklus fehlschlägt), wird gezählt, nicht doppelt behalten. Die Nachricht sagt, wann der Alert zuerst und zuletzt ausgelöst wurde und wie oft, und ein verspätet zugestellter Alert sagt das gleich zu Beginn. Seit der neunten Audit-Schleife gehen die behaltenen Alerts in der Reihenfolge raus, in der sie zuletzt ausgelöst wurden: Ein erneut ausgelöster Alert rückt hinter die anderen, sodass das, was zuletzt zu einem Thema gesagt wird, sein neuester Stand ist (eine Überwachung, die fehlschlägt, sich erholt und wieder fehlschlägt, während der Webhook ausgefallen ist, wird zuletzt als „fehlschlagend“ zugestellt, wo sie früher mit „erholt“ endete). Über hundert hinaus wird nur ein Alert, der in jedem Zyklus ausgelöst wird, solange seine Ursache andauert (ein Vault, der nicht konvertieren kann, der fehlschlagende Bridge-Batch), zuerst verworfen, sodass ein einmaliger Alert, etwa ein Notfall-Transfer, und das letzte Wort jeder Episode nie verdrängt werden. Seit der zehnten Audit-Schleife trägt der Text eines Fehlers, in seinem Log, seinen Alerts und seiner Zustandsdatei, von einer RPC-Adresse nur Schema und Host, nie den Rest, in den Anbieter den Key setzen
  • Liest seit der neunten Audit-Schleife eine Minute lang, nachdem eine seiner eigenen Transaktionen gemint wurde, was diese Transaktion an ihrem Block geändert hat, nie am neuesten, und schätzt dort das Gas dessen, was er als Nächstes sendet. Der Testnet-Lauf fand den Grund: Ein Bridge-Batch, der direkt nach der Konvertierung desselben Durchlaufs gesendet wurde, wurde auf einem Node eines lastverteilten Endpoints simuliert, der einen Block hinter der Konvertierung lag, sah nichts zu bridgen und löste einen falschen Alert aus. Ein Node hinter diesem Block antwortet jetzt mit einem Fehler, und der Batch wartet einen Durchlauf mit einer Warnung. Jede Transaktion des Keepers geht außerdem mit ihrer Gas-Schätzung mal 1,25 raus, seit das Glamsterdam-Upgrade von Ethereum die Aufrufe in seinen Transaktionen schwerer gemacht hat
  • Liest seit der neunten Audit-Schleife eine von einer Chain gelesene Zeit, die kein Datum fassen kann (der Start eines Feeds, das Ende eines Zeitfensters, die Frist eines Tickets), als „an unknown time“, statt das Lesen fehlschlagen zu lassen, das auf sie traf
  • Prüft seit der siebten Audit-Schleife vor seinem ersten Zyklus, dass jeder RPC die Chain bedient, die seine Konfiguration nennt, und verweigert sonst den Start. Später entdeckt, stoppt eine falsche Chain die Arbeit auf dieser Chain mit einem Alert; eine Chain, deren Kennung nicht gelesen werden kann, wartet, und die Arbeit auf der anderen Chain läuft weiter. Seit der achten Audit-Schleife müssen beide Chain-Kennungen gesetzt sein (unten), und eine für eine andere Chain geschriebene Zustandsdatei bleibt unangetastet, bis der Keeper gelesen hat, welche Chain sein RPC bedient (siehe „Neustarts“)
  • Liest seit der achten Audit-Schleife die zwei Preisfeed-Schutzmechanismen des Oracles der Spiegel-Vaults auf Robinhood Chain: Solange das Oracle jeden Preis wegen des Sequencers zurückhält, warten die Remote-Käufe, mit einem Alert, und eine Aktie in einer Kapitalmaßnahme wartet allein (siehe „Wenn das Oracle Preise zurückhält“)
  • Zahlt das auf dem Remote-Hub wartende Cash mit einem Sweep aus, auf beiden Rails: Einträge, deren Tokens angekommen sind, und was den Hub erreicht hat, während er pausiert war. Auf der USDG-Rail hält er sich damit zurück, solange der Remote-Hub auf die Bereinigung eines Notfall-Transfers durch den Owner von StockFun wartet, was er einmal meldet, und fährt fort, sobald die Bücher bereinigt sind. Seit dem 2026-10-05 holt er per Sweep auch einen Anteil nach, den ein Spiegel-Vault abgelehnt hat, sobald dieser Vault das Cash wieder annimmt; auf der kanonischen Rail sendet er diesen Sweep nur, wenn er etwas auszahlen würde
  • Löst den BuybackBurner aus und rechnet dabei das auf dem Hook gutgeschriebene Buyback-Guthaben mit, das der Burner abholt, bevor er kauft
  • Sendet einmal pro Zeitfenster, standardmäßig nach der US-Handelszeit, die Aktien jedes Marktes an den Airdrop-Contract, ohne je die Aufteilung festzulegen: siehe unten
  • Zahlt seit dem 2026-10-05 in jedem Zyklus, unabhängig von der Handelszeit, aus, was der Hook und der Liquiditäts-Lock für einen Empfänger behalten, der es abgelehnt hat: was der Hook dem Vault eines Marktes schuldet (payTreasury), und die Anteile einer Gebühreneinsammlung, die der Lock für einen Vault oder einen Creator behält (payOwed). Jede Zahlung wird zuerst simuliert und nur gesendet, wenn sie etwas auszahlt. Beide Aufrufe stehen jedem offen
  • Sammelt seit dem 2026-10-05 die LP-Gebühren eines Pools ein, der mit einer solchen Gebühr erstellt wurde (collectFees, für jeden offen), höchstens einmal am Tag pro Pool. StockFun-Pools erheben standardmäßig keine LP-Gebühr, also gibt es standardmäßig nichts einzusammeln

Der Konvertierungsrhythmus

Der Gründer hat am 2026-09-27 entschieden, dass das ETH eines Vaults einmal pro täglichem Zyklus konvertiert wird, kurz vor dem Airdrop, und nur, wenn der Vault bei dieser Prüfung die Schwelle hält. Der Keeper hält sich seit dem 2026-10-06 daran; bis dahin konvertierte er das ETH eines Vaults bei jedem Durchlauf der Handelszeit, sobald der Vault die Schwelle hielt.

  • Das Zeitfenster. Der Zyklus ist das Zeitfenster des Airdrops: Es schließt, wann der Airdrop-Contract es sagt (24 Stunden, die standardmäßig um 13:00 UTC schließen), den $STOCKFUN-Markt eingeschlossen; solange die Factory keinen Airdrop-Contract benennt, nach diesem Standardzeitplan
  • Eine Prüfung pro Zeitfenster. Die Schleife macht weiterhin standardmäßig alle fünf Minuten einen Durchlauf, und jeder Durchlauf endet mit einem Zyklusbericht. Die Schwelle wird beim ersten Durchlauf nach dem Schließen des Zeitfensters geprüft, der den Vault erreicht. Liegt der Saldo auf oder über ihr, wird das ETH konvertiert, einmal: Die eigene Aufzeichnung des Vaults über seine letzte ETH-Konvertierung, von der Chain gelesen, sagt es den nächsten Durchläufen, ein Neustart ändert also nichts. Liegt er darunter, wartet das ETH auf das nächste Zeitfenster, auch wenn Trades ihn später am Tag über die Schwelle bringen; der Keeper hält diese Prüfung in seiner Zustandsdatei fest. Seit dem 2026-10-06 hält er sie als das Ende des Zeitfensters fest, für das die Prüfung erfolgte, nie als die Zeit seiner eigenen Uhr, die eine um den Schließzeitpunkt leicht falsch gehende Uhr vom Zeitfenster der Chain abweichen lassen konnte; eine Prüfung, die ein älterer Keeper geschrieben hat, zählt nicht, sodass ein solcher Vault im Zeitfenster des Upgrades erneut geprüft wird. Seit der sechsten Audit-Schleife liest die Prüfung den Saldo des Vaults nach dem Schließen des Zeitfensters: Ein Durchlauf, der über den Schließzeitpunkt hinweg lief, hielt früher den Saldo fest, den er davor gelesen hatte, und ein Vault, der die Schwelle rechtzeitig überschritten hatte, übersprang dieses Zeitfenster
  • Eine Konvertierung, die bei der Prüfung nicht rausgehen kann (ein stiller ETH/USD-Feed, ein Handelsplatz, der sie nicht innerhalb der Grenze des Vaults ausführen kann, eine fehlgeschlagene Transaktion, ein Zeitfenster, das der Keeper nicht lesen kann), wird bei den nächsten Durchläufen desselben Zeitfensters erneut versucht. Ein Zeitfenster, das er nicht lesen kann, zählt als Fehlschlag des ETH-Schritts, nach wiederholten Fehlschlägen gemeldet, und das USDC des Vaults bewegt sich trotzdem weiter
  • Das USDC, seit der sechsten Audit-Schleife. Das USDC, das bereits in einem Vault liegt, geht weiter, ob die Schwelle erreicht ist oder nicht, in seinem eigenen Tempo: Sein Kauf auf Ethereum oder seine Freigabe in einen Bridge-Batch geht einmal nach jeder ETH-Konvertierung des Vaults und sonst höchstens einmal pro Zeitfenster (ein Geschenk, eine Rückerstattung, was ein fehlgeschlagener oder halbierter Schritt übrig ließ). Nur ein Schritt, der durchging, zählt; einer, der fehlschlägt, wird bei den nächsten Durchläufen erneut versucht. Die Entscheidung des Gründers vom 2026-09-27 erstreckt sich damit auf das USDC: Bis dahin brachten ein paar Einheiten USDC, die vor jedem Durchlauf an einen Vault gesendet wurden, den Keeper dazu, bei jedem Durchlauf einen Kauf oder einen ganzen Bridge-Batch mit seiner Gebühr zu senden
  • Was bei jedem Durchlauf rausgeht: die Käufe auf Robinhood Chain. Der Saldo eines Spiegel-Vaults kann eine Zustellung nicht von einem Geschenk unterscheiden, und die Obergrenzen jedes Kaufs verteilen eine große Zustellung absichtlich auf mehrere Durchläufe. Das ETH, das eine halbierte Konvertierung übrig lässt (der Handelsplatz konnte nicht den gesamten Saldo innerhalb der Grenze ausführen), wartet auf das nächste Zeitfenster
  • Lokale und Testnet-Läufe setzen KEEPER_CONVERT_ONCE_PER_WINDOW auf false und konvertieren, kaufen und bridgen dann bei jedem Durchlauf; überall sonst bleibt es an, sein Standardwert

An anderen Stellen dieser Seite bedeutet „in jedem Zyklus“ bei jedem Durchlauf der Schleife, wie im Zyklusbericht; nur der tägliche Zyklus des Airdrops ist das Zeitfenster.

Jeder Fehler für sich

Seit dem 2026-10-05 lassen die Contracts ein Leg, eine Aktie, einen Markt oder eine Zustellung fehlschlagen, ohne die anderen anzuhalten, und melden mit einem Event, was fehlgeschlagen ist. Der Keeper liest diese Events und meldet, was hängen bleibt; seine eigene Arbeit ist auf dieselbe Weise aufgeteilt.

  • Ein Kauf-Leg. Das Leg jeder Aktie wird für sich geplant: Ein Leg, das nicht geplant werden kann, wird übersprungen, und die anderen Legs laufen. Ein Leg, das der Vault als fehlgeschlagen meldet (LegFailed), behält sein Cash für seine Aktie reserviert; der Keeper zählt es nie als konvertiert und gibt nach drei Fehlschlägen dieser Aktie in Folge in diesem Vault einen Alert aus (KEEPER_ALERT_AFTER_FAILURES). Wenn kein Leg eines Vaults geplant werden kann, schlägt der Vault als Ganzes fehl, wie zuvor
  • Ein Markt eines Bridge-Batches. Ein Markt, den der Bridge-Hub aus einem Batch auslässt (MarketSkipped), behält sein USDC in seinem Vault für einen späteren Batch. Wird er aus drei Batches in Folge ausgelassen (KEEPER_BRIDGE_ALERT_AFTER_SKIPS), wird er einmal gemeldet, mit dem dekodierten Grund und seiner Behebung. Seit der zehnten Audit-Schleife wartet ein Markt, den die Obergrenze des Adapters aus einem Batch auslässt, auf den nächsten Durchlauf, im Log vermerkt, und führt diesen Batch an; ein Batch, den der Adapter ablehnt (über seiner Obergrenze, oder ein ohne seine Batch-Einstellungen upgegradeter Adapter), wird mit dem genannten Grund und den eigenen Märkten des Batches gemeldet
  • Eine abgelehnte Zustellung. Ein Anteil, den der Cash-Token einem Spiegel-Vault verweigert hat (DeliveryRefused), wird einmal gemeldet, mit seiner Behebung, bis der Remote-Hub diesem Markt nichts mehr davon schuldet
  • Ein unlesbarer Vault. Ein Vault, dessen eigene Views nicht antworten, etwa nach einem kaputten Upgrade, bleibt in diesem Zyklus außen vor; die anderen Vaults konvertieren. Nach drei Zyklen in Folge wird er einmal gemeldet (KEEPER_ALERT_AFTER_FAILURES)
  • Eine bleibende Schuld. Solange ein Vault, oder der Hook für den Anteil eines Creators, das ihm geschuldete ETH weiter ablehnt, meldet der Keeper einmal pro Episode, dass der Pool auf den Owner von StockFun wartet (ein korrigierendes Upgrade), und protokolliert das Ende der Episode, sobald die Schuld bezahlt ist, vom Keeper oder von irgendjemand anderem

Was nur der Owner von StockFun bereinigen kann, ist „wartet auf den Admin“: ein Alert pro Episode, nie als Fehlschlag gezählt, und der Rest läuft unterdessen weiter.

Der Zyklusbericht enthält nun die ausgezahlten und die noch offenen Schulden, die fehlgeschlagenen Legs, die Pools, deren LP-Gebühren eingesammelt wurden, und, für den Airdrop-Schritt, die eröffneten Zyklen, die durchgeführten Suchen nach beiseitegelegten Aktien, die Vaults, die gesendet haben, und die Zustellungen, die noch unterwegs sind. Seit dem 2026-10-06 wird eine Sendung in ein Zeitfenster ohne berechtigte Bestände, die der Airdrop-Contract beiseitelegt, gesondert gezählt (airdropHeldAside), nicht mehr bei den Vaults, die gesendet haben; auf der kanonischen Rail zählt er die gesendeten erneuten Ausführungen von Tickets (redeemed) und die noch verfolgten Tickets (ticketsWatched). Seit der siebten Audit-Schleife zählt er außerdem die Märkte, deren Airdrop-Sendung darauf wartet, ihre Kosten wert zu sein (airdropBelowCost), und die für den Webhook behaltenen Alerts (alertsUndelivered), und sagt, wann die Kennung einer Chain noch nicht geprüft ist (deferred: chain-unverified).

Wenn das Oracle Preise zurückhält

Seit dem 2026-10-06 kann das Oracle der Spiegel-Vaults einen Preis zurückhalten (siehe Die Robinhood-Rail), und seit der achten Audit-Schleife liest der Keeper es, bevor er irgendetwas bepreist:

  • Der Sequencer. Einmal pro Zyklus fragt er das Oracle, was seine Sequencer-Prüfung sagt. Solange der Sequencer ausgefallen ist, nicht länger als die Karenzzeit wieder läuft oder sein Uptime-Feed nicht gelesen werden kann, kann keine Aktie bepreist werden: Der Kauf des Vaults wartet, nichts wird bepreist und nichts zählt als Fehlschlag. Ein Alert eröffnet die Episode, in der Zustandsdatei behalten, damit ein Neustart ihn nicht erneut auslöst, und einer sagt, wann die Käufe wieder aufgenommen werden. Die Prüfung ist auf Robinhood Chain aus, bis Chainlink einen Uptime-Feed dafür veröffentlicht, sodass heute nichts davon geschehen kann
  • Eine Kapitalmaßnahme. Eine Aktie, deren Token sein Oracle pausiert, wird von vornherein aus dem Kauf herausgelassen, im Log vermerkt, ihr USDG für sie behalten; sie zählt nie für den Fehlschlag-Alert, und die anderen Aktien des Baskets werden gekauft. Ein Leg, das der Vault aus diesem Grund als fehlgeschlagen meldet, zwischen dem Plan des Keepers und seinem Kauf, ist erwartet und wird ebenfalls nicht gezählt
  • Der Grund, genannt. Wo die Grenze eines Legs nicht gelesen werden kann, weil ein Schutzmechanismus seinen Preis zurückhält, protokolliert der Keeper den Grund, auf beiden Chains, statt eines Vaults, der das Leg nicht bepreisen kann. Ein Schutzmechanismus, den er nicht lesen kann (ein Oracle aus der Zeit vor den Schutzmechanismen), hält nichts zurück: Die eigene Grenze jedes Legs entscheidet, wie zuvor. Seit der neunten Audit-Schleife werden auch die anderen Fehler des Oracles dekodiert: Ein veralteter Feed erscheint als StalePrice im Log und im Grund eines fehlgeschlagenen Legs, wo dort ein undekodierter Code stand

Der Airdrop-Schritt

Die Seite des Contracts ist seit dem 2026-10-04 programmiert, der Schritt des Keepers seit dem 2026-10-05. In jedem Zyklus verfolgt der Keeper vor der Prüfung der Handelszeit zuerst die bereits gesendeten Zustellungen. Dann nimmt er, solange die Factory einen Airdrop-Contract benennt, jeden Markt der Reihe nach, den $STOCKFUN-Markt eingeschlossen:

  1. Einmal pro Zeitfenster. Ein Vault ist für das Zeitfenster erledigt, wenn seine letzte Sendung (lastAirdropAt) am oder nach dem Ende des Zeitfensters liegt, in dem eine Sendung jetzt landen würde (currentCycleEnd). Beides wird von der Chain gelesen, ein Neustart ändert also nichts. Standardmäßig sendet der Keeper erst, wenn die US-Handelszeit des Tages vorbei ist, damit die Käufe des Tages in einer einzigen Sendung in das an diesem Tag beendete Zeitfenster gehen, und nur, wenn der Vault Aktien hält; seit der siebten Audit-Schleife nur die Aktien, die so viel wert sind, wie ihr Senden kostet (unten). Seit der zehnten Audit-Schleife wird mit diesem Standard ein Vault, der nach Handelsschluss ohne etwas zu senden gelesen wurde, erst wieder gelesen, wenn die nächste Handelszeit beginnt oder das Zeitfenster weiterrückt, auf den Rails, deren Käufe der New Yorker Handelszeit folgen (nicht der von Ondo): Was er hält, stammt aus seinen Käufen, die in der Handelszeit getätigt werden. Nicht, solange ein eigener Kauf noch auf sein Receipt wartet, das im Laufe des Abends landen kann: Dieser Vault wird bei jedem Durchlauf gelesen, und was der Kauf bringt, geht in das an diesem Tag beendete Zeitfenster
  2. Zuerst die beiseitegelegten Aktien, auch wenn nichts zu senden ist. Hält der Markt Aktien beiseite, assignUnassigned, höchstens fünf Aufrufe pro Zyklus, bis sie zugewiesen sind, was den Zyklus des Zeitfensters eröffnet, das sie aufnimmt, oder kein beendetes Zeitfenster mehr zu prüfen bleibt. Seit dem 2026-10-06 führt der Keeper diese Suche durch, ob der Vault etwas zu senden hat oder nicht, und unabhängig davon, ob der Vault pausiert ist: Bis dahin lief sie nur vor einer Sendung, sodass ein Markt, der einmal gehandelt wurde und dann still wurde, seinen ersten Airdrop, beiseitegelegt, außer Reichweite seiner Holder hielt, bis zu einem neuen Trade oder bis jemand die Suche von Hand durchführte. Eine nicht abgeschlossene Suche hält eine Sendung in ein Zeitfenster ohne berechtigte Bestände bis zum nächsten Zyklus zurück. Seit der sechsten Audit-Schleife wird, solange der Vault nichts zu senden hat, eine Suche, die nichts zuweisen würde (noch kann kein Zeitfenster die Aktien aufnehmen), erst gesendet, wenn die Suche des Marktes dem letzten Zeitfenster um maxWindowsPerAssign Zeitfenster hinterherhinkt, standardmäßig 30: eine Suche im Monat statt dauerhaft einer am Tag. Eine Suche, die die Aktien zuweist, geht immer raus. Seit der siebten Audit-Schleife bedeutet „nichts zu senden“ nichts, was das Senden wert ist, nach derselben Regel wie die Sendung: Auf der Bridge-Rail zählt der Dust, den das OFT nicht transportieren kann und den jede Sendung im Spiegel-Vault zurücklässt, für nichts, und die Grenze greift auch dort
  3. Der Zyklus, nur vor einer Sendung. openCycle, sodass jede Zustellung ihm nur noch etwas hinzufügt; nie für ein Zeitfenster, in das nichts gesendet wird, und seit der siebten Audit-Schleife nur für eine Sendung, die ihre Kosten wert ist, die Eröffnung eingeschlossen. Ein Zeitfenster ohne berechtigte Bestände ist kein Fehler: Die Aktien werden dann beiseitegelegt
  4. Die Sendung. Auf der lokalen Rail sendToAirdrop auf dem TreasuryVault des Marktes. Auf der Bridge-Rail sendToAirdrop auf dem Spiegel-Vault, unter Zahlung seiner angegebenen LayerZero-Gebühr (quoteSendToAirdrop) plus einer Marge, standardmäßig 10 %; der Vault gibt den Überschuss zurück. Seit der neunten Audit-Schleife tragen die Sendung und jede ihrer Preisabfragen das Gas, das ihre Zustellungen auf Ethereum erhalten und das der Keeper wählt (unten). Vor dieser Sendung prüft der Keeper, dass der Remote-Hub an den Airdrop-Contract der Factory sendet, dass jede Aktie einen Adapter hat und dass der Adapter antwortet, und dass das OFT der Aktie auf Ethereum auf dem Airdrop-Contract registriert ist. Seit der siebten Audit-Schleife listet die Sendung nur die Aktien, die ihre Kosten wert sind, und ihre Gebühr wird für sie erneut abgefragt
  5. Die Zustellungen. Auf der Bridge-Rail wird die Zustellung jeder Aktie verfolgt, bis der LayerZero-Endpoint auf Ethereum ihren letzten Schritt ausgeführt hat, der dem Airdrop-Contract gutschreibt. Seit der neunten Audit-Schleife führt der Keeper eine auf diesem Endpoint festhängende Zustellung selbst erneut aus (unten). Eine Zustellung, die nicht innerhalb von standardmäßig 60 Minuten gutgeschrieben ist, löst einen Alert aus, der die Befehle enthält, die ihre Schritte von Hand ausführen; jeder kann sie ausführen

Jede Aktie geht für sich: Eine Aktie, deren Saldo nicht gelesen werden kann (ein Einfrieren durch den Emittenten), eine ohne Adapter oder deren OFT nicht registriert ist, eine, deren Adapter nicht antwortet (peers(): kein Contract an seiner Adresse oder keine LayerZero-App; seit dem 2026-10-06, bis dahin ließ das die ganze Sendung des Marktes fehlschlagen), seit der achten Audit-Schleife eine, deren LayerZero-Gebühr ihr Adapter nicht abfragen kann (unten), und eine, die der Vault als nicht gesendet meldet (AirdropSendFailed), bleiben außen vor, mit einem Alert, und die anderen gehen. Auch jeder Markt geht für sich: Einer, der immer wieder fehlschlägt, wird nach drei Fehlschlägen in Folge einmal gemeldet, und der nächste Markt läuft weiter. Seit dem 2026-10-06 hat eine Suche nach beiseitegelegten Aktien, die immer wieder fehlschlägt, einen eigenen Alert, der ihre Behebung nennt: Jeder kann assignUnassigned für diesen Markt aufrufen.

„Wartet auf den Admin“ umfasst hier einen pausierten Airdrop-Contract, eine Aktie, die dem Airdrop-Contract nach einem Notfall-Transfer fehlt (diese Aktie wartet in den Vaults, die anderen gehen), einen Remote-Hub, der an einen anderen Airdrop-Contract als den der Factory sendet, und, seit der neunten Audit-Schleife, einen Remote-Hub, dessen Gas-Grenzen für die Zustellungen nicht gesetzt sind oder dessen Obergrenze unter dem liegt, was eine Zustellung braucht.

Was das Senden wert ist

Seit der siebten Audit-Schleife, am 2026-10-06, sendet der Keeper nur, was so viel wert ist, wie sein Senden kostet. Bis dahin ging jede Aktie über null: Ein Geschenk knapp über dem Dust an den Vault eines Marktes, den niemand handelt, brachte den Keeper dazu, jeden Tag den Zyklus dieses Zeitfensters zu eröffnen und eine LayerZero-Nachricht oder eine Sendung auf Ethereum zu bezahlen.

  • Was eine Sendung trägt. Eine Aktie, deren Saldo gelesen werden kann und über null liegt; auf der Bridge-Rail muss sie außerdem einen Adapter und eine eigene Preisabfrage über null haben. Die Preisabfrage des Vaults ist gleichermaßen null für den Dust, den das OFT nicht transportieren kann, und für eine Aktie, deren Adapter ihre Sendung nicht bepreisen kann, daher fragt der Keeper seit der achten Audit-Schleife den Adapter der Aktie selbst, für die Sendung, die der Vault bauen würde: Der Dust wird nie gesendet und nie gemeldet; eine Aktie, deren Preisabfrage fehlschlägt, deren eigene Sendung fehlschlagen würde, wird mit einem Alert, der den Grund nennt, ausgelassen; und eine Aktie, die der Keeper nicht fragen kann, geht wie zuvor, und ihre Sendung entscheidet. Bis dahin galt eine solche Aktie als Dust und fiel wortlos aus jeder Sendung
  • Ihr Wert. Jede Aktie wird mit dem eigenen Oracle ihres Vaults bewertet, zur letzten Antwort ihres Preis-Feeds, veraltet oder nicht, da dies eine Schätzung und nie eine Grenze ist; die Kosten, in ETH bezahlt, werden mit dem ETH/USD-Feed desselben Oracles in Dollar umgerechnet
  • Ihre eigenen Kosten. Jede Aktie muss mindestens ihre eigenen Kosten wert sein: ihre LayerZero-Gebühr auf der Bridge-Rail, wo jede Aktie eine eigene Nachricht ist, oder ihren Anteil am Gas der Sendung auf der lokalen Rail. Ein Geschenk, das seine eigene Nachricht nicht wert ist, fährt nie bei einer echten Sendung mit
  • Die ganze Sendung. Die Aktien, die bestehen, müssen zusammen die ganze Sendung wert sein, plus die Eröffnung des Zeitfensters (openCycle), wenn sein Zyklus noch nicht eröffnet ist. Auf der lokalen Rail wird die Eröffnung seit der achten Audit-Schleife einmal gezählt: Die eigene Schätzung der Sendung, bei geschlossenem Zyklus genommen, enthält sie bereits, sodass nur die Grundkosten der Eröffnungstransaktion hinzukommen; doppelt gezählt hielt sie tagelang eine Sendung zurück, die etwas mehr wert war, als sie kostete. Sonst geht keine, und der Zyklus wird nicht eröffnet
  • Was wartet. Was nicht geht, bleibt im Vault und geht in einem späteren Zeitfenster, mit dem, was sich ansammelt. Ein Markt, dessen Sendung wartet, wird im Zyklusbericht gezählt und einmal pro Zeitfenster protokolliert
  • Was nicht gelesen werden kann. Ein Preis, eine Gebühr oder Gaskosten, die der Keeper nicht lesen kann, lassen die Sendung gehen, wie vor der Regel: Ein Lesen, das fehlschlägt, hält nie eine echte Sendung zurück

KEEPER_AIRDROP_MIN_VALUE_BPS setzt das Vielfache: standardmäßig 10.000, einmal die Kosten, sodass eine Sendung, die mindestens so viel wert ist, wie sie kostet, geht, wie groß sie darüber auch ist; ein höherer Wert hält kleinere Sendungen zurück, bis sie dieses Vielfache wert sind, und 0 sendet, was immer getragen wird. Dieselbe Regel entscheidet, ob ein Vault für die Suche nach beiseitegelegten Aktien oben etwas zu senden hat. Das Audit hat sie als seinen empfohlenen Standard übernommen; sie entscheidet nur, wann eine Aktie geht, nie wie viel, was oder wohin.

Das Gas der Zustellung auf Ethereum

Am 2026-10-06 hat Sepolia das Glamsterdam-Upgrade von Ethereum aktiviert, das einen neuen Storage-Slot etwa das Fünffache seines früheren Gases kosten lässt, und jeder Airdrop-Zustellung des ersten Zyklus des LayerZero-Testnet-Laufs ging beim Executor von LayerZero das Gas aus: Eine Sendung bezahlte nur das Gas des letzten Schritts der Zustellung, und das Gas ihres ersten Schritts war, was der Owner des LayerZero-Adapters der Aktie erzwingt (auf dem Mainnet der Emittent). Seit der neunten Audit-Schleife, nach der Entscheidung des Gründers vom selben Tag:

  • Der Keeper simuliert jede Zustellung auf Ethereum vor der Sendung: den Token-Contract der Aktie, der sie empfängt, und den Airdrop-Contract, der sie gutschreibt, so, wie die Zustellung sie vorfinden wird. Er verlangt den Bedarf der schwersten Aktie mal 1,25, abzüglich des Gases, das der LayerZero-Adapter der Aktie für den ersten Schritt bereits erzwingt
  • Wenn eine Simulation nicht laufen kann, nimmt er, was die letzten Zustellungen des Marktes auf Ethereum verbraucht haben, dann die Standardwerte des Remote-Hubs
  • Der Remote-Hub begrenzt es. Der Owner von StockFun setzt für jeden der beiden Schritte einen Standardwert, eine Untergrenze und eine Obergrenze (siehe Die Robinhood-Rail); was immer der Keeper verlangt, wird zwischen ihnen gehalten. Eine Anfrage, die die Obergrenze unter den Bedarf einer Zustellung drückt, ist „wartet auf den Admin“: Die Sendung geht trotzdem, und eine Zustellung, die festhängt, wird erneut ausgeführt (nächster Abschnitt)
  • Für die Holder ändert sich nichts. Der Keeper entscheidet nur das Gas, das eine Zustellung erhält, nie wie viel gesendet wird, wohin oder an wen
  • Nur bei Bedarf neu gewählt. Ein Gas-Paar, das aus der Simulation jeder Aktie gewählt wurde, wird für das Zeitfenster behalten, solange die Aktien, der Zustand des Zyklus des Zeitfensters und die Frage, ob eine Zustellung nach dem Ende des nächsten Zeitfensters landen kann, gleich bleiben; eines, das eine Simulation nicht liefern konnte, wird bei jedem Durchlauf neu gewählt. Seit der zehnten Audit-Schleife liest eine Sendung, die nur den Staub trägt, den die Bridge nicht tragen kann, nichts von der Umgebung der Zustellung, und ein Paar, das simuliert wurde, nachdem der Zyklus des Zeitfensters eröffnet war, ein Zustand, der nie zurückgeht, wird wiederverwendet, ohne ihn erneut zu lesen

Eine auf Ethereum festhängende Zustellung

Eine Zustellung, der das Gas ausgeht, verliert nichts: Sie bleibt auf dem Endpoint von LayerZero auf Ethereum, ihr erster Schritt verifiziert und nicht ausgeführt oder ihr letzter Schritt gespeichert und nicht ausgeführt, bis jemand sie mit mehr Gas erneut ausführt. Seit der neunten Audit-Schleife tut der Keeper das selbst:

  • Er liest in jedem Zyklus den Schritt jeder Zustellung auf dem Endpoint. Sobald der Executor an der Reihe war (sein Fehlschlag, nur vom eigenen Executor von LayerZero geglaubt, oder zehn Minuten), führt er den festhängenden Schritt von seinem Ethereum-Key aus erneut aus, mit dem simulierten Bedarf mal 1,25 und nie mehr als KEEPER_AIRDROP_REEXECUTION_MAX_GAS, standardmäßig 4.000.000
  • Eine, die er nicht senden kann (ihre Simulation schlägt fehl, ihr Bedarf liegt über der Grenze, seinem Key fehlt ETH), wird einmal gemeldet, mit dem Befehl, sie von Hand auszuführen, und in jedem Zyklus erneut versucht
  • Eine, die on-chain erneut fehlschlägt, der Schritt noch festhängend, ist der zweite Fehlschlag: gemeldet, mit dem Befehl, und vom Keeper nie erneut gesendet. Er entscheidet das nur anhand eines Lesens des Schritts, das antwortet, und erst, wenn der Block des fehlgeschlagenen Laufs einige Blöcke tief liegt (KEEPER_LOG_LAG_BLOCKS), sodass weder ein Node, der einen Block zurückliegt, noch eine Reorganisation dieses Blocks ihn aufgeben lassen kann
  • Der Ethereum-Key des Keepers bezahlt diese Läufe: Unter Glamsterdam braucht ein letzter Schritt, der einen Zyklus eröffnet, etwa eine Million Gas

Der Keeper wählt, wann, und das Gas einer Zustellung innerhalb der Grenzen des Owners, sonst nichts. Eine Sendung, die nach dem nächsten Schließzeitpunkt ankommt, wird über das Zeitfenster des nächsten Tages gemessen.

Sieben Variablen steuern den Schritt: KEEPER_AIRDROP (standardmäßig an), KEEPER_AIRDROP_AFTER_SESSION (standardmäßig an; aus auf einem Testnet, das die Handelszeit ignoriert), KEEPER_AIRDROP_FEE_MARGIN_BPS (1.000), KEEPER_AIRDROP_TRANSIT_MINUTES (60), seit der siebten Audit-Schleife KEEPER_AIRDROP_MIN_VALUE_BPS (10.000) und seit der neunten KEEPER_AIRDROP_REEXECUTION_MAX_GAS (4.000.000) und KEEPER_AIRDROP_LZ_EXECUTOR (leer: der Executor von LayerZero auf der Chain des Keepers, der einzige Aufrufer, dessen Fehlschlag-Meldungen der Keeper glaubt).

Neustarts: die Zustandsdatei

Seit dem 2026-10-05 schreibt der Keeper, was er von einem Zyklus zum nächsten verfolgt, in eine Zustandsdatei (KEEPER_STATE_DIR): die Airdrop-Zustellungen und die Bridge-Transfers, die unterwegs sind, die Transaktionen, die auf ein Receipt warten, seine Alert-Episoden und Fehlschlag-Serien; seit der sechsten Audit-Schleife außerdem die Tickets der kanonischen Rail, die er verfolgt, die Stelle, an der die Suche jedes Transfers stehen geblieben ist, und wann das USDC jedes Vaults zuletzt rausging; seit der siebten die Alerts, die sein Webhook noch nicht angenommen hat. Eine Datei, die ein älterer Keeper geschrieben hat, wird so geladen, wie sie ist. Er schreibt die Datei nach jedem Zyklus und jeder Sendung und liest sie einmal beim Start. Ein Neustart vergisst nichts davon: Eine Zustellung, deren letzter Schritt nach einem Neustart fehlschlägt, wird weiterhin gemeldet, eine vor dem Neustart gesendete Transaktion wird nie erneut gesendet, und eine bereits gemeldete Episode wird nicht zweimal gemeldet. Eine für eine andere Factory geschriebene Datei wird beiseitegelegt, und der Keeper startet leer, mit einer Warnung. Seit der achten Audit-Schleife bleibt eine für eine andere Chain geschriebene Datei zunächst, wie sie ist, weder gelesen noch überschrieben, bis der Keeper gelesen hat, welche Chain sein RPC bedient: Bedient er die konfigurierte Chain, gehörte die Datei einer anderen Chain und wird dann beiseitegelegt; wenn nicht, ist die konfigurierte Kennung der Fehler, der Keeper verweigert den Start, und sobald sie korrigiert ist, nimmt der Keeper seine Datei wieder auf, einschließlich der Einzahlungen, die er verfolgte. Bis dahin kostete eine vertippte Kennung die Datei, bevor der Keeper den Start verweigerte. Die behaltenen Alerts sind seit derselben Schleife einer pro unterschiedlichem Alert; eine Datei, die ein älterer Keeper geschrieben hat, wird so geladen, wie sie ist. Seit der neunten Audit-Schleife behält die Datei außerdem das Paket jeder Airdrop-Zustellung und ihre Läufe durch den Keeper, das Gas, das die letzten Zustellungen des Marktes verbraucht haben, und die letzte erneute Ausführung jedes kanonischen Tickets durch den Keeper; eine Datei, die ein älterer Keeper geschrieben hat, wird weiterhin so geladen, wie sie ist.

Seit dem 2026-10-06:

  • Jede Sendung liegt vor ihrem Warten auf der Festplatte. Jede Transaktion geht mit der Nonce raus, die die Chain der Adresse des Keepers unmittelbar davor gibt, und wird mit ihrem Hash und ihrer Nonce in die Zustandsdatei geschrieben, sobald der Hash zurückkommt, bevor auf ihr Receipt gewartet wird: Ein Keeper, der während des Wartens beendet wird, liest sie bei seinem Neustart über ihren Hash, statt sie erneut zu senden
  • Eine verlorene Transaktion wird aufgegeben. Eine, die viermal KEEPER_RECEIPT_ALERT_MS nach ihrem Senden (standardmäßig zwei Stunden) kein Node mehr kennt, wird mit einem Alert fallen gelassen, sodass sie Sendungen ihrer Art nicht mehr zurückhält; ihre Nonce ist weiterhin frei, und die nächste Transaktion des Keepers nimmt sie. Der Alert für eine noch nicht geminte Transaktion sagt, wie man sie ersetzt
  • Vollständig geschrieben. Eine Festplatte, die zu voll ist, um die Datei aufzunehmen, ist ein Fehler, der gemeldet wird, und die letzte gute Datei bleibt; bis dahin konnte eine abgeschnittene Kopie sie ersetzen
  • Ein Keeper pro Ordner. Der Keeper setzt eine Sperre in seinem Zustandsordner (keeper.lock): Ein zweiter Keeper auf demselben Ordner verweigert den Start und nennt den ersten. Eine Sperre, deren Keeper nicht mehr läuft, wird übernommen; eine, die ein Keeper auf einem anderen Host hinterlassen hat, nicht, und der Betreiber löscht sie, sobald dieser Keeper nicht mehr läuft. Ein Dry Run setzt keine Sperre

Die Bemessung jedes Schritts

Seit dem 2026-10-01 konvertiert der Vault den Betrag, den der Keeper nennt, nicht seinen gesamten Saldo. Der Keeper bemisst ihn wie folgt:

Schritt Betrag
ETH → USDC Der gesamte Saldo, halbiert, solange die Preisabfrage die Grenze des Vaults verfehlt, nie unter der Konvertierungsschwelle; seit dem 2026-10-06 wartet der Rest auf das nächste Zeitfenster
Eine Aktie auf Uniswap-Pools auf Ethereum Die Reservierung der Aktie, höchstens viermal halbiert; ein Leg, das die Grenze dann noch verfehlt, wartet auf den nächsten Zyklus, mit unangetasteter Reservierung
Eine Aktie auf der optionalen Ondo-Rail Die Reservierung der Aktie, begrenzt auf das Nominallimit der Handelssitzung. Seit dem 2026-10-06 wird ein Leg, das Ondo unter der Grenze des Vaults bepreist, nie gesendet: Die kostenlose Preisabfrage wird vor jeder Attestierung gelesen, und sobald eine Attestierung unter der Grenze zurückkommt, wird für diese Aktie bis zum nächsten Zeitfenster keine mehr angefragt
Eine Aktie auf Robinhood Chain Die Reservierung der Aktie, einzeln durch eine feste Obergrenze begrenzt und, wenn ihr Pool gemessen werden kann, durch einen Anteil an der Tiefe dieses Pools

Was nicht ausgegeben wird, wartet im Vault auf den nächsten Zyklus (beim ETH auf das nächste Zeitfenster); das Cash einer Aktie bleibt für diese Aktie reserviert.

Seit der Security-Pipeline vom 2026-10-01 hält jeder Kauf, auf jeder Rail, die Aktien kauft, bei der letzten Aktie des Baskets n−1 Einheiten zurück, wobei n die Anzahl der Aktien ist. Die Vaults geben den Rundungsrest der Gewichtungen an die letzte Aktie, sodass einige Einheiten Cash, die zwischen dem Auslesen durch den Keeper und seiner Transaktion eingehen, diese eine Reservierung um bis zu n−2 Einheiten senken können; den ausgelesenen Betrag auszugeben, würde den gesamten Aufruf fehlschlagen lassen, und jeder könnte das mit einem Dust-Transfer verursachen. Was zurückgehalten wird, bleibt für den nächsten Aufruf reserviert. Alles andere, was die Vaults aufruft, sollte dieselbe Marge einhalten. Eine Korrektur in den Contracts, welche die dokumentierte Allokationsregel ändert, wartet auf die Entscheidung des Owners. Seit dem 2026-10-06 wird ein Vault, der nicht mehr als diese wenigen Einheiten USDC hält (höchstens vier, da ein Basket höchstens fünf Aktien umfasst), ihretwegen nicht mehr angesteuert: Sie warten auf das nächste USDC, das sein ETH bringt.

Der Burn von $STOCKFUN wird auf dieselbe Weise bemessen: Eine Tranche, deren Price Impact die Obergrenze des Keepers übersteigt, wird halbiert, nie unter die Schwelle des Keepers, und der Rest wird in späteren Zyklen verbrannt. Seit der Security-Pipeline vom 2026-10-01 wird auch eine Tranche halbiert, die der $STOCKFUN-Pool nicht vollständig ausführen kann; vorher schlug der Burn für diesen Zyklus fehl. Jeder andere Fehlschlag wird nicht erneut versucht.

Was er nicht kann

Ein Asset außerhalb des Baskets wählen. Das reservierte Cash einer Aktie zu einer anderen Aktie verschieben. Eine Oracle-Grenze lockern. Ein Asset irgendwohin senden außer dorthin, wohin der Contract es sendet. Irgendetwas abheben. Wählen, wer einen Airdrop erhält oder wie viel er umfasst, oder sich selbst einen Anteil zuweisen.

Sein Auslösen ist reserviert, um Sandwiching zu verhindern, nicht weil dem Keeper vertraut wird: Jeder Aufruf, den er macht, wird innerhalb der Grenzen der Vaults ausgeführt.

Der Zyklus

flowchart TD S[Täglicher Zyklus, nach 13:00 UTC] --> C{Börse geöffnet?

NYSE-Kalender} C -->|nein| W[Warten] C -->|ja| P{Contract pausiert?} P -->|ja| W P -->|nein| A{Erste Prüfung des Vaults

in diesem Zeitfenster: ≥ 0,1 ETH?} A -->|nein, das ETH wartet

auf das nächste Zeitfenster| N[Nächster Markt] A -->|ja| E[ETH → USDC, Grenze 50 bps] E --> B[USDC → USDG → Bridge] B --> R{Auf der Remote-Chain angekommen?} R -->|nein| M[Überwachen, Ticket erneut ausführen] R -->|ja| K[Aktien kaufen, Grenze 200 bps] K --> AD[An den Airdrop-Contract senden] AD --> N

Die Uhrzeit, die Schwelle und die Grenzen im Diagramm sind die Standardeinstellungen. Der Keeper macht alle fünf Minuten einen Durchlauf; das ETH eines Vaults wird einmal pro Zeitfenster geprüft, bei seinem ersten Durchlauf nach dem Schließen, während das USDC, das er bereits hält, einmal nach jeder Konvertierung und sonst höchstens einmal pro Zeitfenster weitergeht. Die Sendung an den Airdrop-Contract läuft einmal pro Zeitfenster, standardmäßig nach der Handelszeit; die Schulden, die LP-Gebühren, die Zustellungen und, seit der sechsten Audit-Schleife, die Tickets der kanonischen Rail werden in jedem Zyklus behandelt, unabhängig von der Handelszeit.

Seine Konfiguration

Alles läuft über Umgebungsvariablen: RPCs für beide Chains, der Private Key des Keepers, Contract-Adressen, Intervall und die Sicherheitshebel — Dry Run, einmaliger Durchlauf, geöffnete Börse erforderlich. Seit dem 2026-10-05 außerdem: die Variablen des Airdrop-Schritts, oben; die Einsammlung der LP-Gebühren, KEEPER_COLLECT_FEES (standardmäßig an), KEEPER_COLLECT_FEES_HOURS (24) und KEEPER_COLLECT_FEES_MIN_WEI (0); der Alert nach wiederholtem Auslassen, KEEPER_BRIDGE_ALERT_AFTER_SKIPS (3); und der Ordner der Zustandsdatei, KEEPER_STATE_DIR. Seit dem 2026-10-06 KEEPER_CONVERT_ONCE_PER_WINDOW (standardmäßig an): Das ETH eines Vaults wird einmal pro Zeitfenster konvertiert, und seit der sechsten Audit-Schleife geht sein USDC einmal nach jeder Konvertierung und sonst höchstens einmal pro Zeitfenster; ein lokaler oder Testnet-Lauf schaltet es ab und konvertiert, kauft und bridgt bei jedem Durchlauf. Seit der sechsten Audit-Schleife außerdem KEEPER_TICKET_ALERT_HOURS (6): auf der kanonischen Rail die Stunden, nach denen ein Ticket, das nicht als ausgeführt bekannt ist, gemeldet wird. KEEPER_STOCK_ROUTER, der Router, den die Factory für neue Vaults benennt, bestimmt nur, welche Handelszeit einen Zyklus freigibt; jeder Vault wird auf seinem eigenen Router bepreist.

Seit der siebten Audit-Schleife werden die Chain-Kennungen, KEEPER_CHAIN_ID und KEEPER_REMOTE_CHAIN_ID, vor dem ersten Zyklus gegen die RPCs geprüft: 1 mit 4663 auf dem Mainnet, 11155111 mit 46630 auf dem Testnet. Seit der achten Audit-Schleife müssen beide gesetzt sein: KEEPER_CHAIN_ID immer, KEEPER_REMOTE_CHAIN_ID mit der Bridge, und der Keeper verweigert ohne sie den Start (bis dahin las sich, wenn sie fehlten, KEEPER_CHAIN_ID als 11155111 und KEEPER_REMOTE_CHAIN_ID als 4663). Seit der zehnten Audit-Schleife begrenzt KEEPER_LOG_MAX_SELECTORS (standardmäßig 1.000, mindestens 5) die Adressen und Event-Werte, die eine Log-Anfrage nennt, so gezählt, wie die Nodes von Robinhood Chain sie zählen; hinter dem öffentlichen Endpoint von Sepolia, der zehn Adressen oder mehr ablehnt, ist sie auf 10 gesetzt. Zwei Variablen sagen, wie weit unter dem neuesten Block seine Log-Suchen anhalten: KEEPER_LOG_LAG_BLOCKS (2, auf Ethereum) und KEEPER_REMOTE_LOG_LAG_BLOCKS (12, auf Robinhood Chain); seit der achten Audit-Schleife ist die erste auch, wie tief der Block eines Bridge-Batches liegen muss, bevor der Keeper ihn verfolgt, und die zweite, wie weit unter dem neuesten Block ein Ticket gelesen wird. Die Schutzmechanismen des Oracles brauchen keine Variable: Der Keeper liest sie auf dem Oracle jedes Spiegel-Vaults. Eine leer gelassene ganzzahlige Variable nimmt ihren Standardwert, und eine außerhalb ihres Bereichs stoppt den Keeper beim Start.

Der Key des Keepers ist ein Hot Key, nur mit Gas finanziert und verschieden von dem des Deployers.

Seine Grenzen

  • Auf der USDG-Rail erscheint eine Zustellung, die der Cash-Token verweigert hat, bevor der Keeper startete, oder während er angehalten war, nur als Warnung, wenn er den Sweep ausführt; die kanonische Rail findet einen solchen Anteil im eigenen Zustand des Remote-Hubs
  • Bis zur neunten Audit-Schleife führte der Keeper den letzten Schritt einer fehlgeschlagenen Zustellung (lzCompose) nicht selbst aus; seitdem führt er einen festhängenden Schritt erneut aus, begrenzt, und ein zweiter Fehlschlag wird einem Menschen überlassen, mit dem Befehl
  • Die Notfall-Überwachung behält ihre Position über einen Neustart hinweg nicht: Events, die emittiert wurden, während der Keeper angehalten war, werden nicht gescannt
  • Ein Keeper, der in den wenigen Millisekunden zwischen einer Sendung und ihrem Schreiben in die Zustandsdatei beendet wird, kann diese Transaktion bei seinem Neustart ein weiteres Mal senden; die eigenen Prüfungen der Contracts lassen die meisten solcher Wiederholungen fehlschlagen, auf Kosten ihres Gases
  • Die Suche eines Transfers nach seiner Ankunft liest einen Block nie zweimal: Eine Reorganisation, die eine Ankunft in einen bereits gelesenen Block verschiebt, überlässt diesen Transfer dem Transit-Alert. Seit der siebten Audit-Schleife hält jede Log-Suche einige Blöcke unter dem neuesten an, was eine Gutschrift, und ihren Transit-Alert, um diese wenigen Blöcke verzögert
  • Seit der achten Audit-Schleife wird ein Bridge-Batch verfolgt, sobald sein Block einige Blöcke tief liegt, einen Zyklus später als zuvor, und der nächste Batch wartet auf ihn; eine tiefere Reorganisation ist nicht abgedeckt, wie bei den Log-Suchen. Ein in den letzten wenigen Blöcken ausgeführtes Ticket liest sich dort noch als lebend, bis der neueste Block ebenso viele Blöcke über seine Ausführung hinaus ist: der nächste Zyklus auf einer belebten Chain, mehr Zyklen auf einer ruhigen. Seit der neunten Audit-Schleife wird eines, das die eigene erneute Ausführung des Keepers gelöscht hat, unterdessen weder erneut ausgeführt noch gemeldet, auch nach einem Neustart; eines, das jemand anderes in diesen Blöcken erneut ausgeführt hat, wird erneut versucht, scheitert in der Simulation und kann nach Ablauf der Alert-Stunden noch als lebend gemeldet werden
  • Die Minute, während der der Keeper am Block seiner eigenen letzten Transaktion liest, deckt keinen Node ab, der mehr als eine Minute hinter seinen Peers liegt
  • Auf der lokalen Rail wird die Eröffnung des Zeitfensters einmal gezählt, ohne das, was die zweite Transaktion wiederholt (rund 5 % der Kosten): Eine Sendung kann gehen, die bis zu so viel weniger wert ist, als sie kostet
  • Seit der zehnten Audit-Schleife geht eine Aktie, die einem Vault nach Handelsschluss außerhalb eines Kaufs gegeben wird, mit der Sendung der nächsten Handelszeit in ein späteres Zeitfenster: Der Keeper liest einen Vault, der nichts zu senden hat, erst in der nächsten Handelszeit wieder. Ein Kauf, dessen Receipt der Keeper im letzten Durchlauf der Handelszeit gelesen hat, könnte im ersten Durchlauf nach Handelsschluss auch von einem Node, der hinter diesem Lesen zurückliegt, als leer gelesen werden, was ein Durchlaufintervall erfordert, das kürzer ist als der Rückstand dieses Nodes (etwa fünf Sekunden auf Sepolia), nie die standardmäßigen fünf Minuten

Preflight

Vor jedem echten Lauf prüft ein Preflight-Befehl, ohne eine einzige Transaktion zu schreiben, dass die Netzwerke antworten, dass die Adressen Code tragen, dass die LayerZero-Peers des USDG-OFT übereinstimmen, dass USDG nicht von seinem Emittenten, Paxos, pausiert ist und dass die Basket-Gewichtungen so sind, wie sie sein sollen.

Seit der achten Audit-Schleife prüft er auch die Schutzmechanismen des Oracles. Sein Manifest muss angeben, wie die Sequencer-Prüfung eingestellt ist, so oder so: kein Uptime-Feed und keine Karenzzeit (die Prüfung aus, wie heute) oder ein Feed mit einer Karenzzeit. Er liest diesen Feed, wenn es einen gibt, und die Oracle-Pause des Tokens jeder Aktie: Ein Token in einer Kapitalmaßnahme ist eine Warnung, die die Prüfung nicht fehlschlagen lässt; ein Token ohne das Signal schlägt fehl. Nach dem Deployment prüft er, dass das deployte Oracle dem Manifest entspricht, dass sein Sequencer-Zustand Preise durchlässt und dass die Pause-Prüfung jeder Aktie an ist. Der Befehl inspect des Keepers gibt dieselben Schutzmechanismen aus: die Sequencer-Prüfung und ihren Zustand sowie die Pause-Prüfung jeder Aktie und ob ihr Token gerade pausiert.

Seit der neunten Audit-Schleife läuft er auch auf dem Deployment des LayerZero-Testnet-Laufs (Sepolia und das Testnet von Robinhood Chain), anhand der zwei Dateien dieses Laufs, mit RPCs, die für dieses Paar benannt sind, sodass ein Mainnet-RPC nie zum Testnet befragt wird; jedes andere Chain-Paar, eine Mischung eingeschlossen, wird abgelehnt. Auf dem Testnet liest er keinen Uniswap-v3-Router, den diese Chain nicht hat, und misst den ETH/USD-Feed an dem Heartbeat, den das Oracle des Laufs erhalten hat. Auf beiden Paaren prüft er, dass der Remote-Router den v3-Router benennt, den das Manifest angibt. Auf dem Testnet-Deployment ausgeführt: 68 Prüfungen, alle bestanden.

Er verweigert den Lauf ohne RPCs, statt einen falschen Erfolg zu melden.