Le lancement en deux positions

Depuis l'amendement du 2026-09-12, il n'y a plus de bonding curve. Toute la supply part en liquidité Uniswap v4 verrouillée, dès la transaction de création. Dans le code depuis le 2026-09-28 : LiquidityLock.launchMarket fait tout cela dans la transaction de création du marché, et les tests fixent le prix d'ouverture lu par la Lens, 3 401 582 525 wei par token.

Pourquoi la courbe a disparu

L'ancienne courbe était un produit constant sur réserves virtuelles :

x = VIRTUAL_ETH   + netReserve     (3,75 ETH + ce qui est entré)
y = TOKEN_RESERVE - tokensSold     (1,1 Md − ce qui est sorti)

Or c'est exactement ce qu'est une position de liquidité concentrée : les réserves virtuelles de v3/v4 sont cet offset. La correspondance n'est pas une approximation, c'est la même équation écrite autrement.

Ce que la suppression fait gagner : plus de migration — le moment le plus risqué du protocole — plus de fee de graduation à extraire, un seul chemin de frais au lieu de deux, et des marchés routables par les agrégateurs dès leur premier bloc.

Les deux bandes

graph LR A["FDV 3,409 ETH

tick 195000

ouverture"] -->|bande 1 · 700M tokens · 7,535 ETH| B["FDV 34,091 ETH

tick 171960

10x"] B -->|bande 2 · 300M tokens · sans borne| C["tick −887220

plafond de prix"]
Bande 1 Bande 2
Tokens 700 000 000 300 000 000
Ticks [171960, 195000] [−887220, 171960]
Profondeur 7,535 ETH pour la traverser 14,5 ETH à 2× · 45,7 ETH à 20× · 144,6 ETH à 200×

tickSpacing 60, et aucune commission de LP.

Ce sont les réglages de lancement par défaut. Depuis le 2026-10-05, la supply, les tokens de la bande 1 (la bande 2 prend le reste), le tick de lancement, les ticks du bas des deux bandes, le tick spacing et la commission de LP forment un seul réglage de l'owner de StockFun, setLaunchConfig sur la factory, qui vaut pour les marchés créés ensuite. Il refuse une forme qu'aucun pool ne pourrait tenir : une bande vide, des ticks hors du spacing ou dans le désordre, un tick spacing ou une commission de LP hors limites, des bandes dont la liquidité dépasse ce qu'un tick peut porter. Chaque pool garde la forme, la commission de LP et le tick spacing avec lesquels il a été créé : le lock enregistre ses ticks, et la Lens donne la commission de LP et le tick spacing de chaque marché.

Le point délicat : le prix d'ouverture

Les deux positions ne contiennent que des tokens au lancement. C'est ce qui permet au protocole de n'avancer aucun ETH : tout l'ETH que le pool contiendra un jour vient des acheteurs.

Pour qu'une position soit token-only, le prix courant doit être au niveau ou au-dessus du haut de sa plage. D'où :

sqrtStartX96 = TickMath.getSqrtPriceAtTick(BAND1_UPPER);  // et non sqrt(FDV brute)

Le tick exact de la FDV de lancement est 194 977,95, et le tick utilisable le plus proche au-dessus est 195 000. Dériver sqrtStart de la FDV brute placerait le prix dans la bande 1, et le contrôle NotSingleSided du LiquidityLock rejetterait le dépôt.

La quantisation laisse une FDV effective de 3,4016 ETH au lieu de 3,409, soit −0,22 %.

Ce que ça donne à l'usage

Achats successifs de 2 ETH, depuis le lancement, avec les réglages par défaut :

Dépensé FDV Supply détenue
2 ETH ~$27 600 36,1 %
4 ETH ~$50 400 53,3 %
10 ETH ~$164 000 74,8 %
50 ETH ~$2,78 M 93,9 %

Le premier ticket prend 36,1 % de la supply — contre 36,99 % sur l'ancienne courbe. Le lancement se comporte comme avant, à moins d'un point près, ce qui était le critère de choix des paramètres.

Le plafond structurel d'une bande

L'ETH qu'une bande peut absorber, si 100 % de la supply y était déposée, vaut exactement la moyenne géométrique de ses deux FDV :

$$ E{\max} = \sqrt{\text{FDV}{\text{début}} \times \text{FDV}_{\text{fin}}}

$$

C'est ce qui contraint le choix des paramètres : on ne peut pas fixer librement le prix de lancement, le haut de bande et la profondeur — le nombre de tokens ferme le système.

Le mode fin

Comme les tokens, le lock ne peut pas être upgradé : son code est ce qui garde la liquidité dans les pools. Depuis le 2026-10-02, il a une sortie, le mode fin, pour le cas où le projet s'arrête.

  1. L'annonce. L'owner de StockFun appelle end(), et le lock enregistre, publiquement, la date 30 jours plus tard. Dès lors, aucun nouveau marché ne peut être lancé, ni la position $STOCKFUN créée : aucun marché n'a moins que le préavis entier. Le trading et l'encaissement des frais continuent
  2. Le préavis. Pendant 30 jours, chaque pool continue de trader. L'owner peut annuler à tout moment avec cancelEnd(), et les lancements reprennent
  3. La récupération. Une fois les 30 jours écoulés, l'owner peut retirer toutes les positions d'un pool — les deux bandes d'un marché, la position unique de $STOCKFUN — et en envoyer l'ETH et les tokens, dons non encaissés compris, vers n'importe quelle adresse (recoverLiquidity). Un pool récupéré n'encaisse plus rien et ne compte plus comme verrouillé ; une annulation ultérieure le laisse vide

Les 30 jours sont le préavis des holders. C'est une constante du lock, END_DELAY, pas un réglage : le seul délai fixe du protocole.

Ce que le lock garde d'autre

Un pool créé avec une commission de LP l'accumule sur ses positions ; n'importe qui peut l'encaisser (collectFees), et le keeper le fait une fois par jour. Depuis le 2026-10-05, chaque part est payée à part : une part que le vault refuse, ou que le hook refuse pour le créateur, reste dans le lock pour son destinataire (vaultOwed, creatorOwed, au total totalOwed), et n'importe qui la lui paie ensuite par payOwed, qui ne paie que ce destinataire ; les autres parts sont payées pendant ce temps.

Entre deux transactions, le lock ne garde que ces parts. Ce qu'on lui envoie d'autre par erreur, l'owner du protocole le sort : rescue pour l'ETH, au-delà des parts gardées, et pour tout token ; depuis la cinquième boucle d'audit du 2026-10-05, rescueClaims pour des claims v4, des soldes ERC-6909 du PoolManager, et rescueNft pour un NFT envoyé par un simple transferFrom. Le lock n'a aucun appel générique : par le PoolManager, il pourrait atteindre la récupération du mode fin sans ses 30 jours. Les positions ne s'atteignent que par le mode fin.