05 / PRÜFENNUMMERIERTER TESTPLAN

Manueller Testplan auf Sepolia

Diese Seite ist eine von Hand ausführbare Checkliste für das Sepolia-Testnetz, gedacht für eine Person mit einem Wallet. Jeder Fall trägt eine feste Nummer der Form T-01, die in einem Bericht zitiert werden kann.

Bevor Sie beginnen. Dieser Plan bezieht sich auf die neue Version. Das öffentliche Manifest des Repositorys beschreibt das im Einsatz befindliche Sepolia-Deployment mit LP-Gebühren 100: Dieser Plan gilt dafür. Ein Fall, der auf die getestete Version nicht zutrifft, wird als „außerhalb des Versionsumfangs“ vermerkt, niemals als „Fehlschlag“.

Die genannten Werte stammen aus dem Code der neuen Version unter contracts/src/ und aus den Designentscheidungen vom 14. September 2026. Ein Verhalten, das nicht ermittelt werden konnte, ist mit „beim Test zu bestätigen“ markiert.

So verwenden Sie diesen Plan

Jeder Abschnitt stellt seine Fälle in einer Tabelle mit sechs Spalten dar. Die letzten beiden werden während der Abnahme ausgefüllt.

Spalte Was dort eingetragen wird
Fall Die feste Kennung, T-01 bis T-110
Vorbedingungen Was vor dem Beginn zutreffen muss
Schritte Die Aktionen in ihrer Reihenfolge
Erwartetes Ergebnis Was Code und Entscheidungen vorsehen
Beobachtetes Ergebnis Was geschehen ist, mit Transaktionshash oder Abfrageblock
Schweregrad Leer, wenn konform; sonst Blockierend, Schwerwiegend, Geringfügig oder Kosmetisch
Schweregrad Kriterium
Blockierend Verlust oder Blockierung von Mitteln, nicht erhobene Steuer, verlorene Wall, aus dem Kapital gezahlte Belohnung
Schwerwiegend Verhalten entgegen den Quellen, fehlende Ablehnung, falsch angezeigte Zahl
Geringfügig Anzeigeabweichung ohne Folgen auf der Blockchain, ungenaue Meldung
Kosmetisch Typografie, Layout, Beschriftung

Eine gemäß einem Ablehnungsfall abgelehnte Transaktion ist ein Erfolg. Ein Hash bedeutet nur, dass die Transaktion eingereicht wurde: Nur der Beleg gibt Auskunft über den Erfolg.

Manche Fälle laufen nicht über die Oberfläche. In ihren aktuellen Quellen liest die dApp die ABI der im Einsatz befindlichen Version und stellt weder Aufträge mit exakter Ausgabe noch claimTeam() noch die detaillierten Abfragen der Walls bereit. Diese Fälle sind als „Direktaufruf“ markiert: Sie werden mit einem Werkzeug für Vertragsaufrufe auf den Adressen aus dem Manifest des getesteten Deployments ausgeführt.

1. Vorbereitung

Erfassen Sie diese Elemente vor dem ersten Swap: Sie dienen als Referenz für alle späteren Vergleiche.

  • Das Netzwerk: Sepolia, Chain-ID 11155111.
  • Die Adressen des getesteten Deployments, aus seinem Manifest gelesen: Token, Hook, PoolManager, poolId, Router, Lens, V2-Registry, Vault, Launcher; dann, sobald das Launchpad hinzugefügt ist, Governance-Vault und Forge. Kopieren Sie keinen privaten Schlüssel in Ihre Notizen.
  • Die festgeschriebenen Parameter: fee, tickSpacing, LAUNCH_ETH, MIN_POOL_SUPPLY, launchTimestamp, moduleRevision.
  • Der Anfangszustand: snapshot() des Lens, band() des Hooks, totalSupply() und totalBurned() des Tokens, pendingFloorEth, pendingAbsorbedTokens, wallCount(), activeWallCount(), teamAccrued, teamPaidCumulative, rewardReserve() des Vaults und die Blocknummer der Abfrage.

Planen Sie Test-ETH zusätzlich zu den getauschten Beträgen ein: Jede Transaktion zahlt ihr Gas, und mehrere Fälle erfordern abgelehnte Transaktionen, die ebenfalls Gas verbrauchen.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-01 Wallet installiert Sepolia auswählen; die mit der getesteten Version verbundene dApp öffnen Das Netzwerk wird erkannt; keine Aufforderung, auf einer anderen Blockchain zu signieren
T-02 Neues Konto Über einen Sepolia-Faucet mit Test-ETH ausstatten Guthaben nach Aktualisierung im Wallet und in der dApp sichtbar
T-03 Manifest liegt vor Jede angezeigte Adresse mit der im Manifest vergleichen Identitäten stimmen überein; poolId, fee und tickSpacing passen zusammen
T-04 Noch kein Swap ausgeführt snapshot() lesen und den Block notieren Referenzwerte festgehalten, Block identifiziert
T-05 Direktaufruf poolKey() des Hooks lesen currency0 gleich der Nulladresse, fee = 100, tickSpacing = 10, hooks gleich dem Hook
T-06 V2-Registry lesbar moduleRevision() und die Moduladressen lesen Revision notiert; jede Änderung während der Abnahme erfordert eine erneute Prüfung vor jeder Signatur

2. Start und Band

