Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xa8cE277Cb870D02562c1155fbe49c7983cC15481
Balance 0 ETH
Nonce 1
Code Size 19799 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

19799 bytes
0x608060405260043610610248575f3560e01c806390d49b9d11610134578063bec45f09116100b3578063e8f91f6811610078578063e8f91f6814610820578063ef2459531461083f578063f25f4b561461085e578063f2fde38b1461087d578063fc4e9db91461089c578063fe6f7a79146108b1575f80fd5b8063bec45f091461076a578063c89acd9314610796578063ce7842f5146107d7578063d3a17f29146107ec578063e6a053d014610801575f80fd5b8063a7da7e5e116100f9578063a7da7e5e146106c4578063a9b07c26146106d9578063ad3d0dd0146106ee578063b0957c371461070d578063b5f5478a1461074b575f80fd5b806390d49b9d1461063257806396ec50c31461065157806399c4abad146106705780639c1ecb5114610685578063a263e2b9146106b1575f80fd5b80633e8f682f116101cb578063650025a011610190578063650025a01461054d578063713494d71461056c578063715018a61461058b578063806ab0281461059f5780638da5cb5b146105be5780638f911b6e146105da575f80fd5b80633e8f682f146103ac57806342180106146103cb5780634cf1115d146103ea57806357bd2792146103ff578063623949761461042e575f80fd5b80631876b6fd116102115780631876b6fd1461030557806319edabae146103245780632637b3c21461034357806332fb14d81461037a578063390add5c1461038d575f80fd5b8062a672921461024c57806304df2de81461026d578063054877d71461028c578063164f519d1461029f57806318059e0d146102e6575b5f80fd5b348015610257575f80fd5b5061026b6102663660046147ec565b6108dd565b005b348015610278575f80fd5b5061026b610287366004614816565b610d25565b61026b61029a3660046147ec565b611376565b3480156102aa575f80fd5b506102d36102b9366004614868565b6001600160a01b03165f9081526011602052604090205490565b6040519081526020015b60405180910390f35b3480156102f1575f80fd5b5061026b610300366004614868565b61179e565b348015610310575f80fd5b5061026b61031f36600461488a565b611895565b34801561032f575f80fd5b5061026b61033e3660046148c9565b6118fa565b34801561034e575f80fd5b50600254610362906001600160a01b031681565b6040516001600160a01b0390911681526020016102dd565b61026b6103883660046147ec565b6119e5565b348015610398575f80fd5b5061026b6103a736600461488a565b611eb2565b3480156103b7575f80fd5b5061026b6103c6366004614908565b61226d565b3480156103d6575f80fd5b5061026b6103e53660046147ec565b612341565b3480156103f5575f80fd5b506102d3600b5481565b34801561040a575f80fd5b5061041e61041936600461488a565b612676565b6040516102dd949392919061491f565b348015610439575f80fd5b506104d46104483660046147ec565b600e60209081525f9283526040808420909152908252902080546001820154600283015460038401546004850154600586015460068701546007880154600890980154969795966001600160a01b03958616969486169593949293919260ff80821693610100830482169362010000840490911692600160b01b8104831692600160b81b90910416908d565b604080519d8e5260208e019c909c526001600160a01b039a8b169b8d019b909b5297891660608c015260808b019690965260a08a019490945260c0890192909252151560e0880152151561010087015290921661012085015290151561014084015215156101608301526101808201526101a0016102dd565b348015610558575f80fd5b50600654610362906001600160a01b031681565b348015610577575f80fd5b5061026b610586366004614908565b6126cf565b348015610596575f80fd5b5061026b6127c1565b3480156105aa575f80fd5b5061026b6105b93660046147ec565b6127d4565b3480156105c9575f80fd5b505f546001600160a01b0316610362565b3480156105e5575f80fd5b506106156105f4366004614908565b600f6020525f9081526040902080546001909101546001600160a01b031682565b604080519283526001600160a01b039091166020830152016102dd565b34801561063d575f80fd5b5061026b61064c366004614868565b612dcc565b34801561065c575f80fd5b5061041e61066b3660046147ec565b612ed7565b34801561067b575f80fd5b506102d360095481565b348015610690575f80fd5b506106a461069f366004614908565b612f23565b6040516102dd9190614971565b61026b6106bf3660046147ec565b612fd3565b3480156106cf575f80fd5b506102d3600a5481565b3480156106e4575f80fd5b506102d360055481565b3480156106f9575f80fd5b50600354610362906001600160a01b031681565b348015610718575f80fd5b5061073b610727366004614868565b60106020525f908152604090205460ff1681565b60405190151581526020016102dd565b348015610756575f80fd5b5061026b6107653660046148c9565b6134eb565b348015610775575f80fd5b506107896107843660046147ec565b6137cc565b6040516102dd919061499d565b3480156107a1575f80fd5b506102d36107b03660046147ec565b6001600160a01b03919091165f908152601260209081526040808320938352929052205490565b3480156107e2575f80fd5b506102d3600c5481565b3480156107f7575f80fd5b506102d360075481565b34801561080c575f80fd5b5061026b61081b366004614868565b61390c565b34801561082b575f80fd5b5061026b61083a3660046148c9565b6139fd565b34801561084a575f80fd5b5061026b61085936600461488a565b613c87565b348015610869575f80fd5b50600454610362906001600160a01b031681565b348015610888575f80fd5b5061026b610897366004614868565b613ce7565b3480156108a7575f80fd5b506102d360085481565b3480156108bc575f80fd5b506108d06108cb3660046147ec565b613d24565b6040516102dd9190614a68565b6108e5613dcb565b6001600160a01b038083165f908152600e6020908152604080832085845282529182902082516101a081018452815481526001820154928101929092526002810154841692820183905260038101548416606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff808216151560e08501526101008083048216151590850152620100008204909516610120840152600160b01b810485161515610140840152600160b81b9004909316151561016082015260089092015461018083015233146109dd5760405162461bcd60e51b81526004016109d490614ab5565b60405180910390fd5b60025460405163bb941cff60e01b8152600481018490525f9182916001600160a01b039091169063bb941cff9060240160a060405180830381865afa158015610a28573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a4c9190614af9565b50505091509150846001600160a01b0316826001600160a01b031614610a845760405162461bcd60e51b81526004016109d490614b49565b6001600160a01b0381163014610ae75760405162461bcd60e51b815260206004820152602260248201527f4d61726b6574706c61636520646f6573206e6f74206f776e20796f7572206c6f604482015261636b60f01b60648201526084016109d4565b82610160015115610c27575f601384610180015181548110610b0b57610b0b614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a0880152918652845191820185526004840154909216815260058301548187019081526006840154948201949094526007909201549082015292820192909252905190915015801590610bb3575080516040015115155b15610be557610bcc8686600187855f01515f0151613df5565b610be086865f8785602001515f0151613df5565b610c25565b80516040015115610c0457610be08686600187855f01515f0151613df5565b602080820151015115610c2557610c2586865f8785602001515f0151613df5565b505b8260e0015115610c72576001600160a01b0385165f908152600e6020908152604080832087845290915281206007908101805460ff19169055805491610c6c83614b9d565b91905055505b600254604051631317dfd560e21b8152600481018690523360248201526001600160a01b0390911690634c5f7f54906044015f604051808303815f87803b158015610cbb575f80fd5b505af1158015610ccd573d5f803e3d5ffd5b5050604080516001600160a01b0389168152602081018890527fd8d8dd977744d71ee93407138bda907529b982980d73888fe0c9b2e65a22b54a93500190505b60405180910390a1505050610d2160018055565b5050565b60025460405163bb941cff60e01b8152600481018690525f9182916001600160a01b039091169063bb941cff9060240160a060405180830381865afa158015610d70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d949190614af9565b50505091509150866001600160a01b0316826001600160a01b031614610dcc5760405162461bcd60e51b81526004016109d490614b49565b336001600160a01b03821614610e245760405162461bcd60e51b815260206004820152601760248201527f596f7520646f6e74206f776e2074686174206c6f636b2e00000000000000000060448201526064016109d4565b5f851180610e3157505f84115b610e895760405162461bcd60e51b8152602060048201526024808201527f596f75206d75737420736574206120707269636520696e2044726f7073206f726044820152630408aa8960e31b60648201526084016109d4565b6001600160a01b038088165f908152600e602090815260408083208a845282529182902082516101a08101845281548152600182015492810192909252600281015484169282019290925260038201548316606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e08401526101008083048216151590840152620100008204909416610120830152600160b01b810484161515610140830152600160b81b9004909216151561016083015260080154610180820152610f61614774565b81602001515f03610fe05760058054905f610f7b83614bb2565b90915550506040805180820182528981526001600160a01b038b81166020808401918252600580545f908152600f9092529490209251835551600190920180546001600160a01b0319169290911691909117905554610fd9906140de565b9050610ff0565b610fed82602001516140de565b90505b601381908060018154018082558091505060019003905f5260205f2090600802015f909190919091505f820151815f015f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010155604082015181600201556060820151816003015550506020820151816004015f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010155604082015181600201556060820151816003015550505050604051806101a001604052808981526020016005548152602001336001600160a01b031681526020018a6001600160a01b031681526020018881526020018781526020014281526020015f151581526020015f15158152602001866001600160a01b031681526020015f15158152602001600115158152602001601454815250600e5f8b6001600160a01b03166001600160a01b031681526020019081526020015f205f8a81526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506060820151816003015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015f6101000a81548160ff0219169083151502179055506101008201518160070160016101000a81548160ff0219169083151502179055506101208201518160070160026101000a8154816001600160a01b0302191690836001600160a01b031602179055506101408201518160070160166101000a81548160ff0219169083151502179055506101608201518160070160176101000a81548160ff021916908315150217905550610180820151816008015590505060145f8154809291906112c990614bb2565b90915550506001600160a01b0389165f9081526010602052604090205460ff16611323576001600160a01b0389165f908152601060205260408120805460ff19166001179055600880549161131d83614bb2565b91905055505b604080516001600160a01b038b168152602081018a9052338183015290517f59607239d3ee813dbfff34bf34115611fe94fb26e5b48a0ef8d4bf79aa14e4969181900360600190a1505050505050505050565b6001600160a01b0382165f908152600e6020908152604080832084845290915290206007810154600160b81b900460ff166113ed5760405162461bcd60e51b81526020600482015260176024820152762634b9ba34b733903737ba103337b91030bab1ba34b7b760491b60448201526064016109d4565b6002810154336001600160a01b039091160361144b5760405162461bcd60e51b815260206004820152601c60248201527f556e61626c6520746f20626964206f6e206f776e206c697374696e670000000060448201526064016109d4565b600781015460ff166114935760405162461bcd60e51b81526020600482015260116024820152702634b9ba34b7339034b730b1ba34bb329760791b60448201526064016109d4565b6007810154610100900460ff16156114bd5760405162461bcd60e51b81526004016109d490614bca565b5f60138260080154815481106114d5576114d5614b75565b905f5260205f2090600802019050805f016002015434116115385760405162461bcd60e51b815260206004820152601f60248201527f4d757374206f75746269642063757272656e742068696768657374206269640060448201526064016109d4565b60028101541561157e57805460028201546040516001600160a01b039092169181156108fc0291905f818181858888f1935050505015801561157c573d5f803e3d5ffd5b505b6040518060800160405280336001600160a01b031681526020015f81526020013481526020018360010154815250815f015f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010155604082015181600201556060820151816003015590505060115f336001600160a01b03166001600160a01b031681526020019081526020015f20815f01908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f82015f9054906101000a90046001600160a01b0316815f015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600182015481600101556002820154816002015560038201548160030155505060125f856001600160a01b03166001600160a01b031681526020019081526020015f205f8481526020019081526020015f20815f01908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f82015f9054906101000a90046001600160a01b0316815f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018201548160010155600282015481600201556003820154816003015550507f911d834cc781bcb7a08922b9dd1f1d175c0a0467d9705194c2e200f8ce2786bb3385855f34604051611790959493929190614bf9565b60405180910390a150505050565b6117a661413b565b6003546001600160a01b038083169116036117d35760405162461bcd60e51b81526004016109d490614c2a565b600d546001600160a01b03908116908216036118405760405162461bcd60e51b815260206004820152602660248201527f43616e74207365742064726f70732061646472657373206173207a65726f206160448201526564647265737360d01b60648201526084016109d4565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527feed32b1d15218d2b905229bcc6a4dd0a75381381080d5df9abf26df932900a40906020015b60405180910390a150565b61189d613dcb565b6001600160a01b038084165f908152600e602090815260408083208684529091529020600281015490911633146118e65760405162461bcd60e51b81526004016109d490614ab5565b6005018190556118f560018055565b505050565b61190261413b565b6001600160a01b0383165f908152600e6020908152604080832085845290915290206007810154600160b01b900460ff161515821515036119855760405162461bcd60e51b815260206004820152601a60248201527f4d757374206368616e6765206c697374696e672073746174757300000000000060448201526064016109d4565b60078101805460ff60b01b1916600160b01b179055604080516001600160a01b038616815260208101859052831515918101919091527f6ac07a0a54aac377d86e9a534e22075879c11393183985c4f8b532e54922e74390606001611790565b6119ed613dcb565b6001600160a01b038083165f908152600e6020908152604080832085845282529182902082516101a08101845281548152600182015492810192909252600281015484169282019290925260038201548316606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084018190526101008084048316151590850152620100008304909516610120840152600160b01b820481161515610140840152600160b81b90910416151561016082015260089091015461018082015290611add5760405162461bcd60e51b81526004016109d490614c6f565b5f8160a0015111611b305760405162461bcd60e51b815260206004820152601e60248201527f4c697374696e67206e6f7420666f722073616c6520696e2044726f70732e000060448201526064016109d4565b60a08101516003546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611b7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b9f9190614ca6565b11611be25760405162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10323937b8399760691b60448201526064016109d4565b60035460408281015160a084015191516323b872dd60e01b81523360048201526001600160a01b0391821660248201526044810192909252909116906323b872dd906064016020604051808303815f875af1158015611c43573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c679190614cbd565b611c6f575f80fd5b80610160015115611daf575f601382610180015181548110611c9357611c93614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a0880152918652845191820185526004840154909216815260058301548187019081526006840154948201949094526007909201549082015292820192909252905190915015801590611d3b575080516040015115155b15611d6d57611d548484600185855f01515f0151613df5565b611d6884845f8585602001515f0151613df5565b611dad565b80516040015115611d8c57611d688484600185855f01515f0151613df5565b602080820151015115611dad57611dad84845f8585602001515f0151613df5565b505b6001600160a01b0383165f908152600e6020908152604080832085845290915281206007908101805461ffff1916610100179055805491611def83614b9d565b9091555050600254604051631317dfd560e21b8152600481018490523360248201526001600160a01b0390911690634c5f7f54906044015f604051808303815f87803b158015611e3d575f80fd5b505af1158015611e4f573d5f803e3d5ffd5b50505050606081810151825160a0840151604080516001600160a01b0390941684526020840192909252908201527ffbbf21fadfc9dc43f3b916db2f7189d5d02b76b9913dc0cc5fe430a2408d5be7910160405180910390a150610d2160018055565b611eba613dcb565b6001600160a01b0383165f908152600e6020908152604080832085845290915290206007810154600160b81b900460ff16611f315760405162461bcd60e51b81526020600482015260176024820152762634b9ba34b733903737ba103337b91030bab1ba34b7b760491b60448201526064016109d4565b6002810154336001600160a01b0390911603611f8f5760405162461bcd60e51b815260206004820152601c60248201527f556e61626c6520746f20626964206f6e206f776e206c697374696e670000000060448201526064016109d4565b600781015460ff16611fd75760405162461bcd60e51b81526020600482015260116024820152702634b9ba34b7339034b730b1ba34bb329760791b60448201526064016109d4565b6007810154610100900460ff16156120015760405162461bcd60e51b81526004016109d490614bca565b5f601382600801548154811061201957612019614b75565b905f5260205f20906008020190508060040160010154831161207d5760405162461bcd60e51b815260206004820152601f60248201527f4d757374206f75746269642063757272656e742068696768657374206269640060448201526064016109d4565b60058101541561210857600354600482810154600584015460405163a9059cbb60e01b81526001600160a01b039283169381019390935260248301529091169063a9059cbb906044016020604051808303815f875af11580156120e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121069190614cbd565b505b6003546040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b03909116906323b872dd906064016020604051808303815f875af115801561215c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121809190614cbd565b50604080516080810182523380825260208083018790525f8385018190526001878101546060909501859052600487810180546001600160a01b03199081168717825560058a018c815560068b0186815560078c01998a55888752601188528a87208054808801825590885297872093549790940290920180549091166001600160a01b039096169590951785555491840191909155546002830155925460039091015591517f911d834cc781bcb7a08922b9dd1f1d175c0a0467d9705194c2e200f8ce2786bb9261225a92909189918991899190614bf9565b60405180910390a150506118f560018055565b61227561413b565b600a8111156122bb5760405162461bcd60e51b81526020600482015260126024820152714d6178696d756d206665652069732031302560701b60448201526064016109d4565b80600b540361230c5760405162461bcd60e51b815260206004820152601760248201527f596f75206d757374206368616e6765207468652066656500000000000000000060448201526064016109d4565b600b8190556040518181527f92e9901563c29600f17b7b8af210ae933bf96e332213cb87e7552dfa514267999060200161188a565b6001600160a01b038083165f908152600e6020908152604080832085845282529182902082516101a081018452815481526001820154928101929092526002810154841692820183905260038101548416606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff808216151560e08501526101008083048216151590850152620100008204909516610120840152600160b01b810485161515610140840152600160b81b9004909316151561016082015260089092015461018083015233146124605760405162461bcd60e51b815260206004820152601a60248201527f4c6f636b20646f65736e742062656c6f6e6720746f20796f752e00000000000060448201526064016109d4565b8060e00151156124b25760405162461bcd60e51b815260206004820152601760248201527f4c697374696e6720616c7265616479206163746976652e00000000000000000060448201526064016109d4565b806101000151156124d55760405162461bcd60e51b81526004016109d490614bca565b60025460405163bb941cff60e01b8152600481018490525f9182916001600160a01b039091169063bb941cff9060240160a060405180830381865afa158015612520573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125449190614af9565b50505091509150846001600160a01b0316826001600160a01b03161461257c5760405162461bcd60e51b81526004016109d490614b49565b6001600160a01b03811630146125e05760405162461bcd60e51b815260206004820152602360248201527f4c6f636b206f776e657273686970206e6f7420796574207472616e736665727260448201526232b21760e91b60648201526084016109d4565b6001600160a01b0385165f908152600e6020908152604080832087845290915281206007908101805460ff1916600117905580549161261e83614bb2565b91905055507fffc94e502ef8914a677eff4a2c6d414a0a0198c1ef347a351d3ce55b850600518360600151845f015185608001518660a00151604051612667949392919061491f565b60405180910390a15050505050565b6012602052825f5260405f20602052815f5260405f208181548110612699575f80fd5b5f91825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169550935090915084565b6126d761413b565b6032600c54111561273b5760405162461bcd60e51b815260206004820152602860248201527f4d6178696d756d20726566657272616c20626f6e757320697320353025206f66604482015267207468652066656560c01b60648201526084016109d4565b80600c540361278c5760405162461bcd60e51b815260206004820152601960248201527f596f75206d757374206368616e67652074686520626f6e75730000000000000060448201526064016109d4565b600c8190556040518181527f2d53ccc6ff6495c443d8e0b7f9f16ef2ed2ed00fe89b2f53ee258d09d5dc84269060200161188a565b6127c961413b565b6127d25f614167565b565b6127dc61413b565b6001600160a01b038083165f908152600e60209081526040808320858452909152902060028101549091166128535760405162461bcd60e51b815260206004820152601760248201527f4c697374696e6720646f6573206e6f742065786973742e00000000000000000060448201526064016109d4565b6007810154600160b81b900460ff1615612c75575f601382600801548154811061287f5761287f614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a0880152918652845191820185526004840154909216815260058301548187019081526006840154948201949094526007909201549082015292820192909252905190915015801590612927575080516040015115155b15612ac657604080516101a08101825283548152600184810154602083015260028501546001600160a01b039081169383019390935260038501548316606083015260048501546080830152600585015460a0830152600685015460c0830152600785015460ff808216151560e08501526101008083048216151590850152620100008204909416610120840152600160b01b810484161515610140840152600160b81b9004909216151561016082015260088401546101808201528251516129f39287928792613df5565b604080516101a08101825283548152600184015460208083019190915260028501546001600160a01b039081169383019390935260038501548316606083015260048501546080830152600585015460a0830152600685015460c0830152600785015460ff808216151560e08501526101008083048216151590850152620100008204909416610120840152600160b01b810484161515610140840152600160b81b9004909216151561016082015260088401546101808201529082015151612ac191869186915f91613df5565b612c73565b80516040015115612b9857604080516101a08101825283548152600184810154602083015260028501546001600160a01b039081169383019390935260038501548316606083015260048501546080830152600585015460a0830152600685015460c0830152600785015460ff808216151560e08501526101008083048216151590850152620100008204909416610120840152600160b01b810484161515610140840152600160b81b900490921615156101608201526008840154610180820152825151612ac19287928792613df5565b602080820151015115612c7357604080516101a08101825283548152600184015460208083019190915260028501546001600160a01b039081169383019390935260038501548316606083015260048501546080830152600585015460a0830152600685015460c0830152600785015460ff808216151560e08501526101008083048216151590850152620100008204909416610120840152600160b01b810484161515610140840152600160b81b9004909216151561016082015260088401546101808201529082015151612c7391869186915f91613df5565b505b6002805490820154604051631317dfd560e21b8152600481018590526001600160a01b039182166024820152911690634c5f7f54906044015f604051808303815f87803b158015612cc4575f80fd5b505af1158015612cd6573d5f803e3d5ffd5b50505050600781015460ff1615612d07576007808201805460ff191690558054905f612d0183614b9d565b91905055505b6001600160a01b038381165f818152600e60209081526040808320878452825280832083815560018101849055600280820180546001600160a01b031990811690915560038301805490911690556004820185905560058201859055600682018590556007820180546001600160c01b03191690556008909101939093559185015482519384529083018690529092168183015290517fcfdaf92a7e2c3e7092ed2ce4d1e8ff8628ba41454aba8ade74b09230ccd9e1d19181900360600190a1505050565b612dd461413b565b6004546001600160a01b03808316911603612e1f5760405162461bcd60e51b815260206004820152600b60248201526a14d85b59481dd85b1b195d60aa1b60448201526064016109d4565b600d546001600160a01b0390811690821603612e895760405162461bcd60e51b815260206004820152602360248201527f43616e7420736574206665652077616c6c6574206173207a65726f206164647260448201526265737360e81b60648201526084016109d4565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f446e39bcf1b47cfadfaa23442cb4b34682cfe6bd9220da084894e3b1f834e4f39060200161188a565b6011602052815f5260405f208181548110612ef0575f80fd5b5f91825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169450925084565b612f2b614774565b60138281548110612f3e57612f3e614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a08801529186528451918201855260048401549092168152600583015481870152600683015493810193909352600790910154908201529181019190915292915050565b612fdb613dcb565b6001600160a01b038083165f908152600e6020908152604080832085845282529182902082516101a08101845281548152600182015492810192909252600281015484169282019290925260038201548316606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084018190526101008084048316151590850152620100008304909516610120840152600160b01b820481161515610140840152600160b81b909104161515610160820152600890910154610180820152906130cb5760405162461bcd60e51b81526004016109d490614c6f565b5f81608001511161311e5760405162461bcd60e51b815260206004820152601c60248201527f4c697374696e67206e6f7420666f722073616c6520696e204554482e0000000060448201526064016109d4565b806080015134146131715760405162461bcd60e51b815260206004820152601860248201527f496e636f727265637420616d6f756e74206f66204554482e000000000000000060448201526064016109d4565b5f6064600b54346131829190614cd8565b61318c9190614cef565b90505f6131998234614d0e565b600d546101208501519192506001600160a01b03918216911614613258575f6064600c54846131c89190614cd8565b6131d29190614cef565b90506131de8184614d0e565b6101208501516040519194506001600160a01b03169082156108fc029083905f818181858888f19350505050158015613219573d5f803e3d5ffd5b506004546040516001600160a01b039091169084156108fc029085905f818181858888f19350505050158015613251573d5f803e3d5ffd5b5050613291565b6004546040516001600160a01b039091169083156108fc029084905f818181858888f1935050505015801561328f573d5f803e3d5ffd5b505b82604001516001600160a01b03166108fc8290811502906040515f60405180830381858888f193505050501580156132cb573d5f803e3d5ffd5b508261016001511561340c575f6013846101800151815481106132f0576132f0614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a0880152918652845191820185526004840154909216815260058301548187019081526006840154948201949094526007909201549082015292820192909252905190915015801590613398575080516040015115155b156133ca576133b18686600187855f01515f0151613df5565b6133c586865f8785602001515f0151613df5565b61340a565b805160400151156133e9576133c58686600187855f01515f0151613df5565b60208082015101511561340a5761340a86865f8785602001515f0151613df5565b505b6001600160a01b0385165f908152600e6020908152604080832087845290915281206007908101805461ffff191661010017905580549161344c83614b9d565b9091555050600254604051631317dfd560e21b8152600481018690523360248201526001600160a01b0390911690634c5f7f54906044015f604051808303815f87803b15801561349a575f80fd5b505af11580156134ac573d5f803e3d5ffd5b505050606084015184516040517f69a914f685e0f03a5a21bd63a3230c06f9bec4aea66717647b372fe4aeeb0e609350610d0d9291908590879061491f565b6134f3613dcb565b6001600160a01b0383165f908152600e602090815260408083208584529091528120600881015460138054929392909190811061353257613532614b75565b5f9182526020909120600284015460089092020191506001600160a01b031633146135965760405162461bcd60e51b815260206004820152601460248201527313dddb995c8818d85b881858d8d95c1d08189a5960621b60448201526064016109d4565b5f83156136785750600581015481901561367357604080516101a081018252845481526001850154602082015260028501546001600160a01b03908116928201929092526003850154821660608201526004808601546080830152600586015460a0830152600686015460c0830152600786015460ff808216151560e085015261010080830482161515908501526201000082048516610120850152600160b01b820481161515610140850152600160b81b9091041615156101608301526008860154610180830152840154613673928992899289159216613df5565b61374e565b50600281015460048201901561374e57604080516101a081018252845481526001850154602082015260028501546001600160a01b039081169282019290925260038501548216606082015260048501546080820152600585015460a0820152600685015460c0820152600785015460ff808216151560e084015261010080830482161515908401526201000082048416610120840152600160b01b820481161515610140840152600160b81b9091041615156101608201526008850154610180820152835461374e9289928992899216613df5565b5f816002015411801561375e5750835b8061377557505f8160010154118015613775575083155b6137b55760405162461bcd60e51b81526020600482015260116024820152700426964206d75737420657863656564203607c1b60448201526064016109d4565b6137c08382866141b6565b5050506118f560018055565b604080516101a0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152506001600160a01b038083165f908152600e6020908152604080832085845282529182902082516101a08101845281548152600182015492810192909252600281015484169282019290925260038201548316606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e08401526101008083048216151590840152620100008204909416610120830152600160b01b810484161515610140830152600160b81b90049092161515610160830152600801546101808201525b92915050565b61391461413b565b6002546001600160a01b038083169116036139415760405162461bcd60e51b81526004016109d490614c2a565b600d546001600160a01b03908116908216036139af5760405162461bcd60e51b815260206004820152602760248201527f43616e7420736574206c6f636b65722061646472657373206173207a65726f206044820152666164647265737360c81b60648201526084016109d4565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd1e25d3a5cb7db8e456f378c93f7c629672442690f78e6db92e8b706f4a14ee49060200161188a565b613a05613dcb565b6001600160a01b038084165f908152600e6020908152604080832086845282529182902082516101a08101845281548152600182015492810192909252600281015484169282019290925260038201548316606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e08401526101008083048216151590840152620100008204909416610120830152600160b01b810484161515610140830152600160b81b900490921615156101608301819052600890910154610180830152613b255760405162461bcd60e51b815260206004820152601b60248201527f4e6f2061756374696f6e20666f722074686973206c697374696e67000000000060448201526064016109d4565b5f601382610180015181548110613b3e57613b3e614b75565b5f9182526020918290206040805160c081018252600890930290910180546001600160a01b0390811684840190815260018301546060808701919091526002840154608080880191909152600385015460a08801529186528451918201855260048401549092168152600583015481870152600683015493810193909352600790910154908201529181019190915290508215613c2157805160400151613c1c5760405162461bcd60e51b8152602060048201526012602482015271139bc811551208189a59081c1c995cd95b9d60721b60448201526064016109d4565b613c6f565b5f81602001516020015111613c6f5760405162461bcd60e51b8152602060048201526014602482015273139bc8111c9bdc1cc8189a59081c1c995cd95b9d60621b60448201526064016109d4565b613c7c8585858533613df5565b50506118f560018055565b613c8f613dcb565b6001600160a01b038084165f908152600e60209081526040808320868452909152902060028101549091163314613cd85760405162461bcd60e51b81526004016109d490614ab5565b6004018190556118f560018055565b613cef61413b565b6001600160a01b038116613d1857604051631e4fbdf760e01b81525f60048201526024016109d4565b613d2181614167565b50565b6001600160a01b0382165f9081526012602090815260408083208484528252808320805482518185028101850190935280835260609492939192909184015b82821015613dbf575f848152602090819020604080516080810182526004860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003015460608301529083529092019101613d63565b50505050905092915050565b600260015403613dee57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b5f601383610180015181548110613e0e57613e0e614b75565b905f5260205f20906008020190508315613f595780546001600160a01b03838116911614613e7e5760405162461bcd60e51b815260206004820152601e60248201527f596f7520617265206e6f742074686520746f702045544820626964646572000060448201526064016109d4565b8054600282018054604080516080810182525f80825260208083018290529282018190529188015160609091018190526001600160a01b03198516865560018601829055925560038401919091556001600160a01b03909116908015613f52576040516001600160a01b0383169082156108fc029083905f818181858888f19350505050158015613f11573d5f803e3d5ffd5b507fd038669569294da1ed6a4b796b710f95383972092f174a8241d3ecfca9b737798489895f85604051613f49959493929190614bf9565b60405180910390a15b50506140d6565b60048101546001600160a01b03838116911614613fb85760405162461bcd60e51b815260206004820181905260248201527f596f7520617265206e6f742074686520746f702044726f70732062696464657260448201526064016109d4565b600481018054600583018054604080516080810182525f80825260208083018290529282018190529189015160609091018190526001600160a01b0319851690955591829055600685019190915560078401929092556001600160a01b03169080156140d35760035460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af115801561406e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140929190614cbd565b507fd038669569294da1ed6a4b796b710f95383972092f174a8241d3ecfca9b73779848989845f6040516140ca959493929190614bf9565b60405180910390a15b50505b505050505050565b6140e6614774565b6140ee614774565b60408051608080820183525f808352602080840182905283850182905260608085018990529386528451928301855281835282810182905293820152908101949094528101929092525090565b5f546001600160a01b031633146127d25760405163118cdaa760e01b81523360048201526024016109d4565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600783015460ff166141da5760405162461bcd60e51b81526004016109d490614c6f565b600254835460405163bb941cff60e01b815260048101919091525f916001600160a01b03169063bb941cff9060240160a060405180830381865afa158015614224573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142489190614af9565b50929350506001600160a01b038316915061429c90505760405162461bcd60e51b81526020600482015260126024820152714d69736d6174636820696e20696e7075747360701b60448201526064016109d4565b81156145495782600201544710156142e55760405162461bcd60e51b815260206004820152600c60248201526b125b9cdd59999a58da595b9d60a21b60448201526064016109d4565b5f6064600b5485600201546142fa9190614cd8565b6143049190614cef565b90505f8185600201546143179190614d0e565b5f6002870155600d5460078801549192506001600160a01b039081166201000090920416146143e6575f6064600c54846143519190614cd8565b61435b9190614cef565b90506143678184614d0e565b60078801546040519194506201000090046001600160a01b0316906108fc8315029083905f818181858888f193505050501580156143a7573d5f803e3d5ffd5b506004546040516001600160a01b039091169084156108fc029085905f818181858888f193505050501580156143df573d5f803e3d5ffd5b505061441f565b6004546040516001600160a01b039091169083156108fc029084905f818181858888f1935050505015801561441d573d5f803e3d5ffd5b505b60028601546040516001600160a01b039091169082156108fc029083905f818181858888f19350505050158015614458573d5f803e3d5ffd5b506007808701805461ffff19166101001790558054905f61447883614b9d565b909155505060025486548654604051631317dfd560e21b815260048101929092526001600160a01b03908116602483015290911690634c5f7f54906044015f604051808303815f87803b1580156144cd575f80fd5b505af11580156144df573d5f803e3d5ffd5b5050505060038601548654604080516001600160a01b03909316835260208301919091528101829052606081018390525f60808201527fdf9999b822a9ad830b81cf414b531921a00afd58dd5d785554b525802804b5f99060a00160405180910390a1505061476e565b60018301546003546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015614594573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145b89190614ca6565b116145fb5760405162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10323937b8399760691b60448201526064016109d4565b6001830154600354600286015460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303815f875af1158015614654573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146789190614cbd565b614680575f80fd5b5f600185018190556007808701805461ffff19166101001790558054916146a683614b9d565b909155505060025485548554604051631317dfd560e21b815260048101929092526001600160a01b03908116602483015290911690634c5f7f54906044015f604051808303815f87803b1580156146fb575f80fd5b505af115801561470d573d5f803e3d5ffd5b5050505060038501548554604080516001600160a01b03909316835260208301919091525f9082018190526060820152608081018290527fdf9999b822a9ad830b81cf414b531921a00afd58dd5d785554b525802804b5f99060a001612667565b50505050565b6040805160c0810182525f918101828152606082018390526080820183905260a082019290925290819081526020016147d360405180608001604052805f6001600160a01b031681526020015f81526020015f81526020015f81525090565b905290565b6001600160a01b0381168114613d21575f80fd5b5f80604083850312156147fd575f80fd5b8235614808816147d8565b946020939093013593505050565b5f805f805f60a0868803121561482a575f80fd5b8535614835816147d8565b9450602086013593506040860135925060608601359150608086013561485a816147d8565b809150509295509295909350565b5f60208284031215614878575f80fd5b8135614883816147d8565b9392505050565b5f805f6060848603121561489c575f80fd5b83356148a7816147d8565b95602085013595506040909401359392505050565b8015158114613d21575f80fd5b5f805f606084860312156148db575f80fd5b83356148e6816147d8565b92506020840135915060408401356148fd816148bc565b809150509250925092565b5f60208284031215614918575f80fd5b5035919050565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b80516001600160a01b031682526020808201519083015260408082015190830152606090810151910152565b5f61010082019050614984828451614945565b60208301516149966080840182614945565b5092915050565b5f6101a082019050825182526020830151602083015260408301516149cd60408401826001600160a01b03169052565b5060608301516149e860608401826001600160a01b03169052565b506080830151608083015260a083015160a083015260c083015160c083015260e0830151614a1a60e084018215159052565b5061010083810151151590830152610120808401516001600160a01b031690830152610140808401511515908301526101608084015115159083015261018092830151929091019190915290565b602080825282518282018190525f9190848201906040850190845b81811015614aa957614a96838551614945565b9284019260809290920191600101614a83565b50909695505050505050565b60208082526024908201527f54686973206c697374696e6720646f6573206e6f742062656c6f6e6720746f206040820152633cb7ba9760e11b606082015260800190565b5f805f805f60a08688031215614b0d575f80fd5b8551614b18816147d8565b6020870151909550614b29816147d8565b809450506040860151925060608601519150608086015161485a816148bc565b602080825260129082015271496e76616c6964204c50206164647265737360701b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f81614bab57614bab614b89565b505f190190565b5f60018201614bc357614bc3614b89565b5060010190565b6020808252601590820152742634b9ba34b7339030b63932b0b23c9039b7b6321760591b604082015260600190565b6001600160a01b03958616815293909416602084015260408301919091526060820152608081019190915260a00190565b60208082526025908201527f4d75737420696e70757420646966666572656e7420636f6e7472616374206164604082015264647265737360d81b606082015260800190565b60208082526017908201527f4c697374696e67206d757374206265206163746976652e000000000000000000604082015260600190565b5f60208284031215614cb6575f80fd5b5051919050565b5f60208284031215614ccd575f80fd5b8151614883816148bc565b808202811582820484141761390657613906614b89565b5f82614d0957634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561390657613906614b8956fea26469706673582212200860f05069db18eb8cb4942ba25b7948893cea19fb9729dd555d9e2a1306fb7e64736f6c63430008180033

