Forkchoice Ethereum Mainnet

Address Contract Verified

Address 0xcEa577BA70168CA36033Da64734C0E321ba844d0
Balance 0 ETH
Nonce 1
Code Size 19375 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

19375 bytes
0x60806040526004361061013f575f3560e01c806385f8c259116100b3578063b6f9de951161006d578063b6f9de95146103ff578063c45a015514610412578063d06ca61f14610445578063e8e3370014610464578063f305d7191461049e578063fb3bdb41146104b1575f5ffd5b806385f8c2591461030b5780638803dbee1461032a578063ad5c464814610349578063ad615dec14610394578063b059a3e6146103b3578063b6664d5c146103e0575f5ffd5b80634a25d94a116101045780634a25d94a146102515780635c11d7951461027057806378fcb3271461028f578063791ac947146102ae5780637ecebe00146102cd5780637ff36ab5146102f8575f5ffd5b8063054d50d41461018257806318cbafe5146101b45780631f00ca74146101e057806330adf81f146101ff57806338ed173914610232575f5ffd5b3661017e57336001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2161461017c5761017c6131bd565b005b5f5ffd5b34801561018d575f5ffd5b506101a161019c3660046131d1565b6104c4565b6040519081526020015b60405180910390f35b3480156101bf575f5ffd5b506101d36101ce366004613261565b61058e565b6040516101ab91906132ce565b3480156101eb575f5ffd5b506101d36101fa366004613354565b6108f4565b34801561020a575f5ffd5b506101a17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b34801561023d575f5ffd5b506101d361024c366004613261565b610a55565b34801561025c575f5ffd5b506101d361026b366004613261565b610b4f565b34801561027b575f5ffd5b5061017c61028a366004613261565b610c6a565b34801561029a575f5ffd5b506101d36102a9366004613261565b610f41565b3480156102b9575f5ffd5b5061017c6102c8366004613261565b610f7e565b3480156102d8575f5ffd5b506101a16102e7366004613412565b5f6020819052908152604090205481565b6101d3610306366004613434565b61119b565b348015610316575f5ffd5b506101a16103253660046131d1565b61152a565b348015610335575f5ffd5b506101d3610344366004613261565b6115c5565b348015610354575f5ffd5b5061037c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b0390911681526020016101ab565b34801561039f575f5ffd5b506101a16103ae3660046131d1565b61165f565b3480156103be575f5ffd5b506103d26103cd366004613500565b6116f6565b6040516101ab9291906135a8565b3480156103eb575f5ffd5b5061037c6103fa3660046135c2565b6117e8565b61017c61040d366004613434565b611826565b34801561041d575f5ffd5b5061037c7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b348015610450575f5ffd5b506101d361045f366004613354565b611bf3565b34801561046f575f5ffd5b5061048361047e36600461364d565b611d28565b604080519384526020840192909252908201526060016101ab565b6104836104ac3660046136c4565b611e85565b6101d36104bf366004613434565b61213a565b5f5f84116105195760405162461bcd60e51b815260206004820152601e60248201527f4143523a20494e53554646494349454e545f494e5055545f414d4f554e54000060448201526064015b60405180910390fd5b5f8311801561052757505f82115b6105435760405162461bcd60e51b81526004016105109061371e565b5f610550856103e5613769565b90505f61055d8483613769565b90505f8261056d876103e8613769565b6105779190613786565b90506105838183613799565b979650505050505050565b606081428110156105b15760405162461bcd60e51b8152600401610510906137b8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21686866105e86001826137de565b8181106105f7576105f76137f1565b905060200201602081019061060c9190613412565b6001600160a01b0316146106325760405162461bcd60e51b815260040161051090613805565b61066e888787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611bf392505050565b915086826001845161068091906137de565b81518110610690576106906137f1565b602002602001015110156106b65760405162461bcd60e51b815260040161051090613830565b6107da86865f8181106106cb576106cb6137f1565b90506020020160208101906106e09190613412565b337f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a439058a8a5f818110610722576107226137f1565b90506020020160208101906107379190613412565b8b8b600181811061074a5761074a6137f1565b905060200201602081019061075f9190613412565b6040518363ffffffff1660e01b815260040161077c9291906135a8565b602060405180830381865afa158015610797573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107bb9190613867565b855f815181106107cd576107cd6137f1565b60200260200101516124fc565b610818828787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525030925061261b915050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316632e1a7d4d836001855161085691906137de565b81518110610866576108666137f1565b60200260200101516040518263ffffffff1660e01b815260040161088c91815260200190565b5f604051808303815f87803b1580156108a3575f5ffd5b505af11580156108b5573d5f5f3e3d5ffd5b505050506108e98483600185516108cc91906137de565b815181106108dc576108dc6137f1565b60200260200101516128d3565b509695505050505050565b60606002825110156109185760405162461bcd60e51b815260040161051090613805565b81516001600160401b0381111561093157610931613310565b60405190808252806020026020018201604052801561095a578160200160208202803683370190505b50905082816001835161096d91906137de565b8151811061097d5761097d6137f1565b6020026020010181815250505f6001835161099891906137de565b90505b8015610a4e575f806109e9856109b26001866137de565b815181106109c2576109c26137f1565b60200260200101518685815181106109dc576109dc6137f1565b6020026020010151612991565b91509150610a11848481518110610a0257610a026137f1565b6020026020010151838361152a565b84610a1d6001866137de565b81518110610a2d57610a2d6137f1565b60200260200101818152505050508080610a4690613882565b91505061099b565b5092915050565b60608142811015610a785760405162461bcd60e51b8152600401610510906137b8565b610ab4888787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611bf392505050565b9150868260018451610ac691906137de565b81518110610ad657610ad66137f1565b60200260200101511015610afc5760405162461bcd60e51b815260040161051090613830565b610b1186865f8181106106cb576106cb6137f1565b6108e9828787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525089925061261b915050565b60608142811015610b725760405162461bcd60e51b8152600401610510906137b8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168686610ba96001826137de565b818110610bb857610bb86137f1565b9050602002016020810190610bcd9190613412565b6001600160a01b031614610bf35760405162461bcd60e51b815260040161051090613805565b610c2f888787808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506108f492505050565b915086825f81518110610c4457610c446137f1565b602002602001015111156106b65760405162461bcd60e51b815260040161051090613897565b8042811015610c8b5760405162461bcd60e51b8152600401610510906137b8565b610d9685855f818110610ca057610ca06137f1565b9050602002016020810190610cb59190613412565b337f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390589895f818110610cf757610cf76137f1565b9050602002016020810190610d0c9190613412565b8a8a6001818110610d1f57610d1f6137f1565b9050602002016020810190610d349190613412565b6040518363ffffffff1660e01b8152600401610d519291906135a8565b602060405180830381865afa158015610d6c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d909190613867565b8a6124fc565b5f8585610da46001826137de565b818110610db357610db36137f1565b9050602002016020810190610dc89190613412565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015610e0e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e3291906138ce565b9050610e718686808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250889250612ad7915050565b86818787610e806001826137de565b818110610e8f57610e8f6137f1565b9050602002016020810190610ea49190613412565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a08231906024015b602060405180830381865afa158015610eeb573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0f91906138ce565b610f1991906137de565b1015610f375760405162461bcd60e51b815260040161051090613830565b5050505050505050565b60608142811015610f645760405162461bcd60e51b8152600401610510906137b8565b610f72888888888888610a55565b98975050505050505050565b8042811015610f9f5760405162461bcd60e51b8152600401610510906137b8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168585610fd66001826137de565b818110610fe557610fe56137f1565b9050602002016020810190610ffa9190613412565b6001600160a01b0316146110205760405162461bcd60e51b815260040161051090613805565b61103585855f818110610ca057610ca06137f1565b6110728585808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250309250612ad7915050565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316906370a0823190602401602060405180830381865afa1580156110d6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fa91906138ce565b90508681101561111c5760405162461bcd60e51b815260040161051090613830565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d906024015f604051808303815f87803b15801561117b575f5ffd5b505af115801561118d573d5f5f3e3d5ffd5b50505050610f3784826128d3565b606081428110156111be5760405162461bcd60e51b8152600401610510906137b8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031686865f8181106111fa576111fa6137f1565b905060200201602081019061120f9190613412565b6001600160a01b0316146112355760405162461bcd60e51b815260040161051090613805565b611271348787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611bf392505050565b915086826001845161128391906137de565b81518110611293576112936137f1565b602002602001015110156112b95760405162461bcd60e51b815260040161051090613830565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0835f815181106112fa576112fa6137f1565b60200260200101516040518263ffffffff1660e01b81526004015f604051808303818588803b15801561132b575f5ffd5b505af115801561133d573d5f5f3e3d5ffd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390589895f8181106113b2576113b26137f1565b90506020020160208101906113c79190613412565b8a8a60018181106113da576113da6137f1565b90506020020160208101906113ef9190613412565b6040518363ffffffff1660e01b815260040161140c9291906135a8565b602060405180830381865afa158015611427573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061144b9190613867565b845f8151811061145d5761145d6137f1565b60200260200101516040518363ffffffff1660e01b81526004016114969291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156114b2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d691906138e5565b6114e2576114e26131bd565b611520828787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525089925061261b915050565b5095945050505050565b5f5f841161154a5760405162461bcd60e51b815260040161051090613830565b5f8311801561155857505f82115b6115745760405162461bcd60e51b81526004016105109061371e565b5f61157f8585613769565b61158b906103e8613769565b90505f61159886856137de565b6115a4906103e5613769565b90506115b08183613799565b6115bb906001613786565b9695505050505050565b606081428110156115e85760405162461bcd60e51b8152600401610510906137b8565b611624888787808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506108f492505050565b915086825f81518110611639576116396137f1565b60200260200101511115610afc5760405162461bcd60e51b815260040161051090613897565b5f5f84116116af5760405162461bcd60e51b815260206004820152601860248201527f4143523a20494e53554646494349454e545f414d4f554e5400000000000000006044820152606401610510565b5f831180156116bd57505f82115b6116d95760405162461bcd60e51b81526004016105109061371e565b826116e48386613769565b6116ee9190613799565b949350505050565b5f5f8888888833604051611709906131a3565b611717959493929190613932565b604051809103905ff080158015611730573d5f5f3e3d5ffd5b506040516364e329cb60e11b81529092506001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f169063c9c653969061178290859088906004016135a8565b6020604051808303815f875af115801561179e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117c29190613867565b90506117d0823383886124fc565b6117dc843383866124fc565b97509795505050505050565b5f8383836040516117f8906131b0565b61180493929190613980565b604051809103905ff08015801561181d573d5f5f3e3d5ffd5b50949350505050565b80428110156118475760405162461bcd60e51b8152600401610510906137b8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031685855f818110611883576118836137f1565b90506020020160208101906118989190613412565b6001600160a01b0316146118be5760405162461bcd60e51b815260040161051090613805565b5f3490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b15801561191b575f5ffd5b505af115801561192d573d5f5f3e3d5ffd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390589895f8181106119a2576119a26137f1565b90506020020160208101906119b79190613412565b8a8a60018181106119ca576119ca6137f1565b90506020020160208101906119df9190613412565b6040518363ffffffff1660e01b81526004016119fc9291906135a8565b602060405180830381865afa158015611a17573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3b9190613867565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af1158015611a85573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aa991906138e5565b611ab557611ab56131bd565b5f8686611ac36001826137de565b818110611ad257611ad26137f1565b9050602002016020810190611ae79190613412565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611b2d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b5191906138ce565b9050611b908787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250899250612ad7915050565b87818888611b9f6001826137de565b818110611bae57611bae6137f1565b9050602002016020810190611bc39190613412565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a0823190602401610ed0565b6060600282511015611c175760405162461bcd60e51b815260040161051090613805565b81516001600160401b03811115611c3057611c30613310565b604051908082528060200260200182016040528015611c59578160200160208202803683370190505b50905082815f81518110611c6f57611c6f6137f1565b6020026020010181815250505f5b60018351611c8b91906137de565b811015610a4e575f5f611ccf858481518110611ca957611ca96137f1565b602002602001015186856001611cbf9190613786565b815181106109dc576109dc6137f1565b91509150611cf7848481518110611ce857611ce86137f1565b602002602001015183836104c4565b84611d03856001613786565b81518110611d1357611d136137f1565b60209081029190910101525050600101611c7d565b5f5f5f8342811015611d4c5760405162461bcd60e51b8152600401610510906137b8565b611d5a8c8c8c8c8c8c612e76565b80945081955050505f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a439058e8e6040518363ffffffff1660e01b8152600401611db19291906135a8565b602060405180830381865afa158015611dcc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611df09190613867565b9050611dfe8d3383886124fc565b611e0a8c3383876124fc565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af1158015611e4f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e7391906138ce565b92505050985098509895505050505050565b5f5f5f8342811015611ea95760405162461bcd60e51b8152600401610510906137b8565b611ed78a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b348c8c612e76565b60405163e6a4390560e01b815291955093505f906001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f169063e6a4390590611f4c908e907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906004016135a8565b602060405180830381865afa158015611f67573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8b9190613867565b9050611f998b3383886124fc565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004015f604051808303818588803b158015611ff2575f5ffd5b505af1158015612004573d5f5f3e3d5ffd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb925060440190506020604051808303815f875af1158015612076573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061209a91906138e5565b6120a6576120a66131bd565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af11580156120eb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061210f91906138ce565b92508334111561212c5761212c3361212786346137de565b6128d3565b505096509650969350505050565b6060814281101561215d5760405162461bcd60e51b8152600401610510906137b8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031686865f818110612199576121996137f1565b90506020020160208101906121ae9190613412565b6001600160a01b0316146121d45760405162461bcd60e51b815260040161051090613805565b612210878787808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152506108f492505050565b915034825f81518110612225576122256137f1565b6020026020010151111561224b5760405162461bcd60e51b815260040161051090613897565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0835f8151811061228c5761228c6137f1565b60200260200101516040518263ffffffff1660e01b81526004015f604051808303818588803b1580156122bd575f5ffd5b505af11580156122cf573d5f5f3e3d5ffd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390589895f818110612344576123446137f1565b90506020020160208101906123599190613412565b8a8a600181811061236c5761236c6137f1565b90506020020160208101906123819190613412565b6040518363ffffffff1660e01b815260040161239e9291906135a8565b602060405180830381865afa1580156123b9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123dd9190613867565b845f815181106123ef576123ef6137f1565b60200260200101516040518363ffffffff1660e01b81526004016124289291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af1158015612444573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061246891906138e5565b612474576124746131bd565b6124b2828787808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525089925061261b915050565b815f815181106124c4576124c46137f1565b60200260200101513411156115205761152033835f815181106124e9576124e96137f1565b60200260200101513461212791906137de565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291515f9283929088169161255f91906139b8565b5f604051808303815f865af19150503d805f8114612598576040519150601f19603f3d011682016040523d82523d5f602084013e61259d565b606091505b50915091508180156125c75750805115806125c75750808060200190518101906125c791906138e5565b6126135760405162461bcd60e51b815260206004820152601960248201527f4143523a205452414e534645525f46524f4d5f4641494c4544000000000000006044820152606401610510565b505050505050565b5f5b6001835161262b91906137de565b8110156128cd575f5f848381518110612646576126466137f1565b60200260200101518584600161265c9190613786565b8151811061266c5761266c6137f1565b6020026020010151915091505f61268383836130c7565b5090505f87612693866001613786565b815181106126a3576126a36137f1565b602002602001015190505f5f836001600160a01b0316866001600160a01b0316146126cf57825f6126d2565b5f835b915091505f60028a516126e591906137de565b88106126f157886127a1565b6001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f1663e6a43905878c61272d8c6002613786565b8151811061273d5761273d6137f1565b60200260200101516040518363ffffffff1660e01b81526004016127629291906135a8565b602060405180830381865afa15801561277d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127a19190613867565b60405163e6a4390560e01b81529091506001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f169063e6a43905906127f2908a908a906004016135a8565b602060405180830381865afa15801561280d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128319190613867565b6001600160a01b031663022c0d9f8484845f6040519080825280601f01601f19166020018201604052801561286d576020820181803683370190505b506040518563ffffffff1660e01b815260040161288d94939291906139ce565b5f604051808303815f87803b1580156128a4575f5ffd5b505af11580156128b6573d5f5f3e3d5ffd5b50506001909901985061261d975050505050505050565b50505050565b604080515f808252602082019092526001600160a01b0384169083906040516128fc91906139b8565b5f6040518083038185875af1925050503d805f8114612936576040519150601f19603f3d011682016040523d82523d5f602084013e61293b565b606091505b505090508061298c5760405162461bcd60e51b815260206004820152601860248201527f4143523a204554485f5452414e534645525f4641494c454400000000000000006044820152606401610510565b505050565b5f5f5f61299e85856130c7565b5090505f5f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390588886040518363ffffffff1660e01b81526004016129f19291906135a8565b602060405180830381865afa158015612a0c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a309190613867565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612a6b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a8f9190613a10565b506001600160701b031691506001600160701b03169150826001600160a01b0316876001600160a01b031614612ac6578082612ac9565b81815b909890975095505050505050565b5f5b60018351612ae791906137de565b81101561298c575f5f848381518110612b0257612b026137f1565b602002602001015185846001612b189190613786565b81518110612b2857612b286137f1565b6020026020010151915091505f612b3f83836130c7565b5090505f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390585856040518363ffffffff1660e01b8152600401612b919291906135a8565b602060405180830381865afa158015612bac573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bd09190613867565b90505f5f5f5f846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612c12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c369190613a10565b506001600160701b031691506001600160701b031691505f5f876001600160a01b03168a6001600160a01b031614612c6f578284612c72565b83835b6040516370a0823160e01b81526001600160a01b038a8116600483015292945090925083918c16906370a0823190602401602060405180830381865afa158015612cbe573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ce291906138ce565b612cec91906137de565b9550612cf98683836104c4565b9450505050505f5f856001600160a01b0316886001600160a01b031614612d2157825f612d24565b5f835b915091505f60028c51612d3791906137de565b8a10612d43578a612df3565b6001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f1663e6a43905898e612d7f8e6002613786565b81518110612d8f57612d8f6137f1565b60200260200101516040518363ffffffff1660e01b8152600401612db49291906135a8565b602060405180830381865afa158015612dcf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612df39190613867565b604080515f8152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f90612e3490869086908690602481016139ce565b5f604051808303815f87803b158015612e4b575f5ffd5b505af1158015612e5d573d5f5f3e3d5ffd5b50506001909b019a50612ad99950505050505050505050565b60405163e6a4390560e01b81525f90819081907f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b03169063e6a4390590612eca908c908c906004016135a8565b602060405180830381865afa158015612ee5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f099190613867565b6001600160a01b031603612fa7576040516364e329cb60e11b81526001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f169063c9c6539690612f65908b908b906004016135a8565b6020604051808303815f875af1158015612f81573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fa59190613867565b505b5f5f612fb38a8a612991565b91509150815f148015612fc4575080155b15612fd4578793508692506130ba565b5f612fe089848461165f565b905087811161304457858110156130395760405162461bcd60e51b815260206004820152601a60248201527f4143523a20494e53554646494349454e545f425f414d4f554e540000000000006044820152606401610510565b8894509250826130b8565b5f61305089848661165f565b905089811115613062576130626131bd565b878110156130b25760405162461bcd60e51b815260206004820152601a60248201527f4143523a20494e53554646494349454e545f415f414d4f554e540000000000006044820152606401610510565b94508793505b505b5050965096945050505050565b5f5f826001600160a01b0316846001600160a01b03160361312a5760405162461bcd60e51b815260206004820152601860248201527f4143523a204944454e544943414c5f41444452455353455300000000000000006044820152606401610510565b826001600160a01b0316846001600160a01b03161061314a57828461314d565b83835b90925090506001600160a01b03821661319c5760405162461bcd60e51b81526020600482015260116024820152704143523a205a45524f5f4144445245535360781b6044820152606401610510565b9250929050565b61094680613a5d83390190565b6107d7806143a383390190565b634e487b7160e01b5f52600160045260245ffd5b5f5f5f606084860312156131e3575f5ffd5b505081359360208301359350604090920135919050565b5f5f83601f84011261320a575f5ffd5b5081356001600160401b03811115613220575f5ffd5b6020830191508360208260051b850101111561319c575f5ffd5b6001600160a01b038116811461324e575f5ffd5b50565b803561325c8161323a565b919050565b5f5f5f5f5f5f60a08789031215613276575f5ffd5b863595506020870135945060408701356001600160401b03811115613299575f5ffd5b6132a589828a016131fa565b90955093505060608701356132b98161323a565b95989497509295919493608090920135925050565b602080825282518282018190525f918401906040840190835b818110156133055783518352602093840193909201916001016132e7565b509095945050505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561334c5761334c613310565b604052919050565b5f5f60408385031215613365575f5ffd5b8235915060208301356001600160401b03811115613381575f5ffd5b8301601f81018513613391575f5ffd5b80356001600160401b038111156133aa576133aa613310565b8060051b6133ba60208201613324565b918252602081840181019290810190888411156133d5575f5ffd5b6020850194505b8385101561340357843592506133f18361323a565b828252602094850194909101906133dc565b80955050505050509250929050565b5f60208284031215613422575f5ffd5b813561342d8161323a565b9392505050565b5f5f5f5f5f60808688031215613448575f5ffd5b8535945060208601356001600160401b03811115613464575f5ffd5b613470888289016131fa565b90955093505060408601356134848161323a565b949793965091946060013592915050565b5f82601f8301126134a4575f5ffd5b81356001600160401b038111156134bd576134bd613310565b6134d0601f8201601f1916602001613324565b8181528460208386010111156134e4575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f5f5f60e0888a031215613516575f5ffd5b87356001600160401b0381111561352b575f5ffd5b6135378a828b01613495565b97505060208801356001600160401b03811115613552575f5ffd5b61355e8a828b01613495565b965050604088013560ff81168114613574575f5ffd5b9450606088013593506080880135925061359060a08901613251565b96999598509396929591949193505060c09091013590565b6001600160a01b0392831681529116602082015260400190565b5f5f5f606084860312156135d4575f5ffd5b83356001600160401b038111156135e9575f5ffd5b6135f586828701613495565b93505060208401356001600160401b03811115613610575f5ffd5b61361c86828701613495565b92505060408401356001600160401b03811115613637575f5ffd5b61364386828701613495565b9150509250925092565b5f5f5f5f5f5f5f5f610100898b031215613665575f5ffd5b88356136708161323a565b975060208901356136808161323a565b965060408901359550606089013594506080890135935060a0890135925060c08901356136ac8161323a565b979a969950949793969295919450919260e001359150565b5f5f5f5f5f5f60c087890312156136d9575f5ffd5b86356136e48161323a565b955060208701359450604087013593506060870135925060808701356137098161323a565b9598949750929591949360a090920135925050565b6020808252601b908201527f4143523a20494e53554646494349454e545f4c49515549444954590000000000604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761378057613780613755565b92915050565b8082018082111561378057613780613755565b5f826137b357634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252600c908201526b1050d48e881156141254915160a21b604082015260600190565b8181038181111561378057613780613755565b634e487b7160e01b5f52603260045260245ffd5b60208082526011908201527008286a47440929cac82989288bea082a89607b1b604082015260600190565b6020808252601f908201527f4143523a20494e53554646494349454e545f4f55545055545f414d4f554e5400604082015260600190565b5f60208284031215613877575f5ffd5b815161342d8161323a565b5f8161389057613890613755565b505f190190565b6020808252601b908201527f4143523a204558434553534956455f494e5055545f414d4f554e540000000000604082015260600190565b5f602082840312156138de575f5ffd5b5051919050565b5f602082840312156138f5575f5ffd5b8151801515811461342d575f5ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60a081525f61394460a0830188613904565b82810360208401526139568188613904565b60ff969096166040840152505060608101929092526001600160a01b031660809091015292915050565b606081525f6139926060830186613904565b82810360208401526139a48186613904565b905082810360408401526115bb8185613904565b5f82518060208501845e5f920191825250919050565b84815283602082015260018060a01b0383166040820152608060608201525f6115bb6080830184613904565b80516001600160701b038116811461325c575f5ffd5b5f5f5f60608486031215613a22575f5ffd5b613a2b846139fa565b9250613a39602085016139fa565b9150604084015163ffffffff81168114613a51575f5ffd5b80915050925092509256fe608060405234801561000f575f5ffd5b5060405161094638038061094683398101604081905261002e9161014e565b5f6100398682610277565b5060016100468582610277565b506002805460ff191660ff851617905560038290556001600160a01b0381165f818152600460209081526040808320869055518581527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050610331565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126100d4575f5ffd5b81516001600160401b038111156100ed576100ed6100b1565b604051601f8201601f19908116603f011681016001600160401b038111828210171561011b5761011b6100b1565b604052818152838201602001851015610132575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f5f5f5f5f60a08688031215610162575f5ffd5b85516001600160401b03811115610177575f5ffd5b610183888289016100c5565b602088015190965090506001600160401b038111156101a0575f5ffd5b6101ac888289016100c5565b945050604086015160ff811681146101c2575f5ffd5b6060870151608088015191945092506001600160a01b03811681146101e5575f5ffd5b809150509295509295909350565b600181811c9082168061020757607f821691505b60208210810361022557634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561027257805f5260205f20601f840160051c810160208510156102505750805b601f840160051c820191505b8181101561026f575f815560010161025c565b50505b505050565b81516001600160401b03811115610290576102906100b1565b6102a48161029e84546101f3565b8461022b565b6020601f8211600181146102d6575f83156102bf5750848201515b5f19600385901b1c1916600184901b17845561026f565b5f84815260208120601f198516915b8281101561030557878501518255602094850194600190920191016102e5565b508482101561032257868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6106088061033e5f395ff3fe608060405234801561000f575f5ffd5b5060043610610090575f3560e01c8063313ce56711610063578063313ce567146100ff57806370a082311461011e57806395d89b411461013d578063a9059cbb14610145578063dd62ed3e14610158575f5ffd5b806306fdde0314610094578063095ea7b3146100b257806318160ddd146100d557806323b872dd146100ec575b5f5ffd5b61009c610182565b6040516100a9919061045d565b60405180910390f35b6100c56100c03660046104ad565b61020d565b60405190151581526020016100a9565b6100de60035481565b6040519081526020016100a9565b6100c56100fa3660046104d5565b610223565b60025461010c9060ff1681565b60405160ff90911681526020016100a9565b6100de61012c36600461050f565b60046020525f908152604090205481565b61009c61029a565b6100c56101533660046104ad565b6102a7565b6100de61016636600461052f565b600560209081525f928352604080842090915290825290205481565b5f805461018e90610560565b80601f01602080910402602001604051908101604052809291908181526020018280546101ba90610560565b80156102055780601f106101dc57610100808354040283529160200191610205565b820191905f5260205f20905b8154815290600101906020018083116101e857829003601f168201915b505050505081565b5f6102193384846102b3565b5060015b92915050565b6001600160a01b0383165f9081526005602090815260408083203384529091528120545f1914610285576001600160a01b0384165f9081526005602090815260408083203384529091528120805484929061027f9084906105ac565b90915550505b610290848484610368565b5060019392505050565b6001805461018e90610560565b5f610219338484610368565b6001600160a01b0382166103075760405162461bcd60e51b815260206004820152601660248201527545524332303a20617070726f766520746f207a65726f60501b60448201526064015b60405180910390fd5b6001600160a01b038381165f8181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166103be5760405162461bcd60e51b815260206004820152601760248201527f45524332303a207472616e7366657220746f207a65726f00000000000000000060448201526064016102fe565b6001600160a01b0383165f90815260046020526040812080548392906103e59084906105ac565b90915550506001600160a01b0382165f90815260046020526040812080548392906104119084906105bf565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161035b91815260200190565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b03811681146104a8575f5ffd5b919050565b5f5f604083850312156104be575f5ffd5b6104c783610492565b946020939093013593505050565b5f5f5f606084860312156104e7575f5ffd5b6104f084610492565b92506104fe60208501610492565b929592945050506040919091013590565b5f6020828403121561051f575f5ffd5b61052882610492565b9392505050565b5f5f60408385031215610540575f5ffd5b61054983610492565b915061055760208401610492565b90509250929050565b600181811c9082168061057457607f821691505b60208210810361059257634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561021d5761021d610598565b8082018082111561021d5761021d61059856fea2646970667358221220f9ac9fae3772878eb4fbb6f47047a3a5538a8d904d02bc7e503edeebd1fb728b64736f6c634300081c0033608060405234801561000f575f5ffd5b506040516107d73803806107d783398101604081905261002e916100f9565b5f610039848261020c565b506001610046838261020c565b506002610053828261020c565b505050506102c6565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011261007f575f5ffd5b81516001600160401b038111156100985761009861005c565b604051601f8201601f19908116603f011681016001600160401b03811182821017156100c6576100c661005c565b6040528181528382016020018510156100dd575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f5f5f6060848603121561010b575f5ffd5b83516001600160401b03811115610120575f5ffd5b61012c86828701610070565b602086015190945090506001600160401b03811115610149575f5ffd5b61015586828701610070565b604086015190935090506001600160401b03811115610172575f5ffd5b61017e86828701610070565b9150509250925092565b600181811c9082168061019c57607f821691505b6020821081036101ba57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561020757805f5260205f20601f840160051c810160208510156101e55750805b601f840160051c820191505b81811015610204575f81556001016101f1565b50505b505050565b81516001600160401b038111156102255761022561005c565b610239816102338454610188565b846101c0565b6020601f82116001811461026b575f83156102545750848201515b5f19600385901b1c1916600184901b178455610204565b5f84815260208120601f198516915b8281101561029a578785015182556020948501946001909201910161027a565b50848210156102b757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b610504806102d35f395ff3fe608060405234801561000f575f5ffd5b5060043610610055575f3560e01c806306fdde03146100595780636352211e146100775780636a627842146100a257806370a08231146100c357806395d89b41146100d6575b5f5ffd5b6100616100de565b60405161006e91906103f9565b60405180910390f35b61008a61008536600461042e565b610169565b6040516001600160a01b03909116815260200161006e565b6100b56100b0366004610445565b6101d8565b60405190815260200161006e565b6100b56100d1366004610445565b610246565b6100616102af565b5f80546100ea90610472565b80601f016020809104026020016040519081016040528092919081815260200182805461011690610472565b80156101615780601f1061013857610100808354040283529160200191610161565b820191905f5260205f20905b81548152906001019060200180831161014457829003601f168201915b505050505081565b5f818152600360205260408120546001600160a01b0316806101d25760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e204944000000000000000060448201526064015b60405180910390fd5b92915050565b5f6001600160a01b0382166102265760405162461bcd60e51b81526020600482015260146024820152734552433732313a206d696e7420746f207a65726f60601b60448201526064016101c9565b600880545f9182610236836104aa565b9190505590506101d283826102bc565b5f6001600160a01b0382166102945760405162461bcd60e51b81526020600482015260146024820152734552433732313a207a65726f206164647265737360601b60448201526064016101c9565b506001600160a01b03165f9081526004602052604090205490565b600180546100ea90610472565b6001600160a01b0382166103095760405162461bcd60e51b81526020600482015260146024820152734552433732313a206d696e7420746f207a65726f60601b60448201526064016101c9565b5f818152600360205260409020546001600160a01b0316156103645760405162461bcd60e51b81526020600482015260146024820152734552433732313a20746f6b656e2065786973747360601b60448201526064016101c9565b60078054905f610373836104aa565b90915550505f81815260036020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600490915281208054916103b9836104aa565b909155505060405181906001600160a01b038416905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f6020828403121561043e575f5ffd5b5035919050565b5f60208284031215610455575f5ffd5b81356001600160a01b038116811461046b575f5ffd5b9392505050565b600181811c9082168061048657607f821691505b6020821081036104a457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f600182016104c757634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220cdc3723748f5030359ecaa6f20bdb7c0c82b76d758b4b3332cb489594f2c410a64736f6c634300081c0033a2646970667358221220410afd260ffe3c2d80b98dc8a7ce387219b83533690b4d0e0b1846c10b3c37ef64736f6c634300081c0033

