Il rail Robinhood

Le azioni tokenizzate detenute dai vault risiedono su Robinhood Chain, una L2 Arbitrum Orbit. Il protocollo la raggiunge tramite LayerZero, con l'OFT USDG di Paxos come tratta cash.

Perché questo rail

La scelta è stata definita il 2026-09-11, dopo aver scartato il rail precedente.

Su un rail a mint primario, un contratto vault deve essere idoneo a detenere l'asset presso l'emittente: KYB, registrazione dell'indirizzo del contratto, e una conferma scritta che l'emittente non ha mai documentato pubblicamente. Era l'unico ostacolo davvero inevitabile del progetto.

I pool secondari di Robinhood Chain non richiedono nulla di tutto ciò: sono aperti a tutti. StockFun non ha alcun rapporto con l'emittente e non ne ha bisogno.

Il prezzo pagato per questa libertà è una dipendenza cross-chain: un bridge, due hub, e una stablecoin emessa da una terza parte che può congelarla. È un rischio accettato e documentato, non un rischio evitato.

Il circuito

flowchart LR V[TreasuryVault

Ethereum] -->|ETH → USDC

Uniswap v4| U[USDC] U -->|USDC → USDG

Curve| G[USDG] G --> BH[BridgeHub] BH -->|OFT di Paxos

LayerZero| RH[RemoteHub

Robinhood Chain] RH --> MV[Vault speculare

CREATE2, uno per mercato] MV -->|pool v3 / v4| S[Stock Tokens] S -->|adapter delle azioni, wrapped| AD[AirdropDistributor

Ethereum] AD -->|riscossioni| HO[Holder del token

su Ethereum]

Il percorso inverso dell'USDG, da Robinhood Chain a Ethereum, serviva solo al buyback del creatore; entrambi sono stati rimossi dal codice il 2026-09-28.

Dal 2026-10-04 il vault speculare invia le sue azioni al contratto dell'airdrop su Ethereum: ogni azione viene bloccata nel suo adapter LayerZero su Robinhood Chain e coniata in forma wrapped su Ethereum, dove gli holder la riscuotono. Quel percorso trasporta solo azioni. Gli adapter, uno per azione, non sono ancora nel repository per la mainnet; i test usano dei mock, e l'esecuzione su testnet con LayerZero del 2026-10-06 ha usato adapter di test (sotto).

Cosa è permissionless e cosa no

Componente Stato
Endpoint LayerZero Permissionless
Pool secondari degli Stock Token Permissionless — ciò che usa il protocollo
Mint / burn primario di Robinhood KYB — non usato
USDG Paxos controlla mint e burn, e può mettere in pausa o congelare

L'ultima riga è la dipendenza più rigida del rail, ed è reale.

Il vault speculare

