Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x25233dDD68dAc9ac40E1E8D80c58d36b524032b2
Balance 0 ETH
Nonce 1
Code Size 24159 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

24159 bytes
0x60a0604052600436101561178b575b361561178957346101aa576bcdccd5c65a7d4860ce3abbe9805c9081331860601b825f351860e01c176101aa575f905d336ccf9e3c5a26621af382fa17f24f1460140236036004116101aa57600319336ccf9e3c5a26621af382fa17f24f146014023603019060a01c61ffff168060041461112c5780600114610ff557806003146109bc578060061461028c57806002146101be576005146100be57634e487b7160e01b5f52605160045260245ffd5b60243560443580926060105f146101ae575060c435906040516100e081611df9565b338152836020820152602319360191608083126101aa57604080519361010585611e45565b126101aa576040519061011782611df9565b6001600160a01b03811681036101aa57815284602082015282526064356020830152608435604083015261014a83611ed8565b906101586040519283611eb5565b838252368460e401116101aa575f6020856101809660e4838701378401015260a43592614d35565b6040519060608252602082810152602082604001528160600152806080016040525b602081519101f35b5f80fd5b6101b991339061246b565b610180565b506080116101aa5760043560243560443590602482013560601c92815f821391180218903083145f14610212576101fe925060383391013560601c61246b565b60405161020a81611e7d565b5f81526101a2565b906102206102879315614d1a565b6040519061022d82611df9565b338252602082015261024236602c8401611f48565b90610281608d84013560011693369060ad7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff778260040135019101611ef4565b91614d35565b6101fe565b50506024356058359060783590605819810190609d905f6040516080525f60805160c00152610300386101e060805101396104e0608051016040526102f18560801c876fffffffffffffffffffffffffffffffff16853560601c60805160c001615dff565b92836080515283608051602001528360805160400152866fffffffffffffffffffffffffffffffff16608051608001528560801c60805160a00152369436935f956020015173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145f1461093457506103633060893560601c14614d1a565b6080516040015161271061ffff843560501c16470204905260151901906016015b62ffffff82116108d957608051604001513060893560601c0361090d575b87600160781b166108eb575b51608051606001526103c16080516153f2565b906103ca614eff565b906103d3614ecd565b60208210156106955750505050608051604001519384602001519451956104026080515160805160c001615be7565b60805160200151805115610680575b5060805160c00151801580156105ff575b505060805151978860200151985198818a9260801c83106105f657509061044f9160443560601c90615609565b600160781b161561053d57505050508115908115610492575b5050505b6040519060608252602082810152602082604001528160600152806080016040526101a2565b60893560601c30036105295730905b60601b9161050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526f0b0d9c09000000000000000000000000600c525f806064601c82335af115610504575f6060526040525f8080610468565b3d5f823e3d90fd5b506020526fcbf0dbf50000000000000000000000005f5260246010fd5b6bcd1e9517bb0cb8d0d5cde8935c906104a1565b90919293608051606001519580870396146105da576001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee036105c35750505050505f6014526fa58411940000000000000000000000005f525f806024601082335af1156105b8575f6004601c6020936311da60b48452335af161046c575b6040513d5f823e3d90fd5b946105d49560893560601c906156f9565b5061046c565b6014526ffb772a880000000000000000000000005f5260246010fd5b60801c90612448565b61066c5760e0608051015160805160400151810361064b575b5060015b818110156104225760019061064560e06080518360051b01015180602001519051903090615609565b0161061c565b602081015190516106669130906001600160a01b0316615609565b5f610618565b634e487b7160e01b5f52603260045260245ffd5b61068f9060805160c001615be7565b5f610411565b6107866001600160a01b03926106c2863560f01c966001196002930190830160805160c00160805161540f565b92907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6608051602001516020015194876080515160200151958760601b998a988860601b988d6020848c73777777777777777777777777777777777777777760611b9e8f918082109083141516911417858518028095181691015218168b528435908160e81c60408d015262ffffff8260d01c16900b60608c015260301c1660808a01520190601a01919091803560e81c6002198160038185820195010195030192565b919692989062ffffff88116108d9576020926001600160a01b035f93612710888810898b141516888b1417159182158c526080518801515102048503868b015273fffd8963efd1fc6a506488495d951d53639afb81026401000276a418166040890152806040519263f3cd914c84528b518073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415028487015260808c8701856040015e60608a8560c0015e61012084810152818461014001528361016001376101440190601c0182335af1156105b8575f5190600f9180830b92608051602001519384519485878610888a141516868a14178560801d850b84180283188101116108c557608093841d90920b8181188886149888141597909510969096169690961792909202948518909201905251518051909290916108bd91849118615530565b0190526103d3565b634e487b7160e01b5f52601160045260245ffd5b634e487b715f5260326020526024601cfd5b6109068686868a856020015186519060893560601c906156f9565b81526103ae565b61092d6001600160a01b0361092189614eeb565b16602089013590615c1d565b81526103a2565b60893560601c30036109775750601519823560501c92601601910191612710608051604001519161ffff61096c308560200151612414565b911602049052610384565b9550505050505061098d60893560601c15614d1a565b60919060f235600116604182013560e81c809203906041820191610112908382116101aa5760d0190190610384565b5050601435603435605819336ccf9e3c5a26621af382fa17f24f1460140236030160595f91604051925f8460c00152610300386101e08601396104e08401604052610a258560801c876fffffffffffffffffffffffffffffffff16853560601c8760c001615dff565b92838552838560200152838560400152866fffffffffffffffffffffffffffffffff1685608001528560801c8560a00152369036935f956020015173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145f14610f5b57610a8c3060453560601c14614d1a565b604087015161271061ffff843560501c16470204905260151901906016015b62ffffff82116108d95786604001513060453560601c03610f34575b88600160781b16610f12575b518760600152610ae2876153f2565b90610aeb614eff565b60405192610af884611e29565b5f84525f60208501525f60408501525f60608501525f60808501525f60a0850152606060c08501525b6003831015610d1257505050508460400151948560200151955196610b4a82518360c001615be7565b8160200151805115610cff575b508160c0015180158015610c98575b50508151988960200151995199818b9260801c83106105f6575090610b90915f3560601c906155aa565b600160781b1615610c4d5750505050508115908115610bc7575b5050505b60405190602082528160200152806040016040526101a2565b60453560601c3003610c395730905b60601b9161050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526fae639329000000000000000000000000600c525f806064601c82335af115610504575f6060526040525f8080610baa565b6bcd1e9517bb0cb8d0d5cde8935c90610bd6565b6060979697959192939495015196808814610c7b57610c759697039060453560601c90615668565b50610bae565b506014526ffb772a880000000000000000000000005f5260246010fd5b61066c5760e083015183604001518103610cde575b5060015b81811015610b665780610cd860e08660019460051b010151806020015190519030906155aa565b01610cb1565b60208101519051610cf99130906001600160a01b03166155aa565b5f610cad565b610d0c908360c001615be7565b5f610b57565b80600119610d2e923560f01c9401906002018a60c0018b61540f565b92838261c0008316610e4f57505081612710610daa92610db6943560601c88602001528c6001600160a01b03809160200151602001511660408a01528d51602001511660608901528c602001515102046080870152601319604051950190601401919091803560e81c6002198160038185820195010195030192565b95929391953691611ef4565b60c086015262ffffff84116108d957604051603f1986015190601f1987015190632bfb780c603f198901526020601f1989015260605f60448a60c001518b8151910390818d60c0015201016023198b0182335af1156105b8576020519160405193603f198a0152601f198901526040528b60200151908151039052610e3e8b51918251614759565b905260608560c00152604052610b21565b92509362ffffff106108d957613fff816140006127109316155f14610eef575f60208601526001600160a01b038c51602001511660408601525b168a602001515102046060830152604051601f19830151906343583be5601f1985015260605f60a4600319870182335af115610504576020519060405192601f198601526040528a60200151908151039052610ee88a51918251614759565b9052610b21565b600160208601526001600160a01b038c6020015160200151166040860152610e89565b610f2d87878787856020015186519060453560601c90615668565b8152610ad3565b610f546001600160a01b03610f4886614eeb565b16602086013590615c1d565b8152610ac7565b60453560601c3003610f9b57601519823560501c9260160191019161271088604001519161ffff610f90308560200151612414565b911602049052610aab565b505050505050610fb060453560601c15614d1a565b60146ccf9e3c5a26621af382fa17f24f33140236036002198181013560e81c9182900390810190600160ae351690604d9060ce908482116101aa5760d0190190610aab565b5060a0116101aa576084357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f81019060a435906001600160a01b038083168084036101aa57611048916004351614614d1a565b60405161105481611df9565b33815260243560208201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c360192608084126101aa57604080519461109986611e45565b126101aa57604051906110ab82611df9565b815260c4356020820152835260e43560208401526101043560408401526110d184611ed8565b916110df6040519384611eb5565b8483523660a48201116101aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f5f916101fe966101256020870137840101526101053560011692614d35565b5050604435607835906098359060581981019060bd905f604051935f8560c00152610300386101e08701396104e085016040526111878660801c886fffffffffffffffffffffffffffffffff16863560601c8860c001615dff565b93848652848660200152848660400152876fffffffffffffffffffffffffffffffff1686608001528660801c8660a00152369136945f966020015173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145f1461170357506111ef3060a93560601c14614d1a565b604087015161271061ffff843560501c16470204905260151901906016015b62ffffff82116108d95786604001513060a93560601c036116e8575b88600160781b166116c6575b8051607f1c6115e65751876060015261124e876153f2565b90611257614ecd565b915b602382101561143257505050846040015194856020015195519661128182518360c001615be7565b816020015180511561141f575b508160c00151801580156113b8575b50508151988960200151995199818b9260801c83106105f65750906112c89160643560601c9061554b565b600160781b1615611390575050505050811590811561130a575050506040519060608252602082810152602082604001528160600152806080016040526101a2565b60a93560601c300361137c5730905b60601b9161050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526f03a65ab6000000000000000000000000600c525f806064601c82335af115610504575f6060526040525f8080610468565b6bcd1e9517bb0cb8d0d5cde8935c90611319565b6060979697959192939495015196808814610c7b576105d49697039060a93560601c906152d0565b61066c5760e0830151836040015181036113fe575b5060015b8181101561129d57806113f860e08660019460051b0101518060200151905190309061554b565b016113d1565b602081015190516114199130906001600160a01b031661554b565b5f6113cd565b61142c908360c001615be7565b5f61128e565b8060011961144e923560f01c9301906002018960c0018a61540f565b9091886020015190815191602001518a51602001518160601b938160601b9273777777777777777777777777777777777777777760611b926001600160a01b038080931691169082888710898714151687871417838318028093181660208c015218168852601f198760200196019635604089015262ffffff87116108d95760405f6bffff9a5889f795069a41a8a36bffff9a58c9f7f0ae8d3e0684858714868a14158a891016171502186bffffffffffffffffffffffff1661800087166115f857825182815260e4916020820160608e825e80518073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415029052612710617fff8a1687020482608001528988108a88141516888814178260a001528160c00152828160e00152601c0182335af1156105b857617fff6115ab8e96612710945f519660205197925b808210908314151691141786821802809618976020015195869118615530565b93805190858203905284119416020410176115e6578851908151905f81136115d7575f03019052611259565b602483633351b2608152601c01fd5b634e487b715f5260116020526024601cfd5b82516f101e895200000000000000000000000081526101049160148d8601602084015e6034820160608e825e80518073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415029052612710617fff8a1687020482609401528988108a88141516888814178260b401528160d40152828160f4015260100182335af1156105b8575f5192602051600f8180820b188680830b181790612710617fff891686020490612710617fff8a16870204900b183d60401117176101aa578e9661271094617fff936115ab93979261158b565b6116e187878787856020015186519060a93560601c906152d0565b8152611236565b6116fc6001600160a01b03610f4886614eeb565b815261122a565b60a93560601c30036117445750601519823560501c9260160191019161271088604001519161ffff611739308560200151612414565b91160204905261120e565b9550505050505061175a60a93560601c15614d1a565b60b161011235600116606183013560e81c809303916061830192610132908482116101aa5760d019019061120e565b005b5f3560e01c80634b7758a514611cb457806367c4a3b014611c865780638bc1e8eb14611c0a5780638da5cb5b14611bdf5763fd3ad6d40361000e57346101aa57600319360160e081126101aa576060136101aa5767ffffffffffffffff80606435116101aa573660236064350112156101aa578060643560040135116101aa573660246064356004013560051b6064350101116101aa576001600160a01b0360a43516908160a435036101aa5760c435918183116101aa57366023840112156101aa5782600401359182116101aa5736602483850101116101aa57611893336ccf9e3c5a26621af382fa17f24f1860601b1536600310163360131936013560601c1802331890565b90816001600160a01b03165f526b08054751d605e5c08a2210bf60205260405f205460601b15611bd2576001600160a01b0360806040517fdc83993a2ffc65b01b71ed08790b6e39c5c55d76937b62a3b5085b02071f1259815260606004826020013720921614611bb5576bc7aebfbc05485e093720deaa5c80611bc257506bc7aebfbc05485e093720deaa5d60a43560601b15611bb5576bcd1e9517bb0cb8d0d5cde8935c8060601b611b99575060a4356001600160a01b03166bcd1e9517bb0cb8d0d5cde8935d60643560040135156101aa57602460643501356064350160248101359060448101359261199e604860031985019301916024604051970184848860e01c612006565b8560405215611b4b5760016064356044015b606435600401358210611ab2576004356001600160a01b0381168082036101aa57602435906001600160a01b038216918281036101aa576044359283156101aa5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015611aa25747935b808510611a9a575015611a8b575050611a28916124cb565b60a4356bcd1e9517bb0cb8d0d5cde8935c1860601b611a7e575f6bcd1e9517bb0cb8d0d5cde8935d6bc7aebfbc05485e093720deaa5c80611a6e57602060405160018152f35b63e25527c25f526020526024601cfd5b635149e7955f526004601cfd5b611a95935061246b565b611a28565b925050612448565b611aac3083612414565b93611a10565b803560643501602481013560448201359160486003198301910160405193611ade83838360e01c612bba565b8560405215611afa5750505050506020600191019101906119b0565b8495507fffffffff000000000000000000000000000000000000000000000000000000009087633c74eed660809752876020015216856040015260608581015281858501528460a001370190601c01fd5b7fffffffff00000000000000000000000000000000000000000000000000000000608094633c74eed687525f876020015216856040015260608581015281858501528460a001370190601c01fd5b6014526f7407c0f80000000000000000000000005f5260246010fd5b63e758b8d55f526004601cfd5b639936cbab5f526020526024601cfd5b631e0921045f526004601cfd5b346101aa575f6003193601126101aa576020611bf9611daf565b6001600160a01b0360405191168152f35b346101aa575f6003193601126101aa57604051808060400160206b08054751d605e5c08a2210bf60205260019060015f526001600160a01b03908160405f2054165b808403611c6c5750505050039060208152603f19820160051c8160200152f35b8085525f9081526040902054869550938101938216611c4c565b346101aa575f6003193601126101aa57602060405173352650ac2653508d946c4912b07895b22edd84cd8152f35b346101aa5760606003193601126101aa576004356001600160a01b03908181168091036101aa57602435918083168093036101aa5760443580151581036101aa57611d22336ccf9e3c5a26621af382fa17f24f1860601b1536600310163360131936013560601c1802331890565b611d2a611daf565b1860601b611bd257835f526b08054751d605e5c08a2210bf60205260405f209182541691835f5260405f2085158385151817838760011802871882541860601b1793838782180218905555611d7b57005b63e2b339fd5f526020526040526044601cfd5b35906001600160a01b03821682036101aa57565b359081151582036101aa57565b632bb839875f52600460205260405f6024601c6d04533fe15556b1e086bb1a72ceae5afa156105b85760403d106101aa575f51906020518060281c8360a01c17904211176101aa57565b6040810190811067ffffffffffffffff821117611e1557604052565b634e487b7160e01b5f52604160045260245ffd5b60e0810190811067ffffffffffffffff821117611e1557604052565b6060810190811067ffffffffffffffff821117611e1557604052565b6080810190811067ffffffffffffffff821117611e1557604052565b6020810190811067ffffffffffffffff821117611e1557604052565b60c0810190811067ffffffffffffffff821117611e1557604052565b90601f601f19910116810190811067ffffffffffffffff821117611e1557604052565b67ffffffffffffffff8111611e1557601f01601f191660200190565b929192611f0082611ed8565b91611f0e6040519384611eb5565b8294818452818301116101aa578281602093845f960137010152565b9080601f830112156101aa57816020611f4593359101611ef4565b90565b8092910391608083126101aa5760405190611f6282611e45565b60408294126101aa5760606040918251611f7b81611df9565b611f8482611d8e565b81526020820135602082015284528281013560208501520135910152565b610140818303126101aa57611fb681611d8e565b92611fc360208301611da2565b92604083013592606081013592608082013567ffffffffffffffff81116101aa57612000611ff685610120938601611f2a565b9460a08501611f48565b92013590565b939291909361201884848488856124da565b15612027575050505050600190565b63fe944a9d8103612078575061206c926001600160a01b03926120538661206594612071980190611fa2565b99929598919690979493943691611ef4565b96166147a2565b6149b0565b505b600190565b63fb17ae4781036120cc57506120b163ffffffff926120a0866120c194612071980190611fa2565b9791949690959a9392933691611ef4565b946001600160a01b038a166147a2565b9160801c1690614938565b638d62436181036122f85750830192610100818503126101aa576120ef81611d8e565b9060209060409061210e612104838301611da2565b9760608301611f48565b946121b960e08301359761212d6001600160a01b039384923691611ef4565b86865195878b518884015e878b8301886060015e5f8760a001538251809383018860a1015e826081018752730a7e848aca42d879ef06507fca0e7b33a0a63c1e5f52013587527fbb7b783eb4b8ca46925c5384a6b9919df57cb83da8f76e37291f58d0dd5c439a865260ff600b5360a1856055600b209201018652169651858382511691015190615c1d565b94835195835193848701908860e4015e60c08760c40152895f03637fffffff191860030b8760a401525f876084015289876064015286604401521684602401526f3eece7db00000000000000000000000084601001528060e40184528301610120019052826bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe991825c806122e957505f80917f67ca7c91000000000000000100000000000000000000000000000000000000008617855d838151910182875af191612285614b31565b92156122e2575c806122d3575090816122a49282518301019101612b3f565b9390508284106122b75750505050600190565b156122ca576122c590614ade565b612448565b6122c590614ab6565b9063d66fcc385f52526024601cfd5b5081519101fd5b8263ab7646c45f52526024601cfd5b91939163c4d55cad0361240c578161231591612324930190611fa2565b94969195929890973691611ef4565b92826060810204606014831517156108c557876060810204606014881517156108c5576060880260801c15156060840260801c15158260801c151517176115e65760606001600160a01b0393816120719a604080519b8a51998d81519c8d928d6101329285610115868401820101526020018484015e602001918d01015e6101358d8b018c010182525f8d6101310153816020820160f18f015e518c60b1015e5f8b609d01520289608801520287607801528660680152168460580152018060d10183604401526020836024015263f83d08ba83600401526101150182528160a80153614881565b505050505f90565b602460105f926020946014526f70a0823100000000000000000000000084525afa156105b8573d601f10156101aa575f5190565b916054526034526014526f97a6f3b90000000000000000000000005f5260646010fd5b60105f60449260209582956014526034526fa9059cbb00000000000000000000000082525af1156124bb573d153d601f1060015f51141617156124ae575f603452565b6390b8ec185f526004601cfd5b60405162ffffff163d5f823e3d90fd5b5f80809381935af1156105b857565b9391909293630dfeb41981145f146126b5575082019260a0838503126101aa5761253261251461250985611d8e565b956020809601611f48565b916125296001600160a01b0380971684614766565b50933691611ef4565b926bc7aebfbc05485e093720deaa925f845c945d8315611bb5575f9485946bcd1e9517bb0cb8d0d5cde8935c6040988980519561256e87611e99565b608187527f536c69707061676520736c69707061676529536c697070616765286164647265888801527f737320726563697069656e742c6164647265737320627579546f6b656e2c7569828801527f6e74323536206d696e416d6f756e744f757429546f6b656e5065726d6973736960608801527f6f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7460808801527f290000000000000000000000000000000000000000000000000000000000000060a08801528180519963137c29fe8b528181518c8c015e89018a6060015e8860a0015e168560e001528461010001526101408085610120015282519261016091868584019101528584860192015e805180930190828501610180015e016101840190601c01826e22d473030f116ddee9f6b43ac78ba35af1156126ac5750600190565b513d5f823e3d90fd5b91939291639ebf8e8d0361240c5781019360e0828603126101aa576126d982611d8e565b9260208301359067ffffffffffffffff82116101aa5761270b61270188612713948701611f2a565b9760408601611f48565b953691611ef4565b805160890194856089116108c55761278f91601f1961274a61273489611ed8565b986127426040519a8b611eb5565b808a52611ed8565b013660208901378151602001518760480152604082602001886068015e5f8760a801538051906020018760a9015e5160206001600160a01b0382511691015190615c1d565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82116115e6579493929190955b8051602c81106108d957601482015197601583015197601884015199602c85015192819b849c859c6001600160a01b0387166001600160a01b0386161015612b33575b60ff81811680612a1c575050509a809c9d8b9c731f98431c8ad98523631ae4a59f267346ea31f9849c9a9b9c917fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549163fa461e33955b62ffffff1660405192816040526020525f8052606091821b600c521560051b90035f209060405261288792614a97565b6001600160a01b031692815195858360280152826014015285825285604051968793849360c49183602001908684015e8460a40160a090526001600160a01b038b166001600160a01b038a16101573fffd8963efd1fc6a506488495d951d53639afb81026401000276a418856084015284606401526001600160a01b038a166001600160a01b0389161084604401528a8460249e8f92602c106001600160a01b038216301802906001600160a01b031618910152836010016f128acb0800000000000000000000000090520182520160e40160405261296592614a29565b908180518101036040136101aa576001600160a01b0380604095602085015196879501519560405216911610911802185f03975f8912612a0b57602c899211156129e657505030969160188251106129d65750806017196018925101828201520195602886529493929190956127be565b634e487b715f526032602052601cfd5b955095505050935060c08101358310612a0157505050600190565b60c0013590612448565b83634e487b715f526011602052601cfd5b60018103612a74575050509a809c9d8b9c7341ff9aa7e16b8b1a8a8dc4f0efacd93d02d071c99c9a9b9c917f6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2916323a69e7595612857565b60028103612acc575050509a809c9d8b9c73baceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f9c9a9b9c917fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549163fa461e3395612857565b600303612b225750509a809c9d8b9c7370fe4a44ea505cfa3a57b95cf2862d4fd5f0f6879c9a9b9c917fe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf91633a1c453c95612857565b63d3b1276d5f52166020526024601cfd5b9d5050829c8590612801565b91908260409103126101aa576020825192015190565b9190610100838203126101aa57612b6b83611d8e565b92612b7860208201611d8e565b92604082013592612b8b60608401611da2565b9260808101359260a08201359260c083013567ffffffffffffffff81116101aa5760e091612000918501611f2a565b9092919063d92aadfb8103612f53575082016101209081848203126101aa57612be284611d8e565b90602094612bf282878301611f48565b90612bff60a08201611d8e565b9260c082013567ffffffffffffffff81116101aa57820190612c2091611f2a565b612c2c60e08301611d8e565b9561010080930135936001600160a01b03808097169716612c4d9082614766565b8b8884959395515116968a60409c8d998a5190612c6982611e61565b81528481018690528a810183905260016060820152601f190180517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa825260a0822091528a51909c6bcd1e9517bb0cb8d0d5cde8935c612cc883611e61565b83821683528683018e9052168b82015260016060820152601f190180517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa825260a0822091529a8b95612d1b3084612414565b82811181841802189182612d2e92615255565b9d8e868b0152612d3d9261246b565b88805197612d4a89611e61565b60588952848901987f436f6e73696465726174696f6e286164647265737320746f6b656e2c75696e748a528281017f32353620616d6f756e742c6164647265737320636f756e74657270617274792c9052606081017f626f6f6c207061727469616c46696c6c416c6c6f77656429000000000000000090528251612dcd81611e45565b602e8152868101907f546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c7582528481017f696e7432353620616d6f756e7429000000000000000000000000000000000000905284519b8c938985017f436f6e73696465726174696f6e20636f6e73696465726174696f6e29000000009052518091603c86015e830190603c8201905f8252519283915e01603c81015f905203601c81018a52603c01612e7d908a611eb5565b81519a8b98899663137c29fe88528282518983015e01866060015e8460a0015e8260e0015201526101409182910152815191610160918584840191015284838c0192015e815191828a0190828501610180015e016101840190601c015a915f9291836e22d473030f116ddee9f6b43ac78ba38194f115612f49576fffffffffffffffffffffffffffffffff9394957f49fa719b76f0f6b7e76be94b56c26671a548e1c712d5b13dc2874f70a75982765f5252835190845260605f209352166010525f5260305fa0600190565b83513d5f823e3d90fd5b638d68a156810361337b57508201916080818403126101aa57612f7581611d8e565b9160208201359360408301359067ffffffffffffffff82116101aa57612f9c918401611f2a565b93612fe485516020870151907fffffffffffffffffffffffffffffffffffffffff000000000000000000000000918281169160148110613366575b503092505060601c612414565b8181029181830414901517156108c5576127109004936040519361300785611e45565b60288552604036602087013730917f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff879197116115e6575b865190602c82106108d95760148801519360158901519460188a015192602c8b0151938a838690879a6001600160a01b0389166001600160a01b038816101561335b575b60ff8181168061326857505050731f98431c8ad98523631ae4a59f267346ea31f984917fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549163fa461e33955b62ffffff169060405192826040526020525f805260601b600c521560051b6060035f20906040526130ff92614a97565b6001600160a01b031692815195858360280152826014015285825285604051968793849360c49183602001908684015e8460a40160a090526001600160a01b038b166001600160a01b038a16101573fffd8963efd1fc6a506488495d951d53639afb81026401000276a418856084015284606401526001600160a01b038a166001600160a01b038916108460440152602c8b116001600160a01b038d163018026001600160a01b038d16188460240152836010016f128acb0800000000000000000000000090520182520160e4016040526131d992614a29565b908180518101036040136101aa576001600160a01b0380604095602085015196879501519560405216911610911802185f03925f84126115e657602c8492111561324357505030919560188151106108d9578060171960189251018282015201956028865261303f565b94939650945050506060810135831061325e57505050600190565b6060013590612448565b600181036132b6575050507341ff9aa7e16b8b1a8a8dc4f0efacd93d02d071c9917f6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2916323a69e75956130cf565b600281036133045750505073baceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f917fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549163fa461e33956130cf565b6003919293949550145f14612b22575050908c917370fe4a44ea505cfa3a57b95cf2862d4fd5f0f687917fe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf91633a1c453c956130cf565b869250889150613083565b8391925060140360031b1b1616805f80612fd7565b928363103b48be829495145f1461362b575060c091810103126101aa576133a181611d8e565b6020916133af838201611d8e565b90604090818101356133c360608301611d8e565b60808301359262ffffff841684036101aa5760a00135956001600160a01b03808097169216926001918280871614935f9280613612575b5087519390836135e2575b630902f1ac5f52885f6004601c8a5afa156135d957883d106101aa578b978a948760051b9d8e93845194821851958085811c1614831517613587575b5050915f9391601c9361ffff6127109260081c16820302920282019102049b63022c0d9f86526080808701528260a08701528c8982880101526004018818850101521660608201525f8060a4601c840182875af11561050457508587106134ae5750505050505050600190565b60049291829115613529578451938480927fd21220a70000000000000000000000000000000000000000000000000000000082525afa9283156126ac57505f926134fc575b50505b16612448565b61351b9250803d10613522575b6135138183611eb5565b810190614cfb565b84806134f3565b503d613509565b8451938480927f0dfe16810000000000000000000000000000000000000000000000000000000082525afa9283156126ac57505f9261356a575b50506134f6565b6135809250803d10613522576135138183611eb5565b8480613563565b6024919394959697505f9250601c906370a0823184528b85525afa156135d957873d106101aa575f518381106135c8578a949392919083900389601c613441565b601189634e487b715f52526024601cfd5b843d5f823e3d90fd5b63a9059cbb5f52868c528389528b5f6044601c82855af1156135d957815f51148c3d1015163d1517613405575f80fd5b6127109193506136223085612414565b0204915f6133fa565b6338c9c14781036136985750019060a0818303126101aa5761364c81611d8e565b9061365960408201611d8e565b90608081013567ffffffffffffffff81116101aa576120739461367d918301611f2a565b9260206001600160a01b036060840135941692013590614b60565b6334ee90ca810361375d5750608091810103126101aa576136b881611d8e565b906136c560208201611d8e565b6001600160a01b0381811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14926040810135841561374d5747915b818311613709575b50505050505050600190565b60606127109101358302049103908181811191180218925f1461373d575050613731916124cb565b5f8080808080806136fd565b61374893169061246b565b613731565b6137573085612414565b916136f5565b905063af72634f810361379557506001600160a01b036137868361206c93612071950190612b55565b979096959195949294166150a9565b829063736180c88103613907575060c091810103126101aa576137b781611d8e565b6137c360408301611da2565b9160608101356080820135936001600160a01b0380861686036101aa57612710906137f060a08601611d8e565b95169461382173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486020858483180280941897013592309118612414565b020490156138bb5763fae036d55f5260205f6004601c885afa156105b857601f3d11156101aa57620f4240670de0b6b3a76400005f5101910204918183106122c557505060105f60209481946044946034526014526f8d7ef9bb00000000000000000000000082525af1156138a257601f3d11156101aa575f603452600190565b6040516bffffffffffffffffffffffff163d5f823e3d90fd5b60105f602094968194966044946034526014526f9599127600000000000000000000000082525af1156138a257601f3d11156101aa575f6034525f51918183106122c557505050600190565b636472b2768103613dee575060c091810103126101aa5761392781611d8e565b61393360208301611d8e565b60608301356001600160a01b03811690036101aa5761395460808401611da2565b926040519161018083810160405260368460608501353c630902f1ac5f5260405f6004601c60608601355afa156105b8575f51602051908060701c8260701c173d606011176101aa576001600160a01b038560200151166001600160a01b038651166001600160a01b0389828418028093181694876040015195866014526fd283e75f0000000000000000000000005f5260205f60246010845afa156105b8573d6020116101aa5760205f602460108251948b6014526f402d267d00000000000000000000000084525afa156105b8573d6020116101aa575f5101604051966001600160a01b0360608a0135166040528060601b602c526f1647292a000000000000000000000000600c5260205f6044601c730c9a3dd6b8f28529d72d7f9ce918d493519ee3835afa156105b8575f519760405263961be3915f5260205f6004601c6001600160a01b03898918165afa156105b8573d6020116101aa575f80516318e22d9882528888188e028818808218918111919091021891906040906004601c888a186001600160a01b03165afa156105b8575f5195602051968760101c9060101c173d604011176101aa5760648760061c603f8916600a0a0204956347bd37185f5260205f6004601c6001600160a01b03868618165afa156105b8573d6020116101aa578c978f975f5190818315826dffffffffffffffffffffffffffff18028218039215816dffffffffffffffffffffffffffff180218110292848410613d90575b5050505096613c0a978560a00151908660c0015190876060015192886080015191885f14613d4657808c11908c030292828411613d315790613bc49492918a610100015194615b94565b86808203911102915b670de0b6b3a764000091866101200151830393818302811090828402180291021802045f916040890135613cf5575b8215613ccb575b5050615159565b9160a08201358310613c82575060018211613c29575b50505050600190565b5f606060a4936001600160a01b03839796846020819960405195869163022c0d9f835260051b9083828401015282180101521681830152608081810152828160a00152601c019201355af1156105b8575f808080613c20565b5f6004601c6001600160a01b03848982806020988901511692511680926338d52e0f8852180218165afa156105b8575f51908160a01c3d602011176101aa5760a0013590612448565b613ce59192506001600160a01b0360608a01351690612414565b9081818111911802185f80613c03565b91506127106040890135613d093085612414565b0204818111818318021891613d2c836001600160a01b0360608c0135168361246b565b613bfc565b613d4194918a60e00151946157cb565b613bc4565b9193828b11928b03929092029290828411613d7a5790613d6d9492918a60e0015194615b94565b8780820391110291613bcd565b613d8b94918a6101000151946157cb565b613d6d565b60209498505f9397508282613db56001600160a01b039384602497601c971816612414565b87526307a2d13a865218165afa156105b8573d6020116101aa57613c0a9689948c945f51019081818110159118021890975f8080613b7a565b905063fd8c38e18103613e2c575063ffffffff613e14836120c193612071950190612b55565b956001600160a01b03889a98969296959395166150a9565b82906367848fe78103614186575060c091810103126101aa57613e4e81611d8e565b602091613e5c838201611d8e565b9060409384820135936060830135936001600160a01b03808616918287036101aa578860a0613e8d60808901611da2565b970135985f908061416f575b508061415757505082613eab91612414565b88517f1865c57d000000000000000000000000000000000000000000000000000000008152610120908181600481885afa91821561414d57908b9695949392915f92614048575b50505f916fffffffffffffffffffffffffffffffff8060e4938a8c8714614040575051165b169003945b88831461402f57601f19601f637fffffff995b895198613f3b8a611e61565b89528089019a8c15158c528a8a019087825260608b019060030b81528b5191613f6383611e7d565b8883528c519d8e9c8d9b8c997f3eece7db000000000000000000000000000000000000000000000000000000008b521660048a0152516024890152511515604488015251151560648701525160030b608486015260c060a486015280519182918260c4880152018686015e85858286010152011681010301925af19485156126ac575f95613ffe575b50508284106122b75750505050600190565b61401e929550803d10614028575b6140168183611eb5565b810190612b3f565b9050925f80613fec565b503d61400c565b601f19601f637fffffff1999613f2f565b015116613f17565b91509195508082813d8311614146575b6140628183611eb5565b810103126101aa578a5190810181811067ffffffffffffffff821117611e15578b5261408d82614b06565b815261409a878301614b06565b878201526140a98b8301614b23565b8b8201526140b960608301614b23565b6060820152608082015164ffffffffff811681036101aa57608082015260a08201518060030b81036101aa5760a082015260c082015180151581036101aa5760c082015260e082015163ffffffff811681036101aa5760e0820152610100809201519560ff871687036101aa57918101959095528994816fffffffffffffffffffffffffffffffff613ef2565b503d614058565b8b513d5f823e3d90fd5b9392915f919561416a868660e49461246b565b613f1c565b612710915061417e3085612414565b02045f613e99565b9050636c5f9cf981036142615750906141a191810190612b55565b60608498929594979396970297808904606014901517156108c5576060860295808704606014901517156108c5578560801c15158860801c15158260801c15156127108a111717176115e6576120719760d3966001600160a01b039460405199885180996020018c8c015e8a60b301528960b101523089609d015288608801528760780152866068015216846058015281606f0184604401526020846024015263f83d08ba84600401528160b30184528360a80153820101604052614881565b829063ca9e5d0f81036143b0575060c091810103126101aa5761428381611d8e565b61428f60208301611d8e565b60408301356060840135936001600160a01b0391828616938487036101aa578360a06142bd60808601611da2565b9401359616948261438f575b5050505f1461431d57506014526fdd93f59a0000000000000000000000005f5260205f6024601082865af1156105b857601f3d11156101aa575f519181831061431457505050600190565b6122c590615074565b906014526fbd6015b40000000000000000000000005f5260205f6024601082875af1156105b857601f3d11156101aa575f51928284106143605750505050600190565b5f6004601c60209363d4b9704684525afa156105b857601f3d11156101aa575f518060a01c6101aa5716612448565b6127106143a8936143a03085612414565b02049161246b565b5f80806142c9565b63b8df6d4d14159050614753578160a091810103126101aa576143d281611d8e565b90602060409182810135906001600160a01b038216948583036101aa57606090614421614400838501611da2565b916127108760808701359601356144173084612414565b0204988991614f3a565b156147145782905f96865161443581611e29565b88815286810190898252888101908a8252848101928b845260808201908c825260a083018d815260c084019d8e5263ffa642255f526004958d5f88601c809d5afa1561470a57603f3d11156101aa578c5f888c8f83518551885289526317be952e84525afa1561470a57601f9e8f3d11156101aa575f518060081c6101aa5760ff1660038110156146ed575f8f918f8e908c92865263796da7af84525afa15614700578f3d11156101aa578d5f898f8e9083518b52637c9b8e8984525afa15614700578f3d11156101aa578d5f898f8e908351875263eab5d20e84525afa15614700578f3d11156101aa578d5f898f8e9083518c5263ec2fd46d84525afa15614700578f3d11156101aa575f518452805160038110156146ed57614606575050505050614563915083615791565b905b63c0ffa1785f52875f82878a5afa156145fc57893d11156101aa57875f80519263ab44a7a38252878a5afa156145fc57893d11156101aa57670de0b6b3a764000080915f510101910204938085106145f15750925f9492859260849589519363e67ce7068552848a0152838a01528281015282826080015201915af1156126ac57503d11612073575f80fd5b84906122c587615074565b88513d5f823e3d90fd5b949293945160038110156146da578895949392919060010361465f57505090670de0b6b3a7640000614657949592516ec097ce7bc90715b34b9f100000000004935192519586925194020491615c8b565b900390614565565b9551935190519551959194509092038483038088116146c2575050858401938493516ec097ce7bc90715b34b9f1000000000049151670de0b6b3a76400008080978682970204028380820491061515018202049084030193030204020490614565565b915093506146d39291508503615791565b0190614565565b602188634e487b7160e01b5f525260245ffd5b602189634e487b7160e01b5f525260245ffd5b8e513d5f823e3d90fd5b8d513d5f823e3d90fd5b84955f9495916084949386935192638dae73338452838901528289015281810152818160800152601c01915af1156126ac5750601f3d11612073575f80fd5b50505f90565b919082018092116108c557565b909161479d6040519361477885611df9565b6020808601945f8652866001600160a01b038094169052519182511691015190615c1d565b809252565b9290959394979691806060810204606014811517156108c557816060810204606014821517156108c5576060820260801c15156060820260801c15158460801c151517176115e65760608092604080519b8951988d81519b8c928c6101329285610115868401820101526020018484015e602001918c01015e6101358d8a018b010182525f8d6101310153816020820160f18f015e518c60b1015e5f8b609d015202896088015202876078015286606801528560580152018060d1018460440152602084602401526348c8949184600401526101150183528260a80153565b73e0e0e08a6a4b9dc7bd67bcb7aade5cf48157d44490816bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe991825c8061492857505f9182917fb45a3c0e0000000000000004e0e0e08a6a4b9dc7bd67bcb7aade5cf48157d444855d82602083519301915af1906148ff614b31565b911561491f575c8061490f575090565b63d66fcc385f526020526024601cfd5b50602081519101fd5b63ab7646c45f526020526024601cfd5b73ba1333333333a1ba1108e8412f11850a5c319ba9806bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe992835c806149285750915f92917403ba1333333333a1ba1108e8412f11850a5c319ba9849360e01b17855d82602083519301915af1906148ff614b31565b6e04444c5dc75cb358380d2e3de08a9090816bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe991825c8061492857505f9182917f91dd73460000000000000006000000000004444c5dc75cb358380d2e3de08a90855d82602083519301915af1906148ff614b31565b6001600160a01b0316806bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe992835c8061492857509181740200000000000000000000000000000000000000005f9493859460e01b1717855d82602083519301915af1906148ff614b31565b929190604051935f5260205260405260ff600b536055600b2091604052565b5f6004601c602093630fc63d1084525afa156105b8575f51908160a01c3d602011176101aa57565b5f6004601c602093635f64b55b84525afa156105b8575f51908160a01c3d602011176101aa57565b51906fffffffffffffffffffffffffffffffff821682036101aa57565b51908160070b82036101aa57565b3d15614b5b573d90614b4282611ed8565b91614b506040519384611eb5565b82523d5f602084013e565b606090565b9291906001600160a01b03808316946e22d473030f116ddee9f6b43ac78ba38614611bb5575f9181169073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8203614c865750505061271090470204938051155f14614c0a575050614be0575f80809381935af1614bcf614b31565b9015614bd85750565b602081519101fd5b60046040517f01da1572000000000000000000000000000000000000000000000000000000008152fd5b909392602083018084116108c5578251106108d957835f9460208695850101525b602083519301915af1614c3c614b31565b9015614bd85751159081614c7c575b50614c5257565b60046040517f82d5d76a000000000000000000000000000000000000000000000000000000008152fd5b90503b155f614c4b565b9091949282979497155f14614ca557505050614be0575f928392614c2b565b614cbd90614cb897949693973084612414565b6151f9565b602086018087116108c5578551106108d95787845f988360208b9a8a01015203614cea575b505050614c2b565b614cf392614f3a565b5f8087614ce2565b908160209103126101aa57516001600160a01b03811681036101aa5790565b15614d2157565b634e487b7160e01b5f52600160045260245ffd5b6bc7aebfbc05485e093720deaa805c9493905f905d8415611bb5576bcd1e9517bb0cb8d0d5cde8935c93604095865191614d6e83611e99565b608183527f536c69707061676520736c69707061676529536c69707061676528616464726560208401527f737320726563697069656e742c6164647265737320627579546f6b656e2c7569888401527f6e74323536206d696e416d6f756e744f757429546f6b656e5065726d6973736960608401527f6f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7460808401527f290000000000000000000000000000000000000000000000000000000000000060a0840152614ec0575f958787968180519763137c29fe89528181518a6020015e602001886060015e8660a0015e6001600160a01b03168460e00152836101000152610140808461012001528151916101609185848401910152848360200192015e8151918260200190828501610180015e016101840190601c01826e22d473030f116ddee9f6b43ac78ba35af1156126ac5750565b631c500e5c5f526004601cfd5b60405190614eda82611e45565b5f6040838281528260208201520152565b356001600160a01b03811681036101aa5790565b6040519060a0820182811067ffffffffffffffff821117611e15576040525f6080838281528260208201528260408201528260608201520152565b906001600160a01b036040519384917fdd62ed3e0000000000000000000000000000000000000000000000000000000083523060048401528084166024840152826044602097889388165afa9182156105b8575f92615045575b508110614fa2575b50505050565b614ffd575b60105f80936044936014525f196034526f095ea7b300000000000000000000000082525af1156124bb573d153d601f1060015f5114161715614ff0575f6034525f808080614f9c565b633e3f8f735f526004601cfd5b806014525f6034526f095ea7b30000000000000000000000005f52825f6044601082865af1156124bb573d153d601f1060015f51141617614fa757633e3f8f735f526004601cfd5b9091508481813d831161506d575b61505d8183611eb5565b810103126101aa5751905f614f94565b503d615053565b5f6004601c602093634a248d2a84525afa156105b857601f3d11156101aa575f518060a01c6101aa576001600160a01b031690565b9293909594979691976060820291808304606014901517156108c5576060810290808204606014901517156108c5578060801c15158260801c15158460801c15156127108c111717176115e65760d39660405199875180986020018c8b015e8a60b301528960b101523089609d0152886088015287607801528660680152856058015281606f018560440152602085602401526348c8949185600401528160b30185528460a80153830101604052565b9091928360a00151928460c0015190856060015192866080015194670de0b6b3a76400008861012001518202049003915f146151ca5701938285116151b2576151a69560e0015194615b94565b80150180820391110290565b906151c5956101009493940151946157cb565b6151a6565b960193919291908285116151e7576151a695610100015194615b94565b906151c59560e09493940151946157cb565b5f198282098282029182808310920390612710948591099180821461524e577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91945083831191030360fc1b910360041c170290565b5050500490565b90915f1983830983830290818082109103938185146152c757611f459584910993039091909281805f0316809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b50500492915050565b9490929395919573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b038716145f1461530d57505050505050611f4581336124cb565b602095966040519788602401526f0c11dedd0000000000000000000000008860100152876044015260449330036153ca575b5050508091508352820101604052336bcd1e9517bb0cb8d0d5cde8935c1860601b15611bb5576bcdccd5c65a7d4860ce3abbe990815c8061492857505f80917f599d0714000000000000000500000000000000000000000000000000000000003317845d60208151910182335af1906153b6614b31565b911561491f575c8061490f57506060015190565b829350604060c495810188606401378660a4015281868501528560e4013701805f808061533f565b604001518051156154005750565b8063fb772a8860249252601c01fd5b9190939293813592836001948060f81c9182615432575b50505050508101920390565b95839496615477945180604001805115615519575b505081841161549e575b50601491925001948360800151906001600160a01b038560a001519360581c1690615dff565b908181526040015180911461548f5780808080615426565b8063784cb7b860249252601c01fd5b85602001938451805115615509575b50600281036154c857505060149192855190525b8291615451565b601493506154da919250600314614d1a565b858201359261550260159287608001516001600160a01b038960a001519260581c168b615dff565b90526154c1565b615513908a615be7565b5f6154ad565b898051850180825260051b01918252525f80615447565b905f821261553c575090565b80634c085bf160249252601c01fd5b60601b90821561050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526f03a65ab6000000000000000000000000600c525f806064601c82335af115610504575f606052604052565b60601b90821561050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526fae639329000000000000000000000000600c525f806064601c82335af115610504575f606052604052565b60601b90821561050c57604051926060526040528073777777777777777777777777777777777777777760611b141502602c526f0b0d9c09000000000000000000000000600c525f806064601c82335af115610504575f606052604052565b919591949392906001600160a01b031630036156ca5750505050816156ba575b6014526034526f15afd4090000000000000000000000005f5260205f6044601082335af1156124bb575f515f60345290565b6156c582338361246b565b615688565b6102816156c5946156f1604051936156e185611df9565b3385528960208601523690611f48565b933691611ef4565b93959290949194846014526fa58411940000000000000000000000005f525f806024601082335af1156105b8576001600160a01b03163003615760575050506157449250339061246b565b6311da60b45f5260205f6004601c82335af1156105b8575f5190565b61578c9594929350906156f1610281926040519461577d86611df9565b33865260208601523690611f48565b615744565b6157c690670de0b6b3a764000083516ec097ce7bc90715b34b9f10000000000491602060808601519501519202048380615c8b565b900390565b9093929491670de0b6b3a7640000938587029203020182028160011b938086860202808310928391825f039103180190828183061515169104019261589484806fffffffffffffffffffffffffffffffff1060071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b177ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be831593831c1c601f161a180190565b610100908103607f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818201911102906159596503782dace9d98902806fffffffffffffffffffffffffffffffff1060071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b177ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be831593831c1c601f161a180190565b9003606d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9382019111028181811091180218928360011b925f14615a5d57826159b792826159af938a800292030260021b615d2d565b918480615d2d565b01615a42818070ffffffffffffffffffffffffffffffffff1060071b81811c68ffffffffffffffffff1060061b1781811c64ffffffffff1060051b1781811c62ffffff1060041b179060019160b56201000083831c0191841c1b0260121c80820401821c80820401821c80820401821c80820401821c80820401821c80820401821c80910401901c90565b908180021001901b01908082049106151501905b8111900390565b929082955091615a8a615a8285615b8a9795039788968a80029788910260021b615d11565b918480615d11565b0194615b16868070ffffffffffffffffffffffffffffffffff1060071b81811c68ffffffffffffffffff1060061b1781811c64ffffffffff1060051b1781811c62ffffff1060041b179060019160b56201000083831c0191841c1b0260121c80820401821c80820401821c80820401821c80820401821c80820401821c80820401821c80910401901c90565b80809260011b9704109003901b01805f19838609928086029509938281808795109103039091909281805f0316809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b9015150190615a56565b919394929092670de0b6b3a7640000908181145f14615bbe57505003029080820491061515010190565b83838284615bdb9984969997980202970302910201920302615d52565b8091019081105f031790565b906040019081519182615bf957505050565b5f905280515f198101825260051b01818103615c13575050565b5180825260400152565b612710908219828110615c31575b50505090565b6bcd1e9517bb0cb8d0d5cde893927fe98f46388916ca2f096ea767dc04dddb45d2ca2c2f44e7bcc529d6aded9c11f0845c3f14615c6f575b50615c2b565b615c8294500391614cb891905c90612414565b5f808080615c69565b9190670de0b6b3a7640000928381860204029383039183828402049185040190818110155f14615d075703826001945b8360021b02048180020191600183811c01835b848210615cf657505060011b9315615cef57015b0290808204910615150190565b9003615ce2565b909350838104840160011c90615cce565b9003825f94615cbb565b905f198183099102908180821091030382610100031b911c1790565b91905f198184099202908181610100039381808210910303841b911c17911b15150190565b90915f19918284820991848202918183808610950396858803920992818311948686019714615de857918391615dd19391909281805f0316809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b90151581019081106115e65701019081105f031790565b80935082915004910615150101019081105f031790565b919392610300916001600160a01b0316948509060191610120830192610140810190815190816101608582189201511702615e4b57508115615e3e5752565b63ad1991f55f526004601cfd5b639a62e8b45f52602052506040526044601cfd