Verified Source Code Partial Match

Compiler: v0.8.24+commit.e11b9ed9 EVM: shanghai Optimization: Yes (200 runs)
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 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);
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "./Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
ReentrancyGuard.sol 84 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}
DropsTeamFinanceV2.sol 1013 lines
//SPDX-License-Identifier: MIT

/*

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠛⠛⠛⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 

Drops Lock Marketplace is the first locked liquidity marketplace.
This smart contract is our Team Finance LP lock marketplace v2.

https://app.drops.site
https://drops.site
https://t.me/dropserc
https://x.com/dropserc

$DROPS token address -> 0xA562912e1328eEA987E04c2650EfB5703757850C
 
*/

pragma solidity ^0.8.0;
import "./Ownable.sol";
import "./IERC20.sol";
import "./ReentrancyGuard.sol";

interface ITeamFinanceLocker {
    function depositsByWithdrawalAddress(
        address userAddress,
        uint256 index
    ) external view returns (uint256);

    function lockedToken(
        uint256 lockId
    ) external view returns (address, address, uint256, uint256, bool);

    function transferLocks(uint256 lockId, address newOwner) external;
}

/// @title Marketplace for LP Token Lock Ownership
/// @notice This contract allows users to list and sell their Uniswap V2 LP token lock ownerships locked through Team Finance.
contract DropsTFMarketplace is Ownable, ReentrancyGuard {
    // Team Finance V2 Locker address
    ITeamFinanceLocker public tfLocker;

    // Native Drops token address
    IERC20 public dropsToken;
    address payable public feeWallet;
    uint256 public listingCount;
    address public marketplaceOwner;
    uint256 public activeListings;
    uint256 public listedLPsCount;
    uint256 public totalValueListedInDrops;
    uint256 public totalValueList;
    uint256 public ethFee;
    uint256 public referralBonus;

    // Zero address constant
    address zeroAddress = 0x0000000000000000000000000000000000000000;

    // Relevant listing info
    struct Listing {
        uint256 lockID;
        uint256 listingID;
        address payable seller;
        address lpAddress;
        uint256 priceInETH;
        uint256 priceInDrops;
        uint256 listDate;
        bool isActive;
        bool isSold;
        address payable referral;
        bool isVerified;
        bool forAuction;
        uint256 auctionIndex;
    }

    struct Bid {
        address bidder;
        uint256 dropsBid;
        uint256 ethBid;
        uint256 listingID;
    }

    struct ListingDetail {
        uint256 lockID;
        address lpAddress;
    }

    struct AuctionDetails {
        Bid topEthBid;
        Bid topDropsBid;
    }

    // lpAddress + lockID -> returns Listing
    mapping(address => mapping(uint256 => Listing)) public lpToLockID;
    mapping(uint256 => ListingDetail) public listingDetail;
    mapping(address => bool) public isLPListed;
    mapping(address => Bid[]) public userBids;
    mapping(address => mapping(uint256 => Bid[])) public lpBids;

    // Auctions:
    AuctionDetails[] auctions;
    uint256 auctionCount;

    // Relevant events
    event NewBid(
        address bidder,
        address lpAddress,
        uint256 lockID,
        uint256 bidInDrops,
        uint256 bidInEth
    );
    event BidRedacted(
        address bidder,
        address lpAddress,
        uint256 lockId,
        uint256 bidInDrops,
        uint bidInEth
    );
    event BidAccepted(
        address lpToken,
        uint256 lockId,
        uint256 profitInEth,
        uint256 feeEth,
        uint256 profitInDrops
    );
    event LockPurchasedWithETH(
        address lpToken,
        uint256 lockID,
        uint256 profitInETH,
        uint256 feeETH
    );
    event LockPurchasedWithDrops(
        address lpToken,
        uint256 lockID,
        uint256 profitInDrops
    );
    event ListingInitiated(address lpToken, uint256 lockID, address seller);
    event NewActiveListing(
        address lpToken,
        uint256 lockID,
        uint256 priceInETH,
        uint256 priceInDrops
    );
    event LockVerified(address lpToken, uint256 lockID, bool status);
    event ListingRedacted(address lpToken, uint256 lockID, address seller);
    event ListingWithdrawn(address lpToken, uint256 lockID);
    event DropsAddressUpdated(address _dropsAddress);
    event FeeAddressUpdated(address _feeWallet);
    event LockerAddressUpdated(address _lockerAddress);
    event ChangedETHFee(uint256 _ethFee);
    event ChangedReferralBonus(uint256 _referralBonus);

    /// @notice Initialize the contract with Uniswap V2 Locker, Fee Wallet, and Drops Token addresses
    /// @dev Sets the contract's dependencies and the owner upon deployment
    /// @param _tfLocker Address of the Uniswap V2 Locker contract
    /// @param _feeWallet Address of the wallet where fees will be collected
    /// @param _dropsTokenAddress Address of the Drops token contract
    constructor(
        address _tfLocker,
        address payable _feeWallet,
        address _dropsTokenAddress
    ) Ownable(msg.sender) {
        tfLocker = ITeamFinanceLocker(_tfLocker);
        feeWallet = _feeWallet;
        marketplaceOwner = msg.sender;
        dropsToken = IERC20(_dropsTokenAddress);
        ethFee = 10;
        referralBonus = 30;
    }

    /// @notice Set the referral fee (in percentage)
    /// @dev This function can only be called by the contract owner
    /// @param _referralBonus Referral fee percentage for buyLockWithETH
    function setReferralFee(uint256 _referralBonus) external onlyOwner {
        require(referralBonus <= 50, "Maximum referral bonus is 50% of the fee");
        require(referralBonus != _referralBonus, "You must change the bonus");
        referralBonus = _referralBonus;
        emit ChangedReferralBonus(_referralBonus);
    }

    /// @notice Set the eth fee (in percentage)
    /// @dev This function can only be called by the contract owner
    /// @param _ethFee Fee percentage for buyLockWithETH
    function setETHFee(uint256 _ethFee) external onlyOwner {
        require(_ethFee <= 10, "Maximum fee is 10%");
        require(ethFee != _ethFee, "You must change the fee");
        ethFee = _ethFee;
        emit ChangedETHFee(_ethFee);
    }

    /// @notice Set the address of the Drops token
    /// @dev This function can only be called by the contract owner
    /// @param _dropsTokenAddress The address of the Drops token contract
    function setDropsToken(address _dropsTokenAddress) external onlyOwner {
        require(
            address(dropsToken) != _dropsTokenAddress,
            "Must input different contract address"
        );
        require(
            _dropsTokenAddress != zeroAddress,
            "Cant set drops address as zero address"
        );
        dropsToken = IERC20(_dropsTokenAddress);
        emit DropsAddressUpdated(_dropsTokenAddress);
    }

    /// @notice Set the address of the fee wallet
    /// @dev This function can only be called by the contract owner
    /// @param _feeWallet The address of the new fee wallet
    function setFeeWallet(address payable _feeWallet) external onlyOwner {
        require(feeWallet != _feeWallet, "Same wallet");
        require(
            _feeWallet != zeroAddress,
            "Cant set fee wallet as zero address"
        );
        feeWallet = _feeWallet;
        emit FeeAddressUpdated(_feeWallet);
    }

    /// @notice Set the address of the liquidity locker
    /// @dev This function can only be called by the contract owner
    /// @param _tfLocker The address of the new liquidity locker
    function setLockerAddress(address _tfLocker) external onlyOwner {
        require(
            address(tfLocker) != _tfLocker,
            "Must input different contract address"
        );
        require(
            _tfLocker != zeroAddress,
            "Cant set locker address as zero address"
        );
        tfLocker = ITeamFinanceLocker(_tfLocker);
        emit LockerAddressUpdated(_tfLocker);
    }

    function _initializeAuctionDetails(
        uint256 _listingId
    ) internal pure returns (AuctionDetails memory) {
        AuctionDetails memory blankAuctionDetails;
        blankAuctionDetails.topEthBid = Bid(address(0), 0, 0, _listingId);
        blankAuctionDetails.topDropsBid = Bid(address(0), 0, 0, _listingId);

        return blankAuctionDetails;
    }

    /// @notice List an LP token lock for sale
    /// @dev The seller must be the owner of the lock and approve this contract to manage the lock
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    /// @param _priceInETH The selling price in ETH
    /// @param _priceInDrops The selling price in Drops tokens
    function initiateListing(
        address _lpAddress,
        uint256 _lockId,
        uint256 _priceInETH,
        uint256 _priceInDrops,
        address payable _referral
    ) external {
        (address __lpAddress, address owner, , , ) = tfLocker.lockedToken(
            _lockId
        );
        require(__lpAddress == _lpAddress, "Invalid LP address");
        require(msg.sender == owner, "You dont own that lock.");
        require(
            (_priceInETH > 0) || (_priceInDrops > 0),
            "You must set a price in Drops or ETH"
        );
        Listing memory tempListing = lpToLockID[_lpAddress][_lockId];

        AuctionDetails memory tempDetails;
        if (tempListing.listingID == 0) {
            listingCount++;
            listingDetail[listingCount] = ListingDetail(_lockId, _lpAddress);
            tempDetails = _initializeAuctionDetails(listingCount);
        } else {
            tempDetails = _initializeAuctionDetails(tempListing.listingID);
        }
        auctions.push(tempDetails);

        lpToLockID[_lpAddress][_lockId] = Listing(
            _lockId,
            listingCount,
            payable(msg.sender),
            _lpAddress,
            _priceInETH,
            _priceInDrops,
            block.timestamp,
            false,
            false,
            _referral,
            false,
            true,
            auctionCount
        );

        auctionCount++;

        if (!isLPListed[_lpAddress]) {
            isLPListed[_lpAddress] = true;
            listedLPsCount++;
        }

        emit ListingInitiated(_lpAddress, _lockId, msg.sender);
    }

    /// @notice Bid on a listing with Ethereum - transfer ETH to CA until bid is either beat, accepted, or withdrawn
    /// @dev Bidder must not be listing owner.
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    function bidEth(address _lpAddress, uint256 _lockId) external payable {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockId];
        require(tempListing.forAuction, "Listing not for auction");
        require(
            tempListing.seller != msg.sender,
            "Unable to bid on own listing"
        );
        require(tempListing.isActive, "Listing inactive.");
        require(!tempListing.isSold, "Listing already sold.");

        AuctionDetails storage currentAuction = auctions[
            tempListing.auctionIndex
        ];

        require(
            msg.value > currentAuction.topEthBid.ethBid,
            "Must outbid current highest bid"
        );

        if (currentAuction.topEthBid.ethBid > 0) {
            payable(currentAuction.topEthBid.bidder).transfer(
                currentAuction.topEthBid.ethBid
            );
        }

        currentAuction.topEthBid = Bid(
            msg.sender,
            0,
            msg.value,
            tempListing.listingID
        );

        userBids[msg.sender].push(currentAuction.topEthBid);
        lpBids[_lpAddress][_lockId].push(currentAuction.topEthBid);
        emit NewBid(msg.sender, _lpAddress, _lockId, 0, msg.value);
    }

    /// @notice Bid on a listing with Drops - transfer Drops to CA until bid is either beat, accepted, or withdrawn
    /// @dev Bidder must not be listing owner
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    /// @param _amount Amount of Drops to bid with
    function bidDrops(
        address _lpAddress,
        uint256 _lockId,
        uint256 _amount
    ) external nonReentrant {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockId];
        require(tempListing.forAuction, "Listing not for auction");
        require(
            tempListing.seller != msg.sender,
            "Unable to bid on own listing"
        );
        require(tempListing.isActive, "Listing inactive.");
        require(!tempListing.isSold, "Listing already sold.");

        AuctionDetails storage currentAuction = auctions[
            tempListing.auctionIndex
        ];

        require(
            _amount > currentAuction.topDropsBid.dropsBid,
            "Must outbid current highest bid"
        );

        if (currentAuction.topDropsBid.dropsBid > 0) {
            dropsToken.transfer(
                currentAuction.topDropsBid.bidder,
                currentAuction.topDropsBid.dropsBid
            );
        }

        dropsToken.transferFrom(msg.sender, address(this), _amount);

        currentAuction.topDropsBid = Bid(
            msg.sender,
            _amount,
            0,
            tempListing.listingID
        );

        userBids[msg.sender].push(currentAuction.topDropsBid);

        emit NewBid(msg.sender, _lpAddress, _lockId, _amount, 0);
    }

    function acceptBid(
        address _lpAddress,
        uint256 _lockId,
        bool _eth
    ) external nonReentrant {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockId];
        AuctionDetails storage tempAuction = auctions[tempListing.auctionIndex];
        require(tempListing.seller == msg.sender, "Owner can accept bid");

        Bid storage topBid;
        if (_eth) {
            topBid = tempAuction.topEthBid;
            if (tempAuction.topDropsBid.dropsBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    !_eth,
                    tempListing,
                    tempAuction.topDropsBid.bidder
                );
            }
        } else {
            topBid = tempAuction.topDropsBid;
            if (tempAuction.topEthBid.ethBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    _eth,
                    tempListing,
                    tempAuction.topEthBid.bidder
                );
            }
        }

        require(
            (topBid.ethBid > 0 && _eth) || (topBid.dropsBid > 0 && !_eth),
            "Bid must exceed 0"
        );

        _winAuction(tempListing, topBid, _eth);
    }

    function _winAuction(
        Listing storage _tempListing,
        Bid storage _winningBid,
        bool _eth
    ) private {
        require(_tempListing.isActive, "Listing must be active.");

        (address __lpAddress, , , , ) = tfLocker.lockedToken(
            _tempListing.lockID
        );
        require(__lpAddress != address(0), "Mismatch in inputs");

        if (_eth) {
            require(
                address(this).balance >= _winningBid.ethBid,
                "Insufficient"
            );
            uint256 feeAmount = _winningBid.ethBid * ethFee / 100;
            uint256 toPay = _winningBid.ethBid - feeAmount;
            _winningBid.ethBid = 0;

            if (_tempListing.referral != zeroAddress) {
                uint256 feeForReferral = (feeAmount * referralBonus) / 100;
                feeAmount = feeAmount - feeForReferral;
                _tempListing.referral.transfer(feeForReferral);
                feeWallet.transfer(feeAmount);
            } else {
                feeWallet.transfer(feeAmount);
            }

            payable(_tempListing.seller).transfer(toPay);
            _tempListing.isActive = false;
            _tempListing.isSold = true;
            activeListings--;

            tfLocker.transferLocks(_tempListing.lockID, _winningBid.bidder);

            emit BidAccepted(
                _tempListing.lpAddress,
                _tempListing.lockID,
                toPay,
                feeAmount,
                0
            );
        } else {
            require(
                dropsToken.balanceOf(address(this)) > _winningBid.dropsBid,
                "Insufficient drops."
            );

            uint256 toSend = _winningBid.dropsBid;
            require(dropsToken.transfer(_tempListing.seller, toSend));
            _winningBid.dropsBid = 0;

            _tempListing.isActive = false;
            _tempListing.isSold = true;
            activeListings--;

            tfLocker.transferLocks(_tempListing.lockID, _winningBid.bidder);

            emit BidAccepted(
                _tempListing.lpAddress,
                _tempListing.lockID,
                0,
                0,
                toSend
            );
        }
    }

    /// @notice Redact your bid on select lock - must be done prior to the expiry date of auction.
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    /// @param ethBid True if bidder is redacting a bid in ETH, false if bid is in Drops
    function redactBid(
        address _lpAddress,
        uint256 _lockId,
        bool ethBid
    ) external nonReentrant {
        Listing memory tempListing = lpToLockID[_lpAddress][_lockId];
        require(tempListing.forAuction, "No auction for this listing");

        AuctionDetails memory currentAuction = auctions[
            tempListing.auctionIndex
        ];

        if (ethBid) {
            require(currentAuction.topEthBid.ethBid > 0, "No ETH bid present");
        } else {
            require(
                currentAuction.topDropsBid.dropsBid > 0,
                "No Drops bid present"
            );
        }

        _returnBid(_lpAddress, _lockId, ethBid, tempListing, msg.sender);
    }

    function _returnBid(
        address _lpAddress,
        uint256 _lockId,
        bool _eth,
        Listing memory _tempListing,
        address _sender
    ) internal {
        AuctionDetails storage currentAuction = auctions[
            _tempListing.auctionIndex
        ];
        if (_eth) {
            require(
                currentAuction.topEthBid.bidder == _sender,
                "You are not the top ETH bidder"
            );
            address payable toSend = payable(currentAuction.topEthBid.bidder);
            uint256 amount = currentAuction.topEthBid.ethBid;
            currentAuction.topEthBid = Bid(
                address(0),
                0,
                0,
                _tempListing.listingID
            );

            if (amount > 0) {
                toSend.transfer(amount);

                emit BidRedacted(_sender, _lpAddress, _lockId, 0, amount);
            }
        } else {
            require(
                currentAuction.topDropsBid.bidder == _sender,
                "You are not the top Drops bidder"
            );
            address toSend = currentAuction.topDropsBid.bidder;
            uint256 amount = currentAuction.topDropsBid.dropsBid;
            currentAuction.topDropsBid = Bid(
                address(0),
                0,
                0,
                _tempListing.listingID
            );

            if (amount > 0) {
                dropsToken.transfer(toSend, amount);

                emit BidRedacted(_sender, _lpAddress, _lockId, amount, 0);
            }
        }
    }

    /// @notice Activate an initiated listing
    /// @dev The seller must have transfered lock ownership to address(this)
    /// @param _lpAddress Address of the LP token
    /// @param _lockId Unique lockID (per lpAddress) of the lock
    function activateListing(address _lpAddress, uint256 _lockId) external {
        Listing memory tempListing = lpToLockID[_lpAddress][_lockId];
        require(tempListing.seller == msg.sender, "Lock doesnt belong to you.");
        require(!tempListing.isActive, "Listing already active.");
        require(!tempListing.isSold, "Listing already sold.");
        (address __lpAddress, address owner, , , ) = tfLocker.lockedToken(
            _lockId
        );
        require(__lpAddress == _lpAddress, "Invalid LP address");
        require(owner == address(this), "Lock ownership not yet transferred.");
        lpToLockID[_lpAddress][_lockId].isActive = true;
        activeListings++;
        emit NewActiveListing(
            tempListing.lpAddress,
            tempListing.lockID,
            tempListing.priceInETH,
            tempListing.priceInDrops
        );
    }

    function fetchListing(
        address _lpAddress,
        uint256 _lockID
    ) external view returns (Listing memory) {
        return (lpToLockID[_lpAddress][_lockID]);
    }

    function totalUserBidsCount(address _user) external view returns (uint256) {
        return userBids[_user].length;
    }

    function totalLPBidsCount(
        address _lpAddress,
        uint256 _lockID
    ) public view returns (uint256) {
        return lpBids[_lpAddress][_lockID].length;
    }

    function fetchLPBids(
        address _lpAddress,
        uint256 _lockID
    ) external view returns (Bid[] memory) {
        return (lpBids[_lpAddress][_lockID]);
    }

    function fetchAuctionDetails(
        uint256 _auctionIndex
    ) external view returns (AuctionDetails memory) {
        return (auctions[_auctionIndex]);
    }

    /// @notice Purchase a listed LP token lock with ETH
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    function buyLockWithETH(
        address _lpAddress,
        uint256 _lockId
    ) external payable nonReentrant {
        Listing memory _tempListing = lpToLockID[_lpAddress][_lockId];
        require(_tempListing.isActive, "Listing must be active.");
        require(_tempListing.priceInETH > 0, "Listing not for sale in ETH.");
        require(
            msg.value == _tempListing.priceInETH,
            "Incorrect amount of ETH."
        );

        uint256 feeAmount = msg.value * ethFee / 100;
        uint256 toPay = msg.value - feeAmount;

        if (_tempListing.referral != zeroAddress) {
            uint256 feeForReferral = (feeAmount * referralBonus) / 100;
            feeAmount = feeAmount - feeForReferral;
            _tempListing.referral.transfer(feeForReferral);
            feeWallet.transfer(feeAmount);
        } else {
            feeWallet.transfer(feeAmount);
        }

        payable(_tempListing.seller).transfer(toPay);

        if (_tempListing.forAuction) {
            AuctionDetails memory currentAuction = auctions[
                _tempListing.auctionIndex
            ];

            if (
                currentAuction.topDropsBid.dropsBid > 0 &&
                currentAuction.topEthBid.ethBid > 0
            ) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    _tempListing,
                    currentAuction.topEthBid.bidder
                );

                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    _tempListing,
                    currentAuction.topDropsBid.bidder
                );
            } else if (currentAuction.topEthBid.ethBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    _tempListing,
                    currentAuction.topEthBid.bidder
                );
            } else if (currentAuction.topDropsBid.dropsBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    _tempListing,
                    currentAuction.topDropsBid.bidder
                );
            }
        }

        lpToLockID[_lpAddress][_lockId].isActive = false;
        lpToLockID[_lpAddress][_lockId].isSold = true;
        activeListings--;

        tfLocker.transferLocks(_lockId, payable(msg.sender));

        emit LockPurchasedWithETH(
            _tempListing.lpAddress,
            _tempListing.lockID,
            toPay,
            feeAmount
        );
    }

    /// @notice Purchase a listed LP token lock with Drops tokens
    /// @dev Requires approval to transfer Drops tokens to cover the purchase price
    /// @param _lpAddress Address of the LP token
    /// @param _lockID The ID of the lock
    function buyLockWithDrops(
        address _lpAddress,
        uint256 _lockID
    ) external payable nonReentrant {
        Listing memory tempListing = lpToLockID[_lpAddress][_lockID];

        require(tempListing.isActive, "Listing must be active.");
        require(tempListing.priceInDrops > 0, "Listing not for sale in Drops.");
        require(
            dropsToken.balanceOf(msg.sender) > tempListing.priceInDrops,
            "Insufficient drops."
        );

        require(
            dropsToken.transferFrom(
                msg.sender,
                tempListing.seller,
                tempListing.priceInDrops
            )
        );

        if (tempListing.forAuction) {
            AuctionDetails memory currentAuction = auctions[
                tempListing.auctionIndex
            ];

            if (
                currentAuction.topDropsBid.dropsBid > 0 &&
                currentAuction.topEthBid.ethBid > 0
            ) {
                _returnBid(
                    _lpAddress,
                    _lockID,
                    true,
                    tempListing,
                    currentAuction.topEthBid.bidder
                );

                _returnBid(
                    _lpAddress,
                    _lockID,
                    false,
                    tempListing,
                    currentAuction.topDropsBid.bidder
                );
            } else if (currentAuction.topEthBid.ethBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockID,
                    true,
                    tempListing,
                    currentAuction.topEthBid.bidder
                );
            } else if (currentAuction.topDropsBid.dropsBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockID,
                    false,
                    tempListing,
                    currentAuction.topDropsBid.bidder
                );
            }
        }

        lpToLockID[_lpAddress][_lockID].isActive = false;
        lpToLockID[_lpAddress][_lockID].isSold = true;
        activeListings--;

        tfLocker.transferLocks(_lockID, payable(msg.sender));

        emit LockPurchasedWithDrops(
            tempListing.lpAddress,
            tempListing.lockID,
            tempListing.priceInDrops
        );
    }

    /// @notice Withdraw a listed LP token lock
    /// @dev Only the seller can withdraw the listing
    /// @param _lpAddress Address of the LP token
    /// @param _lockId The ID of the lock
    function withdrawListing(
        address _lpAddress,
        uint256 _lockId
    ) external nonReentrant {
        Listing memory tempListing = lpToLockID[_lpAddress][_lockId];
        require(
            tempListing.seller == msg.sender,
            "This listing does not belong to you."
        );

        (address __lpAddress, address owner, , , ) = tfLocker.lockedToken(
            _lockId
        );
        require(__lpAddress == _lpAddress, "Invalid LP address");
        require(owner == address(this), "Marketplace does not own your lock");

        if (tempListing.forAuction) {
            AuctionDetails memory currentAuction = auctions[
                tempListing.auctionIndex
            ];

            if (
                currentAuction.topDropsBid.dropsBid > 0 &&
                currentAuction.topEthBid.ethBid > 0
            ) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    tempListing,
                    currentAuction.topEthBid.bidder
                );

                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    tempListing,
                    currentAuction.topDropsBid.bidder
                );
            } else if (currentAuction.topEthBid.ethBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    tempListing,
                    currentAuction.topEthBid.bidder
                );
            } else if (currentAuction.topDropsBid.dropsBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    tempListing,
                    currentAuction.topDropsBid.bidder
                );
            }
        }

        if (tempListing.isActive) {
            lpToLockID[_lpAddress][_lockId].isActive = false;
            activeListings--;
        }

        tfLocker.transferLocks(_lockId, payable(msg.sender));

        emit ListingWithdrawn(_lpAddress, _lockId);
    }

    /// @notice Verify a listing as safe
    /// @dev Only dev can verify listings
    /// @param _lpAddress Address of the LP token
    /// @param _lockID Unique lock ID (per lpAdress) of the lock
    /// @param status Status of verification
    function verifyListing(
        address _lpAddress,
        uint256 _lockID,
        bool status
    ) external onlyOwner {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockID];
        require(status != tempListing.isVerified, "Must change listing status");
        tempListing.isVerified = true;
        emit LockVerified(_lpAddress, _lockID, status);
    }

    /// @notice Change the ETH price of a listing
    /// @dev Only seller can change price
    /// @param _lpAddress Address of the LP token
    /// @param _lockID Unique lock ID (per lpAddress) of the lock
    /// @param newPriceInETH Updated ETH price of listing
    function changePriceInETH(
        address _lpAddress,
        uint256 _lockID,
        uint256 newPriceInETH
    ) external nonReentrant {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockID];
        require(
            tempListing.seller == msg.sender,
            "This listing does not belong to you."
        );
        tempListing.priceInETH = newPriceInETH;
    }

    /// @notice Change the price of a listing in Drops
    /// @dev Only seller can change price
    /// @param _lpAddress Address of the LP token
    /// @param _lockID Unique lock ID (per lpAddress) of the lock
    /// @param newPriceInDrops Updated Drops price of listing
    function changePriceInDrops(
        address _lpAddress,
        uint256 _lockID,
        uint256 newPriceInDrops
    ) external nonReentrant {
        Listing storage tempListing = lpToLockID[_lpAddress][_lockID];
        require(
            tempListing.seller == msg.sender,
            "This listing does not belong to you."
        );
        tempListing.priceInDrops = newPriceInDrops;
    }

    /// @notice Return ownership of a lock to the original seller and remove the listing
    /// @dev Only the contract owner can call this function
    /// @param _lpAddress Address of the LP token associated with the lock
    /// @param _lockId The ID of the lock to be redacted
    function redactListing(
        address _lpAddress,
        uint256 _lockId
    ) external onlyOwner {
        Listing storage _tempListing = lpToLockID[_lpAddress][_lockId];

        require(_tempListing.seller != address(0), "Listing does not exist.");

        if (_tempListing.forAuction) {
            AuctionDetails memory currentAuction = auctions[
                _tempListing.auctionIndex
            ];

            if (
                currentAuction.topDropsBid.dropsBid > 0 &&
                currentAuction.topEthBid.ethBid > 0
            ) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    _tempListing,
                    currentAuction.topEthBid.bidder
                );

                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    _tempListing,
                    currentAuction.topDropsBid.bidder
                );
            } else if (currentAuction.topEthBid.ethBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    true,
                    _tempListing,
                    currentAuction.topEthBid.bidder
                );
            } else if (currentAuction.topDropsBid.dropsBid > 0) {
                _returnBid(
                    _lpAddress,
                    _lockId,
                    false,
                    _tempListing,
                    currentAuction.topDropsBid.bidder
                );
            }
        }

        tfLocker.transferLocks(_lockId, _tempListing.seller);

        if (_tempListing.isActive) {
            _tempListing.isActive = false;
            activeListings--;
        }

        delete lpToLockID[_lpAddress][_lockId];
        emit ListingRedacted(_lpAddress, _lockId, _tempListing.seller);
    }
}

