Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xB4B0ea46Fe0E9e8EAB4aFb765b527739F2718671
Balance 0 ETH
Nonce 1
Code Size 17102 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

17102 bytes
0x6080604052600436106101855760003560e01c806385f8c259116100d1578063b6f9de951161008a578063ded9382a11610064578063ded9382a1461053d578063e8e337001461055d578063f305d71914610598578063fb3bdb41146105ab57600080fd5b8063b6f9de95146104ea578063baa2abde146104fd578063d06ca61f1461051d57600080fd5b806385f8c259146104025780638803dbee14610422578063ace3a8a714610442578063ad5c464814610476578063ad615dec146104aa578063af2979eb146104ca57600080fd5b806338ed17391161013e5780635c11d795116101185780635c11d7951461038f5780636d91c0e2146103af578063791ac947146103cf5780637ff36ab5146103ef57600080fd5b806338ed17391461032f5780634a25d94a1461034f5780635b0d59841461036f57600080fd5b806302751cec1461020e578063054d50d41461024857806318cbafe5146102765780631f00ca74146102a35780632195995c146102c35780632dd31000146102e357600080fd5b3661020957336001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216146102075760405162461bcd60e51b815260206004820152601b60248201527f5377617073526f757465723a20494e56414c49445f53454e444552000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561021a57600080fd5b5061022e61022936600461387c565b6105be565b604080519283526020830191909152015b60405180910390f35b34801561025457600080fd5b506102686102633660046138da565b6106b1565b60405190815260200161023f565b34801561028257600080fd5b5061029661029136600461394b565b61078b565b60405161023f91906139be565b3480156102af57600080fd5b506102966102be366004613a18565b610adb565b3480156102cf57600080fd5b5061022e6102de366004613b08565b610b0f565b3480156102ef57600080fd5b506103177f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e281565b6040516001600160a01b03909116815260200161023f565b34801561033b57600080fd5b5061029661034a36600461394b565b610c05565b34801561035b57600080fd5b5061029661036a36600461394b565b610d23565b34801561037b57600080fd5b5061026861038a366004613bb2565b610e61565b34801561039b57600080fd5b506102076103aa36600461394b565b610f6f565b3480156103bb57600080fd5b506103176103ca366004613c48565b6111d2565b3480156103db57600080fd5b506102076103ea36600461394b565b611208565b6102966103fd366004613c93565b61142f565b34801561040e57600080fd5b5061026861041d3660046138da565b611758565b34801561042e57600080fd5b5061029661043d36600461394b565b611838565b34801561044e57600080fd5b506103177f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d19381565b34801561048257600080fd5b506103177f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3480156104b657600080fd5b506102686104c53660046138da565b6118f5565b3480156104d657600080fd5b506102686104e536600461387c565b611987565b6102076104f8366004613c93565b611ad6565b34801561050957600080fd5b5061022e610518366004613cfa565b611e1d565b34801561052957600080fd5b50610296610538366004613a18565b611f99565b34801561054957600080fd5b5061022e610558366004613bb2565b611fc6565b34801561056957600080fd5b5061057d610578366004613d6c565b6120da565b6040805193845260208401929092529082015260600161023f565b61057d6105a636600461387c565b6121f9565b6102966105b9366004613c93565b612482565b60008082428110156105e25760405162461bcd60e51b81526004016101fe90613de8565b610611897f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8a8a308a611e1d565b90935091506106218986856127dd565b604051632e1a7d4d60e01b8152600481018390527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561068357600080fd5b505af1158015610697573d6000803e3d6000fd5b505050506106a58583612928565b50965096945050505050565b60008084116107115760405162461bcd60e51b815260206004820152602660248201527f537761707348656c7065723a20494e53554646494349454e545f494e5055545f604482015265105353d5539560d21b60648201526084016101fe565b6000831180156107215750600082115b61073d5760405162461bcd60e51b81526004016101fe90613e1f565b600061074b856103e5613e78565b905060006107598483613e78565b905060008261076a876103e8613e78565b6107749190613e97565b90506107808183613eaf565b979650505050505050565b606081428110156107ae5760405162461bcd60e51b81526004016101fe90613de8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21686866107e5600182613ed1565b8181106107f4576107f4613ee8565b90506020020160208101906108099190613efe565b6001600160a01b03161461082f5760405162461bcd60e51b81526004016101fe90613f1b565b61088d7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506129ea92505050565b915086826001845161089f9190613ed1565b815181106108af576108af613ee8565b602002602001015110156108d55760405162461bcd60e51b81526004016101fe90613f52565b6109bb868660008181106108eb576108eb613ee8565b90506020020160208101906109009190613efe565b3361099b7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28a8a600081811061093857610938613ee8565b905060200201602081019061094d9190613efe565b8b8b600181811061096057610960613ee8565b90506020020160208101906109759190613efe565b7f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b856000815181106109ae576109ae613ee8565b6020026020010151612c1d565b6109fa82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250612d77915050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316632e1a7d4d8360018551610a389190613ed1565b81518110610a4857610a48613ee8565b60200260200101516040518263ffffffff1660e01b8152600401610a6e91815260200190565b600060405180830381600087803b158015610a8857600080fd5b505af1158015610a9c573d6000803e3d6000fd5b50505050610ad0848360018551610ab39190613ed1565b81518110610ac357610ac3613ee8565b6020026020010151612928565b509695505050505050565b6060610b087f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28484612fc1565b9392505050565b6000806000610b607f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28f8f7f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050600087610b6f578c610b73565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610bae903390309086908f908e908e908e90600401613f99565b600060405180830381600087803b158015610bc857600080fd5b505af1158015610bdc573d6000803e3d6000fd5b50505050610bef8f8f8f8f8f8f8f611e1d565b9350935050509b509b9950505050505050505050565b60608142811015610c285760405162461bcd60e51b81526004016101fe90613de8565b610c867f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506129ea92505050565b9150868260018451610c989190613ed1565b81518110610ca857610ca8613ee8565b60200260200101511015610cce5760405162461bcd60e51b81526004016101fe90613f52565b610ce4868660008181106108eb576108eb613ee8565b610ad082878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612d77915050565b60608142811015610d465760405162461bcd60e51b81526004016101fe90613de8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168686610d7d600182613ed1565b818110610d8c57610d8c613ee8565b9050602002016020810190610da19190613efe565b6001600160a01b031614610dc75760405162461bcd60e51b81526004016101fe90613f1b565b610e257f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612fc192505050565b91508682600081518110610e3b57610e3b613ee8565b602002602001015111156108d55760405162461bcd60e51b81526004016101fe90613fda565b600080610ed07f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050600086610edf578b610ee3565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610f1e903390309086908e908d908d908d90600401613f99565b600060405180830381600087803b158015610f3857600080fd5b505af1158015610f4c573d6000803e3d6000fd5b50505050610f5e8d8d8d8d8d8d611987565b9d9c50505050505050505050505050565b8042811015610f905760405162461bcd60e51b81526004016101fe90613de8565b61102185856000818110610fa657610fa6613ee8565b9050602002016020810190610fbb9190613efe565b3361101b7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289896000818110610ff357610ff3613ee8565b90506020020160208101906110089190613efe565b8a8a600181811061096057610960613ee8565b8a612c1d565b60008585611030600182613ed1565b81811061103f5761103f613ee8565b90506020020160208101906110549190613efe565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa15801561109c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c0919061401d565b9050611100868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250613112915050565b8681878761110f600182613ed1565b81811061111e5761111e613ee8565b90506020020160208101906111339190613efe565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a08231906024015b602060405180830381865afa15801561117c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a0919061401d565b6111aa9190613ed1565b10156111c85760405162461bcd60e51b81526004016101fe90613f52565b5050505050505050565b60006112008484847f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b949350505050565b80428110156112295760405162461bcd60e51b81526004016101fe90613de8565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168585611260600182613ed1565b81811061126f5761126f613ee8565b90506020020160208101906112849190613efe565b6001600160a01b0316146112aa5760405162461bcd60e51b81526004016101fe90613f1b565b6112c085856000818110610fa657610fa6613ee8565b6112fe858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613112915050565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316906370a0823190602401602060405180830381865afa158015611365573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611389919061401d565b9050868110156113ab5760405162461bcd60e51b81526004016101fe90613f52565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561140d57600080fd5b505af1158015611421573d6000803e3d6000fd5b505050506111c88482612928565b606081428110156114525760405162461bcd60e51b81526004016101fe90613de8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168686600081811061148f5761148f613ee8565b90506020020160208101906114a49190613efe565b6001600160a01b0316146114ca5760405162461bcd60e51b81526004016101fe90613f1b565b6115287f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506129ea92505050565b915086826001845161153a9190613ed1565b8151811061154a5761154a613ee8565b602002602001015110156115705760405162461bcd60e51b81526004016101fe90613f52565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0836000815181106115b2576115b2613ee8565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156115e557600080fd5b505af11580156115f9573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb6116647f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289896000818110610ff357610ff3613ee8565b8460008151811061167757611677613ee8565b60200260200101516040518363ffffffff1660e01b81526004016116b09291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af11580156116cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f39190614036565b61170f5760405162461bcd60e51b81526004016101fe90614053565b61174e82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612d77915050565b5095945050505050565b60008084116117b95760405162461bcd60e51b815260206004820152602760248201527f537761707348656c7065723a20494e53554646494349454e545f4f555450555460448201526617d05353d5539560ca1b60648201526084016101fe565b6000831180156117c95750600082115b6117e55760405162461bcd60e51b81526004016101fe90613e1f565b60006117f18585613e78565b6117fd906103e8613e78565b9050600061180b8685613ed1565b611817906103e5613e78565b90506118238183613eaf565b61182e906001613e97565b9695505050505050565b6060814281101561185b5760405162461bcd60e51b81526004016101fe90613de8565b6118b97f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612fc192505050565b915086826000815181106118cf576118cf613ee8565b60200260200101511115610cce5760405162461bcd60e51b81526004016101fe90613fda565b60008084116119465760405162461bcd60e51b815260206004820181905260248201527f537761707348656c7065723a20494e53554646494349454e545f414d4f554e5460448201526064016101fe565b6000831180156119565750600082115b6119725760405162461bcd60e51b81526004016101fe90613e1f565b8261197d8386613e78565b6112009190613eaf565b600081428110156119aa5760405162461bcd60e51b81526004016101fe90613de8565b6119d9887f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28989893089611e1d565b6040516370a0823160e01b8152306004820152909350611a529150899086906001600160a01b038316906370a0823190602401602060405180830381865afa158015611a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4d919061401d565b6127dd565b604051632e1a7d4d60e01b8152600481018390527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611ab457600080fd5b505af1158015611ac8573d6000803e3d6000fd5b50505050610ad08483612928565b8042811015611af75760405162461bcd60e51b81526004016101fe90613de8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031685856000818110611b3457611b34613ee8565b9050602002016020810190611b499190613efe565b6001600160a01b031614611b6f5760405162461bcd60e51b81526004016101fe90613f1b565b60003490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611bcf57600080fd5b505af1158015611be3573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb611c4e7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289896000818110610ff357610ff3613ee8565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611c9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cbf9190614036565b611cdb5760405162461bcd60e51b81526004016101fe90614053565b60008686611cea600182613ed1565b818110611cf957611cf9613ee8565b9050602002016020810190611d0e9190613efe565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611d56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7a919061401d565b9050611dba878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613112915050565b87818888611dc9600182613ed1565b818110611dd857611dd8613ee8565b9050602002016020810190611ded9190613efe565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a082319060240161115f565b6000808242811015611e415760405162461bcd60e51b81526004016101fe90613de8565b6000611e8f7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28c8c7f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050611e9d8133838c612c1d565b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015611ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0d919061408a565b915091506000611f1d8e8e61340d565b509050806001600160a01b03168e6001600160a01b031614611f40578183611f43565b82825b90975095508a871015611f685760405162461bcd60e51b81526004016101fe906140ae565b89861015611f885760405162461bcd60e51b81526004016101fe906140f0565b505050505097509795505050505050565b6060610b087f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e284846129ea565b60008060006120377f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050600087612046578c61204a565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90612085903390309086908f908e908e908e90600401613f99565b600060405180830381600087803b15801561209f57600080fd5b505af11580156120b3573d6000803e3d6000fd5b505050506120c58e8e8e8e8e8e6105be565b9350935050509a509a98505050505050505050565b600080600083428110156121005760405162461bcd60e51b81526004016101fe90613de8565b61210e8c8c8c8c8c8c6134f6565b909450925060006121617f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28e8e7f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b905061216f8d338388612c1d565b61217b8c338387612c1d565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af11580156121c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e7919061401d565b92505050985098509895505050505050565b6000806000834281101561221f5760405162461bcd60e51b81526004016101fe90613de8565b61224d8a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b348c8c6134f6565b909450925060006122c07f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b90506122ce8b338388612c1d565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561232957600080fd5b505af115801561233d573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb925060440190506020604051808303816000875af11580156123b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d69190614036565b6123f25760405162461bcd60e51b81526004016101fe90614053565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af115801561243a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245e919061401d565b9250833411156124745761247433853403612928565b505096509650969350505050565b606081428110156124a55760405162461bcd60e51b81526004016101fe90613de8565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316868660008181106124e2576124e2613ee8565b90506020020160208101906124f79190613efe565b6001600160a01b03161461251d5760405162461bcd60e51b81526004016101fe90613f1b565b61257b7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e288888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612fc192505050565b9150348260008151811061259157612591613ee8565b602002602001015111156125b75760405162461bcd60e51b81526004016101fe90613fda565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0836000815181106125f9576125f9613ee8565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561262c57600080fd5b505af1158015612640573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663a9059cbb6126ab7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e289896000818110610ff357610ff3613ee8565b846000815181106126be576126be613ee8565b60200260200101516040518363ffffffff1660e01b81526004016126f79291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015612716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273a9190614036565b6127565760405162461bcd60e51b81526004016101fe90614053565b61279582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612d77915050565b816000815181106127a8576127a8613ee8565b602002602001015134111561174e5761174e33836000815181106127ce576127ce613ee8565b60200260200101513403612928565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291516000928392871691612869919061415e565b6000604051808303816000865af19150503d80600081146128a6576040519150601f19603f3d011682016040523d82523d6000602084013e6128ab565b606091505b50915091508180156128d55750805115806128d55750808060200190518101906128d59190614036565b6129215760405162461bcd60e51b815260206004820152601c60248201527f537761707348656c7065723a205452414e534645525f4641494c45440000000060448201526064016101fe565b5050505050565b604080516000808252602082019092526001600160a01b038416908390604051612952919061415e565b60006040518083038185875af1925050503d806000811461298f576040519150601f19603f3d011682016040523d82523d6000602084013e612994565b606091505b50509050806129e55760405162461bcd60e51b815260206004820181905260248201527f537761707348656c7065723a204554485f5452414e534645525f4641494c454460448201526064016101fe565b505050565b6060600282511015612a0e5760405162461bcd60e51b81526004016101fe90613f1b565b815167ffffffffffffffff811115612a2857612a28613a02565b604051908082528060200260200182016040528015612a51578160200160208202803683370190505b5090508281600081518110612a6857612a68613ee8565b60200260200101818152505060005b60018351612a859190613ed1565b811015612b3d57600080612ad887868581518110612aa557612aa5613ee8565b602002602001015187866001612abb9190613e97565b81518110612acb57612acb613ee8565b6020026020010151613769565b91509150612b00848481518110612af157612af1613ee8565b602002602001015183836106b1565b84612b0c856001613e97565b81518110612b1c57612b1c613ee8565b60200260200101818152505050508080612b359061417a565b915050612a77565b509392505050565b6000806000846001600160a01b0316866001600160a01b031610612b6a578486612b6d565b85855b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b166034820152919350915060009060480160408051601f19818403018152908290528051602090910120733d602d80600a3d3981f3363d3d373d3d3d363d7360601b8252606096871b60148301526f5af43d82803e903d91602b57fd5bf3ff60801b60288301529890951b603886015250505050604c81019390935250506037808220606c830152605591012090565b600080856001600160a01b03166040518060600160405280602581526020016142746025913980516020909101206040516001600160a01b038089166024830152871660448201526064810186905260840160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612cad919061415e565b6000604051808303816000865af19150503d8060008114612cea576040519150601f19603f3d011682016040523d82523d6000602084013e612cef565b606091505b5091509150818015612d19575080511580612d19575080806020019051810190612d199190614036565b612d6f5760405162461bcd60e51b815260206004820152602160248201527f537761707348656c7065723a205452414e534645525f46524f4d5f4641494c456044820152601160fa1b60648201526084016101fe565b505050505050565b60005b60018351612d889190613ed1565b811015612fbb57600080848381518110612da457612da4613ee8565b602002602001015185846001612dba9190613e97565b81518110612dca57612dca613ee8565b6020026020010151915091506000612de2838361340d565b509050600087612df3866001613e97565b81518110612e0357612e03613ee8565b60200260200101519050600080836001600160a01b0316866001600160a01b031614612e3157826000612e35565b6000835b91509150600060028a51612e499190613ed1565b8810612e555788612ec4565b612ec47f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2878c612e868c6002613e97565b81518110612e9657612e96613ee8565b60200260200101517f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050612f127f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e288887f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015612f4f576020820181803683370190505b506040518563ffffffff1660e01b8152600401612f6f9493929190614193565b600060405180830381600087803b158015612f8957600080fd5b505af1158015612f9d573d6000803e3d6000fd5b50505050505050505050508080612fb39061417a565b915050612d7a565b50505050565b6060600282511015612fe55760405162461bcd60e51b81526004016101fe90613f1b565b815167ffffffffffffffff811115612fff57612fff613a02565b604051908082528060200260200182016040528015613028578160200160208202803683370190505b50905082816001835161303b9190613ed1565b8151811061304b5761304b613ee8565b6020026020010181815250506000600183516130679190613ed1565b90505b8015612b3d576000806130ad8786613083600187613ed1565b8151811061309357613093613ee8565b6020026020010151878681518110612acb57612acb613ee8565b915091506130d58484815181106130c6576130c6613ee8565b60200260200101518383611758565b846130e1600186613ed1565b815181106130f1576130f1613ee8565b6020026020010181815250505050808061310a906141e3565b91505061306a565b60005b600183516131239190613ed1565b8110156129e55760008084838151811061313f5761313f613ee8565b6020026020010151858460016131559190613e97565b8151811061316557613165613ee8565b602002602001015191509150600061317d838361340d565b50905060006131ce7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e285857f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132389190614211565b506001600160701b031691506001600160701b03169150600080876001600160a01b03168a6001600160a01b031614613272578284613275565b83835b6040516370a0823160e01b81526001600160a01b038a8116600483015292945090925083918c16906370a0823190602401602060405180830381865afa1580156132c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132e7919061401d565b6132f19190613ed1565b95506132fe8683836106b1565b945050505050600080856001600160a01b0316886001600160a01b0316146133285782600061332c565b6000835b91509150600060028c516133409190613ed1565b8a1061334c578a61337d565b61337d7f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2898e612e868e6002613e97565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f906133bf9086908690869060248101614193565b600060405180830381600087803b1580156133d957600080fd5b505af11580156133ed573d6000803e3d6000fd5b5050505050505050505050505080806134059061417a565b915050613115565b600080826001600160a01b0316846001600160a01b0316036134715760405162461bcd60e51b815260206004820181905260248201527f537761707348656c7065723a204944454e544943414c5f41444452455353455360448201526064016101fe565b826001600160a01b0316846001600160a01b031610613491578284613494565b83835b90925090506001600160a01b0382166134ef5760405162461bcd60e51b815260206004820152601960248201527f537761707348656c7065723a205a45524f5f414444524553530000000000000060448201526064016101fe565b9250929050565b60405163e6a4390560e01b81526001600160a01b0387811660048301528681166024830152600091829182917f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e29091169063e6a4390590604401602060405180830381865afa15801561356d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135919190614256565b6001600160a01b031603613635576040516364e329cb60e11b81526001600160a01b03898116600483015288811660248301527f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e2169063c9c65396906044016020604051808303816000875af115801561360f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136339190614256565b505b6000806136637f000000000000000000000000ee3e9e46e34a27dc755a63e2849c9913ee1a06e28b8b613769565b91509150816000148015613675575080155b1561368757878793509350505061375e565b60006136948984846118f5565b90508781116136ca57858110156136bd5760405162461bcd60e51b81526004016101fe906140f0565b889450925061375e915050565b60006136d78984866118f5565b9050898111156137355760405162461bcd60e51b815260206004820152602360248201527f5377617073526f757465723a20494e56414c49445f444553495245445f414d4f60448201526215539560ea1b60648201526084016101fe565b878110156137555760405162461bcd60e51b81526004016101fe906140ae565b94508793505050505b965096945050505050565b6000806000613778858561340d565b5090506000806137aa8888887f0000000000000000000000007290367aa694703220516a35e68e3d339ee7d193612b45565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156137e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380b9190614211565b506001600160701b031691506001600160701b03169150826001600160a01b0316876001600160a01b031614613842578082613845565b81815b90999098509650505050505050565b6001600160a01b038116811461386957600080fd5b50565b803561387781613854565b919050565b60008060008060008060c0878903121561389557600080fd5b86356138a081613854565b955060208701359450604087013593506060870135925060808701356138c581613854565b8092505060a087013590509295509295509295565b6000806000606084860312156138ef57600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261391857600080fd5b50813567ffffffffffffffff81111561393057600080fd5b6020830191508360208260051b85010111156134ef57600080fd5b60008060008060008060a0878903121561396457600080fd5b8635955060208701359450604087013567ffffffffffffffff81111561398957600080fd5b61399589828a01613906565b90955093505060608701356139a981613854565b80925050608087013590509295509295509295565b6020808252825182820181905260009190848201906040850190845b818110156139f6578351835292840192918401916001016139da565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613a2b57600080fd5b8235915060208084013567ffffffffffffffff80821115613a4b57600080fd5b818601915086601f830112613a5f57600080fd5b813581811115613a7157613a71613a02565b8060051b604051601f19603f83011681018181108582111715613a9657613a96613a02565b604052918252848201925083810185019189831115613ab457600080fd5b938501935b82851015613ad957613aca8561386c565b84529385019392850192613ab9565b8096505050505050509250929050565b801515811461386957600080fd5b803560ff8116811461387757600080fd5b60008060008060008060008060008060006101608c8e031215613b2a57600080fd5b8b35613b3581613854565b9a5060208c0135613b4581613854565b995060408c0135985060608c0135975060808c0135965060a08c0135613b6a81613854565b955060c08c0135945060e08c0135613b8181613ae9565b9350613b906101008d01613af7565b92506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000806000806000806000806101408b8d031215613bd257600080fd5b8a35613bdd81613854565b995060208b0135985060408b0135975060608b0135965060808b0135613c0281613854565b955060a08b0135945060c08b0135613c1981613ae9565b9350613c2760e08c01613af7565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080600060608486031215613c5d57600080fd5b8335613c6881613854565b92506020840135613c7881613854565b91506040840135613c8881613854565b809150509250925092565b600080600080600060808688031215613cab57600080fd5b85359450602086013567ffffffffffffffff811115613cc957600080fd5b613cd588828901613906565b9095509350506040860135613ce981613854565b949793965091946060013592915050565b600080600080600080600060e0888a031215613d1557600080fd5b8735613d2081613854565b96506020880135613d3081613854565b955060408801359450606088013593506080880135925060a0880135613d5581613854565b8092505060c0880135905092959891949750929550565b600080600080600080600080610100898b031215613d8957600080fd5b8835613d9481613854565b97506020890135613da481613854565b965060408901359550606089013594506080890135935060a0890135925060c0890135613dd081613854565b8092505060e089013590509295985092959890939650565b6020808252601d908201527f5377617073526f757465723a20444541444c494e455f45585049524544000000604082015260600190565b60208082526023908201527f537761707348656c7065723a20494e53554646494349454e545f4c495155494460408201526249545960e81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613e9257613e92613e62565b500290565b60008219821115613eaa57613eaa613e62565b500190565b600082613ecc57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015613ee357613ee3613e62565b500390565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613f1057600080fd5b8135610b0881613854565b60208082526019908201527f5377617073526f757465723a20494e56414c49445f5041544800000000000000604082015260600190565b60208082526027908201527f5377617073526f757465723a20494e53554646494349454e545f4f555450555460408201526617d05353d5539560ca1b606082015260800190565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b60208082526023908201527f5377617073526f757465723a204558434553534956455f494e5055545f414d4f60408201526215539560ea1b606082015260800190565b60006020828403121561402f57600080fd5b5051919050565b60006020828403121561404857600080fd5b8151610b0881613ae9565b6020808252601a908201527f5377617073526f757465723a205452414e534645525f4641494c000000000000604082015260600190565b6000806040838503121561409d57600080fd5b505080516020909101519092909150565b60208082526022908201527f5377617073526f757465723a20494e53554646494349454e545f415f414d4f55604082015261139560f21b606082015260800190565b60208082526022908201527f5377617073526f757465723a20494e53554646494349454e545f425f414d4f55604082015261139560f21b606082015260800190565b60005b8381101561414d578181015183820152602001614135565b83811115612fbb5750506000910152565b60008251614170818460208701614132565b9190910192915050565b60006001820161418c5761418c613e62565b5060010190565b84815283602082015260018060a01b038316604082015260806060820152600082518060808401526141cc8160a0850160208701614132565b601f01601f19169190910160a00195945050505050565b6000816141f2576141f2613e62565b506000190190565b80516001600160701b038116811461387757600080fd5b60008060006060848603121561422657600080fd5b61422f846141fa565b925061423d602085016141fa565b9150604084015163ffffffff81168114613c8857600080fd5b60006020828403121561426857600080fd5b8151610b088161385456fe7472616e7366657246726f6d28616464726573732c616464726573732c75696e7432353629a26469706673582212207dea02283b88a465792995de6238b8f85659e5f689fb350f51f3ac2a20d9229d64736f6c634300080e0033