Verified Source Code Partial Match

Compiler: v0.8.25+commit.b61c2a91 EVM: cancun Optimization: Yes (2000 runs)
MainnetIntentFlat.sol 10898 lines
// SPDX-License-Identifier: MIT
pragma solidity =0.8.25 >=0.6.2 >=0.8.25 ^0.8.0 ^0.8.25;

// src/vendor/Clz.sol

// @author Modified from Solady by Vectorized https://github.com/Vectorized/solady/blob/701406e8126cfed931645727b274df303fbcd94d/src/utils/LibBit.sol#L30-L45 under the MIT license
library Clz {
    /// @dev Count leading zeros.
    /// Returns the number of zeros preceding the most significant one bit.
    /// If `x` is zero, returns 256.
    function clz(uint256 x) internal pure returns (uint256 r) {
        assembly ("memory-safe") {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            // We use a 5-bit deBruijn Sequence to convert `x`'s 8
            // most-significant bits into an index. We then index the lookup
            // table (bytewise) by the deBruijn symbol to obtain the bitwise
            // inverse of its logarithm.
            r :=
                add(
                    xor(
                        r,
                        byte(
                            and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
                            0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff
                        )
                    ),
                    iszero(x)
                )
        }
    }

    function bitLength(uint256 x) internal pure returns (uint256) {
        unchecked {
            return 256 - clz(x);
        }
    }
}

