Forkchoice Ethereum Mainnet

Address Contract Verified

Address 0xFD0F3eB31aCF86ECc63F2d2C35845C0e80a71E44
Balance 0 ETH
Nonce 1
Code Size 14163 bytes
Indexed Transactions 0 (1 on-chain, 0.7% indexed)
External Etherscan · Sourcify

Contract Bytecode

14163 bytes
0x608060405260043610610122575f3560e01c80637de3c6e41161009f578063d654e9a411610063578063d654e9a414610367578063e6a43905146103a3578063f2fde38b146103df578063f6f1e30614610407578063f887ea401461042357610129565b80637de3c6e4146102a55780637fd6f15c146102c15780638da5cb5b146102eb57806395ccea6714610315578063c45a01551461033d57610129565b806365e17c9d116100e657806365e17c9d146101f95780636b792c4b14610223578063715018a61461024b5780637ae06e58146102615780637ce3489b1461027d57610129565b80631526b8481461012d57806332a5d56f146101555780633b1cd1871461017d5780633fc8cef3146101a75780634b023cf8146101d157610129565b3661012957005b5f5ffd5b348015610138575f5ffd5b50610153600480360381019061014e9190612322565b61044d565b005b348015610160575f5ffd5b5061017b600480360381019061017691906123a7565b61049a565b005b348015610188575f5ffd5b506101916105d2565b60405161019e91906123f4565b60405180910390f35b3480156101b2575f5ffd5b506101bb6105d8565b6040516101c8919061241c565b60405180910390f35b3480156101dc575f5ffd5b506101f760048036038101906101f29190612435565b6105fd565b005b348015610204575f5ffd5b5061020d610710565b60405161021a919061241c565b60405180910390f35b34801561022e575f5ffd5b5061024960048036038101906102449190612322565b610735565b005b348015610256575f5ffd5b5061025f6107f0565b005b61027b60048036038101906102769190612460565b610803565b005b348015610288575f5ffd5b506102a3600480360381019061029e9190612322565b610b80565b005b6102bf60048036038101906102ba9190612532565b610c12565b005b3480156102cc575f5ffd5b506102d5610f12565b6040516102e291906123f4565b60405180910390f35b3480156102f6575f5ffd5b506102ff610f18565b60405161030c919061241c565b60405180910390f35b348015610320575f5ffd5b5061033b600480360381019061033691906125bb565b610f3f565b005b348015610348575f5ffd5b50610351610f76565b60405161035e919061241c565b60405180910390f35b348015610372575f5ffd5b5061038d60048036038101906103889190612749565b610f9b565b60405161039a91906123f4565b60405180910390f35b3480156103ae575f5ffd5b506103c960048036038101906103c491906123a7565b611098565b6040516103d6919061241c565b60405180910390f35b3480156103ea575f5ffd5b5061040560048036038101906104009190612435565b61113c565b005b610421600480360381019061041c91906127a3565b6111be565b005b34801561042e575f5ffd5b5061043761159b565b604051610444919061241c565b60405180910390f35b6104556115c0565b7f2596ea4192286cc20062cf773414aef3b23a5b57b4bdc47f888e9d9059d838c46003548260405161048892919061281a565b60405180910390a18060038190555050565b6104a26115c0565b8160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561052b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061054f9190612855565b60065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60035481565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6106056115c0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610673576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066a906128da565b60405180910390fd5b7f63f8f609737c2dc01ff1d619040ccd6cb6d0e1e7b04f5271d959deefa09ef54b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16826040516106c59291906128f8565b60405180910390a18060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61073d6115c0565b5f610746610f18565b73ffffffffffffffffffffffffffffffffffffffff16826040516107699061294c565b5f6040518083038185875af1925050503d805f81146107a3576040519150601f19603f3d011682016040523d82523d5f602084013e6107a8565b606091505b50509050806107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e3906129aa565b60405180910390fd5b5050565b6107f86115c0565b6108015f61163e565b565b61080b6116ff565b5f8511801561081957505f84115b610858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084f90612a38565b60405180910390fd5b60035434101561089d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089490612ac6565b60405180910390fd5b6108ca3330878a73ffffffffffffffffffffffffffffffffffffffff1661174e909392919063ffffffff16565b6108f73330868973ffffffffffffffffffffffffffffffffffffffff1661174e909392919063ffffffff16565b61090187866117d7565b61090b86856117d7565b5f5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8e337008a8a8a8a8a8a338b6040518963ffffffff1660e01b8152600401610975989796959493929190612ae4565b6060604051808303815f875af1158015610991573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b59190612b74565b50915091505f82886109c79190612bf1565b90505f82886109d69190612bf1565b90505f821115610a0c57610a0b33838d73ffffffffffffffffffffffffffffffffffffffff166118789092919063ffffffff16565b5b5f811115610a4057610a3f33828c73ffffffffffffffffffffffffffffffffffffffff166118789092919063ffffffff16565b5b5f6003541115610b17575f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600354604051610a929061294c565b5f6040518083038185875af1925050503d805f8114610acc576040519150601f19603f3d011682016040523d82523d5f602084013e610ad1565b606091505b5050905080610b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0c90612c6e565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff167fb5bf3f2c68363aa6e695c29010485bcfecb5439239c6b1306fdec5b26cb7c62e8c8c8787604051610b639493929190612c8c565b60405180910390a250505050610b776118fe565b50505050505050565b610b886115c0565b6101f4811115610bcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc490612d19565b60405180910390fd5b7f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df6130260025482604051610c0092919061281a565b60405180910390a18060028190555050565b610c1a6116ff565b5f600267ffffffffffffffff811115610c3657610c3561260d565b5b604051908082528060200260200182016040528015610c645781602001602082028036833780820191505090505b5090505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603610d5d5760075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815f81518110610ccf57610cce612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508581600181518110610d1e57610d1d612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610ef2565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1603610e535786815f81518110610da457610da3612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110610e1457610e13612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610ef1565b86815f81518110610e6757610e66612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508581600181518110610eb657610eb5612d37565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b5b610f0187878787858888611907565b50610f0a6118fe565b505050505050565b60025481565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610f476115c0565b610f7233828473ffffffffffffffffffffffffffffffffffffffff166118789092919063ffffffff16565b5050565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f61271060025485610fae9190612d64565b610fb89190612dd2565b84610fc39190612bf1565b90505f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d06ca61f83866040518363ffffffff1660e01b8152600401611022929190612eb9565b5f60405180830381865afa15801561103c573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110649190612fa7565b905080600182516110759190612bf1565b8151811061108657611085612d37565b5b60200260200101519250505092915050565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a4390584846040518363ffffffff1660e01b81526004016110f59291906128f8565b602060405180830381865afa158015611110573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111349190612855565b905092915050565b6111446115c0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a99061305e565b60405180910390fd5b6111bb8161163e565b50565b6111c66116ff565b5f841180156111d457505f34115b611213576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120a90612a38565b60405180910390fd5b60035482346112229190612bf1565b1015611263576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125a90612ac6565b60405180910390fd5b6112903330868873ffffffffffffffffffffffffffffffffffffffff1661174e909392919063ffffffff16565b61129a85856117d7565b5f600354346112a99190612bf1565b90505f5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d719848a8a8a8a338b6040518863ffffffff1660e01b81526004016113129695949392919061307c565b60606040518083038185885af115801561132e573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113539190612b74565b50915091505f82886113659190612bf1565b90505f81111561139b5761139a33828b73ffffffffffffffffffffffffffffffffffffffff166118789092919063ffffffff16565b5b5f82856113a89190612bf1565b90505f81111561145c575f3373ffffffffffffffffffffffffffffffffffffffff16826040516113d79061294c565b5f6040518083038185875af1925050503d805f8114611411576040519150601f19603f3d011682016040523d82523d5f602084013e611416565b606091505b505090508061145a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145190613125565b60405180910390fd5b505b5f6003541115611533575f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166003546040516114ae9061294c565b5f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b5050905080611531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152890612c6e565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff167fb5bf3f2c68363aa6e695c29010485bcfecb5439239c6b1306fdec5b26cb7c62e8b5f878760405161157f9493929190612c8c565b60405180910390a250505050506115946118fe565b5050505050565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6115c8611f63565b73ffffffffffffffffffffffffffffffffffffffff166115e6610f18565b73ffffffffffffffffffffffffffffffffffffffff161461163c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116339061318d565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600260015403611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173b906131f5565b60405180910390fd5b6002600181905550565b6117d1846323b872dd60e01b85858560405160240161176f93929190613213565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f6a565b50505050565b8173ffffffffffffffffffffffffffffffffffffffff1663095ea7b360055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401611833929190613248565b6020604051808303815f875af115801561184f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118739190613283565b505050565b6118f98363a9059cbb60e01b8484604051602401611897929190613248565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f6a565b505050565b60018081905550565b5f8511611949576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119409061331e565b60405180910390fd5b5f6127106002548761195b9190612d64565b6119659190612dd2565b90505f81876119749190612bf1565b90505f73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603611c2357863410156119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390613386565b60405180910390fd5b5f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1683604051611a329061294c565b5f6040518083038185875af1925050503d805f8114611a6c576040519150601f19603f3d011682016040523d82523d5f602084013e611a71565b606091505b5050905080611ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aac90612c6e565b60405180910390fd5b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ff36ab5838989338a6040518663ffffffff1660e01b8152600401611b1694939291906133a4565b5f6040518083038185885af1158015611b31573d5f5f3e3d5ffd5b50505050506040513d5f823e3d601f19601f82011682018060405250810190611b5a9190612fa7565b505f8834611b689190612bf1565b90505f811115611c1c575f3373ffffffffffffffffffffffffffffffffffffffff1682604051611b979061294c565b5f6040518083038185875af1925050503d805f8114611bd1576040519150601f19603f3d011682016040523d82523d5f602084013e611bd6565b606091505b5050905080611c1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1190613125565b60405180910390fd5b505b5050611f04565b5f83611c2f575f611ca8565b8973ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611c68919061241c565b602060405180830381865afa158015611c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ca791906133ee565b5b9050611cd733308a8d73ffffffffffffffffffffffffffffffffffffffff1661174e909392919063ffffffff16565b611d2360045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848c73ffffffffffffffffffffffffffffffffffffffff166118789092919063ffffffff16565b8315611daf57808a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d63919061241c565b602060405180830381865afa158015611d7e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611da291906133ee565b611dac9190612bf1565b91505b611db98a836117d7565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611dfc8b87612030565b848a8a338b604051602401611e15959493929190613419565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611e7f91906134b9565b5f604051808303815f865af19150503d805f8114611eb8576040519150601f19603f3d011682016040523d82523d5f602084013e611ebd565b606091505b5050905080611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890613519565b60405180910390fd5b50505b3373ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e460628a8a8a86604051611f509493929190612c8c565b60405180910390a2505050505050505050565b5f33905090565b5f611fcb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121199092919063ffffffff16565b90505f81511480611fec575080806020019051810190611feb9190613283565b5b61202b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612022906135a7565b60405180910390fd5b505050565b5f5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480156120695750815b1561208a5760055f9054906101000a90505063791ac94760e01b9050612113565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036120d95760055f9054906101000a9050506318cbafe560e01b9050612113565b81156120fb5760055f9054906101000a905050635c11d79560e01b9050612113565b60055f9054906101000a9050506338ed173960e01b90505b92915050565b606061212784845f85612130565b90509392505050565b606082471015612175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216c90613635565b60405180910390fd5b5f5f8673ffffffffffffffffffffffffffffffffffffffff16858760405161219d91906134b9565b5f6040518083038185875af1925050503d805f81146121d7576040519150601f19603f3d011682016040523d82523d5f602084013e6121dc565b606091505b50915091506121ed878383876121f9565b92505050949350505050565b6060831561225a575f835103612252576122128561226d565b612251576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122489061369d565b60405180910390fd5b5b829050612265565b612264838361228f565b5b949350505050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f825111156122a15781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d591906136fd565b60405180910390fd5b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b612301816122ef565b811461230b575f5ffd5b50565b5f8135905061231c816122f8565b92915050565b5f60208284031215612337576123366122e7565b5b5f6123448482850161230e565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6123768261234d565b9050919050565b6123868161236c565b8114612390575f5ffd5b50565b5f813590506123a18161237d565b92915050565b5f5f604083850312156123bd576123bc6122e7565b5b5f6123ca85828601612393565b92505060206123db85828601612393565b9150509250929050565b6123ee816122ef565b82525050565b5f6020820190506124075f8301846123e5565b92915050565b6124168161236c565b82525050565b5f60208201905061242f5f83018461240d565b92915050565b5f6020828403121561244a576124496122e7565b5b5f61245784828501612393565b91505092915050565b5f5f5f5f5f5f5f60e0888a03121561247b5761247a6122e7565b5b5f6124888a828b01612393565b97505060206124998a828b01612393565b96505060406124aa8a828b0161230e565b95505060606124bb8a828b0161230e565b94505060806124cc8a828b0161230e565b93505060a06124dd8a828b0161230e565b92505060c06124ee8a828b0161230e565b91505092959891949750929550565b5f8115159050919050565b612511816124fd565b811461251b575f5ffd5b50565b5f8135905061252c81612508565b92915050565b5f5f5f5f5f5f60c0878903121561254c5761254b6122e7565b5b5f61255989828a01612393565b965050602061256a89828a01612393565b955050604061257b89828a0161230e565b945050606061258c89828a0161230e565b935050608061259d89828a0161230e565b92505060a06125ae89828a0161251e565b9150509295509295509295565b5f5f604083850312156125d1576125d06122e7565b5b5f6125de85828601612393565b92505060206125ef8582860161230e565b9150509250929050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612643826125fd565b810181811067ffffffffffffffff821117156126625761266161260d565b5b80604052505050565b5f6126746122de565b9050612680828261263a565b919050565b5f67ffffffffffffffff82111561269f5761269e61260d565b5b602082029050602081019050919050565b5f5ffd5b5f6126c66126c184612685565b61266b565b905080838252602082019050602084028301858111156126e9576126e86126b0565b5b835b8181101561271257806126fe8882612393565b8452602084019350506020810190506126eb565b5050509392505050565b5f82601f8301126127305761272f6125f9565b5b81356127408482602086016126b4565b91505092915050565b5f5f6040838503121561275f5761275e6122e7565b5b5f61276c8582860161230e565b925050602083013567ffffffffffffffff81111561278d5761278c6122eb565b5b6127998582860161271c565b9150509250929050565b5f5f5f5f5f60a086880312156127bc576127bb6122e7565b5b5f6127c988828901612393565b95505060206127da8882890161230e565b94505060406127eb8882890161230e565b93505060606127fc8882890161230e565b925050608061280d8882890161230e565b9150509295509295909350565b5f60408201905061282d5f8301856123e5565b61283a60208301846123e5565b9392505050565b5f8151905061284f8161237d565b92915050565b5f6020828403121561286a576128696122e7565b5b5f61287784828501612841565b91505092915050565b5f82825260208201905092915050565b7f466c7578537761703a207a65726f2061646472657373000000000000000000005f82015250565b5f6128c4601683612880565b91506128cf82612890565b602082019050919050565b5f6020820190508181035f8301526128f1816128b8565b9050919050565b5f60408201905061290b5f83018561240d565b612918602083018461240d565b9392505050565b5f81905092915050565b50565b5f6129375f8361291f565b915061294282612929565b5f82019050919050565b5f6129568261292c565b9150819050919050565b7f466c7578537761703a20455448207472616e73666572206661696c65640000005f82015250565b5f612994601d83612880565b915061299f82612960565b602082019050919050565b5f6020820190508181035f8301526129c181612988565b9050919050565b7f537761703a20416d6f756e7473206d75737420626520677265617465722074685f8201527f616e203000000000000000000000000000000000000000000000000000000000602082015250565b5f612a22602483612880565b9150612a2d826129c8565b604082019050919050565b5f6020820190508181035f830152612a4f81612a16565b9050919050565b7f537761703a206e6f7420656e6f7567682062616c616e636520746f20706179205f8201527f6665650000000000000000000000000000000000000000000000000000000000602082015250565b5f612ab0602383612880565b9150612abb82612a56565b604082019050919050565b5f6020820190508181035f830152612add81612aa4565b9050919050565b5f61010082019050612af85f83018b61240d565b612b05602083018a61240d565b612b1260408301896123e5565b612b1f60608301886123e5565b612b2c60808301876123e5565b612b3960a08301866123e5565b612b4660c083018561240d565b612b5360e08301846123e5565b9998505050505050505050565b5f81519050612b6e816122f8565b92915050565b5f5f5f60608486031215612b8b57612b8a6122e7565b5b5f612b9886828701612b60565b9350506020612ba986828701612b60565b9250506040612bba86828701612b60565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612bfb826122ef565b9150612c06836122ef565b9250828203905081811115612c1e57612c1d612bc4565b5b92915050565b7f466c7578537761703a20666565207472616e73666572206661696c65640000005f82015250565b5f612c58601d83612880565b9150612c6382612c24565b602082019050919050565b5f6020820190508181035f830152612c8581612c4c565b9050919050565b5f608082019050612c9f5f83018761240d565b612cac602083018661240d565b612cb960408301856123e5565b612cc660608301846123e5565b95945050505050565b7f466c7578537761703a20666565206578636565647320352500000000000000005f82015250565b5f612d03601883612880565b9150612d0e82612ccf565b602082019050919050565b5f6020820190508181035f830152612d3081612cf7565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612d6e826122ef565b9150612d79836122ef565b9250828202612d87816122ef565b91508282048414831517612d9e57612d9d612bc4565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612ddc826122ef565b9150612de7836122ef565b925082612df757612df6612da5565b5b828204905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612e348161236c565b82525050565b5f612e458383612e2b565b60208301905092915050565b5f602082019050919050565b5f612e6782612e02565b612e718185612e0c565b9350612e7c83612e1c565b805f5b83811015612eac578151612e938882612e3a565b9750612e9e83612e51565b925050600181019050612e7f565b5085935050505092915050565b5f604082019050612ecc5f8301856123e5565b8181036020830152612ede8184612e5d565b90509392505050565b5f67ffffffffffffffff821115612f0157612f0061260d565b5b602082029050602081019050919050565b5f612f24612f1f84612ee7565b61266b565b90508083825260208201905060208402830185811115612f4757612f466126b0565b5b835b81811015612f705780612f5c8882612b60565b845260208401935050602081019050612f49565b5050509392505050565b5f82601f830112612f8e57612f8d6125f9565b5b8151612f9e848260208601612f12565b91505092915050565b5f60208284031215612fbc57612fbb6122e7565b5b5f82015167ffffffffffffffff811115612fd957612fd86122eb565b5b612fe584828501612f7a565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f613048602683612880565b915061305382612fee565b604082019050919050565b5f6020820190508181035f8301526130758161303c565b9050919050565b5f60c08201905061308f5f83018961240d565b61309c60208301886123e5565b6130a960408301876123e5565b6130b660608301866123e5565b6130c3608083018561240d565b6130d060a08301846123e5565b979650505050505050565b7f466c7578537761703a2045544820726566756e64206661696c656400000000005f82015250565b5f61310f601b83612880565b915061311a826130db565b602082019050919050565b5f6020820190508181035f83015261313c81613103565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f613177602083612880565b915061318282613143565b602082019050919050565b5f6020820190508181035f8301526131a48161316b565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6131df601f83612880565b91506131ea826131ab565b602082019050919050565b5f6020820190508181035f83015261320c816131d3565b9050919050565b5f6060820190506132265f83018661240d565b613233602083018561240d565b61324060408301846123e5565b949350505050565b5f60408201905061325b5f83018561240d565b61326860208301846123e5565b9392505050565b5f8151905061327d81612508565b92915050565b5f60208284031215613298576132976122e7565b5b5f6132a58482850161326f565b91505092915050565b7f537761703a20616d6f756e74496e206d757374206265206772656174657220745f8201527f68616e2030000000000000000000000000000000000000000000000000000000602082015250565b5f613308602583612880565b9150613313826132ae565b604082019050919050565b5f6020820190508181035f830152613335816132fc565b9050919050565b7f537761703a20496e73756666696369656e7420455448000000000000000000005f82015250565b5f613370601683612880565b915061337b8261333c565b602082019050919050565b5f6020820190508181035f83015261339d81613364565b9050919050565b5f6080820190506133b75f8301876123e5565b81810360208301526133c98186612e5d565b90506133d8604083018561240d565b6133e560608301846123e5565b95945050505050565b5f60208284031215613403576134026122e7565b5b5f61341084828501612b60565b91505092915050565b5f60a08201905061342c5f8301886123e5565b61343960208301876123e5565b818103604083015261344b8186612e5d565b905061345a606083018561240d565b61346760808301846123e5565b9695505050505050565b5f81519050919050565b8281835e5f83830152505050565b5f61349382613471565b61349d818561291f565b93506134ad81856020860161347b565b80840191505092915050565b5f6134c48284613489565b915081905092915050565b7f537761703a20546f6b656e2073776170206661696c65640000000000000000005f82015250565b5f613503601783612880565b915061350e826134cf565b602082019050919050565b5f6020820190508181035f830152613530816134f7565b9050919050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e5f8201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b5f613591602a83612880565b915061359c82613537565b604082019050919050565b5f6020820190508181035f8301526135be81613585565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f5f8201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b5f61361f602683612880565b915061362a826135c5565b604082019050919050565b5f6020820190508181035f83015261364c81613613565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f613687601d83612880565b915061369282613653565b602082019050919050565b5f6020820190508181035f8301526136b48161367b565b9050919050565b5f81519050919050565b5f6136cf826136bb565b6136d98185612880565b93506136e981856020860161347b565b6136f2816125fd565b840191505092915050565b5f6020820190508181035f83015261371581846136c5565b90509291505056fea2646970667358221220e81ae9007e32038df00965b106e7f5ac50f5cbcd70eacfe292c6cf7c2375b14d64736f6c634300081c0033