Verified Source Code Partial Match

Compiler: v0.8.14+commit.80d49f37 EVM: london Optimization: Yes (200 runs)
IWETH.sol 22 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

interface IWETH {

    function deposit()
        external
        payable;

    function transfer(
        address _to,
        uint256 _value
    )
        external
        returns (bool);

    function withdraw(
        uint256
    )
        external;
}
IERC20.sol 13 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

interface IERC20 {

    function balanceOf(
        address _owner
    )
        external
        view
        returns (uint256);
}
ISwapsPair.sol 84 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

import "./ISwapsERC20.sol";

interface ISwapsPair is ISwapsERC20 {

    function MINIMUM_LIQUIDITY()
        external
        pure
        returns (uint256);

    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 (uint256);

    function price1CumulativeLast()
        external
        view
        returns (uint256);

    function kLast()
        external
        view
        returns (uint256);

    function mint(
        address _to
    )
        external
        returns (uint256 liquidity);

    function burn(
        address _to
    )
        external
        returns (
            uint256 amount0,
            uint256 amount1
        );

    function swap(
        uint256 _amount0Out,
        uint256 _amount1Out,
        address _to,
        bytes calldata _data
    )
        external;

    function skim()
        external;

    function initialize(
        address,
        address
    )
        external;
}
ISwapsERC20.sol 91 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