// src/Context.sol

abstract contract AbstractContext {
    function _msgSender() internal view virtual returns (address);

    function _msgData() internal view virtual returns (bytes calldata);

    function _isForwarded() internal view virtual returns (bool);
}

abstract contract Context is AbstractContext {
    function _msgSender() internal view virtual override returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual override returns (bytes calldata) {
        return msg.data;
    }

    function _isForwarded() internal view virtual override returns (bool) {
        return false;
    }
}

// src/deployer/DeployerAddress.sol

address constant DEPLOYER = 0x00000000000004533Fe15556B1E086BB1A72cEae;

// src/utils/FastLogic.sol

library FastLogic {
    function or(bool a, bool b) internal pure returns (bool r) {
        assembly ("memory-safe") {
            r := or(a, b)
        }
    }

    function and(bool a, bool b) internal pure returns (bool r) {
        assembly ("memory-safe") {
            r := and(a, b)
        }
    }

    function andNot(bool a, bool b) internal pure returns (bool r) {
        assembly ("memory-safe") {
            r := gt(a, b)
        }
    }
}

// src/utils/FreeMemory.sol

abstract contract FreeMemory {
    modifier DANGEROUS_freeMemory() {
        uint256 freeMemPtr;
        assembly ("memory-safe") {
            freeMemPtr := mload(0x40)
        }
        _;
        assembly ("memory-safe") {
            mstore(0x40, freeMemPtr)
        }
    }
}