Read Contract

activeListings 0xd3a17f29 → uint256
dropsToken 0xad3d0dd0 → address
ethFee 0x4cf1115d → uint256
feeWallet 0xf25f4b56 → address
fetchAuctionDetails 0x9c1ecb51 → tuple
fetchLPBids 0xfe6f7a79 → tuple[]
fetchListing 0xbec45f09 → tuple
isLPListed 0xb0957c37 → bool
listedLPsCount 0xfc4e9db9 → uint256
listingCount 0xa9b07c26 → uint256
listingDetail 0x8f911b6e → uint256, address
lpBids 0x57bd2792 → address, uint256, uint256, uint256
lpToLockID 0x62394976 → uint256, uint256, address, address, uint256, uint256, uint256, bool, bool, address, bool, bool, uint256
marketplaceOwner 0x650025a0 → address
owner 0x8da5cb5b → address
referralBonus 0xce7842f5 → uint256
tfLocker 0x2637b3c2 → address
totalLPBidsCount 0xc89acd93 → uint256
totalUserBidsCount 0x164f519d → uint256
totalValueList 0xa7da7e5e → uint256
totalValueListedInDrops 0x99c4abad → uint256
userBids 0x96ec50c3 → address, uint256, uint256, uint256

Write Contract 20 functions

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