interface ISwapsERC20 {

    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 (uint256);

    function balanceOf(
        address _owner
    )
        external
        view
        returns (uint256);

    function allowance(
        address _owner,
        address _spender
    )
        external
        view
        returns (uint256);

    function approve(
        address _spender,
        uint256 _value
    )
        external
        returns (bool);

    function transfer(
        address _to,
        uint256 _value
    )
        external
        returns (bool);

    function transferFrom(
        address _from,
        address _to,
        uint256 _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 (uint256);

    function permit(
        address _owner,
        address _spender,
        uint256 _value,
        uint256 _deadline,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    )
        external;
}
SwapsHelper.sol 229 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

contract SwapsHelper {

    uint256 constant UINT256_MAX = type(uint256).max;
    address constant ZERO_ADDRESS = address(0);

    function sortTokens(
        address _tokenA,
        address _tokenB
    )
        internal
        pure
        returns (
            address token0,
            address token1
        )
    {
        require(
            _tokenA != _tokenB,
            "SwapsHelper: IDENTICAL_ADDRESSES"
        );

        (token0, token1) = _tokenA < _tokenB
            ? (_tokenA, _tokenB)
            : (_tokenB, _tokenA);

        require(
            token0 != ZERO_ADDRESS,
            "SwapsHelper: ZERO_ADDRESS"
        );
    }

    function quote(
        uint256 _amountA,
        uint256 _reserveA,
        uint256 _reserveB
    )
        public
        pure
        returns (uint256 amountB)
    {
        require(
            _amountA > 0,
            "SwapsHelper: INSUFFICIENT_AMOUNT"
        );

        require(
            _reserveA > 0 && _reserveB > 0,
            "SwapsHelper: INSUFFICIENT_LIQUIDITY"
        );

        amountB = _amountA
            * _reserveB
            / _reserveA;
    }

    function getAmountOut(
        uint256 _amountIn,
        uint256 _reserveIn,
        uint256 _reserveOut
    )
        public
        pure
        returns (uint256 amountOut)
    {
        require(
            _amountIn > 0,
            "SwapsHelper: INSUFFICIENT_INPUT_AMOUNT"
        );

        require(
            _reserveIn > 0 && _reserveOut > 0,
            "SwapsHelper: INSUFFICIENT_LIQUIDITY"
        );

        uint256 amountInWithFee = _amountIn * 997;
        uint256 numerator = amountInWithFee * _reserveOut;
        uint256 denominator = _reserveIn * 1000 + amountInWithFee;

        amountOut = numerator / denominator;
    }

    function getAmountIn(
        uint256 _amountOut,
        uint256 _reserveIn,
        uint256 _reserveOut
    )
        public
        pure
        returns (uint256 amountIn)
    {
        require(
            _amountOut > 0,
            "SwapsHelper: INSUFFICIENT_OUTPUT_AMOUNT"
        );

        require(
            _reserveIn > 0 &&
            _reserveOut > 0,
            "SwapsHelper: INSUFFICIENT_LIQUIDITY"
        );

        uint256 numerator = _reserveIn * _amountOut * 1000;
        uint256 denominator = (_reserveOut - _amountOut) * 997;

        amountIn = numerator / denominator + 1;
    }


    bytes4 constant TRANSFER = bytes4(
        keccak256(
            bytes(
                "transfer(address,uint256)"
            )
        )
    );

    bytes4 constant TRANSFER_FROM = bytes4(
        keccak256(
            bytes(
                "transferFrom(address,address,uint256)"
            )
        )
    );

    function _safeTransfer(
        address _token,
        address _to,
        uint256 _value
    )
        internal
    {
        (bool success, bytes memory data) = _token.call(
            abi.encodeWithSelector(
                TRANSFER,
                _to,
                _value
            )
        );

        require(
            success && (
                data.length == 0 || abi.decode(
                    data, (bool)
                )
            ),
            "SwapsHelper: TRANSFER_FAILED"
        );
    }

    function _safeTransferFrom(
        address _token,
        address _from,
        address _to,
        uint256 _value
    )
        internal
    {
        (bool success, bytes memory data) = _token.call(
            abi.encodeWithSelector(
                TRANSFER_FROM,
                _from,
                _to,
                _value
            )
        );

        require(
            success && (
                data.length == 0 || abi.decode(
                    data, (bool)
                )
            ),
            "SwapsHelper: TRANSFER_FROM_FAILED"
        );
    }

    function _safeTransferETH(
        address to,
        uint256 value
    )
        internal
    {
        (bool success,) = to.call{
            value: value
        }(new bytes(0));

        require(
            success,
            "SwapsHelper: ETH_TRANSFER_FAILED"
        );
    }

    function _pairFor(
        address _factory,
        address _tokenA,
        address _tokenB,
        address _implementation
    )
        internal
        pure
        returns (address predicted)
    {
        (address token0, address token1) = _tokenA < _tokenB
            ? (_tokenA, _tokenB)
            : (_tokenB, _tokenA);

        bytes32 salt = keccak256(
            abi.encodePacked(
                token0,
                token1
            )
        );

        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, _implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
            mstore(add(ptr, 0x38), shl(0x60, _factory))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }
}
SwapsRouter.sol 1235 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

import "./IWETH.sol";
import "./IERC20.sol";
import "./ISwapsFactory.sol";
import "./ISwapsPair.sol";
import "./SwapsHelper.sol";

contract SwapsRouter is SwapsHelper {

    address public immutable FACTORY;
    address public immutable WETH;
    address public immutable PAIR;

    modifier ensure(
        uint256 _deadline
    ) {
        require(
            _deadline >= block.timestamp,
            "SwapsRouter: DEADLINE_EXPIRED"
        );
        _;
    }

    constructor(
        address _factory,
        address _WETH
    ) {
        FACTORY = _factory;
        WETH = _WETH;
        PAIR = ISwapsFactory(_factory).cloneTarget();
    }

    receive()
        external
        payable
    {
        require(
            msg.sender == WETH,
            "SwapsRouter: INVALID_SENDER"
        );
    }

    function _addLiquidity(
        address _tokenA,
        address _tokenB,
        uint256 _amountADesired,
        uint256 _amountBDesired,
        uint256 _amountAMin,
        uint256 _amountBMin
    )
        internal
        returns (uint256, uint256)
    {
        if (ISwapsFactory(FACTORY).getPair(_tokenA, _tokenB) == ZERO_ADDRESS) {
            ISwapsFactory(FACTORY).createPair(
                _tokenA,
                _tokenB
            );
        }

        (
            uint256 reserveA,
            uint256 reserveB

        ) = getReserves(
            FACTORY,
            _tokenA,
            _tokenB
        );

        if (reserveA == 0 && reserveB == 0) {
            return (
                _amountADesired,
                _amountBDesired
            );
        }

        uint256 amountBOptimal = quote(
            _amountADesired,
            reserveA,
            reserveB
        );

        if (amountBOptimal <= _amountBDesired) {

            require(
                amountBOptimal >= _amountBMin,
                "SwapsRouter: INSUFFICIENT_B_AMOUNT"
            );

            return (
                _amountADesired,
                amountBOptimal
            );
        }

        uint256 amountAOptimal = quote(
            _amountBDesired,
            reserveB,
            reserveA
        );

        require(
            amountAOptimal <= _amountADesired,
            "SwapsRouter: INVALID_DESIRED_AMOUNT"
        );

        require(
            amountAOptimal >= _amountAMin,
            "SwapsRouter: INSUFFICIENT_A_AMOUNT"
        );

        return (
            amountAOptimal,
            _amountBDesired
        );
    }

    function addLiquidity(
        address _tokenA,
        address _tokenB,
        uint256 _amountADesired,
        uint256 _amountBDesired,
        uint256 _amountAMin,
        uint256 _amountBMin,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        )
    {
        (amountA, amountB) = _addLiquidity(
            _tokenA,
            _tokenB,
            _amountADesired,
            _amountBDesired,
            _amountAMin,
            _amountBMin
        );

        address pair = _pairFor(
            FACTORY,
            _tokenA,
            _tokenB,
            PAIR
        );

        _safeTransferFrom(
            _tokenA,
            msg.sender,
            pair,
            amountA
        );

        _safeTransferFrom(
            _tokenB,
            msg.sender,
            pair,
            amountB
        );

        liquidity = ISwapsPair(pair).mint(_to);
    }

    function addLiquidityETH(
        address _token,
        uint256 _amountTokenDesired,
        uint256 _amountTokenMin,
        uint256 _amountETHMin,
        address _to,
        uint256 _deadline
    )
        external
        payable
        ensure(_deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH) = _addLiquidity(
            _token,
            WETH,
            _amountTokenDesired,
            msg.value,
            _amountTokenMin,
            _amountETHMin
        );

        address pair = _pairFor(
            FACTORY,
            _token,
            WETH,
            PAIR
        );

        _safeTransferFrom(
            _token,
            msg.sender,
            pair,
            amountToken
        );

        IWETH(WETH).deposit{
            value: amountETH
        }();

        require(
            IWETH(WETH).transfer(
                pair,
                amountETH
            ),
            "SwapsRouter: TRANSFER_FAIL"
        );

        liquidity = ISwapsPair(pair).mint(_to);

        if (msg.value > amountETH) {
            unchecked {
                _safeTransferETH(
                    msg.sender,
                    msg.value - amountETH
                );
            }
        }
    }