// src/allowanceholder/IAllowanceHolder.sol

IAllowanceHolder constant ALLOWANCE_HOLDER = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734);

interface IAllowanceHolder {
    /// @notice Executes against `target` with the `data` payload. Prior to execution, token permits
    ///         are temporarily stored for the duration of the transaction. These permits can be
    ///         consumed by the `operator` during the execution
    /// @notice `operator` consumes the funds during its operations by calling back into
    ///         `AllowanceHolder` with `transferFrom`, consuming a token permit.
    /// @dev Neither `exec` nor `transferFrom` check that `token` contains code.
    /// @dev msg.sender is forwarded to target appended to the msg data (similar to ERC-2771)
    /// @param operator An address which is allowed to consume the token permits
    /// @param token The ERC20 token the caller has authorised to be consumed
    /// @param amount The quantity of `token` the caller has authorised to be consumed
    /// @param target A contract to execute operations with `data`
    /// @param data The data to forward to `target`
    /// @return result The returndata from calling `target` with `data`
    /// @notice If calling `target` with `data` reverts, the revert is propagated
    function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
        external
        payable
        returns (bytes memory result);

    /// @notice The counterpart to `exec` which allows for the consumption of token permits later
    ///         during execution
    /// @dev *DOES NOT* check that `token` contains code. This function vacuously succeeds if
    ///      `token` is empty.
    /// @dev can only be called by the `operator` previously registered in `exec`
    /// @param token The ERC20 token to transfer
    /// @param owner The owner of tokens to transfer
    /// @param recipient The destination/beneficiary of the ERC20 `transferFrom`
    /// @param amount The quantity of `token` to transfer`
    /// @return true
    function transferFrom(address token, address owner, address recipient, uint256 amount) external returns (bool);
}