Bei der Initialisierung des Pools platziert der Hook seine gesamte Einlage in einer einzigen Position [minUsableTick, tickUpper], identifiziert durch BAND_SALT. tickUpper ist der auf den Abstand abgerundete Eröffnungstick, sodass die Position nur CUBIT enthält. Der Hook lehnt eine Einlage unterhalb von MIN_POOL_SUPPLY, also 80 % des Angebots, ab und verbrennt den Rundungsstaub.

Der vollständige Start überträgt außerdem 20 % des Angebots an die Reserve des Vaults und tätigt in derselben Transaktion einen Kauf über 0,1 ETH.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-07 Start erfolgt, Direktaufruf band() lesen lower = −887 270; upper gleich dem auf das Vielfache von 10 abgerundeten Eröffnungstick, also 155 390 bei einer FDV von 3,75 ETH; Liquidität ungleich null
T-08 Starttransaktion bekannt Ihre Ereignisse lesen BandBootstrapped(lower, upper, liquidity, tokens) einmal emittiert, mit den Werten von band(); tokens gleich der Einlage abzüglich Rundungsstaub
T-09 Start ohne anfänglichen Kauf bandEth und bandTokens in snapshot() vor jedem Swap lesen bandEth = 0; bandTokens gleich der Einlage, bis auf Rundungen
T-10 Start erfolgt, Direktaufruf token.balanceOf(hook) lesen Null, abgesehen von direkten Übertragungen Dritter: Der Hook behält nach der Initialisierung keine rohen CUBIT
T-11 Direktaufruf Versuchen, dem Pool Liquidität hinzuzufügen Ablehnung ExternalLiquidityForbidden: Der Hook ist der einzige Liquiditätsanbieter
T-12 Probe-Deployment Den Pool mit einer Einlage unterhalb von MIN_POOL_SUPPLY initialisieren Ablehnung SupplyNotDeposited; kein Band platziert
T-13 Vollständiger Start rewardReserve() des Vaults nach der Starttransaktion lesen Reserve gleich 20 % des Angebots, also 4,2 Millionen CUBIT; keine Teamzuteilung und kein Airdrop
T-14 Vollständiger Start Den Kauf des Deployers in der Starttransaktion lesen Kauf über 0,1 ETH; BuyTaxed mit 3 % für das Team; erhaltene CUBIT frei übertragbar
T-15 Kauf bestätigt, Direktaufruf Die erwartete Ausgabe aus den virtuellen Reserven des Bandes neu berechnen Ausgabe konsistent mit der x·y=k-Kurve nach Steuer von 3 % und LP-Gebühren; zu Beginn 16,8 Millionen CUBIT gegenüber 3 virtuellen ETH — beim Test zu bestätigen
T-16 Kauf und anschließender Verkauf der gekauften CUBIT bandEth davor, dazwischen und danach lesen bandEth steigt beim Kauf und kehrt dann zu seinem Ausgangswert zurück; es übersteigt nie die tatsächlich durch Käufe eingebrachten ETH

3. Kauf- und Verkaufsabläufe

Der Router stellt swapExactIn(key, zeroForOne, amountIn, amountOutMin, recipient, deadline) und swapExactOut(key, zeroForOne, amountOut, amountInMax, recipient, deadline) bereit. zeroForOne = true kauft CUBIT mit ETH.

In den aktuellen Quellen der dApp verwendet die Oberfläche nur die exakte Eingabe. Der Nutzer gibt immer den Betrag ein, den er zahlt; die erhaltene Menge ist ein schreibgeschütztes Feld. Abläufe mit exakter Ausgabe müssen daher per Direktaufruf des Routers getestet werden.

Ein Kauf sendet native ETH als msg.value. Ein Verkauf sendet den Wert null und erfordert eine ERC-20-Freigabe der CUBIT an den Router: Die Oberfläche fordert eine Genehmigung über den exakten Betrag an, nie unbegrenzt, sodass ein größerer Verkauf eine neue Genehmigung verlangt.

Der Router lehnt Teilausführungen ab: Eine nicht vollständig verbrauchte exakte Eingabe löst IncompleteInput aus, eine nicht vollständig erfüllte exakte Ausgabe löst InsufficientOutput aus. Da die Steuer auf den angeforderten Betrag bemessen wird, schützt der Abbruch den Nutzer.