    function removeLiquidity(
        address _tokenA,
        address _tokenB,
        uint256 _liquidity,
        uint256 _amountAMin,
        uint256 _amountBMin,
        address _to,
        uint256 _deadline
    )
        public
        ensure(_deadline)
        returns (
            uint256 amountA,
            uint256 amountB
        )
    {
        address pair = _pairFor(
            FACTORY,
            _tokenA,
            _tokenB,
            PAIR
        );

        _safeTransferFrom(
            pair,
            msg.sender,
            pair,
            _liquidity
        );

        (
            uint256 amount0,
            uint256 amount1

        ) = ISwapsPair(pair).burn(_to);

        (address token0,) = sortTokens(
            _tokenA,
            _tokenB
        );

        (amountA, amountB) = _tokenA == token0
            ? (amount0, amount1)
            : (amount1, amount0);

        require(
            amountA >= _amountAMin,
            "SwapsRouter: INSUFFICIENT_A_AMOUNT"
        );

        require(
            amountB >= _amountBMin,
            "SwapsRouter: INSUFFICIENT_B_AMOUNT"
        );
    }

    function removeLiquidityETH(
        address _token,
        uint256 _liquidity,
        uint256 _amountTokenMin,
        uint256 _amountETHMin,
        address _to,
        uint256 _deadline
    )
        public
        ensure(_deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH
        )
    {
        (amountToken, amountETH) = removeLiquidity(
            _token,
            WETH,
            _liquidity,
            _amountTokenMin,
            _amountETHMin,
            address(this),
            _deadline
        );

        _safeTransfer(
            _token,
            _to,
            amountToken
        );

        IWETH(WETH).withdraw(
            amountETH
        );

        _safeTransferETH(
            _to,
            amountETH
        );
    }