// lib/permit2/src/interfaces/IEIP712.sol

interface IEIP712 {
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// lib/forge-std/src/interfaces/IERC165.sol

interface IERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    /// uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    /// `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

// src/interfaces/IERC1967Proxy.sol

interface IERC1967Proxy {
    event Upgraded(address indexed implementation);

    function implementation() external view returns (address);

    function version() external view returns (string memory);

    function upgrade(address newImplementation) external payable returns (bool);

    function upgradeAndCall(address newImplementation, bytes calldata data) external payable returns (bool);
}

// lib/forge-std/src/interfaces/IERC20.sol

/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
    /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
    /// is the new allowance.
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /// @notice Returns the amount of tokens in existence.
    function totalSupply() external view returns (uint256);

    /// @notice Returns the amount of tokens owned by `account`.
    function balanceOf(address account) external view returns (uint256);

    /// @notice Moves `amount` tokens from the caller's account to `to`.
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Returns the remaining number of tokens that `spender` is allowed
    /// to spend on behalf of `owner`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
    /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
    /// `amount` is then deducted from the caller's allowance.
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Returns the name of the token.
    function name() external view returns (string memory);

    /// @notice Returns the symbol of the token.
    function symbol() external view returns (string memory);

    /// @notice Returns the decimals places of the token.
    function decimals() external view returns (uint8);
}

