[{"data":1,"prerenderedAt":1178},["ShallowReactive",2],{"docs:ru:\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate":3},{"id":4,"title":5,"body":6,"cover":1169,"description":1170,"extension":1171,"meta":1172,"navigation":1173,"path":1174,"seo":1175,"stem":1176,"__hash__":1177},"docs\u002Fru\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate.md","Разработка на Duel",{"type":7,"value":8,"toc":1162},"minimark",[9,13,17,22,29,131,186,214,218,224,305,312,337,343,349,450,453,535,558,565,658,699,702,722,783,801,805,863,882,886,1103,1110,1114,1158],[10,11,5],"h1",{"id":12},"разработка-на-duel",[14,15,16],"p",{},"Пулы Duel — это стандартные пулы Uniswap V4 с hook, а каждое число, которое показывает приложение, берётся из публичных представлений и событий. Боты, терминалы, дашборды и агрегаторы могут строить на нём, ни у кого не спрашивая разрешения.",[18,19,21],"h2",{"id":20},"чтение-дуэли","Чтение дуэли",[14,23,24,28],{},[25,26,27],"code",{},"DuelLens"," собирает всё о дуэли одним вызовом:",[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,135,136,139,140,143,144,147,148,151,152,155,156,159,160,163,164,167,168,171,172,175,176,151,179,151,182,185],{},[25,134,81],{}," содержит идентификатор дуэли, её создателя и URI метаданных, обе стороны (токен, название, символ, эмиссию, цену и тик пула, ETH за токен, реальный ETH в пуле), три ключа пулов, соотношение в реальном времени (",[25,137,138],{},"gaugeBps",", доля стороны A в базисных пунктах), среднее раунда на текущий момент (",[25,141,142],{},"roundGaugeBps","), банк, комиссии создателя, объём и выкупы за всё время, текущий антиснайп-налог, номер, начало и конец раунда и то, были ли в нём сделки (",[25,145,146],{},"roundTraded","), время и тик запуска (",[25,149,150],{},"launchTime",", ",[25,153,154],{},"startTick","), то, является ли она дуэлью поддержки, её категорию (",[25,157,158],{},"category",", по нумерации приложения, 0 — без категории), условия её комиссий (",[25,161,162],{},"fees",") и ту часть своей доли, которую протокол берёт сейчас (",[25,165,166],{},"protocolRateBps",", из 10 000): протокол получает ",[25,169,170],{},"fees.protocolShareBps × protocolRateBps \u002F 10 000"," комиссии свопа, а банк — остаток этой доли. В контрактах и их ABI сторона B называется ",[25,173,174],{},"D",": ",[25,177,178],{},"d",[25,180,181],{},"tokenD",[25,183,184],{},"keyD",".",[14,187,188,189,151,192,151,195,151,198,151,201,151,204,151,207,210,211,185],{},"У hook есть и представления поменьше: ",[25,190,191],{},"pairCount()",[25,193,194],{},"getPair(pairId)",[25,196,197],{},"poolKeys(pairId)",[25,199,200],{},"gaugeBps(pairId)",[25,202,203],{},"snipeTaxBps(pairId)",[25,205,206],{},"protocolRateBps()",[25,208,209],{},"protocolFees()"," и ",[25,212,213],{},"firstRoundEnd(launchTime)",[18,215,217],{"id":216},"торговля","Торговля",[14,219,220,221,223],{},"Любой роутер Uniswap V4 может торговать в пулах дуэли. Соберите ключи пулов из ",[25,222,197],{},":",[225,226,227,249],"table",{},[228,229,230],"thead",{},[231,232,233,237,240,243,246],"tr",{},[234,235,236],"th",{},"Пул",[234,238,239],{},"currency0",[234,241,242],{},"currency1",[234,244,245],{},"fee",[234,247,248],{},"tickSpacing",[250,251,252,273,289],"tbody",{},[231,253,254,258,264,267,270],{},[255,256,257],"td",{},"ETH \u002F A",[255,259,260,261,65],{},"ETH (",[25,262,263],{},"address(0)",[255,265,266],{},"токен A",[255,268,269],{},"0",[255,271,272],{},"200",[231,274,275,278,282,285,287],{},[255,276,277],{},"ETH \u002F B",[255,279,260,280,65],{},[25,281,263],{},[255,283,284],{},"токен B",[255,286,269],{},[255,288,272],{},[231,290,291,294,297,300,302],{},[255,292,293],{},"A \u002F B",[255,295,296],{},"меньший адрес токена",[255,298,299],{},"больший",[255,301,269],{},[255,303,304],{},"60",[14,306,307,308,311],{},"Hook взимает комиссии через return deltas, поэтому запрашивайте котировки через V4 Quoter: его ответы учитывают все комиссии и налоги. Переход через ETH — это его ",[25,309,310],{},"quoteExactInput"," по пути токен → ETH → другой токен.",[14,313,314,315,318,319,210,321,324,325,328,329,332,333,336],{},"Своп, комиссию которого hook взимает до исполнения (покупка или переход с точным входом, продажа с точным выходом), должен исполниться полностью: своп, который его ценовой лимит или пул ETH с нехваткой ETH остановили бы раньше, откатывается с ",[25,316,317],{},"PartialFill",". PoolManager оборачивает ошибку hook: ",[25,320,317],{},[25,322,323],{},"ArbitrageStarved"," приходят внутри ",[25,326,327],{},"WrappedError(address target, bytes4 selector, bytes reason, bytes details)",", а когда о них сообщает V4 Quoter — внутри ",[25,330,331],{},"UnexpectedRevertBytes(bytes revertData)",". Декодируйте ",[25,334,335],{},"reason",", чтобы прочитать ошибку hook.",[14,338,339,340,342],{},"Каждая сделка завершается выравниванием, которое выполняет hook и которому нужен собственный газ: своп, оставляющий ему слишком мало газа, откатывается с ",[25,341,323],{},", а не пропускает его. Отправляйте свопы с газом из оценки, никак не меньше, и с запасом: первый своп после закрытия раунда заодно рассчитывает этот раунд (его выкуп, затем выравнивание — примерно на 170 000 газа больше), чего оценка, сделанная до закрытия, не учитывает. Приложение добавляет к каждой оценке 500 000 газа.",[14,344,345,348],{},[25,346,347],{},"DuelRouter"," предлагает один вызов для свопа в одном пуле:",[30,350,352],{"className":32,"code":351,"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,353,354,364,378,389,400,410,421,429],{"__ignoreMap":35},[39,355,356,358,361],{"class":41,"line":42},[39,357,46],{"class":45},[39,359,360],{"class":49}," swapExactIn",[39,362,363],{"class":53},"(\n",[39,365,366,369,372,375],{"class":41,"line":90},[39,367,368],{"class":45},"    PoolKey",[39,370,371],{"class":45}," calldata",[39,373,374],{"class":61}," key",[39,376,377],{"class":53},",\n",[39,379,381,384,387],{"class":41,"line":380},3,[39,382,383],{"class":57},"    bool",[39,385,386],{"class":61}," zeroForOne",[39,388,377],{"class":53},[39,390,392,395,398],{"class":41,"line":391},4,[39,393,394],{"class":57},"    uint256",[39,396,397],{"class":61}," amountIn",[39,399,377],{"class":53},[39,401,403,405,408],{"class":41,"line":402},5,[39,404,394],{"class":57},[39,406,407],{"class":61}," minAmountOut",[39,409,377],{"class":53},[39,411,413,416,419],{"class":41,"line":412},6,[39,414,415],{"class":57},"    address",[39,417,418],{"class":61}," recipient",[39,420,377],{"class":53},[39,422,424,426],{"class":41,"line":423},7,[39,425,394],{"class":57},[39,427,428],{"class":61}," deadline\n",[39,430,432,434,436,439,441,443,445,448],{"class":41,"line":431},8,[39,433,65],{"class":53},[39,435,68],{"class":45},[39,437,438],{"class":45}," payable",[39,440,75],{"class":74},[39,442,78],{"class":53},[39,444,58],{"class":57},[39,446,447],{"class":61}," amountOut",[39,449,87],{"class":53},[14,451,452],{},"и один для перехода через ETH: покидаемая сторона продаётся в своём пуле ETH, а весь полученный ETH тратится в пуле другой:",[30,454,456],{"className":32,"code":455,"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,457,458,467,478,489,497,505,513,519],{"__ignoreMap":35},[39,459,460,462,465],{"class":41,"line":42},[39,461,46],{"class":45},[39,463,464],{"class":49}," swapThroughEth",[39,466,363],{"class":53},[39,468,469,471,473,476],{"class":41,"line":90},[39,470,368],{"class":45},[39,472,371],{"class":45},[39,474,475],{"class":61}," keyIn",[39,477,377],{"class":53},[39,479,480,482,484,487],{"class":41,"line":380},[39,481,368],{"class":45},[39,483,371],{"class":45},[39,485,486],{"class":61}," keyOut",[39,488,377],{"class":53},[39,490,491,493,495],{"class":41,"line":391},[39,492,394],{"class":57},[39,494,397],{"class":61},[39,496,377],{"class":53},[39,498,499,501,503],{"class":41,"line":402},[39,500,394],{"class":57},[39,502,407],{"class":61},[39,504,377],{"class":53},[39,506,507,509,511],{"class":41,"line":412},[39,508,415],{"class":57},[39,510,418],{"class":61},[39,512,377],{"class":53},[39,514,515,517],{"class":41,"line":423},[39,516,394],{"class":57},[39,518,428],{"class":61},[39,520,521,523,525,527,529,531,533],{"class":41,"line":431},[39,522,65],{"class":53},[39,524,68],{"class":45},[39,526,75],{"class":74},[39,528,78],{"class":53},[39,530,58],{"class":57},[39,532,447],{"class":61},[39,534,87],{"class":53},[14,536,537,538,541,542,545,546,549,550,553,554,557],{},"Продажа в пул ETH Duel, которая останавливается на цене запуска пула, когда его ETH исчерпан, отправляется снова на остаток в том же вызове, как только выравнивание, которое выполняет hook, выкупит у пула то, что принимает пул между сторонами: до ",[25,539,540],{},"SALE_PASSES()"," (8) свопов, пока цена пула ниже лимита свопов. Каждый платит комиссию hook со своего ETH, а ",[25,543,544],{},"minAmountOut"," учитывает их все. V4 Quoter Uniswap котирует один своп: сверх того, что он исполняет, он отвечает ",[25,547,548],{},"NotEnoughLiquidity",". Приложение котирует такую продажу, выполняя роутер от имени трейдера (",[25,551,552],{},"eth_call"," с переопределением состояния, ",[25,555,556],{},"DuelSimulator",").",[14,559,560,561,564],{},"То, что выравнивание уже не может выкупить, ",[25,562,563],{},"sell"," проводит дальше через пул между сторонами в пул ETH другой стороны, куда выравнивания перенесли ETH, который за это платит:",[30,566,568],{"className":32,"code":567,"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,569,570,579,589,600,611,619,627,635,641],{"__ignoreMap":35},[39,571,572,574,577],{"class":41,"line":42},[39,573,46],{"class":45},[39,575,576],{"class":49}," sell",[39,578,363],{"class":53},[39,580,581,583,585,587],{"class":41,"line":90},[39,582,368],{"class":45},[39,584,371],{"class":45},[39,586,475],{"class":61},[39,588,377],{"class":53},[39,590,591,593,595,598],{"class":41,"line":380},[39,592,368],{"class":45},[39,594,371],{"class":45},[39,596,597],{"class":61}," keyCross",[39,599,377],{"class":53},[39,601,602,604,606,609],{"class":41,"line":391},[39,603,368],{"class":45},[39,605,371],{"class":45},[39,607,608],{"class":61}," keyOther",[39,610,377],{"class":53},[39,612,613,615,617],{"class":41,"line":402},[39,614,394],{"class":57},[39,616,397],{"class":61},[39,618,377],{"class":53},[39,620,621,623,625],{"class":41,"line":412},[39,622,394],{"class":57},[39,624,407],{"class":61},[39,626,377],{"class":53},[39,628,629,631,633],{"class":41,"line":423},[39,630,415],{"class":57},[39,632,418],{"class":61},[39,634,377],{"class":53},[39,636,637,639],{"class":41,"line":431},[39,638,394],{"class":57},[39,640,428],{"class":61},[39,642,644,646,648,650,652,654,656],{"class":41,"line":643},9,[39,645,65],{"class":53},[39,647,68],{"class":45},[39,649,75],{"class":74},[39,651,78],{"class":53},[39,653,58],{"class":57},[39,655,447],{"class":61},[39,657,87],{"class":53},[14,659,660,662,663,666,667,670,671,674,675,678,679,681,682,684,685,688,689,691,692,695,696,698],{},[25,661,563],{}," продаёт в ",[25,664,665],{},"keyIn"," так же, как ",[25,668,669],{},"swapExactIn",", затем остаток — через ",[25,672,673],{},"keyCross",", который принимает всё (его комиссия перехода сжигается, как при любом переходе), и в ",[25,676,677],{},"keyOther",", тоже проход за проходом. ",[25,680,544],{}," учитывает ETH обоих пулов. То, что не может выкупить и ",[25,683,677],{},", выплачивается ",[25,686,687],{},"recipient"," в токене этого пула и не учитывается в минимальном выходе. Приложение продаёт через ",[25,690,563],{},", когда V4 Quoter отклоняет продажу, а ",[25,693,694],{},"DuelSimulator.simulateSale"," показывает, что ",[25,697,563],{}," продаст всё за ETH.",[14,700,701],{},"Другой роутер V4 делает один своп. Продажу с точным входом сверх того, что может оплатить ETH пула, hook не отклоняет (его комиссия берётся после свопа, с выплаченного ETH): продажа исполняется частично, до цены запуска пула, а остаток остаётся у продавца. Задайте минимальный выход под то, что может исполниться, а остаток продайте следующей транзакцией — в то, что выкупило выравнивание.",[14,703,704,705,707,708,151,711,210,714,717,718,721],{},"Чтобы купить, отправьте ETH вместе с ",[25,706,669],{},". Чтобы продать или перейти, одобрите роутеру токен или позвольте permit (EIP-2612) сделать это в той же транзакции: ",[25,709,710],{},"swapExactInWithPermit",[25,712,713],{},"swapThroughEthWithPermit",[25,715,716],{},"sellWithPermit"," принимают те же аргументы плюс permit вызывающего ровно на ",[25,719,720],{},"amountIn",", подписанный для роутера:",[30,723,725],{"className":32,"code":724,"language":34,"meta":35,"style":35},"struct Permit {\n    uint256 deadline;\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n",[25,726,727,738,749,759,769,778],{"__ignoreMap":35},[39,728,729,732,735],{"class":41,"line":42},[39,730,731],{"class":45},"struct",[39,733,734],{"class":57}," Permit",[39,736,737],{"class":53}," {\n",[39,739,740,742,746],{"class":41,"line":90},[39,741,394],{"class":57},[39,743,745],{"class":744},"s8w-G"," deadline",[39,747,748],{"class":53},";\n",[39,750,751,754,757],{"class":41,"line":380},[39,752,753],{"class":57},"    uint8",[39,755,756],{"class":744}," v",[39,758,748],{"class":53},[39,760,761,764,767],{"class":41,"line":391},[39,762,763],{"class":57},"    bytes32",[39,765,766],{"class":744}," r",[39,768,748],{"class":53},[39,770,771,773,776],{"class":41,"line":402},[39,772,763],{"class":57},[39,774,775],{"class":744}," s",[39,777,748],{"class":53},[39,779,780],{"class":41,"line":412},[39,781,782],{"class":53},"}\n",[14,784,785,786,789,790,793,794,797,798,800],{},"Для каждого токена Duel владелец кошелька подписывает permit в домене EIP-712 с именем ",[25,787,788],{},"Duel",", версией ",[25,791,792],{},"1",", привязанном к адресу этого токена (об этом сообщает его ",[25,795,796],{},"eip712Domain()",", ERC-5267). Роутер сначала использует permit и игнорирует его неудачу: permit, уже отправленный кем угодно, установил разрешение, а неудачный ничего не меняет; тогда своп берёт то, что покрывает уже действующее разрешение, и откатывается, если его не хватает. После частично исполненного свопа неиспользованная часть разрешения остаётся действующей: срок permit ограничивает, когда можно использовать подпись, но не прекращает уже выданное разрешение. Роутер забирает токены только у вызывающего. ETH перехода остаётся в PoolManager, чтобы его потратил второй пул; пул Duel тратит его целиком, иначе hook откатывает своп (",[25,799,317],{},"), а на любом другом пуле то, что он не может потратить, возвращается вызывающему.",[18,802,804],{"id":803},"запуск-дуэли","Запуск дуэли",[14,806,807,810,811,814,815,151,818,151,821,151,824,827,828,151,831,151,834,837,838,151,841,843,844,847,848,851,852,855,856,859,860,557],{},[25,808,809],{},"DuelFactory.createPair(CreateParams)"," запускает дуэль; отправьте вместе с вызовом комиссию запуска и покупки при запуске, излишек возвращается. ",[25,812,813],{},"CreateParams"," — это ",[25,816,817],{},"nameA",[25,819,820],{},"symbolA",[25,822,823],{},"nameD",[25,825,826],{},"symbolD"," (сторона B), ",[25,829,830],{},"metadataURI",[25,832,833],{},"buyA",[25,835,836],{},"buyD"," (ETH, потраченный на каждую сторону при запуске, без антиснайп-налога), ",[25,839,840],{},"supporter",[25,842,158],{}," (по нумерации категорий в приложении, 0 — без категории) и ",[25,845,846],{},"config"," — ",[25,849,850],{},"configHash()"," фабрики в том виде, в каком вы его прочитали: запуск откатывается с ",[25,853,854],{},"ConfigChanged",", если условия с тех пор изменились. Название занимает от 1 до 128 байт, тикер — от 1 до 40, а URI метаданных — не более 4 096 (",[25,857,858],{},"InvalidMetadata","); покупка при запуске свыше 5 % эмиссии стороны откатывается (",[25,861,862],{},"CreatorBuyTooLarge",[14,864,865,866,869,870,873,874,877,878,881],{},"Фабрика начинает работу с приостановленными запусками. Пока ",[25,867,868],{},"paused()"," равно true, запустить дуэль может только ",[25,871,872],{},"owner()","; вызовы остальных откатываются с ",[25,875,876],{},"CreationPaused",". Владелец открывает запуски через ",[25,879,880],{},"setPaused(false)",". Существующие дуэли продолжают торговаться.",[18,883,885],{"id":884},"события","События",[225,887,888,901],{},[228,889,890],{},[231,891,892,895,898],{},[234,893,894],{},"Контракт",[234,896,897],{},"Событие",[234,899,900],{},"Когда",[250,902,903,916,932,944,956,968,980,992,1004,1016,1028,1040,1056,1074,1086],{},[231,904,905,908,913],{},[255,906,907],{},"DuelFactory",[255,909,910],{},[25,911,912],{},"PairCreated(pairId, creator, tokenA, tokenD)",[255,914,915],{},"Запущена дуэль",[231,917,918,921,926],{},[255,919,920],{},"DuelHook",[255,922,923],{},[25,924,925],{},"PairRegistered(pairId, tokenA, tokenD, creator, category)",[255,927,928,929,931],{},"Её пулы зарегистрированы в hook, в той же транзакции; ",[25,930,158],{}," — её тема, по нумерации категорий в приложении (0 — без категории)",[231,933,934,936,941],{},[255,935,920],{},[255,937,938],{},[25,939,940],{},"FeeTaken(pairId, fee, snipeTax)",[255,942,943],{},"Сделка в паре с ETH заплатила комиссию",[231,945,946,948,953],{},[255,947,920],{},[255,949,950],{},[25,951,952],{},"SwitchFeeBurned(pairId, token, amount)",[255,954,955],{},"Переход сжёг свою комиссию",[231,957,958,960,965],{},[255,959,920],{},[255,961,962],{},[25,963,964],{},"ArbitrageCaptured(pairId, profit)",[255,966,967],{},"Выравнивание пополнило банк",[231,969,970,972,977],{},[255,971,920],{},[255,973,974],{},[25,975,976],{},"RoundSettled(pairId, roundIndex, averageTick, winner, ethSpent, tokensBurned)",[255,978,979],{},"Раунд закрыт",[231,981,982,984,989],{},[255,983,920],{},[255,985,986],{},[25,987,988],{},"CreatorFeesClaimed(pairId, to, amount)",[255,990,991],{},"Создателю выплачено",[231,993,994,996,1001],{},[255,995,907],{},[255,997,998],{},[25,999,1000],{},"CreatorTransferStarted(pairId, creator, newCreator)",[255,1002,1003],{},"Создатель предложил свою роль (нулевому адресу — предложение отозвано)",[231,1005,1006,1008,1013],{},[255,1007,920],{},[255,1009,1010],{},[25,1011,1012],{},"CreatorChanged(pairId, from, to)",[255,1014,1015],{},"Роль создателя дуэли перешла к другому",[231,1017,1018,1020,1025],{},[255,1019,920],{},[255,1021,1022],{},[25,1023,1024],{},"CreatorFeesGivenUp(pairId, creator)",[255,1026,1027],{},"Создатель навсегда направил свою долю будущих комиссий в банки",[231,1029,1030,1032,1037],{},[255,1031,920],{},[255,1033,1034],{},[25,1035,1036],{},"ProtocolFeesClaimed(to, amount)",[255,1038,1039],{},"Казначейству выплачено",[231,1041,1042,1044,1049],{},[255,1043,920],{},[255,1045,1046],{},[25,1047,1048],{},"ProtocolRateSet(rateBps)",[255,1050,1051,1052,1055],{},"Доля протокола в комиссии за своп всех дуэлей сразу изменилась: он берёт из неё ",[25,1053,1054],{},"rateBps"," (10 000 — всю), остальное идёт в банки",[231,1057,1058,1060,1071],{},[255,1059,907],{},[255,1061,1062,151,1065,151,1068],{},[25,1063,1064],{},"ConfigProposed(config, eta)",[25,1066,1067],{},"ConfigApplied(config)",[25,1069,1070],{},"ConfigCancelled()",[255,1072,1073],{},"Условия запуска предложены на 48 часов вперёд, применены, отозваны",[231,1075,1076,1078,1083],{},[255,1077,907],{},[255,1079,1080],{},[25,1081,1082],{},"PausedSet(paused)",[255,1084,1085],{},"Запуски приостановлены или возобновлены",[231,1087,1088,1091,1096],{},[255,1089,1090],{},"PoolManager",[255,1092,1093],{},[25,1094,1095],{},"Swap(id, sender, amount0, amount1, sqrtPriceX96, liquidity, tick, fee)",[255,1097,1098,1099,1102],{},"Каждая сделка, включая выравнивание самого hook (его ",[25,1100,1101],{},"sender"," — это hook)",[14,1104,1105,1106,1109],{},"Списки сделок читают свопы из всех трёх пулов; графики цены и соотношения читают только два пула ETH. Списки холдеров используют события ",[25,1107,1108],{},"Transfer"," токенов. Subgraph индексирует свопы, балансы, холдеров и рассчитанные раунды, чтобы приложение могло загрузить историю, не проигрывая сеть заново с момента запуска.",[18,1111,1113],{"id":1112},"расчёт-и-выплаты","Расчёт и выплаты",[1115,1116,1117,1124,1134,1152],"ul",{},[1118,1119,1120,1123],"li",{},[25,1121,1122],{},"settle(pairId)"," рассчитывает завершённый раунд. Вызвать её может кто угодно.",[1118,1125,1126,1129,1130,1133],{},[25,1127,1128],{},"claimCreatorFees(pairId)"," платит только создателю дуэли — кошельку, который её запустил, или адресу, которому он передал роль; ",[25,1131,1132],{},"claimProtocolFees()"," платит казначейству, указанному на момент выплаты. Запустить любую из этих выплат может кто угодно. Казначейство может смениться после 48-часовой задержки фабрики; вызывающий не может выбрать другого получателя.",[1118,1135,1136,1139,1140,1143,1144,1147,1148,1151],{},[25,1137,1138],{},"transferCreator(pairId, newCreator)"," на фабрике предлагает роль создателя дуэли, которую принимает ",[25,1141,1142],{},"acceptCreator(pairId)",", вызванная с ",[25,1145,1146],{},"newCreator","; ",[25,1149,1150],{},"pendingCreator(pairId)"," читает предложение. Предлагает роль только создатель, а принимает только адрес, которому она предложена.",[1118,1153,1154,1157],{},[25,1155,1156],{},"giveUpCreatorFees(pairId)"," в hook навсегда направляет долю создателя в будущих комиссиях в банки. Вызвать функцию может только текущий создатель. Уже накопленные комиссии по-прежнему доступны создателю, а роль создателя по-прежнему можно передать.",[1159,1160,1161],"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":380,"links":1163},[1164,1165,1166,1167,1168],{"id":20,"depth":90,"text":21},{"id":216,"depth":90,"text":217},{"id":803,"depth":90,"text":804},{"id":884,"depth":90,"text":885},{"id":1112,"depth":90,"text":1113},null,"Чтение дуэлей через DuelLens, торговля в их пулах Uniswap V4 через любой роутер V4 или DuelRouter, события hook: руководство для ботов и агрегаторов.","md",{},true,"\u002Fru\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate",{"title":5,"description":1170},"ru\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate","GXR9BI0CWbbjff2kVdNWca5wsNfE-MLE94b7FNN40Ys",1791232796964]