Verified Source Code Full Match

Compiler: v0.8.28+commit.7893614a EVM: cancun Optimization: Yes (200 runs)
AuthenticallyCryptoRouter.sol 600 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Interfaces
interface IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

interface IWETH {
    function deposit() external payable;
    function withdraw(uint) external;
    function totalSupply() external view returns (uint);
    function balanceOf(address account) external view returns (uint);
    function transfer(address recipient, uint amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address spender, uint amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint amount) external returns (bool);
}

interface IUniswapV2Pair {
    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);
    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);
    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;
}

interface IUniswapV2Factory {
    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function createPair(address tokenA, address tokenB) external returns (address pair);
}

// Implementation contracts
contract ERC20Token {
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _totalSupply,
        address _owner
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _totalSupply;
        balanceOf[_owner] = _totalSupply;
        emit Transfer(address(0), _owner, _totalSupply);
    }
    
    function transfer(address to, uint256 value) external returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }
    
    function approve(address spender, uint256 value) external returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }
    
    function transferFrom(address from, address to, uint256 value) external returns (bool) {
        if (allowance[from][msg.sender] != type(uint256).max) {
            allowance[from][msg.sender] -= value;
        }
        _transfer(from, to, value);
        return true;
    }
    
    function _transfer(address from, address to, uint256 value) internal {
        require(to != address(0), "ERC20: transfer to zero");
        balanceOf[from] -= value;
        balanceOf[to] += value;
        emit Transfer(from, to, value);
    }
    
    function _approve(address owner, address spender, uint256 value) internal {
        require(spender != address(0), "ERC20: approve to zero");
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }
}

