Le TreasuryVault

Un vault par marché. Il reçoit 2 % de chaque trade et les transforme en actions tokenisées, airdroppées aux holders du token. C'est le contrat le plus lourd du protocole, et celui qui a le moins de pouvoirs.

Ce qu'il n'a pas

Pas de fonction withdraw. Pas de transfer. Pas de sweep. Pas d'owner. Ces fonctions n'existent pas dans l'implémentation actuelle, ce qui est vérifiable par n'importe qui : un appel échoue parce qu'il n'y a rien à appeler. Depuis le 2026-10-02, le vault lui-même est upgradable : voir plus bas.

Le cycle de conversion

  1. Accumulation. L'ETH arrive au fil des trades. Une fois toutes les 24 heures, le cycle démarre si le vault détient au moins 0,1 ETH quand le keeper le vérifie, à son premier passage après la fermeture de la fenêtre de l'airdrop ; en dessous, rien ne se déclenche ce jour-là, même si l'ETH franchit le seuil plus tard — le gas et le slippage mangeraient l'opération. Le keeper s'y tient depuis le 2026-10-06 ; jusque-là, il convertissait pendant la séance dès que le vault détenait le seuil.
  2. ETH → USDC sur Uniswap v4 Ethereum, borné à 50 points de base contre le feed ETH/USD. Paire profonde, la borne peut être serrée. Le keeper fixe le montant, au moins le seuil et au plus le solde, et la borne est calculée sur ce montant.
  3. USDC → USDG via Curve, puis passage par l'OFT de Paxos sur LayerZero.
  4. Achat des actions sur les pools secondaires de Robinhood Chain, par le vault miroir, borné à 200 points de base contre un feed Chainlink indépendant, chaque action sur le cash qui lui est réservé.
  5. Airdrop. Une fois la séance US du jour terminée, le keeper envoie les actions achetées au contrat de l'airdrop sur Ethereum, une fois par fenêtre, où les holders du token les réclament, au prorata. Depuis la septième boucle d'audit, le 2026-10-06, il ne les envoie qu'une fois qu'elles valent ce que leur envoi coûte ; sinon, elles attendent au vault une fenêtre suivante.

Le vault mesure ce qu'il reçoit réellement et refuse si le résultat reste sous le minimum du keeper, qui n'est jamais plus lâche que la borne (depuis le 2026-10-05 ; jusque-là, le résultat n'était comparé qu'à la borne). Il ne fait confiance ni au keeper, ni au rail, ni au prix annoncé.

Le seuil et les deux bornes sont les valeurs par défaut de réglages de l'owner de StockFun, depuis le 2026-10-05, lus en direct par chaque vault : ceux de la factory pour les vaults Ethereum, celui du hub distant pour les achats des vaults miroirs. Un changement vaut dès la conversion suivante de chaque vault.

Montants et réservations

Depuis le 2026-10-01, après l'audit de sécurité du 2026-09-29 :

  • Chaque étape dépense un montant que fixe le keeper. Un vault plus gros que ce que sa place d'échange absorbe dans la borne convertit par tranches, sur plusieurs cycles. Avant, chaque étape dépensait le solde entier, et un vault devenu trop gros pour sa place d'échange ne pouvait plus jamais convertir.
  • La borne de l'étape ETH est calculée sur ce montant, pas sur le solde du moment. L'ETH qu'apportent les trades pendant que la transaction attend n'invalide plus le minimum du keeper.
  • Le cash est réservé action par action. À mesure qu'il arrive, il est mis de côté pour chaque action du basket, aux poids du basket. Chaque action ne dépense que sa propre réservation, et une action que le keeper saute la garde pour plus tard. Avant, la part d'une action sautée était redivisée sur tout le basket : en sautant des actions, un keeper pouvait faire passer presque toute une trésorerie dans une seule action.
  • Chaque jambe s'exécute à part, depuis le 2026-10-05. Une jambe qui échoue — une route qui échoue, une action gelée, une sortie sous le minimum, une cotation refusée, et depuis le 2026-10-06 sur Robinhood Chain une action dont le token met son oracle en pause pour une opération sur titres — garde sa réservation, avec l'événement LegFailed, et les autres jambes passent. Si aucune ne passe, l'appel échoue avec la raison de la première, comme une jambe seule. Avant, une jambe qui échouait faisait échouer tout l'appel. Sur Robinhood Chain, quand le contrôle du séquenceur de l'oracle est posé, un séquenceur arrêté ou tout juste revenu retient toutes les jambes (voir Le rail Robinhood) ; ce contrôle reste éteint tant que Chainlink ne publie pas de feed de disponibilité pour cette chaîne.

Les deux vaults qui achètent des actions fonctionnent ainsi : le vault miroir sur Robinhood Chain, en USDG, et le vault Ethereum sur le rail local, en USDC.