// src/IERC721Owner.sol

interface IERC721Owner {
    function ownerOf(uint256) external view returns (address);
}

// src/interfaces/IMultiCall.sol

interface IMultiCall_0 {
    function multicall(bytes[] calldata datas) external;
}

// src/deployer/Nonce.sol

/// @dev if you update this, you also have to update the length of the array `NonceList.List.links` in Deployer.sol
type Nonce is uint32;

function incr(Nonce a) pure returns (Nonce) {
    return Nonce.wrap(Nonce.unwrap(a) + 1);
}

function Nonce_gt(Nonce a, Nonce b) pure returns (bool) {
    return Nonce.unwrap(a) > Nonce.unwrap(b);
}

function Nonce_eq(Nonce a, Nonce b) pure returns (bool) {
    return Nonce.unwrap(a) == Nonce.unwrap(b);
}

function isNull_0(Nonce a) pure returns (bool) {
    return Nonce.unwrap(a) == 0;
}

using {incr, Nonce_gt as >, Nonce_eq as ==, isNull_0} for Nonce global;

Nonce constant zero = Nonce.wrap(0);

// src/core/univ3forks/PancakeSwapV3.sol

address constant pancakeSwapV3Factory = 0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9;
bytes32 constant pancakeSwapV3InitHash = 0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2;
uint8 constant pancakeSwapV3ForkId = 1;

interface IPancakeSwapV3Callback {
    function pancakeV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}

// src/utils/Panic.sol

library Panic {
    function panic(uint256 code) internal pure {
        assembly ("memory-safe") {
            mstore(0x00, 0x4e487b71) // selector for `Panic(uint256)`
            mstore(0x20, code)
            revert(0x1c, 0x24)
        }
    }

    // https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require
    uint8 internal constant GENERIC = 0x00;
    uint8 internal constant ASSERT_FAIL = 0x01;
    uint8 internal constant ARITHMETIC_OVERFLOW = 0x11;
    uint8 internal constant DIVISION_BY_ZERO = 0x12;
    uint8 internal constant ENUM_CAST = 0x21;
    uint8 internal constant CORRUPT_STORAGE_ARRAY = 0x22;
    uint8 internal constant POP_EMPTY_ARRAY = 0x31;
    uint8 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    uint8 internal constant OUT_OF_MEMORY = 0x41;
    uint8 internal constant ZERO_FUNCTION_POINTER = 0x51;
}

// src/utils/Revert.sol

library Revert {
    function _revert(bytes memory reason) internal pure {
        assembly ("memory-safe") {
            revert(add(reason, 0x20), mload(reason))
        }
    }

    function maybeRevert(bool success, bytes memory reason) internal pure {
        if (!success) {
            _revert(reason);
        }
    }
}

// src/core/univ3forks/SolidlyV3.sol

address constant solidlyV3Factory = 0x70Fe4a44EA505cFa3A57b95cF2862D4fd5F0f687;
address constant solidlyV3SonicFactory = 0x777fAca731b17E8847eBF175c94DbE9d81A8f630;
bytes32 constant solidlyV3InitHash = 0xe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf;
uint8 constant solidlyV3ForkId = 3;

interface ISolidlyV3Callback {
    function solidlyV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}

// src/vendor/Sqrt.sol

// @author Modified from Solady by Vectorized https://github.com/Vectorized/solady/blob/701406e8126cfed931645727b274df303fbcd94d/src/utils/FixedPointMathLib.sol#L774-L826 under the MIT license.
library Sqrt {
    /// @dev Returns the square root of `x`, rounded down.
    function _sqrt(uint256 x) private pure returns (uint256 z) {
        assembly ("memory-safe") {
            // `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.
            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // Let `y = x / 2**r`. We check `y >= 2**(k + 8)`
            // but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.
            let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffffff, shr(r, x))))
            z := shl(shr(1, r), z)

            // Goal was to get `z*z*y` within a small factor of `x`. More iterations could
            // get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.
            // We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.
            // That's not possible if `x < 256` but we can just verify those cases exhaustively.

            // Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.
            // Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.
            // Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.

            // For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`
            // is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,
            // with largest error when `s = 1` and when `s = 256` or `1/256`.

            // Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.
            // Then we can estimate `sqrt(y)` using
            // `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.

            // There is no overflow risk here since `y < 2**136` after the first branch above.
            z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
        }
    }

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        z = _sqrt(x);
        assembly ("memory-safe") {
            // If `x+1` is a perfect square, the Babylonian method cycles between
            // `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            z := sub(z, lt(div(x, z), z))
        }
    }

    function sqrtUp(uint256 x) internal pure returns (uint256 z) {
        z = _sqrt(x);
        assembly ("memory-safe") {
            z := add(lt(mul(z, z), x), z)
        }
    }
}

// src/core/univ3forks/SushiswapV3.sol

address constant sushiswapV3MainnetFactory = 0xbACEB8eC6b9355Dfc0269C18bac9d6E2Bdc29C4F;
address constant sushiswapV3Factory = 0xc35DADB65012eC5796536bD9864eD8773aBc74C4; // Base, Linea
address constant sushiswapV3ArbitrumFactory = 0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e;
//address constant sushiswapV3AvalancheFactory = 0x3e603C14aF37EBdaD31709C4f848Fc6aD5BEc715;
//address constant sushiswapV3BlastFactory = 0x7680D4B43f3d1d54d6cfEeB2169463bFa7a6cf0d;
//address constant sushiswapV3BnbFactory = 0x126555dd55a39328F69400d6aE4F782Bd4C34ABb;
address constant sushiswapV3OptimismFactory = 0x9c6522117e2ed1fE5bdb72bb0eD5E3f2bdE7DBe0;
address constant sushiswapV3PolygonFactory = 0x917933899c6a5F8E37F31E19f92CdBFF7e8FF0e2;
address constant sushiswapV3ScrollFactory = 0x46B3fDF7b5CDe91Ac049936bF0bDb12c5d22202e;
address constant sushiswapV3GnosisFactory = 0xf78031CBCA409F2FB6876BDFDBc1b2df24cF9bEf;
//bytes32 constant sushiswapV3BlastInitHash = 0x8e13daee7f5a62e37e71bf852bcd44e7d16b90617ed2b17c24c2ee62411c5bae;
uint8 constant sushiswapV3ForkId = 2;

// src/core/univ3forks/UniswapV3.sol

address constant uniswapV3MainnetFactory = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
address constant uniswapV3SepoliaFactory = 0x0227628f3F023bb0B980b67D528571c95c6DaC1c;
address constant uniswapV3BaseFactory = 0x33128a8fC17869897dcE68Ed026d694621f6FDfD;
address constant uniswapV3BnbFactory = 0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7;
address constant uniswapV3AvalancheFactory = 0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD;
address constant uniswapV3BlastFactory = 0x792edAdE80af5fC680d96a2eD80A44247D2Cf6Fd;
address constant uniswapV3ScrollFactory = 0x70C62C8b8e801124A4Aa81ce07b637A3e83cb919;
address constant uniswapV3LineaFactory = 0x31FAfd4889FA1269F7a13A66eE0fB458f27D72A9;
address constant uniswapV3MantleFactory = 0x0d922Fb1Bc191F64970ac40376643808b4B74Df9;
address constant uniswapV3TaikoFactory = 0x75FC67473A91335B5b8F8821277262a13B38c9b3;
address constant uniswapV3WorldChainFactory = 0x7a5028BDa40e7B173C278C5342087826455ea25a;
address constant uniswapV3GnosisFactory = 0xe32F7dD7e3f098D518ff19A22d5f028e076489B1;
address constant uniswapV3SonicFactory = 0xcb2436774C3e191c85056d248EF4260ce5f27A9D;
address constant uniswapV3InkFactory = 0x640887A9ba3A9C53Ed27D0F7e8246A4F933f3424;
address constant uniswapV3MonadTestnetFactory = 0x961235a9020B05C44DF1026D956D1F4D78014276;
address constant uniswapV3UnichainFactory = 0x1F98400000000000000000000000000000000003; // https://github.com/Uniswap/contracts/blob/main/deployments/130.md#fri-nov-08-2024
address constant uniswapV3PlasmaFactory = 0xcb2436774C3e191c85056d248EF4260ce5f27A9D;
bytes32 constant uniswapV3InitHash = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
uint8 constant uniswapV3ForkId = 0;

