[{"data":1,"prerenderedAt":1174},["ShallowReactive",2],{"docs:en:\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate":3},{"id":4,"title":5,"body":6,"cover":1165,"description":1166,"extension":1167,"meta":1168,"navigation":1169,"path":1170,"seo":1171,"stem":1172,"__hash__":1173},"docs\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate.md","Build on Duel",{"type":7,"value":8,"toc":1158},"minimark",[9,13,17,22,29,131,187,216,220,226,307,314,339,345,351,451,454,536,559,566,659,695,698,718,779,797,801,859,878,882,1099,1106,1110,1154],[10,11,5],"h1",{"id":12},"build-on-duel",[14,15,16],"p",{},"Duel's pools are standard Uniswap V4 pools with a hook, and every number the app shows comes from public views and\nevents. Bots, terminals, dashboards and aggregators can build on it without asking.",[18,19,21],"h2",{"id":20},"reading-a-duel","Reading a duel",[14,23,24,28],{},[25,26,27],"code",{},"DuelLens"," gathers everything about a duel in one call:",[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],{},"A ",[25,135,81],{}," holds the duel's id, creator and metadata URI, both sides (token, name, symbol, supply, pool price and\ntick, ETH per token, real ETH in the pool), the three pool keys, the live split (",[25,138,139],{},"gaugeBps",", side A's share in basis\npoints), the round's average so far (",[25,142,143],{},"roundGaugeBps","), the pot, the creator fees, the all-time volume and buybacks, the\ncurrent anti-snipe tax, the round's index, start and end and whether it traded (",[25,146,147],{},"roundTraded","), the launch time and tick\n(",[25,150,151],{},"launchTime",", ",[25,154,155],{},"startTick","), whether it is a supporter duel, its category (",[25,158,159],{},"category",", as the app numbers them, 0 for\nnone), its fee terms (",[25,162,163],{},"fees",") and the part of its share the protocol takes now (",[25,166,167],{},"protocolRateBps",", out of 10,000): the\nprotocol gets ",[25,170,171],{},"fees.protocolShareBps × protocolRateBps \u002F 10,000"," of the swap fee, and the pot the rest of that share. In\nthe contracts and their ABIs, side B is ",[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],{},"The hook has smaller views: ",[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()"," and ",[25,214,215],{},"firstRoundEnd(launchTime)",[18,217,219],{"id":218},"trading","Trading",[14,221,222,223,225],{},"Any Uniswap V4 router can trade a duel's pools. Build the pool keys from ",[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],{},"the lower token address",[257,300,301],{},"the higher one",[257,303,271],{},[257,305,306],{},"60",[14,308,309,310,313],{},"The hook takes its fees through return deltas, so quote with the V4 Quoter: its answers include every fee and tax. A\nswitch through ETH is its ",[25,311,312],{},"quoteExactInput"," along the path token → ETH → other token.",[14,315,316,317,320,321,212,323,326,327,330,331,334,335,338],{},"A swap whose fee the hook takes before it runs (an exact-input buy or switch, an exact-output sell) must fill\ncompletely: one that its price limit, or an ETH pool short of ETH, would stop early reverts with ",[25,318,319],{},"PartialFill",". The\nPoolManager wraps a hook's error: ",[25,322,319],{},[25,324,325],{},"ArbitrageStarved"," arrive inside\n",[25,328,329],{},"WrappedError(address target, bytes4 selector, bytes reason, bytes details)",", and inside\n",[25,332,333],{},"UnexpectedRevertBytes(bytes revertData)"," when the V4 Quoter reports them. Decode ",[25,336,337],{},"reason"," to read the hook's error.",[14,340,341,342,344],{},"Each trade ends with the hook’s realignment, which needs gas of its own: a swap that leaves it too little reverts with ",[25,343,325],{}," rather than skipping it. Send swaps with the gas an estimate gives, never less, and with headroom: the first swap after a round's close also settles the round (its buyback, then a realignment, some 170,000 gas more), which an estimate made before the close does not count. The app adds 500,000 gas to each estimate.",[14,346,347,350],{},[25,348,349],{},"DuelRouter"," offers one call for a swap in one 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],{},"and one for a switch through ETH, the side sold in its ETH pool and all the ETH it gives spent in the other's:",[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],{},"A sale into a Duel ETH pool that stops at the pool's launch price, its ETH spent, is sent again for the rest in the same call, once the hook's realignment has bought back from the pool what the pool between the sides takes: up to ",[25,540,541],{},"SALE_PASSES()"," (8) swaps, while the pool's price is under the swaps' limit. Each pays the hook's fee on its own ETH, and ",[25,544,545],{},"minAmountOut"," counts them all. Uniswap's V4 Quoter quotes one swap: past what it fills, it answers ",[25,548,549],{},"NotEnoughLiquidity",". The app quotes such a sale by running the router as the trader (an ",[25,552,553],{},"eth_call"," with a state override, ",[25,556,557],{},"DuelSimulator",").",[14,560,561,562,565],{},"What the realignment can no longer buy back, ",[25,563,564],{},"sell"," takes on through the pool between the sides into the other side's ETH pool, where the realignments moved the ETH that pays for it:",[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],{},"It sells into ",[25,663,664],{},"keyIn"," as ",[25,667,668],{},"swapExactIn"," does, then what is left through ",[25,671,672],{},"keyCross",", which takes it all (its switch fee burned, as on any switch), and into ",[25,675,676],{},"keyOther",", pass after pass too. ",[25,679,545],{}," counts the ETH of both pools. What ",[25,682,676],{}," cannot buy back either is paid to ",[25,685,686],{},"recipient"," in its token, outside the minimum. The app sells through ",[25,689,564],{}," when the quoter refuses a sale and ",[25,692,693],{},"DuelSimulator.simulateSale"," shows it selling everything for ETH.",[14,696,697],{},"Another V4 router makes one swap. The hook does not refuse an exact-input sale past what the pool's ETH pays for (its fee is taken after the swap, on the ETH paid out): the sale fills in part, down to the pool's launch price, and the rest stays with the seller. Set the minimum output for what can fill, and sell the rest in a later transaction, into what the realignment bought back.",[14,699,700,701,703,704,152,707,212,710,713,714,717],{},"Send ETH with ",[25,702,668],{}," to buy. To sell or switch, approve the router for the token, or let a permit (EIP-2612)\napprove it in the same transaction: ",[25,705,706],{},"swapExactInWithPermit",[25,708,709],{},"swapThroughEthWithPermit",[25,711,712],{},"sellWithPermit"," take the same\narguments and the caller's permit for exactly ",[25,715,716],{},"amountIn",", signed for the router:",[30,719,721],{"className":32,"code":720,"language":34,"meta":35,"style":35},"struct Permit {\n    uint256 deadline;\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n",[25,722,723,734,745,755,765,774],{"__ignoreMap":35},[39,724,725,728,731],{"class":41,"line":42},[39,726,727],{"class":45},"struct",[39,729,730],{"class":57}," Permit",[39,732,733],{"class":53}," {\n",[39,735,736,738,742],{"class":41,"line":90},[39,737,395],{"class":57},[39,739,741],{"class":740},"s8w-G"," deadline",[39,743,744],{"class":53},";\n",[39,746,747,750,753],{"class":41,"line":381},[39,748,749],{"class":57},"    uint8",[39,751,752],{"class":740}," v",[39,754,744],{"class":53},[39,756,757,760,763],{"class":41,"line":392},[39,758,759],{"class":57},"    bytes32",[39,761,762],{"class":740}," r",[39,764,744],{"class":53},[39,766,767,769,772],{"class":41,"line":403},[39,768,759],{"class":57},[39,770,771],{"class":740}," s",[39,773,744],{"class":53},[39,775,776],{"class":41,"line":413},[39,777,778],{"class":53},"}\n",[14,780,781,782,785,786,789,790,793,794,796],{},"Your wallet signs a Duel token’s permits in that token’s EIP-712 domain named ",[25,783,784],{},"Duel",", version ",[25,787,788],{},"1",", using the token’s address (its\n",[25,791,792],{},"eip712Domain()",", ERC-5267, says so). The router uses the permit first and ignores its failure: one already sent by\nanyone has set the allowance, and one that fails changes nothing, the swap then taking what the allowance already\nstanding covers and reverting if it falls short. A swap that fills only in part leaves the unused allowance in place:\nthe permit deadline limits when its signature can be submitted; it does not expire an allowance already granted. The router only pulls tokens from the caller.\nThe ETH of a switch stays in the PoolManager for the second pool to spend; a Duel pool spends it all or the hook reverts the swap (",[25,795,319],{},"), and on any other pool what it cannot spend is paid back to the caller.",[18,798,800],{"id":799},"launching","Launching",[14,802,803,806,807,810,811,152,814,152,817,152,820,823,824,152,827,152,830,833,834,152,837,839,840,843,844,847,848,851,852,855,856,558],{},[25,804,805],{},"DuelFactory.createPair(CreateParams)"," launches a duel; send the launch fee and the launch buys with it, any excess is refunded. ",[25,808,809],{},"CreateParams"," is ",[25,812,813],{},"nameA",[25,815,816],{},"symbolA",[25,818,819],{},"nameD",[25,821,822],{},"symbolD"," (side B), ",[25,825,826],{},"metadataURI",[25,828,829],{},"buyA",[25,831,832],{},"buyD"," (the ETH spent on each side at launch, free of the anti-snipe tax), ",[25,835,836],{},"supporter",[25,838,159],{}," (as the app numbers its categories, 0 for none) and ",[25,841,842],{},"config",", the factory's ",[25,845,846],{},"configHash()"," as you read it: the launch reverts with ",[25,849,850],{},"ConfigChanged"," if the terms changed since. A name takes 1 to 128 bytes, a ticker 1 to 40 and the metadata URI 4,096 at most (",[25,853,854],{},"InvalidMetadata","); a launch buy above 5% of a side's supply reverts (",[25,857,858],{},"CreatorBuyTooLarge",[14,860,861,862,865,866,869,870,873,874,877],{},"The factory starts paused. While ",[25,863,864],{},"paused()"," is true, only ",[25,867,868],{},"owner()"," can launch a duel; other callers revert with ",[25,871,872],{},"CreationPaused",". The owner opens launches with ",[25,875,876],{},"setPaused(false)",". Existing duels keep trading.",[18,879,881],{"id":880},"events","Events",[227,883,884,897],{},[230,885,886],{},[233,887,888,891,894],{},[236,889,890],{},"Contract",[236,892,893],{},"Event",[236,895,896],{},"When",[252,898,899,912,928,940,952,964,976,988,1000,1012,1024,1036,1052,1070,1082],{},[233,900,901,904,909],{},[257,902,903],{},"DuelFactory",[257,905,906],{},[25,907,908],{},"PairCreated(pairId, creator, tokenA, tokenD)",[257,910,911],{},"A duel launched",[233,913,914,917,922],{},[257,915,916],{},"DuelHook",[257,918,919],{},[25,920,921],{},"PairRegistered(pairId, tokenA, tokenD, creator, category)",[257,923,924,925,927],{},"Its pools registered with the hook, in the same transaction; ",[25,926,159],{}," is what it is about, as the app numbers its categories (0 for none)",[233,929,930,932,937],{},[257,931,916],{},[257,933,934],{},[25,935,936],{},"FeeTaken(pairId, fee, snipeTax)",[257,938,939],{},"A trade against ETH paid its fee",[233,941,942,944,949],{},[257,943,916],{},[257,945,946],{},[25,947,948],{},"SwitchFeeBurned(pairId, token, amount)",[257,950,951],{},"A switch burned its fee",[233,953,954,956,961],{},[257,955,916],{},[257,957,958],{},[25,959,960],{},"ArbitrageCaptured(pairId, profit)",[257,962,963],{},"The realignment filled the pot",[233,965,966,968,973],{},[257,967,916],{},[257,969,970],{},[25,971,972],{},"RoundSettled(pairId, roundIndex, averageTick, winner, ethSpent, tokensBurned)",[257,974,975],{},"A round closed",[233,977,978,980,985],{},[257,979,916],{},[257,981,982],{},[25,983,984],{},"CreatorFeesClaimed(pairId, to, amount)",[257,986,987],{},"A creator was paid",[233,989,990,992,997],{},[257,991,903],{},[257,993,994],{},[25,995,996],{},"CreatorTransferStarted(pairId, creator, newCreator)",[257,998,999],{},"A creator offered its role (to the zero address: the offer withdrawn)",[233,1001,1002,1004,1009],{},[257,1003,916],{},[257,1005,1006],{},[25,1007,1008],{},"CreatorChanged(pairId, from, to)",[257,1010,1011],{},"A duel’s creator role changed hands",[233,1013,1014,1016,1021],{},[257,1015,916],{},[257,1017,1018],{},[25,1019,1020],{},"CreatorFeesGivenUp(pairId, creator)",[257,1022,1023],{},"The creator permanently redirected its share of future fees to the pots",[233,1025,1026,1028,1033],{},[257,1027,916],{},[257,1029,1030],{},[25,1031,1032],{},"ProtocolFeesClaimed(to, amount)",[257,1034,1035],{},"The treasury was paid",[233,1037,1038,1040,1045],{},[257,1039,916],{},[257,1041,1042],{},[25,1043,1044],{},"ProtocolRateSet(rateBps)",[257,1046,1047,1048,1051],{},"The protocol's share of every duel's swap fee changed at once: it takes ",[25,1049,1050],{},"rateBps"," of it (10,000 for all), the rest goes to the pots",[233,1053,1054,1056,1067],{},[257,1055,903],{},[257,1057,1058,152,1061,152,1064],{},[25,1059,1060],{},"ConfigProposed(config, eta)",[25,1062,1063],{},"ConfigApplied(config)",[25,1065,1066],{},"ConfigCancelled()",[257,1068,1069],{},"Launch terms proposed for 48 hours ahead, applied, withdrawn",[233,1071,1072,1074,1079],{},[257,1073,903],{},[257,1075,1076],{},[25,1077,1078],{},"PausedSet(paused)",[257,1080,1081],{},"Launches paused or resumed",[233,1083,1084,1087,1092],{},[257,1085,1086],{},"PoolManager",[257,1088,1089],{},[25,1090,1091],{},"Swap(id, sender, amount0, amount1, sqrtPriceX96, liquidity, tick, fee)",[257,1093,1094,1095,1098],{},"Every trade, including the hook's own realignment (its ",[25,1096,1097],{},"sender"," is the hook)",[14,1100,1101,1102,1105],{},"Trade lists read swaps from all three pools; the price and split charts read the two ETH pools only. Holder lists use token ",[25,1103,1104],{},"Transfer"," events. The subgraph indexes swaps, balances, holders and settled rounds so the app can load history without replaying the chain from launch.",[18,1107,1109],{"id":1108},"settling-and-claiming","Settling and claiming",[1111,1112,1113,1120,1130,1148],"ul",{},[1114,1115,1116,1119],"li",{},[25,1117,1118],{},"settle(pairId)"," settles a finished round. Anyone can call it.",[1114,1121,1122,1125,1126,1129],{},[25,1123,1124],{},"claimCreatorFees(pairId)"," pays only the duel’s creator, the launching wallet or the address it handed its role to; ",[25,1127,1128],{},"claimProtocolFees()"," pays the treasury configured at claim time. Anyone can trigger either claim. The treasury can change after the factory’s 48-hour delay; a caller cannot choose a different recipient.",[1114,1131,1132,1135,1136,1139,1140,1143,1144,1147],{},[25,1133,1134],{},"transferCreator(pairId, newCreator)"," on the factory offers a duel’s creator role, which ",[25,1137,1138],{},"acceptCreator(pairId)"," from ",[25,1141,1142],{},"newCreator"," takes; ",[25,1145,1146],{},"pendingCreator(pairId)"," reads the offer. Only the creator offers it, and only the address offered takes it.",[1114,1149,1150,1153],{},[25,1151,1152],{},"giveUpCreatorFees(pairId)"," on the hook permanently sends the creator share of future fees to the round pots. Only the current creator can call it. Fees already accumulated remain claimable by the creator, and the creator role can still be transferred.",[1155,1156,1157],"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":1159},[1160,1161,1162,1163,1164],{"id":20,"depth":90,"text":21},{"id":218,"depth":90,"text":219},{"id":799,"depth":90,"text":800},{"id":880,"depth":90,"text":881},{"id":1108,"depth":90,"text":1109},null,"Read duels with DuelLens, trade their Uniswap V4 pools with any V4 router or DuelRouter, and follow the hook’s events: a guide for bots and aggregators.","md",{},true,"\u002Fdocs\u002Fduel\u002Fcontracts\u002Fintegrate",{"title":5,"description":1166},"docs\u002Fduel\u002Fcontracts\u002Fintegrate","lx5RA9fR5sNT07gvj-LBni-OlDphRzc4x3age1WGtZE",1791231651148]