Ogni mercato ha un vault speculare su Robinhood Chain, deployato tramite CREATE2 a un indirizzo prevedibile da Ethereum. Il keeper può quindi farlo deployare in anticipo dall'hub remoto, prima che arrivino gli USDC, così un trasferimento non arriva mai su un indirizzo senza codice. Dal 2026-10-05 possono farlo solo il keeper e l'owner di StockFun (predeploy): fino ad allora chiunque poteva farlo, anche per un mercato che non esisteva ancora, legando il suo vault speculare ai collegamenti di quel giorno. L'hub remoto apprende chi è il keeper da un batch del bridge, che lo trasporta: prima del primo batch non conosce alcun keeper, quindi l'owner di StockFun deploya in anticipo il vault speculare del primo mercato. Dal secondo ciclo di audit del 2026-10-05, un mercato il cui vault speculare il keeper non può deployare in anticipo (prima del primo batch, o dopo un cambio di keeper che l'hub remoto non ha ancora appreso) viene lasciato fuori dal batch, con un avviso, invece di essere inviato con troppo poco gas per deployare il suo vault; gli altri mercati passano, e il loro batch trasporta il nuovo keeper.

Dal 2026-10-02 ogni vault speculare è un proxy, un MirrorVaultProxy, davanti all'implementazione dei vault che l'hub remoto indica al momento del deploy del vault. Il costruttore del proxy non prende alcun argomento, quindi il suo creation code, e con esso l'indirizzo di ogni vault speculare, resta prevedibile da Ethereum qualunque sia l'implementazione. Il basket del vault arriva con il primo batch, che dal 2026-10-05 allinea anche lo stock router e l'oracolo del vault a quelli che l'hub remoto indica in quel momento: un vault deployato prima che un'azione fosse listata accetta un basket con quell'azione. L'owner di StockFun, così come l'hub remoto lo rispecchia, fa l'upgrade dei vault speculari uno per uno, mercato per mercato, con effetto immediato.

I percorsi di swap non sono fissati nel codice: arrivano nella calldata, codificati come abi.encode(uint8 version, bytes payload) — versione 3 per un path Uniswap v3 compattato, versione 4 per un array di PathKey v4. Il vault riceve diversi candidati per tratta ed esegue sul primo che rispetta il suo limite. Dal 2026-10-01 un percorso che esegue solo una parte dell'importo fallisce, e si prova il candidato successivo; prima, un'esecuzione parziale su un percorso v3 lasciava l'USDG non speso bloccato nel router.

Dalla pipeline di sicurezza del 2026-10-01, un percorso v3 viene eseguito un pool alla volta. Ogni pool deve consumare tutto il proprio input, altrimenti il percorso fallisce; il suo output torna allo stock router ed è l'input del pool successivo, e l'ultimo pool paga il vault, nel rispetto del minimo della tratta. Un pool che fallisce annulla i pool precedenti dello stesso tentativo, e si prova il candidato successivo. Fino ad allora il controllo vedeva solo il primo pool di un percorso: un'esecuzione parziale più avanti lasciava il token intermedio nel router v3 di Uniswap, SwapRouter02, dove chiunque poteva prenderlo, mentre la tratta andava a buon fine. Una tratta v3 multi-hop ora costa uno swap e un'approvazione per pool.

Ogni tratta spende solo l'USDG riservato alla propria azione, secondo i pesi del basket: vedi Il TreasuryVault. Il suo limite di prezzo rispetto al feed dell'azione, 200 punti base di default, è un'impostazione che detiene l'hub remoto e che ogni vault speculare legge in tempo reale (setStockMaxSlippageBps). Dal 2026-10-05 il vault applica il minimo del keeper stesso, mai più permissivo di quel limite, a ciò che è effettivamente arrivato.

Quando l'oracolo trattiene un prezzo

Dal 2026-10-06 l'oracolo dei vault speculari ha due protezioni, che la documentazione stessa di Robinhood raccomanda; ciascuna può solo trattenere un prezzo, mai cambiarlo.

  • Un'operazione societaria. Mentre un'azione ne attraversa una (un frazionamento, per esempio), il suo token dice che il suo oracolo è in pausa (oraclePaused()), e il suo feed Chainlink mantiene il suo ultimo valore, che può ancora sembrare fresco mentre il moltiplicatore del token cambia. L'oracolo trattiene allora il prezzo di quell'azione: la sua tratta d'acquisto fallisce da sola (StockOraclePaused), il suo USDG resta riservato per essa, e le altre azioni del basket vengono acquistate. Il controllo è attivo per ogni azione; l'owner di StockFun può disattivarlo per una singola azione (setOraclePauseCheck), il cui prezzo si affida allora ai soli controlli del proprio feed. Un token che non risponde conta come non in pausa.
  • Il sequencer. Robinhood Chain è una chain Arbitrum con un unico sequencer. Con il feed di uptime del sequencer L2 di Chainlink impostato (setSequencerUptimeFeed), l'oracolo trattiene ogni prezzo finché il feed dice che il sequencer è fermo, che è ripartito da non più del periodo di grazia (un'ora di default), o non si può leggere: fino ad allora nessuna tratta compra. Oggi non esiste alcun feed del genere per Robinhood Chain, quindi il rail viene deployato con questo controllo disattivato; l'owner di StockFun imposta il feed se Chainlink ne pubblica uno.

Il keeper vede entrambe prima di quotare qualsiasi cosa (vedi Il keeper), il Worker dice perché manca il prezzo di un'azione, e la dapp lo mostra (vedi La dapp).

L'invio delle azioni all'airdrop