Aus den Quellen der dApp gelesene Einstellungen der Oberfläche, während der Abnahme zu prüfen: Slippage-Toleranz standardmäßig 1,0 %, Eingabe auf zwei Dezimalstellen und den Bereich 0 bis 99,99 begrenzt; Mindestempfang in Ganzzahlen berechnet und auf den nächsten Wei aufgerundet; Quotierung 30 Sekunden aktuell; On-Chain-Frist = Zeitstempel der Blockchain plus 120 Sekunden minus Alter der Quotierung.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-17 Ausreichendes ETH-Guthaben Einen kleinen Betrag kaufen, zum Beispiel 0,001 ETH Erfolgreicher Beleg; CUBIT gutgeschrieben; Ereignis BuyTaxed emittiert
T-18 Hohes ETH-Guthaben Einen hohen Betrag kaufen Erfolgreicher Beleg; die Preiswirkung zeigt sich in der Quotierung, nicht im Steuersatz
T-19 CUBIT im Wallet Freigeben, dann verkaufen Zwei getrennte Transaktionen; Netto-ETH erhalten; SellTaxed emittiert
T-20 Vorheriger Verkauf bestätigt Einen größeren Betrag als zuvor verkaufen Eine neue Genehmigung wird angefordert: Die Freigabe galt dem exakten Betrag
T-21 Swap-Bildschirm geöffnet Die vorgeschlagene Toleranz ablesen, ohne sie zu ändern Standardwert 1,0 %
T-22 Swap-Bildschirm geöffnet 0.005, dann 100, dann einen negativen Wert eingeben Eingaben abgelehnt, mit einer Meldung zum Bereich 0–99,99 und zu den zwei Dezimalstellen
T-23 Aktuelle Quotierung Die Toleranz auf ihren niedrigsten akzeptierten Wert setzen, eine Preisbewegung abwarten, dann signieren Ablehnung TooLittleReceived(received, minimum); kein Token verloren; die Oberfläche fordert nicht dazu auf, den Schutz zu entfernen
T-24 Quotierung angezeigt Mehr als 30 Sekunden ohne Aktion verstreichen lassen, dann signieren wollen Die Quotierung gilt als veraltet und wird vor jeder Signatur neu berechnet
T-25 Quotierung fast veraltet Kurz vor dem Ablauf signieren und die übermittelte Frist ablesen Die Frist beträgt 120 Sekunden minus das Alter der Quotierung: Eine 30 Sekunden alte Quotierung lässt etwa 90 Sekunden
T-26 Direktaufruf swapExactIn mit einer bereits abgelaufenen Frist aufrufen Ablehnung Expired; keine Mittelbewegung
T-27 Direktaufruf swapExactOut für einen Kauf mit großzügiger Eingabeobergrenze aufrufen Exakte Menge erhalten; ETH-Überschuss in derselben Transaktion an den Aufrufer erstattet
T-28 Direktaufruf swapExactOut mit einer Eingabeobergrenze aufrufen, die einen Wei unter dem erforderlichen Betrag liegt Ablehnung TooMuchRequested(required, maximum)
T-29 CUBIT-Guthaben größer als das, was Band und Walls zurückkaufen können, zum Beispiel als Belohnung erhaltene CUBIT Dieses Guthaben mit exakter Eingabe über den Router verkaufen Ablehnung IncompleteInput; die Steuer wird mit der Transaktion rückgängig gemacht — beim Test zu bestätigen
T-30 Direktaufruf Mit exakter Ausgabe mehr ETH anfordern, als das Buch bedienen kann Ablehnung InsufficientOutput; keine Teilabrechnung
T-31 Direktaufruf Nacheinander einen Betrag null, einen Nullempfänger, einen inkonsistenten Wert msg.value und dann einen anderen Poolschlüssel senden Jeweilige Ablehnungen InvalidAmount, ZeroRecipient, WrongValue, WrongPool
T-32 Kompatibler Drittanbieter-Router Über eine Drittanbieter-Route kaufen und dann verkaufen Die Hook-Steuern gelten
T-33 Aufrufvertrag oder Transaktionsbündel Einen Kauf und dann einen Verkauf in derselben Transaktion ausführen Beide Teile werden getrennt besteuert

4. Steuern und Buchhaltung

Vorgang Grundlage Verteilung
Kauf 3 % des Brutto-ETH-Anteils 100 % Teamanteil; die Zuweisung an die Walls ist ausdrücklich null
Verkauf 15 % der Brutto-ETH-Ausgabe 12 % an die Walls, 3 % an das Team

Bei exakter Eingabe ist die Kaufsteuer im bereitgestellten Betrag enthalten und auf den nächsten Wei aufgerundet. Bei exakter Ausgabe kommt sie zum Pool-Anteil hinzu, sodass die auf die Gesamtsumme bezogene Steuer 3 % bleibt.

Bei einem Verkauf mit exakter Ausgabe beträgt die Steuer ceil(sortie × 1500 / 8500): Der Pool erzeugt die angeforderte Ausgabe plus die Steuer. Bei einem Verkauf mit exakter Eingabe beträgt sie ceil(brut × 15 %). Bei der Verteilung wird der Teamanteil abgerundet, und der gesamte Rest in Wei geht an die Walls.

In den aktuellen Quellen der dApp verlangt die Oberfläche, diese Sätze auf der Blockchain abzufragen, bevor sie einen Swap zulässt: Solange sie nicht geprüft sind, bleibt die Schaltfläche im Wartezustand.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-34 Kauf bestätigt BuyTaxed(ethIn, toFloor, toTeam) lesen toFloor ist null; toTeam beträgt 3 % der Bruttoeingabe, auf den nächsten Wei aufgerundet
T-35 Kauf bestätigt teamAccrued davor und danach vergleichen Anstieg gleich dem Teamanteil
T-36 Verkauf bestätigt SellTaxed(ethOut, toFloor, toTeam) lesen toFloor + toTeam ergibt 15 % des Bruttobetrags; toTeam beträgt 3 % des Bruttobetrags; die Summe ist auf den Wei genau
T-37 teamAccrued ungleich null, Direktaufruf claimTeam() von einem beliebigen Konto aufrufen Die Mittel gehen an die festgeschriebene Teamadresse; TeamPaid(amount, cumulative) emittiert; teamAccrued auf null zurückgesetzt
T-38 teamAccrued gleich null, Direktaufruf claimTeam() aufrufen Der Aufruf schlägt nicht fehl und überträgt nichts
T-39 Ein Kauf und dann ein Verkauf desselben Betrags Anfangs- und End-ETH ohne Gas vergleichen Der erhaltene Faktor nähert sich 0,97 × 0,85 = 0,8245; die Abweichung erklärt sich durch LP-Gebühren, Preiswirkung und Rundungen
T-40 Zwei Verkäufe sehr unterschiedlicher Größe Die Steuern im Verhältnis zu den Bruttobeträgen vergleichen Der Satz bleibt in beiden Fällen 15 %; keine Staffelung und keine Befreiung

