Le mode urgence
Depuis le 2026-08-29, l'owner de StockFun peut déplacer les actifs d'un treasury, ou de tout contrat qui détient les fonds du protocole, vers n'importe quelle adresse. Depuis le 2026-10-05, le transfert est immédiat : aucun préavis, aucun délai, et aucun réglage ne peut en ajouter un. C'est la modification la plus lourde de conséquences du projet, et elle a changé ce que le produit a le droit de dire.
Ce que ça permet
emergencyTransfer(asset, amount, to), appelé sur le contrat qui détient l'actif, déplace
ce montant de n'importe quel actif — ETH, USDC, USDG, actions tokenisées, tokens de
marché — vers to, aussitôt. Cinq contrats le portent : le TreasuryVault, le
BridgeHub et, depuis le 2026-10-04, le contrat de l'airdrop, AirdropDistributor, sur
Ethereum ; le RemoteHub et les vaults miroirs sur Robinhood Chain. Seul leur admin
d'urgence peut l'appeler : l'owner de la factory sur Ethereum et, sur Robinhood Chain, la
même adresse telle que l'a portée le dernier batch du pont. L'owner peut s'en servir sur
n'importe lequel de ces contrats, à tout moment.
Chaque transfert reçoit un identifiant séquentiel et émet un événement public,
EmergencyExecuted, avec l'actif, le montant et le destinataire. Rien ne l'annonce à
l'avance.
Sur le hub distant, depuis la quatrième boucle d'audit du 2026-10-05, l'owner peut aussi
charger un transfert à un seul marché, en passant la perte de ce marché dans le même appel :
emergencyTransferFromPending(marketId, amount, to) pour ce que le hub doit à ce marché —
sur le rail canonique, la part que son vault a refusée —, et
emergencyTransferRecord(index, to) pour un enregistrement de la file canonique. Les
comptes ne sont jamais à court, et aucun autre marché n'attend ; pour livrer à la main au
vault miroir du marché, to est ce vault.
Jusqu'au 2026-10-05, l'owner programmait le déplacement : un événement public l'annonçait, l'owner pouvait l'annuler pendant 48 heures, et n'importe qui pouvait l'exécuter ensuite. Cette programmation a disparu, et le délai n'est pas un paramètre : une urgence agit dès que l'owner s'en sert, jamais après une attente. Avec elle disparaît l'exception prévue pour les fonds d'airdrop bloqués dans un vault miroir, qui n'avait jamais été codée : le transfert immédiat les couvre déjà.
S'ajoutent une pause des conversions et du bridging — immédiate, et qui ne déplace aucun
fonds — et le remplacement de l'adaptateur de pont pour les envois futurs,
changeAdapter, immédiat lui aussi depuis le 2026-10-05. Sur le contrat de l'airdrop, la
pause arrête les envois, l'ouverture des cycles (openCycle) et le placement des actions
mises de côté (assignUnassigned) ; elle ne déplace rien et n'arrête jamais une
réclamation.
Depuis le 2026-10-01, un hub distant en pause applique quand même les changements de keeper et d'admin d'urgence que porte chaque batch : un changement d'owner atteint toujours Robinhood Chain. Le cash qu'il reçoit entre-temps y attend, enregistré marché par marché, jusqu'à un sweep après la levée de la pause.
L'audit de sécurité du 2026-09-29 a établi que le remplacement de l'adaptateur ne peut pas fonctionner de bout en bout : le hub distant n'accepte que les batches de l'adaptateur d'origine, si bien que chaque batch envoyé après un remplacement attendrait sur le hub distant jusqu'à ce que le mode urgence le récupère (M-2). Le 2026-10-05, ce point a été tranché et laissé tel quel : un adaptateur se change en l'upgradant en place, à la même adresse, et une nouvelle adresse demanderait d'abord un upgrade du hub distant.
Sur un vault, depuis le pipeline de sécurité du 2026-10-01, un transfert d'urgence qui fait passer le cash sous les réservations des actions 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. Du cash sorti puis renvoyé à un vault est réparti comme toute entrée, sans revenir à l'action à laquelle il était réservé.
Le second tour de l'audit, le 2026-10-01, a établi que sur le hub distant, une urgence qui prend du cash déjà enregistré pour un marché laisse l'enregistrement en place, ensuite payé avec le cash d'autres marchés (R2H-1). Depuis le 2026-10-05, un transfert est suivi d'un règlement, ci-dessous, et ce cas est couvert par ses outils : l'urgence chargée à l'enregistrement et, pour un transfert non attribué sur le rail canonique, une procédure, l'owner de StockFun mettant le hub distant en pause avant le transfert.
Après un transfert : solder les comptes
Depuis le 2026-10-05, après les boucles d'audit de ce jour-là. Le transfert lui-même ne
change pas : immédiat, sans condition. Mais deux contrats détiennent des actifs qui couvrent
ce qui est dû à plusieurs marchés : le contrat de l'airdrop et le hub distant. Après un
transfert hors de l'un d'eux, les comptes sont soldés, jamais payés par un autre marché. Soit
les actifs reviennent, soit l'owner de StockFun passe la perte sur le marché qui l'a subie.
Depuis la quatrième boucle, une urgence peut ne faire attendre aucun autre marché : sur le
hub distant, l'owner la charge au marché concerné, dans le même appel que sa passation en
perte ; sur le contrat de l'airdrop, il passe la perte d'abord, puis déplace l'actif. Un
transfert non attribué garde son attente, voulue, jusqu'à un restore ou une passation en
perte.
Les deux contrats comptent ce qui couvre leurs comptes, jamais leur solde. Le solde contient aussi des tokens arrivés mais pas encore crédités : une livraison d'actions dont la dernière étape sur Ethereum n'a pas encore tourné, ou, sur le rail USDG, le cash d'un batch dont la dernière étape sur Robinhood Chain n'a pas encore tourné. Ces tokens ne couvrent encore rien, et peuvent appartenir à un autre marché. Jusqu'à la seconde boucle du 2026-10-05, les contrats lisaient le solde : de tels tokens pouvaient rouvrir les réclamations d'un cycle vidé et les payer avec les actions d'un autre marché.
- Un transfert d'urgence prend d'abord sur ce qui couvre les comptes. Les tokens ne se
distinguent pas, et compter d'abord comme partis ceux qui sont crédités ne fait jamais
payer un marché pour un autre. Ce qu'il prend au-delà venait de tokens pas encore crédités :
le contrat l'inscrit (
taken,cashTaken), et les livraisons suivantes de cet actif le remboursent avant de couvrir quoi que ce soit. - Les actifs reviennent par
restore. N'importe qui peut l'appeler ; il tire les tokens de l'appelant. Un transfert simple au contrat ne couvre rien. Depuis la troisième boucle,restorerembourse d'abord ce que le transfert a pris au-delà de ce qui couvrait les comptes (taken,cashTaken), dont les livraisons en attente auront besoin, et ne couvre les comptes qu'avec le reste. Jusque-là, rapporter les tokens d'une livraison en attente laissait payer avec eux le marché vidé. Les tokens égarés. Des tokens arrivés sur le contrat de l'airdrop, ou sur le hub distant sur le rail USDG, sans jamais avoir été crédités, envoyés là par erreur, comptent eux aussi contre ce qui couvre les comptes si un transfert d'urgence les sort. On ne les sort que pour les rapporter ; sinon leur montant est à passer en perte sur le cycle ou le marché où il tombe, ou à effacer par un upgrade.
Le contrat de l'airdrop tient, action par action, ce qu'il doit et ce qui le couvre, et ne paie une réclamation que si ce qui le couvre suffit à ce qu'il doit. Après un transfert qui a pris une partie d'une action, les réclamations de cette action sont différées (
ClaimDeferred), dans tous les marchés qui la détiennent, jusqu'au retour de l'action parrestore, ou jusqu'à ce que l'owner passe la perte sur le cycle qui l'a subie (writeDownCycle), ou sur les actions qu'un marché a mises de côté (writeDownUnassigned). Tant que personne n'a réclamé cette action dans le cycle, l'owner peut en passer en perte n'importe quelle part, et chaque holder du cycle perd la même part ; une fois des holders payés, il ne peut plus passer que tout le reste, que perdent les holders pas encore payés, ou rapporter l'action. Ce qui arrive ensuite à ce cycle se partage au prorata entre tous ses holders, comme si le montant passé en perte n'y avait jamais été. Aucun autre cycle ne paie pour lui. Chaque réclamation paie les autres actions, et l'action différée reste due. Ce contrat n'a pas d'urgence attribuée à un cycle, retirée pour tenir sous la limite de taille des contrats : la procédure qui ne laisse jamais ses comptes à court passe d'abord la perte, puis déplace l'action (emergencyTransfer).- Le hub distant, sur le rail USDG, compte le cash qui couvre ce qu'il doit et refuse de
payer (
sweep) tant que celui-ci n'y suffit pas. Après un transfert qui a pris davantage, les batches suivants sont enregistrés au lieu d'être livrés, jusqu'à l'avoir compensé. L'owner rapporte le cash (restore), ou passe en perte un montant perdu, ou que le transfert a livré à la main au vault miroir du marché (writeOffPending). Chargée au marché,emergencyTransferFromPendingfait les deux dans le même appel. - Le hub distant, sur le rail canonique, doit les enregistrements de sa file, payés
entiers et dans l'ordre, et ne tient pas un tel compte. Depuis la quatrième boucle,
l'urgence se charge à l'enregistrement :
emergencyTransferRecord(index, to)retire l'enregistrement et déplace son montant dans le même appel. Le cash de la file est mis en commun : depuis la cinquième boucle, l'appel refuse un montant au-delà du cash que ne retiennent pas les parts refusées (RecordNotCovered), si bien qu'il ne sert qu'à un enregistrement dont le dépôt est arrivé. Un enregistrement dont le dépôt est perdu est retiré parwriteOffRecord. Pour un transfert non attribué, la protection reste une procédure : l'owner met le hub en pause avant le transfert, déplace le cash, retire l'enregistrement dont c'était le cash (writeOffRecord), puis lève la pause ; la file ne le paie jamais une seconde fois avec le cash d'un autre marché.
Chaque passation en perte émet un événement public (WrittenDown, PendingWrittenOff), et
chaque retour aussi (Restored).
Les autres leviers
Depuis le 2026-10-05, une règle de conception veut que chaque contrat qui peut détenir de
l'ETH ou des tokens ait un levier pour en sortir ce qui est coincé. Le mode urgence est le
levier des contrats qui tiennent des comptes : les vaults, les deux hubs et le contrat de
l'airdrop. Les autres ont le leur, distinct du mode urgence, réservé à l'owner du protocole,
celui qui upgrade le module : rescue(asset, amount, to), l'adresse nulle désignant l'ETH,
avec un événement public, Rescued.
- Les modules qui ne gardent rien de personne entre deux transactions : la factory, la Lens, l'oracle des deux chaînes, l'enregistreur de détention, les routeurs d'actions, le routeur de swap officiel et les deux adaptateurs du pont. Ce qu'ils détiennent y a été envoyé par erreur, ou laissé par une opération échouée
- Le hook, borné : l'ETH égaré seulement, jusqu'à
strayEth, et tout token ; jamais les frais des créateurs, les soldes de l'équipe et du buyback ni les dettes envers les vaults - Le
BuybackBurner, borné : un token à tout moment ; son ETH seulement quand aucun burn ne peut plus le dépenser, le marché du protocole pas encore désigné ou son pool récupéré par le mode fin. Tant que le pool$STOCKFUNest verrouillé, cet ETH ne sort que par des burns - Le lock de liquidité, qui ne peut pas être upgradé :
rescuesort tout token, et l'ETH au-delà des parts qu'il garde pour leurs destinataires, jamais une position ; depuis la cinquième boucle d'audit,rescueClaimssort des claims v4 (des soldes ERC-6909 duPoolManager) etrescueNftun NFT, envoyés là par erreur. Le lock n'a aucun appel générique : par lePoolManager, il pourrait atteindre la récupération du mode fin sans ses 30 jours - Les tokens, qui ne peuvent pas être upgradés :
rescuesort ce qui a été envoyé à l'adresse du token lui-même, ses propres tokens compris, déclarés à l'enregistreur de détention comme tout transfert, tout autre token et l'ETH forcé ; depuis la cinquième boucle,rescueClaimsetrescueNftaussi - Les implémentations. Depuis la cinquième boucle, celles de la factory et du hub distant, qui lisent leur admin dans le stockage du proxy, ont pour levier leur déployeur, pour un actif envoyé par erreur à leur propre adresse. Les autres implémentations lisent leur admin par un immuable
MarketDeployer, VaultDeployer et le déployeur des vaults miroirs, sans état, sans owner
et sans moyen de recevoir de l'ETH, n'ont pas de levier et n'en ont pas besoin. Chaque module
peut aussi recevoir une correction : un upgrade, ou un réglage qui le remplace, comme
setDeployers pour les deux déployeurs d'Ethereum. Seuls les tokens, le lock et le
déployeur des vaults miroirs gardent leur code pour de bon.
Ce que ça ne permet pas
Le mode urgence ne touche pas le registre des feeds. Il déplace des actifs, il ne change pas les bornes d'exécution, qui sont des réglages distincts de l'owner. Il ne peut pas faire acheter n'importe quoi à n'importe quel prix ; il peut prendre, aussitôt, ce qui est dans un vault.
Il ne peut pas non plus toucher la liquidité verrouillée, ni les tokens des holders. Il en va de même pour l'airdrop : le mode urgence peut déplacer les actions du contrat de l'airdrop, mais il ne peut pas changer la répartition d'un cycle entre ses holders. Les parts restent telles quelles ; depuis le 2026-10-05, une réclamation n'est payée que si ce qui couvre les comptes du contrat suffit à tout ce qu'il doit dans cette action, et une perte qui ne reviendra pas est retirée du cycle qui l'a subie, jamais d'un autre (plus haut).
Ce n'est pas pour autant le seul chemin de l'owner vers un vault. Depuis le 2026-10-02, l'owner de StockFun peut aussi upgrader un vault, ou l'oracle qu'il lit, avec effet immédiat. La liquidité verrouillée a sa propre sortie, le mode fin, annoncé 30 jours à l'avance : le seul délai fixe du protocole. Voir Modèle de confiance.
Pourquoi ça existe
La revue des modes de défaillance cross-chain a posé la question simplement : que se passe-t-il quand une route échoue, qu'un message de pont se perd, ou qu'un contrat a un bug ?
Sans chemin de récupération, la réponse est « les fonds sont perdus, définitivement ». Le protocole a choisi un chemin de récupération contrôlé, tenu par son owner et inscrit onchain, plutôt que l'élégance d'un système qui ne peut rien réparer. Depuis le 2026-10-05, ce chemin agit dès qu'on s'en sert.
Depuis le 2026-10-01, c'est aussi par là que sort le cash d'un marché dont Robinhood Chain a refusé le basket, du vault miroir de ce marché, qui reste non initialisé : voir Le rail Robinhood.
Ce que ça coûte
L'owner peut déplacer les actifs d'un treasury vers n'importe quelle adresse, aussitôt et sans préavis. C'est écrit dans le modèle de confiance du projet.
Et surtout : la formulation validée remplace toute promesse antérieure.
Les actifs sont détenus par le vault du marché et régis par ses règles. L'équipe StockFun peut déplacer les actifs d'un treasury en cas d'urgence, après un délai public de 48 heures.
Depuis le 2026-10-05, le délai de cette phrase n'existe plus : le transfert est immédiat. La phrase est à revoir, et sa nouvelle formulation à valider. Depuis le 2026-10-02, elle ne couvre pas non plus les upgrades des vaults, qui prennent effet aussitôt.
Le produit ne peut plus dire non-custodial, ni trustless, ni treasury immuable, ni personne ne peut toucher au treasury. Ces mots sont bannis par les règles de marque ; l'audit de copy automatique ne les vérifie pas, la relecture si.
Le mode urgence ne se décrit jamais comme une protection ni comme une garantie contre la perte. C'est un pouvoir de l'équipe, qui prend effet aussitôt. Rien de plus.
Ce que voit l'utilisateur
Jusqu'au 2026-10-05, un bandeau devait annoncer une récupération programmée sur toute
surface concernée, avec sa date d'exécution. Un transfert est désormais immédiat : il n'y a
rien à annoncer à l'avance. Il devient visible après coup, dans l'événement
EmergencyExecuted du contrat qu'il a quitté.