contract ERC721Token {
    string public name;
    string public symbol;
    string private _baseTokenURI;
    
    // Token ID to owner address mapping
    mapping(uint256 => address) private _owners;
    
    // Owner address to token count mapping
    mapping(address => uint256) private _balances;
    
    // Token ID to approved address mapping
    mapping(uint256 => address) private _tokenApprovals;
    
    // Owner to operator approvals mapping
    mapping(address => mapping(address => bool)) private _operatorApprovals;
    
    uint256 private _totalSupply;
    uint256 private _nextTokenId;
    
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    
    constructor(
        string memory _name,
        string memory _symbol,
        string memory baseTokenURI
    ) {
        name = _name;
        symbol = _symbol;
        _baseTokenURI = baseTokenURI;
    }
    
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: zero address");
        return _balances[owner];
    }
    
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }
    
    function mint(address to) external returns (uint256) {
        require(to != address(0), "ERC721: mint to zero");
        uint256 tokenId = _nextTokenId++;
        _mint(to, tokenId);
        return tokenId;
    }
    
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to zero");
        require(_owners[tokenId] == address(0), "ERC721: token exists");
        
        _totalSupply++;
        _owners[tokenId] = to;
        _balances[to]++;
        
        emit Transfer(address(0), to, tokenId);
    }
}