5. Automatische Walls

Bei jedem Verkauf, mit exakter Eingabe wie mit exakter Ausgabe, ruft der Hook _collectCrossedWalls() und danach _placeWall() auf. Er leert zuerst alle Walls, die der Preis vollständig durchlaufen hat, von der nächstgelegenen bis zur entferntesten, und platziert dann alle wartenden ETH am Ziel 0,4 × prix courant + 0,6 × prix de lancement, das anhand des Preises nach dem Verkauf berechnet und auf den Tick gerundet wird. Liegt dieses Ziel nicht strikt oberhalb des Pool-Ticks, was auf oder unter dem Startpreis geschieht, wird die Wall 1 % unter dem aktuellen Preis platziert.

Eine geleerte Wall fügt ihre CUBIT zu pendingAbsorbedTokens hinzu und gibt ihre restlichen ETH, Gebühren und Staub, an pendingFloorEth zurück. Eine nur teilweise aufgebrauchte Wall bleibt bestehen. Nur ein Betrag, der zu klein ist, um Liquidität zu erzeugen, und der Extremfall eines Preises ganz oben im Tick-Bereich, wo keine Wall unter den Preis passt, lassen Mittel in pendingFloorEth warten: Der Verkauf wird deswegen nie abgelehnt. Der CUBIT-Router ruft anschließend deliverAbsorbed() in einem try/catch auf.

Die Referenz floorPrice() des Lens beschreibt die zuletzt finanzierte Wall, kein globales Minimum. Jede durchlaufene Wall kostet etwa 185 000 Gas: Innerhalb des Limits von 16 777 216 Gas einer Transaktion durchläuft ein Verkauf höchstens etwa 88 Walls.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-41 Preis oberhalb des Startpreises Verkaufen, dann die Walls lesen WallFunded(id, lower, addedEth, liquidity) emittiert; mit den wartenden ETH, darunter den 12 % des Verkaufs, wird am Ziel-Tick eine Wall erstellt oder verstärkt, bis auf Rundungen; pendingFloorEth behält nur den nicht platzierten Restbestand
T-42 Vorherige Situation Das Ziel aus dem Preis nach dem Verkauf und dem Startpreis neu berechnen Der Wert lower der Wall entspricht dem mit diesem Preis berechneten 40/60-Ziel, auf den Tick gerundet
T-43 Zwei Verkäufe, deren Ziel auf denselben Tick fällt wallCount() und walls(id) lesen Eine einzige Wall: Beide Ereignisse WallFunded tragen dieselbe id, die Liquidität steigt, keine neue Kennung wird erstellt
T-44 Mehrere Walls an verschiedenen Ticks Mehrmals verkaufen und kaufen, dann walls(id) erneut lesen Der Wert lower jeder Wall bleibt unverändert; keine Wall wird verschoben
T-45 Aktive Wall unterhalb des Preises Einen Betrag verkaufen, der die Wall teilweise aufbraucht, ohne sie zu durchlaufen Die Wall bleibt aktiv, mit ETH und CUBIT; kein WallAbsorbed; pendingAbsorbedTokens unverändert
T-46 Teilweise aufgebrauchte Wall Kaufen, bis der Preis wieder über der Wall liegt Die Wall hat ihre CUBIT verkauft und wieder ETH erhalten; ihre Kennung und ihr Tick sind unverändert
T-47 Aktive Wall, Verkauf über den CUBIT-Router Einen Betrag verkaufen, der die Wall vollständig durchläuft WallAbsorbed(id, cubit, ethRemaining) und TokensAbsorbed(amount, pendingAbsorbedTokens), dann AbsorbedDelivered(sink, amount) und RewardReserveFunded in derselben Transaktion; rewardReserve() steigt um diese CUBIT; pendingAbsorbedTokens fällt auf null zurück; totalSupply() und totalBurned() sind unverändert
T-48 Preis nahe dem Startpreis, 40/60-Ziel nicht unter dem Markt Einen kleinen, bedienbaren Betrag verkaufen, dann die Walls lesen Der Verkauf gelingt; WallFunded emittiert; die Wall wird 1 % unter dem Preis nach dem Verkauf platziert, auf den Tick gerundet; pendingFloorEth behält nur den nicht platzierten Restbestand
T-49 Situation aus T-48 Erneut einen kleinen, bedienbaren Betrag verkaufen, dann pendingFloorEth lesen WallFunded 1 % unter dem neuen Preis emittiert; pendingFloorEth behält nur Rundungsstaub: Von einem Verkauf zum nächsten sammelt sich kein Rückstand an
T-50 Kompatibler Drittanbieter-Router Über eine Drittanbieter-Route verkaufen und dabei eine Wall vollständig durchlaufen, dann deliverAbsorbed() von einem beliebigen Konto aufrufen Steuern angewandt; TokensAbsorbed emittiert, und die CUBIT bleiben bis zum Aufruf, der AbsorbedDelivered emittiert, in pendingAbsorbedTokens
T-51 Mehrere finanzierte Walls floorPrice() und netFloorPrice() des Lens lesen, dann wallAmountsPage(0, 500) und die folgenden Seiten bis activeWallCount, alle im selben Block Referenz der zuletzt finanzierten Wall, als solche dargestellt; die CUBIT der Walls sind die Summe der Seiten plus pendingAbsorbedTokens, genau einmal addiert
T-52 Forge-Kindmarkt, vollständig durchlaufene Wall absorbedTokenSink() des Kind-Hooks lesen, dann die Ereignisse des Verkaufs Empfänger gleich governanceVault() der Forge; AbsorbedDelivered emittiert; Tranche Deposited(token, from, amount, unlockAt) 30 Tage gesperrt
T-106 Viele in einem Verkauf zu durchlaufende Walls Den Gasbedarf des Verkaufs schätzen, dann den Verkauf senden Etwa 185 000 Gas pro durchlaufener Wall; bei mehr als etwa 88 Walls überschreitet der Verkauf 16 777 216 Gas und schlägt ohne Verlust fehl: den Verkauf aufteilen
T-107 Probe-Deployment, dessen CUBIT-Empfänger die Übertragung ablehnt Über den CUBIT-Router verkaufen und dabei eine Wall durchlaufen, dann deliverAbsorbed() erneut aufrufen Der Verkauf gelingt; die CUBIT bleiben in pendingAbsorbedTokens; der Aufruf steht jedem Konto offen und schlägt fehl, solange der Empfänger ablehnt

