Address Contract Partially Verified
Address
0x12D737470fB3ec6C3DeEC9b518100Bec9D520144
Balance
0 ETH
Nonce
1
Code Size
22202 bytes
Creator
0xd694Bf94...83Ab at tx 0xb840085e...dd5776
Indexed Transactions
0
Contract Bytecode
22202 bytes
0x6080604052600436108015610448575b36156104465734610213577e9355806b743562f351db2e3726091207f49fa1cdccd5c65a7d4860ce3abbe9905f825c925d7fffffffff000000000000000000000000000000000000000000000000000000005f3581811692610431575b50808316911603610213576001600160a01b0380821633036102135736600411610213577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36019160a01c61ffff16908160011461035d57816002146102175750600314610101577f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffd5b6080116102135760043560443590816004013561012181602485016155c4565b60601c9181601411610213575f81131561020957915b308103610193575061017361017b9360387fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec33940191016155c4565b60601c6133d1565b60405161018781610bc2565b5f81525b602081519101f35b916101a261020494931561347f565b604051906101af82610b2d565b33825260208201526101fe6101c736602c8601610c01565b92608d8501356001169460ad7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff773693019101610c77565b91614bb8565b61017b565b5060243591610137565b5f80fd5b9160a091501061021357608435907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f82019160a435918083168084036102135761026591600435161461347f565b60405161027181610b2d565b33815260243560208201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c360192608084126102135760408051946102b686610b76565b1261021357604051906102c882610b2d565b815260c4356020820152835260e43560208401526101043560408401526102ee84610c5b565b916102fc6040519384610bde565b8483523660a4820111610213577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f5f91610349966101256020870137840101526101053560011692614bb8565b60405161035581610bc2565b5f815261018b565b9160a091500361021357600435604435908060a01c8260a01c17610213578261038791161561347f565b5f5c905f805d60019260015c915f60015d60025c5f60025d60035c905f60035d6040519460209486860160045c995f60045d878b8a01019a89528a60405260055b8b831061041f575050506103499850604051946103e486610b2d565b16845284840152604051926103f884610b76565b83528383015260408201526040519161041083610b2d565b33835260643590830152614bb8565b805c83525f815d8101918801916103c8565b818093503660040360031b1b1616905f61006c565b005b5f3560e01c63fd3ad6d40361000f5734610213577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360160e08112610213576060136102135767ffffffffffffffff60643511610213573660236064350112156102135767ffffffffffffffff6064356004013511610213573660246064356004013560051b606435010111610213576001600160a01b0360a4351660a435036102135767ffffffffffffffff60c435116102135736602360c4350112156102135767ffffffffffffffff60c43560040135116102135736602460c4356004013560c4350101116102135760806064356024015b60246064356004013560051b60643501018110610ad65760a06064356004013560051b608020604051907f615e8d716cef7295e75dd3f1f10d679914ad6d7759e8e9459f0109ef7524170182526060600460208401376080820152207f1643bf8e9fdaef48c4abf5a998de359be44a235ac7aebfbc05485e093720deaa5c80610aa557507f1643bf8e9fdaef48c4abf5a998de359be44a235ac7aebfbc05485e093720deaa5d6001600160a01b0360a4351615610a7b576001600160a01b037f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c1680610a4a5760a4356001600160a01b03167f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935d606435600401351561021357602460643501356064350160448101359060487ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602483013501910191604051926106b660c43560040135602460c43501858486610cba565b84604052156109e35760015b606435600401358110610915576004356001600160a01b03811680820361021357602435906001600160a01b038216928383036102135760443593841580159061090c575b6107fd575b50505050506001600160a01b0360a435166001600160a01b037f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c16036107d3575f7f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935d7f1643bf8e9fdaef48c4abf5a998de359be44a235ac7aebfbc05485e093720deaa5c806107a257602060405160018152f35b602490604051907fe25527c20000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517f5149e795000000000000000000000000000000000000000000000000000000008152fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81036108865750504791838310610838575061082e925061343f565b808080808061070c565b6040517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526024810193909352506044820152606490fd5b0390fd5b602493919250602090604051948580926370a0823160e01b82523060048301525afa928315610901575f936108cd575b50838310610838576108c893506133d1565b61082e565b9092506020813d6020116108f9575b816108e960209383610bde565b81010312610213575191846108b6565b3d91506108dc565b6040513d5f823e3d90fd5b50801515610707565b60246064358260051b010135606435019060448201359160487ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc602483013501910160405191610966818387611e6b565b836040521561097c5750505060019150016106c2565b7fffffffff00000000000000000000000000000000000000000000000000000000839584957f3c74eed60000000000000000000000000000000000000000000000000000000061088296526004870152166024850152606060448501526064840191610b0d565b83927fffffffff00000000000000000000000000000000000000000000000000000000610882937f3c74eed60000000000000000000000000000000000000000000000000000000086525f6004870152166024850152606060448501526064840191610b0d565b602490604051907f7407c0f80000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517fe758b8d5000000000000000000000000000000000000000000000000000000008152fd5b602490604051907f9936cbab0000000000000000000000000000000000000000000000000000000082526004820152fd5b60448135606435016024810135918291018437822082526020918201910161053c565b35906001600160a01b038216820361021357565b601f8260209493601f1993818652868601375f8582860101520116010190565b6040810190811067ffffffffffffffff821117610b4957604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6060810190811067ffffffffffffffff821117610b4957604052565b6080810190811067ffffffffffffffff821117610b4957604052565b67ffffffffffffffff8111610b4957604052565b6020810190811067ffffffffffffffff821117610b4957604052565b90601f601f19910116810190811067ffffffffffffffff821117610b4957604052565b8092910391608083126102135760405190610c1b82610b76565b60408294126102135760606040918251610c3481610b2d565b610c3d82610af9565b81526020820135602082015284528281013560208501520135910152565b67ffffffffffffffff8111610b4957601f01601f191660200190565b929192610c8382610c5b565b91610c916040519384610bde565b829481845281830111610213578281602093845f960137010152565b3590811515820361021357565b919091610cca8585848685611552565b15610cd9575050505050600190565b7fffffffff00000000000000000000000000000000000000000000000000000000167f8d62436100000000000000000000000000000000000000000000000000000000810361114957508101906101008183031261021357610d3a81610af9565b92602091604094610d59610d4f878401610cad565b9560608401610c01565b9660e083013597610e7e610e086055610d7d6001600160a01b039889963691610c77565b967fbb7b783eb4b8ca46925c5384a6b9919df57cb83da8f76e37291f58d0dd5c439a60e18d730a7e848aca42d879ef06507fca0e7b33a0a63c1e8d82519c8d91848c518483015e848c8201846060015e5f8360a001538151918291018360a1015e806081018252019160a18301809152528c60ac82019460ff8653013560c1820152015220926135fc565b881561112357637fffffff5b8a5191610e2083610b92565b8252891515898301525f8b83015260030b6060820152610e708a51968792868b8501987f3eece7db000000000000000000000000000000000000000000000000000000008a521660248501611df7565b03601f198101865285610bde565b16927f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c1683146110fa577e9355806b743562f351db2e3726091207f49fa1cdccd5c65a7d4860ce3abbe991825c806110ca57505f9182917f67ca7c91000000000000000200000000000000000000000000000000000000008617855d519082865af190610f0a614fb4565b91156110c2575c806110925750808380610f2993518301019101611e41565b939050858410610f3e57505050505050600190565b6004939291829115611016578551948580927f5f64b55b0000000000000000000000000000000000000000000000000000000082525afa90811561100c575f91610fd5575b506108829250925b519384937f97a6f3b9000000000000000000000000000000000000000000000000000000008552600485016040919493926001600160a01b03606083019616825260208201520152565b905082813d8311611005575b610feb8183610bde565b8101031261021357610fff61088292611e57565b85610f83565b503d610fe1565b84513d5f823e3d90fd5b8551948580927f0fc63d100000000000000000000000000000000000000000000000000000000082525afa90811561100c575f9161105b575b50610882925092610f8b565b905082813d831161108b575b6110718183610bde565b810103126102135761108561088292611e57565b8561104f565b503d611067565b6024908651907fd66fcc380000000000000000000000000000000000000000000000000000000082526004820152fd5b508281519101fd5b6024908851907fab7646c40000000000000000000000000000000000000000000000000000000082526004820152fd5b600486517fe758b8d5000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000610e14565b7fdaac39fd000000000000000000000000000000000000000000000000000000000361152c5781019260e0828503126102135761118582610af9565b602092838101359469ffffffffffffffffffff86168603610213576111c26111b1604098898501610c01565b916001600160a01b03953691610c77565b926111cc826135fc565b9267ffffffffffffffff93848960101c16958960081c9680155f14611437575076d6940c0e5f2ff0ff18a3be9b835635039256dc4b4963805f526017600920949088949392915b5f805d80518b01519060019160015d808c015160025d8d015160035d818b018b8351938401019260045d6005905b83811061141a57505050508a5199898b01977fdd96994f00000000000000000000000000000000000000000000000000000000895260ff1660248c015260ff1660448b015260648a015260c00135608489015260a488015f905260c488015f90521660e48701526101048087017f6370a85c000000000000000000000000000000000000000000000000000000009052865261014086019186831090831117610b49578187528316927f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c1683146113f257507e9355806b743562f351db2e3726091207f49fa1cdccd5c65a7d4860ce3abbe993845c806113c25750915f92918380937f6370a85c000000000000000100000000000000000000000000000000000000008417885d51925af190611376614fb4565b91156113bc5750505c908161138c575050600190565b6024925051907fd66fcc380000000000000000000000000000000000000000000000000000000082526004820152fd5b81519101fd5b6024908751907fab7646c40000000000000000000000000000000000000000000000000000000082526004820152fd5b807fe758b8d50000000000000000000000000000000000000000000000000000000060049252fd5b80919293949596975051825d8b019082018a969594939291611241565b608081101561147257730c0e5f2ff0ff18a3be9b835635039256dc4b496360145261d6945f526034536017601e20945b908894939291611213565b600863ffffffff8c60301c16611511575b6001811b66ffffffffffffff8d60181c161015611509575b6001811b821015611501575b6001811b68ffffffffffffffff008a1610156114f9575b60031c90815280607f018a53730c0e5f2ff0ff18a3be9b835635039256dc4b49635f528060d501600a536094600b53601601600a2094611467565b6008016114be565b6008016114a7565b60100161149b565b5060288782036114835760118b634e487b715f52526024601cfd5b505050505f90565b9080601f830112156102135781602061154f93359101610c77565b90565b9091907fffffffff00000000000000000000000000000000000000000000000000000000167f5228831d00000000000000000000000000000000000000000000000000000000810361177d5750810161016082820312610213576115b582610af9565b906115c38160208501610c01565b946115d060a08501610af9565b9460c08501359667ffffffffffffffff88116102135761171a866fffffffffffffffffffffffffffffffff966116746116228860e061161b6117789f9b6117709c6117099f01611534565b9501610c01565b9a61163b6001600160a01b039788809316993691610c77565b9261166d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8ef602089510151111561347f565b168561344e565b9990918b61170388806116878c8561344e565b929094515116917f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c90604051936116be85610b92565b845260208401521660408201525f6060820152601f19019081517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa835260a083209252565b9c614a4a565b8986611713613512565b9286614e5a565b515116906040519161172b83610b92565b825284602083015260408201525f6060820152601f19019081517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa835260a083209252565b911691614eee565b600190565b929391927f0dfeb4190000000000000000000000000000000000000000000000000000000081036117f45750820160a08382031261021357611778936117e56001600160a01b036117dd6117ee9460206117d689610af9565b9801610c01565b95168561344e565b50923691610c77565b91614a4a565b92949193927f9ebf8e8d0000000000000000000000000000000000000000000000000000000003611dc95784019360e0818603126102135761183581610af9565b9260208201359067ffffffffffffffff82116102135761186761185d8861186f948601611534565b9760408501610c01565b953691610c77565b80516089019485608911611b90576118d991601f196118a661189089610c5b565b9861189e6040519a8b610bde565b808a52610c5b565b013660208901378151602001518760480152604082602001886068015e5f8760a801538051906020018760a9015e6135fc565b5f937f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211611b7e5795905b815190602c8210611b0457866014840151601585015197601886015190602c87015194838690879c6001600160a01b0389166001600160a01b0388161015611dbe575b60ff1680611c7657506001600160a01b03916119c591731f98431c8ad98523631ae4a59f267346ea31f9847fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549263fa461e33985b62ffffff16906040519387165f528616602052806040521560051b6060035f20916040526137e1565b1691855190858760280152866014015285528c602c88115f14611be25750611a646001600160a01b0393878594611a5f611a7395611a516040519b8c9586938d8c8084169116105f14611bc4578d8c806401000276a4945b7f128acb080000000000000000000000000000000000000000000000000000000060208a0152169116103060248701614a14565b03601f198101845283610bde565b6136d1565b60208082518301019101611e41565b9590946040525b1691161015611bbd57505b7f80000000000000000000000000000000000000000000000000000000000000008114611b90575f03945f8612611b7e57602c86921115611b165750503093906018815110611b045780517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe80160189091019081526028865290611905565b634e487b715f5260326020526024601cfd5b939650935050925060c08301358210611b3157505050600190565b6040517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b0391909116600482015260c0929092013560248301526044820152606490fd5b634e487b715f5260116020526024601cfd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9050611a85565b8d8c8073fffd8963efd1fc6a506488495d951d5263988d2594611a1d565b926001600160a01b03611c5293611a5f89611a51849b9a8a611a6498879b888616898416105f14611c5a57886401000276a4935b816040519b8c997f128acb080000000000000000000000000000000000000000000000000000000060208c015216911610911660248701614a14565b949093611a7a565b8873fffd8963efd1fc6a506488495d951d5263988d2593611c16565b60018103611cce57506001600160a01b03916119c5917341ff9aa7e16b8b1a8a8dc4f0efacd93d02d071c97f6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2926323a69e759861199c565b60028103611d2657506001600160a01b03916119c59173baceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f7fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549263fa461e339861199c565b9091929394959650600381145f14611d8d57506119c58d96959493926001600160a01b03927370fe4a44ea505cfa3a57b95cf2862d4fd5f0f6877fe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf92633a1c453c9861199c565b602490604051907fd3b1276d0000000000000000000000000000000000000000000000000000000082526004820152fd5b869250889150611948565b50925050505f90565b90601f19601f602080948051918291828752018686015e5f8582860101520116010190565b606061154f94936001600160a01b0360c094168352805160208401526020810151151560408401526040810151151582840152015160030b60808201528160a08201520190611dd2565b9190826040910312610213576020825192015190565b51906001600160a01b038216820361021357565b915f92611e79828483613810565b15611e875750505050600190565b7fffffffff00000000000000000000000000000000000000000000000000000000167f339a02300000000000000000000000000000000000000000000000000000000081036124fc57508160c0918101031261021357611ee681610af9565b602091611ef4838201610af9565b9060409384820135906060830135936001600160a01b03808616809603610213578060a0611f2460808801610cad565b96013597169415612327578751916370a0823160e01b83526004943086850152736b175474e89094c44da98b954eedeac495271d0f938581602481885afa9081156122bc578c916122f8575b5061271091611f7e916149e2565b04918951907ffae036d5000000000000000000000000000000000000000000000000000000008252858288818c5afa9182156122bc5787929187918e936122c6575b508c51938480927f313ce56700000000000000000000000000000000000000000000000000000000825287165afa9182156122bc578c92612275575b50670de0b6b3a764000060ff91019116600a0a830204978089106122265750508751907fdd62ed3e00000000000000000000000000000000000000000000000000000000825230858301528660248301528382604481865afa91821561221c575f926121ed575b5081106120fe575b505050823b156120fa5784517f8d7ef9bb0000000000000000000000000000000000000000000000000000000081526001600160a01b03909216908201908152602081019390935292918491849182908490829060400103925af19081156120f157506120da575b5050600190565b6120e48291610bae565b6120ee57806120d3565b80fd5b513d84823e3d90fd5b8580fd5b612191575b905f6044819389519485917f095ea7b300000000000000000000000000000000000000000000000000000000835289888401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248401525af11561218957503d15601f3d1160015f511416171561217e575f808061206b565b633e3f8f735f52601cfd5b3d5f823e3d90fd5b86517f095ea7b300000000000000000000000000000000000000000000000000000000815285848201525f6024820152825f60448382865af11561218957503d15601f3d1160015f511416176121035782633e3f8f735f52601cfd5b9091508381813d8311612215575b6122058183610bde565b810103126102135751905f612063565b503d6121fb565b89513d5f823e3d90fd5b6108828987928c519485947f97a6f3b900000000000000000000000000000000000000000000000000000000865285016040919493926001600160a01b03606083019616825260208201520152565b9091508581813d83116122b5575b61228d8183610bde565b810103126122b157670de0b6b3a76400006122a960ff926149d4565b929150611ffc565b8b80fd5b503d612283565b8b513d8e823e3d90fd5b9350915082813d83116122f1575b6122de8183610bde565b810103126102135785879251915f611fc0565b503d6122d4565b90508581813d8311612320575b61230f8183610bde565b810103126102135751612710611f70565b503d612305565b82602491899a989a97969593949751928380926370a0823160e01b825230600483015287165afa9081156124c3575f916124cd575b506127109161236a916149e2565b04908651907f01664f660000000000000000000000000000000000000000000000000000000082528582600481885afa9182156124c3579183916123b5935f92612494575b5061523a565b823b156102135785517f959912760000000000000000000000000000000000000000000000000000000081526001600160a01b039290921660048301526024820152905f908290604490829084905af1801561100c57612481575b5083612420575b50505050600190565b81803e51908282106124325780612417565b6064935051917f97a6f3b9000000000000000000000000000000000000000000000000000000008352736b175474e89094c44da98b954eedeac495271d0f600484015260248301526044820152fd5b61248c919250610bae565b5f905f612410565b6124b5919250883d8a116124bc575b6124ad8183610bde565b8101906149f5565b905f6123af565b503d6124a3565b88513d5f823e3d90fd5b90508581813d83116124f5575b6124e48183610bde565b81010312610213575161271061235c565b503d6124da565b9192509082907f67848fe70000000000000000000000000000000000000000000000000000000081036128dc575060c091810103126102135761253e81610af9565b60209061254c828401610af9565b9160409283850135946060810135916001600160a01b03908184168094036102135760a061257c60808501610cad565b930135975f9080612875575b50878161286057869150916024849351809481936370a0823160e01b8352896004840152165afa908115612856575f91612829575b5086517f1865c57d0000000000000000000000000000000000000000000000000000000081526101208082600481895afa91821561221c579089949392915f9261272b575b50506fffffffffffffffffffffffffffffffff809188875f14612723575051165b169003955b83156126fd57637fffffff5b83519761264089610b92565b8852841515878901525f8489015260030b606088015261269b835161266481610bc2565b5f8152845198899485947f3eece7db0000000000000000000000000000000000000000000000000000000086521660048501611df7565b03815f865af19384156126f3575f946126c2575b50858410610f3e57505050505050600190565b6126e3919450853d87116126ec575b6126db8183610bde565b810190611e41565b9050925f6126af565b503d6126d1565b85513d5f823e3d90fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000612634565b015116612623565b818096508193503d8311612822575b6127448183610bde565b8101031261021357885193840184811067ffffffffffffffff821117610b4957895261276f8161499c565b845261277c87820161499c565b8785015261278b8982016149b9565b8985015261279b606082016149b9565b6060850152608081015164ffffffffff8116810361021357608085015260a08101518060030b81036102135760a08501526127d860c082016149c7565b60c085015260e081015163ffffffff8116810361021357846fffffffffffffffffffffffffffffffff92839260e08d9801526128186101008092016149d4565b9082015291612602565b503d61273a565b90508481813d831161284f575b6128408183610bde565b8101031261021357515f6125bd565b503d612836565b87513d5f823e3d90fd5b92918186612870929993996133d1565b612628565b88516370a0823160e01b8152306004820152915086826024818688165afa801561221c575f906128ad575b612710925002045f612588565b508682813d83116128d5575b6128c38183610bde565b810103126102135761271091516128a0565b503d6128b9565b7fca9e5d0f000000000000000000000000000000000000000000000000000000008103612c3d575060c091810103126102135761291881610af9565b906020612926818301610af9565b9160409283820135916060810135916001600160a01b0393848416809403610213578460a061295760808601610cad565b9401359816948682612bba575b505050505f14612ab1578351917fdd93f59a000000000000000000000000000000000000000000000000000000008352600483015282826024815f855af191821561100c575f92612a82575b508482106129c2575050505050600190565b826004918551928380927f4a248d2a0000000000000000000000000000000000000000000000000000000082525afa92831561100c575f93612a49575b505091517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b0391909116600482015260248101929092526044820152606490fd5b90809350813d8311612a7b575b612a608183610bde565b8101031261021357612a7461088292611e57565b91856129ff565b503d612a56565b9091508281813d8311612aaa575b612a9a8183610bde565b810103126102135751905f6129b0565b503d612a90565b8351917fbd6015b4000000000000000000000000000000000000000000000000000000008352600483015282826024815f855af191821561100c575f92612b8b575b50848210612b05575050505050600190565b826004918551928380927fd4b970460000000000000000000000000000000000000000000000000000000082525afa92831561100c575f93612a4957505091517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b0391909116600482015260248101929092526044820152606490fd5b9091508281813d8311612bb3575b612ba38183610bde565b810103126102135751905f612af3565b503d612b99565b6024918951928380926370a0823160e01b825230600483015287165afa9081156124c35790859392915f91612c08575b50612bff9391612bf991614f31565b916133d1565b5f808086612964565b809450888092503d8311612c36575b612c218183610bde565b81010312610213579151849290612bff612bea565b503d612c17565b7fb8df6d4d00000000000000000000000000000000000000000000000000000000141590506133cb578160a0918101031261021357612c7b81610af9565b90602091604090818301356001600160a01b039384821680920361021357612ca560608201610cad565b9260808201359185516370a0823160e01b8152888160248160049b308d83015287165afa908115612856579089915f9161339c575b5081612ce99293013590614f31565b94612cf586868561523a565b156133505750845160e0810181811067ffffffffffffffff8211176133245786525f81528781015f8152868201905f825260608301905f825260808401915f835260a08501905f825260c086015f81528c8c8b8151928380927fffa642250000000000000000000000000000000000000000000000000000000082525afa8015613226578f908f928f908e925f915f91613305575b508852895251928380927f17be952e0000000000000000000000000000000000000000000000000000000082525afa8015613226578f5f916132cf575b5060ff91501660038110156131cc5781528b517f796da7af0000000000000000000000000000000000000000000000000000000081528e818f818e5afa908115613226578f908f928f908e925f9161329a575b508b5251928380927f7c9b8e890000000000000000000000000000000000000000000000000000000082525afa908115613226578f908f928f908e925f91613265575b50865251928380927feab5d20e0000000000000000000000000000000000000000000000000000000082525afa908115613226578f908f928f908e925f91613230575b508a5251928380927fec2fd46d0000000000000000000000000000000000000000000000000000000082525afa908115613226578f5f926131f8575b50508452805160038110156131cc576130db57505050505050612eff908561558f565b8551907fc0ffa17800000000000000000000000000000000000000000000000000000000825288828981885afa918215612856575f926130ac575b508651917fab44a7a300000000000000000000000000000000000000000000000000000000835289838a81895afa9081156124c3575f9161307b575b612f8f935001670de0b6b3a7640000908101910261502a565b9180831061302c575050908592915f855196612faa88610bc2565b818852612fe38751988996879586947fe67ce7060000000000000000000000000000000000000000000000000000000086528501614980565b03925af19081156130235750612ffa575050600190565b813d831161301c575b61300d8183610bde565b81010312610213575f806120d3565b503d613003565b513d5f823e3d90fd5b61088283889288519485947f97a6f3b900000000000000000000000000000000000000000000000000000000865285016040919493926001600160a01b03606083019616825260208201520152565b90508983813d83116130a5575b6130928183610bde565b8101031261021357612f8f925190612f76565b503d613088565b9091508881813d83116130d4575b6130c48183610bde565b810103126102135751905f612f3a565b503d6130ba565b5160038110156131a05760010361311e5750506130fc613116939451614fe3565b915190670de0b6b3a7640000898651925194020491615608565b905103612eff565b919290935190519003835182519003808a11155f14613189575050916131719391838961315095510194859451614fe3565b9251905191519061317783670de0b6b3a7640000809981988583960261502a565b026156a2565b82020490840301930302040204612eff565b915093915061319a9250870361558f565b01612eff565b60218d7f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b60218e7f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b90809250813d831161321f575b61320f8183610bde565b8101031261021357515f8f612edc565b503d613205565b8d513d5f823e3d90fd5b945050505081813d831161325e575b6132498183610bde565b81010312610213578e8b8f928f90515f612ea0565b503d61323f565b945050505081813d8311613293575b61327e8183610bde565b81010312610213578e8b8f928f90515f612e5d565b503d613274565b945050505081813d83116132c8575b6132b38183610bde565b81010312610213578e8b8f928f90515f612e1a565b503d6132a9565b905081813d83116132fe575b6132e58183610bde565b81010312610213576132f860ff916149d4565b8f612dc7565b503d6132db565b905061331e9150823d84116126ec576126db8183610bde565b5f612d8a565b6041887f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b9390505f85939293519661336388610bc2565b818852612fe38751988996879586947f8dae73330000000000000000000000000000000000000000000000000000000086528501614980565b82819392503d83116133c4575b6133b38183610bde565b810103126102135751889081612cda565b503d6133a9565b50505f90565b60446020925f80936001600160a01b03966040519788947fa9059cbb00000000000000000000000000000000000000000000000000000000865216600485015260248401525af11561218957503d15601f3d1160015f511416171561343257565b6390b8ec185f526004601cfd5b5f80809381935af11561090157565b909161347a6040519261346084610b2d565b60208401935f85526001600160a01b0381961690526135fc565b809252565b1561348657565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b604051906134c082610b76565b602e82527f696e7432353620616d6f756e74290000000000000000000000000000000000006040837f546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c7560208201520152565b60405161351e81610b92565b6058815261154f603c60208301927f436f6e73696465726174696f6e286164647265737320746f6b656e2c75696e7484527f32353620616d6f756e742c6164647265737320636f756e74657270617274792c60408201527f626f6f6c207061727469616c46696c6c416c6c6f776564290000000000000000606082015260206135a56134b3565b6040519586937f436f6e73696465726174696f6e20636f6e73696465726174696f6e2900000000848601525180918686015e8301908482015f8152815193849201905e015f8382015203601c810184520182610bde565b51906020820151917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8ef831161362e5750565b909160206001600160a01b03809351169260247f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c60405195869384926370a0823160e01b84521660048301525afa918215610901575f9261369b575b509061271161154f920190614f31565b91506020823d6020116136c9575b816136b660209383610bde565b810103126102135790519061271161368b565b3d91506136a9565b6001600160a01b03809116907f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c168114610a7b577e9355806b743562f351db2e3726091207f49fa1cdccd5c65a7d4860ce3abbe992835c806137b057509181740300000000000000000000000000000000000000005f9493859460e01b1717855d82602083519301915af190613766614fb4565b91156137a7575c80613776575090565b602490604051907fd66fcc380000000000000000000000000000000000000000000000000000000082526004820152fd5b50602081519101fd5b602490604051907fab7646c40000000000000000000000000000000000000000000000000000000082526004820152fd5b9160406055938151908152600b81019360ff8553602082015201522090565b359062ffffff8216820361021357565b9091907fffffffff00000000000000000000000000000000000000000000000000000000167fc1fb425e0000000000000000000000000000000000000000000000000000000081036138be5750810160c0828203126102135761387282610af9565b906138808160208501610c01565b9060a084013567ffffffffffffffff8111610213576138af6138b7926001600160a01b03926117789701611534565b93168261344e565b5090614a4a565b7fd92aadfb000000000000000000000000000000000000000000000000000000008103613b435750810161012082820312610213576138fc82610af9565b9160209261390c83858401610c01565b61391860a08401610af9565b9360c08401359067ffffffffffffffff821161021357613939918501611534565b9161010061394960e08601610af9565b940135936139946001600160a01b03808098169361398d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8ef8b88510151111561347f565b168461344e565b9590918785515116916139f46040938451906139af82610b92565b8152898c820152868582015260016060820152601f19019081517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa835260a083209252565b9760248b613a747f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c9c875190613a2a82610b92565b8088169e8f83528785840152168882015260016060820152601f19019081517f7d806873084f389a66fd0315dead7adaad8ae6e8b6cf9fb0d3db61e5a91c3ffa835260a083209252565b9b8651928380926370a0823160e01b82523060048301525afa94851561302357505f94613b00575b5093613ae184878c95856117789f9b9899613aef9b976fffffffffffffffffffffffffffffffff9e9b9511613af6575b9084613ad792615500565b809b8601526133d1565b613ae9613512565b93614e5a565b1691614eee565b9093508390613acc565b95919a809794508681999692993d8311613b3c575b613b1f8183610bde565b810103126102135794519599939692959094939092613ae1613a9c565b503d613b15565b9192917f8d68a1560000000000000000000000000000000000000000000000000000000081036140935750820160808382031261021357613b8383610af9565b9060408401359067ffffffffffffffff821161021357613ba4918501611534565b9160246020845181860151907fffffffffffffffffffffffffffffffffffffffff00000000000000000000000091828116916014811061407e575b50509050604051928380926370a0823160e01b825230600483015260601c5afa908115610901575f9161404a575b50613c20612710916020870135906149e2565b049360405193613c2f85610b76565b6028855260403660208701379430937f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211611b7e5795905b815190602c8210611b0457866014840151601585015197601886015190602c87015194838690879c6001600160a01b0389166001600160a01b038816101561403f575b60ff1680613f2857506001600160a01b0391613d2791731f98431c8ad98523631ae4a59f267346ea31f9847fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549263fa461e339862ffffff16906040519387165f528616602052806040521560051b6060035f20916040526137e1565b1691855190858760280152866014015285528c602c88115f14613eb15750611a646001600160a01b0393878594611a5f613db195611a516040519b8c9586938d8c8084169116105f14611bc4577f128acb080000000000000000000000000000000000000000000000000000000060208601526401000276a4918c168c8f16103060248701614a14565b9590946040525b1691161015613eaa57505b7f80000000000000000000000000000000000000000000000000000000000000008114611b90575f03945f8612611b7e57602c86921115613e425750503093906018815110611b045780517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe80160189091019081526028865290613c68565b939650935050925060608301358210613e5d57505050600190565b6040517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526060929092013560248301526044820152606490fd5b9050613dc3565b926001600160a01b03613f2093611a5f89611a51849b9a8a611a6498879b888616898416105f14611c5a57886401000276a493816040519b8c997f128acb080000000000000000000000000000000000000000000000000000000060208c015216911610911660248701614a14565b949093613db8565b60018103613f8057506001600160a01b0391613d27917341ff9aa7e16b8b1a8a8dc4f0efacd93d02d071c97f6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2926323a69e759861199c565b60028103613fd857506001600160a01b0391613d279173baceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f7fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b549263fa461e339861199c565b9091929394959650600381145f14611d8d5750613d278d96959493926001600160a01b03927370fe4a44ea505cfa3a57b95cf2862d4fd5f0f6877fe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf92633a1c453c9861199c565b869250889150613cab565b90506020813d602011614076575b8161406560209383610bde565b810103126102135751613c20613c0d565b3d9150614058565b8391925060140360031b1b1616805f80613bdf565b92837f103b48be00000000000000000000000000000000000000000000000000000000829495145f146143f3575060c09181010312610213576140d581610af9565b6020916140e3838201610af9565b9160409182810135906140f860608201610af9565b9060a061410760808301613800565b910135926001600160a01b03808098169316926001908180851614935f9284614380575b83945089519361434a575b630902f1ac5f52895f6004601c8a5afa1561434157893d10610213578b8b928760051b9687519288811851948084811c16148215176142f4575b506060955061ffff6127109260081c1682030292028201910204975f601c8d8187019763022c0d9f88526080808901528360a08901528c82828a0101526004011886010152169101525f8060a48382875af11561218957508284106141db5750505050505050600190565b600491879115614290578551928380927fd21220a70000000000000000000000000000000000000000000000000000000082525afa90811561100c576108829495965f92614273575b5050935b519485947f97a6f3b900000000000000000000000000000000000000000000000000000000865216600485016040919493926001600160a01b03606083019616825260208201520152565b6142899250803d106124bc576124ad8183610bde565b8680614224565b8551928380927f0dfe16810000000000000000000000000000000000000000000000000000000082525afa90811561100c576108829495965f926142d7575b505093614228565b6142ed9250803d106124bc576124ad8183610bde565b86806142cf565b9294505091936024601c5f926370a0823184528b85525afa15614341578b3d10610213575f51838110614330579183916060948d94038e614170565b60118d634e487b715f52526024601cfd5b833d5f823e3d90fd5b63a9059cbb8452868c850152848a8501528b5f6044601c870182875af11561434157805f51148c3d1015163d1517614136575f80fd5b9250928851906370a0823160e01b82523060048301528b82602481865afa80156143e9575f906143ba575b6127109250020491839061412b565b508b82813d83116143e2575b6143d08183610bde565b810103126102135761271091516143ab565b503d6143c6565b8a513d5f823e3d90fd5b7f38c9c14700000000000000000000000000000000000000000000000000000000810361447c5750019060a0818303126102135761443081610af9565b9061443d60408201610af9565b90608081013567ffffffffffffffff81116102135761177894614461918301611534565b9260206001600160a01b036060840135941692013590615034565b7ff5b99189000000000000000000000000000000000000000000000000000000008103614856575060a09181010312610213576144b881610af9565b906040810135916001600160a01b0392838116809103610213576144de60608401613800565b6040517f392f37e9000000000000000000000000000000000000000000000000000000008152936001808316149160e086600481875afa908115610901575f91885f985f935f945f9b5f935f966147db575b50878197839781969f6145429061347f565b8c156147c6575b50505050505f91602088013561474c575b8983158d858215938461473b575b5050509061472d575b6146bc575b6145be93508686670de0b6b3a76400008099818099020493020495869461271061ffff838089800204818880020401818a89020402049660081c1682020490030204016153c1565b90030204946080820135861061466d57505015614667575f925b6040516145e481610bc2565b5f8152823b15610213575f946146438692604051988997889687957f022c0d9f00000000000000000000000000000000000000000000000000000000875260048701526024860152166044840152608060648401526084830190611dd2565b03925af1801561090157614658575b50600190565b61466190610bae565b5f614652565b5f6145d8565b6040517f97a6f3b90000000000000000000000000000000000000000000000000000000081526001600160a01b0391909116600482015260809190910135602482015260448101859052606490fd5b915060208b60248b60405196879384926370a0823160e01b84526004840152165afa80156109015784905f906146f7575b8d94500391614576565b50506020833d602011614725575b8161471260209383610bde565b8101031261021357836145be93516146ed565b3d9150614705565b5060018083811c1614614571565b614744926133d1565b8d858d614568565b915060208b6024604051809681936370a0823160e01b8352306004840152165afa8015610901578c935f9161478e575b5061271090602089013502049161455a565b9350506020833d6020116147be575b816147aa60209383610bde565b81010312610213576127108c93519061477c565b3d915061479d565b9e509198509650945091505f80808080614549565b9c50505094505050505060e0863d60e01161484e575b816147fe60e09383610bde565b81010312610213578580519188602083015193604084015192606085015161484060c061483960a061483260808b016149c7565b9901611e57565b9d01611e57565b92969490959b92945f614530565b3d91506147f1565b7fc876d21d00000000000000000000000000000000000000000000000000000000141590506133cb5781606091810103126102135761489481610af9565b60406148a260208401610af9565b920135906001600160a01b038091169083169273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee84145f146148fa5750479250908083116148e7575b505050600190565b6148f292039061343f565b5f80806148df565b916020602494604051958680926370a0823160e01b82523060048301525afa938415610901575f9461494c575b508084116149385750505050600190565b6149439303916133d1565b5f808080612417565b9093506020813d602011614978575b8161496860209383610bde565b810103126102135751925f614927565b3d915061495b565b61154f9392606092825260208201528160408201520190611dd2565b51906fffffffffffffffffffffffffffffffff8216820361021357565b51908160070b820361021357565b5190811515820361021357565b519060ff8216820361021357565b81810292918115918404141715611b9057565b9081602091031261021357516001600160a01b03811681036102135790565b919360a09361154f96956001600160a01b0380941685521515602085015260408401521660608201528160808201520190611dd2565b9190917f1643bf8e9fdaef48c4abf5a998de359be44a235ac7aebfbc05485e093720deaa5f815c915d8015610a7b57614bb6937f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c9060405193614aad85610b92565b605b8552614bb1604660208701967f536c697070616765416e64416374696f6e73286164647265737320726563697088527f69656e742c6164647265737320627579546f6b656e2c75696e74323536206d6960408201527f6e416d6f756e744f75742c62797465735b5d20616374696f6e7329000000000060608201526020614b346134b3565b604051998a937f536c697070616765416e64416374696f6e7320736c697070616765416e644163848601527f74696f6e7329000000000000000000000000000000000000000000000000000060408601525180918686015e8301908482015f8152815193849201905e015f83820152036026810188520186610bde565b614e5a565b565b9291907f1643bf8e9fdaef48c4abf5a998de359be44a235ac7aebfbc05485e093720deaa935f855c955d8415610a7b577f46bacb9b87ba1d2910347e4a3e052d06c824a45acd1e9517bb0cb8d0d5cde8935c7f74696f6e73290000000000000000000000000000000000000000000000000000604095614d1860468860208151614c4181610b92565b605b81528181017f536c697070616765416e64416374696f6e73286164647265737320726563697081527f69656e742c6164647265737320627579546f6b656e2c75696e74323536206d69848301527f6e416d6f756e744f75742c62797465735b5d20616374696f6e732900000000006060830152614cbe6134b3565b9184519889957f536c697070616765416e64416374696f6e7320736c697070616765416e644163868801528601525180918686015e8301908482015f8152815193849201905e015f83820152036026810185520183610bde565b614e31576e22d473030f116ddee9f6b43ac78ba392833b1561021357614e155f96614de48894614dc59b6001600160a01b038c9889519e8f9c8d9b8c9a7f137c29fe000000000000000000000000000000000000000000000000000000008c52614d9960048d018251602080916001600160a01b0381511684520151910152565b60208181015160448e015291015160648c015281516001600160a01b031660848c0152015160a48a0152565b1660c487015260e4860152610140610104860152610144850190611dd2565b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc84830301610124850152611dd2565b03925af19081156130235750614e285750565b614bb690610bae565b600486517f1c500e5c000000000000000000000000000000000000000000000000000000008152fd5b91909294936e22d473030f116ddee9f6b43ac78ba392833b1561021357614edd5f96614de48894614dc59a6001600160a01b0360409889519d8e9c8d9b8c9a7f137c29fe000000000000000000000000000000000000000000000000000000008c52614d9960048d018251602080916001600160a01b0381511684520151910152565b03925af1801561090157614e285750565b9190917f49fa719b76f0f6b7e76be94b56c26671a548e1c712d5b13dc2874f70a75982765f526020526040519160405260605f20916040526010525f5260305fa0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828209828202918280831092039180830391612710958691099282861115611b7e5714614fae577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919350828211900360fc1b910360041c170290565b50500490565b3d15614fde573d90614fc582610c5b565b91614fd36040519384610bde565b82523d5f602084013e565b606090565b8015614ffd576ec097ce7bc90715b34b9f10000000000490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b8115614ffd570490565b9291906001600160a01b03808316946e22d473030f116ddee9f6b43ac78ba38614610a7b575f91811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee810361515c575050506150859047614f31565b938051155f146150e05750506150b6575f80809381935af16150a5614fb4565b90156150ae5750565b602081519101fd5b60046040517f01da1572000000000000000000000000000000000000000000000000000000008152fd5b90939260208301808411611b9057825110611b0457835f9460208695850101525b602083519301915af1615112614fb4565b90156150ae5751159081615152575b5061512857565b60046040517f82d5d76a000000000000000000000000000000000000000000000000000000008152fd5b90503b155f615121565b9091949281979497155f1461517b575050506150b6575f928392615101565b604096959496939293516370a0823160e01b81523060048201526020918282602481875afa8015610901575f9061520b575b6151b79250614f31565b92818101808211611b90578851106151fa57865f9896949293838a9997958c948a010152036151e9575b505050615101565b6151f29261523a565b5f80876151e1565b603282634e487b715f52526024601cfd5b508282813d8311615233575b6152218183610bde565b81010312610213576151b791516151ad565b503d615217565b916001600160a01b039182916040519384927fdd62ed3e0000000000000000000000000000000000000000000000000000000084523060048501521692836024840152826044602096879389165afa918215610901575f92615392575b5081106152a5575b50505050565b615333575b60445f91826040519586927f095ea7b300000000000000000000000000000000000000000000000000000000845260048401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248401525af11561218957503d15601f3d1160015f5114161715615326575f80808061529f565b633e3f8f735f526004601cfd5b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081528160048201525f6024820152825f60448382885af11561218957503d15601f3d1160015f511416176152aa57633e3f8f735f526004601cfd5b9091508381813d83116153ba575b6153aa8183610bde565b810103126102135751905f615297565b503d6153a0565b929091670de0b6b3a7640000918285800204948381870204955f935b60ff851061540f5760046040517f481b61af000000000000000000000000000000000000000000000000000000008152fd5b85818002048789886003878286890181898402040204958587105f146154915702020401888383030204918215615450575b505060019101945b01936153dd565b14905061548657600180820188888083800204860181848902040204116154795750875f615441565b9750505050509350505090565b955050509350505090565b020204018882840302049182156154af575b50506001910394615449565b14905080156154c6575b615486576001875f6154a3565b5086867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018180828002048601918702040204106154b9565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82840981838502938480841093039509908085146155875782805f0316809304600280826003021880830282030280830282030280830282030280830282030280830282030280920290030294600184805f0304019185841191030302920304170290565b505091500490565b906155be9061559e8151614fe3565b90670de0b6b3a76400006080820194602086519301519302049080615608565b90510390565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090358181169392601481106155f957505050565b60140360031b82901b16169150565b90919392670de0b6b3a7640000918281830204029482615628858861502a565b92810394850204910190818110155f14615697570381600191955b8460021b02048580020194600186811c019186925b838110615681575061154f9596505f146156795701915b60011b91026156a2565b90039161566f565b92508261568e818961502a565b0160011c615658565b9003815f9195615643565b6156ac828261502a565b9182021461154f576001019056
Verified Source Code Partial Match
Compiler: v0.8.25+commit.b61c2a91
EVM: cancun
Optimization: Yes (10000 runs)
MainnetFlat.sol 3793 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 >=0.8.25 ^0.8.17 ^0.8.25;
// 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);
}
// lib/permit2/src/interfaces/IEIP712.sol
interface IEIP712 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// 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/IERC721Owner.sol
interface IERC721Owner {
function ownerOf(uint256) external view returns (address);
}
// src/allowanceholder/IAllowanceHolder.sol
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);
}
// 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/core/univ3forks/SolidlyV3.sol
address constant solidlyV3Factory = 0x70Fe4a44EA505cFa3A57b95cF2862D4fd5F0f687;
bytes32 constant solidlyV3InitHash = 0xe9b68c5f77858eecac2e651646e208175e9b1359d68d0e14fc69f8c54e5010bf;
uint8 constant solidlyV3ForkId = 3;
interface ISolidlyV3Callback {
function solidlyV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}
// 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;
//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;
bytes32 constant uniswapV3InitHash = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
uint8 constant uniswapV3ForkId = 0;
interface IUniswapV3Callback {
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}
// 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/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/utils/UnsafeMath.sol
library UnsafeMath {
function unsafeInc(uint256 x) internal pure returns (uint256) {
unchecked {
return x + 1;
}
}
function unsafeInc(int256 x) internal pure returns (int256) {
unchecked {
return x + 1;
}
}
function unsafeNeg(int256 x) internal pure returns (int256) {
unchecked {
return -x;
}
}
function unsafeDiv(uint256 numerator, uint256 denominator) internal pure returns (uint256 quotient) {
assembly ("memory-safe") {
quotient := div(numerator, denominator)
}
}
function unsafeDiv(int256 numerator, int256 denominator) internal pure returns (int256 quotient) {
assembly ("memory-safe") {
quotient := sdiv(numerator, denominator)
}
}
function unsafeMod(uint256 numerator, uint256 denominator) internal pure returns (uint256 remainder) {
assembly ("memory-safe") {
remainder := mod(numerator, denominator)
}
}
function unsafeMod(int256 numerator, int256 denominator) internal pure returns (int256 remainder) {
assembly ("memory-safe") {
remainder := smod(numerator, denominator)
}
}
function unsafeMulMod(uint256 a, uint256 b, uint256 m) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := mulmod(a, b, m)
}
}
function unsafeAddMod(uint256 a, uint256 b, uint256 m) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := addmod(a, b, m)
}
}
}
// 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/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();
/// @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);
/// @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);
/// @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);
/// @notice Thrown when an AllowanceHolder transfer's permit is past its deadline
error SignatureExpired(uint256 deadline);
/// @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();
// src/vendor/SafeTransferLib.sol
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @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 {
uint32 private constant _TRANSFER_FROM_FAILED_SELECTOR = 0x7939f424; // bytes4(keccak256("TransferFromFailed()"))
uint32 private constant _TRANSFER_FAILED_SELECTOR = 0x90b8ec18; // bytes4(keccak256("TransferFailed()"))
uint32 private constant _APPROVE_FAILED_SELECTOR = 0x3e3f8f73; // bytes4(keccak256("ApproveFailed()"))
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address payable to, uint256 amount) internal {
assembly ("memory-safe") {
// Transfer the ETH and store if it succeeded or not.
if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
let freeMemoryPointer := mload(0x40)
returndatacopy(freeMemoryPointer, 0, returndatasize())
revert(freeMemoryPointer, returndatasize())
}
}
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal {
assembly ("memory-safe") {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)) {
returndatacopy(freeMemoryPointer, 0, returndatasize())
revert(freeMemoryPointer, returndatasize())
}
// We check that the call either returned exactly 1 (can't just be non-zero data), or had no
// return data.
if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
mstore(0, _TRANSFER_FROM_FAILED_SELECTOR)
revert(0x1c, 0x04)
}
}
}
function safeTransfer(IERC20 token, address to, uint256 amount) internal {
assembly ("memory-safe") {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) {
returndatacopy(freeMemoryPointer, 0, returndatasize())
revert(freeMemoryPointer, returndatasize())
}
// We check that the call either returned exactly 1 (can't just be non-zero data), or had no
// return data.
if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
mstore(0, _TRANSFER_FAILED_SELECTOR)
revert(0x1c, 0x04)
}
}
}
function safeApprove(IERC20 token, address to, uint256 amount) internal {
assembly ("memory-safe") {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) {
returndatacopy(freeMemoryPointer, 0, returndatasize())
revert(freeMemoryPointer, returndatasize())
}
// We check that the call either returned exactly 1 (can't just be non-zero data), or had no
// return data.
if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) {
mstore(0, _APPROVE_FAILED_SELECTOR)
revert(0x1c, 0x04)
}
}
}
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/ISettlerActions.sol
interface ISettlerActions {
/// @dev Transfer funds from msg.sender Permit2.
function TRANSFER_FROM(address recipient, ISignatureTransfer.PermitTransferFrom memory permit, bytes memory sig)
external;
/// @dev Transfer funds from metatransaction requestor into the Settler contract using Permit2. Only for use in `Settler.executeMetaTxn` where the signature is provided as calldata
function METATXN_TRANSFER_FROM(address recipient, ISignatureTransfer.PermitTransferFrom memory permit) external;
/// @dev Settle an RfqOrder between maker and taker transfering funds directly between the parties
// Post-req: Payout if recipient != taker
function RFQ_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory makerPermit,
address maker,
bytes memory makerSig,
ISignatureTransfer.PermitTransferFrom memory takerPermit,
bytes memory takerSig
) external;
/// @dev Settle an RfqOrder between maker and taker transfering funds directly between the parties for the entire amount
function METATXN_RFQ_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory makerPermit,
address maker,
bytes memory makerSig,
ISignatureTransfer.PermitTransferFrom memory takerPermit
) external;
/// @dev Settle an RfqOrder between Maker and Settler. Transfering funds from the Settler contract to maker.
/// Retaining funds in the settler contract.
// Pre-req: Funded
// Post-req: Payout
function RFQ(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
address maker,
bytes memory makerSig,
address takerToken,
uint256 maxTakerAmount
) external;
/// @dev Trades against UniswapV3 using the contracts balance for funding
// Pre-req: Funded
// Post-req: Payout
function UNISWAPV3(address recipient, uint256 bps, bytes memory path, uint256 amountOutMin) external;
/// @dev Trades against UniswapV3 using user funds via Permit2 for funding
function UNISWAPV3_VIP(
address recipient,
bytes memory path,
ISignatureTransfer.PermitTransferFrom memory permit,
bytes memory sig,
uint256 amountOutMin
) external;
function MAKERPSM(address recipient, address gemToken, uint256 bps, address psm, bool buyGem, uint256 amountOutMin)
external;
function CURVE_TRICRYPTO_VIP(
address recipient,
uint80 poolInfo,
ISignatureTransfer.PermitTransferFrom memory permit,
bytes memory sig,
uint256 minBuyAmount
) external;
function METATXN_CURVE_TRICRYPTO_VIP(
address recipient,
uint80 poolInfo,
ISignatureTransfer.PermitTransferFrom memory permit,
uint256 minBuyAmount
) external;
function DODOV1(address sellToken, uint256 bps, address pool, bool quoteForBase, uint256 minBuyAmount) external;
function DODOV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
bool quoteForBase,
uint256 minBuyAmount
) external;
function VELODROME(address recipient, uint256 bps, address pool, uint24 swapInfo, uint256 minBuyAmount) external;
/// @dev Trades against UniswapV3 using user funds via Permit2 for funding. Metatransaction variant. Signature is over all actions.
function METATXN_UNISWAPV3_VIP(
address recipient,
bytes memory path,
ISignatureTransfer.PermitTransferFrom memory permit,
uint256 amountOutMin
) external;
/// @dev Trades against MaverickV2 using the contracts balance for funding
/// This action does not use the MaverickV2 callback, so it takes an arbitrary pool address to make calls against.
/// Passing `tokenAIn` as a parameter actually saves gas relative to introspecting the pool's `tokenA()` accessor.
function MAVERICKV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
bool tokenAIn,
uint256 minBuyAmount
) external;
/// @dev Trades against MaverickV2, spending the taker's coupon inside the callback
/// This action requires the use of the MaverickV2 callback, so we take the MaverickV2 CREATE2 salt as an argument to derive the pool address from the trusted factory and inithash.
/// @param salt is formed as `keccak256(abi.encode(feeAIn, feeBIn, tickSpacing, lookback, tokenA, tokenB, kinds, address(0)))`
function MAVERICKV2_VIP(
address recipient,
bytes32 salt,
bool tokenAIn,
ISignatureTransfer.PermitTransferFrom memory permit,
bytes memory sig,
uint256 minBuyAmount
) external;
/// @dev Trades against MaverickV2, spending the taker's coupon inside the callback; metatransaction variant
function METATXN_MAVERICKV2_VIP(
address recipient,
bytes32 salt,
bool tokenAIn,
ISignatureTransfer.PermitTransferFrom memory permit,
uint256 minBuyAmount
) external;
/// @dev Trades against UniswapV2 using the contracts balance for funding
/// @param swapInfo is encoded as the upper 16 bits as the fee of the pool in bps, the second
/// lowest bit as "sell token has transfer fee", and the lowest bit as the
/// "token0 for token1" flag.
function UNISWAPV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
uint24 swapInfo,
uint256 amountOutMin
) external;
function POSITIVE_SLIPPAGE(address recipient, address token, uint256 expectedAmount) external;
/// @dev Trades against a basic AMM which follows the approval, transferFrom(msg.sender) interaction
// Pre-req: Funded
// Post-req: Payout
function BASIC(address sellToken, uint256 bps, address pool, uint256 offset, bytes calldata data) external;
}
// src/allowanceholder/AllowanceHolderContext.sol
abstract contract AllowanceHolderContext is Context {
IAllowanceHolder internal constant _ALLOWANCE_HOLDER = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734);
function _isForwarded() internal view virtual override returns (bool) {
return super._isForwarded() || super._msgSender() == address(_ALLOWANCE_HOLDER);
}
function _msgSender() internal view virtual override returns (address sender) {
sender = super._msgSender();
if (sender == address(_ALLOWANCE_HOLDER)) {
// ERC-2771 like usage where the _trusted_ `AllowanceHolder` has appended the appropriate
// msg.sender to the msg data
assembly ("memory-safe") {
sender := shr(0x60, calldataload(sub(calldatasize(), 0x14)))
}
}
}
// this is here to avoid foot-guns and make it very explicit that we intend
// to pass the confused deputy check in AllowanceHolder
function balanceOf(address) external pure {
assembly ("memory-safe") {
mstore8(0x00, 0x00)
return(0x00, 0x01)
}
}
}
// src/utils/AddressDerivation.sol
library AddressDerivation {
using UnsafeMath for uint256;
uint256 internal constant _SECP256K1_P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
uint256 internal constant _SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
uint256 internal constant SECP256K1_GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;
uint256 internal constant SECP256K1_GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;
error InvalidCurve(uint256 x, uint256 y);
// keccak256(abi.encodePacked(ECMUL([x, y], k)))[12:]
function deriveEOA(uint256 x, uint256 y, uint256 k) internal pure returns (address) {
if (k == 0) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
if (k >= _SECP256K1_N || x >= _SECP256K1_P || y >= _SECP256K1_P) {
Panic.panic(Panic.ARITHMETIC_OVERFLOW);
}
// +/-7 are neither square nor cube mod p, so we only have to check one
// coordinate against 0. if it is 0, then the other is too (the point at
// infinity) or the point is invalid
if (
x == 0
|| y.unsafeMulMod(y, _SECP256K1_P)
!= x.unsafeMulMod(x, _SECP256K1_P).unsafeMulMod(x, _SECP256K1_P).unsafeAddMod(7, _SECP256K1_P)
) {
revert InvalidCurve(x, y);
}
unchecked {
// https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384
return ecrecover(
bytes32(0), uint8(27 + (y & 1)), bytes32(x), bytes32(UnsafeMath.unsafeMulMod(x, k, _SECP256K1_N))
);
}
}
// keccak256(RLP([deployer, nonce]))[12:]
function deriveContract(address deployer, uint64 nonce) internal pure returns (address result) {
if (nonce == 0) {
assembly ("memory-safe") {
mstore(
0x00,
or(
0xd694000000000000000000000000000000000000000080,
shl(8, and(0xffffffffffffffffffffffffffffffffffffffff, deployer))
)
)
result := keccak256(0x09, 0x17)
}
} else if (nonce < 0x80) {
assembly ("memory-safe") {
// we don't care about dirty bits in `deployer`; they'll be overwritten later
mstore(0x14, deployer)
mstore(0x00, 0xd694)
mstore8(0x34, nonce)
result := keccak256(0x1e, 0x17)
}
} else {
// compute ceil(log_256(nonce)) + 1
uint256 nonceLength = 8;
unchecked {
if ((uint256(nonce) >> 32) != 0) {
nonceLength += 32;
if (nonce == type(uint64).max) {
Panic.panic(Panic.ARITHMETIC_OVERFLOW);
}
}
if ((uint256(nonce) >> 8) >= (1 << nonceLength)) {
nonceLength += 16;
}
if (uint256(nonce) >= (1 << nonceLength)) {
nonceLength += 8;
}
// ceil
if ((uint256(nonce) << 8) >= (1 << nonceLength)) {
nonceLength += 8;
}
// bytes, not bits
nonceLength >>= 3;
}
assembly ("memory-safe") {
// we don't care about dirty bits in `deployer` or `nonce`. they'll be overwritten later
mstore(nonceLength, nonce)
mstore8(0x20, add(0x7f, nonceLength))
mstore(0x00, deployer)
mstore8(0x0a, add(0xd5, nonceLength))
mstore8(0x0b, 0x94)
result := keccak256(0x0a, add(0x16, nonceLength))
}
}
}
// keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initHash))[12:]
function deriveDeterministicContract(address deployer, bytes32 salt, bytes32 initHash)
internal
pure
returns (address result)
{
assembly ("memory-safe") {
let ptr := mload(0x40)
// we don't care about dirty bits in `deployer`; they'll be overwritten later
mstore(ptr, deployer)
mstore8(add(ptr, 0x0b), 0xff)
mstore(add(ptr, 0x20), salt)
mstore(add(ptr, 0x40), initHash)
result := keccak256(add(ptr, 0x0b), 0x55)
}
}
}
// src/vendor/FullMath.sol
/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
/// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
library FullMath {
using UnsafeMath for uint256;
/// @notice 512-bit multiply [prod1 prod0] = a * b
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return prod0 Least significant 256 bits of the product
/// @return prod1 Most significant 256 bits of the product
/// @return remainder Remainder of full-precision division
function _mulDivSetup(uint256 a, uint256 b, uint256 denominator)
private
pure
returns (uint256 prod0, uint256 prod1, uint256 remainder)
{
// Compute the product mod 2**256 and mod 2**256 - 1 then use the Chinese
// Remainder Theorem to reconstruct the 512 bit result. The result is stored
// in two 256 variables such that product = prod1 * 2**256 + prod0
assembly ("memory-safe") {
// Full-precision multiplication
{
let mm := mulmod(a, b, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
prod0 := mul(a, b)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
remainder := mulmod(a, b, denominator)
}
}
/// @notice 512-bit by 256-bit division.
/// @param prod0 Least significant 256 bits of the product
/// @param prod1 Most significant 256 bits of the product
/// @param denominator The divisor
/// @param remainder Remainder of full-precision division
/// @return The 256-bit result
/// @dev Overflow and division by zero aren't checked and are GIGO errors
function _mulDivInvert(uint256 prod0, uint256 prod1, uint256 denominator, uint256 remainder)
private
pure
returns (uint256)
{
uint256 inv;
assembly ("memory-safe") {
// Make division exact by rounding [prod1 prod0] down to a multiple of
// denominator
// Subtract 256 bit number from 512 bit number
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
// Factor powers of two out of denominator
{
// Compute largest power of two divisor of denominator.
// Always >= 1.
let twos := and(sub(0, denominator), denominator)
// Divide denominator by power of two
denominator := div(denominator, twos)
// Divide [prod1 prod0] by the factors of two
prod0 := div(prod0, twos)
// Shift in bits from prod1 into prod0. For this we need to flip `twos`
// such that it is 2**256 / twos.
// If twos is zero, then it becomes one
twos := add(div(sub(0, twos), twos), 1)
prod0 := or(prod0, mul(prod1, twos))
}
// Invert denominator mod 2**256
// Now that denominator is an odd number, it has an inverse modulo 2**256
// such that denominator * inv = 1 mod 2**256.
// Compute the inverse by starting with a seed that is correct correct for
// four bits. That is, denominator * inv = 1 mod 2**4
inv := xor(mul(3, denominator), 2)
// Now use Newton-Raphson iteration to improve the precision.
// Thanks to Hensel's lifting lemma, this also works in modular
// arithmetic, doubling the correct bits in each step.
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**8
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**16
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**32
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**64
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**128
inv := mul(inv, sub(2, mul(denominator, inv))) // inverse mod 2**256
}
// Because the division is now exact we can divide by multiplying with the
// modular inverse of denominator. This will give us the correct result
// modulo 2**256. Since the precoditions guarantee that the outcome is less
// than 2**256, this is the final result. We don't need to compute the high
// bits of the result and prod1 is no longer required.
unchecked {
return prod0 * inv;
}
}
/// @notice Calculates a×b÷denominator with full precision then rounds towards 0. Throws if result overflows a uint256 or denominator == 0
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return The 256-bit result
function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256) {
(uint256 prod0, uint256 prod1, uint256 remainder) = _mulDivSetup(a, b, denominator);
// Make sure the result is less than 2**256.
// Also prevents denominator == 0
if (denominator <= prod1) {
Panic.panic(denominator == 0 ? Panic.DIVISION_BY_ZERO : Panic.ARITHMETIC_OVERFLOW);
}
// Handle non-overflow cases, 256 by 256 division
if (prod1 == 0) {
return prod0.unsafeDiv(denominator);
}
return _mulDivInvert(prod0, prod1, denominator, remainder);
}
/// @notice Calculates a×b÷denominator with full precision then rounds towards 0. Overflowing a uint256 or denominator == 0 are GIGO errors
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return The 256-bit result
function unsafeMulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256) {
(uint256 prod0, uint256 prod1, uint256 remainder) = _mulDivSetup(a, b, denominator);
// Overflow and zero-division checks are skipped
// Handle non-overflow cases, 256 by 256 division
if (prod1 == 0) {
return prod0.unsafeDiv(denominator);
}
return _mulDivInvert(prod0, prod1, denominator, remainder);
}
}
// src/core/Permit2PaymentAbstract.sol
abstract contract Permit2PaymentAbstract is AbstractContext {
string internal constant TOKEN_PERMISSIONS_TYPE = "TokenPermissions(address token,uint256 amount)";
function _isRestrictedTarget(address) internal view virtual returns (bool);
function _operator() internal view virtual returns (address);
function _permitToSellAmount(ISignatureTransfer.PermitTransferFrom memory permit)
internal
view
virtual
returns (uint256 sellAmount);
function _permitToTransferDetails(ISignatureTransfer.PermitTransferFrom memory permit, address recipient)
internal
view
virtual
returns (ISignatureTransfer.SignatureTransferDetails memory transferDetails, uint256 sellAmount);
function _transferFromIKnowWhatImDoing(
ISignatureTransfer.PermitTransferFrom memory permit,
ISignatureTransfer.SignatureTransferDetails memory transferDetails,
address from,
bytes32 witness,
string memory witnessTypeString,
bytes memory sig,
bool isForwarded
) internal virtual;
function _transferFromIKnowWhatImDoing(
ISignatureTransfer.PermitTransferFrom memory permit,
ISignatureTransfer.SignatureTransferDetails memory transferDetails,
address from,
bytes32 witness,
string memory witnessTypeString,
bytes memory sig
) internal virtual;
function _transferFrom(
ISignatureTransfer.PermitTransferFrom memory permit,
ISignatureTransfer.SignatureTransferDetails memory transferDetails,
bytes memory sig,
bool isForwarded
) internal virtual;
function _transferFrom(
ISignatureTransfer.PermitTransferFrom memory permit,
ISignatureTransfer.SignatureTransferDetails memory transferDetails,
bytes memory sig
) internal virtual;
function _setOperatorAndCall(
address target,
bytes memory data,
uint32 selector,
function (bytes calldata) internal returns (bytes memory) callback
) internal virtual returns (bytes memory);
modifier metaTx(address msgSender, bytes32 witness) virtual;
modifier takerSubmitted() virtual;
function _allowanceHolderTransferFrom(address token, address owner, address recipient, uint256 amount)
internal
virtual;
}
// src/SettlerAbstract.sol
abstract contract SettlerAbstract is Permit2PaymentAbstract {
// Permit2 Witness for meta transactions
string internal constant SLIPPAGE_AND_ACTIONS_TYPE =
"SlippageAndActions(address recipient,address buyToken,uint256 minAmountOut,bytes[] actions)";
bytes32 internal constant SLIPPAGE_AND_ACTIONS_TYPEHASH =
0x615e8d716cef7295e75dd3f1f10d679914ad6d7759e8e9459f0109ef75241701;
uint256 internal constant BASIS = 10_000;
constructor() {
assert(SLIPPAGE_AND_ACTIONS_TYPEHASH == keccak256(bytes(SLIPPAGE_AND_ACTIONS_TYPE)));
}
function _hasMetaTxn() internal pure virtual returns (bool);
function _dispatch(uint256 i, bytes4 action, bytes calldata data) internal virtual returns (bool);
}
// src/core/MakerPSM.sol
interface IPSM {
/// @dev Get the fee for selling DAI to USDC in PSM
/// @return tout toll out [wad]
function tout() external view returns (uint256);
/// @dev Get the address of the underlying vault powering PSM
/// @return address of gemJoin contract
function gemJoin() external view returns (address);
/// @dev Sell USDC for DAI
/// @param usr The address of the account trading USDC for DAI.
/// @param gemAmt The amount of USDC to sell in USDC base units
function sellGem(address usr, uint256 gemAmt) external;
/// @dev Buy USDC for DAI
/// @param usr The address of the account trading DAI for USDC
/// @param gemAmt The amount of USDC to buy in USDC base units
function buyGem(address usr, uint256 gemAmt) external;
}
// Maker units https://github.com/makerdao/dss/blob/master/DEVELOPING.md
// wad: fixed point decimal with 18 decimals (for basic quantities, e.g. balances)
uint256 constant WAD = 10 ** 18;
IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
abstract contract MakerPSM is SettlerAbstract {
using UnsafeMath for uint256;
using SafeTransferLib for IERC20;
constructor() {
assert(block.chainid == 1 || block.chainid == 31337);
}
function sellToMakerPsm(
address recipient,
IERC20 gemToken,
uint256 bps,
IPSM psm,
bool buyGem,
uint256 amountOutMin
) internal {
if (buyGem) {
// phantom overflow can't happen here because DAI has decimals ...
// [truncated — 156545 bytes total]
Write Contract 1 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
Token Balances (2)
View Transfers →Recent Transactions
No transactions found for this address