    function removeLiquidityWithPermit(
        address _tokenA,
        address _tokenB,
        uint256 _liquidity,
        uint256 _amountAMin,
        uint256 _amountBMin,
        address _to,
        uint256 _deadline,
        bool _approveMax,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    )
        external
        returns (uint256, uint256)
    {
        address pair = _pairFor(
            FACTORY,
            _tokenA,
            _tokenB,
            PAIR
        );

        uint256 value = _approveMax
            ? UINT256_MAX
            : _liquidity;

        ISwapsPair(pair).permit(
            msg.sender,
            address(this),
            value,
            _deadline,
            _v,
            _r,
            _s
        );

        return removeLiquidity(
            _tokenA,
            _tokenB,
            _liquidity,
            _amountAMin,
            _amountBMin,
            _to,
            _deadline
        );
    }

    function removeLiquidityETHWithPermit(
        address _token,
        uint256 _liquidity,
        uint256 _amountTokenMin,
        uint256 _amountETHMin,
        address _to,
        uint256 _deadline,
        bool _approveMax,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    )
        external
        returns (uint256, uint256)
    {
        address pair = _pairFor(
            FACTORY,
            _token,
            WETH,
            PAIR
        );

        uint256 value = _approveMax
            ? UINT256_MAX
            : _liquidity;

        ISwapsPair(pair).permit(
            msg.sender,
            address(this),
            value,
            _deadline,
            _v,
            _r,
            _s
        );

        return removeLiquidityETH(
            _token,
            _liquidity,
            _amountTokenMin,
            _amountETHMin,
            _to,
            _deadline
        );
    }

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address _token,
        uint256 _liquidity,
        uint256 _amountTokenMin,
        uint256 _amountETHMin,
        address _to,
        uint256 _deadline
    )
        public
        ensure(_deadline)
        returns (uint256 amountETH)
    {
        (, amountETH) = removeLiquidity(
            _token,
            WETH,
            _liquidity,
            _amountTokenMin,
            _amountETHMin,
            address(this),
            _deadline
        );

        _safeTransfer(
            _token,
            _to,
            IERC20(_token).balanceOf(address(this))
        );

        IWETH(WETH).withdraw(
            amountETH
        );

        _safeTransferETH(
            _to,
            amountETH
        );
    }

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address _token,
        uint256 _liquidity,
        uint256 _amountTokenMin,
        uint256 _amountETHMin,
        address _to,
        uint256 _deadline,
        bool _approveMax,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    )
        external
        returns (uint256 amountETH)
    {
        address pair = _pairFor(
            FACTORY,
            _token,
            WETH,
            PAIR
        );

        uint256 value = _approveMax
            ? UINT256_MAX
            : _liquidity;

        ISwapsPair(pair).permit(
            msg.sender,
            address(this),
            value,
            _deadline,
            _v,
            _r,
            _s
        );

        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
            _token,
            _liquidity,
            _amountTokenMin,
            _amountETHMin,
            _to,
            _deadline
        );
    }

    function _swap(
        uint256[] memory _amounts,
        address[] memory _path,
        address _to
    )
        internal
    {
        for (uint256 i; i < _path.length - 1; i++) {

            (address input, address output) = (
                _path[i],
                _path[i + 1]
            );

            (address token0,) = sortTokens(
                input,
                output
            );

            uint256 amountOut = _amounts[i + 1];

            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint(0), amountOut)
                : (amountOut, uint(0));

            address to = i < _path.length - 2
                ? _pairFor(FACTORY, output, _path[i + 2], PAIR)
                : _to;

            ISwapsPair(
                _pairFor(
                    FACTORY,
                    input,
                    output,
                    PAIR
                )
            ).swap(
                amount0Out,
                amount1Out,
                to,
                new bytes(0)
            );
        }
    }

    function swapExactTokensForTokens(
        uint256 _amountIn,
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        amounts = _getAmountsOut(
            FACTORY,
            _amountIn,
            _path
        );

        require(
            amounts[amounts.length - 1] >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );

        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            amounts[0]
        );

        _swap(
            amounts,
            _path,
            _to
        );
    }

    function swapTokensForExactTokens(
        uint256 _amountOut,
        uint256 _amountInMax,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        amounts = _getAmountsIn(
            FACTORY,
            _amountOut,
            _path
        );

        require(
            amounts[0] <= _amountInMax,
            "SwapsRouter: EXCESSIVE_INPUT_AMOUNT"
        );

        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            amounts[0]
        );

        _swap(
            amounts,
            _path,
            _to
        );
    }

    function swapExactETHForTokens(
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        payable
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        require(
            _path[0] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = _getAmountsOut(
            FACTORY,
            msg.value,
            _path
        );

        require(
            amounts[amounts.length - 1] >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );

        IWETH(WETH).deposit{
            value: amounts[0]
        }();

        require(
            IWETH(WETH).transfer(
                _pairFor(
                    FACTORY,
                    _path[0],
                    _path[1],
                    PAIR
                ),
                amounts[0]
            ),
            "SwapsRouter: TRANSFER_FAIL"
        );

        _swap(
            amounts,
            _path,
            _to
        );
    }

    function swapTokensForExactETH(
        uint256 _amountOut,
        uint256 _amountInMax,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        require(
            _path[_path.length - 1] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = _getAmountsIn(
            FACTORY,
            _amountOut,
            _path
        );

        require(
            amounts[0] <= _amountInMax,
            "SwapsRouter: EXCESSIVE_INPUT_AMOUNT"
        );

        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            amounts[0]
        );

        _swap(
            amounts,
            _path,
            address(this)
        );

        IWETH(WETH).withdraw(
            amounts[amounts.length - 1]
        );

        _safeTransferETH(
            _to,
            amounts[amounts.length - 1]
        );
    }

    function swapExactTokensForETH(
        uint256 _amountIn,
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        require(
            _path[_path.length - 1] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = _getAmountsOut(
            FACTORY,
            _amountIn,
            _path
        );

        require(
            amounts[amounts.length - 1] >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );

        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            amounts[0]
        );

        _swap(
            amounts,
            _path,
            address(this)
        );

        IWETH(WETH).withdraw(
            amounts[amounts.length - 1]
        );

        _safeTransferETH(
            _to,
            amounts[amounts.length - 1]
        );
    }

    function swapETHForExactTokens(
        uint256 _amountOut,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        payable
        ensure(_deadline)
        returns (uint256[] memory amounts)
    {
        require(
            _path[0] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = _getAmountsIn(
            FACTORY,
            _amountOut,
            _path
        );

        require(
            amounts[0] <= msg.value,
            "SwapsRouter: EXCESSIVE_INPUT_AMOUNT"
        );

        IWETH(WETH).deposit{
            value: amounts[0]
        }();

        require(
            IWETH(WETH).transfer(
                _pairFor(
                    FACTORY,
                    _path[0],
                    _path[1],
                    PAIR
                ),
                amounts[0]
            ),
            "SwapsRouter: TRANSFER_FAIL"
        );

        _swap(
            amounts,
            _path,
            _to
        );

        if (msg.value > amounts[0]) {
            unchecked {
                _safeTransferETH(
                    msg.sender,
                    msg.value - amounts[0]
                );
            }
        }
    }

    function _swapSupportingFeeOnTransferTokens(
        address[] memory _path,
        address _to
    )
        internal
    {
        for (uint256 i; i < _path.length - 1; i++) {

            (address input, address output) = (
                _path[i],
                _path[i + 1]
            );

            (address token0,) = sortTokens(
                input,
                output
            );

            ISwapsPair pair = ISwapsPair(
                _pairFor(
                    FACTORY,
                    input,
                    output,
                    PAIR
                )
            );

            uint256 amountInput;
            uint256 amountOutput;

            {

            (
                uint256 reserve0,
                uint256 reserve1,

            ) = pair.getReserves();

            (uint256 reserveInput, uint256 reserveOutput) = input == token0
                ? (reserve0, reserve1)
                : (reserve1, reserve0);

            amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput;
            amountOutput = getAmountOut(
                amountInput,
                reserveInput,
                reserveOutput
            );

            }

            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint(0), amountOutput)
                : (amountOutput, uint(0));

            address to = i < _path.length - 2
                ? _pairFor(FACTORY, output, _path[i + 2], PAIR)
                : _to;

            pair.swap(
                amount0Out,
                amount1Out,
                to,
                new bytes(0)
            );
        }
    }

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 _amountIn,
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
    {
        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            _amountIn
        );

        uint256 balanceBefore = IERC20(_path[_path.length - 1]).balanceOf(_to);

        _swapSupportingFeeOnTransferTokens(
            _path,
            _to
        );

        require(
            IERC20(_path[_path.length - 1]).balanceOf(_to) - balanceBefore >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );
    }

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        payable
        ensure(_deadline)
    {
        require(
            _path[0] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        uint256 amountIn = msg.value;

        IWETH(WETH).deposit{
            value: amountIn
        }();

        require(
            IWETH(WETH).transfer(
                _pairFor(
                    FACTORY,
                    _path[0],
                    _path[1],
                    PAIR
                ),
                amountIn
            ),
            "SwapsRouter: TRANSFER_FAIL"
        );

        uint256 balanceBefore = IERC20(_path[_path.length - 1]).balanceOf(_to);

        _swapSupportingFeeOnTransferTokens(
            _path,
            _to
        );

        require(
            IERC20(_path[_path.length - 1]).balanceOf(_to) - balanceBefore >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 _amountIn,
        uint256 _amountOutMin,
        address[] calldata _path,
        address _to,
        uint256 _deadline
    )
        external
        ensure(_deadline)
    {
        require(
            _path[_path.length - 1] == WETH,
            "SwapsRouter: INVALID_PATH"
        );

        _safeTransferFrom(
            _path[0],
            msg.sender,
            _pairFor(
                FACTORY,
                _path[0],
                _path[1],
                PAIR
            ),
            _amountIn
        );

        _swapSupportingFeeOnTransferTokens(
            _path,
            address(this)
        );

        uint256 amountOut = IERC20(WETH).balanceOf(
            address(this)
        );

        require(
            amountOut >= _amountOutMin,
            "SwapsRouter: INSUFFICIENT_OUTPUT_AMOUNT"
        );

        IWETH(WETH).withdraw(
            amountOut
        );

        _safeTransferETH(
            _to,
            amountOut
        );
    }

    function pairFor(
        address _factory,
        address _tokenA,
        address _tokenB
    )
        external
        view
        returns (address predicted)
    {
        predicted = _pairFor(
            _factory,
            _tokenA,
            _tokenB,
            PAIR
        );
    }

    function getAmountsOut(
        uint256 _amountIn,
        address[] memory _path
    )
        external
        view
        returns (uint256[] memory amounts)
    {
        return _getAmountsOut(
            FACTORY,
            _amountIn,
            _path
        );
    }

    function getAmountsIn(
        uint256 _amountOut,
        address[] memory _path
    )
        external
        view
        returns (uint256[] memory amounts)
    {
        return _getAmountsIn(
            FACTORY,
            _amountOut,
            _path
        );
    }

    function getReserves(
        address _factory,
        address _tokenA,
        address _tokenB
    )
        internal
        view
        returns (
            uint256 reserveA,
            uint256 reserveB
        )
    {
        (address token0,) = sortTokens(
            _tokenA,
            _tokenB
        );

        (
            uint256 reserve0,
            uint256 reserve1,

        ) = ISwapsPair(
            _pairFor(
                _factory,
                _tokenA,
                _tokenB,
                PAIR
            )
        ).getReserves();

        (reserveA, reserveB) = _tokenA == token0
            ? (reserve0, reserve1)
            : (reserve1, reserve0);
    }

    function _getAmountsOut(
        address _factory,
        uint256 _amountIn,
        address[] memory _path
    )
        internal
        view
        returns (uint256[] memory amounts)
    {
        require(
            _path.length >= 2,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = new uint256[](
            _path.length
        );

        amounts[0] = _amountIn;

        for (uint256 i; i < _path.length - 1; i++) {

            (
                uint256 reserveIn,
                uint256 reserveOut

            ) = getReserves(
                _factory,
                _path[i],
                _path[i + 1]
            );

            amounts[i + 1] = getAmountOut(
                amounts[i],
                reserveIn,
                reserveOut
            );
        }
    }

    function _getAmountsIn(
        address _factory,
        uint256 _amountOut,
        address[] memory _path
    )
        internal
        view
        returns (uint256[] memory amounts)
    {
        require(
            _path.length >= 2,
            "SwapsRouter: INVALID_PATH"
        );

        amounts = new uint256[](
            _path.length
        );

        amounts[amounts.length - 1] = _amountOut;

        for (uint256 i = _path.length - 1; i > 0; i--) {

            (
                uint256 reserveIn,
                uint256 reserveOut

            ) = getReserves(
                _factory,
                _path[i - 1],
                _path[i]
            );

            amounts[i - 1] = getAmountIn(
                amounts[i],
                reserveIn,
                reserveOut
            );
        }
    }
}

contract RouterCodeCheck {

    function routerCodeHash()
        external
        pure
        returns (bytes32)
    {
        return keccak256(
            type(SwapsRouter).creationCode
        );
    }
}
ISwapsFactory.sol 56 lines
// SPDX-License-Identifier: BCOM

pragma solidity =0.8.14;

interface ISwapsFactory {

    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(uint256)
        external
        view
        returns (address pair);

    function allPairsLength()
        external
        view
        returns (uint256);

    function createPair(
        address _tokenA,
        address _tokenB
    )
        external
        returns (address pair);

    function setFeeTo(
        address
    )
        external;

    function setFeeToSetter(
        address
    )
        external;

    function cloneTarget()
        external
        view
        returns (address target);
}

Read Contract

FACTORY 0x2dd31000 → address
PAIR 0xace3a8a7 → address
WETH 0xad5c4648 → address
getAmountIn 0x85f8c259 → uint256
getAmountOut 0x054d50d4 → uint256
getAmountsIn 0x1f00ca74 → uint256[]
getAmountsOut 0xd06ca61f → uint256[]
pairFor 0x6d91c0e2 → address
quote 0xad615dec → uint256

Write Contract 17 functions

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

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
removeLiquidity 0xbaa2abde
address _tokenA
address _tokenB
uint256 _liquidity
uint256 _amountAMin
uint256 _amountBMin
address _to
uint256 _deadline
returns: uint256, uint256
removeLiquidityETH 0x02751cec
address _token
uint256 _liquidity
uint256 _amountTokenMin
uint256 _amountETHMin
address _to
uint256 _deadline
returns: uint256, uint256
removeLiquidityETHSupportingFeeOnTransferTokens 0xaf2979eb
address _token
uint256 _liquidity
uint256 _amountTokenMin
uint256 _amountETHMin
address _to
uint256 _deadline
returns: uint256
removeLiquidityETHWithPermit 0xded9382a
address _token
uint256 _liquidity
uint256 _amountTokenMin
uint256 _amountETHMin
address _to
uint256 _deadline
bool _approveMax
uint8 _v
bytes32 _r
bytes32 _s
returns: uint256, uint256
removeLiquidityETHWithPermitSupportingFeeOnTransferTokens 0x5b0d5984
address _token
uint256 _liquidity
uint256 _amountTokenMin
uint256 _amountETHMin
address _to
uint256 _deadline
bool _approveMax
uint8 _v
bytes32 _r
bytes32 _s
returns: uint256
removeLiquidityWithPermit 0x2195995c
address _tokenA
address _tokenB
uint256 _liquidity
uint256 _amountAMin
uint256 _amountBMin
address _to
uint256 _deadline
bool _approveMax
uint8 _v
bytes32 _r
bytes32 _s
returns: uint256, uint256
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