6. mCUBIT Vault

Der Vault zahlt eine Belohnung in CUBIT, die ausschließlich aus rewardReserve entnommen wird. Sie beträgt DAILY_REWARD_BPS = 300, also 3 % der Einlage pro Zeitraum von 24 Stunden (REWARD_PERIOD), anteilig berechnet und auf einen Zeitraum gedeckelt: Darüber hinaus verfällt der Überschuss. Sie übersteigt nie den Saldo der Reserve und wird nie aus dem Kapital gezahlt.

Jede Einlage startet eine Sperre von 24 Stunden (LOCK_DURATION) für die gesamte Position des Wallets neu; eine Auszahlung vor Ablauf wird mit Locked abgelehnt. Eine Einlage, eine Auszahlung oder ein Abruf zahlt zuerst die erworbene Belohnung aus und startet den Zeitraum neu. Jedes Konto kann die Reserve mit fundRewardReserve(amount) speisen. Der Ablauf richtet sich nach dem Zeitstempel der Blockchain, nicht nach der Uhr des Browsers.

Die Belohnung wird ausschließlich in CUBIT gezahlt und mit claimCubit() abgerufen: Der Vault stellt keine Funktion für Belohnungen in WETH bereit.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-53 Vault verfügbar, CUBIT im Wallet Freigeben, dann hinterlegen Staked(user, amount, unlockAt) emittiert; unlockAt gleich dem Zeitstempel des Blocks plus 24 Stunden
T-54 Bestehende Position Vor Ablauf erneut hinterlegen Die Sperre wird für die gesamte Position neu gestartet; die erworbene Belohnung wird, sofern ungleich null, mit CubitRewardClaimed ausgezahlt, und der Zeitraum startet neu
T-55 Sperre läuft Eine Auszahlung anfordern Ablehnung Locked
T-56 Sperre abgelaufen Einen Teil der Einlage auszahlen Teilauszahlung akzeptiert; Withdrawn emittiert; die erworbene Belohnung wird zuerst ausgezahlt; der verbleibende Saldo bleibt hinterlegt
T-57 Einlage von 1 000 CUBIT, ausreichende Reserve pendingCubit nach 12 Stunden und dann nach 24 Stunden lesen Etwa 15 CUBIT, dann 30 CUBIT
T-58 Vorherige Situation 48 Stunden ohne Abruf warten, dann pendingCubit lesen Weiterhin 30 CUBIT: Der zweite Tag verfällt
T-59 Erworbene Belohnung claimCubit() aufrufen CUBIT übertragen; CubitRewardClaimed emittiert; rewardReserve sinkt um den ausgezahlten Betrag; pendingCubit fällt auf null zurück
T-60 Probe-Deployment mit kleiner Reserve Eine Belohnung abrufen, die größer als die Reserve ist Nur der Saldo der Reserve wird ausgezahlt; die Reserve fällt auf null; das Kapital wird nicht angetastet
T-61 Direktaufruf fundRewardReserve(0) und dann nach Freigabe fundRewardReserve(x) von einem beliebigen Konto aufrufen Ablehnung InvalidAmount, dann RewardReserveFunded(from, x); rewardReserve steigt um x
T-62 Direktaufruf token.balanceOf(vault) zu mehreren Zeitpunkten mit totalStaked + rewardReserve vergleichen Das Guthaben des Vaults liegt nie unter dieser Summe
T-63 Betrag null, Direktaufruf stake(0) und dann withdraw(0) aufrufen Ablehnung InvalidAmount in beiden Fällen
T-64 Vault nicht an die aktuelle Registry angebunden Eine Einlage versuchen Ablehnung Inactive
T-65 Offene Position Die angezeigte Sperrdauer ablesen Anzeige in Stunden, abgeleitet aus LOCK_DURATION: 24 Stunden
T-66 dApp geöffnet Nach einem Ablauf für Belohnungen in WETH suchen Keiner: Nur die Belohnung in CUBIT wird angeboten

7. Governance-Vault des Launchpads

Der Governance-Vault erhält die Startgebühren der Forge in ETH und die von den Walls der Forge-Kindmärkte aufgenommenen Token. Jede Einlage ist 30 Tage gesperrt (LOCK_DURATION), gerechnet ab ihrem eigenen Eingang. Nur der Deployer kann abrufen, dauerhaft und ohne Möglichkeit, dieses Recht zu übertragen, und nur die Tranchen, deren Datum verstrichen ist, von der ältesten zur neuesten. ETH wird unter dem Schlüssel ETH(), der Nulladresse, verbucht. Lesen Sie die ABI des getesteten Deployments vor der Abnahme erneut. Der Deployer kann die Sperre aller bestehenden und künftigen Einlagen mit extendLock verlängern; lockExtension() wächst nur und wird zu jedem Datum addiert.

