Address Contract Partially Verified
Address
0x39da41747a83aeE658334415666f3EF92DD0D541
Balance
0 ETH
Nonce
1
Code Size
14571 bytes
Creator
0xcD0313FD...6cB6 at tx 0xece66985...9945fa
Indexed Transactions
0
Contract Bytecode
14571 bytes
0x6080604052600436106102a45760003560e01c80638da5cb5b1161016e578063ccf3dc82116100cb578063ecb96fe61161007f578063f23a6e6111610064578063f23a6e6114610797578063f2fde38b146107c4578063fc525395146107e457600080fd5b8063ecb96fe614610746578063f0b9e5ba1461076c57600080fd5b8063ddb382f9116100b0578063ddb382f9146106cd578063e4dd4b8a146106f1578063e6041f9a1461072657600080fd5b8063ccf3dc821461068d578063d8579704146106ad57600080fd5b8063b7ce33a211610122578063bc197c8111610107578063bc197c8114610629578063bd38837b14610658578063c5cadd7f1461067857600080fd5b8063b7ce33a2146105e9578063b92779631461060957600080fd5b80639f2ba09b116101535780639f2ba09b1461058f578063a1b62797146105af578063b19337a4146105c957600080fd5b80638da5cb5b1461055e5780639a2b81151461057c57600080fd5b806326e2dca21161021c5780635eacc63a116101d0578063715018a6116101b5578063715018a61461050957806381ea4ea61461051e57806383206e801461053e57600080fd5b80635eacc63a146104d65780636335f25e146104e957600080fd5b8063452a932011610201578063452a932014610476578063565528d7146104965780635d799f87146104b657600080fd5b806326e2dca2146104365780633a5750b61461045657600080fd5b806311f8541711610273578063180cb47f11610258578063180cb47f146103a4578063186b100c146103e45780631bd78748146103f757600080fd5b806311f8541714610340578063150b7a021461035f57600080fd5b806301ffc9a7146102b057806304824e70146102f657806309ba153d146103185780630a9254e41461032b57600080fd5b366102ab57005b600080fd5b3480156102bc57600080fd5b506102e16102cb3660046128b4565b6001600160e01b0319166301ffc9a760e01b1490565b60405190151581526020015b60405180910390f35b34801561030257600080fd5b506103166103113660046128fa565b610804565b005b610316610326366004612d22565b61085e565b34801561033757600080fd5b506103166109d7565b34801561034c57600080fd5b506006546102e190610100900460ff1681565b34801561036b57600080fd5b5061038b61037a366004612e18565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016102ed565b3480156103b057600080fd5b506103cc73cd0313fd7cca5648d2948c42c320ba50cd0e6cb681565b6040516001600160a01b0390911681526020016102ed565b6103166103f23660046130df565b610b9c565b34801561040357600080fd5b506104176104123660046131e8565b610c6e565b604080516001600160a01b0390931683529015156020830152016102ed565b34801561044257600080fd5b50610316610451366004613246565b610ca3565b34801561046257600080fd5b506103166104713660046131e8565b610da2565b34801561048257600080fd5b506002546103cc906001600160a01b031681565b3480156104a257600080fd5b506103166104b13660046132bc565b610e6f565b3480156104c257600080fd5b506103166104d13660046132fe565b610f39565b6103166104e4366004613337565b611084565b3480156104f557600080fd5b506004546103cc906001600160a01b031681565b34801561051557600080fd5b506103166111ad565b34801561052a57600080fd5b506103166105393660046128fa565b611201565b34801561054a57600080fd5b50610316610559366004613426565b6112cb565b34801561056a57600080fd5b506000546001600160a01b03166103cc565b61031661058a366004613443565b611326565b34801561059b57600080fd5b506103166105aa366004613480565b61138b565b3480156105bb57600080fd5b506006546102e19060ff1681565b3480156105d557600080fd5b506103166105e43660046128fa565b611446565b3480156105f557600080fd5b506103166106043660046134c1565b6114b0565b34801561061557600080fd5b506103166106243660046131e8565b6115e0565b34801561063557600080fd5b5061038b610644366004613556565b63bc197c8160e01b98975050505050505050565b34801561066457600080fd5b506003546103cc906001600160a01b031681565b34801561068457600080fd5b5061031661162d565b34801561069957600080fd5b506103166106a8366004613615565b61165a565b3480156106b957600080fd5b506103166106c83660046128fa565b6116ff565b3480156106d957600080fd5b506106e360055481565b6040519081526020016102ed565b3480156106fd57600080fd5b5061071161070c3660046131e8565b611787565b604080519283529015156020830152016102ed565b34801561073257600080fd5b50610316610741366004613426565b6117b8565b34801561075257600080fd5b506006546103cc906201000090046001600160a01b031681565b34801561077857600080fd5b5061038b610787366004613643565b63785cf2dd60e11b949350505050565b3480156107a357600080fd5b5061038b6107b236600461369f565b63f23a6e6160e01b9695505050505050565b3480156107d057600080fd5b506103166107df3660046128fa565b61181a565b3480156107f057600080fd5b506103166107ff3660046128fa565b6118e7565b6000546001600160a01b031633146108515760405162461bcd60e51b815260206004820181905260248201526000805160206138bf83398151915260448201526064015b60405180910390fd5b61085b8147611951565b50565b60015460011461089d5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610848565b600260015560005b8451518110156109b15784518051829081106108c3576108c361371b565b60200260200101516001600160a01b03166323b872dd3330886020015185815181106108f1576108f161371b565b60209081029190910101516040516001600160a01b03938416602482015292909116604483015260648201526084016040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516109599190613731565b6000604051808303816000865af19150503d8060008114610996576040519150601f19603f3d011682016040523d82523d6000602084013e61099b565b606091505b50505080806109a99061376c565b9150506108a5565b506109bb826119bb565b6109c483611a68565b6109cd81611d93565b5050600180555050565b6000546001600160a01b03163314610a1f5760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b73b7f7f6c52f2e2fdb1963eab30438024864c313f66001600160a01b031663ddd81f826040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a6e57600080fd5b505af1158015610a82573d6000803e3d6000fd5b5050604051631538f65960e31b815230600482015273b7f7f6c52f2e2fdb1963eab30438024864c313f6925063a9c7b2c89150602401602060405180830381865afa158015610ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af99190613793565b600480546001600160a01b0319166001600160a01b039290921691909117815560405163a22cb46560e01b815273c3f733ca98e0dad0386979eb96fb1722a1a05e699181019190915260016024820152737c40c393dc0f283f318791d746d894ddd36935729063a22cb46590604401600060405180830381600087803b158015610b8257600080fd5b505af1158015610b96573d6000803e3d6000fd5b50505050565b60065460ff16610bee5760405162461bcd60e51b815260206004820152601260248201527f747261646573206e6f7420616c6c6f77656400000000000000000000000000006044820152606401610848565b600154600114610c2d5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610848565b6002600155610c3b81611f9a565b610c46878787612082565b610c4f846119bb565b610c5883611a68565b610c6182611d93565b5050600180555050505050565b60078181548110610c7e57600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b900460ff1682565b6000546001600160a01b03163314610ceb5760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b60005b82811015610d9b57846001600160a01b03166323b872dd3084878786818110610d1957610d1961371b565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b158015610d7057600080fd5b505af1158015610d84573d6000803e3d6000fd5b505050508080610d939061376c565b915050610cee565b5050505050565b6000546001600160a01b03163314610dea5760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6040805180820190915290815260016020820181815260088054928301815560005291517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee360029092029182015590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4909101805460ff1916911515919091179055565b6000546001600160a01b03163314610eb75760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6040518060400160405280836001600160a01b0316815260200182151581525060078481548110610eea57610eea61371b565b600091825260209182902083519101805493909201511515600160a01b0274ffffffffffffffffffffffffffffffffffffffffff199093166001600160a01b0390911617919091179055505050565b6000546001600160a01b03163314610f815760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa158015610fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff391906137b0565b6040516001600160a01b03909216602483015260448201526064016040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516110479190613731565b6000604051808303816000865af19150503d8060008114610d9b576040519150601f19603f3d011682016040523d82523d6000602084013e610d9b565b6001546001146110c35760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610848565b600260015560005b815181101561119357737be8076f4ea4a4ad08075c2508e481d6c946d12b6001600160a01b03168282815181106111045761110461371b565b6020026020010151600001518383815181106111225761112261371b565b60200260200101516020015160405161113b9190613731565b60006040518083038185875af1925050503d8060008114611178576040519150601f19603f3d011682016040523d82523d6000602084013e61117d565b606091505b505050808061118b9061376c565b9150506110cb565b5047156111a65760008060008047335af1505b5060018055565b6000546001600160a01b031633146111f55760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6111ff6000612481565b565b6000546001600160a01b031633146112495760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b604080518082019091526001600160a01b03918216815260016020820181815260078054928301815560005291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688909101805492511515600160a01b0274ffffffffffffffffffffffffffffffffffffffffff199093169190931617179055565b6000546001600160a01b031633146113135760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6006805460ff1916911515919091179055565b6001546001146113655760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610848565b600260015561137381611a68565b47156111a65760008060008047335af1505060018055565b6000546001600160a01b031633146113d35760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b60405163095ea7b360e01b81526001600160a01b0383811660048301526024820183905284169063095ea7b3906044016020604051808303816000875af1158015611422573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9691906137c9565b6000546001600160a01b0316331461148e5760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146114f85760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b60005b848110156115d757866001600160a01b031663f242432a30848989868181106115265761152661371b565b9050602002013588888781811061153f5761153f61371b565b6040516001600160e01b031960e089901b1681526001600160a01b03968716600482015295909416602486015250604484019190915260209091020135606482015260a06084820152600060a482015260c401600060405180830381600087803b1580156115ac57600080fd5b505af11580156115c0573d6000803e3d6000fd5b5050505080806115cf9061376c565b9150506114fb565b50505050505050565b6000546001600160a01b031633146116285760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b600555565b6002546001600160a01b0316336001600160a01b03161461164d57600080fd5b6006805461ffff19169055565b6000546001600160a01b031633146116a25760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6040518060400160405280838152602001821515815250600884815481106116cc576116cc61371b565b60009182526020918290208351600292909202019081559101516001909101805460ff1916911515919091179055505050565b6000546001600160a01b031633146117475760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b600680546001600160a01b0390921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b6008818154811061179757600080fd5b60009182526020909120600290910201805460019091015490915060ff1682565b6000546001600160a01b031633146118005760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b600680549115156101000261ff0019909216919091179055565b6000546001600160a01b031633146118625760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b6001600160a01b0381166118de5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610848565b61085b81612481565b6000546001600160a01b0316331461192f5760405162461bcd60e51b815260206004820181905260248201526000805160206138bf8339815191526044820152606401610848565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600080600080600085875af19050806119b65760405162461bcd60e51b815260206004820152602160248201527f5f7472616e736665724574683a20457468207472616e73666572206661696c656044820152601960fa1b6064820152608401610848565b505050565b60005b8151811015611a645760035482516000916001600160a01b0316908490849081106119eb576119eb61371b565b602002602001015160000151604051611a049190613731565b600060405180830381855af49150503d8060008114611a3f576040519150601f19603f3d011682016040523d82523d6000602084013e611a44565b606091505b50509050611a51816124d1565b5080611a5c8161376c565b9150506119be565b5050565b60005b8151811015611a64576000806000600660029054906101000a90046001600160a01b03166001600160a01b031663b1283e77868681518110611aaf57611aaf61371b565b6020026020010151600001516040518263ffffffff1660e01b8152600401611ad991815260200190565b606060405180830381865afa158015611af6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b1a91906137e6565b92509250925080611b6d5760405162461bcd60e51b815260206004820152601760248201527f5f74726164653a20496e416374697665204d61726b65740000000000000000006044820152606401610848565b737be8076f4ea4a4ad08075c2508e481d6c946d12b6001600160a01b0384161480611bb45750737f268357a8c2552623316e2562d90e642bb538e56001600160a01b038416145b15611c5657826001600160a01b0316858581518110611bd557611bd561371b565b602002602001015160200151868681518110611bf357611bf361371b565b602002602001015160400151604051611c0c9190613731565b60006040518083038185875af1925050503d8060008114611c49576040519150601f19603f3d011682016040523d82523d6000602084013e611c4e565b606091505b505050611d7d565b600082611cf857836001600160a01b0316868681518110611c7957611c7961371b565b602002602001015160200151878781518110611c9757611c9761371b565b602002602001015160400151604051611cb09190613731565b60006040518083038185875af1925050503d8060008114611ced576040519150601f19603f3d011682016040523d82523d6000602084013e611cf2565b606091505b50611d6f565b836001600160a01b0316868681518110611d1457611d1461371b565b602002602001015160400151604051611d2d9190613731565b600060405180830381855af49150503d8060008114611d68576040519150601f19603f3d011682016040523d82523d6000602084013e611d6d565b606091505b505b509050611d7b816124d1565b505b5050508080611d8b9061376c565b915050611a6b565b4715611da55760008060008047335af1505b60005b8151811015611a64576000828281518110611dc557611dc561371b565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3991906137b0565b1115611f8857818181518110611e5157611e5161371b565b60200260200101516001600160a01b031663a9059cbb33848481518110611e7a57611e7a61371b565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eee91906137b0565b6040516001600160a01b03909216602483015260448201526064016040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611f429190613731565b6000604051808303816000865af19150503d8060008114611f7f576040519150601f19603f3d011682016040523d82523d6000602084013e611f84565b606091505b5050505b80611f928161376c565b915050611da8565b60055460208201511015611ff05760405162461bcd60e51b815260206004820152601060248201527f496e73756666696369656e7420666565000000000000000000000000000000006044820152606401610848565b60208101511561085b578051600780546000929081106120125761201261371b565b6000918252602091829020604080518082019091529101546001600160a01b0381168252600160a01b900460ff161515918101829052915061207457611a6473cd0313fd7cca5648d2948c42c320ba50cd0e6cb68360015b6020020151611951565b8051611a649083600161206a565b60005b8351518110156121915783518051829081106120a3576120a361371b565b60200260200101516001600160a01b03166323b872dd3330876020015185815181106120d1576120d161371b565b60209081029190910101516040516001600160a01b03938416602482015292909116604483015260648201526084016040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516121399190613731565b6000604051808303816000865af19150503d8060008114612176576040519150601f19603f3d011682016040523d82523d6000602084013e61217b565b606091505b50505080806121899061376c565b915050612085565b5060005b82518110156123a0578281815181106121b0576121b061371b565b6020026020010151600001516001600160a01b031673b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b03160361220f5761220a8382815181106121fd576121fd61371b565b60200260200101516124e0565b61238e565b8281815181106122215761222161371b565b6020026020010151600001516001600160a01b03167360cd862c9c687a9de49aecdc3a99b74a4fc54ab66001600160a01b03160361227b5761220a83828151811061226e5761226e61371b565b602002602001015161267f565b60005b8382815181106122905761229061371b565b6020026020010151604001515181101561238c578382815181106122b6576122b661371b565b6020026020010151600001516001600160a01b03166323b872dd6122d73390565b308786815181106122ea576122ea61371b565b60200260200101516040015185815181106123075761230761371b565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561236157600080fd5b505af1158015612375573d6000803e3d6000fd5b5050505080806123849061376c565b91505061227e565b505b806123988161376c565b915050612195565b5060005b8151811015610b96578181815181106123bf576123bf61371b565b6020026020010151600001516001600160a01b0316632eb2c2d66123e03390565b308585815181106123f3576123f361371b565b6020026020010151602001518686815181106124115761241161371b565b6020026020010151604001516040518563ffffffff1660e01b815260040161243c9493929190613863565b600060405180830381600087803b15801561245657600080fd5b505af115801561246a573d6000803e3d6000fd5b5050505080806124799061376c565b9150506123a4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8061085b573d6000803e3d6000fd5b60005b816040015151811015611a6457600082600001516001600160a01b031663581781688460400151848151811061251b5761251b61371b565b60200260200101516040518263ffffffff1660e01b815260040161254191815260200190565b602060405180830381865afa15801561255e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125829190613793565b90506001600160a01b03811633146125ea5760405162461bcd60e51b815260206004820152602560248201527f5f61636365707443727970746f50756e6b3a20696e76616c69642070756e6b2060448201526437bbb732b960d91b6064820152608401610848565b82600001516001600160a01b0316638264fe98846040015184815181106126135761261361371b565b60200260200101516040518263ffffffff1660e01b815260040161263991815260200190565b600060405180830381600087803b15801561265357600080fd5b505af1158015612667573d6000803e3d6000fd5b505050505080806126779061376c565b9150506124e3565b60005b816040015151811015611a645760006126b7836040015183815181106126aa576126aa61371b565b6020026020010151612845565b8351604051633894ca5760e01b81527fffffffffff000000000000000000000000000000000000000000000000000000831660048201529192506000916001600160a01b0390911690633894ca5790602401602060405180830381865afa158015612726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061274a9190613793565b90506001600160a01b03811633146127b25760405162461bcd60e51b815260206004820152602560248201527f5f6163636570744d6f6f6e4361743a20696e76616c6964206d6f6f6e6361742060448201526437bbb732b960d91b6064820152608401610848565b83516040516301be705160e41b81527fffffffffff000000000000000000000000000000000000000000000000000000841660048201526001600160a01b0390911690631be7051090602401600060405180830381600087803b15801561281857600080fd5b505af115801561282c573d6000803e3d6000fd5b505050505050808061283d9061376c565b915050612682565b6040805160208082528183019092526000918291906020820181803683375050506020810184815260405191925060059081830190600a8401905b81831015612898578051835260209283019201612880565b505060058352601f01601f191660405250602001519392505050565b6000602082840312156128c657600080fd5b81356001600160e01b0319811681146128de57600080fd5b9392505050565b6001600160a01b038116811461085b57600080fd5b60006020828403121561290c57600080fd5b81356128de816128e5565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561295057612950612917565b60405290565b6040516060810167ffffffffffffffff8111828210171561295057612950612917565b6040516020810167ffffffffffffffff8111828210171561295057612950612917565b604051601f8201601f1916810167ffffffffffffffff811182821017156129c5576129c5612917565b604052919050565b600067ffffffffffffffff8211156129e7576129e7612917565b5060051b60200190565b600082601f830112612a0257600080fd5b81356020612a17612a12836129cd565b61299c565b82815260059290921b84018101918181019086841115612a3657600080fd5b8286015b84811015612a5a578035612a4d816128e5565b8352918301918301612a3a565b509695505050505050565b600082601f830112612a7657600080fd5b81356020612a86612a12836129cd565b82815260059290921b84018101918181019086841115612aa557600080fd5b8286015b84811015612a5a5780358352918301918301612aa9565b600060408284031215612ad257600080fd5b612ada61292d565b9050813567ffffffffffffffff80821115612af457600080fd5b612b00858386016129f1565b83526020840135915080821115612b1657600080fd5b50612b2384828501612a65565b60208301525092915050565b600082601f830112612b4057600080fd5b813567ffffffffffffffff811115612b5a57612b5a612917565b612b6d601f8201601f191660200161299c565b818152846020838601011115612b8257600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112612bb057600080fd5b81356020612bc0612a12836129cd565b82815260059290921b84018101918181019086841115612bdf57600080fd5b8286015b84811015612a5a57803567ffffffffffffffff80821115612c045760008081fd5b908801906060828b03601f1901811315612c1e5760008081fd5b612c26612956565b838801358152604080850135828a0152918401359183831115612c495760008081fd5b612c578d8a85880101612b2f565b908201528652505050918301918301612be3565b600082601f830112612c7c57600080fd5b81356020612c8c612a12836129cd565b82815260059290921b84018101918181019086841115612cab57600080fd5b8286015b84811015612a5a57803567ffffffffffffffff80821115612cd05760008081fd5b90880190818a03601f1901861315612ce85760008081fd5b612cf0612979565b8683013582811115612d025760008081fd5b612d108c8983870101612b2f565b82525085525050918301918301612caf565b60008060008060808587031215612d3857600080fd5b843567ffffffffffffffff80821115612d5057600080fd5b612d5c88838901612ac0565b95506020870135915080821115612d7257600080fd5b612d7e88838901612b9f565b94506040870135915080821115612d9457600080fd5b612da088838901612c6b565b93506060870135915080821115612db657600080fd5b50612dc3878288016129f1565b91505092959194509250565b60008083601f840112612de157600080fd5b50813567ffffffffffffffff811115612df957600080fd5b602083019150836020828501011115612e1157600080fd5b9250929050565b600080600080600060808688031215612e3057600080fd5b8535612e3b816128e5565b94506020860135612e4b816128e5565b935060408601359250606086013567ffffffffffffffff811115612e6e57600080fd5b612e7a88828901612dcf565b969995985093965092949392505050565b600082601f830112612e9c57600080fd5b81356020612eac612a12836129cd565b82815260059290921b84018101918181019086841115612ecb57600080fd5b8286015b84811015612a5a57803567ffffffffffffffff80821115612ef05760008081fd5b908801906060828b03601f1901811315612f0a5760008081fd5b612f12612956565b87840135612f1f816128e5565b815260408481013584811115612f355760008081fd5b612f438e8b838901016129f1565b838b015250918401359183831115612f5b5760008081fd5b612f698d8a85880101612a65565b908201528652505050918301918301612ecf565b600082601f830112612f8e57600080fd5b81356020612f9e612a12836129cd565b82815260059290921b84018101918181019086841115612fbd57600080fd5b8286015b84811015612a5a57803567ffffffffffffffff80821115612fe25760008081fd5b908801906060828b03601f1901811315612ffc5760008081fd5b613004612956565b87840135613011816128e5565b8152604084810135848111156130275760008081fd5b6130358e8b83890101612a65565b838b01525091840135918383111561304d5760008081fd5b61305b8d8a85880101612a65565b908201528652505050918301918301612fc1565b600082601f83011261308057600080fd5b6040516040810181811067ffffffffffffffff821117156130a3576130a3612917565b80604052508060408401858111156130ba57600080fd5b845b818110156130d45780358352602092830192016130bc565b509195945050505050565b6000806000806000806000610100888a0312156130fb57600080fd5b873567ffffffffffffffff8082111561311357600080fd5b61311f8b838c01612ac0565b985060208a013591508082111561313557600080fd5b6131418b838c01612e8b565b975060408a013591508082111561315757600080fd5b6131638b838c01612f7d565b965060608a013591508082111561317957600080fd5b6131858b838c01612c6b565b955060808a013591508082111561319b57600080fd5b6131a78b838c01612b9f565b945060a08a01359150808211156131bd57600080fd5b506131ca8a828b016129f1565b9250506131da8960c08a0161306f565b905092959891949750929550565b6000602082840312156131fa57600080fd5b5035919050565b60008083601f84011261321357600080fd5b50813567ffffffffffffffff81111561322b57600080fd5b6020830191508360208260051b8501011115612e1157600080fd5b6000806000806060858703121561325c57600080fd5b8435613267816128e5565b9350602085013567ffffffffffffffff81111561328357600080fd5b61328f87828801613201565b90945092505060408501356132a3816128e5565b939692955090935050565b801515811461085b57600080fd5b6000806000606084860312156132d157600080fd5b8335925060208401356132e3816128e5565b915060408401356132f3816132ae565b809150509250925092565b6000806040838503121561331157600080fd5b823561331c816128e5565b9150602083013561332c816128e5565b809150509250929050565b6000602080838503121561334a57600080fd5b823567ffffffffffffffff8082111561336257600080fd5b818501915085601f83011261337657600080fd5b8135613384612a12826129cd565b81815260059190911b830184019084810190888311156133a357600080fd5b8585015b83811015613419578035858111156133bf5760008081fd5b86016040818c03601f19018113156133d75760008081fd5b6133df61292d565b828a013581529082013590878211156133f85760008081fd5b6134068d8b84860101612b2f565b818b0152855250509186019186016133a7565b5098975050505050505050565b60006020828403121561343857600080fd5b81356128de816132ae565b60006020828403121561345557600080fd5b813567ffffffffffffffff81111561346c57600080fd5b61347884828501612b9f565b949350505050565b60008060006060848603121561349557600080fd5b83356134a0816128e5565b925060208401356134b0816128e5565b929592945050506040919091013590565b600080600080600080608087890312156134da57600080fd5b86356134e5816128e5565b9550602087013567ffffffffffffffff8082111561350257600080fd5b61350e8a838b01613201565b9097509550604089013591508082111561352757600080fd5b5061353489828a01613201565b9094509250506060870135613548816128e5565b809150509295509295509295565b60008060008060008060008060a0898b03121561357257600080fd5b883561357d816128e5565b9750602089013561358d816128e5565b9650604089013567ffffffffffffffff808211156135aa57600080fd5b6135b68c838d01613201565b909850965060608b01359150808211156135cf57600080fd5b6135db8c838d01613201565b909650945060808b01359150808211156135f457600080fd5b506136018b828c01612dcf565b999c989b5096995094979396929594505050565b60008060006060848603121561362a57600080fd5b833592506020840135915060408401356132f3816132ae565b6000806000806060858703121561365957600080fd5b8435613664816128e5565b935060208501359250604085013567ffffffffffffffff81111561368757600080fd5b61369387828801612dcf565b95989497509550505050565b60008060008060008060a087890312156136b857600080fd5b86356136c3816128e5565b955060208701356136d3816128e5565b94506040870135935060608701359250608087013567ffffffffffffffff8111156136fd57600080fd5b61370989828a01612dcf565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6000825160005b818110156137525760208186018101518583015201613738565b81811115613761576000828501525b509190910192915050565b60006001820161378c57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000602082840312156137a557600080fd5b81516128de816128e5565b6000602082840312156137c257600080fd5b5051919050565b6000602082840312156137db57600080fd5b81516128de816132ae565b6000806000606084860312156137fb57600080fd5b8351613806816128e5565b6020850151909350613817816132ae565b60408501519092506132f3816132ae565b600081518084526020808501945080840160005b838110156138585781518752958201959082019060010161383c565b509495945050505050565b60006001600160a01b03808716835280861660208401525060a0604083015261388f60a0830185613828565b82810360608401526138a18185613828565b83810360809094019390935250506000815260200194935050505056fe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a164736f6c634300080d000a
Verified Source Code Partial Match
Compiler: v0.8.13+commit.abaa5c0e
EVM: london
Optimization: Yes (800 runs)
BlurSwap.sol 504 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./utils/ReentrancyGuard.sol";
import "./markets/MarketRegistry.sol";
import "./SpecialTransferHelper.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IERC721.sol";
import "./interfaces/IERC1155.sol";
contract BlurSwap is SpecialTransferHelper, Ownable, ReentrancyGuard {
struct OpenseaTrades {
uint256 value;
bytes tradeData;
}
struct ERC20Details {
address[] tokenAddrs;
uint256[] amounts;
}
struct ERC1155Details {
address tokenAddr;
uint256[] ids;
uint256[] amounts;
}
struct ConverstionDetails {
bytes conversionData;
}
struct AffiliateDetails {
address affiliate;
bool isActive;
}
struct SponsoredMarket {
uint256 marketId;
bool isActive;
}
address public constant GOV = 0xcD0313FD7CCa5648d2948c42C320Ba50CD0E6cB6;
address public guardian;
address public converter;
address public punkProxy;
uint256 public baseFees;
bool public openForTrades;
bool public openForFreeTrades;
MarketRegistry public marketRegistry;
AffiliateDetails[] public affiliates;
SponsoredMarket[] public sponsoredMarkets;
modifier isOpenForTrades() {
require(openForTrades, "trades not allowed");
_;
}
modifier isOpenForFreeTrades() {
require(openForFreeTrades, "free trades not allowed");
_;
}
constructor(address _marketRegistry, address _guardian) {
marketRegistry = MarketRegistry(_marketRegistry);
guardian = _guardian;
baseFees = 0;
openForTrades = true;
openForFreeTrades = true;
}
function setUp() external onlyOwner {
// Create CryptoPunk Proxy
IWrappedPunk(0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6).registerProxy();
punkProxy = IWrappedPunk(0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6).proxyInfo(address(this));
// approve wrapped mooncats rescue to AcclimatedMoonCats contract
IERC721(0x7C40c393DC0f283F318791d746d894DdD3693572).setApprovalForAll(0xc3f733ca98E0daD0386979Eb96fb1722A1A05E69, true);
}
// @audit This function is used to approve specific tokens to specific market contracts with high volume.
// This is done in very rare cases for the gas optimization purposes.
function setOneTimeApproval(IERC20 token, address operator, uint256 amount) external onlyOwner {
token.approve(operator, amount);
}
function updateGuardian(address _guardian) external onlyOwner {
guardian = _guardian;
}
function addAffiliate(address _affiliate) external onlyOwner {
affiliates.push(AffiliateDetails(_affiliate, true));
}
function updateAffiliate(uint256 _affiliateIndex, address _affiliate, bool _IsActive) external onlyOwner {
affiliates[_affiliateIndex] = AffiliateDetails(_affiliate, _IsActive);
}
function addSponsoredMarket(uint256 _marketId) external onlyOwner {
sponsoredMarkets.push(SponsoredMarket(_marketId, true));
}
function updateSponsoredMarket(uint256 _marketIndex, uint256 _marketId, bool _isActive) external onlyOwner {
sponsoredMarkets[_marketIndex] = SponsoredMarket(_marketId, _isActive);
}
function setBaseFees(uint256 _baseFees) external onlyOwner {
baseFees = _baseFees;
}
function setOpenForTrades(bool _openForTrades) external onlyOwner {
openForTrades = _openForTrades;
}
function setOpenForFreeTrades(bool _openForFreeTrades) external onlyOwner {
openForFreeTrades = _openForFreeTrades;
}
// @audit we will setup a system that will monitor the contract for any leftover
// assets. In case any asset is leftover, the system should be able to trigger this
// function to close all the trades until the leftover assets are rescued.
function closeAllTrades() external {
require(_msgSender() == guardian);
openForTrades = false;
openForFreeTrades = false;
}
function setConverter(address _converter) external onlyOwner {
converter = _converter;
}
function setMarketRegistry(MarketRegistry _marketRegistry) external onlyOwner {
marketRegistry = _marketRegistry;
}
function _transferEth(address _to, uint256 _amount) internal {
bool callStatus;
assembly {
// Transfer the ETH and store if it succeeded or not.
callStatus := call(gas(), _to, _amount, 0, 0, 0, 0)
}
require(callStatus, "_transferEth: Eth transfer failed");
}
function _collectFee(uint256[2] memory feeDetails) internal {
require(feeDetails[1] >= baseFees, "Insufficient fee");
if (feeDetails[1] > 0) {
AffiliateDetails memory affiliateDetails = affiliates[feeDetails[0]];
affiliateDetails.isActive
? _transferEth(affiliateDetails.affiliate, feeDetails[1])
: _transferEth(GOV, feeDetails[1]);
}
}
function _checkCallResult(bool _success) internal pure {
if (!_success) {
// Copy revert reason from call
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
function _transferFromHelper(
ERC20Details memory erc20Details,
SpecialTransferHelper.ERC721Details[] memory erc721Details,
ERC1155Details[] memory erc1155Details
) internal {
// transfer ERC20 tokens from the sender to this contract
for (uint256 i = 0; i < erc20Details.tokenAddrs.length; i++) {
erc20Details.tokenAddrs[i].call(abi.encodeWithSelector(0x23b872dd, msg.sender, address(this), erc20Details.amounts[i]));
}
// transfer ERC721 tokens from the sender to this contract
for (uint256 i = 0; i < erc721Details.length; i++) {
// accept CryptoPunks
if (erc721Details[i].tokenAddr == 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB) {
_acceptCryptoPunk(erc721Details[i]);
}
// accept Mooncat
else if (erc721Details[i].tokenAddr == 0x60cd862c9C687A9dE49aecdC3A99b74A4fc54aB6) {
_acceptMoonCat(erc721Details[i]);
}
// default
else {
for (uint256 j = 0; j < erc721Details[i].ids.length; j++) {
IERC721(erc721Details[i].tokenAddr).transferFrom(
_msgSender(),
address(this),
erc721Details[i].ids[j]
);
}
}
}
// transfer ERC1155 tokens from the sender to this contract
for (uint256 i = 0; i < erc1155Details.length; i++) {
IERC1155(erc1155Details[i].tokenAddr).safeBatchTransferFrom(
_msgSender(),
address(this),
erc1155Details[i].ids,
erc1155Details[i].amounts,
""
);
}
}
function _conversionHelper(
ConverstionDetails[] memory _converstionDetails
) internal {
for (uint256 i = 0; i < _converstionDetails.length; i++) {
// convert to desired asset
(bool success, ) = converter.delegatecall(_converstionDetails[i].conversionData);
// check if the call passed successfully
_checkCallResult(success);
}
}
function _trade(
MarketRegistry.TradeDetails[] memory _tradeDetails
) internal {
for (uint256 i = 0; i < _tradeDetails.length; i++) {
// get market details
(address _proxy, bool _isLib, bool _isActive) = marketRegistry.markets(_tradeDetails[i].marketId);
// market should be active
require(_isActive, "_trade: InActive Market");
// execute trade
if (_proxy == 0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b || _proxy == 0x7f268357A8c2552623316e2562D90e642bB538E5) {
_proxy.call{value:_tradeDetails[i].value}(_tradeDetails[i].tradeData);
} else {
(bool success, ) = _isLib
? _proxy.delegatecall(_tradeDetails[i].tradeData)
: _proxy.call{value:_tradeDetails[i].value}(_tradeDetails[i].tradeData);
// check if the call passed successfully
_checkCallResult(success);
}
}
}
// function _tradeSponsored(
// MarketRegistry.TradeDetails[] memory _tradeDetails,
// uint256 sponsoredMarketId
// ) internal returns (bool isSponsored) {
// for (uint256 i = 0; i < _tradeDetails.length; i++) {
// // check if the trade is for the sponsored market
// if (_tradeDetails[i].marketId == sponsoredMarketId) {
// isSponsored = true;
// }
// // get market details
// (address _proxy, bool _isLib, bool _isActive) = marketRegistry.markets(_tradeDetails[i].marketId);
// // market should be active
// require(_isActive, "_trade: InActive Market");
// // execute trade
// if (_proxy == 0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b) {
// _proxy.call{value:_tradeDetails[i].value}(_tradeDetails[i].tradeData);
// } else {
// (bool success, ) = _isLib
// ? _proxy.delegatecall(_tradeDetails[i].tradeData)
// : _proxy.call{value:_tradeDetails[i].value}(_tradeDetails[i].tradeData);
// // check if the call passed successfully
// _checkCallResult(success);
// }
// }
// }
function _returnDust(address[] memory _tokens) internal {
// return remaining ETH (if any)
assembly {
if gt(selfbalance(), 0) {
let callStatus := call(
gas(),
caller(),
selfbalance(),
0,
0,
0,
0
)
}
}
// return remaining tokens (if any)
for (uint256 i = 0; i < _tokens.length; i++) {
if (IERC20(_tokens[i]).balanceOf(address(this)) > 0) {
_tokens[i].call(abi.encodeWithSelector(0xa9059cbb, msg.sender, IERC20(_tokens[i]).balanceOf(address(this))));
}
}
}
function batchBuyFromOpenSea(
OpenseaTrades[] memory openseaTrades
) payable external nonReentrant {
// execute trades
for (uint256 i = 0; i < openseaTrades.length; i++) {
// execute trade
address(0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b).call{value:openseaTrades[i].value}(openseaTrades[i].tradeData);
}
// return remaining ETH (if any)
assembly {
if gt(selfbalance(), 0) {
let callStatus := call(
gas(),
caller(),
selfbalance(),
0,
0,
0,
0
)
}
}
}
function batchBuyWithETH(
MarketRegistry.TradeDetails[] memory tradeDetails
) payable external nonReentrant {
// execute trades
_trade(tradeDetails);
// return remaining ETH (if any)
assembly {
if gt(selfbalance(), 0) {
let callStatus := call(
gas(),
caller(),
selfbalance(),
0,
0,
0,
0
)
}
}
}
function batchBuyWithERC20s(
ERC20Details memory erc20Details,
MarketRegistry.TradeDetails[] memory tradeDetails,
ConverstionDetails[] memory converstionDetails,
address[] memory dustTokens
) payable external nonReentrant {
// transfer ERC20 tokens from the sender to this contract
for (uint256 i = 0; i < erc20Details.tokenAddrs.length; i++) {
erc20Details.tokenAddrs[i].call(abi.encodeWithSelector(0x23b872dd, msg.sender, address(this), erc20Details.amounts[i]));
}
// Convert any assets if needed
_conversionHelper(converstionDetails);
// execute trades
_trade(tradeDetails);
// return dust tokens (if any)
_returnDust(dustTokens);
}
// swaps any combination of ERC-20/721/1155
// User needs to approve assets before invoking swap
// WARNING: DO NOT SEND TOKENS TO THIS FUNCTION DIRECTLY!!!
function multiAssetSwap(
ERC20Details memory erc20Details,
SpecialTransferHelper.ERC721Details[] memory erc721Details,
ERC1155Details[] memory erc1155Details,
ConverstionDetails[] memory converstionDetails,
MarketRegistry.TradeDetails[] memory tradeDetails,
address[] memory dustTokens,
uint256[2] memory feeDetails // [affiliateIndex, ETH fee in Wei]
) payable external isOpenForTrades nonReentrant {
// collect fees
_collectFee(feeDetails);
// transfer all tokens
_transferFromHelper(
erc20Details,
erc721Details,
erc1155Details
);
// Convert any assets if needed
_conversionHelper(converstionDetails);
// execute trades
_trade(tradeDetails);
// return dust tokens (if any)
_returnDust(dustTokens);
}
// Utility function that is used for free swaps for sponsored markets
// WARNING: DO NOT SEND TOKENS TO THIS FUNCTION DIRECTLY!!!
// function multiAssetSwapWithoutFee(
// ERC20Details memory erc20Details,
// SpecialTransferHelper.ERC721Details[] memory erc721Details,
// ERC1155Details[] memory erc1155Details,
// ConverstionDetails[] memory converstionDetails,
// MarketRegistry.TradeDetails[] memory tradeDetails,
// address[] memory dustTokens,
// uint256 sponsoredMarketIndex
// ) payable external isOpenForFreeTrades nonReentrant {
// // fetch the marketId of the sponsored market
// SponsoredMarket memory sponsoredMarket = sponsoredMarkets[sponsoredMarketIndex];
// // check if the market is active
// require(sponsoredMarket.isActive, "multiAssetSwapWithoutFee: InActive sponsored market");
//
// // transfer all tokens
// _transferFromHelper(
// erc20Details,
// erc721Details,
// erc1155Details
// );
//
// // Convert any assets if needed
// _conversionHelper(converstionDetails);
//
// // execute trades
// bool isSponsored = _tradeSponsored(tradeDetails, sponsoredMarket.marketId);
//
// // check if the trades include the sponsored market
// require(isSponsored, "multiAssetSwapWithoutFee: trades do not include sponsored market");
//
// // return dust tokens (if any)
// _returnDust(dustTokens);
// }
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public virtual returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) public virtual returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return 0x150b7a02;
}
// Used by ERC721BasicToken.sol
function onERC721Received(
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return 0xf0b9e5ba;
}
function supportsInterface(bytes4 interfaceId)
external
virtual
view
returns (bool)
{
return interfaceId == this.supportsInterface.selector;
}
receive() external payable {}
// Emergency function: In case any ETH get stuck in the contract unintentionally
// Only owner can retrieve the asset balance to a recipient address
function rescueETH(address recipient) onlyOwner external {
_transferEth(recipient, address(this).balance);
}
// Emergency function: In case any ERC20 tokens get stuck in the contract unintentionally
// Only owner can retrieve the asset balance to a recipient address
function rescueERC20(address asset, address recipient) onlyOwner external {
asset.call(abi.encodeWithSelector(0xa9059cbb, recipient, IERC20(asset).balanceOf(address(this))));
}
// Emergency function: In case any ERC721 tokens get stuck in the contract unintentionally
// Only owner can retrieve the asset balance to a recipient address
function rescueERC721(address asset, uint256[] calldata ids, address recipient) onlyOwner external {
for (uint256 i = 0; i < ids.length; i++) {
IERC721(asset).transferFrom(address(this), recipient, ids[i]);
}
}
// Emergency function: In case any ERC1155 tokens get stuck in the contract unintentionally
// Only owner can retrieve the asset balance to a recipient address
function rescueERC1155(address asset, uint256[] calldata ids, uint256[] calldata amounts, address recipient) onlyOwner external {
for (uint256 i = 0; i < ids.length; i++) {
IERC1155(asset).safeTransferFrom(address(this), recipient, ids[i], amounts[i], "");
}
}
}
IERC20.sol 55 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IERC20 {
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Sets `amount` 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 amount) 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);
}
IERC721.sol 27 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IERC721 {
/// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
/// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
/// THEY MAY BE PERMANENTLY LOST
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `_from` is
/// not the current owner. Throws if `_to` is the zero address. Throws if
/// `_tokenId` is not a valid NFT.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) external;
function setApprovalForAll(address operator, bool approved) external;
function approve(address to, uint256 tokenId) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function balanceOf(address _owner) external view returns (uint256);
}
IERC1155.sol 23 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IERC1155 {
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external;
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
}
SpecialTransferHelper.sol 104 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "@openzeppelin/contracts/utils/Context.sol";
import "./interfaces/ICryptoPunks.sol";
import "./interfaces/IWrappedPunk.sol";
import "./interfaces/IMoonCatsRescue.sol";
contract SpecialTransferHelper is Context {
struct ERC721Details {
address tokenAddr;
address[] to;
uint256[] ids;
}
function _uintToBytes5(uint256 id)
internal
pure
returns (bytes5 slicedDataBytes5)
{
bytes memory _bytes = new bytes(32);
assembly {
mstore(add(_bytes, 32), id)
}
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(5, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, 5)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), 27)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, 5)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
assembly {
slicedDataBytes5 := mload(add(tempBytes, 32))
}
}
function _acceptMoonCat(ERC721Details memory erc721Details) internal {
for (uint256 i = 0; i < erc721Details.ids.length; i++) {
bytes5 catId = _uintToBytes5(erc721Details.ids[i]);
address owner = IMoonCatsRescue(erc721Details.tokenAddr).catOwners(catId);
require(owner == _msgSender(), "_acceptMoonCat: invalid mooncat owner");
IMoonCatsRescue(erc721Details.tokenAddr).acceptAdoptionOffer(catId);
}
}
function _transferMoonCat(ERC721Details memory erc721Details) internal {
for (uint256 i = 0; i < erc721Details.ids.length; i++) {
IMoonCatsRescue(erc721Details.tokenAddr).giveCat(_uintToBytes5(erc721Details.ids[i]), erc721Details.to[i]);
}
}
function _acceptCryptoPunk(ERC721Details memory erc721Details) internal {
for (uint256 i = 0; i < erc721Details.ids.length; i++) {
address owner = ICryptoPunks(erc721Details.tokenAddr).punkIndexToAddress(erc721Details.ids[i]);
require(owner == _msgSender(), "_acceptCryptoPunk: invalid punk owner");
ICryptoPunks(erc721Details.tokenAddr).buyPunk(erc721Details.ids[i]);
}
}
function _transferCryptoPunk(ERC721Details memory erc721Details) internal {
for (uint256 i = 0; i < erc721Details.ids.length; i++) {
ICryptoPunks(erc721Details.tokenAddr).transferPunk(erc721Details.to[i], erc721Details.ids[i]);
}
}
}
ReentrancyGuard.sol 19 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
uint256 private reentrancyStatus = 1;
modifier nonReentrant() {
require(reentrancyStatus == 1, "REENTRANCY");
reentrancyStatus = 2;
_;
reentrancyStatus = 1;
}
}
MarketRegistry.sol 44 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "@openzeppelin/contracts/access/Ownable.sol";
contract MarketRegistry is Ownable {
struct TradeDetails {
uint256 marketId;
uint256 value;
bytes tradeData;
}
struct Market {
address proxy;
bool isLib;
bool isActive;
}
Market[] public markets;
constructor(address[] memory proxies, bool[] memory isLibs) {
for (uint256 i = 0; i < proxies.length; i++) {
markets.push(Market(proxies[i], isLibs[i], true));
}
}
function addMarket(address proxy, bool isLib) external onlyOwner {
markets.push(Market(proxy, isLib, true));
}
function setMarketStatus(uint256 marketId, bool newStatus) external onlyOwner {
Market storage market = markets[marketId];
market.isActive = newStatus;
}
function setMarketProxy(uint256 marketId, address newProxy, bool isLib) external onlyOwner {
Market storage market = markets[marketId];
market.proxy = newProxy;
market.isLib = isLib;
}
}
ICryptoPunks.sol 10 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface ICryptoPunks {
function punkIndexToAddress(uint index) external view returns(address owner);
function offerPunkForSaleToAddress(uint punkIndex, uint minSalePriceInWei, address toAddress) external;
function buyPunk(uint punkIndex) external payable;
function transferPunk(address to, uint punkIndex) external;
}
IWrappedPunk.sol 25 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IWrappedPunk {
/**
* @dev Mints a wrapped punk
*/
function mint(uint256 punkIndex) external;
/**
* @dev Burns a specific wrapped punk
*/
function burn(uint256 punkIndex) external;
/**
* @dev Registers proxy
*/
function registerProxy() external;
/**
* @dev Gets proxy address
*/
function proxyInfo(address user) external view returns (address);
}
IMoonCatsRescue.sol 11 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IMoonCatsRescue {
function acceptAdoptionOffer(bytes5 catId) payable external;
function makeAdoptionOfferToAddress(bytes5 catId, uint price, address to) external;
function giveCat(bytes5 catId, address to) external;
function catOwners(bytes5 catId) external view returns(address);
function rescueOrder(uint256 rescueIndex) external view returns(bytes5 catId);
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}
Ownable.sol 76 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/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.
*
* By default, the owner account will be the one that deploys the contract. 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;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing 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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_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);
}
}
Read Contract
GOV 0x180cb47f → address
affiliates 0x1bd78748 → address, bool
baseFees 0xddb382f9 → uint256
converter 0xbd38837b → address
guardian 0x452a9320 → address
marketRegistry 0xecb96fe6 → address
openForFreeTrades 0x11f85417 → bool
openForTrades 0xa1b62797 → bool
owner 0x8da5cb5b → address
punkProxy 0x6335f25e → address
sponsoredMarkets 0xe4dd4b8a → uint256, bool
supportsInterface 0x01ffc9a7 → bool
Write Contract 27 functions
These functions modify contract state and require a wallet transaction to execute.
addAffiliate 0x81ea4ea6
address _affiliate
addSponsoredMarket 0x3a5750b6
uint256 _marketId
batchBuyFromOpenSea 0xdefdb8bd
tuple[] openseaTrades
batchBuyWithERC20s 0x97f73ac7
tuple erc20Details
tuple[] tradeDetails
tuple[] converstionDetails
address[] dustTokens
batchBuyWithETH 0x0824d1ca
tuple[] tradeDetails
closeAllTrades 0xc5cadd7f
No parameters
multiAssetSwap 0xf2bc3e27
tuple erc20Details
tuple[] erc721Details
tuple[] erc1155Details
tuple[] converstionDetails
tuple[] tradeDetails
address[] dustTokens
uint256[2] feeDetails
onERC1155BatchReceived 0xbc197c81
address
address
uint256[]
uint256[]
bytes
returns: bytes4
onERC1155Received 0xf23a6e61
address
address
uint256
uint256
bytes
returns: bytes4
onERC721Received 0x150b7a02
address
address
uint256
bytes
returns: bytes4
onERC721Received 0xf0b9e5ba
address
uint256
bytes
returns: bytes4
renounceOwnership 0x715018a6
No parameters
rescueERC1155 0xb7ce33a2
address asset
uint256[] ids
uint256[] amounts
address recipient
rescueERC20 0x5d799f87
address asset
address recipient
rescueERC721 0x26e2dca2
address asset
uint256[] ids
address recipient
rescueETH 0x04824e70
address recipient
setBaseFees 0xb9277963
uint256 _baseFees
setConverter 0xb19337a4
address _converter
setMarketRegistry 0xd8579704
address _marketRegistry
setOneTimeApproval 0x9f2ba09b
address token
address operator
uint256 amount
setOpenForFreeTrades 0xe6041f9a
bool _openForFreeTrades
setOpenForTrades 0x83206e80
bool _openForTrades
setUp 0x0a9254e4
No parameters
transferOwnership 0xf2fde38b
address newOwner
updateAffiliate 0x565528d7
uint256 _affiliateIndex
address _affiliate
bool _IsActive
updateGuardian 0xfc525395
address _guardian
updateSponsoredMarket 0xccf3dc82
uint256 _marketIndex
uint256 _marketId
bool _isActive
Recent Transactions
No transactions found for this address