contract AuthenticallyCryptoRouter {
    address public immutable factory;
    address public immutable WETH;
    uint256 private constant UINT_MAX = type(uint256).max;
    bytes32 immutable DOMAIN_SEPARATOR;
    bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    mapping(address => uint) public nonces;

    modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'ACR: EXPIRED');
        _;
    }

    constructor(address _factory, address _WETH) {
        factory = _factory;
        WETH = _WETH;
        
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                keccak256(bytes('Authentically Crypto Router')),
                keccak256(bytes('1')),
                block.chainid,
                address(this)
            )
        );
    }

    receive() external payable {
        assert(msg.sender == WETH);
    }

    // Helper functions
    function _safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ACR: TRANSFER_FROM_FAILED');
    }

    function _safeTransfer(address token, address to, uint value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ACR: TRANSFER_FAILED');
    }

    function _safeApprove(address token, address spender, uint value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ACR: APPROVE_FAILED');
    }

    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        require(tokenA != tokenB, 'ACR: IDENTICAL_ADDRESSES');
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), 'ACR: ZERO_ADDRESS');
    }

    function getReserves(address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
        (address token0,) = sortTokens(tokenA, tokenB);
        (uint reserve0, uint reserve1,) = IUniswapV2Pair(IUniswapV2Factory(factory).getPair(tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }

    // Quotes and amounts
    function quote(uint amountA, uint reserveA, uint reserveB) public pure returns (uint amountB) {
        require(amountA > 0, 'ACR: INSUFFICIENT_AMOUNT');
        require(reserveA > 0 && reserveB > 0, 'ACR: INSUFFICIENT_LIQUIDITY');
        amountB = (amountA * reserveB) / reserveA;
    }

    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure returns (uint amountOut) {
        require(amountIn > 0, 'ACR: INSUFFICIENT_INPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'ACR: INSUFFICIENT_LIQUIDITY');
        uint amountInWithFee = amountIn * 997;
        uint numerator = amountInWithFee * reserveOut;
        uint denominator = (reserveIn * 1000) + amountInWithFee;
        amountOut = numerator / denominator;
    }

    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure returns (uint amountIn) {
        require(amountOut > 0, 'ACR: INSUFFICIENT_OUTPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'ACR: INSUFFICIENT_LIQUIDITY');
        uint numerator = reserveIn * amountOut * 1000;
        uint denominator = (reserveOut - amountOut) * 997;
        amountIn = (numerator / denominator) + 1;
    }

    function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts) {
        require(path.length >= 2, 'ACR: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[0] = amountIn;
        for (uint i; i < path.length - 1; i++) {
            (uint reserveIn, uint reserveOut) = getReserves(path[i], path[i + 1]);
            amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
        }
    }

    function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts) {
        require(path.length >= 2, 'ACR: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[amounts.length - 1] = amountOut;
        for (uint i = path.length - 1; i > 0; i--) {
            (uint reserveIn, uint reserveOut) = getReserves(path[i - 1], path[i]);
            amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
        }
    }

    // Swap functions
    function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = sortTokens(input, output);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? IUniswapV2Factory(factory).getPair(output, path[i + 2]) : _to;
            IUniswapV2Pair(IUniswapV2Factory(factory).getPair(input, output)).swap(
                amount0Out, amount1Out, to, new bytes(0)
            );
        }
    }

// Custom named swap function
    function AuthenticallyBasedSwap(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        return swapExactTokensForTokens(amountIn, amountOutMin, path, to, deadline);
    }

    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) public virtual ensure(deadline) returns (uint[] memory amounts) {
        amounts = getAmountsOut(amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'ACR: INSUFFICIENT_OUTPUT_AMOUNT');
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]);
        _swap(amounts, path, to);
    }

    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        amounts = getAmountsIn(amountOut, path);
        require(amounts[0] <= amountInMax, 'ACR: EXCESSIVE_INPUT_AMOUNT');
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]);
        _swap(amounts, path, to);
    }

    function swapExactETHForTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual payable ensure(deadline) returns (uint[] memory amounts) {
        require(path[0] == WETH, 'ACR: INVALID_PATH');
        amounts = getAmountsOut(msg.value, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'ACR: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
    }

    function swapTokensForExactETH(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        require(path[path.length - 1] == WETH, 'ACR: INVALID_PATH');
        amounts = getAmountsIn(amountOut, path);
        require(amounts[0] <= amountInMax, 'ACR: EXCESSIVE_INPUT_AMOUNT');
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]);
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        _safeTransferETH(to, amounts[amounts.length - 1]);
    }

    function swapExactTokensForETH(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint[] memory amounts) {
        require(path[path.length - 1] == WETH, 'ACR: INVALID_PATH');
        amounts = getAmountsOut(amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'ACR: INSUFFICIENT_OUTPUT_AMOUNT');
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]);
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        _safeTransferETH(to, amounts[amounts.length - 1]);
    }

    function swapETHForExactTokens(
        uint amountOut,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual payable ensure(deadline) returns (uint[] memory amounts) {
        require(path[0] == WETH, 'ACR: INVALID_PATH');
        amounts = getAmountsIn(amountOut, path);
        require(amounts[0] <= msg.value, 'ACR: EXCESSIVE_INPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(IUniswapV2Factory(factory).getPair(path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
        if (msg.value > amounts[0]) _safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    // Fee on transfer token support
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) {
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amountIn);
        uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
            'ACR: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual payable ensure(deadline) {
        require(path[0] == WETH, 'ACR: INVALID_PATH');
        uint amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(IWETH(WETH).transfer(IUniswapV2Factory(factory).getPair(path[0], path[1]), amountIn));
        uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
            'ACR: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual ensure(deadline) {
        require(path[path.length - 1] == WETH, 'ACR: INVALID_PATH');
        _safeTransferFrom(path[0], msg.sender, IUniswapV2Factory(factory).getPair(path[0], path[1]), amountIn);
        _swapSupportingFeeOnTransferTokens(path, address(this));
        uint amountOut = IERC20(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, 'ACR: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).withdraw(amountOut);
        _safeTransferETH(to, amountOut);
    }

    // Internal swap function for fee on transfer tokens
    function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = sortTokens(input, output);
            IUniswapV2Pair pair = IUniswapV2Pair(IUniswapV2Factory(factory).getPair(input, output));
            uint amountInput;
            uint amountOutput;
            {
                (uint reserve0, uint reserve1,) = pair.getReserves();
                (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
                amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput;
                amountOutput = getAmountOut(amountInput, reserveInput, reserveOutput);
            }
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0));
            address to = i < path.length - 2 ? IUniswapV2Factory(factory).getPair(output, path[i + 2]) : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }

    // Liquidity functions
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal virtual returns (uint amountA, uint amountB) {
        if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {
            IUniswapV2Factory(factory).createPair(tokenA, tokenB);
        }
        (uint reserveA, uint reserveB) = getReserves(tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, 'ACR: INSUFFICIENT_B_AMOUNT');
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, 'ACR: INSUFFICIENT_A_AMOUNT');
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external virtual ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = IUniswapV2Factory(factory).getPair(tokenA, tokenB);
        _safeTransferFrom(tokenA, msg.sender, pair, amountA);
        _safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IUniswapV2Pair(pair).mint(to);
    }

    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external virtual payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH) = _addLiquidity(
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        address pair = IUniswapV2Factory(factory).getPair(token, WETH);
        _safeTransferFrom(token, msg.sender, pair, amountToken);
        IWETH(WETH).deposit{value: amountETH}();
        assert(IWETH(WETH).transfer(pair, amountETH));
        liquidity = IUniswapV2Pair(pair).mint(to);
        if (msg.value > amountETH) _safeTransferETH(msg.sender, msg.value - amountETH);
    }

    // Helper for ETH transfers
    function _safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value: value}(new bytes(0));
        require(success, 'ACR: ETH_TRANSFER_FAILED');
    }

    // Launch functions
    function launchToken(
        string memory name,
        string memory symbol,
        uint8 decimals,
        uint256 totalSupply,
        uint256 liquidityAmount,
        address pairedToken,
        uint256 pairedTokenAmount
    ) external returns (address token, address pair) {
        // Deploy new token
        token = address(new ERC20Token(
            name,
            symbol,
            decimals,
            totalSupply,
            msg.sender
        ));
        
        // Create liquidity pair
        pair = IUniswapV2Factory(factory).createPair(token, pairedToken);
        
        // Transfer tokens to pair
        _safeTransferFrom(token, msg.sender, pair, liquidityAmount);
        _safeTransferFrom(pairedToken, msg.sender, pair, pairedTokenAmount);
        
        return (token, pair);
    }

    function launchNFTCollection(
        string memory name,
        string memory symbol,
        string memory baseTokenURI
    ) external returns (address) {
        return address(new ERC721Token(
            name,
            symbol,
            baseTokenURI
        ));
    }
}

