Address Contract Verified
Address
0xB67D637B1301EEb56Dba4555bBd15Cd220F1aaD6
Balance
0 ETH
Nonce
1
Code Size
16156 bytes
Creator
0xe096CBEF...2bE6 at tx 0xedf9ad6e...9a895b
Indexed Transactions
0
Contract Bytecode
16156 bytes
0x6080604052600436106102e05760003560e01c806370ed0ada11610184578063c23f001f116100d6578063d598d4c91161008a578063f43084f711610064578063f43084f714610905578063f6e3964014610918578063f7888aec1461093857600080fd5b8063d598d4c9146108ac578063dbb1b5e0146108d9578063de153a48146108ef57600080fd5b8063c9df6508116100bb578063c9df650814610839578063cd626c2814610869578063cd69bef51461087f57600080fd5b8063c23f001f146107d9578063c31c9c071461081157600080fd5b8063a85c38ef11610138578063b5e1a2cc11610112578063b5e1a2cc14610779578063bb5c08fb14610799578063bc66359e146107b957600080fd5b8063a85c38ef14610692578063b202416c14610719578063b54ae16e1461075957600080fd5b806373dd250c1161016957806373dd250c1461060d5780638a66cfd51461062d5780639e43c9c91461065a57600080fd5b806370ed0ada146105cd57806373688914146105e057600080fd5b80633d2e9f461161023d5780634f0e0ef3116101f15780636d626290116101cb5780636d626290146105765780636d6de7e9146105965780636db5c8fd146105b657600080fd5b80634f0e0ef31461050e578063527097251461053657806366e0a4cd1461056357600080fd5b806346c8fe641161022257806346c8fe64146104c857806347b352e5146104db57806347e7ef24146104fb57600080fd5b80633d2e9f46146104a0578063439370b1146104c057600080fd5b80632133e3b9116102945780632c3f35b8116102795780632c3f35b81461044857806335b00d06146104605780633aecd0e31461048057600080fd5b80632133e3b9146103d65780632b2f1e14146103f657600080fd5b8063089fe6aa116102c5578063089fe6aa1461032357806318a042ec146103705780631980bc161461039057600080fd5b806304012690146102ec578063068bcaba1461030357600080fd5b366102e757005b600080fd5b3480156102f857600080fd5b5061030161098b565b005b34801561030f57600080fd5b5061030161031e3660046137c2565b610a2e565b34801561032f57600080fd5b506002546103579074010000000000000000000000000000000000000000900462ffffff1681565b60405162ffffff90911681526020015b60405180910390f35b34801561037c57600080fd5b5061030161038b3660046137df565b610aec565b34801561039c57600080fd5b506103c86103ab36600461380b565b600660209081526000928352604080842090915290825290205481565b604051908152602001610367565b3480156103e257600080fd5b506103c86103f1366004613844565b610c3a565b34801561040257600080fd5b50600d546104239073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610367565b34801561045457600080fd5b506103c86301e1338081565b34801561046c57600080fd5b5061030161047b36600461387f565b610c5c565b34801561048c57600080fd5b506103c861049b3660046137c2565b6115e3565b3480156104ac57600080fd5b506103016104bb366004613943565b611674565b610301611784565b6103016104d6366004613984565b6118f6565b3480156104e757600080fd5b506103016104f63660046139bf565b611925565b6103016105093660046137df565b611b7a565b34801561051a57600080fd5b5061042373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561054257600080fd5b506001546104239073ffffffffffffffffffffffffffffffffffffffff1681565b610301610571366004613a10565b611cf7565b34801561058257600080fd5b50610301610591366004613a29565b611f27565b3480156105a257600080fd5b506103016105b13660046137c2565b6122f7565b3480156105c257600080fd5b506103c86276a70081565b3480156105d957600080fd5b50476103c8565b3480156105ec57600080fd5b506000546104239073ffffffffffffffffffffffffffffffffffffffff1681565b34801561061957600080fd5b50610301610628366004613a7a565b6123b5565b34801561063957600080fd5b506103c86106483660046137c2565b60076020526000908152604090205481565b34801561066657600080fd5b506103c861067536600461380b565b600560209081526000928352604080842090915290825290205481565b34801561069e57600080fd5b506106b26106ad366004613a10565b61247a565b6040805173ffffffffffffffffffffffffffffffffffffffff9b8c168152998b1660208b0152890197909752979094166060870152608086019290925260a085015260c084015260e083015291151561010082015290151561012082015261014001610367565b34801561072557600080fd5b506107496107343660046137c2565b60096020526000908152604090205460ff1681565b6040519015158152602001610367565b34801561076557600080fd5b506103c8610774366004613a9f565b6124fd565b34801561078557600080fd5b50610423610794366004613a10565b61251e565b3480156107a557600080fd5b506103016107b4366004613acb565b612555565b3480156107c557600080fd5b506103016107d4366004613b0d565b6128df565b3480156107e557600080fd5b506103c86107f436600461380b565b600460209081526000928352604080842090915290825290205481565b34801561081d57600080fd5b5061042373e592427a0aece92de3edee1f18e0157c0586156481565b34801561084557600080fd5b506107496108543660046137c2565b600a6020526000908152604090205460ff1681565b34801561087557600080fd5b506103c860035481565b34801561088b57600080fd5b506103c861089a3660046137c2565b600b6020526000908152604090205481565b3480156108b857600080fd5b506002546104239073ffffffffffffffffffffffffffffffffffffffff1681565b3480156108e557600080fd5b506103576102ee81565b3480156108fb57600080fd5b506103c8610e1081565b6103016109133660046137df565b6128fe565b34801561092457600080fd5b506103016109333660046137c2565b612a0f565b34801561094457600080fd5b506103c861095336600461380b565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260046020908152604080832093909416825291909152205490565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906109cb575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610a02576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a6e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610aa5576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600460209081526040808320338452909152902054811115610b56576040517f7b7b36da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600460209081526040808320338452909152902054610b92908290613b95565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832033808552925290912092909255610bd19183612acd565b610be8336000908152600760205260409020429055565b60405181815273ffffffffffffffffffffffffffffffffffffffff83169033907ff2abf94c6b0da8d85e7c6cb49df089e622137e0f674d2d019b4ee40660e38153906020015b60405180910390a35050565b6000612710610c498385613ba8565b610c539190613bbf565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610c9c575060015473ffffffffffffffffffffffffffffffffffffffff163314155b8015610cc0575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610cf7576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d038680613bfa565b9150610d1490506020870187613bfa565b905081148015610d3f5750610d2c6040870187613bfa565b9050610d3b6020880188613bfa565b9050145b610d75576040517fd9183d2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610f1f5760006008610d8e8980613bfa565b84818110610d9e57610d9e613c69565b9050602002013581548110610db557610db5613c69565b906000526020600020906009020190508060070154421015610e03576040517fb621e1bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008810154610100900460ff1615610e47576040517f5fdb34e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600881015460ff1615610e86576040517f0368368700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e936020890189613bfa565b83818110610ea357610ea3613c69565b9050602002016020810190610eb89190613c98565b15610f16576002810154600182015473ffffffffffffffffffffffffffffffffffffffff9081166000908152600560209081526040808320600387015490941683529290529081208054909190610f10908490613cb5565b90915550505b50600101610d78565b506000805b60035481101561143d5760005b60035481101561143457600060056000600c8581548110610f5457610f54613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120600c805491929185908110610f9c57610f9c613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902054111561142c576110ba73e592427a0aece92de3edee1f18e0157c0586156460056000600c868154811061100357611003613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120600c80549192918690811061104b5761104b613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902054600c80548690811061109157611091613c69565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169190612b4e565b6000604051806101000160405280600c85815481106110db576110db613c69565b6000918252602091829020015473ffffffffffffffffffffffffffffffffffffffff168252600c805492909101918590811061111957611119613c69565b6000918252602091829020015473ffffffffffffffffffffffffffffffffffffffff16825260025474010000000000000000000000000000000000000000900462ffffff169082015230604082015260600161117761025842613cb5565b815260200160056000600c878154811061119357611193613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120600c8054919291879081106111db576111db613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528281019390935260409091019020548252018a8a8781811061122557611225613c69565b602090810292909201358352506000918101829052604080517f414bf389000000000000000000000000000000000000000000000000000000008152845173ffffffffffffffffffffffffffffffffffffffff908116600483015292850151831660248201529084015162ffffff1660448201526060840151821660648201526080840151608482015260a084015160a482015260c084015160c482015260e084015190911660e48201529192509073e592427a0aece92de3edee1f18e0157c058615649063414bf38990610104016020604051808303816000875af1158015611313573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113379190613cc8565b905089898681811061134b5761134b613c69565b90506020020135811161138a576040517f1321051400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060066000600c87815481106113a2576113a2613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120600c8054919291879081106113ea576113ea613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040019020558461142681613ce1565b95505050505b600101610f31565b50600101610f24565b5060005b828110156114d3576114cb6114568980613bfa565b8381811061146657611466613c69565b9050602002013589806020019061147d9190613bfa565b8481811061148d5761148d613c69565b90506020020160208101906114a29190613c98565b6114af60408c018c613bfa565b858181106114bf576114bf613c69565b90506020020135612c26565b600101611441565b50831561151b5760005b82811015611519576115116114f28980613bfa565b8381811061150257611502613c69565b90506020020135856000612555565b6001016114dd565b505b60005b6003548110156115d95760005b6003548110156115d057600060056000600c858154811061154e5761154e613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040018120600c80549192918590811061159657611596613c69565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205560010161152b565b5060010161151e565b5050505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611650573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c569190613cc8565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906116b4575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156116eb576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260076020526040902054611720906301e1338090613cb5565b4211611758576040517f2c6dda0800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d5461177f908390859073ffffffffffffffffffffffffffffffffffffffff168461317e565b505050565b600034116117be576040517f1fa6205f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561181a57600080fd5b505af115801561182e573d6000803e3d6000fd5b50503360009081527e137c28eabea4eda5601e544e6551e6761ee561d32c4142c29e0f892835a361602052604090205461186d93503492509050613cb5565b3360009081527e137c28eabea4eda5601e544e6551e6761ee561d32c4142c29e0f892835a3616020908152604080832093909355600790522042905560405134815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29033907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f629060200160405180910390a3565b6118fe611784565b61191f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc285858585611f27565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611965575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561199c576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168315151790558215611b0f5773ffffffffffffffffffffffffffffffffffffffff841660009081526009602052604090205460ff1615611a51576040517f464e3f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611a8b576040517f1fa6205f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054600181019091557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091556000908152600b60205260409020819055611b1c565b611b1a600c85613245565b505b505073ffffffffffffffffffffffffffffffffffffffff91909116600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055600c54600355565b73ffffffffffffffffffffffffffffffffffffffff821660009081526009602052604090205460ff16611bd9576040517fe1478bb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611c13576040517f1fa6205f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c3573ffffffffffffffffffffffffffffffffffffffff831633308461348a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600460209081526040808320338452909152902054611c71908290613cb5565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600460209081526040808320338452825280832093909355600790522042905560405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6290602001610c2e565b3360009081527e137c28eabea4eda5601e544e6551e6761ee561d32c4142c29e0f892835a3616020526040902054811115611d5e576040517f7b7b36da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081527e137c28eabea4eda5601e544e6551e6761ee561d32c4142c29e0f892835a3616020526040902054611d97908290613b95565b3360009081527e137c28eabea4eda5601e544e6551e6761ee561d32c4142c29e0f892835a36160205260409081902091909155517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015611e2e57600080fd5b505af1158015611e42573d6000803e3d6000fd5b50506040516000925033915083908381818185875af1925050503d8060008114611e88576040519150601f19603f3d011682016040523d82523d6000602084013e611e8d565b606091505b5050905080611ec8576040517fdcf35db000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611edf336000908152600760205260409020429055565b60405182815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29033907ff2abf94c6b0da8d85e7c6cb49df089e622137e0f674d2d019b4ee40660e3815390602001610c2e565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600460209081526040808320338452909152902054831115611f91576040517f7b7b36da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611ff6576040517f3445e17c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6276a7008110612032576040517ff59db0ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166000908152600b6020526040902054831015612091576040517f49986e7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851660009081526004602090815260408083203384529091529020546120cd908490613b95565b73ffffffffffffffffffffffffffffffffffffffff808716600081815260046020908152604080832033808552908352818420969096558051610140810182529586529085019290925290830186905290861660608301526080820181905260a0820184905260c082015260089060e081016121498442613cb5565b8152600060208083018290526040928301829052845460018082018755958352818320855160099092020180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617825586840151978201805482169884169890981790975585850151600282015560608601516003820180549098169216919091179095556080840151600486015560a0840151600586015560c0840151600686015560e08401516007808701919091556101008086015160089097018054610120909701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009097169715157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16979097179515150294909417909455338152919092522042905560085473ffffffffffffffffffffffffffffffffffffffff86169033906122b790600190613b95565b60408051878152602081018690527fe8e781512b2b69f39d5e2d87b1a162b544f3ca1fc67f40c2c5344ce6ae71300c910160405180910390a45050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590612337575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561236e576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906123f5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561242c576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805462ffffff90921674010000000000000000000000000000000000000000027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6008818154811061248a57600080fd5b600091825260209091206009909102018054600182015460028301546003840154600485015460058601546006870154600788015460089098015473ffffffffffffffffffffffffffffffffffffffff978816995095871697949690931694919390929160ff808216916101009004168a565b60008261250a8386613ba8565b6125149190613bbf565b90505b9392505050565b600c818154811061252e57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60006008848154811061256a5761256a613c69565b906000526020600020906009020190508060080160019054906101000a900460ff16156125c3576040517f5fdb34e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600881015460ff16806125e65750610e1081600701546125e39190613cb5565b42115b61261c576040517f4771047900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816127085773ffffffffffffffffffffffffffffffffffffffff83166000908152600a602052604090205460ff16612680576040517f532dcedb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600601541180156126cd5750600681015473ffffffffffffffffffffffffffffffffffffffff8085166000908152600460209081526040808320600d549094168352929052205410155b1561270357600d548154600683015461270392869273ffffffffffffffffffffffffffffffffffffffff9182169291169061317e565b612758565b805473ffffffffffffffffffffffffffffffffffffffff163314612758576040517f8ecfde6200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600881015460ff1615801561277d5750610e10816007015461277a9190613cb5565b42115b156127d85760018101546003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055600281015460048201555b600480820154600383015473ffffffffffffffffffffffffffffffffffffffff9081166000908152602093845260408082208654909316825291909352909120546128239190613cb5565b600382015473ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208654851684529091529020919091556008820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055815416330361191f576128ae336000908152600760205260409020429055565b60405184907f3fcc63d4c63f7973d46fabc12bae28bd4c806f711ac836cb6efd2ea0d3961a9190600090a250505050565b6128e98685611b7a565b6128f68686858585611f27565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061293e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15612975576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146129cf576040519150601f19603f3d011682016040523d82523d6000602084013e6129d4565b606091505b505090508061177f576040517fdcf35db000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314801590612a4f575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15612a86576040517f1a06d0fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60405173ffffffffffffffffffffffffffffffffffffffff83811660248301526044820183905261177f91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506134d0565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052612bda848261356b565b61191f5760405173ffffffffffffffffffffffffffffffffffffffff848116602483015260006044830152612c1c91869182169063095ea7b390606401612b07565b61191f84826134d0565b600060088481548110612c3b57612c3b613c69565b6000918252602090912060066009909202019081018390556008810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559050821561312357600381015460009073ffffffffffffffffffffffffffffffffffffffff1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214612d63578160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d539190613d19565b612d5e90600a613e5c565b612d6a565b6402540be4005b600183015473ffffffffffffffffffffffffffffffffffffffff9081166000908152600560209081526040808320600388015490941683529290529081205460028501549293509091612dbe9190846124fd565b600184015473ffffffffffffffffffffffffffffffffffffffff90811660009081526006602090815260408083206003890154909416835292905290812054919250908290612e0e908590613ba8565b612e189190613bbf565b600185015473ffffffffffffffffffffffffffffffffffffffff166000908152600a60205260408120549192509060ff1615612f6c5784600501548560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee69190613d19565b612ef190600a613e5c565b8660020154612f009190613ba8565b612f0a9190613bbf565b612f149083613b95565b9050612f2b85600201546102ee62ffffff16610c3a565b856006015410612f67576040517fedc54d1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613085565b8460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fff9190613d19565b61300a90600a613e5c565b8560050154866002015461301e9190613ba8565b6130289190613bbf565b6130329083613b95565b90506130496130418284613b95565b6102ee610c3a565b856006015410613085576040517fedc54d1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61308f8183613b95565b600480870191909155600386015473ffffffffffffffffffffffffffffffffffffffff908116600090815260209283526040808220600d549093168252919092529020546130de908290613cb5565b600386015473ffffffffffffffffffffffffffffffffffffffff9081166000908152600460209081526040808320600d54909416835292905220555061191f92505050565b60018101546003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556002810154600482015550505050565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600460209081526040808320938716835292905220546131bc908290613b95565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260046020908152604080832088851684529091528082209390935590841681522054613206908290613cb5565b73ffffffffffffffffffffffffffffffffffffffff94851660009081526004602090815260408083209590971682529390935293909120929092555050565b8154600090815b81811015613482578373ffffffffffffffffffffffffffffffffffffffff1685828154811061327d5761327d613c69565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036134705784546000906132b590600190613b95565b9050808214613356578581815481106132d0576132d0613c69565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686838154811061330d5761330d613c69565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8554869061336690600190613b95565b8154811061337657613376613c69565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168682815481106133b3576133b3613c69565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508580548061340b5761340b613e6b565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190555060019250610c56915050565b8061347a81613ce1565b91505061324c565b505092915050565b60405173ffffffffffffffffffffffffffffffffffffffff848116602483015283811660448301526064820183905261191f9186918216906323b872dd90608401612b07565b60006134f273ffffffffffffffffffffffffffffffffffffffff84168361362d565b905080516000141580156135175750808060200190518101906135159190613e9a565b155b1561177f576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516135959190613eb7565b6000604051808303816000865af19150503d80600081146135d2576040519150601f19603f3d011682016040523d82523d6000602084013e6135d7565b606091505b50915091508180156136015750805115806136015750808060200190518101906136019190613e9a565b8015613624575060008573ffffffffffffffffffffffffffffffffffffffff163b115b95945050505050565b6060610c5383836000846000808573ffffffffffffffffffffffffffffffffffffffff1684866040516136609190613eb7565b60006040518083038185875af1925050503d806000811461369d576040519150601f19603f3d011682016040523d82523d6000602084013e6136a2565b606091505b50915091506136b28683836136bc565b9695505050505050565b6060826136d1576136cc8261374b565b612517565b81511580156136f5575073ffffffffffffffffffffffffffffffffffffffff84163b155b15613744576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401613562565b5080612517565b80511561375b5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b73ffffffffffffffffffffffffffffffffffffffff8116811461378d57600080fd5b80356137bd81613790565b919050565b6000602082840312156137d457600080fd5b813561251781613790565b600080604083850312156137f257600080fd5b82356137fd81613790565b946020939093013593505050565b6000806040838503121561381e57600080fd5b823561382981613790565b9150602083013561383981613790565b809150509250929050565b6000806040838503121561385757600080fd5b50508035926020909101359150565b801515811461378d57600080fd5b80356137bd81613866565b60008060008060006080868803121561389757600080fd5b853567ffffffffffffffff808211156138af57600080fd5b908701906060828a0312156138c357600080fd5b909550602087013590808211156138d957600080fd5b818801915088601f8301126138ed57600080fd5b8135818111156138fc57600080fd5b8960208260051b850101111561391157600080fd5b60208301965080955050505061392960408701613874565b9150613937606087016137b2565b90509295509295909350565b60008060006060848603121561395857600080fd5b833561396381613790565b9250602084013561397381613790565b929592945050506040919091013590565b6000806000806080858703121561399a57600080fd5b84356139a581613790565b966020860135965060408601359560600135945092505050565b600080600080608085870312156139d557600080fd5b84356139e081613790565b935060208501356139f081613866565b92506040850135613a0081613866565b9396929550929360600135925050565b600060208284031215613a2257600080fd5b5035919050565b600080600080600060a08688031215613a4157600080fd5b8535613a4c81613790565b94506020860135613a5c81613790565b94979496505050506040830135926060810135926080909101359150565b600060208284031215613a8c57600080fd5b813562ffffff8116811461251757600080fd5b600080600060608486031215613ab457600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613ae057600080fd5b833592506020840135613af281613790565b91506040840135613b0281613866565b809150509250925092565b60008060008060008060c08789031215613b2657600080fd5b8635613b3181613790565b95506020870135613b4181613790565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c5657610c56613b66565b8082028115828204841417610c5657610c56613b66565b600082613bf5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c2f57600080fd5b83018035915067ffffffffffffffff821115613c4a57600080fd5b6020019150600581901b3603821315613c6257600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613caa57600080fd5b813561251781613866565b80820180821115610c5657610c56613b66565b600060208284031215613cda57600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613d1257613d12613b66565b5060010190565b600060208284031215613d2b57600080fd5b815160ff8116811461251757600080fd5b600181815b80851115613d9557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d7b57613d7b613b66565b80851615613d8857918102915b93841c9390800290613d41565b509250929050565b600082613dac57506001610c56565b81613db957506000610c56565b8160018114613dcf5760028114613dd957613df5565b6001915050610c56565b60ff841115613dea57613dea613b66565b50506001821b610c56565b5060208310610133831016604e8410600b8410161715613e18575081810a610c56565b613e228383613d3c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e5457613e54613b66565b029392505050565b6000610c5360ff841683613d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060208284031215613eac57600080fd5b815161251781613866565b6000825160005b81811015613ed85760208186018101518583015201613ebe565b50600092019182525091905056fea2646970667358221220b9ac9302a4f5994f8f475c47dbbec88c653981e47b5085cd259b553ae7e2850664736f6c63430008140033
Verified Source Code Full Match
Compiler: v0.8.20+commit.a1b79de6
EVM: paris
Optimization: Yes (50000 runs)
PayerV3.sol 668 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
pragma abicoder v2;
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; // Interface for Uniswap v3's swap router, for executing token swaps.
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./lib/ArrayUtils.sol";
import {Errors} from "./lib/Errors.sol";
interface IWETH9 is IERC20 {
function deposit() external payable;
function withdraw(uint256) external payable;
}
contract PayerV3 {
using SafeERC20 for IERC20;
using ArrayUtils for address[]; // Enables ArrayUtils operations for address arrays.
address public owner1; // Address of the first owner.
address public owner2; // Address of the second owner.
address public service; // Address of a service account, for automated tasks.
struct Order {
address user; // The address of the user who created the order.
address tokenIn; // The address of the token being sold.
uint256 amountIn; // The amount of tokenIn being sold.
address tokenOut; // The address of the token being bought.
uint256 amountOut; // The amount of tokenOut being bought.
uint256 price; // The price at which the swap is executed.
uint256 additionalAmount; // Additional amount to be paid to the user
uint256 endTimestamp; // Timestamp when the order expires.
bool completed; // Whether the order has been completed.
bool claimed; // Whether the result of the order has been claimed.
}
struct ExecuteOrderParams {
// Parameters for executing multiple orders.
uint256[] orderIds; // Array of order IDs to execute.
bool[] swap; // Array indicating which orders should perform a swap.
uint256[] additionalAmount; // Array of additional amounts for each order.
}
constructor() {
owner1 = msg.sender; // Sets the deployer as the first owner.
payerAddress = owner1; // Initializes payerAddress to the first owner's address.
}
// Fallback and receive functions for handling direct ether transfers.
receive() external payable {}
modifier onlyOwners() {
// Ensures only the owners can call the modified function.
if (msg.sender != owner1 && msg.sender != owner2) {
revert Errors.NotAllowedAddress();
}
_;
}
modifier onlyOwnerOrService() {
// Ensures only the owners or the service account can call the modified function.
if (
msg.sender != owner1 &&
msg.sender != owner2 &&
msg.sender != service
) {
revert Errors.NotAllowedAddress();
}
_;
}
ISwapRouter public constant swapRouter =
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); // Uniswap swap router
uint24 public poolFee = 3000; // Fee for liquidity pool usage, in basis points.
uint24 public constant maxAdditionalAmountPercentage = 750; // Maximum allowed percentage for additionalAmount, in basis points.
uint256 public acceptableTokensArrayLength; // Array length of acceptable token addresses.
uint256 constant swapDeadline = 10 minutes; // Deadline for completing swaps.
mapping(address => mapping(address => uint256)) public balances; // Tracks user balances of various tokens.
mapping(address => mapping(address => uint256)) public swapsIn; // Tracks incoming swaps.
mapping(address => mapping(address => uint256)) public swapsOut; // Tracks outgoing swaps.
mapping(address => uint256) public lastUserActionTime; // Tracks the last action time of users.
Order[] public orders; // Array of all orders.
mapping(address => bool) public acceptableTokens; // Tracks tokens that are acceptable for trading.
mapping(address => bool) public isUsdToken; // Tracks if a token is considered a USD token.
mapping(address => uint256) public minimalTokenAmounts; // Tracks minimal token amounts.
address[] public acceptableTokensArray; // Array of acceptable token addresses.
address public constant wethAddress =
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // Address of Wrapped ETH (WETH) contract.
address public payerAddress; // Address used for making payments.
uint public constant maxDuration = 90 days; // Maximum duration for orders.
uint public constant maxExecutionTime = 1 hours; // Maximum time for executing orders
uint public constant fullAccessAfter = 365 days; // The time that must pass after the user is inactive to gain access to his balances
// Events for logging contract actions
event Deposit(address indexed user, address indexed token, uint256 amount);
event NewOrder(
uint256 indexed orderId,
address indexed user,
address indexed token,
uint256 amount,
uint256 duration
);
event ClaimOrder(uint256 indexed orderId);
event FullWithdrawal(
address indexed user,
address indexed token,
uint256 amount
);
/**
* @dev This combines deposit and makeOrder placement in a single transaction for user convenience.
* Emits a {Deposit}, {NewOrder} events.
*/
function depositAndOrder(
address _tokenAddressIn,
address _tokenAddressOut,
uint256 _amountDeposit,
uint256 _amountOrder,
uint256 _price,
uint256 _duration
) public {
deposit(_tokenAddressIn, _amountDeposit);
makeOrder(
_tokenAddressIn,
_tokenAddressOut,
_amountOrder,
_price,
_duration
);
}
/**
* @dev This combines depositEth and makeOrder placement in a single transaction for user convenience.
* Allows a user to deposit ETH (as WETH) and immediately place an order.
* Emits a {Deposit}, {NewOrder} events.
*/
function depositEthAndOrder(
address _tokenAddressOut,
uint256 _amount,
uint256 _price,
uint256 _duration
) public payable {
depositEth();
makeOrder(wethAddress, _tokenAddressOut, _amount, _price, _duration);
}
/**
* @dev Create an order with the deposited tokens.
* Emits a {NewOrder} events.
*/
function makeOrder(
address _tokenAddressIn,
address _tokenAddressOut,
uint256 _amountIn,
uint256 _price,
uint256 _duration
) public {
// Checks ensure that the user has enough balance, the tokens are different, and the duration is within limits.
if (!(balances[_tokenAddressIn][msg.sender] >= _amountIn)) {
revert Errors.NoTokenBalance();
}
if (!(_tokenAddressIn != _tokenAddressOut)) {
revert Errors.SameTokens();
}
if (!(_duration < maxDuration)) {
revert Errors.DurationMoreMaximum();
}
if (!(_amountIn >= minimalTokenAmounts[_tokenAddressIn])) {
revert Errors.WrongAmount();
}
balances[_tokenAddressIn][msg.sender] =
balances[_tokenAddressIn][msg.sender] -
_amountIn; // Deduct the amount from the user's balance and create the order.
orders.push(
Order(
msg.sender,
_tokenAddressIn,
_amountIn,
_tokenAddressOut,
0,
_price,
0,
block.timestamp + _duration,
false,
false
)
);
_updateUserActionTime(); // Updates the timestamp of the user's last action.
emit NewOrder(
orders.length - 1,
msg.sender,
address(_tokenAddressIn),
_amountIn,
_duration
);
}
/**
* @dev Allows a user to deposit a specific token into their account on the contract.
* Emits a {Deposit} events.
*/
function deposit(address _tokenAddress, uint256 _amount) public payable {
// Checks for token acceptability and non-zero amounts are performed.
if (!acceptableTokens[_tokenAddress]) {
revert Errors.NotAllowedToken();
}
if (_amount == 0) {
revert Errors.NotAllowedZero();
}
IERC20(_tokenAddress).safeTransferFrom(
msg.sender,
address(this),
_amount
);
// Adds the amount to the user's balance and performs the token transfer.
balances[_tokenAddress][msg.sender] =
balances[_tokenAddress][msg.sender] +
_amount;
_updateUserActionTime(); // Updates the timestamp of the user's last action.
emit Deposit(msg.sender, _tokenAddress, _amount);
}
/**
* @dev Allows a user to deposit ETH, which is automatically wrapped into WETH.
* Emits a {Deposit} events.
*/
function depositEth() public payable {
// Checks for non-zero ETH amount.
if (!(msg.value > 0)) {
revert Errors.NotAllowedZero();
}
// Wraps the deposited ETH into WETH and updates the user's balance.
IWETH9(wethAddress).deposit{value: msg.value}();
balances[wethAddress][msg.sender] =
balances[wethAddress][msg.sender] +
msg.value;
_updateUserActionTime(); // Updates the timestamp of the user's last action.
emit Deposit(msg.sender, wethAddress, msg.value);
}
/**
* @dev Allows batch execution of orders based on the provided parameters.
*/
function executeOrders(
ExecuteOrderParams calldata _params,
uint256[] calldata _amountOutMinimum,
bool _claimOrders,
address _usdClaimToken
) public onlyOwnerOrService {
uint256 orderIdsLength = _params.orderIds.length;
// Ensures the consistency of the arrays' lengths and performs initial validations.
if (
!(orderIdsLength == _params.swap.length &&
_params.swap.length == _params.additionalAmount.length)
) {
revert Errors.DifferentLength();
}
// Loop through each order to perform initial checks and accumulate swap amounts.
for (uint256 i; i < orderIdsLength; ) {
Order storage order = orders[_params.orderIds[i]];
if (!(block.timestamp >= order.endTimestamp)) {
revert Errors.WrongExpirationTime();
}
if (order.claimed) {
revert Errors.OrderAlreadyClaimed();
}
if (order.completed) {
revert Errors.OrderAlreadyCompleted();
}
if (_params.swap[i]) {
swapsIn[order.tokenIn][order.tokenOut] += order.amountIn;
}
unchecked {
++i;
}
}
// Perform the swaps and update balances accordingly.
uint256 swapsCount;
for (uint256 i; i < acceptableTokensArrayLength; ) {
for (uint256 j; j < acceptableTokensArrayLength; ) {
if (
swapsIn[acceptableTokensArray[i]][
acceptableTokensArray[j]
] > 0
) {
IERC20(acceptableTokensArray[i]).forceApprove(
address(swapRouter),
swapsIn[acceptableTokensArray[i]][
acceptableTokensArray[j]
]
);
ISwapRouter.ExactInputSingleParams
memory swapParams = ISwapRouter.ExactInputSingleParams({
tokenIn: acceptableTokensArray[i],
tokenOut: acceptableTokensArray[j],
fee: poolFee,
recipient: address(this),
deadline: block.timestamp + swapDeadline,
amountIn: swapsIn[acceptableTokensArray[i]][
acceptableTokensArray[j]
],
amountOutMinimum: _amountOutMinimum[swapsCount],
sqrtPriceLimitX96: 0
});
uint256 amountOut = swapRouter.exactInputSingle(swapParams);
if (!(amountOut > _amountOutMinimum[swapsCount])) {
revert Errors.IncorrectAmountOut();
}
swapsOut[acceptableTokensArray[i]][
acceptableTokensArray[j]
] = amountOut;
swapsCount++;
}
unchecked {
++j;
}
}
unchecked {
++i;
}
}
for (uint256 i; i < orderIdsLength; ) {
_executeOrder(
_params.orderIds[i],
_params.swap[i],
_params.additionalAmount[i]
);
unchecked {
++i;
}
}
// A service on cheap ether networks can brand orders for the user, thereby reducing the user's interaction with the contact
if (_claimOrders) {
for (uint256 i; i < orderIdsLength; ) {
claimOrder(_params.orderIds[i], _usdClaimToken, false);
unchecked {
++i;
}
}
}
// Reset swapsIn map
for (uint256 i; i < acceptableTokensArrayLength; ) {
for (uint256 j; j < acceptableTokensArrayLength; ) {
swapsIn[acceptableTokensArray[i]][acceptableTokensArray[j]] = 0;
unchecked {
++j;
}
}
unchecked {
++i;
}
}
}
/**
* @dev Execution of the order. If the order requires swap then the swap is carried out in accordance with the amounts and proportions received after the exchange of tokens.
* There is also a record of additional funds allocated to the user
*/
function _executeOrder(
uint256 orderId,
bool swap,
uint256 additionalAmount
) private {
Order storage order = orders[orderId];
order.additionalAmount = additionalAmount;
order.completed = true;
if (swap) {
uint256 accuracy = wethAddress == order.tokenOut
? 1e10
: 10 ** IERC20Metadata(order.tokenOut).decimals();
uint256 proportionIn = calculateProportion(
swapsIn[order.tokenIn][order.tokenOut],
order.amountIn,
accuracy
);
uint256 swapAmountOut = (swapsOut[order.tokenIn][order.tokenOut] *
accuracy) / proportionIn;
uint256 remainder;
if (isUsdToken[order.tokenIn]) {
remainder =
swapAmountOut -
(order.amountIn *
10 ** IERC20Metadata(order.tokenOut).decimals()) /
order.price;
if (
!(order.additionalAmount <
calculatePercentage(
order.amountIn,
maxAdditionalAmountPercentage
))
) {
revert Errors.WrongAdditionalAmount();
}
} else {
remainder =
swapAmountOut -
(order.amountIn * order.price) /
10 ** IERC20Metadata(order.tokenIn).decimals();
if (
!(order.additionalAmount <
calculatePercentage(
swapAmountOut - remainder,
maxAdditionalAmountPercentage
))
) {
revert Errors.WrongAdditionalAmount();
}
}
order.amountOut = swapAmountOut - remainder;
balances[order.tokenOut][payerAddress] =
balances[order.tokenOut][payerAddress] +
remainder;
} else {
order.tokenOut = order.tokenIn;
order.amountOut = order.amountIn;
}
}
/**
* @dev Allows user to get funds deposited to balance inside the contract when creating an order with an additional reward.
* The _force parameter allows user to withdraw funds without receiving an additional amount
*/
function claimOrder(
uint256 _orderId,
address _usdToken,
bool _force
) public {
// Checks ensure the order hasn't already been claimed and is either completed or beyond its execution time.
Order storage order = orders[_orderId];
if (order.claimed) {
revert Errors.OrderAlreadyClaimed();
}
if (
!(order.completed ||
block.timestamp > order.endTimestamp + maxExecutionTime)
) {
revert Errors.OrderNotCompleted();
}
// Handle forced claims differently from regular claims.
if (!_force) {
// For regular claims, verify the USD token and manage additional amounts if applicable.
if (!isUsdToken[_usdToken]) {
revert Errors.IsNotUsdToken();
}
if (
order.additionalAmount > 0 &&
balances[_usdToken][payerAddress] >= order.additionalAmount
) {
_balanceTransfer(
_usdToken,
payerAddress,
order.user,
order.additionalAmount
);
}
} else {
// Forced claims are only available to the order's creator.
if (msg.sender != order.user) {
revert Errors.AvailableOnlyOwner();
}
}
if (
!order.completed &&
block.timestamp > order.endTimestamp + maxExecutionTime
) {
// If the order wasn't completed in time, revert to the original token and amount.
order.tokenOut = order.tokenIn;
order.amountOut = order.amountIn;
}
balances[order.tokenOut][order.user] =
balances[order.tokenOut][order.user] +
order.amountOut;
order.claimed = true;
if (msg.sender == order.user) {
_updateUserActionTime();
emit ClaimOrder(_orderId);
}
}
/**
* @dev Allows the user to withdraw their ERC20 tokens from the contract balance
*/
function fullWithdrawal(address _tokenAddress, uint256 _amount) public {
if (balances[_tokenAddress][msg.sender] < _amount) {
revert Errors.NoTokenBalance();
}
balances[_tokenAddress][msg.sender] =
balances[_tokenAddress][msg.sender] -
_amount;
IERC20(_tokenAddress).safeTransfer(msg.sender, _amount);
_updateUserActionTime();
emit FullWithdrawal(msg.sender, _tokenAddress, _amount);
}
/**
* @dev Allows the user to withdraw their ETH from the contract balance
*/
function fullWithdrawalETH(uint256 _amount) public payable {
if (balances[wethAddress][msg.sender] < _amount) {
revert Errors.NoTokenBalance();
}
balances[wethAddress][msg.sender] =
balances[wethAddress][msg.sender] -
_amount;
IWETH9(wethAddress).withdraw(_amount);
(bool sent, ) = msg.sender.call{value: _amount}("");
if (!sent) {
revert Errors.FailedToSendEther();
}
_updateUserActionTime();
emit FullWithdrawal(msg.sender, wethAddress, _amount);
}
/**
* @dev Сalculating the amount from the percentage
*/
function calculatePercentage(
uint256 _quantity,
uint256 _percentage
) public pure returns (uint256) {
return (_quantity * _percentage) / 10000;
}
/**
* @dev Сalculating Proportion
*/
function calculateProportion(
uint256 _quantity,
uint256 _total,
uint256 _accuracy
) public pure returns (uint256) {
return (_quantity * _accuracy) / _total;
}
/**
* @dev Provides the balance of a given token for a specified user.
*/
function balanceOf(
address _tokenAddress,
address _user
) public view returns (uint256) {
return balances[_tokenAddress][_user];
}
/**
* @dev Internal function to transfer balances within the contract.
*/
function _balanceTransfer(
address _tokenAddress,
address _sender,
address _recipient,
uint256 _amount
) internal {
balances[_tokenAddress][_sender] =
balances[_tokenAddress][_sender] -
_amount;
balances[_tokenAddress][_recipient] =
balances[_tokenAddress][_recipient] +
_amount;
}
/**
* @dev Internal function to updates the timestamp of the user's last action.
*/
function _updateUserActionTime() internal {
lastUserActionTime[msg.sender] = block.timestamp;
}
/**
* @dev Allows owners to update the list of acceptable tokens and their USD status.
*/
function editAcceptableToken(
address _token,
bool _value,
bool _isUsd,
uint256 _minimalAmount
) public onlyOwners {
isUsdToken[_token] = _isUsd;
if (_value) {
if (acceptableTokens[_token]) {
revert Errors.DuplicateToken();
}
if (_minimalAmount == 0) {
revert Errors.NotAllowedZero();
}
acceptableTokensArray.push(_token);
minimalTokenAmounts[_token] = _minimalAmount;
} else {
acceptableTokensArray.deleteItem(_token);
}
acceptableTokens[_token] = _value;
acceptableTokensArrayLength = acceptableTokensArray.length;
}
/**
* @dev Returns the contract's current Ether balance.
*/
function getEthBalance() public view returns (uint256) {
return address(this).balance;
}
/**
* @dev Allows the contract owners to withdraw Ether from the contract.
* NOTE: ETH cannot be on the contract during its standard use, since all incoming payments are immediately converted to WETH Token. This function allows to receive mistakenly sent funds
*/
function getBackEth(
address payable _to,
uint256 _amount
) external payable onlyOwners {
(bool sent, ) = _to.call{value: _amount}("");
if (!sent) {
revert Errors.FailedToSendEther();
}
}
/**
* @dev Allows owners to transfer out a user's tokens in emergency situations.
* NOTE: This function is intended as a last resort, for example if a user loses access to their account.
*/
function emergencyQuit(
address _user,
address _tokenAddress,
uint256 _amount
) external onlyOwners {
if (!(block.timestamp > lastUserActionTime[_user] + fullAccessAfter)) {
revert Errors.WrongTimestamp();
}
_balanceTransfer(_tokenAddress, _user, payerAddress, _amount);
}
/**
* @dev Returns the balance of a given token held by the contract.
*/
function getTokenBalance(IERC20 token) public view returns (uint256) {
return token.balanceOf(address(this));
}
/**
* @dev Assigns or updates the service address, which can be used for automated tasks or specific privileges.
*/
function setServiceAddress(address _address) external onlyOwners {
service = _address;
}
/**
* @dev Allows updating the address of the first owner.
*/
function setOwner1Address(address _address) external onlyOwners {
owner1 = _address;
}
/**
* @dev Allows updating the address of the second owner.
*/
function setOwner2Address(address _address) external onlyOwners {
owner2 = _address;
}
/**
* @dev Designates or updates the payer address, which might be used for distributing tokens or managing funds.
*/
function setPayerAddress() external onlyOwners {
payerAddress = msg.sender;
}
/**
* @dev Adjusts the pool fee for swaps conducted through Uniswap V3.
*/
function setPoolFee(uint24 _poolFee) external onlyOwners {
poolFee = _poolFee;
}
}
Errors.sol 25 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
library Errors {
error AvailableOnlyOwner();
error DifferentLength();
error DuplicateToken();
error DurationMoreMaximum();
error FailedToSendEther();
error IncorrectAmountOut();
error NoTokenBalance();
error NotAllowedToken();
error NotAllowedZero();
error NotAllowedAddress();
error OrderAlreadyClaimed();
error OrderNotCompleted();
error OrderAlreadyCompleted();
error SameTokens();
error WrongAdditionalAmount();
error WrongAmount();
error WrongExpirationTime();
error WrongTimestamp();
error IsNotUsdToken();
}
ArrayUtils.sol 23 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity =0.8.20;
library ArrayUtils {
function deleteItem(address[] storage self, address item)
internal
returns (bool success)
{
uint256 length = self.length;
for (uint256 i = 0; i < length; i++) {
if (self[i] == item) {
uint256 newLength = self.length - 1;
if (i != newLength) {
self[i] = self[newLength];
}
self[newLength] = self[self.length - 1];
self.pop();
return true;
}
}
}
}
Address.sol 159 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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);
}
SafeERC20.sol 118 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
ISwapRouter.sol 67 lines
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;
import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';
/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another token
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
/// @return amountOut The amount of the received token
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
/// @return amountOut The amount of the received token
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another token
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
/// @return amountIn The amount of the input token
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
/// @return amountIn The amount of the input token
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
IERC20Permit.sol 90 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
IERC20Metadata.sol 26 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
IUniswapV3SwapCallback.sol 21 lines
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
/// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
/// @dev In the implementation you must pay the pool tokens owed for the swap.
/// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
/// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
/// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
/// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
/// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
/// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
/// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) external;
}
Read Contract
acceptableTokens 0xb202416c → bool
acceptableTokensArray 0xb5e1a2cc → address
acceptableTokensArrayLength 0xcd626c28 → uint256
balanceOf 0xf7888aec → uint256
balances 0xc23f001f → uint256
calculatePercentage 0x2133e3b9 → uint256
calculateProportion 0xb54ae16e → uint256
fullAccessAfter 0x2c3f35b8 → uint256
getEthBalance 0x70ed0ada → uint256
getTokenBalance 0x3aecd0e3 → uint256
isUsdToken 0xc9df6508 → bool
lastUserActionTime 0x8a66cfd5 → uint256
maxAdditionalAmountPercentage 0xdbb1b5e0 → uint24
maxDuration 0x6db5c8fd → uint256
maxExecutionTime 0xde153a48 → uint256
minimalTokenAmounts 0xcd69bef5 → uint256
orders 0xa85c38ef → address, address, uint256, address, uint256, uint256, uint256, uint256, bool, bool
owner1 0x73688914 → address
owner2 0x52709725 → address
payerAddress 0x2b2f1e14 → address
poolFee 0x089fe6aa → uint24
service 0xd598d4c9 → address
swapRouter 0xc31c9c07 → address
swapsIn 0x9e43c9c9 → uint256
swapsOut 0x1980bc16 → uint256
wethAddress 0x4f0e0ef3 → address
Write Contract 17 functions
These functions modify contract state and require a wallet transaction to execute.
claimOrder 0xbb5c08fb
uint256 _orderId
address _usdToken
bool _force
deposit 0x47e7ef24
address _tokenAddress
uint256 _amount
depositAndOrder 0xbc66359e
address _tokenAddressIn
address _tokenAddressOut
uint256 _amountDeposit
uint256 _amountOrder
uint256 _price
uint256 _duration
depositEth 0x439370b1
No parameters
depositEthAndOrder 0x46c8fe64
address _tokenAddressOut
uint256 _amount
uint256 _price
uint256 _duration
editAcceptableToken 0x47b352e5
address _token
bool _value
bool _isUsd
uint256 _minimalAmount
emergencyQuit 0x3d2e9f46
address _user
address _tokenAddress
uint256 _amount
executeOrders 0xa3583a25
tuple _params
uint256[] _amountOutMinimum
bool _claimOrders
address _usdClaimToken
fullWithdrawal 0x18a042ec
address _tokenAddress
uint256 _amount
fullWithdrawalETH 0x66e0a4cd
uint256 _amount
getBackEth 0xf43084f7
address _to
uint256 _amount
makeOrder 0x6d626290
address _tokenAddressIn
address _tokenAddressOut
uint256 _amountIn
uint256 _price
uint256 _duration
setOwner1Address 0x6d6de7e9
address _address
setOwner2Address 0x068bcaba
address _address
setPayerAddress 0x04012690
No parameters
setPoolFee 0x73dd250c
uint24 _poolFee
setServiceAddress 0xf6e39640
address _address
Token Balances (3)
View Transfers →Recent Transactions
No transactions found for this address