Die automatische Übertragung aus den Walls der Kindmärkte wird durch T-52 geprüft, die Einlage der Startgebühr durch T-81. Die Fälle T-67 bis T-73 hinterlegen Test-Token per Direktaufruf; T-108 ruft das ETH einer Gebühr ab.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-67 Test-Token, Direktaufruf Freigeben, dann deposit(token, amount) aufrufen Deposited(token, from, amount, unlockAt) emittiert; unlockAt gleich dem Zeitstempel des Blocks plus 30 Tage; held(token) steigt entsprechend
T-68 Einlage jünger als 30 Tage claim(token, n) vom Deployer aufrufen Ablehnung NothingToClaim
T-69 Entsperrte Tranche claim(token, n) von einem anderen Konto aufrufen Ablehnung NotDeployer
T-70 Eine Einlage pro Tag über 7 Tage Ab dem 30. Tag nach der ersten Einlage täglich abrufen Pro Tag wird eine Tranche ausgezahlt, von der ältesten zur neuesten; die letzte 30 Tage nach der siebten Einlage; Claimed(token, amount, tranches) bei jedem Abruf
T-71 Mehrere entsperrte Tranchen claim(token, 1) aufrufen Nur eine Tranche ausgezahlt; die nächste bleibt abrufbar
T-72 Per einfacher Übertragung gesendete Token lockUntracked(token) aufrufen und dann ohne neue Übertragung erneut aufrufen Neue Tranche, ab dem ersten Aufruf 30 Tage gesperrt; der zweite Aufruf wird mit NothingToLock abgelehnt
T-73 Gesperrte und entsperrte Tranchen claimable(token) und locked(token) lesen Der abrufbare Betrag plus der gesperrte Betrag ergibt held(token)
T-108 Startgebühr aus T-81 vor mehr als 30 Tagen eingezahlt claim(address(0), 1) von einem anderen Konto, dann vom Deployer aufrufen Ablehnung NotDeployer, dann ETH an den Deployer ausgezahlt; Claimed(address(0), amount, 1) emittiert; held(address(0)) sinkt um den ausgezahlten Betrag
T-109 Gesperrte Tranchen extendLock(extra) von einem anderen Konto, dann vom Deployer aufrufen Ablehnung NotDeployer, dann LockExtended(extra, lockExtension) emittiert; jedes mit tranche(token, i) gelesene Datum verschiebt sich um extra; keine Funktion verkürzt die Sperre

8. Forge

Die Forge ist ein öffentliches Launchpad, das als zukünftige Veröffentlichung vorgestellt wird. Sie ist nicht Teil des CUBIT-Starts: Sie wird danach zusammen mit ihrem Governance-Vault hinzugefügt. Notieren Sie ihre Adressen, sobald das Launchpad hinzugefügt ist.

Jedes Konto startet einen Kindmarkt gegen Zahlung der exakten Gebühr. Ein Forge-Kindmarkt hinterlegt sein gesamtes Angebot in seinem Band, die Forge erhält die Adresse des Governance-Vaults bei ihrer Erstellung, und jeder Start zahlt seine Gebühr von 0,005 ETH an diesen Vault, der sie behält: Der startende Account erhält sie nie zurück. Die Deployment-Salts sind an den startenden Account gebunden.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-81 Forge verfügbar, beliebiges Konto Einen Kindmarkt mit der exakten Gebühr von 0,005 ETH starten ChildLaunched(token, hook, launcher, team, fee) emittiert; BandBootstrapped des Kindmarkts zeigt eine Einlage gleich seinem gesamten Angebot, bis auf Rundungen; der Governance-Vault emittiert Deposited(address(0), forge, fee, unlockAt), mit unlockAt gleich dem Block-Zeitstempel plus 30 Tage und einer etwaigen Verlängerung; pendingFloorEth des übergeordneten Hooks unverändert
T-82 Forge verfügbar Einen Start mit falschem Wert, leerem Namen, Null-Team oder anderer Vorlage versuchen Ablehnung: wrong launch fee, invalid name, invalid team oder template mismatch
T-110 Salts eines Starts, von einem anderen Konto gesehen Von einem zweiten Konto mit denselben Salts starten Die Adressen des ersten Starts werden nicht übernommen: Die Salts sind an den startenden Account gebunden, und der zweite Start wird mit child deployment failed abgelehnt, wenn seine Hook-Adresse die Berechtigungen nicht trägt

9. Austausch und Befugnisse

Die Authority der Registry kann vier Peripherieadressen jederzeit ohne Verzögerung austauschen: Vault, Router, Lens und Forge. Jeder Austausch emittiert ModuleUpdated, erhöht moduleRevision und schließt die betroffene Funktion, bis das Team sie wieder öffnet: Vault, Momentum oder Forge; der Austausch des Routers schließt keine Funktion. Ein Kandidat, der bereits registriert ist, an einen anderen Hook oder Token angebunden ist oder bereits Stake hält, wird mit InvalidModule abgelehnt.