Read Contract

PERMIT_TYPEHASH 0x30adf81f → bytes32
WETH 0xad5c4648 → address
factory 0xc45a0155 → address
getAmountIn 0x85f8c259 → uint256
getAmountOut 0x054d50d4 → uint256
getAmountsIn 0x1f00ca74 → uint256[]
getAmountsOut 0xd06ca61f → uint256[]
nonces 0x7ecebe00 → uint256
quote 0xad615dec → uint256

Write Contract 14 functions

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

AuthenticallyBasedSwap 0x78fcb327
uint256 amountIn
uint256 amountOutMin
address[] path
address to
uint256 deadline
returns: uint256[]
addLiquidity 0xe8e33700
address tokenA
address tokenB
uint256 amountADesired
uint256 amountBDesired
uint256 amountAMin
uint256 amountBMin
address to
uint256 deadline
returns: uint256, uint256, uint256
addLiquidityETH 0xf305d719
address token
uint256 amountTokenDesired
uint256 amountTokenMin
uint256 amountETHMin
address to
uint256 deadline
returns: uint256, uint256, uint256
launchNFTCollection 0xb6664d5c
string name
string symbol
string baseTokenURI
returns: address
launchToken 0xb059a3e6
string name
string symbol
uint8 decimals
uint256 totalSupply
uint256 liquidityAmount
address pairedToken
uint256 pairedTokenAmount
returns: address, address
swapETHForExactTokens 0xfb3bdb41
uint256 amountOut
address[] path
address to
uint256 deadline
returns: uint256[]
swapExactETHForTokens 0x7ff36ab5
uint256 amountOutMin
address[] path
address to
uint256 deadline
returns: uint256[]
swapExactETHForTokensSupportingFeeOnTransferTokens 0xb6f9de95
uint256 amountOutMin
address[] path
address to
uint256 deadline
swapExactTokensForETH 0x18cbafe5
uint256 amountIn
uint256 amountOutMin
address[] path
address to
uint256 deadline
returns: uint256[]
swapExactTokensForETHSupportingFeeOnTransferTokens 0x791ac947
uint256 amountIn
uint256 amountOutMin
address[] path
address to
uint256 deadline
swapExactTokensForTokens 0x38ed1739
uint256 amountIn
uint256 amountOutMin
address[] path
address to
uint256 deadline
returns: uint256[]
swapExactTokensForTokensSupportingFeeOnTransferTokens 0x5c11d795
uint256 amountIn
uint256 amountOutMin
address[] path
address to
uint256 deadline
swapTokensForExactETH 0x4a25d94a
uint256 amountOut
uint256 amountInMax
address[] path
address to
uint256 deadline
returns: uint256[]
swapTokensForExactTokens 0x8803dbee
uint256 amountOut
uint256 amountInMax
address[] path
address to
uint256 deadline
returns: uint256[]

Recent Transactions

No transactions found for this address