acceptBid 0xb5f5478a
address _lpAddress
uint256 _lockId
bool _eth
activateListing 0x42180106
address _lpAddress
uint256 _lockId
bidDrops 0x390add5c
address _lpAddress
uint256 _lockId
uint256 _amount
bidEth 0x054877d7
address _lpAddress
uint256 _lockId
buyLockWithDrops 0x32fb14d8
address _lpAddress
uint256 _lockID
buyLockWithETH 0xa263e2b9
address _lpAddress
uint256 _lockId
changePriceInDrops 0x1876b6fd
address _lpAddress
uint256 _lockID
uint256 newPriceInDrops
changePriceInETH 0xef245953
address _lpAddress
uint256 _lockID
uint256 newPriceInETH
initiateListing 0x04df2de8
address _lpAddress
uint256 _lockId
uint256 _priceInETH
uint256 _priceInDrops
address _referral
redactBid 0xe8f91f68
address _lpAddress
uint256 _lockId
bool ethBid
redactListing 0x806ab028
address _lpAddress
uint256 _lockId
renounceOwnership 0x715018a6
No parameters
setDropsToken 0x18059e0d
address _dropsTokenAddress
setETHFee 0x3e8f682f
uint256 _ethFee
setFeeWallet 0x90d49b9d
address _feeWallet
setLockerAddress 0xe6a053d0
address _tfLocker
setReferralFee 0x713494d7
uint256 _referralBonus
transferOwnership 0xf2fde38b
address newOwner
verifyListing 0x19edabae
address _lpAddress
uint256 _lockID
bool status
withdrawListing 0x00a67292
address _lpAddress
uint256 _lockId

Recent Transactions

No transactions found for this address