Der Hook hat keinen Administrator, und niemand kann die Swaps oder den Mechanismus der Walls pausieren. Die Teamadresse behält dauerhafte Befugnisse: Sie erhält den Teamanteil der Steuern und tauscht die Module der Registry aus, die sie anschließend aktiviert.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-83 Einlagen und Reserve im aktuellen Vault Den Vault austauschen Hinterlegte CUBIT, Belohnungsreserve und Fristen bleiben im alten Vault; keine Mittel verschoben
T-84 Vault ausgetauscht Im alten Vault abrufen, dann auszahlen, dann eine Einlage versuchen Abruf und Auszahlung bleiben verfügbar; die neue Einlage wird mit Inactive abgelehnt
T-85 Kandidat bereits registriert oder mit Stake Den Wechsel versuchen Ablehnung InvalidModule
T-86 Austausch erfolgt moduleRevision() und das Ereignis lesen; nach einem Austausch des Vaults eine Einlage in den neuen Vault versuchen Revision erhöht; ModuleUpdated(module, previous, current, revision) stimmt überein; die Einlage wird bis zur erneuten Aktivierung des Vaults mit Inactive abgelehnt
T-87 Freigabe an den alten Router erteilt Den Router austauschen, dann einen Verkauf versuchen Die alte Freigabe gilt nicht für den neuen Spender; eine neue Genehmigung wird angefordert
T-88 Router ausgetauscht Über den früheren Router tauschen Der Swap bleibt möglich und die Hook-Steuern gelten; die Dapp nutzt den neuen Router
T-89 Direktaufruf Die ABI des bereitgestellten Hooks untersuchen Keine Funktion erlaubt es, die Swaps oder den Mechanismus der Walls auszusetzen; der Hook hat keinen Administrator
T-90 Direktaufruf snapshot() des Lens lesen, dann die Wall-Seiten im selben Block Der Snapshot enthält nur Felder zu Markt, Band, Walls und Konten, das Gesamtangebot, die Belohnungsreserve, die Anzahl aktiver Walls, den Abfrageblock und die beste Wall: keine Wall-Summen, und seine Kosten hängen nicht von der Anzahl der Walls ab; das Umlaufangebot entspricht totalSupply abzüglich der CUBIT der Walls und rewardReserve, und die gehaltenen CUBIT sind dieses Angebot abzüglich bandTokens
T-91 Jederzeit nach dem Start Kaufen und verkaufen Die Swaps funktionieren normal: Kein Konto kann sie blockieren

10. Erwartete Ablehnungsfälle

Diese Tabelle dient während der gesamten Abnahme als Referenz. Die automatischen Walls fügen dem Verkauf keine Ablehnungen hinzu: Kann eine Wall nicht platziert werden, warten die Mittel, und nach einer fehlgeschlagenen Übertragung warten die CUBIT.

Achtung. In den aktuellen Quellen der dApp werden Vertragsfehler nicht übersetzt: Eine On-Chain-Ablehnung kann als rohe, in der Anzeige abgeschnittene Meldung erscheinen. Notieren Sie für jede ausgelöste Ablehnung den genau angezeigten Text und beurteilen Sie, ob er verständlich ist.

Fehler Was ihn auslöst Was die Anwendung zeigen sollte
ExternalLiquidityForbidden Hinzufügen von Liquidität durch Dritte Vorgang nicht möglich: Das Protokoll ist der einzige Liquiditätsanbieter
SupplyNotDeposited Initialisierung mit einer Einlage unter 80 % des Angebots Start nicht möglich, Einlage unzureichend
Expired Transaktionsfrist überschritten Quotierung abgelaufen, eine neue berechnen
TooLittleReceived(received, minimum) Ausgabe unter dem akzeptierten Minimum Slippage-Schutz ausgelöst
TooMuchRequested(required, maximum) Eingabe über der akzeptierten Obergrenze Schutz der Eingabeobergrenze ausgelöst
IncompleteInput Exakte Eingabe nicht vollständig verbraucht Betrag zu groß für die verfügbare Liquidität
InsufficientOutput Exakte Ausgabe nicht vollständig erfüllt Das Buch kann diese Ausgabe nicht bedienen
InvalidAmount, ZeroRecipient, WrongValue, WrongPool Ungültige Auftragsparameter oder an den Vault gesendeter Betrag null Eingabefehler, ohne rohen Code
Inactive, Locked Vault nicht an die aktuelle Registry angebunden oder Auszahlung vor Ablauf Modul nicht verfügbar oder Entsperrzeitpunkt
NotDeployer, NothingToClaim, NothingToLock, NothingToExtend Abruf oder Verlängerung beim Governance-Vault durch Dritte, Abruf vor Ablauf, Sperrung ohne neues Guthaben, Verlängerung um null Vorbehaltene Aktion, nichts abzurufen, nichts zu sperren oder nichts zu verlängern
NotAuthority, InvalidModule Austausch durch Dritte angefordert oder inkompatibler Kandidat Austausch abgelehnt, mit Begründung

Rein anwendungsseitige Ablehnungen werden ebenfalls erfasst: veraltete Quotierung, geänderter Swap-Kontext, Wallet auf einer anderen Blockchain, gewechseltes Konto, geänderte Modulrevision, noch nicht geprüfte Steuersätze.

11. Anwendung

Diese Fälle werden mit der dApp durchgeführt. Die genannten Verhaltensweisen der Oberfläche stammen aus ihren Quellen und werden während der Abnahme geprüft.

