Address Contract Partially Verified
Address
0xB4B0ea46Fe0E9e8EAB4aFb765b527739F2718671
Balance
0 ETH
Nonce
1
Code Size
17102 bytes
Creator
0x641AD78B...e689 at tx 0xeae77e17...f1d69b
Indexed Transactions
0
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