interface IUniswapV3Callback {
    function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}

// src/deployer/Feature.sol

type Feature is uint128;

function Feature_eq(Feature a, Feature b) pure returns (bool) {
    return Feature.unwrap(a) == Feature.unwrap(b);
}

function isNull_1(Feature a) pure returns (bool) {
    return Feature.unwrap(a) == 0;
}

using {Feature_eq as ==, isNull_1} for Feature global;

function wrap(uint256 x) pure returns (Feature) {
    if (x > type(uint128).max) {
        Panic.panic(Panic.ARITHMETIC_OVERFLOW);
    }
    if (x == 0) {
        Panic.panic(Panic.ENUM_CAST);
    }
    return Feature.wrap(uint128(x));
}

// lib/forge-std/src/interfaces/IERC4626.sol

/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
/// https://eips.ethereum.org/EIPS/eip-4626
interface IERC4626 is IERC20 {
    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares
    );

    /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
    /// @dev
    /// - MUST be an ERC-20 token contract.
    /// - MUST NOT revert.
    function asset() external view returns (address assetTokenAddress);

    /// @notice Returns the total amount of the underlying asset that is “managed” by Vault.
    /// @dev
    /// - SHOULD include any compounding that occurs from yield.
    /// - MUST be inclusive of any fees that are charged against assets in the Vault.
    /// - MUST NOT revert.
    function totalAssets() external view returns (uint256 totalManagedAssets);

    /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
    /// scenario where all the conditions are met.
    /// @dev
    /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
    /// - MUST NOT show any variations depending on the caller.
    /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
    /// - MUST NOT revert.
    ///
    /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
    /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
    /// from.
    function convertToShares(uint256 assets) external view returns (uint256 shares);

    /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
    /// scenario where all the conditions are met.
    /// @dev
    /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
    /// - MUST NOT show any variations depending on the caller.
    /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
    /// - MUST NOT revert.
    ///
    /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
    /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
    /// from.
    function convertToAssets(uint256 shares) external view returns (uint256 assets);

    /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
    /// through a deposit call.
    /// @dev
    /// - MUST return a limited value if receiver is subject to some deposit limit.
    /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
    /// - MUST NOT revert.
    function maxDeposit(address receiver) external view returns (uint256 maxAssets);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
    /// current on-chain conditions.
    /// @dev
    /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
    ///   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
    ///   in the same transaction.
    /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
    ///   deposit would be accepted, regardless if the user has enough tokens approved, etc.
    /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
    /// - MUST NOT revert.
    ///
    /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
    /// share price or some other type of condition, meaning the depositor will lose assets by depositing.
    function previewDeposit(uint256 assets) external view returns (uint256 shares);

    /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
    /// @dev
    /// - MUST emit the Deposit event.
    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
    ///   deposit execution, and are accounted for during deposit.
    /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
    ///   approving enough underlying tokens to the Vault contract, etc).
    ///
    /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
    /// @dev
    /// - MUST return a limited value if receiver is subject to some mint limit.
    /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
    /// - MUST NOT revert.
    function maxMint(address receiver) external view returns (uint256 maxShares);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
    /// current on-chain conditions.
    /// @dev
    /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
    ///   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
    ///   same transaction.
    /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
    ///   would be accepted, regardless if the user has enough tokens approved, etc.
    /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
    /// - MUST NOT revert.
    ///
    /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
    /// share price or some other type of condition, meaning the depositor will lose assets by minting.
    function previewMint(uint256 shares) external view returns (uint256 assets);

    /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
    /// @dev
    /// - MUST emit the Deposit event.
    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
    ///   execution, and are accounted for during mint.
    /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
    ///   approving enough underlying tokens to the Vault contract, etc).
    ///
    /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
    function mint(uint256 shares, address receiver) external returns (uint256 assets);

    /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
    /// Vault, through a withdrawal call.
    /// @dev
    /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
    /// - MUST NOT revert.
    function maxWithdraw(address owner) external view returns (uint256 maxAssets);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
    /// given current on-chain conditions.
    /// @dev
    /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
    ///   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
    ///   called
    ///   in the same transaction.
    /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
    ///   the withdrawal would be accepted, regardless if the user has enough shares, etc.
    /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
    /// - MUST NOT revert.
    ///
    /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
    /// share price or some other type of condition, meaning the depositor will lose assets by depositing.
    function previewWithdraw(uint256 assets) external view returns (uint256 shares);

    /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver.
    /// @dev
    /// - MUST emit the Withdraw event.
    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
    ///   withdraw execution, and are accounted for during withdrawal.
    /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
    ///   not having enough shares, etc).
    ///
    /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
    /// Those methods should be performed separately.
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
    /// through a redeem call.
    /// @dev
    /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
    /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
    /// - MUST NOT revert.
    function maxRedeem(address owner) external view returns (uint256 maxShares);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
    /// given current on-chain conditions.
    /// @dev
    /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
    ///   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
    ///   same transaction.
    /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
    ///   redemption would be accepted, regardless if the user has enough shares, etc.
    /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
    /// - MUST NOT revert.
    ///
    /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
    /// share price or some other type of condition, meaning the depositor will lose assets by redeeming.
    function previewRedeem(uint256 shares) external view returns (uint256 assets);

    /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver.
    /// @dev
    /// - MUST emit the Withdraw event.
    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
    ///   redeem execution, and are accounted for during redeem.
    /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
    ///   not having enough shares, etc).
    ///
    /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
    /// Those methods should be performed separately.
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}

// src/interfaces/IOwnable.sol

interface IOwnable is IERC165 {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function owner() external view returns (address);

    function transferOwnership(address) external returns (bool);

    error PermissionDenied();
    error ZeroAddress();
}

// src/interfaces/ISettlerBase.sol

interface ISettlerBase {
    struct AllowedSlippage {
        address payable recipient;
        IERC20 buyToken;
        uint256 minAmountOut;
    }
}

// lib/permit2/src/interfaces/ISignatureTransfer.sol

/// @title SignatureTransfer
/// @notice Handles ERC20 token transfers through signature based actions
/// @dev Requires user's token approval on the Permit2 contract
interface ISignatureTransfer is IEIP712 {
    /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount
    /// @param maxAmount The maximum amount a spender can request to transfer
    error InvalidAmount(uint256 maxAmount);

    /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred
    /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred
    error LengthMismatch();

    /// @notice Emits an event when the owner successfully invalidates an unordered nonce.
    event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);

    /// @notice The token and amount details for a transfer signed in the permit transfer signature
    struct TokenPermissions {
        // ERC20 token address
        address token;
        // the maximum amount that can be spent
        uint256 amount;
    }

    /// @notice The signed permit message for a single token transfer
    struct PermitTransferFrom {
        TokenPermissions permitted;
        // a unique value for every token owner's signature to prevent signature replays
        uint256 nonce;
        // deadline on the permit signature
        uint256 deadline;
    }

    /// @notice Specifies the recipient address and amount for batched transfers.
    /// @dev Recipients and amounts correspond to the index of the signed token permissions array.
    /// @dev Reverts if the requested amount is greater than the permitted signed amount.
    struct SignatureTransferDetails {
        // recipient address
        address to;
        // spender requested amount
        uint256 requestedAmount;
    }

    /// @notice Used to reconstruct the signed permit message for multiple token transfers
    /// @dev Do not need to pass in spender address as it is required that it is msg.sender
    /// @dev Note that a user still signs over a spender address
    struct PermitBatchTransferFrom {
        // the tokens and corresponding amounts permitted for a transfer
        TokenPermissions[] permitted;
        // a unique value for every token owner's signature to prevent signature replays
        uint256 nonce;
        // deadline on the permit signature
        uint256 deadline;
    }

    /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection
    /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order
    /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce
    /// @dev It returns a uint256 bitmap
    /// @dev The index, or wordPosition is capped at type(uint248).max
    function nonceBitmap(address, uint256) external view returns (uint256);

    /// @notice Transfers a token using a signed permit message
    /// @dev Reverts if the requested amount is greater than the permitted signed amount
    /// @param permit The permit data signed over by the owner
    /// @param owner The owner of the tokens to transfer
    /// @param transferDetails The spender's requested transfer details for the permitted token
    /// @param signature The signature to verify
    function permitTransferFrom(
        PermitTransferFrom memory permit,
        SignatureTransferDetails calldata transferDetails,
        address owner,
        bytes calldata signature
    ) external;

    /// @notice Transfers a token using a signed permit message
    /// @notice Includes extra data provided by the caller to verify signature over
    /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
    /// @dev Reverts if the requested amount is greater than the permitted signed amount
    /// @param permit The permit data signed over by the owner
    /// @param owner The owner of the tokens to transfer
    /// @param transferDetails The spender's requested transfer details for the permitted token
    /// @param witness Extra data to include when checking the user signature
    /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
    /// @param signature The signature to verify
    function permitWitnessTransferFrom(
        PermitTransferFrom memory permit,
        SignatureTransferDetails calldata transferDetails,
        address owner,
        bytes32 witness,
        string calldata witnessTypeString,
        bytes calldata signature
    ) external;

    /// @notice Transfers multiple tokens using a signed permit message
    /// @param permit The permit data signed over by the owner
    /// @param owner The owner of the tokens to transfer
    /// @param transferDetails Specifies the recipient and requested amount for the token transfer
    /// @param signature The signature to verify
    function permitTransferFrom(
        PermitBatchTransferFrom memory permit,
        SignatureTransferDetails[] calldata transferDetails,
        address owner,
        bytes calldata signature
    ) external;

    /// @notice Transfers multiple tokens using a signed permit message
    /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
    /// @notice Includes extra data provided by the caller to verify signature over
    /// @param permit The permit data signed over by the owner
    /// @param owner The owner of the tokens to transfer
    /// @param transferDetails Specifies the recipient and requested amount for the token transfer
    /// @param witness Extra data to include when checking the user signature
    /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
    /// @param signature The signature to verify
    function permitWitnessTransferFrom(
        PermitBatchTransferFrom memory permit,
        SignatureTransferDetails[] calldata transferDetails,
        address owner,
        bytes32 witness,
        string calldata witnessTypeString,
        bytes calldata signature
    ) external;

    /// @notice Invalidates the bits specified in mask for the bitmap at the word position
    /// @dev The wordPos is maxed at type(uint248).max
    /// @param wordPos A number to index the nonceBitmap at
    /// @param mask A bitmap masked against msg.sender's current bitmap at the word position
    function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;
}