Verified Source Code Full Match

Compiler: v0.8.28+commit.7893614a EVM: cancun Optimization: No
Flux.sol 693 lines
// SPDX-License-Identifier: MIT
// Sources flattened with hardhat v2.28.6

pragma solidity ^0.8.20;

// File @openzeppelin/contracts/utils/[email protected]

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

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File @openzeppelin/contracts/access/[email protected]

abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        _transferOwnership(_msgSender());
    }

    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    function owner() public view virtual returns (address) {
        return _owner;
    }

    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

interface IERC20Permit {
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function nonces(address owner) external view returns (uint256);

    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File @openzeppelin/contracts/token/ERC20/[email protected]

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

// File @openzeppelin/contracts/utils/[email protected]

library Address {
    function isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");
        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        if (returndata.length > 0) {
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File @openzeppelin/contracts/token/ERC20/utils/[email protected]

library SafeERC20 {
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

// File @openzeppelin/contracts/security/[email protected]

abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        _status = _NOT_ENTERED;
    }

    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

// File contracts/FluxSwap_v2.sol

interface IFactory {
    function getPair(
        address tokenA,
        address tokenB
    ) external view returns (address pair);
}

interface IRouter {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);

    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    )
        external
        payable
        returns (uint amountToken, uint amountETH, uint liquidity);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

    function getAmountsOut(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);
}

contract SecurySwap is Ownable, ReentrancyGuard {
    using SafeERC20 for IERC20;

    event Swap(address indexed user, address tokenIn, address tokenOut, uint256 amountIn, uint256 fee);
    event LiquidityAdded(address indexed user, address tokenA, address tokenB, uint256 amountA, uint256 amountB);
    event FeeUpdated(uint256 oldFee, uint256 newFee);
    event FeeAccountUpdated(address oldAccount, address newAccount);
    event LiquidityFeeUpdated(uint256 oldFee, uint256 newFee);

    uint public feePercent = 50; // 0.5%
    uint public addLiquidityFee = 0; // in wei

    address public feeAccount;
    address public router;
    address public factory;
    address public weth;

    constructor(address _feeAccount, address _router) {
        require(_feeAccount != address(0), "FluxSwap: zero fee account");
        feeAccount = _feeAccount;
        router = _router;
        factory = IRouter(_router).factory();
        weth = IRouter(_router).WETH();
    }

    receive() external payable {}

    function swapTokens(
        address _tokenA,
        address _tokenB,
        uint256 _amountIn,
        uint256 _amountOutMin,
        uint _deadline,
        bool _feeOnTransfer
    ) external payable nonReentrant {
        address[] memory path = new address[](2);
        if (_tokenA == address(0)) {
            path[0] = weth;
            path[1] = _tokenB;
        } else if (_tokenB == address(0)) {
            path[0] = _tokenA;
            path[1] = weth;
        } else {
            path[0] = _tokenA;
            path[1] = _tokenB;
        }

        _swap(
            _tokenA,
            _tokenB,
            _amountIn,
            _amountOutMin,
            path,
            _deadline,
            _feeOnTransfer
        );
    }

    function _swap(
        address _tokenA,
        address _tokenB,
        uint256 _amountIn,
        uint256 _amountOutMin,
        address[] memory _path,
        uint _deadline,
        bool _feeOnTransfer
    ) internal {
        require(_amountIn > 0, "Swap: amountIn must be greater than 0");

        uint fee = (_amountIn * feePercent) / 10000;
        uint amountToSwap = _amountIn - fee;

        if (_tokenA == address(0)) {
            require(msg.value >= _amountIn, "Swap: Insufficient ETH");

            (bool feeSuccess, ) = payable(feeAccount).call{value: fee}("");
            require(feeSuccess, "FluxSwap: fee transfer failed");

            IRouter(router).swapExactETHForTokens{value: amountToSwap}(
                _amountOutMin,
                _path,
                msg.sender,
                _deadline
            );

            uint excess = msg.value - _amountIn;
            if (excess > 0) {
                (bool refundSuccess, ) = payable(msg.sender).call{value: excess}("");
                require(refundSuccess, "FluxSwap: ETH refund failed");
            }
        } else {
            uint balanceBefore = _feeOnTransfer
                ? IERC20(_tokenA).balanceOf(address(this))
                : 0;

            IERC20(_tokenA).safeTransferFrom(
                msg.sender,
                address(this),
                _amountIn
            );
            IERC20(_tokenA).safeTransfer(feeAccount, fee);

            if (_feeOnTransfer) {
                amountToSwap =
                    IERC20(_tokenA).balanceOf(address(this)) -
                    balanceBefore;
            }

            _approveForRouter(_tokenA, amountToSwap);

            (bool success, ) = router.call(
                abi.encodeWithSelector(
                    _getSwapFunction(_tokenB, _feeOnTransfer),
                    amountToSwap,
                    _amountOutMin,
                    _path,
                    msg.sender,
                    _deadline
                )
            );
            require(success, "Swap: Token swap failed");
        }

        emit Swap(msg.sender, _tokenA, _tokenB, _amountIn, fee);
    }

    function _getSwapFunction(
        address _tokenB,
        bool _feeOnTransfer
    ) internal view returns (bytes4) {
        if (_tokenB == address(0) && _feeOnTransfer)
            return
                IRouter(router)
                    .swapExactTokensForETHSupportingFeeOnTransferTokens
                    .selector;
        else if (_tokenB == address(0))
            return IRouter(router).swapExactTokensForETH.selector;
        else if (_feeOnTransfer)
            return
                IRouter(router)
                    .swapExactTokensForTokensSupportingFeeOnTransferTokens
                    .selector;
        else return IRouter(router).swapExactTokensForTokens.selector;
    }

    function _approveForRouter(address _token, uint _amount) internal {
        IERC20(_token).approve(router, _amount);
    }

    function getOutputTokenAmount(
        uint inputAmount,
        address[] memory path
    ) external view returns (uint outputAmount) {
        uint amount = inputAmount - ((inputAmount * feePercent) / 10000);
        uint[] memory outputs = IRouter(router).getAmountsOut(amount, path);
        return outputs[outputs.length - 1];
    }

    function setFeePercent(uint _feePercent) external onlyOwner {
        require(_feePercent <= 500, "FluxSwap: fee exceeds 5%");
        emit FeeUpdated(feePercent, _feePercent);
        feePercent = _feePercent;
    }

    function setFeeAccount(address _feeAccount) external onlyOwner {
        require(_feeAccount != address(0), "FluxSwap: zero address");
        emit FeeAccountUpdated(feeAccount, _feeAccount);
        feeAccount = _feeAccount;
    }

    // Typo preserved for ABI compatibility
    function setLiquidtyFee(uint256 _addLiquidityFee) external onlyOwner {
        emit LiquidityFeeUpdated(addLiquidityFee, _addLiquidityFee);
        addLiquidityFee = _addLiquidityFee;
    }

    function setRouterWeth(address _router, address _weth) external onlyOwner {
        router = _router;
        factory = IRouter(_router).factory();
        weth = _weth;
    }

    function getPair(
        address _tokenA,
        address _tokenB
    ) external view returns (address) {
        return IFactory(factory).getPair(_tokenA, _tokenB);
    }

    function addLiquidity(
        address _tokenA,
        address _tokenB,
        uint _amountADesired,
        uint _amountBDesired,
        uint _amountAMin,
        uint _amountBMin,
        uint _deadline
    ) external payable nonReentrant {
        require(
            _amountADesired > 0 && _amountBDesired > 0,
            "Swap: Amounts must be greater than 0"
        );
        require(
            msg.value >= addLiquidityFee,
            "Swap: not enough balance to pay fee"
        );

        IERC20(_tokenA).safeTransferFrom(
            msg.sender,
            address(this),
            _amountADesired
        );
        IERC20(_tokenB).safeTransferFrom(
            msg.sender,
            address(this),
            _amountBDesired
        );

        _approveForRouter(_tokenA, _amountADesired);
        _approveForRouter(_tokenB, _amountBDesired);

        (uint amountA, uint amountB, ) = IRouter(router).addLiquidity(
            _tokenA,
            _tokenB,
            _amountADesired,
            _amountBDesired,
            _amountAMin,
            _amountBMin,
            msg.sender,
            _deadline
        );

        uint leftoverA = _amountADesired - amountA;
        uint leftoverB = _amountBDesired - amountB;
        if (leftoverA > 0) IERC20(_tokenA).safeTransfer(msg.sender, leftoverA);
        if (leftoverB > 0) IERC20(_tokenB).safeTransfer(msg.sender, leftoverB);

        if (addLiquidityFee > 0) {
            (bool feeSuccess, ) = payable(feeAccount).call{value: addLiquidityFee}("");
            require(feeSuccess, "FluxSwap: fee transfer failed");
        }

        emit LiquidityAdded(msg.sender, _tokenA, _tokenB, amountA, amountB);
    }

    function addLiquidityETH(
        address _token,
        uint _amountTokenDesired,
        uint _amountTokenMin,
        uint _amountETHMin,
        uint _deadline
    ) external payable nonReentrant {
        require(
            _amountTokenDesired > 0 && msg.value > 0,
            "Swap: Amounts must be greater than 0"
        );
        require(
            msg.value - _amountETHMin >= addLiquidityFee,
            "Swap: not enough balance to pay fee"
        );

        IERC20(_token).safeTransferFrom(
            msg.sender,
            address(this),
            _amountTokenDesired
        );
        _approveForRouter(_token, _amountTokenDesired);

        uint ethForRouter = msg.value - addLiquidityFee;

        (uint amountToken, uint amountETH, ) = IRouter(router).addLiquidityETH{value: ethForRouter}(
            _token,
            _amountTokenDesired,
            _amountTokenMin,
            _amountETHMin,
            msg.sender,
            _deadline
        );

        uint leftoverToken = _amountTokenDesired - amountToken;
        if (leftoverToken > 0) IERC20(_token).safeTransfer(msg.sender, leftoverToken);

        uint leftoverETH = ethForRouter - amountETH;
        if (leftoverETH > 0) {
            (bool refundSuccess, ) = payable(msg.sender).call{value: leftoverETH}("");
            require(refundSuccess, "FluxSwap: ETH refund failed");
        }

        if (addLiquidityFee > 0) {
            (bool feeSuccess, ) = payable(feeAccount).call{value: addLiquidityFee}("");
            require(feeSuccess, "FluxSwap: fee transfer failed");
        }

        emit LiquidityAdded(msg.sender, _token, address(0), amountToken, amountETH);
    }

    function emergencyWithdraw(
        address _token,
        uint256 _amount
    ) external onlyOwner {
        IERC20(_token).safeTransfer(msg.sender, _amount);
    }

    function emergencyWithdrawETH(uint256 _amount) external onlyOwner {
        (bool success, ) = payable(owner()).call{value: _amount}("");
        require(success, "FluxSwap: ETH transfer failed");
    }
}

Read Contract

addLiquidityFee 0x3b1cd187 → uint256
factory 0xc45a0155 → address
feeAccount 0x65e17c9d → address
feePercent 0x7fd6f15c → uint256
getOutputTokenAmount 0xd654e9a4 → uint256
getPair 0xe6a43905 → address
owner 0x8da5cb5b → address
router 0xf887ea40 → address
weth 0x3fc8cef3 → address

Write Contract 11 functions

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

addLiquidity 0x7ae06e58
address _tokenA
address _tokenB
uint256 _amountADesired
uint256 _amountBDesired
uint256 _amountAMin
uint256 _amountBMin
uint256 _deadline
addLiquidityETH 0xf6f1e306
address _token
uint256 _amountTokenDesired
uint256 _amountTokenMin
uint256 _amountETHMin
uint256 _deadline
emergencyWithdraw 0x95ccea67
address _token
uint256 _amount
emergencyWithdrawETH 0x6b792c4b
uint256 _amount
renounceOwnership 0x715018a6
No parameters
setFeeAccount 0x4b023cf8
address _feeAccount
setFeePercent 0x7ce3489b
uint256 _feePercent
setLiquidtyFee 0x1526b848
uint256 _addLiquidityFee
setRouterWeth 0x32a5d56f
address _router
address _weth
swapTokens 0x7de3c6e4
address _tokenA
address _tokenB
uint256 _amountIn
uint256 _amountOutMin
uint256 _deadline
bool _feeOnTransfer
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

This address has 1 on-chain transactions, but only 0.7% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →