Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x601deaa741d09145B76B8A76752324484664d455
Balance 0 ETH
Nonce 1
Code Size 14089 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

14089 bytes
0x6080604052600436106100eb575f3560e01c8063adc244ac11610089578063cc03f31711610058578063cc03f31714610318578063d0eac51814610340578063d6cd913714610368578063e1254fba146103a4576100f2565b8063adc244ac1461026a578063b638b1eb14610294578063c12a00a8146102c4578063c45a0155146102ee576100f2565b80637d882097116100c55780637d882097146101985780638e7eed47146101c25780639cb3823a146101f2578063a22e2a091461022e576100f2565b80630ba36dcd146100f65780633fc8cef3146101325780637306efbf1461015c576100f2565b366100f257005b5f80fd5b348015610101575f80fd5b5061011c60048036038101906101179190612f47565b6103e0565b6040516101299190612f8a565b60405180910390f35b34801561013d575f80fd5b506101466103f4565b6040516101539190612fb2565b60405180910390f35b348015610167575f80fd5b50610182600480360381019061017d919061302c565b610418565b60405161018f9190612f8a565b60405180910390f35b3480156101a3575f80fd5b506101ac61061a565b6040516101b99190612f8a565b60405180910390f35b6101dc60048036038101906101d7919061307c565b610620565b6040516101e99190612f8a565b60405180910390f35b3480156101fd575f80fd5b506102186004803603810190610213919061302c565b610d1d565b6040516102259190612f8a565b60405180910390f35b348015610239575f80fd5b50610254600480360381019061024f91906130f3565b610ede565b6040516102619190612f8a565b60405180910390f35b348015610275575f80fd5b5061027e6115da565b60405161028b9190612fb2565b60405180910390f35b6102ae60048036038101906102a9919061307c565b6115fe565b6040516102bb9190612f8a565b60405180910390f35b3480156102cf575f80fd5b506102d8611d25565b6040516102e59190612fb2565b60405180910390f35b3480156102f9575f80fd5b50610302611d49565b60405161030f9190612fb2565b60405180910390f35b348015610323575f80fd5b5061033e6004803603810190610339919061317c565b611d6d565b005b34801561034b575f80fd5b506103666004803603810190610361919061317c565b611ee6565b005b348015610373575f80fd5b5061038e6004803603810190610389919061302c565b6120d3565b60405161039b9190612f8a565b60405180910390f35b3480156103af575f80fd5b506103ca60048036038101906103c59190612f47565b612290565b6040516103d79190612f8a565b60405180910390f35b5f602052805f5260405f205f915090505481565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b5f80610446837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc287876122d5565b90505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa77f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288886040518463ffffffff1660e01b81526004016104c6939291906131b6565b602060405180830381865afa1580156104e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061050591906131ff565b90505f610534837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc289856124ca565b925050505f610586827f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b90506105ef815f8151811061059e5761059d61322a565b5b6020026020010151876105b19190613284565b87886105bd91906132b7565b6105c79190613325565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8a6122d5565b9050806001815181106106055761060461322a565b5b60200260200101519450505050509392505050565b60015481565b5f824281101561065c576040517f4d3620e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b1580156106c2575f80fd5b505af11580156106d4573d5f803e3d5ffd5b50505050505f610706347f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8a6122d5565b90505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa77f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b8b6040518463ffffffff1660e01b8152600401610786939291906131b6565b602060405180830381865afa1580156107a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107c591906131ff565b90505f6107f4837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28c856124ca565b92505050610845817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b92506108ae835f8151811061085d5761085c61322a565b5b6020026020010151346108709190613284565b343461087c91906132b7565b6108869190613325565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28c8c6122d5565b925085836001815181106108c5576108c461322a565b5b60200260200101511015610905576040517f4e65335400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f610934867f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28f886124ca565b92509250925081836109469190613284565b97507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86885f815181106109985761099761322a565b5b60200260200101516040518363ffffffff1660e01b81526004016109bd929190613355565b6020604051808303815f875af11580156109d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109fd91906133b1565b507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86836040518363ffffffff1660e01b8152600401610a59929190613355565b6020604051808303815f875af1158015610a75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9991906133b1565b508473ffffffffffffffffffffffffffffffffffffffff16636d9a640a84848e6040518463ffffffff1660e01b8152600401610ad7939291906133dc565b5f604051808303815f87803b158015610aee575f80fd5b505af1158015610b00573d5f803e3d5ffd5b505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb7f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb885f81518110610b7457610b7361322a565b5b602002602001015134610b879190613411565b6040518363ffffffff1660e01b8152600401610ba4929190613355565b6020604051808303815f875af1158015610bc0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be491906133b1565b507f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb73ffffffffffffffffffffffffffffffffffffffff16636d9a640a825f306040518463ffffffff1660e01b8152600401610c4293929190613486565b5f604051808303815f87803b158015610c59575f80fd5b505af1158015610c6b573d5f803e3d5ffd5b505050508c73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167f764f0dc063c06f32d89a3f3af80c0db4be8a090901f589a478b447e0a51f09f1348c604051610d059291906134bb565b60405180910390a45050505050505095945050505050565b5f80610d4b83867f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2876122d5565b90505f81600181518110610d6257610d6161322a565b5b602002602001015190505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa7887f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2896040518463ffffffff1660e01b8152600401610dea939291906131b6565b602060405180830381865afa158015610e05573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e2991906131ff565b90505f610e5884897f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2856124ca565b92505050610ea9817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b9350835f81518110610ebe57610ebd61322a565b5b602002602001015183610ed19190613411565b9450505050509392505050565b5f8342811015610f1a576040517f4d3620e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610f47858a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b6122d5565b90505f81600181518110610f5e57610f5d61322a565b5b602002602001015190505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa78c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28d6040518463ffffffff1660e01b8152600401610fe6939291906131b6565b602060405180830381865afa158015611001573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102591906131ff565b90505f805f611056868f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2876124ca565b925092509250600154811115611097576040517ea4ac7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110e4817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b955088865f815181106110fa576110f961322a565b5b60200260200101518661110d9190613411565b1015611145576040517f4e65335400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b81526004016111a0929190613355565b6020604051808303815f875af11580156111bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e091906133b1565b508d73ffffffffffffffffffffffffffffffffffffffff166323b872dd33868d6040518463ffffffff1660e01b815260040161121e939291906134e2565b6020604051808303815f875af115801561123a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125e91906133b1565b508373ffffffffffffffffffffffffffffffffffffffff16636d9a640a8484306040518463ffffffff1660e01b815260040161129c939291906133dc565b5f604051808303815f87803b1580156112b3575f80fd5b505af11580156112c5573d5f803e3d5ffd5b50505050855f815181106112dc576112db61322a565b5b6020026020010151856112ef9190613411565b97507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb7f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb885f815181106113615761136061322a565b5b60200260200101516040518363ffffffff1660e01b8152600401611386929190613355565b6020604051808303815f875af11580156113a2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113c691906133b1565b507f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb73ffffffffffffffffffffffffffffffffffffffff16636d9a640a825f306040518463ffffffff1660e01b815260040161142493929190613486565b5f604051808303815f87803b15801561143b575f80fd5b505af115801561144d573d5f803e3d5ffd5b505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d875f815181106114a05761149f61322a565b5b6020026020010151876114b39190613411565b6040518263ffffffff1660e01b81526004016114cf9190612f8a565b5f604051808303815f87803b1580156114e6575f80fd5b505af11580156114f8573d5f803e3d5ffd5b5050505061152b8c875f815181106115135761151261322a565b5b6020026020010151876115269190613411565b612867565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff167f764f0dc063c06f32d89a3f3af80c0db4be8a090901f589a478b447e0a51f09f18d8c6040516115c19291906134bb565b60405180910390a4505050505050509695505050505050565b7f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb81565b5f824281101561163a576040517f4d3620e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b1580156116a0575f80fd5b505af11580156116b2573d5f803e3d5ffd5b50505050505f6116e4847f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8a612674565b90505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa77f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b8b6040518463ffffffff1660e01b8152600401611764939291906131b6565b602060405180830381865afa15801561177f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117a391906131ff565b90505f805f6117d4857f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28e876124ca565b925092509250845f815181106117ed576117ec61322a565b5b60200260200101519650611844817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b945034855f8151811061185a5761185961322a565b5b60200260200101518861186d9190613284565b11156118a5576040517f287bcbeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85896040518363ffffffff1660e01b8152600401611900929190613355565b6020604051808303815f875af115801561191c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061194091906133b1565b507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b815260040161199c929190613355565b6020604051808303815f875af11580156119b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119dc91906133b1565b508373ffffffffffffffffffffffffffffffffffffffff16636d9a640a84848d6040518463ffffffff1660e01b8152600401611a1a939291906133dc565b5f604051808303815f87803b158015611a31575f80fd5b505af1158015611a43573d5f803e3d5ffd5b505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb7f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb875f81518110611ab757611ab661322a565b5b60200260200101516040518363ffffffff1660e01b8152600401611adc929190613355565b6020604051808303815f875af1158015611af8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b1c91906133b1565b507f0000000000000000000000009dd78ea2b7a92b6cb5d4a495dac34f8641070ceb73ffffffffffffffffffffffffffffffffffffffff16636d9a640a825f306040518463ffffffff1660e01b8152600401611b7a93929190613486565b5f604051808303815f87803b158015611b91575f80fd5b505af1158015611ba3573d5f803e3d5ffd5b50505050845f81518110611bba57611bb961322a565b5b602002602001015187611bcd9190613284565b96505f8734611bdc9190613411565b90505f811115611c77577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b8152600401611c3f9190612f8a565b5f604051808303815f87803b158015611c56575f80fd5b505af1158015611c68573d5f803e3d5ffd5b50505050611c763382612867565b5b8c73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167f764f0dc063c06f32d89a3f3af80c0db4be8a090901f589a478b447e0a51f09f18b8d604051611d0d9291906134bb565b60405180910390a45050505050505095945050505050565b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8681565b7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d281565b5f8103611da6576040517f98bbadf500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611df19190613284565b925050819055508060015f828254611e099190613284565b925050819055507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401611e6d939291906134e2565b6020604051808303815f875af1158015611e89573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ead91906133b1565b611ee3576040517f09a3166a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f8103611f1f576040517f98bbadf500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054811115611f95576040517f2424d0ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611fe09190613411565b925050819055508060015f828254611ff89190613411565b925050819055507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b815260040161205a929190613355565b6020604051808303815f875af1158015612076573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061209a91906133b1565b6120d0576040517f09a3166a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f80612101837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28787612674565b90505f7f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa77f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288886040518463ffffffff1660e01b8152600401612181939291906131b6565b602060405180830381865afa15801561219c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121c091906131ff565b90505f6121ef837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc289856124ca565b925050505f612241827f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86600a612674565b9050805f815181106122565761225561322a565b5b6020026020010151845f815181106122715761227061322a565b5b60200260200101516122839190613284565b9450505050509392505050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60605f600267ffffffffffffffff8111156122f3576122f2613517565b5b6040519080825280602002602001820160405280156123215781602001602082028036833780820191505090505b50905085815f815181106123385761233761322a565b5b6020026020010181815250505f8061235187878761290b565b915091507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036123f2576123cd6103f26103e88a6123bc91906132b7565b6123c69190613325565b8383612a9a565b836001815181106123e1576123e061322a565b5b6020026020010181815250506124bc565b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160361248f576103f26103e86124568a8585612a9a565b61246091906132b7565b61246a9190613325565b8360018151811061247e5761247d61322a565b5b6020026020010181815250506124bb565b61249a888383612a9a565b836001815181106124ae576124ad61322a565b5b6020026020010181815250505b5b829350505050949350505050565b5f805f806124d88787612b4d565b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161461253057876001815181106125225761252161322a565b5b60200260200101515f61254e565b5f886001815181106125455761254461322a565b5b60200260200101515b80945081955050505f885f8151811061256a5761256961322a565b5b602002602001015190508573ffffffffffffffffffffffffffffffffffffffff16632f725638868473ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff16146125ca575f6125cc565b835b878673ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16146126065785612608565b5f5b6040518563ffffffff1660e01b81526004016126279493929190613544565b602060405180830381865afa158015612642573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612666919061359b565b925050509450945094915050565b60605f600267ffffffffffffffff81111561269257612691613517565b5b6040519080825280602002602001820160405280156126c05781602001602082028036833780820191505090505b50905085816001815181106126d8576126d761322a565b5b6020026020010181815250505f806126f187878761290b565b915091507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603612791576103e86103f26127598a8585612e1f565b61276391906132b7565b61276d9190613325565b835f815181106127805761277f61322a565b5b602002602001018181525050612859565b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160361282d576128096103e86103f28a6127f891906132b7565b6128029190613325565b8383612e1f565b835f8151811061281c5761281b61322a565b5b602002602001018181525050612858565b612838888383612e1f565b835f8151811061284b5761284a61322a565b5b6020026020010181815250505b5b829350505050949350505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161288c906135f3565b5f6040518083038185875af1925050503d805f81146128c6576040519150601f19603f3d011682016040523d82523d5f602084013e6128cb565b606091505b5050905080612906576040517f72e99d2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f805f6129188686612b4d565b5090505f807f000000000000000000000000acff9eee0a5522000e7141b77107359a6462e8d273ffffffffffffffffffffffffffffffffffffffff166309175fa78989896040518463ffffffff1660e01b815260040161297a939291906131b6565b602060405180830381865afa158015612995573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129b991906131ff565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612a01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a259190613683565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612a84578082612a87565b81815b8095508196505050505050935093915050565b5f808403612ad4576040517f287bcbeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f831480612ae157505f82145b15612b18576040517f041626f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8285612b2591906132b7565b90505f8585612b349190613284565b90508082612b429190613325565b925050509392505050565b5f808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612bb4576040517f88fa1f7100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612c5957507f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15612d6d577f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612cd8577f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba8684612cfb565b7f000000000000000000000000695f775551fb0d28b64101c9507c06f334b4ba86835b80925081935050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612d68576040517f66fed25500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e18565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610612da7578284612daa565b83835b80925081935050505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e17576040517f66fed25500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b9250929050565b5f808403612e59576040517f4e65335400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f831480612e6657505f82145b80612e715750818410155b15612ea8576040517f041626f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8484612eb591906132b7565b90505f8584612ec49190613411565b905060018183612ed49190613325565b612ede9190613284565b925050509392505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612f1682612eed565b9050919050565b612f2681612f0c565b8114612f30575f80fd5b50565b5f81359050612f4181612f1d565b92915050565b5f60208284031215612f5c57612f5b612ee9565b5b5f612f6984828501612f33565b91505092915050565b5f819050919050565b612f8481612f72565b82525050565b5f602082019050612f9d5f830184612f7b565b92915050565b612fac81612f0c565b82525050565b5f602082019050612fc55f830184612fa3565b92915050565b5f61ffff82169050919050565b612fe181612fcb565b8114612feb575f80fd5b50565b5f81359050612ffc81612fd8565b92915050565b61300b81612f72565b8114613015575f80fd5b50565b5f8135905061302681613002565b92915050565b5f805f6060848603121561304357613042612ee9565b5b5f61305086828701612f33565b935050602061306186828701612fee565b925050604061307286828701613018565b9150509250925092565b5f805f805f60a0868803121561309557613094612ee9565b5b5f6130a288828901612f33565b95505060206130b388828901612fee565b94505060406130c488828901612f33565b93505060606130d588828901613018565b92505060806130e688828901613018565b9150509295509295909350565b5f805f805f8060c0878903121561310d5761310c612ee9565b5b5f61311a89828a01612f33565b965050602061312b89828a01612fee565b955050604061313c89828a01612f33565b945050606061314d89828a01613018565b935050608061315e89828a01613018565b92505060a061316f89828a01613018565b9150509295509295509295565b5f6020828403121561319157613190612ee9565b5b5f61319e84828501613018565b91505092915050565b6131b081612fcb565b82525050565b5f6060820190506131c95f830186612fa3565b6131d66020830185612fa3565b6131e360408301846131a7565b949350505050565b5f815190506131f981612f1d565b92915050565b5f6020828403121561321457613213612ee9565b5b5f613221848285016131eb565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61328e82612f72565b915061329983612f72565b92508282019050808211156132b1576132b0613257565b5b92915050565b5f6132c182612f72565b91506132cc83612f72565b92508282026132da81612f72565b915082820484148315176132f1576132f0613257565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61332f82612f72565b915061333a83612f72565b92508261334a576133496132f8565b5b828204905092915050565b5f6040820190506133685f830185612fa3565b6133756020830184612f7b565b9392505050565b5f8115159050919050565b6133908161337c565b811461339a575f80fd5b50565b5f815190506133ab81613387565b92915050565b5f602082840312156133c6576133c5612ee9565b5b5f6133d38482850161339d565b91505092915050565b5f6060820190506133ef5f830186612f7b565b6133fc6020830185612f7b565b6134096040830184612fa3565b949350505050565b5f61341b82612f72565b915061342683612f72565b925082820390508181111561343e5761343d613257565b5b92915050565b5f819050919050565b5f819050919050565b5f61347061346b61346684613444565b61344d565b612f72565b9050919050565b61348081613456565b82525050565b5f6060820190506134995f830186612f7b565b6134a66020830185613477565b6134b36040830184612fa3565b949350505050565b5f6040820190506134ce5f830185612f7b565b6134db6020830184612f7b565b9392505050565b5f6060820190506134f55f830186612fa3565b6135026020830185612fa3565b61350f6040830184612f7b565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f6080820190506135575f830187612f7b565b6135646020830186612f7b565b6135716040830185612f7b565b61357e6060830184612f7b565b95945050505050565b5f8151905061359581613002565b92915050565b5f602082840312156135b0576135af612ee9565b5b5f6135bd84828501613587565b91505092915050565b5f81905092915050565b50565b5f6135de5f836135c6565b91506135e9826135d0565b5f82019050919050565b5f6135fd826135d3565b9150819050919050565b5f6dffffffffffffffffffffffffffff82169050919050565b61362981613607565b8114613633575f80fd5b50565b5f8151905061364481613620565b92915050565b5f63ffffffff82169050919050565b6136628161364a565b811461366c575f80fd5b50565b5f8151905061367d81613659565b92915050565b5f805f6060848603121561369a57613699612ee9565b5b5f6136a786828701613636565b93505060206136b886828701613636565b92505060406136c98682870161366f565b915050925092509256fea264697066735822122085e6d0dd392db6ce0da171a9d781f30499a9950dda0b7c216c2fc0543fd2f99b64736f6c63430008140033

Verified Source Code Full Match

Compiler: v0.8.20+commit.a1b79de6 EVM: shanghai Optimization: No
Router.sol 393 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IWETH.sol";
import "./interfaces/IRouter.sol";
import "./interfaces/IFactory.sol";
import "./interfaces/IPair.sol";

/// @title Router is used to swap on Antfarm Protocol without having to own ATF tokens
/// @notice This Version only supports ETH swaps and relies on the ATF/ETH Oracle
contract Router is IRouter {
    address public immutable factory;
    address public immutable antfarmToken;
    address public immutable weth;
    address public immutable oraclePair;

    mapping(address => uint256) public userDeposits;
    uint256 public totalDeposits;

    constructor(address _factory, address _weth) {
        factory = _factory;
        antfarmToken = IFactory(factory).protocolToken();
        weth = _weth;
        oraclePair = IFactory(factory).getPair(antfarmToken, weth, uint16(10));
    }

    modifier ensure(uint256 deadline) {
        if (deadline < block.timestamp) revert Router__Expired();
        _;
    }

    receive() external payable {}

    /// @inheritdoc IRouter
    function swapExactETHForTokens(
        address _output,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountOutMin
    ) external payable ensure(_deadline) returns (uint256 _amountOut) {
        IWETH(weth).deposit{value: msg.value}();

        uint256[] memory amounts = getAmountsOut(msg.value, weth, _output, _fee);

        address pair = IFactory(factory).getPair(weth, _output, _fee);
        (,, uint256 feeToPay) = _getFeeToPay(amounts, weth, _output, pair);

        // Use 'amounts' to store the required WETH to swap for fee ATF tokens
        amounts = _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));

        amounts = getAmountsOut(
            (msg.value * msg.value) / (msg.value + amounts[0]),
            weth,
            _output,
            _fee
        );

        // Checks that the intermediary calculation is already enough
        if (amounts[1] < _amountOutMin) {
            revert Router__InsufficientOutputAmount();
        }

        (uint256 amount0Out, uint256 amount1Out, uint256 finalFeeToPay) =
            _getFeeToPay(amounts, weth, _output, pair);

        _amountOut = amount0Out + amount1Out;

        IERC20(weth).transfer(pair, amounts[0]);
        IERC20(antfarmToken).transfer(pair, finalFeeToPay);
        IPair(pair).swap(amount0Out, amount1Out, _to);

        IERC20(weth).transfer(oraclePair, msg.value - amounts[0]);
        IPair(oraclePair).swap(finalFeeToPay, 0, address(this));

        emit SwapExecuted(_to, weth, _output, msg.value, _amountOut);
    }

    /// @inheritdoc IRouter
    function swapExactTokensForETH(
        address _input,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountIn,
        uint256 _amountOutMin
    ) external ensure(_deadline) returns (uint256 _amountOut) {
        uint256[] memory amounts = getAmountsOut(_amountIn, _input, weth, _fee);
        uint256 standardAmountOut = amounts[1];

        address pair = IFactory(factory).getPair(_input, weth, _fee);

        (uint256 amount0Out, uint256 amount1Out, uint256 feeToPay) =
            _getFeeToPay(amounts, _input, weth, pair);

        if (feeToPay > totalDeposits) {
            revert Router__InsufficientATFBalance();
        }

        amounts = _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));
        if (standardAmountOut - amounts[0] < _amountOutMin) {
            revert Router__InsufficientOutputAmount();
        }

        IERC20(antfarmToken).transfer(pair, feeToPay);
        IERC20(_input).transferFrom(msg.sender, pair, _amountIn);

        IPair(pair).swap(amount0Out, amount1Out, address(this));

        _amountOut = standardAmountOut - amounts[0];

        IERC20(weth).transfer(oraclePair, amounts[0]);
        IPair(oraclePair).swap(feeToPay, 0, address(this));

        IWETH(weth).withdraw(standardAmountOut - amounts[0]);
        _safeTransferETH(_to, standardAmountOut - amounts[0]);

        emit SwapExecuted(_to, _input, weth, _amountIn, _amountOut);
    }

    /// @inheritdoc IRouter
    function swapETHForExactTokens(
        address _output,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountOut
    ) external payable ensure(_deadline) returns (uint256 _amountIn) {
        // Wrap all received ETH into WETH.
        IWETH(weth).deposit{value: msg.value}();

        uint256[] memory amounts =
            _getAmountsIn(_amountOut, weth, _output, _fee);

        address pair = IFactory(factory).getPair(weth, _output, _fee);
        (uint256 amount0Out, uint256 amount1Out, uint256 feeToPay) =
            _getFeeToPay(amounts, weth, _output, pair);

        _amountIn = amounts[0]; // Temporary storage for the amount of WETH used for main swap
        amounts = _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));

        if (_amountIn + amounts[0] > msg.value) {
            revert Router__InsufficientInputAmount();
        }

        IERC20(weth).transfer(pair, _amountIn);
        IERC20(antfarmToken).transfer(pair, feeToPay);
        IPair(pair).swap(amount0Out, amount1Out, _to);

        IERC20(weth).transfer(oraclePair, amounts[0]);
        IPair(oraclePair).swap(feeToPay, 0, address(this));

        _amountIn += amounts[0];

        uint256 refund = msg.value - _amountIn;
        if (refund > 0) {
            IWETH(weth).withdraw(refund);
            _safeTransferETH(msg.sender, refund);
        }

        emit SwapExecuted(_to, weth, _output, _amountIn, _amountOut);
    }

    /// @inheritdoc IRouter
    function estimateExactETHForTokens(
        address _output,
        uint16 _fee,
        uint256 _amountIn
    ) external view returns (uint256 estimatedOut) {
        uint256[] memory amounts = getAmountsOut(_amountIn, weth, _output, _fee);
        address pair = IFactory(factory).getPair(weth, _output, _fee);
        (,, uint256 feeToPay) = _getFeeToPay(amounts, weth, _output, pair);

        uint256[] memory feeInAmounts =
            _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));

        feeInAmounts = getAmountsOut(
            (_amountIn * _amountIn) / (_amountIn + feeInAmounts[0]),
            weth,
            _output,
            _fee
        );

        return feeInAmounts[1];
    }

    /// @inheritdoc IRouter
    function estimateExactTokensForETH(
        address _input,
        uint16 _fee,
        uint256 _amountIn
    ) external view returns (uint256 estimatedOut) {
        uint256[] memory amounts = getAmountsOut(_amountIn, _input, weth, _fee);
        uint256 standardAmountOut = amounts[1];

        address pair = IFactory(factory).getPair(_input, weth, _fee);
        (,, uint256 feeToPay) = _getFeeToPay(amounts, _input, weth, pair);

        amounts = _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));

        return standardAmountOut - amounts[0];
    }

    /// @inheritdoc IRouter
    function estimateETHForExactTokens(
        address _output,
        uint16 _fee,
        uint256 _amountOut
    ) external view returns (uint256 estimatedIn) {
        uint256[] memory amounts =
            _getAmountsIn(_amountOut, weth, _output, _fee);

        address pair = IFactory(factory).getPair(weth, _output, _fee);
        (,, uint256 feeToPay) = _getFeeToPay(amounts, weth, _output, pair);

        // Calculate WETH needed to pay for ATF fees
        uint256[] memory feeInAmounts =
            _getAmountsIn(feeToPay, weth, antfarmToken, uint16(10));

        // Total ETH needed is the amount for the swap plus the amount needed for fees
        return amounts[0] + feeInAmounts[0];
    }

    function getAmountsOut(
        uint256 amountIn,
        address tokenIn,
        address tokenOut,
        uint16 fee
    ) internal view returns (uint256[] memory) {
        uint256[] memory amounts = new uint256[](2);
        amounts[0] = amountIn;
        (uint256 reserveIn, uint256 reserveOut) =
            _getReserves(tokenIn, tokenOut, fee);

        if (tokenIn == antfarmToken) {
            amounts[1] = _getAmountOut(
                (amountIn * 1000) / (1000 + 10), reserveIn, reserveOut
            );
        } else if (tokenOut == antfarmToken) {
            amounts[1] = (_getAmountOut(amountIn, reserveIn, reserveOut) * 1000)
                / (1000 + 10);
        } else {
            amounts[1] = _getAmountOut(amountIn, reserveIn, reserveOut);
        }

        return amounts;
    }

    function _getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256) {
        if (amountIn == 0) revert Router__InsufficientInputAmount();
        if (reserveIn == 0 || reserveOut == 0) {
            revert Router__InsufficientLiquidity();
        }
        uint256 numerator = amountIn * reserveOut;
        uint256 denominator = reserveIn + amountIn;
        return numerator / denominator;
    }

    function _getAmountsIn(
        uint256 amountOut,
        address tokenIn,
        address tokenOut,
        uint16 fee
    ) internal view returns (uint256[] memory) {
        uint256[] memory amounts = new uint256[](2);
        amounts[1] = amountOut;
        (uint256 reserveIn, uint256 reserveOut) =
            _getReserves(tokenIn, tokenOut, fee);
        if (tokenIn == antfarmToken) {
            amounts[0] = (
                _getAmountIn(amountOut, reserveIn, reserveOut) * (1000 + 10)
            ) / 1000;
        } else if (tokenOut == antfarmToken) {
            amounts[0] = _getAmountIn(
                (amountOut * (1000 + 10)) / 1000, reserveIn, reserveOut
            );
        } else {
            amounts[0] = _getAmountIn(amountOut, reserveIn, reserveOut);
        }
        return amounts;
    }

    function _getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256) {
        if (amountOut == 0) revert Router__InsufficientOutputAmount();
        if (reserveIn == 0 || reserveOut == 0 || amountOut >= reserveOut) {
            revert Router__InsufficientLiquidity();
        }
        uint256 numerator = reserveIn * amountOut;
        uint256 denominator = reserveOut - amountOut;
        return (numerator / denominator) + 1;
    }

    function _getFeeToPay(
        uint256[] memory amounts,
        address tokenIn,
        address tokenOut,
        address pair
    )
        internal
        view
        returns (uint256 amount0Out, uint256 amount1Out, uint256 feeToPay)
    {
        // Original fee calculation for non-ATF pairs
        (address token0,) = _sortTokens(tokenIn, tokenOut);
        (amount0Out, amount1Out) = tokenIn == token0
            ? (uint256(0), amounts[1])
            : (amounts[1], uint256(0));

        uint256 amountIn = amounts[0];

        feeToPay = IPair(pair).getFees(
            amount0Out,
            tokenIn == token0 ? amountIn : uint256(0),
            amount1Out,
            tokenIn == token0 ? uint256(0) : amountIn
        );
    }

    function _getReserves(address tokenA, address tokenB, uint16 fee)
        internal
        view
        returns (uint256 reserveA, uint256 reserveB)
    {
        (address token0,) = _sortTokens(tokenA, tokenB);
        (uint256 reserve0, uint256 reserve1,) =
            IPair(IFactory(factory).getPair(tokenA, tokenB, fee)).getReserves();
        (reserveA, reserveB) =
            tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }

    function _sortTokens(address tokenA, address tokenB)
        internal
        view
        returns (address token0, address token1)
    {
        if (tokenA == tokenB) revert Router__IdenticalAddresses();
        if (tokenA == antfarmToken || tokenB == antfarmToken) {
            (token0, token1) = tokenA == antfarmToken
                ? (antfarmToken, tokenB)
                : (antfarmToken, tokenA);
            if (token1 == address(0)) revert Router__AddressZero();
        } else {
            (token0, token1) =
                tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
            if (token0 == address(0)) revert Router__AddressZero();
        }
    }

    function _safeTransferETH(address to, uint256 value) internal {
        (bool success,) = to.call{value: value}("");
        if (!success) revert Router__ETHTransferFailed();
    }

    function depositATF(uint256 amount) external {
        if (amount == 0) revert Router__ZeroAmount();

        userDeposits[msg.sender] += amount;
        totalDeposits += amount;

        if (
            !IERC20(antfarmToken).transferFrom(msg.sender, address(this), amount)
        ) {
            revert Router__TransferFailed();
        }
    }

    function withdrawATF(uint256 amount) external {
        if (amount == 0) revert Router__ZeroAmount();
        if (amount > userDeposits[msg.sender]) {
            revert Router__InsufficientBalance();
        }

        userDeposits[msg.sender] -= amount;
        totalDeposits -= amount;

        if (!IERC20(antfarmToken).transfer(msg.sender, amount)) {
            revert Router__TransferFailed();
        }
    }

    function getDeposit(address user) external view returns (uint256) {
        return userDeposits[user];
    }
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
IWETH.sol 31 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IWETH {
    // ERC20-like functions
    function deposit() external payable;
    function withdraw(uint256) external;

    // Standard ERC20 functions
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount)
        external
        returns (bool);

    // Events
    event Deposit(address indexed dst, uint256 wad);
    event Withdrawal(address indexed src, uint256 wad);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner, address indexed spender, uint256 value
    );
}
IRouter.sol 145 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @title Router Interface for Antfarm Protocol
/// @notice Interface for handling token swaps with ETH on Antfarm Protocol
/// @dev Implements core swap functionality and estimation methods
interface IRouter {
    error Router__Expired();
    error Router__IdenticalAddresses();
    error Router__AddressZero();
    error Router__ZeroAmount();
    error Router__InsufficientLiquidity();
    error Router__InsufficientInputAmount();
    error Router__InsufficientOutputAmount();
    error Router__ETHTransferFailed();
    error Router__InsufficientBalance();
    error Router__InsufficientATFBalance();
    error Router__TransferFailed();

    event SwapExecuted(
        address indexed sender,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut
    );

    /// @notice Returns the factory contract address
    /// @return Address of the factory contract
    function factory() external view returns (address);

    /// @notice Returns the Antfarm token address
    /// @return Address of the Antfarm token
    function antfarmToken() external view returns (address);

    /// @notice Returns the WETH token address
    /// @return Address of the WETH token
    function weth() external view returns (address);

    /// @notice Returns the oracle pair address
    /// @return Address of the oracle pair
    function oraclePair() external view returns (address);

    /// @notice Allows the contract to receive ETH
    receive() external payable;

    /// @notice Swaps an exact amount of ETH for tokens
    /// @param _output The token address to receive
    /// @param _fee The fee tier of the pool
    /// @param _to The recipient address for the output tokens
    /// @param _deadline The timestamp by which the transaction must be executed
    /// @param _amountOutMin The minimum amount of output tokens to receive
    /// @return _amountOut The actual amount of output tokens received
    function swapExactETHForTokens(
        address _output,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountOutMin
    ) external payable returns (uint256 _amountOut);

    /// @notice Swaps an exact amount of tokens for ETH
    /// @param _input The token address to spend
    /// @param _fee The fee tier of the pool
    /// @param _to The recipient address for the ETH
    /// @param _deadline The timestamp by which the transaction must be executed
    /// @param _amountIn The amount of input tokens to spend
    /// @param _amountOutMin The minimum amount of ETH to receive
    /// @return _amountOut The actual amount of ETH received
    function swapExactTokensForETH(
        address _input,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountIn,
        uint256 _amountOutMin
    ) external returns (uint256 _amountOut);

    /// @notice Swaps ETH for an exact amount of tokens
    /// @dev Refunds excess ETH if too much is sent
    /// @param _output The token address to receive
    /// @param _fee The fee tier of the pool
    /// @param _to The recipient address for the tokens
    /// @param _deadline The timestamp by which the transaction must be executed
    /// @param _amountOut The exact amount of output tokens to receive
    /// @return _amountIn The amount of ETH spent
    function swapETHForExactTokens(
        address _output,
        uint16 _fee,
        address _to,
        uint256 _deadline,
        uint256 _amountOut
    ) external payable returns (uint256 _amountIn);

    /// @notice Estimates the output amount of tokens for an exact ETH input
    /// @param _output The token address to receive
    /// @param _fee The fee tier of the pool
    /// @param _amountIn The amount of ETH to swap
    /// @return estimatedOut The estimated amount of output tokens
    function estimateExactETHForTokens(
        address _output,
        uint16 _fee,
        uint256 _amountIn
    ) external view returns (uint256 estimatedOut);

    /// @notice Estimates the output amount of ETH for an exact token input
    /// @param _input The token address to spend
    /// @param _fee The fee tier of the pool
    /// @param _amountIn The amount of input tokens
    /// @return estimatedOut The estimated amount of ETH
    function estimateExactTokensForETH(
        address _input,
        uint16 _fee,
        uint256 _amountIn
    ) external view returns (uint256 estimatedOut);