Fall Vorbedingungen Schritte Erwartetes Ergebnis Beobachtetes Ergebnis Schweregrad
T-92 dApp geöffnet Die zehn Sprachen der Sprachauswahl durchgehen Jede Sprache zeigt übersetzte Inhalte ohne fehlenden Text oder Überlauf; Produktnamen bleiben bewusst auf Englisch
T-93 Sprache gewählt Neu laden, dann das Fenster unter 640 px verkleinern Die Wahl bleibt von einer Sitzung zur nächsten erhalten; unter 640 px zeigt die Sprachauswahl nur noch die Flagge
T-94 Andere Sprache als Englisch Den Titel der Startseite mit der englischen Version vergleichen Der Titel ist außerhalb des Englischen bewusst gekürzt; er darf weder überlaufen noch abgeschnitten werden
T-95 Bildschirm von etwa 400 px Jeden Bildschirm durchgehen Kein horizontaler Überlauf; breite Bereiche scrollen in ihrem eigenen Container; die Schaltflächen bleiben erreichbar
T-96 Fenster zwischen 768 und 1279 px Die Navigation öffnen Das kompakte Menü wird bis 1279 px verwendet; es schließt sich nach der Navigation
T-97 Transaktion bestätigt Jeden angezeigten Betrag mit den On-Chain-Werten am selben Block vergleichen Die Beträge stimmen überein; Anzeigerundungen ändern den signierten Betrag nicht
T-98 Vorgang in Vorbereitung Mitten im Ablauf das Netzwerk im Wallet wechseln Die Quotierung wird ungültig und die Signatur außerhalb des erwarteten Netzwerks abgelehnt; die Schaltfläche bietet zuerst den Netzwerkwechsel an und verlangt dann eine zweite Aktion zum Tauschen
T-99 Vorgang in Vorbereitung Mitten im Ablauf das Konto im Wallet wechseln Guthaben, Genehmigung und Quotierung werden für das neue Konto neu berechnet; eine für das alte Konto vorbereitete Signatur wird abgelehnt
T-100 Genehmigung erteilt, Swap nicht signiert Die Modulrevision zwischen beiden Schritten ändern lassen Die Anwendung validiert den Kontext erneut und geht nicht stillschweigend zu einem neuen Spender über
T-101 RPC nicht verfügbar oder alte Abfrage Den Zugang zum RPC unterbrechen und beobachten Der Zustand wird als ungeprüft gemeldet, und die Aktionen werden deaktiviert
T-102 Transaktion gesendet Den Hash und dann den Beleg verfolgen Die Oberfläche unterscheidet „eingereicht“ und „erfolgreich“; die Ereignisse sind in einem Sepolia-Explorer überprüfbar
T-103 Eine On-Chain-Ablehnung ausgelöst Den angezeigten Text vollständig erfassen Die Meldung muss für einen Nutzer verständlich bleiben; jeden rohen technischen Code und jede abgeschnittene Meldung festhalten
T-104 Chinesisch, Koreanisch und Japanisch Diese Sprachen ohne Zugriff auf einen externen Schriftartendienst anzeigen Die Zeichen werden korrekt angezeigt: Die Schriftarten werden von der Website bereitgestellt
T-105 Proof-Bildschirm geöffnet Das Band, die Walls und die wartenden Mittel ablesen bandEth, bandTokens, die Walls, die wartenden ETH und die auf Übertragung wartenden CUBIT werden getrennt angezeigt; kein Bildschirm zeigt eine Ladder, Keeper oder einen Burn der Walls

12. Erfassungsbogen

Jede Tabelle der vorherigen Abschnitte ist der Erfassungsbogen ihres Abschnitts: Füllen Sie die Spalten „Beobachtetes Ergebnis“ und „Schweregrad“ Fall für Fall aus. Notieren Sie für das beobachtete Ergebnis mindestens den Transaktionshash oder den Abfrageblock und dann das Festgestellte.

Dem Bericht beizufügende Zusammenfassung:

Abschnitt Fälle Konform Abweichungen Höchster Schweregrad
1. Vorbereitung T-01 bis T-06
2. Start und Band T-07 bis T-16
3. Kauf und Verkauf T-17 bis T-33
4. Steuern und Buchhaltung T-34 bis T-40
5. Automatische Walls T-41 bis T-52, T-106 und T-107
6. mCUBIT Vault T-53 bis T-66
7. Governance-Vault T-67 bis T-73, T-108 und T-109
8. Forge T-81, T-82 und T-110
9. Austausch und Befugnisse T-83 bis T-91
10. Ablehnungsfälle Übergreifende Referenz
11. Anwendung T-92 bis T-105

Eine Abweichung bezieht sich auf die Nummer des Falls, niemals nur auf einen Screenshot. Fügen Sie Netzwerk, Adresse des Deployments, Block, Hash und Version der Anwendung bei.

Grenzen dieses Plans

Dieser Plan beschreibt, was der Code der neuen Version und die Entscheidungen vom 14. September 2026 vorsehen. Er stellt keine Validierung dar: Eine erfolgreiche Abnahme auf Sepolia ersetzt die Testkampagnen nicht.

Die Punkte „beim Test zu bestätigen“ müssen beobachtet und dann in diese Seite übernommen werden.

Quellen: contracts/src/CubitHook.sol, CubitLens.sol, interfaces/ICubitHook.sol, interfaces/ICubitLens.sol, libraries/BandLib.sol, libraries/WallLib.sol, periphery/CubitRouter.sol, CubitV2.sol, CubitVault.sol, CubitGovernanceVault.sol, CubitForge.sol, CubitLaunch.sol, die aktuellen Abläufe von dapp/src und die Designentscheidungen vom 14. September 2026, festgehalten in contracts/docs/REDESIGN_HANDOFF.md.

CUBIT / 26. September 2026 Quellen und Methode