Dans les deux, depuis le pipeline de sécurité du 2026-10-01, un transfert d'urgence qui fait passer le cash sous les réservations les remet toutes à zéro : ce qui reste, et tout ce qui arrive ensuite, est réparti à nouveau aux poids du basket. Une urgence qui ne prend que du cash non réservé, ou un autre actif, les garde. Avant, la remise à zéro n'existait que dans la lecture que le vault faisait de ses réservations : les anciennes réservations revenaient avec l'entrée suivante, et l'ordre des appels du keeper décidait de la composition du basket.

Le rôle du keeper

Déclencher, rien d'autre. Il choisit le moment, fixe le montant de chaque étape, propose des routes de swap, et fournit les montants minimaux — que le vault refuse s'ils sont plus lâches que sa propre borne oracle, ou si un montant dépasse ce qui est réservé à cette action. Le keeper peut demander plus que la borne, jamais moins. Depuis le 2026-10-05, le vault tient le minimum du keeper sur ce qui arrive réellement.

Le keeper dépense la réservation de chaque action en entier, sauf sur la dernière action du basket, où il retient n−1 unités, n étant le nombre d'actions : voir Le keeper.

Le keeper ne peut pas détourner un actif, choisir un autre basket, faire passer le cash d'une action à une autre, ni desserrer une borne.

Sur le rail Ondo optionnel, depuis le 2026-10-05, le routeur ne sert que les vaults de sa factory, celui du protocole et celui de chaque marché enregistré : une attestation Ondo vaut pour qui la présente, et un tiers qui dépensait celle du keeper faisait échouer sa conversion (M-7). Chaque routeur refuse aussi d'être lui-même le destinataire d'une jambe (L-4) : un routeur ne garde rien entre deux transactions.

L'airdrop

Les actions du vault n'ont qu'une destination : les holders du token, à chaque airdrop, au prorata de leur détention. La répartition découle des soldes selon une règle que personne ne choisit — ni le créateur, ni le keeper. Le mécanisme est codé depuis le 2026-10-04, pas déployé : voir L'airdrop.

Sur le rail local, le vault remet lui-même ses actions. sendToAirdrop(stocks), réservé au keeper, envoie tout le solde de chaque action listée du basket au contrat de l'airdrop que désigne la factory, lu en direct. Le vault approuve les montants exacts, le contrat les tire et les crédite au cycle en cours du marché, puis les approbations sont refermées avant la fin de l'appel. Une action listée deux fois ou hors du basket fait échouer l'appel ; une action sans solde est sautée. Depuis le 2026-10-05, chaque action part à part : une action dont le solde ne se lit pas (BalanceUnreadable) ou dont le transfert est refusé, un gel de son émetteur par exemple, reste au vault, avec l'événement AirdropSendFailed, et les autres partent ; si rien ne part, l'appel échoue et dit pourquoi. Un vault câblé au hub de pont refuse cet appel : ses actions sont achetées et détenues sur Robinhood Chain, où le vault miroir les envoie de la même façon, par l'adaptateur LayerZero de chaque action.

Le buyback du créateur, buybackAndBurn(...), qui permettait au créateur de faire vendre des actions de la trésorerie pour racheter et brûler son token, a été abandonné le 2026-09-27 et retiré du code le 2026-09-28.

Ce que le vault peut détenir

ETH, USDC, USDG, et les actions de son basket, plus, sur le rail Ondo optionnel, l'USDon qu'un mint de l'émetteur peut rembourser. Un vault n'achète rien d'autre. Cela découle du code ; aucun test ne le vérifie comme invariant, et rien n'empêche un tiers d'envoyer un token sans rapport à l'adresse d'un vault.

Un vault plein d'USDC n'est pas en panne : il est en transit. Les trois états s'affichent comme la trésorerie en attente du prochain airdrop ; seules les actions sont distribuées, une fois achetées.

Un proxy par marché

Depuis le 2026-10-02, le vault de chaque marché est son propre proxy. Il est créé avec le marché, devant l'implémentation de vault que la factory désigne à ce moment, et initialisé dans la même transaction avec son basket, son marché, et le routeur, l'oracle et le bridge hub que la factory désigne alors. L'owner de StockFun upgrade les vaults un par un, marché par marché, avec effet immédiat. Une nouvelle implémentation désignée dans la factory n'atteint que les marchés créés ensuite.

Les vaults miroirs sur Robinhood Chain suivent la même règle : voir Le rail Robinhood.

Le mode urgence

Depuis le 2026-08-29, l'owner de StockFun peut déplacer n'importe quel actif hors d'un vault, vers n'importe quelle adresse ; depuis le 2026-10-05, le transfert est immédiat, sans préavis. Avec l'airdrop, c'est la seule façon dont l'implémentation actuelle laisse des actifs quitter un vault, et elle est traitée dans Le mode urgence.