Dal 2026-10-04, una volta comprate, le azioni lasciano il vault speculare in un solo modo: sendToAirdrop. Il keeper lo chiama con la lista delle azioni da inviare e paga le commissioni LayerZero; ciò che paga in eccesso gli viene restituito. Per ogni azione, il vault invia il suo intero saldo attraverso l'adapter di quell'azione al contratto dell'airdrop su Ethereum, con l'id del mercato come payload. Il keeper non indica né l'importo né la destinazione: l'adapter di ogni azione (setStockAdapter, che verifica che l'adapter trasporti proprio quel token) e il contratto dell'airdrop (setAirdrop) sono indicati sull'hub remoto dal suo admin, l'owner di StockFun. Un'azione in lista due volte o fuori dal basket fa fallire la chiamata.

Dal 2026-10-06 il keeper indica il gas che ogni consegna riceve su Ethereum: sendToAirdrop(stocks, receiveGas, composeGas), il lzReceive dell'OFT dell'azione oltre a ciò che quell'OFT impone, e il compose del contratto dell'airdrop. L'hub remoto riporta ogni valore tra il minimo e il massimo che il suo admin fissa, e zero prende il default (airdropGas), e il vault costruisce l'invio e la sua quotazione con ciò che l'hub concede; la chiamata con le sole azioni prende entrambi i default. Il keeper sceglie i valori da simulazioni della consegna su Ethereum (vedi Il keeper): l'aggiornamento Glamsterdam di Ethereum, attivo su Sepolia dal 2026-10-06, ha reso un nuovo slot di storage circa cinque volte più caro, e l'unica cifra di compose di prima, 600.000 gas, ha lasciato senza gas sufficiente ogni consegna del primo ciclo dell'esecuzione su testnet con LayerZero. Un hub remoto aggiornato da una versione senza le politiche rifiuta ogni invio e ogni quotazione (AirdropGasNotSet) finché entrambe non sono impostate.

Dal 2026-10-05 ogni azione va a sé. Un'azione senza adapter, una il cui saldo non si può leggere e una il cui invio fallisce — un congelamento dell'emittente, un peer mancante, una commissione che il pagamento del keeper non copre — restano nel vault con un evento (AirdropSendFailed), e le altre partono; quando non parte nulla, la chiamata fallisce e ne indica il motivo. La quotazione, quoteSendToAirdrop, lascia fuori ciò che non sa prezzare invece di fallire.

LayerZero trasporta sei decimali: meno di 10^12 unità di un'azione a 18 decimali, un milionesimo di token, non possono attraversare e restano nel vault per un invio successivo.

Su Ethereum, l'OFT dell'azione conia l'azione wrapped a favore del contratto dell'airdrop, poi l'endpoint di LayerZero lo chiama con il payload. Il contratto accredita la consegna solo se proviene dal suo endpoint, da un OFT di azione registrato dall'owner, da Robinhood Chain, e se è stata inviata dal vault speculare che il bridge hub deriva per il mercato indicato dal payload. Quella consegna viene eseguita con il gas che l'invio portava (sopra); una consegna rimasta senza gas fallisce senza perdere nulla, memorizzata sull'endpoint di LayerZero, con le azioni wrapped già sul contratto dell'airdrop quando è fallito solo il compose, e chiunque può rieseguirla con più gas. Dal 2026-10-06 lo fa il keeper, dalla propria chiave, entro un limite, e segnala con un'allerta un secondo fallimento. Dettagli e misure in Deploy e L'airdrop.

Upgrade e collegamenti

Dal 2026-10-02 ogni contratto StockFun del rail è upgradabile tranne il deployer dei vault speculari, dal cui indirizzo deriva l'indirizzo di ogni vault speculare. Su Ethereum, il bridge hub e i suoi adapter rispondono all'owner della factory. Su Robinhood Chain, l'hub remoto è l'autorità di upgrade: risponde con il proprio admin di emergenza, l'owner di Ethereum così come l'ha trasportato l'ultimo batch, quindi l'hub remoto, i vault speculari, lo stock router e l'oracolo ricevono l'upgrade dall'owner di StockFun, con effetto immediato.

L'hub remoto viene deployato per primo sulla sua chain, con un admin iniziale, che poi indica lo stock router, l'oracolo e l'implementazione dei futuri vault speculari e, quando vengono forniti, la rotta dell'airdrop e gli adapter delle azioni. Il primo batch sostituisce quell'admin con l'owner di StockFun.

Lo stesso admin detiene le impostazioni dell'hub remoto, dal 2026-10-05: le registrazioni che paga uno sweep, 64 di default (setMaxRecordsPerSweep, mai zero), il limite di prezzo degli acquisti dei vault speculari, e il gas di ogni consegna dell'airdrop (setAirdrop); e, dal 2026-10-06, le due protezioni dell'oracolo e le due politiche di gas delle consegne dell'airdrop su Ethereum, ciascuna con un default, un minimo e un massimo (setAirdropReceiveGas, 650.000 tra 200.000 e 1.500.000; setAirdropComposeGas, 1.250.000 tra 600.000 e 4.000.000; un minimo pari a zero, un minimo sopra il massimo e un default al di fuori di essi vengono rifiutati). L'hub remoto le imposta entrambe all'inizializzazione, e DeployRemote le imposta di nuovo dal suo ambiente. Un oracolo sostitutivo che l'admin indica (setOracle) parte con entrambe le protezioni disattivate, quindi l'admin le riattiva per esso; i vault speculari già inizializzati conservano l'oracolo con cui sono stati inizializzati.

Su Ethereum il bridge hub non fa più il deploy del proprio adapter: l'adapter viene deployato puntando all'hub, poi indicato una sola volta dall'owner di StockFun (setAdapter), che ne verifica gli indirizzi fissati. Una sostituzione successiva, changeAdapter, è immediata dal 2026-10-05. Accetta solo un adapter i cui indirizzi fissati sono esattamente quelli dell'attuale: lo stesso hub, la stessa factory, gli stessi token cash, lo stesso hub remoto, la stessa chain di destinazione e lo stesso trasporto. Può cambiare valori di gas, opzioni o il pool Curve, mai una destinazione; l'hub remoto accetta ancora i batch solo dall'adapter per cui è stato costruito (M-2, vedi Modalità di emergenza). Un adapter si cambia quindi facendone l'upgrade sul posto, allo stesso indirizzo; un nuovo indirizzo richiederebbe prima un upgrade dell'hub remoto perché lo accetti. Il 2026-10-05 l'owner ha deciso di lasciare le cose così.

Anche i numeri degli adapter stessi sono impostazioni dell'owner di StockFun: sul rail USDG, il peggior tasso USDG per USDC accettato su Curve, 30 punti base di default, e il gas dell'ultimo passo della consegna su Robinhood Chain (setSettings); dal decimo ciclo di audit, il 2026-10-06, quel gas è una base che richiede ogni batch, 200.000 di default, più una parte per ogni mercato del batch, 400.000 di default, e un batch porta al massimo 17 mercati (setBatchGas; vedi "Il gas di compose di un batch" sotto). Fino ad allora un'unica cifra, 1.200.000 di default, pagava ogni batch, qualunque cosa portasse. Sul rail canonico, il gas dei due ticket (setTicketGas). Dal 2026-10-05 il ticket contabile del rail canonico paga ciò che l'inbox del bridge chiede per la dimensione del batch alla base fee corrente, e l'impostazione ne fissa il minimo. Una quotazione letta offchain, senza un prezzo del gas, vedeva una base fee pari a zero e fissava il prezzo di quel ticket al solo minimo, quindi un batch lungo falliva alla base fee reale; dal secondo ciclo di audit di quel giorno il keeper chiede la quotazione a una base fee da lui indicata (quoteBridgeAt), il doppio dell'ultima, e gli viene restituito l'eccesso. Dal quarto ciclo il ticket di deposito viene prezzato allo stesso modo: ciò che l'inbox chiede per depositCalldataLength() byte alla base fee, e l'impostazione tokenSubmissionCost ne fissa il minimo. Anche quella lunghezza è un'impostazione dell'owner (setDepositCalldataLength, mai zero): 1.024 byte di default, sopra i 740 byte del deposito del gateway per USDC. Fino ad allora il costo di invio del deposito era un'impostazione fissa, e una base fee che lo superava faceva fallire ogni batch.

Guasti che restano circoscritti

Dal 2026-10-01, dopo l'audit di sicurezza del 2026-09-29:

  • Un basket rifiutato blocca solo il proprio mercato. Se Robinhood Chain rifiuta il basket di un mercato, per esempio un'azione che il suo router o il suo oracolo non supporta, il vault speculare di quel mercato resta non inizializzato e conserva il proprio cash, che la modalità di emergenza può recuperare. Gli altri mercati dello stesso batch del bridge passano. Prima, l'intero batch falliva, e chiunque poteva raggruppare mercati sani con uno rifiutato.
  • Un token remoto, un identificatore. L'hub del bridge rifiuta di associare un secondo identificatore di basket a un token di Robinhood Chain già associato.
  • Un hub remoto in pausa applica comunque i ruoli. Ogni batch trasporta il keeper e l'admin di emergenza correnti. Un hub in pausa li applica comunque, così un cambio di owner di StockFun raggiunge sempre Robinhood Chain. Il cash viene registrato per mercato e pagato ai vault speculari con uno sweep dopo la fine della pausa.
  • Le registrazioni canoniche vengono pagate in ordine. Sul bridge Orbit canonico, usato su testnet e come fallback, token e contabilità arrivano in due ticket separati. L'hub paga per intero le registrazioni in attesa, nell'ordine in cui sono arrivati i loro messaggi, chiunque attivi lo sweep. Dalla pipeline di sicurezza del 2026-10-01, un ticket contabile paga al massimo tante registrazioni quante ne ha aggiunte alla coda, a partire dalle più vecchie, e possono appartenere a batch precedenti; lo sweep paga il resto, fino a 64 registrazioni per chiamata di default. Prima, un arretrato lasciato da una pausa o da un deposito in ritardo poteva spingere un ticket oltre il gas fisso della sua esecuzione automatica, e il batch restava non registrato a meno che qualcuno non rieseguisse il ticket a mano entro sette giorni.

Un guasto era circoscritto solo in parte. Il secondo round dell'audit, il 2026-10-01, ha rilevato che se il token cash rifiuta un vault speculare, per esempio perché il suo emittente ha congelato quell'indirizzo, la coda canonica si ferma e, su entrambi i rail, ogni batch che comprende quel mercato fallisce (R2H-2). Il secondo ciclo di audit del 2026-10-05 lo ha mitigato, e il quarto lo ha chiuso lo stesso giorno: una consegna del genere ora attende a sé, e il batch prosegue (più avanti).

Dal 2026-10-05, dopo il ciclo di audit di quel giorno:

  • Solo il keeper esegue il bridge. Il batch del bridge, bridgeReady, spetta solo al keeper. Fino ad allora chiunque poteva inviarne uno: una terza parte poteva infilare un batch al minimo più permissivo dell'adapter tra due propri trade sul pool Curve, o far fallire il batch del keeper facendo prima il bridge di uno dei suoi vault.
  • Un'emergenza sull'hub remoto viene sistemata, non pagata da un altro mercato. Sul rail USDG l'hub rifiuta di pagare ciò che deve finché il cash che lo copre è insufficiente, un conteggio che tiene da sé dal secondo ciclo di audit di quel giorno, mai il suo saldo, che comprende anche il cash dei batch ancora in transito; il cash torna tramite restore. Sul rail canonico l'owner di StockFun mette in pausa l'hub prima del trasferimento, elimina la registrazione il cui cash è stato preso dall'emergenza, poi toglie la pausa. Vedi Modalità di emergenza.

Dal quarto ciclo di audit del 2026-10-05, che applica la regola del fondatore secondo cui un guasto non blocca mai il resto (vedi Architettura):

  • Una consegna rifiutata attende a sé. Sul rail USDG, la quota di un vault speculare che il token cash rifiuta resta sull'hub remoto, dovuta a quel mercato e coperta (DeliveryRefused), e gli altri mercati del batch vengono pagati. Sul rail canonico, una registrazione del genere esce dalla coda e viene tenuta a parte per il suo mercato (undeliverable), così le registrazioni che la seguono e i ticket successivi vengono pagati. Su entrambi, chiunque la paga con sweep(marketId) non appena il vault accetta di nuovo il cash. Dal 2026-10-06 il keeper, sul rail canonico, chiude anche i trasferimenti le cui registrazioni rifiutate un solo sweep ha pagato in una volta, o che l'owner di StockFun ha imputato al mercato, così che nessuno resti seguito per sempre.
  • Ogni mercato di un batch va a sé. bridgeReady lascia fuori un mercato in lista il cui vault non può rilasciare il proprio cash — in pausa, vuoto, rifiutato dall'emittente o, dal quinto ciclo, un vault ancora senza codice, come quello del mercato del protocollo prima che venga indicato —, un mercato sconosciuto o uno il cui payload l'adapter non sa costruire (MarketSkipped), e gli altri partono. Il minimo del keeper copre il batch così come è stato elencato, e viene ridotto in proporzione a ciò che è effettivamente partito; Bridged elenca solo i mercati partiti. Un batch da cui non parte nulla fallisce, con il motivo del primo mercato.
  • Ogni tratta d'acquisto va a sé, sul vault speculare come sul vault di Ethereum (LegFailed): vedi Il TreasuryVault.
  • Un trasferimento di emergenza può essere imputato a un solo mercato. L'owner di StockFun sposta il cash di un mercato e ne sistema i conti nella stessa chiamata, così che nessun altro mercato attenda: emergencyTransferFromPending prende ciò che l'hub deve a quel mercato sul rail USDG, o la sua quota rifiutata sul rail canonico, ed emergencyTransferRecord una registrazione canonica in coda, per intero. Dal quinto ciclo quest'ultima è per una registrazione il cui deposito è arrivato: il cash della coda è comune, per cui rifiuta un importo oltre il cash non trattenuto per le quote rifiutate (RecordNotCovered). Una registrazione il cui deposito è andato perso viene stralciata (writeOffRecord). Sul rail USDG, un trasferimento non imputato ad alcun mercato mantiene la sua attesa generale, per progettazione: i conti mostrano un ammanco finché il cash non viene ripristinato o stralciato.
  • Un prezzo trattenuto trattiene solo le proprie tratte (dal 2026-10-06): un'azione in un'operazione societaria fa fallire solo la propria tratta, in ogni vault speculare; con il controllo del sequencer impostato, un'interruzione del sequencer trattiene ogni tratta finché non è ripartito da almeno il periodo di grazia, e il cash attende nei vault (sopra, "Quando l'oracolo trattiene un prezzo").

Il gas di compose di un batch

Dal decimo ciclo di audit, il 2026-10-06. L'ultimo passo di un batch del bridge su Robinhood Chain, il compose dell'hub remoto, inizializza e finanzia il vault speculare di ogni mercato, quindi il suo gas cresce con il batch. Riceveva un'unica cifra fissa, 1.200.000 di default, qualunque cosa contenesse il batch: quattro nuovi mercati su basket a cinque azioni l'hanno lasciato senza gas. Il loro USDG è rimasto allora sull'hub remoto senza alcuna registrazione, ogni batch successivo con gli stessi mercati è fallito allo stesso modo, e solo un'esecuzione a mano sull'endpoint di Robinhood Chain l'ha sbloccato. Nulla è andato perso, ma nel frattempo nessun mercato del batch ha avuto acquisti né airdrop.

  • Una base e una parte per mercato. L'adapter USDG dà a un batch di n mercati composeGas + n × composeGasPerMarket di gas di compose, 200.000 più 400.000 per mercato di default, sia per l'invio sia per ogni quotazione. Il primo batch di un mercato a cinque azioni richiede circa 294.000 gas (estrapolato da quanto misurato con da una a tre azioni), e un mercato già configurato da 21.000 a 39.000, su un fork della testnet di Robinhood Chain attraverso l'endpoint di LayerZero stesso
  • Al massimo 17 mercati per batch. LayerZero rifiuta un messaggio oltre il limite di dimensione del percorso, 10.000 byte di default, e ogni mercato a cinque azioni aggiunge al massimo 544 byte a quello del batch: 17 mercati ci stanno, 18 no. Un batch più grande viene rifiutato per intero prima che qualcosa si muova, e ogni vault tiene il suo USDC. Il keeper ne invia al massimo altrettanti, prima i mercati che attendono da più tempo, e gli altri partono al suo giro successivo, così nessuno attende per sempre. Il rail canonico non ha questo tetto
  • Entro i limiti di Robinhood Chain. Il gas di compose del batch più grande è al massimo 24.000.000, al di sotto dei 32.000.000 di gas che Robinhood Chain esegue in una transazione; le impostazioni dell'owner non possono andare oltre. Prima della mainnet l'owner legge il limite di dimensione del percorso che segue l'USDG di Paxos e imposta il tetto di conseguenza se differisce
  • Costa poco. L'executor di LayerZero fattura il gas in più al prezzo del gas di Robinhood Chain: sulla testnet la commissione di un batch cresce di 0,00001 ETH per milione di gas
  • Un adapter di prima rifiuta ogni batch finché l'owner non fissa le due nuove impostazioni, cosa che il suo upgrade fa nella stessa transazione. L'adapter della testnet è stato aggiornato così il 2026-10-06, e il suo batch successivo è stato composto dall'executor di LayerZero con la sua nuova opzione, 600.000 gas per un mercato, 115.990 usati
  • Un compose bloccato lo dice. L'allerta del keeper per un trasferimento non accreditato in tempo ora legge il messaggio del batch sull'endpoint di Robinhood Chain: non ancora consegnato lì; composto, con l'accredito a seguire; o memorizzato, con il suo USDG sull'hub remoto, in attesa di essere rieseguito a mano con più gas, cosa che chiunque può fare, e l'allerta dà l'hash del messaggio memorizzato. Il keeper continua a non eseguire da sé un compose del bridge

Cosa è stato verificato, e cosa no

Prima, lo stato attuale. Non è avvenuto alcun deploy sulla mainnet né alcun trasferimento di fondi reali. I test locali simulano la consegna; non dimostrano una vera consegna LayerZero. Gli invii dell'airdrop, implementati il 2026-10-04, sono testati contro mock di LayerZero e degli adapter delle azioni.

L'esecuzione su testnet con LayerZero, 2026-10-06. Il protocollo è stato deployato su Sepolia e sulla testnet di Robinhood Chain (167 transazioni di deploy, tutte riuscite) ed è girato da un capo all'altro sugli endpoint, sul DVN e sull'executor reali di testnet di LayerZero, dalle 13:50 alle 19:07 UTC, con il keeper, in sette finestre orarie: l'ETH di ogni finestra convertito una volta, passato dal bridge in un batch LayerZero, elaborato con compose sull'hub remoto verso il vault speculare e speso sulle tre azioni di test. Sei cicli dell'airdrop sono stati aperti, rinviati via LayerZero ed elaborati con compose sul contratto dell'airdrop; i primi quattro sono stati riscossi per intero dai cinque holder, il quinto in parte, il sesto lasciato da riscuotere, ogni pagamento esattamente la quota calcolata in modo indipendente dal registratore della detenzione. Le esercitazioni di incidente (pause, trasferimenti di emergenza e restore, rescue, un keeper interrotto con una transazione in sospeso, un compose eseguito a mano, un feed non aggiornato, un'azione in pausa, la protezione del sequencer, una consegna che il token cash rifiuta) sono state svolte su messaggi reali e recuperate come documentato, tranne due metà: la pausa del bridge hub di Sepolia, e un compose del bridge eseguito a mano. Sepolia ha attivato l'aggiornamento Glamsterdam di Ethereum durante l'esecuzione: le prime consegne dell'airdrop sono rimaste senza gas presso l'executor di LayerZero e sono state eseguite a mano, e la correzione del gas delle consegne (sopra) è stata applicata con un upgrade e ha sostenuto i cicli successivi. Il keeper è stato riavviato alle 18:25 sul codice del nono ciclo di audit e ha eseguito l'ultima finestra senza problemi, con il gas scelto dalle sue simulazioni.

Ciò che quell'esecuzione non dimostra: l'USDG di Paxos, il cui token di testnet non ha alcuna funzione OFT su queste testnet, quindi un USDG di test sotto il MintBurnOFTAdapter di LayerZero, modellato sulla coppia della mainnet, ne ha preso il posto, e non sono stati messi alla prova né i DVN della coppia, né il suo congelamento, né la sua pausa; le azioni di Robinhood e i loro adapter, al posto dei quali ci sono state azioni di test sotto l'OFTAdapter di LayerZero; feed di prezzo e liquidità reali; il gas, le commissioni e la finalità della mainnet. Resta una prova sulla mainnet, un primo piccolo ciclo su un vault di verifica.

Gli script Sepolia più vecchi usano il bridge Orbit canonico e non validano LayerZero. Un successo su un fork, o su testnet, non è una prova di una consegna reale sulla mainnet.