// src/vendor/SafeTransferLib.sol

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Modified from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address payable to, uint256 amount) internal {
        assembly ("memory-safe") {
            // Transfer the ETH and revert if it fails.
            if iszero(call(gas(), to, amount, 0x00, 0x00, 0x00, 0x00)) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0x00, returndatasize())
                revert(ptr, returndatasize())
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function fastBalanceOf(IERC20 token, address acct) internal view returns (uint256 r) {
        assembly ("memory-safe") {
            mstore(0x14, acct) // Store the `acct` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // Selector for `balanceOf(address)`, with `acct`'s padding.

            // Call and check for revert. Storing the selector with padding in
            // memory at 0 results in a start of calldata at offset 16. Calldata
            // is 36 bytes long (4 bytes selector, 32 bytes argument)
            if iszero(staticcall(gas(), token, 0x10, 0x24, 0x00, 0x20)) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0x00, returndatasize())
                revert(ptr, returndatasize())
            }
            // Check for short returndata and missing code
            if iszero(lt(0x1f, returndatasize())) { revert(0x00, 0x00) }

            r := mload(0x00)
        }
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            let ptr := mload(0x40) // Cache the free memory pointer.

            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(0x60, from)) // Store the `from` argument. (Clears `to`'s padding.)
            mstore(0x0c, 0x23b872dd000000000000000000000000) // Selector for `transferFrom(address,address,uint256)`, with `from`'s padding.

            // Calldata starts at offset 28 and is 100 bytes long (3 * 32 + 4).
            // If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
            if iszero(call(gas(), token, 0x00, 0x1c, 0x64, 0x00, 0x20)) {
                returndatacopy(ptr, 0x00, returndatasize())
                revert(ptr, returndatasize())
            }
            // We check that the call either returned exactly 1 [true] (can't just be non-zero
            // data), or had no return data.
            if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
                mstore(0x00, 0x7939f424) // Selector for `TransferFromFailed()`
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0x00) // Restore the zero slot to zero.
            mstore(0x40, ptr) // Restore the free memory pointer.
        }
    }

    function safeTransfer(IERC20 token, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            // Storing `amount` clobbers the upper bits of the free memory pointer, but those bits
            // can never be set without running into an OOG, so it's safe. We'll restore them to
            // zero at the end.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // Selector for `transfer(address,uint256)`, with `to`'s padding.

            // Calldata starts at offset 16 and is 68 bytes long (2 * 32 + 4).
            // If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
            if iszero(call(gas(), token, 0x00, 0x10, 0x44, 0x00, 0x20)) {
                let ptr := and(0xffffff, mload(0x40))
                returndatacopy(ptr, 0x00, returndatasize())
                revert(ptr, returndatasize())
            }
            // We check that the call either returned exactly 1 [true] (can't just be non-zero
            // data), or had no return data.
            if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
                mstore(0x00, 0x90b8ec18) // Selector for `TransferFailed()`
                revert(0x1c, 0x04)
            }

            mstore(0x34, 0x00) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    function safeApprove(IERC20 token, address to, uint256 amount) internal {
        assembly ("memory-safe") {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            // Storing `amount` clobbers the upper bits of the free memory pointer, but those bits
            // can never be set without running into an OOG, so it's safe. We'll restore them to
            // zero at the end.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // Selector for `approve(address,uint256)`, with `to`'s padding.

            // Calldata starts at offset 16 and is 68 bytes long (2 * 32 + 4).
            // If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
            if iszero(call(gas(), token, 0x00, 0x10, 0x44, 0x00, 0x20)) {
                let ptr := and(0xffffff, mload(0x40))
                returndatacopy(ptr, 0x00, returndatasize())
                revert(ptr, returndatasize())
            }
            // We check that the call either returned exactly 1 [true] (can't just be non-zero
            // data), or had no return data.
            if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
                mstore(0x00, 0x3e3f8f73) // Selector for `ApproveFailed()`
                revert(0x1c, 0x04)
            }

            mstore(0x34, 0x00) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    function safeApproveIfBelow(IERC20 token, address spender, uint256 amount) internal {
        uint256 allowance = token.allowance(address(this), spender);
        if (allowance < amount) {
            if (allowance != 0) {
                safeApprove(token, spender, 0);
            }
            safeApprove(token, spender, type(uint256).max);
        }
    }
}

// src/core/SettlerErrors.sol

/// @notice Thrown when an offset is not the expected value
error InvalidOffset();

/// @notice Thrown when a validating a target contract to avoid certain types of targets
error ConfusedDeputy();

function revertConfusedDeputy() pure {
    assembly ("memory-safe") {
        mstore(0x00, 0xe758b8d5) // selector for `ConfusedDeputy()`
        revert(0x1c, 0x04)
    }
}

/// @notice Thrown when a target contract is invalid given the context
error InvalidTarget();

/// @notice Thrown when validating the caller against the expected caller
error InvalidSender();

/// @notice Thrown in cases when using a Trusted Forwarder / AllowanceHolder is not allowed
error ForwarderNotAllowed();

/// @notice Thrown when a signature length is not the expected length
error InvalidSignatureLen();

/// @notice Thrown when a slippage limit is exceeded
error TooMuchSlippage(IERC20 token, uint256 expected, uint256 actual);

function revertTooMuchSlippage(IERC20 buyToken, uint256 expectedBuyAmount, uint256 actualBuyAmount) pure {
    assembly ("memory-safe") {
        mstore(0x54, actualBuyAmount)
        mstore(0x34, expectedBuyAmount)
        mstore(0x14, buyToken)
        mstore(0x00, 0x97a6f3b9000000000000000000000000) // selector for `TooMuchSlippage(address,uint256,uint256)` with `buyToken`'s padding
        revert(0x10, 0x64)
    }
}

/// @notice Thrown when a byte array that is supposed to encode a function from ISettlerActions is
///         not recognized in context.
error ActionInvalid(uint256 i, bytes4 action, bytes data);

function revertActionInvalid(uint256 i, uint256 action, bytes calldata data) pure {
    assembly ("memory-safe") {
        let ptr := mload(0x40)
        mstore(ptr, 0x3c74eed6) // selector for `ActionInvalid(uint256,bytes4,bytes)`
        mstore(add(0x20, ptr), i)
        mstore(add(0x40, ptr), shl(0xe0, action)) // align as `bytes4`
        mstore(add(0x60, ptr), 0x60) // offset to the length slot of the dynamic value `data`
        mstore(add(0x80, ptr), data.length)
        calldatacopy(add(0xa0, ptr), data.offset, data.length)
        revert(add(0x1c, ptr), add(0x84, data.length))
    }
}

/// @notice Thrown when the encoded fork ID as part of UniswapV3 fork path is not on the list of
///         recognized forks for this chain.
error UnknownForkId(uint8 forkId);

function revertUnknownForkId(uint8 forkId) pure {
    assembly ("memory-safe") {
        mstore(0x00, 0xd3b1276d) // selector for `UnknownForkId(uint8)`
        mstore(0x20, and(0xff, forkId))
        revert(0x1c, 0x24)
    }
}

/// @notice Thrown when an AllowanceHolder transfer's permit is past its deadline
error SignatureExpired(uint256 deadline);

/// @notice Thrown when selling the native asset, but `msg.value` exceeds the value from the generated quote
error MsgValueMismatch(uint256 expected, uint256 actual);

/// @notice An internal error that should never be thrown. Thrown when a callback reenters the
///         entrypoint and attempts to clobber the existing callback.
error ReentrantCallback(uint256 callbackInt);

/// @notice An internal error that should never be thrown. This error can only be thrown by
///         non-metatx-supporting Settler instances. Thrown when a callback-requiring liquidity
///         source is called, but Settler never receives the callback.
error CallbackNotSpent(uint256 callbackInt);

/// @notice Thrown when a metatransaction has reentrancy.
error ReentrantMetatransaction(bytes32 oldWitness);

/// @notice Thrown when any transaction has reentrancy, not just taker-submitted or metatransaction.
error ReentrantPayer(address oldPayer);

/// @notice An internal error that should never be thrown. Thrown when a metatransaction fails to
///         spend a coupon.
error WitnessNotSpent(bytes32 oldWitness);

/// @notice An internal error that should never be thrown. Thrown when the payer is unset
///         unexpectedly.
error PayerSpent();

error DeltaNotPositive(IERC20 token);
error DeltaNotNegative(IERC20 token);
error ZeroSellAmount(IERC20 token);
error ZeroBuyAmount(IERC20 buyToken);
error BoughtSellToken(IERC20 sellToken);
error TokenHashCollision(IERC20 token0, IERC20 token1);
error ZeroToken();

/// @notice Thrown for liquidities that require a Newton-Raphson approximation to solve their
///         constant function when Newton-Raphson fails to converge on the solution in a
///         "reasonable" number of iterations.
error NotConverged();

/// @notice Thrown when the encoded pool manager ID as part of PancakeSwap Infinity fill is not on
///         the list of recognized pool managers.
error UnknownPoolManagerId(uint8 poolManagerId);

// src/utils/Ternary.sol

library Ternary {
    //// All the code duplication ...

// [truncated — 466726 bytes total]

Read Contract

getSolvers 0x8bc1e8eb → address[]
owner 0x8da5cb5b → address
rebateClaimer 0x67c4a3b0 → address

Write Contract 2 functions

These functions modify contract state and require a wallet transaction to execute.

executeMetaTxn 0xe7f9ee31
tuple slippage
bytes[] actions
bytes32
address msgSender
bytes sig
returns: bool
setSolver 0x4b7758a5
address prev
address solver
bool addNotRemove

Token Balances (1)

View Transfers →
stETH 0

Recent Transactions

No transactions found for this address