    /// @notice Estimates the input amount of ETH needed for an exact token output
    /// @param _output The token address to receive
    /// @param _fee The fee tier of the pool
    /// @param _amountOut The exact amount of output tokens desired
    /// @return estimatedIn The estimated amount of ETH needed
    function estimateETHForExactTokens(
        address _output,
        uint16 _fee,
        uint256 _amountOut
    ) external view returns (uint256 estimatedIn);

    /// @notice Deposits ATF tokens
    /// @param amount The amount of ATF tokens to deposit
    function depositATF(uint256 amount) external;

    /// @notice Withdraws ATF tokens
    /// @param amount The amount of ATF tokens to withdraw
    function withdrawATF(uint256 amount) external;

    /// @notice Gets the deposit amount for a user
    /// @param user The address of the user
    /// @return The deposit amount for the user
    function getDeposit(address user) external view returns (uint256);

    /// @notice Returns the deposit amount for a user
    /// @param user The address of the user
    /// @return The deposit amount for the user
    function userDeposits(address user) external view returns (uint256);
}
IFactory.sol 44 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint16 fee,
        uint256 allPairsLength
    );

    function possibleFees(uint256) external view returns (uint16);

    function allPairs(uint256) external view returns (address);

    function protocolToken() external view returns (address);

    function getPairs(uint256 startIndex, uint256 numOfPairs)
        external
        view
        returns (address[] memory, uint256);

    function getPair(address tokenA, address tokenB, uint16 fee)
        external
        view
        returns (address pair);

    function feesForPair(address tokenA, address tokenB, uint256)
        external
        view
        returns (uint16);

    function getFeesForPair(address tokenA, address tokenB)
        external
        view
        returns (uint16[8] memory fees);

    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB, uint16 fee)
        external
        returns (address pair);
}
IPair.sol 92 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IPair {
    error BalanceOverflow();
    error InsufficientFee();
    error InsufficientInputAmount();
    error InsufficientLiquidity();
    error InsufficientLiquidityBurned();
    error InsufficientLiquidityMinted();
    error InsufficientOutputAmount();
    error InvalidReceiver();
    error K();
    error NoBetterOracle();
    error NoOracleFound();
    error SenderNotFactory();
    error SwapAmountTooLow();

    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function antfarmOracle() external view returns (address);
    function antfarmToken() external view returns (address);
    function antfarmTokenReserve() external view returns (uint256);
    function burn(address to, uint256 positionId, uint256 liquidity)
        external
        returns (uint256, uint256);
    function claimDividend(address to, uint256 positionId)
        external
        returns (uint256 claimAmount);
    function claimableDividends(address operator, uint256 positionId)
        external
        view
        returns (uint256 amount);
    function factory() external view returns (address);
    function fee() external view returns (uint16);
    function getFees(
        uint256 amount0Out,
        uint256 amount0In,
        uint256 amount1Out,
        uint256 amount1In
    ) external view returns (uint256 feeToPay);
    function getPositionLP(address operator, uint256 positionId)
        external
        view
        returns (uint128);
    function getReserves()
        external
        view
        returns (
            uint112 _reserve0,
            uint112 _reserve1,
            uint32 _blockTimestampLast
        );
    function initialize(
        address _token0,
        address _token1,
        uint16 _fee,
        address _antfarmToken
    ) external;
    function mint(address to, uint256 positionId) external returns (uint256);
    function positions(address, uint256)
        external
        view
        returns (uint128 lp, uint256 dividend, uint256 lastDividendPoints);
    function scanOracles(uint112 maxReserve)
        external
        view
        returns (address bestOracle);
    function skim(address to) external;
    function swap(uint256 amount0Out, uint256 amount1Out, address to)
        external;
    function sync() external;
    function token0() external view returns (address);
    function token1() external view returns (address);
    function totalSupply() external view returns (uint256);
    function updateOracle() external;
}

Read Contract

antfarmToken 0xc12a00a8 → address
estimateETHForExactTokens 0xd6cd9137 → uint256
estimateExactETHForTokens 0x7306efbf → uint256
estimateExactTokensForETH 0x9cb3823a → uint256
factory 0xc45a0155 → address
getDeposit 0xe1254fba → uint256
oraclePair 0xadc244ac → address
totalDeposits 0x7d882097 → uint256
userDeposits 0x0ba36dcd → uint256
weth 0x3fc8cef3 → address

Write Contract 5 functions

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

depositATF 0xcc03f317
uint256 amount
swapETHForExactTokens 0xb638b1eb
address _output
uint16 _fee
address _to
uint256 _deadline
uint256 _amountOut
returns: uint256
swapExactETHForTokens 0x8e7eed47
address _output
uint16 _fee
address _to
uint256 _deadline
uint256 _amountOutMin
returns: uint256
swapExactTokensForETH 0xa22e2a09
address _input
uint16 _fee
address _to
uint256 _deadline
uint256 _amountIn
uint256 _amountOutMin
returns: uint256
withdrawATF 0xd0eac518
uint256 amount

Recent Transactions

No transactions found for this address