[{"data":1,"prerenderedAt":1175},["ShallowReactive",2],{"docs:fr:\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate":3},{"id":4,"title":5,"body":6,"cover":1166,"description":1167,"extension":1168,"meta":1169,"navigation":1170,"path":1171,"seo":1172,"stem":1173,"__hash__":1174},"docs\u002Ffr\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate.md","Construire sur Duel",{"type":7,"value":8,"toc":1159},"minimark",[9,13,17,22,29,131,187,216,220,226,307,314,339,345,351,451,454,536,559,566,659,695,698,719,780,798,802,860,879,883,1100,1107,1111,1155],[10,11,5],"h1",{"id":12},"construire-sur-duel",[14,15,16],"p",{},"Les pools de Duel sont des pools Uniswap V4 standards avec un hook, et chaque chiffre que montre l’app vient de vues et\nd’événements publics. Bots, terminaux, dashboards et agrégateurs peuvent construire dessus sans rien demander.",[18,19,21],"h2",{"id":20},"lire-un-duel","Lire un duel",[14,23,24,28],{},[25,26,27],"code",{},"DuelLens"," rassemble tout ce qui concerne un duel en un seul appel :",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-solidity shiki shiki-themes vitesse-light vitesse-dark","function getPair(uint256 pairId) external view returns (PairView memory);\nfunction getPairs(uint256 offset, uint256 limit) external view returns (PairView[] memory);\n","solidity","",[25,37,38,88],{"__ignoreMap":35},[39,40,43,47,51,55,59,63,66,69,72,76,79,82,85],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"s5TCs","function",[39,48,50],{"class":49},"s_xSY"," getPair",[39,52,54],{"class":53},"si6no","(",[39,56,58],{"class":57},"s_NWU","uint256",[39,60,62],{"class":61},"s9nN2"," pairId",[39,64,65],{"class":53},")",[39,67,68],{"class":45}," external",[39,70,71],{"class":45}," view",[39,73,75],{"class":74},"sTPum"," returns",[39,77,78],{"class":53}," (",[39,80,81],{"class":45},"PairView",[39,83,84],{"class":45}," memory",[39,86,87],{"class":53},");\n",[39,89,91,93,96,98,100,103,106,109,112,114,116,118,120,122,124,127,129],{"class":41,"line":90},2,[39,92,46],{"class":45},[39,94,95],{"class":49}," getPairs",[39,97,54],{"class":53},[39,99,58],{"class":57},[39,101,102],{"class":61}," offset",[39,104,105],{"class":53},",",[39,107,108],{"class":57}," uint256",[39,110,111],{"class":61}," limit",[39,113,65],{"class":53},[39,115,68],{"class":45},[39,117,71],{"class":45},[39,119,75],{"class":74},[39,121,78],{"class":53},[39,123,81],{"class":45},[39,125,126],{"class":53},"[]",[39,128,84],{"class":45},[39,130,87],{"class":53},[14,132,133,134,136,137,140,141,144,145,148,149,152,153,156,157,160,161,164,165,168,169,172,173,176,177,152,180,152,183,186],{},"Un ",[25,135,81],{}," contient l’identifiant du duel, son créateur et l’URI de ses métadonnées, les deux camps (token, nom,\nsymbole, offre, prix et tick du pool, ETH par token, ETH réel dans le pool), les trois clés de pool, la répartition en\ndirect (",[25,138,139],{},"gaugeBps",", la part du camp A en points de base), la moyenne du round jusqu’ici (",[25,142,143],{},"roundGaugeBps","), la cagnotte,\nles frais du créateur, le volume et les rachats depuis le lancement, la taxe anti-snipe en cours, l’index, le début et la\nfin du round et s’il a été tradé (",[25,146,147],{},"roundTraded","), l’heure et le tick de lancement (",[25,150,151],{},"launchTime",", ",[25,154,155],{},"startTick","), s’il\ns’agit d’un duel supporter, sa catégorie (",[25,158,159],{},"category",", selon la numérotation de l’app, 0 pour aucune), ses conditions de\nfrais (",[25,162,163],{},"fees",") et la fraction de sa part que le protocole prend en ce moment (",[25,166,167],{},"protocolRateBps",", sur 10 000) : le\nprotocole reçoit ",[25,170,171],{},"fees.protocolShareBps × protocolRateBps \u002F 10 000"," des frais de swap, et la cagnotte le reste de cette\npart. Dans les contrats et leurs ABI, le camp B s’appelle ",[25,174,175],{},"D"," : ",[25,178,179],{},"d",[25,181,182],{},"tokenD",[25,184,185],{},"keyD",".",[14,188,189,190,152,193,152,196,152,199,202,203,152,206,152,209,212,213,186],{},"Le hook a des vues plus petites : ",[25,191,192],{},"pairCount()",[25,194,195],{},"getPair(pairId)",[25,197,198],{},"poolKeys(pairId)",[25,200,201],{},"gaugeBps(pairId)",",\n",[25,204,205],{},"snipeTaxBps(pairId)",[25,207,208],{},"protocolRateBps()",[25,210,211],{},"protocolFees()"," et ",[25,214,215],{},"firstRoundEnd(launchTime)",[18,217,219],{"id":218},"trader","Trader",[14,221,222,223,225],{},"N’importe quel router Uniswap V4 peut trader les pools d’un duel. Construisez les clés de pool à partir de\n",[25,224,198],{}," :",[227,228,229,251],"table",{},[230,231,232],"thead",{},[233,234,235,239,242,245,248],"tr",{},[236,237,238],"th",{},"Pool",[236,240,241],{},"currency0",[236,243,244],{},"currency1",[236,246,247],{},"fee",[236,249,250],{},"tickSpacing",[252,253,254,275,291],"tbody",{},[233,255,256,260,266,269,272],{},[257,258,259],"td",{},"ETH \u002F A",[257,261,262,263,65],{},"ETH (",[25,264,265],{},"address(0)",[257,267,268],{},"token A",[257,270,271],{},"0",[257,273,274],{},"200",[233,276,277,280,284,287,289],{},[257,278,279],{},"ETH \u002F B",[257,281,262,282,65],{},[25,283,265],{},[257,285,286],{},"token B",[257,288,271],{},[257,290,274],{},[233,292,293,296,299,302,304],{},[257,294,295],{},"A \u002F B",[257,297,298],{},"l’adresse de token la plus basse",[257,300,301],{},"la plus haute",[257,303,271],{},[257,305,306],{},"60",[14,308,309,310,313],{},"Le hook prélève ses frais par des return deltas : demandez vos cotations au V4 Quoter, dont les réponses incluent tous\nles frais et toutes les taxes. Un changement de camp par l’ETH se cote avec son ",[25,311,312],{},"quoteExactInput",", sur le chemin\ntoken → ETH → autre token.",[14,315,316,317,320,321,212,323,326,327,330,331,334,335,338],{},"Un swap dont le hook prend les frais avant son exécution (un achat ou un changement de camp à entrée exacte, une vente\nà sortie exacte) doit s’exécuter en entier : celui que sa limite de prix, ou un pool ETH à court d’ETH, arrêterait avant\nest annulé avec ",[25,318,319],{},"PartialFill",". Le PoolManager enveloppe l’erreur d’un hook : ",[25,322,319],{},[25,324,325],{},"ArbitrageStarved","\narrivent dans ",[25,328,329],{},"WrappedError(address target, bytes4 selector, bytes reason, bytes details)",", et dans\n",[25,332,333],{},"UnexpectedRevertBytes(bytes revertData)"," quand c’est le V4 Quoter qui les rapporte. Décodez ",[25,336,337],{},"reason"," pour lire l’erreur\ndu hook.",[14,340,341,342,344],{},"Chaque swap se termine par le réalignement du hook, qui a besoin de son propre gaz : un swap qui lui en laisse trop peu est annulé avec ",[25,343,325],{}," au lieu de le sauter. Envoyez les swaps avec le gaz qu’une estimation donne, jamais moins, et avec de la marge : le premier swap après la clôture d’un round règle aussi ce round (son rachat, puis un réalignement, environ 170 000 de gaz en plus), ce qu’une estimation faite avant la clôture ne compte pas. L’app ajoute 500 000 de gaz à chaque estimation.",[14,346,347,350],{},[25,348,349],{},"DuelRouter"," propose un appel pour un swap dans un pool :",[30,352,354],{"className":32,"code":353,"language":34,"meta":35,"style":35},"function swapExactIn(\n    PoolKey calldata key,\n    bool zeroForOne,\n    uint256 amountIn,\n    uint256 minAmountOut,\n    address recipient,\n    uint256 deadline\n) external payable returns (uint256 amountOut);\n",[25,355,356,366,379,390,401,411,422,430],{"__ignoreMap":35},[39,357,358,360,363],{"class":41,"line":42},[39,359,46],{"class":45},[39,361,362],{"class":49}," swapExactIn",[39,364,365],{"class":53},"(\n",[39,367,368,371,374,377],{"class":41,"line":90},[39,369,370],{"class":45},"    PoolKey",[39,372,373],{"class":45}," calldata",[39,375,376],{"class":61}," key",[39,378,202],{"class":53},[39,380,382,385,388],{"class":41,"line":381},3,[39,383,384],{"class":57},"    bool",[39,386,387],{"class":61}," zeroForOne",[39,389,202],{"class":53},[39,391,393,396,399],{"class":41,"line":392},4,[39,394,395],{"class":57},"    uint256",[39,397,398],{"class":61}," amountIn",[39,400,202],{"class":53},[39,402,404,406,409],{"class":41,"line":403},5,[39,405,395],{"class":57},[39,407,408],{"class":61}," minAmountOut",[39,410,202],{"class":53},[39,412,414,417,420],{"class":41,"line":413},6,[39,415,416],{"class":57},"    address",[39,418,419],{"class":61}," recipient",[39,421,202],{"class":53},[39,423,425,427],{"class":41,"line":424},7,[39,426,395],{"class":57},[39,428,429],{"class":61}," deadline\n",[39,431,433,435,437,440,442,444,446,449],{"class":41,"line":432},8,[39,434,65],{"class":53},[39,436,68],{"class":45},[39,438,439],{"class":45}," payable",[39,441,75],{"class":74},[39,443,78],{"class":53},[39,445,58],{"class":57},[39,447,448],{"class":61}," amountOut",[39,450,87],{"class":53},[14,452,453],{},"et un pour un changement de camp par l’ETH, le camp vendu dans son pool ETH et tout l’ETH obtenu dépensé dans celui de\nl’autre :",[30,455,457],{"className":32,"code":456,"language":34,"meta":35,"style":35},"function swapThroughEth(\n    PoolKey calldata keyIn,\n    PoolKey calldata keyOut,\n    uint256 amountIn,\n    uint256 minAmountOut,\n    address recipient,\n    uint256 deadline\n) external returns (uint256 amountOut);\n",[25,458,459,468,479,490,498,506,514,520],{"__ignoreMap":35},[39,460,461,463,466],{"class":41,"line":42},[39,462,46],{"class":45},[39,464,465],{"class":49}," swapThroughEth",[39,467,365],{"class":53},[39,469,470,472,474,477],{"class":41,"line":90},[39,471,370],{"class":45},[39,473,373],{"class":45},[39,475,476],{"class":61}," keyIn",[39,478,202],{"class":53},[39,480,481,483,485,488],{"class":41,"line":381},[39,482,370],{"class":45},[39,484,373],{"class":45},[39,486,487],{"class":61}," keyOut",[39,489,202],{"class":53},[39,491,492,494,496],{"class":41,"line":392},[39,493,395],{"class":57},[39,495,398],{"class":61},[39,497,202],{"class":53},[39,499,500,502,504],{"class":41,"line":403},[39,501,395],{"class":57},[39,503,408],{"class":61},[39,505,202],{"class":53},[39,507,508,510,512],{"class":41,"line":413},[39,509,416],{"class":57},[39,511,419],{"class":61},[39,513,202],{"class":53},[39,515,516,518],{"class":41,"line":424},[39,517,395],{"class":57},[39,519,429],{"class":61},[39,521,522,524,526,528,530,532,534],{"class":41,"line":432},[39,523,65],{"class":53},[39,525,68],{"class":45},[39,527,75],{"class":74},[39,529,78],{"class":53},[39,531,58],{"class":57},[39,533,448],{"class":61},[39,535,87],{"class":53},[14,537,538,539,542,543,546,547,550,551,554,555,558],{},"Une vente dans un pool ETH de Duel qui s’arrête au prix de lancement du pool, son ETH épuisé, est relancée pour le reste dans le même appel, une fois que le réalignement du hook a racheté au pool ce que le pool entre les camps absorbe : jusqu’à ",[25,540,541],{},"SALE_PASSES()"," (8) swaps, tant que le prix du pool reste sous la limite des swaps. Chacun paie les frais du hook sur son propre ETH, et ",[25,544,545],{},"minAmountOut"," les compte tous. Le V4 Quoter d’Uniswap cote un seul swap : au-delà de ce qu’il exécute, il répond ",[25,548,549],{},"NotEnoughLiquidity",". L’app cote une telle vente en exécutant le router comme le trader (un ",[25,552,553],{},"eth_call"," avec un state override, ",[25,556,557],{},"DuelSimulator",").",[14,560,561,562,565],{},"Ce que le réalignement ne peut plus racheter, ",[25,563,564],{},"sell"," l’emmène par le pool entre les camps jusque dans le pool ETH de l’autre camp, où les réalignements ont déplacé l’ETH qui le paie :",[30,567,569],{"className":32,"code":568,"language":34,"meta":35,"style":35},"function sell(\n    PoolKey calldata keyIn,\n    PoolKey calldata keyCross,\n    PoolKey calldata keyOther,\n    uint256 amountIn,\n    uint256 minAmountOut,\n    address recipient,\n    uint256 deadline\n) external returns (uint256 amountOut);\n",[25,570,571,580,590,601,612,620,628,636,642],{"__ignoreMap":35},[39,572,573,575,578],{"class":41,"line":42},[39,574,46],{"class":45},[39,576,577],{"class":49}," sell",[39,579,365],{"class":53},[39,581,582,584,586,588],{"class":41,"line":90},[39,583,370],{"class":45},[39,585,373],{"class":45},[39,587,476],{"class":61},[39,589,202],{"class":53},[39,591,592,594,596,599],{"class":41,"line":381},[39,593,370],{"class":45},[39,595,373],{"class":45},[39,597,598],{"class":61}," keyCross",[39,600,202],{"class":53},[39,602,603,605,607,610],{"class":41,"line":392},[39,604,370],{"class":45},[39,606,373],{"class":45},[39,608,609],{"class":61}," keyOther",[39,611,202],{"class":53},[39,613,614,616,618],{"class":41,"line":403},[39,615,395],{"class":57},[39,617,398],{"class":61},[39,619,202],{"class":53},[39,621,622,624,626],{"class":41,"line":413},[39,623,395],{"class":57},[39,625,408],{"class":61},[39,627,202],{"class":53},[39,629,630,632,634],{"class":41,"line":424},[39,631,416],{"class":57},[39,633,419],{"class":61},[39,635,202],{"class":53},[39,637,638,640],{"class":41,"line":432},[39,639,395],{"class":57},[39,641,429],{"class":61},[39,643,645,647,649,651,653,655,657],{"class":41,"line":644},9,[39,646,65],{"class":53},[39,648,68],{"class":45},[39,650,75],{"class":74},[39,652,78],{"class":53},[39,654,58],{"class":57},[39,656,448],{"class":61},[39,658,87],{"class":53},[14,660,661,662,665,666,669,670,673,674,677,678,680,681,683,684,687,688,690,691,694],{},"Il vend dans ",[25,663,664],{},"keyIn"," comme le fait ",[25,667,668],{},"swapExactIn",", puis ce qui reste par ",[25,671,672],{},"keyCross",", qui l’absorbe en entier (ses frais de changement de camp brûlés, comme pour tout changement de camp), et dans ",[25,675,676],{},"keyOther",", passe après passe là aussi. ",[25,679,545],{}," compte l’ETH des deux pools. Ce que ",[25,682,676],{}," ne peut pas racheter non plus est versé à ",[25,685,686],{},"recipient"," dans le token de ce pool, hors du minimum. L’app vend par ",[25,689,564],{}," quand le V4 Quoter refuse une vente et que ",[25,692,693],{},"DuelSimulator.simulateSale"," montre que cet appel vend tout contre de l’ETH.",[14,696,697],{},"Un autre router V4 fait un seul swap. Le hook ne refuse pas une vente à entrée exacte qui dépasse ce que l’ETH du pool peut payer (ses frais sont pris après le swap, sur l’ETH versé) : la vente s’exécute en partie, jusqu’au prix de lancement du pool, et le reste demeure chez le vendeur. Fixez le minimum reçu pour ce qui peut s’exécuter, et vendez le reste dans une transaction suivante, contre ce que le réalignement a racheté.",[14,699,700,701,703,704,152,707,710,711,714,715,718],{},"Envoyez de l’ETH avec ",[25,702,668],{}," pour acheter. Pour vendre ou changer de camp, approuvez le router pour le token, ou laissez\nun permit (EIP-2612) l’approuver dans la même transaction : ",[25,705,706],{},"swapExactInWithPermit",[25,708,709],{},"swapThroughEthWithPermit"," et\n",[25,712,713],{},"sellWithPermit"," prennent les mêmes arguments, plus le permit de l’appelant pour exactement ",[25,716,717],{},"amountIn",", signé pour le router :",[30,720,722],{"className":32,"code":721,"language":34,"meta":35,"style":35},"struct Permit {\n    uint256 deadline;\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n",[25,723,724,735,746,756,766,775],{"__ignoreMap":35},[39,725,726,729,732],{"class":41,"line":42},[39,727,728],{"class":45},"struct",[39,730,731],{"class":57}," Permit",[39,733,734],{"class":53}," {\n",[39,736,737,739,743],{"class":41,"line":90},[39,738,395],{"class":57},[39,740,742],{"class":741},"s8w-G"," deadline",[39,744,745],{"class":53},";\n",[39,747,748,751,754],{"class":41,"line":381},[39,749,750],{"class":57},"    uint8",[39,752,753],{"class":741}," v",[39,755,745],{"class":53},[39,757,758,761,764],{"class":41,"line":392},[39,759,760],{"class":57},"    bytes32",[39,762,763],{"class":741}," r",[39,765,745],{"class":53},[39,767,768,770,773],{"class":41,"line":403},[39,769,760],{"class":57},[39,771,772],{"class":741}," s",[39,774,745],{"class":53},[39,776,777],{"class":41,"line":413},[39,778,779],{"class":53},"}\n",[14,781,782,783,786,787,790,791,794,795,797],{},"Votre wallet signe les permits d’un token Duel dans le domaine EIP-712 de ce token, nommé ",[25,784,785],{},"Duel",", version ",[25,788,789],{},"1",", à l’adresse du token (son\n",[25,792,793],{},"eip712Domain()",", ERC-5267, l’indique). Le router utilise le permit d’abord et ignore son échec : un permit déjà envoyé\npar n’importe qui a posé l’autorisation, et un permit qui échoue ne change rien, le swap prenant alors ce que couvre\nl’autorisation déjà en place, et échouant si elle ne suffit pas. Un swap qui ne s’exécute qu’en partie conserve l’autorisation inutilisée.\nL’échéance du permit limite le moment où sa signature peut être présentée ; elle ne fait pas expirer l’autorisation déjà accordée. Le router ne prend\nde tokens qu’à l’appelant. L’ETH d’un changement de camp reste dans le PoolManager pour que le second pool le dépense ; un pool Duel le\ndépense en entier ou le hook annule le swap (",[25,796,319],{},"), et sur tout autre pool, ce qu’il ne peut pas dépenser\nrevient à l’appelant.",[18,799,801],{"id":800},"lancer-un-duel","Lancer un duel",[14,803,804,807,808,811,812,152,815,152,818,152,821,824,825,152,828,152,831,834,835,152,838,840,841,844,845,848,849,852,853,856,857,558],{},[25,805,806],{},"DuelFactory.createPair(CreateParams)"," lance un duel ; envoyez avec l’appel les frais de lancement et les achats de lancement, l’excédent est remboursé. ",[25,809,810],{},"CreateParams"," contient ",[25,813,814],{},"nameA",[25,816,817],{},"symbolA",[25,819,820],{},"nameD",[25,822,823],{},"symbolD"," (le camp B), ",[25,826,827],{},"metadataURI",[25,829,830],{},"buyA",[25,832,833],{},"buyD"," (l’ETH dépensé sur chaque camp au lancement, sans taxe anti-snipe), ",[25,836,837],{},"supporter",[25,839,159],{}," (selon la numérotation des catégories de l’app, 0 pour aucune) et ",[25,842,843],{},"config",", le ",[25,846,847],{},"configHash()"," de la factory tel que vous l’avez lu : le lancement est annulé avec ",[25,850,851],{},"ConfigChanged"," si les conditions ont changé depuis. Un nom fait de 1 à 128 octets, un ticker de 1 à 40 et l’URI des métadonnées 4 096 au plus (",[25,854,855],{},"InvalidMetadata",") ; un achat de lancement au-delà de 5 % de l’offre d’un camp est annulé (",[25,858,859],{},"CreatorBuyTooLarge",[14,861,862,863,866,867,870,871,874,875,878],{},"La factory démarre en pause. Tant que ",[25,864,865],{},"paused()"," est vrai, seul ",[25,868,869],{},"owner()"," peut lancer un duel ; les autres appels sont annulés avec ",[25,872,873],{},"CreationPaused",". Le propriétaire ouvre les lancements avec ",[25,876,877],{},"setPaused(false)",". Les duels existants continuent de s’échanger.",[18,880,882],{"id":881},"les-événements","Les événements",[227,884,885,898],{},[230,886,887],{},[233,888,889,892,895],{},[236,890,891],{},"Contrat",[236,893,894],{},"Événement",[236,896,897],{},"Quand",[252,899,900,913,929,941,953,965,977,989,1001,1013,1025,1037,1053,1071,1083],{},[233,901,902,905,910],{},[257,903,904],{},"DuelFactory",[257,906,907],{},[25,908,909],{},"PairCreated(pairId, creator, tokenA, tokenD)",[257,911,912],{},"Un duel a été lancé",[233,914,915,918,923],{},[257,916,917],{},"DuelHook",[257,919,920],{},[25,921,922],{},"PairRegistered(pairId, tokenA, tokenD, creator, category)",[257,924,925,926,928],{},"Ses pools enregistrés auprès du hook, dans la même transaction ; ",[25,927,159],{}," indique son sujet, selon la numérotation des catégories de l’app (0 pour aucune)",[233,930,931,933,938],{},[257,932,917],{},[257,934,935],{},[25,936,937],{},"FeeTaken(pairId, fee, snipeTax)",[257,939,940],{},"Un trade contre l’ETH a payé ses frais",[233,942,943,945,950],{},[257,944,917],{},[257,946,947],{},[25,948,949],{},"SwitchFeeBurned(pairId, token, amount)",[257,951,952],{},"Un changement de camp a brûlé ses frais",[233,954,955,957,962],{},[257,956,917],{},[257,958,959],{},[25,960,961],{},"ArbitrageCaptured(pairId, profit)",[257,963,964],{},"Le réalignement a rempli la cagnotte",[233,966,967,969,974],{},[257,968,917],{},[257,970,971],{},[25,972,973],{},"RoundSettled(pairId, roundIndex, averageTick, winner, ethSpent, tokensBurned)",[257,975,976],{},"Un round s’est clôturé",[233,978,979,981,986],{},[257,980,917],{},[257,982,983],{},[25,984,985],{},"CreatorFeesClaimed(pairId, to, amount)",[257,987,988],{},"Un créateur a été payé",[233,990,991,993,998],{},[257,992,904],{},[257,994,995],{},[25,996,997],{},"CreatorTransferStarted(pairId, creator, newCreator)",[257,999,1000],{},"Un créateur a proposé son rôle (à l’adresse zéro : proposition retirée)",[233,1002,1003,1005,1010],{},[257,1004,917],{},[257,1006,1007],{},[25,1008,1009],{},"CreatorChanged(pairId, from, to)",[257,1011,1012],{},"Le rôle de créateur d’un duel a changé de mains",[233,1014,1015,1017,1022],{},[257,1016,917],{},[257,1018,1019],{},[25,1020,1021],{},"CreatorFeesGivenUp(pairId, creator)",[257,1023,1024],{},"Le créateur a définitivement affecté sa part des frais futurs aux cagnottes",[233,1026,1027,1029,1034],{},[257,1028,917],{},[257,1030,1031],{},[25,1032,1033],{},"ProtocolFeesClaimed(to, amount)",[257,1035,1036],{},"La trésorerie a été payée",[233,1038,1039,1041,1046],{},[257,1040,917],{},[257,1042,1043],{},[25,1044,1045],{},"ProtocolRateSet(rateBps)",[257,1047,1048,1049,1052],{},"La part du protocole sur les frais de swap de tous les duels a changé d’un coup : il en prend ",[25,1050,1051],{},"rateBps"," (10 000 pour la totalité), le reste va aux cagnottes",[233,1054,1055,1057,1068],{},[257,1056,904],{},[257,1058,1059,152,1062,152,1065],{},[25,1060,1061],{},"ConfigProposed(config, eta)",[25,1063,1064],{},"ConfigApplied(config)",[25,1066,1067],{},"ConfigCancelled()",[257,1069,1070],{},"Des conditions de lancement proposées pour 48 heures plus tard, appliquées, retirées",[233,1072,1073,1075,1080],{},[257,1074,904],{},[257,1076,1077],{},[25,1078,1079],{},"PausedSet(paused)",[257,1081,1082],{},"Lancements mis en pause ou rouverts",[233,1084,1085,1088,1093],{},[257,1086,1087],{},"PoolManager",[257,1089,1090],{},[25,1091,1092],{},"Swap(id, sender, amount0, amount1, sqrtPriceX96, liquidity, tick, fee)",[257,1094,1095,1096,1099],{},"Chaque trade, y compris le réalignement du hook lui-même (son ",[25,1097,1098],{},"sender"," est le hook)",[14,1101,1102,1103,1106],{},"Les listes de trades lisent les swaps des trois pools ; les graphiques des prix et de la répartition lisent seulement les deux pools ETH. Les listes de détenteurs utilisent les événements ",[25,1104,1105],{},"Transfer"," des tokens. Le subgraph indexe les swaps, soldes, détenteurs et rounds réglés pour charger l’historique sans relire toute la chaîne depuis le lancement.",[18,1108,1110],{"id":1109},"régler-et-réclamer","Régler et réclamer",[1112,1113,1114,1121,1131,1149],"ul",{},[1115,1116,1117,1120],"li",{},[25,1118,1119],{},"settle(pairId)"," règle un round terminé. N’importe qui peut l’appeler.",[1115,1122,1123,1126,1127,1130],{},[25,1124,1125],{},"claimCreatorFees(pairId)"," paie seulement le créateur du duel, le wallet qui l’a lancé ou l’adresse à qui il a cédé son rôle ; ",[25,1128,1129],{},"claimProtocolFees()"," paie la trésorerie configurée au moment de la réclamation. N’importe qui peut déclencher ces appels. La trésorerie peut changer après le délai de 48 heures de la factory ; l’appelant ne peut pas choisir un autre destinataire.",[1115,1132,1133,1136,1137,1140,1141,1144,1145,1148],{},[25,1134,1135],{},"transferCreator(pairId, newCreator)"," sur la factory propose le rôle de créateur d’un duel, que ",[25,1138,1139],{},"acceptCreator(pairId)"," appelé par ",[25,1142,1143],{},"newCreator"," prend ; ",[25,1146,1147],{},"pendingCreator(pairId)"," lit la proposition. Seul le créateur le propose, et seule l’adresse proposée le prend.",[1115,1150,1151,1154],{},[25,1152,1153],{},"giveUpCreatorFees(pairId)"," sur le hook envoie définitivement la part du créateur sur les frais futurs aux cagnottes des rounds. Seul le créateur actuel peut l’appeler. Les frais déjà accumulés restent réclamables par le créateur, et le rôle de créateur peut toujours être transféré.",[1156,1157,1158],"style",{},"html pre.shiki code .s5TCs, html code.shiki .s5TCs{--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .s_xSY, html code.shiki .s_xSY{--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .si6no, html code.shiki .si6no{--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .s_NWU, html code.shiki .s_NWU{--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .s9nN2, html code.shiki .s9nN2{--shiki-default:#B07D48;--shiki-dark:#BD976A}html pre.shiki code .sTPum, html code.shiki .sTPum{--shiki-default:#1E754F;--shiki-dark:#4D9375}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8w-G, html code.shiki .s8w-G{--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}",{"title":35,"searchDepth":90,"depth":381,"links":1160},[1161,1162,1163,1164,1165],{"id":20,"depth":90,"text":21},{"id":218,"depth":90,"text":219},{"id":800,"depth":90,"text":801},{"id":881,"depth":90,"text":882},{"id":1109,"depth":90,"text":1110},null,"Lire les duels avec DuelLens, trader leurs pools avec DuelRouter ou tout router Uniswap V4, suivre les événements du hook : le guide des bots et agrégateurs.","md",{},true,"\u002Ffr\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate",{"title":5,"description":1167},"fr\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate","fvPv0zYeqi3gRYaccYw23Rd2uw5uh9MSPJqfcTKSzeA",1791232782215]