Address Contract Partially Verified
Address
0xa7d8d9ef8D8Ce8992Df33D8b8CF4Aebabd5bD270
Balance
0 ETH
Nonce
1
Code Size
24451 bytes
Creator
0x96dC73c8...7660 at tx 0x6ba3195a...4c3fb1
Indexed Transactions
0
Contract Bytecode
24451 bytes
0x608060405234801561001057600080fd5b506004361061045f5760003560e01c80638462151c1161024c578063b88d4fde11610146578063dce5d858116100c3578063ed6df98211610087578063ed6df98214611bdd578063ed8abfda14611bfa578063f51f74a914611c17578063f70c0f0414611c34578063f851a44014611c515761045f565b8063dce5d85814611a9e578063e13208b414611abb578063e3f59c4414611aed578063e935b7b114611ba7578063e985e9c514611baf5761045f565b8063cc74234b1161010a578063cc74234b14611974578063d03c390c14611991578063d195b365146119ae578063d7b044b614611a64578063db2ff86114611a815761045f565b8063b88d4fde146117a8578063bee04f9c1461186c578063c34a03b514611889578063c6d73231146118ac578063c87b56dd146119575761045f565b806397dc86cf116101d4578063a65ff74c11610198578063a65ff74c1461152d578063acad01241461157c578063ad0305ce14611627578063b1656ba31461164d578063b7b04fae146116fd5761045f565b806397dc86cf146113f7578063a11ec70a1461141a578063a22cb46514611437578063a3b2cca614611465578063a47d29cb146115105761045f565b80638c2c36221161021b5780638c2c362214610fe25780638c3c9cdd146110e95780638dd91a561461110c57806393961c661461134457806395d89b41146113ef5761045f565b80638462151c14610f03578063867f1a3b14610f795780638ba8f14d14610f9f5780638bddb0a614610fbc5761045f565b8063378599631161035d5780634f029c39116102e557806369d14faf116102a957806369d14faf14610dbd5780636bd5d59114610de95780636c907b7f14610e9457806370a0823114610eba578063826fc39114610ee05761045f565b80634f029c3914610d415780634f6ccce714610d495780635c088dcc14610d66578063621a1f7414610d835780636352211e14610da05761045f565b80633e48e8481161032c5780633e48e84814610a755780633fef6c2a14610b2057806342842e0e14610bcb578063498dd0c114610c015780634aa6d41714610c1e5761045f565b8063378599631461097f5780633949f90614610a2a5780633af32abf14610a325780633bdbd5c414610a585761045f565b80631b689c0b116103eb57806327901822116103af5780632790182214610802578063291d95491461081f5780632d9c0205146108455780632f745c591461094b57806336c7c12c146109775761045f565b80631b689c0b146106ca57806320927ec9146106e757806323b872dd1461070457806325b75d681461073a578063261eb4e5146107e55761045f565b8063095ea7b311610432578063095ea7b31461057d5780630d170673146105a95780630d4d15131461065457806310154bad1461069c57806318160ddd146106c25761045f565b806301ffc9a71461046457806306e1db171461049f57806306fdde03146104c7578063081812fc14610544575b600080fd5b61048b6004803603602081101561047a57600080fd5b50356001600160e01b031916611c59565b604080519115158252519081900360200190f35b6104c5600480360360208110156104b557600080fd5b50356001600160a01b0316611c7c565b005b6104cf611cea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105095781810151838201526020016104f1565b50505050905090810190601f1680156105365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105616004803603602081101561055a57600080fd5b5035611d81565b604080516001600160a01b039092168252519081900360200190f35b6104c56004803603604081101561059357600080fd5b506001600160a01b038135169060200135611de3565b6104c5600480360360408110156105bf57600080fd5b81359190810190604081016020820135600160201b8111156105e057600080fd5b8201836020820111156105f257600080fd5b803590602001918460018302840111600160201b8311171561061357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ef4945050505050565b61068a6004803603606081101561066a57600080fd5b506001600160a01b03813581169160208101359160409091013516611ff2565b60408051918252519081900360200190f35b6104c5600480360360208110156106b257600080fd5b50356001600160a01b03166121ec565b61068a61225c565b61068a600480360360208110156106e057600080fd5b5035612262565b6104cf600480360360208110156106fd57600080fd5b5035612274565b6104c56004803603606081101561071a57600080fd5b506001600160a01b0381358116916020810135909116906040013561230f565b6104c56004803603604081101561075057600080fd5b81359190810190604081016020820135600160201b81111561077157600080fd5b82018360208201111561078357600080fd5b803590602001918460018302840111600160201b831117156107a457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612364945050505050565b6104cf600480360360208110156107fb57600080fd5b5035612461565b6104c56004803603602081101561081857600080fd5b50356124c9565b6104c56004803603602081101561083557600080fd5b50356001600160a01b0316612559565b6108626004803603602081101561085b57600080fd5b50356125c6565b60405180806020018060200184151515158152602001838103835286818151815260200191508051906020019080838360005b838110156108ad578181015183820152602001610895565b50505050905090810190601f1680156108da5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101561090d5781810151838201526020016108f5565b50505050905090810190601f16801561093a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61068a6004803603604081101561096157600080fd5b506001600160a01b03813516906020013561272a565b6105616127a9565b6104c56004803603604081101561099557600080fd5b81359190810190604081016020820135600160201b8111156109b657600080fd5b8201836020820111156109c857600080fd5b803590602001918460018302840111600160201b831117156109e957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506127b8945050505050565b61056161283e565b61048b60048036036020811015610a4857600080fd5b50356001600160a01b031661284d565b6104c560048036036020811015610a6e57600080fd5b5035612862565b6104c560048036036040811015610a8b57600080fd5b81359190810190604081016020820135600160201b811115610aac57600080fd5b820183602082011115610abe57600080fd5b803590602001918460018302840111600160201b83111715610adf57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612a02945050505050565b6104c560048036036040811015610b3657600080fd5b81359190810190604081016020820135600160201b811115610b5757600080fd5b820183602082011115610b6957600080fd5b803590602001918460018302840111600160201b83111715610b8a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612a82945050505050565b6104c560048036036060811015610be157600080fd5b506001600160a01b03813581169160208101359091169060400135612b7f565b61056160048036036020811015610c1757600080fd5b5035612b9a565b610c3b60048036036020811015610c3457600080fd5b5035612bb5565b604051808060200187815260200186151515158152602001806020018515151515815260200184151515158152602001838103835289818151815260200191508051906020019080838360005b83811015610ca0578181015183820152602001610c88565b50505050905090810190601f168015610ccd5780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b83811015610d00578181015183820152602001610ce8565b50505050905090810190601f168015610d2d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b61068a612d43565b61068a60048036036020811015610d5f57600080fd5b5035612d49565b6104c560048036036020811015610d7c57600080fd5b5035612daf565b61068a60048036036020811015610d9957600080fd5b5035612e88565b61056160048036036020811015610db657600080fd5b5035612e9a565b6104c560048036036040811015610dd357600080fd5b50803590602001356001600160a01b0316612ef4565b6104c560048036036040811015610dff57600080fd5b81359190810190604081016020820135600160201b811115610e2057600080fd5b820183602082011115610e3257600080fd5b803590602001918460018302840111600160201b83111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612f98945050505050565b6104c560048036036020811015610eaa57600080fd5b50356001600160a01b0316613018565b61068a60048036036020811015610ed057600080fd5b50356001600160a01b0316613091565b6104c560048036036040811015610ef657600080fd5b50803590602001356130f9565b610f2960048036036020811015610f1957600080fd5b50356001600160a01b031661328d565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610f65578181015183820152602001610f4d565b505050509050019250505060405180910390f35b6104c560048036036020811015610f8f57600080fd5b50356001600160a01b03166132ee565b6104c560048036036020811015610fb557600080fd5b503561335b565b6104c560048036036020811015610fd257600080fd5b50356001600160a01b031661343a565b610fff60048036036020811015610ff857600080fd5b50356134aa565b604051808a6001600160a01b03166001600160a01b0316815260200189815260200188815260200187815260200186151515158152602001856001600160a01b03166001600160a01b0316815260200184815260200180602001836001600160a01b03166001600160a01b03168152602001828103825284818151815260200191508051906020019080838360005b838110156110a657818101518382015260200161108e565b50505050905090810190601f1680156110d35780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b6104cf600480360360408110156110ff57600080fd5b50803590602001356135ca565b6111296004803603602081101561112257600080fd5b5035613677565b6040518080602001806020018060200180602001806020018715151515815260200186810386528c818151815260200191508051906020019080838360005b83811015611180578181015183820152602001611168565b50505050905090810190601f1680156111ad5780820380516001836020036101000a031916815260200191505b5086810385528b5181528b516020918201918d019080838360005b838110156111e05781810151838201526020016111c8565b50505050905090810190601f16801561120d5780820380516001836020036101000a031916815260200191505b5086810384528a5181528a516020918201918c019080838360005b83811015611240578181015183820152602001611228565b50505050905090810190601f16801561126d5780820380516001836020036101000a031916815260200191505b5086810383528951815289516020918201918b019080838360005b838110156112a0578181015183820152602001611288565b50505050905090810190601f1680156112cd5780820380516001836020036101000a031916815260200191505b5086810382528851815288516020918201918a019080838360005b838110156113005781810151838201526020016112e8565b50505050905090810190601f16801561132d5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b6104c56004803603604081101561135a57600080fd5b81359190810190604081016020820135600160201b81111561137b57600080fd5b82018360208201111561138d57600080fd5b803590602001918460018302840111600160201b831117156113ae57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506139cc945050505050565b6104cf613a53565b6104c56004803603604081101561140d57600080fd5b5080359060200135613ab4565b6104c56004803603602081101561143057600080fd5b5035613b22565b6104c56004803603604081101561144d57600080fd5b506001600160a01b0381351690602001351515613baf565b6104c56004803603604081101561147b57600080fd5b81359190810190604081016020820135600160201b81111561149c57600080fd5b8201836020820111156114ae57600080fd5b803590602001918460018302840111600160201b831117156114cf57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613c7b945050505050565b6105616004803603602081101561152657600080fd5b5035613cfb565b61154a6004803603602081101561154357600080fd5b5035613d16565b604080516001600160a01b03958616815293909416602084015282840191909152606082015290519081900360800190f35b6104c56004803603604081101561159257600080fd5b81359190810190604081016020820135600160201b8111156115b357600080fd5b8201836020820111156115c557600080fd5b803590602001918460018302840111600160201b831117156115e657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613d5f945050505050565b61048b6004803603602081101561163d57600080fd5b50356001600160a01b0316613ea7565b6104c56004803603606081101561166357600080fd5b813591602081013591810190606081016040820135600160201b81111561168957600080fd5b82018360208201111561169b57600080fd5b803590602001918460018302840111600160201b831117156116bc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613ebc945050505050565b6104c56004803603604081101561171357600080fd5b81359190810190604081016020820135600160201b81111561173457600080fd5b82018360208201111561174657600080fd5b803590602001918460018302840111600160201b8311171561176757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550614024945050505050565b6104c5600480360360808110156117be57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156117f857600080fd5b82018360208201111561180a57600080fd5b803590602001918460018302840111600160201b8311171561182b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550614121945050505050565b610f296004803603602081101561188257600080fd5b5035614173565b6104c56004803603604081101561189f57600080fd5b50803590602001356141d3565b6104c5600480360360408110156118c257600080fd5b81359190810190604081016020820135600160201b8111156118e357600080fd5b8201836020820111156118f557600080fd5b803590602001918460018302840111600160201b8311171561191657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550614285945050505050565b6104cf6004803603602081101561196d57600080fd5b5035614382565b61068a6004803603602081101561198a57600080fd5b5035614783565b6104c5600480360360208110156119a757600080fd5b5035614795565b6104c5600480360360608110156119c457600080fd5b81359190810190604081016020820135600160201b8111156119e557600080fd5b8201836020820111156119f757600080fd5b803590602001918460018302840111600160201b83111715611a1857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061481a9050565b61056160048036036020811015611a7a57600080fd5b50356148c6565b6104c560048036036020811015611a9757600080fd5b50356148e1565b6104c560048036036020811015611ab457600080fd5b5035614a8a565b6104c560048036036060811015611ad157600080fd5b508035906001600160a01b036020820135169060400135614bd5565b6104c560048036036080811015611b0357600080fd5b810190602081018135600160201b811115611b1d57600080fd5b820183602082011115611b2f57600080fd5b803590602001918460018302840111600160201b83111715611b5057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550506001600160a01b0383351693505050602081013590604001351515614cae565b61068a614e2a565b61048b60048036036040811015611bc557600080fd5b506001600160a01b0381358116916020013516614e30565b6104c560048036036020811015611bf357600080fd5b5035614e5e565b61068a60048036036020811015611c1057600080fd5b5035614ef2565b61068a60048036036020811015611c2d57600080fd5b5035614f04565b61068a60048036036020811015611c4a57600080fd5b5035614f16565b610561614f28565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b601b546001600160a01b03163314611cc8576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b601480546001600160a01b0319166001600160a01b0392909216919091179055565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611d765780601f10611d4b57610100808354040283529160200191611d76565b820191906000526020600020905b815481529060010190602001808311611d5957829003601f168201915b505050505090505b90565b6000611d8c82614f37565b611dc75760405162461bcd60e51b815260040180806020018281038252602c815260200180615dd3602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000611dee82612e9a565b9050806001600160a01b0316836001600160a01b03161415611e415760405162461bcd60e51b8152600401808060200182810382526021815260200180615e4e6021913960400191505060405180910390fd5b336001600160a01b0382161480611e5d5750611e5d8133614e30565b611e985760405162461bcd60e51b8152600401808060200182810382526038815260200180615d0b6038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000828152600c60205260409020600e015482906301000000900460ff1615611f57576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff1680611f8d57506000818152600d60205260409020546001600160a01b031633145b611fcc576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c602090815260409091208451611feb92860190615b41565b5050505050565b336000908152601d602052604081205460ff166120405760405162461bcd60e51b815260040180806020018281038252602b815260200180615f24602b913960400191505060405180910390fd5b6000838152600c60205260409020600981015460089091015461206a90600163ffffffff614f5416565b11156120bd576040805162461bcd60e51b815260206004820152601f60248201527f4d757374206e6f7420657863656564206d617820696e766f636174696f6e7300604482015290519081900360640190fd5b6000838152600c60205260409020600e015462010000900460ff16806120fc57506000838152600d60205260409020546001600160a01b038381169116145b61214d576040805162461bcd60e51b815260206004820181905260248201527f50726f6a656374206d75737420657869737420616e6420626520616374697665604482015290519081900360640190fd5b6000838152600c60205260409020600e0154600160201b900460ff16158061218e57506000838152600d60205260409020546001600160a01b038381169116145b6121d7576040805162461bcd60e51b8152602060048201526015602482015274283ab931b430b9b2b99030b932903830bab9b2b21760591b604482015290519081900360640190fd5b60006121e38585614fb5565b95945050505050565b601b546001600160a01b03163314612238576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03166000908152601c60205260409020805460ff19166001179055565b60075490565b60176020526000908152604090205481565b600e6020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156123075780601f106122dc57610100808354040283529160200191612307565b820191906000526020600020905b8154815290600101906020018083116122ea57829003601f168201915b505050505081565b612319338261515a565b6123545760405162461bcd60e51b8152600401808060200182810382526031815260200180615e6f6031913960400191505060405180910390fd5b61235f8383836151fe565b505050565b6000828152600c60205260409020600e015482906301000000900460ff16156123c7576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff16806123fd57506000818152600d60205260409020546001600160a01b031633145b61243c576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c602090815260409091208451611feb92600490920191860190615b41565b60166020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156123075780601f106122dc57610100808354040283529160200191612307565b600081815260176020908152604080832054808452600d909252909120546001600160a01b03163314612531576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b60008281526017602090815260408083205483526016909152812061255591615bbf565b5050565b601b546001600160a01b031633146125a5576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03166000908152601c60205260409020805460ff19169055565b6000818152600c6020908152604080832060060180548251601f60026000196101006001861615020190931692909204918201859004850281018501909352808352606094859490939291908301828280156126635780601f1061263857610100808354040283529160200191612663565b820191906000526020600020905b81548152906001019060200180831161264657829003601f168201915b5050506000878152600c60209081526040918290206007018054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815295985093509091508301828280156127015780601f106126d657610100808354040283529160200191612701565b820191906000526020600020905b8154815290600101906020018083116126e457829003601f168201915b50505060009687525050600c6020526040909420600e0154929461010090930460ff1692915050565b600061273583613091565b82106127725760405162461bcd60e51b815260040180806020018281038252602b815260200180615c3e602b913960400191505060405180910390fd5b6001600160a01b038316600090815260056020526040902080548390811061279657fe5b9060005260206000200154905092915050565b600b546001600160a01b031681565b6000828152600d602052604090205482906001600160a01b03163314612813576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152600c60209081526040909120835161283892600390920191850190615b41565b50505050565b6014546001600160a01b031681565b601c6020526000908152604090205460ff1681565b6000818152600c60205260409020600e015481906301000000900460ff16156128c5576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054829060ff16806128fb57506000818152600d60205260409020546001600160a01b031633145b61293a576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000838152600c6020526040902060080154156129885760405162461bcd60e51b8152600401808060200182810382526027815260200180615ecc6027913960400191505060405180910390fd5b6000838152600c602052604090206005015460ff16156129c0576000838152600c60205260409020600e01805460ff191690556129dd565b6000838152600c60205260409020600e01805460ff191660011790555b50506000908152600c60205260409020600501805460ff19811660ff90911615179055565b6000828152600d602052604090205482906001600160a01b03163314612a5d576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152600c60209081526040909120835161283892600690920191850190615b41565b6000828152600c60205260409020600e015482906301000000900460ff1615612ae5576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff1680612b1b57506000818152600d60205260409020546001600160a01b031633145b612b5a576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c602090815260409091208451611feb92600d90920191860190615b41565b61235f83838360405180602001604052806000815250614121565b600f602052600090815260409020546001600160a01b031681565b6000818152600c60209081526040808320600a0180548251601f60026000196101006001861615020190931692909204918201859004850281018501909352808352606094938493869385938493830182828015612c545780601f10612c2957610100808354040283529160200191612c54565b820191906000526020600020905b815481529060010190602001808311612c3757829003601f168201915b50505060008a8152600c602081815260409283902091820154600e830154600d9093018054855160026101006001841615026000190190921691909104601f8101859004850282018501909652858152979d50909b5060ff9092169950909350909150830182828015612d085780601f10612cdd57610100808354040283529160200191612d08565b820191906000526020600020905b815481529060010190602001808311612ceb57829003601f168201915b5050506000998a525050600c6020526040909720600e0154959794969395939460ff63010000008604811695600160201b9004169350915050565b60155481565b6000612d5361225c565b8210612d905760405162461bcd60e51b815260040180806020018281038252602c815260200180615ea0602c913960400191505060405180910390fd5b60078281548110612d9d57fe5b90600052602060002001549050919050565b6000818152600d602052604090205481906001600160a01b03163314612e0a576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000828152600c602052604090206005015460ff1615612e5b5760405162461bcd60e51b8152600401808060200182810382526031815260200180615ef36031913960400191505060405180910390fd5b506000908152600c60205260409020600e01805461ff001981166101009182900460ff1615909102179055565b60196020526000908152604090205481565b6000818152600160205260408120546001600160a01b031680612eee5760405162461bcd60e51b8152600401808060200182810382526029815260200180615d6d6029913960400191505060405180910390fd5b92915050565b336000908152601c6020526040902054829060ff1680612f2a57506000818152600d60205260409020546001600160a01b031633145b612f69576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b506000918252600d602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b6000828152600d602052604090205482906001600160a01b03163314612ff3576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152600c60209081526040909120835161283892600790920191850190615b41565b336000908152601c602052604090205460ff1661306f576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481dda1a5d195b1a5cdd195960821b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b0382166130d85760405162461bcd60e51b815260040180806020018281038252602a815260200180615d43602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600360205260409020612eee9061521d565b6000828152600d602052604090205482906001600160a01b03163314613154576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152600c60205260409020600e01546301000000900460ff16158061318c57506000838152600c602052604090206009015482105b6131d0576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b6000838152600c6020526040902060080154821161321f5760405162461bcd60e51b815260040180806020018281038252603d815260200180615d96603d913960400191505060405180910390fd5b620f4240821115613277576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f742065786365656420312c3030302c303030000000000000000000604482015290519081900360640190fd5b506000918252600c602052604090912060090155565b606061329882615221565b8054806020026020016040519081016040528092919081815260200182805480156132e257602002820191906000526020600020905b8154815260200190600101908083116132ce575b50505050509050919050565b601b546001600160a01b0316331461333a576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03166000908152601d60205260409020805460ff19169055565b336000908152601c602052604090205460ff166133b2576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481dda1a5d195b1a5cdd195960821b604482015290519081900360640190fd5b6000818152600c60205260409020600e015481906301000000900460ff1615613415576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b506000908152600c60205260409020600e01805463ff00000019166301000000179055565b601b546001600160a01b03163314613486576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03166000908152601d60205260409020805460ff19166001179055565b6000818152600d60209081526040808320546010835281842054600c845282852060088101546009820154600e92830154601188528689205460128952878a2054948952878a208054895160026101006001841615026000190190921691909104601f81018c90048c0282018c01909a528981526001600160a01b039889169b979a959994986201000090940460ff1697939092169594606094908301828280156135965780601f1061356b57610100808354040283529160200191613596565b820191906000526020600020905b81548152906001019060200180831161357957829003601f168201915b50505060009c8d525050600f6020526040909a2054989a9799969895979496939592946001600160a01b0390931692915050565b6000828152600c60209081526040808320848452600b0182529182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561366a5780601f1061363f5761010080835404028352916020019161366a565b820191906000526020600020905b81548152906001019060200180831161364d57829003601f168201915b5050505050905092915050565b6000818152600c602090815260408083208054825160026001831615610100026000190190921691909104601f81018590048502820185019093528281526060948594859485948594929091908301828280156137155780601f106136ea57610100808354040283529160200191613715565b820191906000526020600020905b8154815290600101906020018083116136f857829003601f168201915b50505050509550600c60008881526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156137c65780601f1061379b576101008083540402835291602001916137c6565b820191906000526020600020905b8154815290600101906020018083116137a957829003601f168201915b50505060008a8152600c60209081526040918290206002908101805484516001821615610100026000190190911692909204601f8101849004840283018401909452838252959a509493509091508301828280156138655780601f1061383a57610100808354040283529160200191613865565b820191906000526020600020905b81548152906001019060200180831161384857829003601f168201915b50505060008a8152600c60209081526040918290206003018054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815295995093509091508301828280156139035780601f106138d857610100808354040283529160200191613903565b820191906000526020600020905b8154815290600101906020018083116138e657829003601f168201915b50505060008a8152600c60209081526040918290206004018054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815295985093509091508301828280156139a15780601f10613976576101008083540402835291602001916139a1565b820191906000526020600020905b81548152906001019060200180831161398457829003601f168201915b5050506000998a525050600c602052604090972060050154959794969395929460ff90931692915050565b600082815260176020908152604080832054808452600d909252909120546001600160a01b03163314613a34576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152601660209081526040909120835161283892850190615b41565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611d765780601f10611d4b57610100808354040283529160200191611d76565b6000828152600d602052604090205482906001600160a01b03163314613b0f576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b5060009182526010602052604090912055565b6000818152600d602052604090205481906001600160a01b03163314613b7d576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b506000908152600c60205260409020600e01805464ff00000000198116600160201b9182900460ff1615909102179055565b6001600160a01b038216331415613c0d576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b3360008181526004602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6000828152600d602052604090205482906001600160a01b03163314613cd6576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000838152600c60209081526040909120835161283892600290920191850190615b41565b600d602052600090815260409020546001600160a01b031681565b6000908152601760209081526040808320548352600d82528083205460118352818420546012845282852054601390945291909320546001600160a01b03938416949390911692565b6000828152600c60205260409020600e015482906301000000900460ff1615613dc2576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff1680613df857506000818152600d60205260409020546001600160a01b031633145b613e37576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c60208181526040808420928301548452600b909201815291208451613e6592860190615b41565b506000848152600c602081905260409091200154613e8a90600163ffffffff614f5416565b6000948552600c6020819052604090952090940193909355505050565b601d6020526000908152604090205460ff1681565b6000838152600c60205260409020600e015483906301000000900460ff1615613f1f576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054849060ff1680613f5557506000818152600d60205260409020546001600160a01b031633145b613f94576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000858152600c6020819052604090912001548410613ff2576040805162461bcd60e51b81526020600482015260156024820152747363726970744964206f7574206f662072616e676560581b604482015290519081900360640190fd5b6000858152600c60209081526040808320878452600b018252909120845161401c92860190615b41565b505050505050565b6000828152600c60205260409020600e015482906301000000900460ff1615614087576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff16806140bd57506000818152600d60205260409020546001600160a01b031633145b6140fc576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c602090815260409091208451611feb92600190920191860190615b41565b61412c84848461230f565b6141388484848461523b565b6128385760405162461bcd60e51b8152600401808060200182810382526032815260200180615c696032913960400191505060405180910390fd5b6000818152601860209081526040918290208054835181840281018401909452808452606093928301828280156132e257602002820191906000526020600020908154815260200190600101908083116132ce5750505050509050919050565b6000828152600d602052604090205482906001600160a01b0316331461422e576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6064821115614272576040805162461bcd60e51b815260206004820152600b60248201526a4d6178206f66203130302560a81b604482015290519081900360640190fd5b5060009182526013602052604090912055565b6000828152600c60205260409020600e015482906301000000900460ff16156142e8576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054839060ff168061431e57506000818152600d60205260409020546001600160a01b031633145b61435d576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000848152600c602090815260409091208451611feb92600a90920191860190615b41565b60608161438e81614f37565b6143df576040805162461bcd60e51b815260206004820152601760248201527f546f6b656e20494420646f6573206e6f74206578697374000000000000000000604482015290519081900360640190fd5b6000838152601660205260409020546002600019610100600184161502019091160415614551576000838152601760209081526040808320548352600c82529182902060070180548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845261454a93928301828280156144a95780601f1061447e576101008083540402835291602001916144a9565b820191906000526020600020905b81548152906001019060200180831161448c57829003601f168201915b5050506000878152601660209081526040918290208054835160026001831615610100026000190190921691909104601f8101849004840282018401909452838152945092508301828280156145405780601f1061451557610100808354040283529160200191614540565b820191906000526020600020905b81548152906001019060200180831161452357829003601f168201915b505050505061536e565b915061477d565b6000838152601760209081526040808320548352600c90915290206005015460ff161580156145a357506000838152601760209081526040808320548352600c9091529020600e0154610100900460ff165b156146c4576000838152601760209081526040808320548352600c82529182902060070180548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845261454a939283018282801561464b5780601f106146205761010080835404028352916020019161464b565b820191906000526020600020905b81548152906001019060200180831161462e57829003601f168201915b5050506000878152601760209081526040808320548352600c825291829020600d018054835160026001831615610100026000190190921691909104601f8101849004840282018401909452838152945092508301828280156145405780601f1061451557610100808354040283529160200191614540565b6000838152601760209081526040808320548352600c82529182902060060180548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845261477a93928301828280156147675780601f1061473c57610100808354040283529160200191614767565b820191906000526020600020905b81548152906001019060200180831161474a57829003601f168201915b5050505050614775856153aa565b61536e565b91505b50919050565b60126020526000908152604090205481565b336000908152601c602052604090205460ff166147ec576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481dda1a5d195b1a5cdd195960821b604482015290519081900360640190fd5b6000908152600c60205260409020600e01805462ff0000198116620100009182900460ff1615909102179055565b6000838152600d602052604090205483906001600160a01b03163314614875576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6000848152600e60209081526040909120845161489492860190615b41565b50506000928352600f602052604090922080546001600160a01b0319166001600160a01b039093169290921790915550565b6011602052600090815260409020546001600160a01b031681565b6000818152600c60205260409020600e015481906301000000900460ff1615614944576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054829060ff168061497a57506000818152600d60205260409020546001600160a01b031633145b6149b9576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000838152600c602081905260409091200154614a1d576040805162461bcd60e51b815260206004820152601e60248201527f746865726520617265206e6f207363726970747320746f2072656d6f76650000604482015290519081900360640190fd5b6000838152600c6020818152604080842092830154600019018452600b90920190528120614a4a91615bbf565b6000838152600c602081905260409091200154614a6e90600163ffffffff61546b16565b6000938452600c60208190526040909420909301929092555050565b6000818152600c60205260409020600e015481906301000000900460ff1615614aed576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481a59881d5b9b1bd8dad95960821b604482015290519081900360640190fd5b336000908152601c6020526040902054829060ff1680614b2357506000818152600d60205260409020546001600160a01b031633145b614b62576040805162461bcd60e51b815260206004820152601a6024820152600080516020615ceb833981519152604482015290519081900360640190fd5b6000838152600c602052604090206008015415614bb05760405162461bcd60e51b8152600401808060200182810382526026815260200180615dff6026913960400191505060405180910390fd5b50506000908152600c60205260409020600e01805460ff19811660ff90911615179055565b6000838152600d602052604090205483906001600160a01b03163314614c30576040805162461bcd60e51b815260206004820152600b60248201526a13db9b1e48185c9d1a5cdd60aa1b604482015290519081900360640190fd5b6064821115614c74576040805162461bcd60e51b815260206004820152600b60248201526a4d6178206f66203130302560a81b604482015290519081900360640190fd5b50600092835260116020908152604080852080546001600160a01b0319166001600160a01b03959095169490941790935560129052912055565b336000908152601c602052604090205460ff16614d05576040805162461bcd60e51b815260206004820152601060248201526f13db9b1e481dda1a5d195b1a5cdd195960821b604482015290519081900360640190fd5b601e546000818152600d6020908152604080832080546001600160a01b0319166001600160a01b038916179055600c82529091208651614d4792880190615b41565b50604080518082018252600381526208aa8960eb1b60208083019182526000858152600e909152929092209051614d7e9290615b41565b506000818152601060209081526040808320869055600c9091529020600e8101805464ff000000001916600160201b17905560058101805484151560ff19909116179055620f424060099091015581614def576000818152600c60205260409020600e01805460ff19169055614e0c565b6000818152600c60205260409020600e01805460ff191660011790555b601e54614e2090600163ffffffff614f5416565b601e555050505050565b601e5481565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b601b546001600160a01b03163314614eaa576040805162461bcd60e51b815260206004820152600a60248201526927b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6019811115614eed576040805162461bcd60e51b815260206004820152600a6024820152694d6178206f662032352560b01b604482015290519081900360640190fd5b601555565b60136020526000908152604090205481565b601a6020526000908152604090205481565b60106020526000908152604090205481565b601b546001600160a01b031681565b6000908152600160205260409020546001600160a01b0316151590565b600082820183811015614fae576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000818152600c6020526040812060080154620f42408302810190614fe190600163ffffffff614f5416565b6000848152600c60209081526040808320600801849055600b54815163990c8f7960e01b8152915193949343936000198501409333936001600160a01b03169263990c8f7992600480840193919291829003018186803b15801561504457600080fd5b505afa158015615058573d6000803e3d6000fd5b505050506040513d602081101561506e57600080fd5b505160408051602080820197909752808201959095526060808601949094529190921b6bffffffffffffffffffffffff191660808401526094808401929092528051808403909201825260b49092018252805190830120600085815260198452828120829055818152601a909352912083905590506150ed85836154c8565b600082815260176020908152604080832087905586835260188252808320805460018101825590845291832090910184905551859184916001600160a01b038916917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f91a4509392505050565b600061516582614f37565b6151a05760405162461bcd60e51b815260040180806020018281038252602c815260200180615cbf602c913960400191505060405180910390fd5b60006151ab83612e9a565b9050806001600160a01b0316846001600160a01b031614806151e65750836001600160a01b03166151db84611d81565b6001600160a01b0316145b806151f657506151f68185614e30565b949350505050565b6152098383836154e5565b6152138382615629565b61235f8282615717565b5490565b6001600160a01b0316600090815260056020526040902090565b600061524f846001600160a01b0316615755565b61525b575060016151f6565b604051630a85bd0160e11b815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156152d55781810151838201526020016152bd565b50505050905090810190601f1680156153025780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561532457600080fd5b505af1158015615338573d6000803e3d6000fd5b505050506040513d602081101561534e57600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b6060614fae838360405180602001604052806000815250604051806020016040528060008152506040518060200160405280600081525061575b565b6060816153cf57506040805180820190915260018152600360fc1b6020820152611c77565b8160005b81156153e757600101600a820491506153d3565b6060816040519080825280601f01601f191660200182016040528015615414576020820181803883390190505b50905060001982015b851561546257600a860660300160f81b8282806001900393508151811061544057fe5b60200101906001600160f81b031916908160001a905350600a8604955061541d565b50949350505050565b6000828211156154c2576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6154d2828261596f565b6154dc8282615717565b61255581615aa0565b826001600160a01b03166154f882612e9a565b6001600160a01b03161461553d5760405162461bcd60e51b8152600401808060200182810382526029815260200180615e256029913960400191505060405180910390fd5b6001600160a01b0382166155825760405162461bcd60e51b8152600401808060200182810382526024815260200180615c9b6024913960400191505060405180910390fd5b61558b81615ae4565b6001600160a01b03831660009081526003602052604090206155ac90615b21565b6001600160a01b03821660009081526003602052604090206155cd90615b38565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461565390600163ffffffff61546b16565b6000838152600660205260409020549091508082146156ee576001600160a01b038416600090815260056020526040812080548490811061569057fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106156ce57fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b0384166000908152600560205260409020805490611feb906000198301615c03565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b3b151590565b6060808690506060869050606086905060608690506060869050606081518351855187518951010101016040519080825280601f01601f1916602001820160405280156157af576020820181803883390190505b509050806000805b8851811015615808578881815181106157cc57fe5b602001015160f81c60f81b8383806001019450815181106157e957fe5b60200101906001600160f81b031916908160001a9053506001016157b7565b5060005b875181101561585d5787818151811061582157fe5b602001015160f81c60f81b83838060010194508151811061583e57fe5b60200101906001600160f81b031916908160001a90535060010161580c565b5060005b86518110156158b25786818151811061587657fe5b602001015160f81c60f81b83838060010194508151811061589357fe5b60200101906001600160f81b031916908160001a905350600101615861565b5060005b8551811015615907578581815181106158cb57fe5b602001015160f81c60f81b8383806001019450815181106158e857fe5b60200101906001600160f81b031916908160001a9053506001016158b6565b5060005b845181101561595c5784818151811061592057fe5b602001015160f81c60f81b83838060010194508151811061593d57fe5b60200101906001600160f81b031916908160001a90535060010161590b565b50909d9c50505050505050505050505050565b6001600160a01b0382166159ca576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6159d381614f37565b15615a25576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b038716908117909155835260039091529020615a6490615b38565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b6000818152600260205260409020546001600160a01b031615615b1e57600081815260026020526040902080546001600160a01b03191690555b50565b8054615b3490600163ffffffff61546b16565b9055565b80546001019055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615b8257805160ff1916838001178555615baf565b82800160010185558215615baf579182015b82811115615baf578251825591602001919060010190615b94565b50615bbb929150615c23565b5090565b50805460018160011615610100020316600290046000825580601f10615be55750615b1e565b601f016020900490600052602060002090810190615b1e9190615c23565b81548183558181111561235f5760008381526020902061235f9181019083015b611d7e91905b80821115615bbb5760008155600101615c2956fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4f6e6c7920617274697374206f722077686974656c69737465640000000000004552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e596f75206d75737420736574206d617820696e766f636174696f6e732067726561746572207468616e2063757272656e7420696e766f636174696f6e734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e6e6f74206d6f64696679206166746572206120746f6b656e206973206d696e7465642e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e647343616e206e6f7420737769746368206166746572206120746f6b656e206973206d696e7465642e63616e206f6e6c7920736574207374617469632049504653206861736820666f72207374617469632070726f6a656374734d757374206d696e742066726f6d2077686974656c6973746564206d696e74657220636f6e74726163742ea265627a7a7231582051af59aaa480c9f60eaa1f551c582b98f97658e00ae81f20caa9d10b2dbfad5f64736f6c63430005110032
Verified Source Code Partial Match
Compiler: v0.5.17+commit.d19bba13
EVM: istanbul
Optimization: Yes (200 runs)
GenArt721Core.sol 1243 lines
// File contracts/libs/IERC165.sol
// File: openzeppelin-solidity/contracts/introspection/IERC165.sol
pragma solidity ^0.5.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* [EIP](https://eips.ethereum.org/EIPS/eip-165).
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others (`ERC165Checker`).
*
* For an implementation, see `ERC165`.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// File contracts/libs/ERC165.sol
// File: openzeppelin-solidity/contracts/introspection/ERC165.sol
pragma solidity ^0.5.0;
/**
* @dev Implementation of the `IERC165` interface.
*
* Contracts may inherit from this and call `_registerInterface` to declare
* their support of an interface.
*/
contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See `IERC165.supportsInterface`.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See `IERC165.supportsInterface`.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
// File contracts/libs/IERC721.sol
// File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol
pragma solidity ^0.5.0;
/**
* @dev Required interface of an ERC721 compliant contract.
*/
contract IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of NFTs in `owner`'s account.
*/
function balanceOf(address owner) public view returns (uint256 balance);
/**
* @dev Returns the owner of the NFT specified by `tokenId`.
*/
function ownerOf(uint256 tokenId) public view returns (address owner);
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
*
*
* Requirements:
* - `from`, `to` cannot be zero.
* - `tokenId` must be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this
* NFT by either `approve` or `setApproveForAll`.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public;
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
* Requirements:
* - If the caller is not `from`, it must be approved to move this NFT by
* either `approve` or `setApproveForAll`.
*/
function transferFrom(address from, address to, uint256 tokenId) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address operator);
function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}
// File contracts/libs/SafeMath.sol
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
pragma solidity ^0.5.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
}
// File contracts/libs/Address.sol
// File: openzeppelin-solidity/contracts/utils/Address.sol
pragma solidity ^0.5.0;
/**
* @dev Collection of functions related to the address type,
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* > It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
// File contracts/libs/Counters.sol
// File: openzeppelin-solidity/contracts/drafts/Counters.sol
pragma solidity ^0.5.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
* overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
* directly accessed.
*/
library Counters {
using SafeMath for uint256;
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
counter._value += 1;
}
function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1);
}
}
// File contracts/libs/IERC721Receiver.sol
// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol
pragma solidity ^0.5.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
contract IERC721Receiver {
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4);
}
// File contracts/libs/ERC721.sol
// File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol
pragma solidity ^0.5.0;
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721 is ERC165, IERC721 {
using SafeMath for uint256;
using Address for address;
using Counters for Counters.Counter;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from token ID to owner
mapping (uint256 => address) private _tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => Counters.Counter) private _ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
constructor () public {
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
}
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _ownedTokensCount[owner].current();
}
function ownerOf(uint256 tokenId) public view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
"ERC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address to, bool approved) public {
require(to != msg.sender, "ERC721: approve to caller");
_operatorApprovals[msg.sender][to] = approved;
emit ApprovalForAll(msg.sender, to, approved);
}
function isApprovedForAll(address owner, address operator) public view returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
_transferFrom(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
transferFrom(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view returns (bool) {
address owner = _tokenOwner[tokenId];
return owner != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
function _burn(address owner, uint256 tokenId) internal {
require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] = address(0);
emit Transfer(owner, address(0), tokenId);
}
function _burn(uint256 tokenId) internal {
_burn(ownerOf(tokenId), tokenId);
}
function _transferFrom(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
internal returns (bool)
{
if (!to.isContract()) {
return true;
}
bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
return (retval == _ERC721_RECEIVED);
}
function _clearApproval(uint256 tokenId) private {
if (_tokenApprovals[tokenId] != address(0)) {
_tokenApprovals[tokenId] = address(0);
}
}
}
// File contracts/libs/IERC721Enumerable.sol
// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Enumerable.sol
pragma solidity ^0.5.0;
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract IERC721Enumerable is IERC721 {
function totalSupply() public view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);
function tokenByIndex(uint256 index) public view returns (uint256);
}
// File contracts/libs/ERC721Enumerable.sol
// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Enumerable.sol
pragma solidity ^0.5.0;
/**
* @title ERC-721 Non-Fungible Token with optional enumeration extension logic
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => uint256[]) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
/**
* @dev Constructor function.
*/
constructor () public {
// register the supported interface to conform to ERC721Enumerable via ERC165
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner.
* @param owner address owning the tokens list to be accessed
* @param index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev Gets the total amount of tokens stored by the contract.
* @return uint256 representing the total amount of tokens
*/
function totalSupply() public view returns (uint256) {
return _allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens.
* @param index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/
function tokenByIndex(uint256 index) public view returns (uint256) {
require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev Internal function to transfer ownership of a given token ID to another address.
* As opposed to transferFrom, this imposes no restrictions on msg.sender.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function _transferFrom(address from, address to, uint256 tokenId) internal {
super._transferFrom(from, to, tokenId);
_removeTokenFromOwnerEnumeration(from, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
}
/**
* @dev Internal function to mint a new token.
* Reverts if the given token ID already exists.
* @param to address the beneficiary that will own the minted token
* @param tokenId uint256 ID of the token to be minted
*/
function _mint(address to, uint256 tokenId) internal {
super._mint(to, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
_addTokenToAllTokensEnumeration(tokenId);
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* Deprecated, use _burn(uint256) instead.
* @param owner owner of the token to burn
* @param tokenId uint256 ID of the token being burned
*/
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
_removeTokenFromOwnerEnumeration(owner, tokenId);
// Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
_ownedTokensIndex[tokenId] = 0;
_removeTokenFromAllTokensEnumeration(tokenId);
}
/**
* @dev Gets the list of token IDs of the requested owner.
* @param owner address owning the tokens
* @return uint256[] List of token IDs owned by the requested address
*/
function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
return _ownedTokens[owner];
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
_ownedTokensIndex[tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
_ownedTokens[from].length--;
// Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
// lastTokenId, or just over the end of the array if the token was the last one).
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length.sub(1);
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
_allTokens.length--;
_allTokensIndex[tokenId] = 0;
}
}
// File contracts/libs/CustomERC721Metadata.sol
// File: contracts/CustomERC721Metadata.sol
pragma solidity ^0.5.0;
/**
* ERC721 base contract without the concept of tokenUri as this is managed by the parent
*/
contract CustomERC721Metadata is ERC165, ERC721, ERC721Enumerable {
// Token name
string private _name;
// Token symbol
string private _symbol;
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/**
* @dev Constructor function
*/
constructor (string memory name, string memory symbol) public {
_name = name;
_symbol = symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
}
/**
* @dev Gets the token name
* @return string representing the token name
*/
function name() external view returns (string memory) {
return _name;
}
/**
* @dev Gets the token symbol
* @return string representing the token symbol
*/
function symbol() external view returns (string memory) {
return _symbol;
}
}
// File contracts/libs/Strings.sol
// File: contracts/Strings.sol
pragma solidity ^0.5.0;
//https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
library Strings {
function strConcat(string memory _a, string memory _b) internal pure returns (string memory _concatenatedString) {
return strConcat(_a, _b, "", "", "");
}
function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory _concatenatedString) {
return strConcat(_a, _b, _c, "", "");
}
function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory _concatenatedString) {
return strConcat(_a, _b, _c, _d, "");
}
function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory _concatenatedString) {
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
bytes memory _bc = bytes(_c);
bytes memory _bd = bytes(_d);
bytes memory _be = bytes(_e);
string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
bytes memory babcde = bytes(abcde);
uint k = 0;
uint i = 0;
for (i = 0; i < _ba.length; i++) {
babcde[k++] = _ba[i];
}
for (i = 0; i < _bb.length; i++) {
babcde[k++] = _bb[i];
}
for (i = 0; i < _bc.length; i++) {
babcde[k++] = _bc[i];
}
for (i = 0; i < _bd.length; i++) {
babcde[k++] = _bd[i];
}
for (i = 0; i < _be.length; i++) {
babcde[k++] = _be[i];
}
return string(babcde);
}
function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);
}
}
// File contracts/GenArt721Core.sol
// File: contracts/GenArt721Core.sol
//0x1454EFCa69FA654e5A7d83CB61c1aD81790c44B7
//https://oneclickdapp.com/radar-valery/
pragma solidity ^0.5.0;
interface Randomizer {
function returnValue() external view returns(bytes32);
}
contract GenArt721Core is CustomERC721Metadata {
using SafeMath for uint256;
event Mint(
address indexed _to,
uint256 indexed _tokenId,
uint256 indexed _projectId
);
Randomizer public randomizerContract;
struct Project {
string name;
string artist;
string description;
string website;
string license;
bool dynamic;
string projectBaseURI;
string projectBaseIpfsURI;
uint256 invocations;
uint256 maxInvocations;
string scriptJSON;
mapping(uint256 => string) scripts;
uint scriptCount;
string ipfsHash;
bool useHashString;
bool useIpfs;
bool active;
bool locked;
bool paused;
}
uint256 constant ONE_MILLION = 1_000_000;
mapping(uint256 => Project) projects;
//All financial functions are stripped from struct for visibility
mapping(uint256 => address) public projectIdToArtistAddress;
mapping(uint256 => string) public projectIdToCurrencySymbol;
mapping(uint256 => address) public projectIdToCurrencyAddress;
mapping(uint256 => uint256) public projectIdToPricePerTokenInWei;
mapping(uint256 => address) public projectIdToAdditionalPayee;
mapping(uint256 => uint256) public projectIdToAdditionalPayeePercentage;
mapping(uint256 => uint256) public projectIdToSecondaryMarketRoyaltyPercentage;
address public artblocksAddress;
uint256 public artblocksPercentage = 10;
mapping(uint256 => string) public staticIpfsImageLink;
mapping(uint256 => uint256) public tokenIdToProjectId;
mapping(uint256 => uint256[]) internal projectIdToTokenIds;
mapping(uint256 => bytes32) public tokenIdToHash;
mapping(bytes32 => uint256) public hashToTokenId;
address public admin;
mapping(address => bool) public isWhitelisted;
mapping(address => bool) public isMintWhitelisted;
uint256 public nextProjectId = 3;
modifier onlyValidTokenId(uint256 _tokenId) {
require(_exists(_tokenId), "Token ID does not exist");
_;
}
modifier onlyUnlocked(uint256 _projectId) {
require(!projects[_projectId].locked, "Only if unlocked");
_;
}
modifier onlyArtist(uint256 _projectId) {
require(msg.sender == projectIdToArtistAddress[_projectId], "Only artist");
_;
}
modifier onlyAdmin() {
require(msg.sender == admin, "Only admin");
_;
}
modifier onlyWhitelisted() {
require(isWhitelisted[msg.sender], "Only whitelisted");
_;
}
modifier onlyArtistOrWhitelisted(uint256 _projectId) {
require(isWhitelisted[msg.sender] || msg.sender == projectIdToArtistAddress[_projectId], "Only artist or whitelisted");
_;
}
constructor(string memory _tokenName, string memory _tokenSymbol, address _randomizerContract) CustomERC721Metadata(_tokenName, _tokenSymbol) public {
admin = msg.sender;
isWhitelisted[msg.sender] = true;
artblocksAddress = msg.sender;
randomizerContract = Randomizer(_randomizerContract);
}
function mint(address _to, uint256 _projectId, address _by) external returns (uint256 _tokenId) {
require(isMintWhitelisted[msg.sender], "Must mint from whitelisted minter contract.");
require(projects[_projectId].invocations.add(1) <= projects[_projectId].maxInvocations, "Must not exceed max invocations");
require(projects[_projectId].active || _by == projectIdToArtistAddress[_projectId], "Project must exist and be active");
require(!projects[_projectId].paused || _by == projectIdToArtistAddress[_projectId], "Purchases are paused.");
uint256 tokenId = _mintToken(_to, _projectId);
return tokenId;
}
function _mintToken(address _to, uint256 _projectId) internal returns (uint256 _tokenId) {
uint256 tokenIdToBe = (_projectId * ONE_MILLION) + projects[_projectId].invocations;
projects[_projectId].invocations = projects[_projectId].invocations.add(1);
bytes32 hash = keccak256(abi.encodePacked(projects[_projectId].invocations, block.number, blockhash(block.number - 1), msg.sender, randomizerContract.returnValue()));
tokenIdToHash[tokenIdToBe]=hash;
hashToTokenId[hash] = tokenIdToBe;
_mint(_to, tokenIdToBe);
tokenIdToProjectId[tokenIdToBe] = _projectId;
projectIdToTokenIds[_projectId].push(tokenIdToBe);
emit Mint(_to, tokenIdToBe, _projectId);
return tokenIdToBe;
}
function updateArtblocksAddress(address _artblocksAddress) public onlyAdmin {
artblocksAddress = _artblocksAddress;
}
function updateArtblocksPercentage(uint256 _artblocksPercentage) public onlyAdmin {
require(_artblocksPercentage <= 25, "Max of 25%");
artblocksPercentage = _artblocksPercentage;
}
function addWhitelisted(address _address) public onlyAdmin {
isWhitelisted[_address] = true;
}
function removeWhitelisted(address _address) public onlyAdmin {
isWhitelisted[_address] = false;
}
function addMintWhitelisted(address _address) public onlyAdmin {
isMintWhitelisted[_address] = true;
}
function removeMintWhitelisted(address _address) public onlyAdmin {
isMintWhitelisted[_address] = false;
}
function updateRandomizerAddress(address _randomizerAddress) public onlyWhitelisted {
randomizerContract = Randomizer(_randomizerAddress);
}
function toggleProjectIsLocked(uint256 _projectId) public onlyWhitelisted onlyUnlocked(_projectId) {
projects[_projectId].locked = true;
}
function toggleProjectIsActive(uint256 _projectId) public onlyWhitelisted {
projects[_projectId].active = !projects[_projectId].active;
}
function updateProjectArtistAddress(uint256 _projectId, address _artistAddress) public onlyArtistOrWhitelisted(_projectId) {
projectIdToArtistAddress[_projectId] = _artistAddress;
}
function toggleProjectIsPaused(uint256 _projectId) public onlyArtist(_projectId) {
projects[_projectId].paused = !projects[_projectId].paused;
}
function addProject(string memory _projectName, address _artistAddress, uint256 _pricePerTokenInWei, bool _dynamic) public onlyWhitelisted {
uint256 projectId = nextProjectId;
projectIdToArtistAddress[projectId] = _artistAddress;
projects[projectId].name = _projectName;
projectIdToCurrencySymbol[projectId] = "ETH";
projectIdToPricePerTokenInWei[projectId] = _pricePerTokenInWei;
projects[projectId].paused=true;
projects[projectId].dynamic=_dynamic;
projects[projectId].maxInvocations = ONE_MILLION;
if (!_dynamic) {
projects[projectId].useHashString = false;
} else {
projects[projectId].useHashString = true;
}
nextProjectId = nextProjectId.add(1);
}
function updateProjectCurrencyInfo(uint256 _projectId, string memory _currencySymbol, address _currencyAddress) onlyArtist(_projectId) public {
projectIdToCurrencySymbol[_projectId] = _currencySymbol;
projectIdToCurrencyAddress[_projectId] = _currencyAddress;
}
function updateProjectPricePerTokenInWei(uint256 _projectId, uint256 _pricePerTokenInWei) onlyArtist(_projectId) public {
projectIdToPricePerTokenInWei[_projectId] = _pricePerTokenInWei;
}
function updateProjectName(uint256 _projectId, string memory _projectName) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].name = _projectName;
}
function updateProjectArtistName(uint256 _projectId, string memory _projectArtistName) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].artist = _projectArtistName;
}
function updateProjectAdditionalPayeeInfo(uint256 _projectId, address _additionalPayee, uint256 _additionalPayeePercentage) onlyArtist(_projectId) public {
require(_additionalPayeePercentage <= 100, "Max of 100%");
projectIdToAdditionalPayee[_projectId] = _additionalPayee;
projectIdToAdditionalPayeePercentage[_projectId] = _additionalPayeePercentage;
}
function updateProjectSecondaryMarketRoyaltyPercentage(uint256 _projectId, uint256 _secondMarketRoyalty) onlyArtist(_projectId) public {
require(_secondMarketRoyalty <= 100, "Max of 100%");
projectIdToSecondaryMarketRoyaltyPercentage[_projectId] = _secondMarketRoyalty;
}
function updateProjectDescription(uint256 _projectId, string memory _projectDescription) onlyArtist(_projectId) public {
projects[_projectId].description = _projectDescription;
}
function updateProjectWebsite(uint256 _projectId, string memory _projectWebsite) onlyArtist(_projectId) public {
projects[_projectId].website = _projectWebsite;
}
function updateProjectLicense(uint256 _projectId, string memory _projectLicense) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].license = _projectLicense;
}
function updateProjectMaxInvocations(uint256 _projectId, uint256 _maxInvocations) onlyArtist(_projectId) public {
require((!projects[_projectId].locked || _maxInvocations<projects[_projectId].maxInvocations), "Only if unlocked");
require(_maxInvocations > projects[_projectId].invocations, "You must set max invocations greater than current invocations");
require(_maxInvocations <= ONE_MILLION, "Cannot exceed 1,000,000");
projects[_projectId].maxInvocations = _maxInvocations;
}
function toggleProjectUseHashString(uint256 _projectId) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
require(projects[_projectId].invocations == 0, "Cannot modify after a token is minted.");
projects[_projectId].useHashString = !projects[_projectId].useHashString;
}
function addProjectScript(uint256 _projectId, string memory _script) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].scripts[projects[_projectId].scriptCount] = _script;
projects[_projectId].scriptCount = projects[_projectId].scriptCount.add(1);
}
function updateProjectScript(uint256 _projectId, uint256 _scriptId, string memory _script) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
require(_scriptId < projects[_projectId].scriptCount, "scriptId out of range");
projects[_projectId].scripts[_scriptId] = _script;
}
function removeProjectLastScript(uint256 _projectId) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
require(projects[_projectId].scriptCount > 0, "there are no scripts to remove");
delete projects[_projectId].scripts[projects[_projectId].scriptCount - 1];
projects[_projectId].scriptCount = projects[_projectId].scriptCount.sub(1);
}
function updateProjectScriptJSON(uint256 _projectId, string memory _projectScriptJSON) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].scriptJSON = _projectScriptJSON;
}
function updateProjectIpfsHash(uint256 _projectId, string memory _ipfsHash) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
projects[_projectId].ipfsHash = _ipfsHash;
}
function updateProjectBaseURI(uint256 _projectId, string memory _newBaseURI) onlyArtist(_projectId) public {
projects[_projectId].projectBaseURI = _newBaseURI;
}
function updateProjectBaseIpfsURI(uint256 _projectId, string memory _projectBaseIpfsURI) onlyArtist(_projectId) public {
projects[_projectId].projectBaseIpfsURI = _projectBaseIpfsURI;
}
function toggleProjectUseIpfsForStatic(uint256 _projectId) onlyArtist(_projectId) public {
require(!projects[_projectId].dynamic, "can only set static IPFS hash for static projects");
projects[_projectId].useIpfs = !projects[_projectId].useIpfs;
}
function toggleProjectIsDynamic(uint256 _projectId) onlyUnlocked(_projectId) onlyArtistOrWhitelisted(_projectId) public {
require(projects[_projectId].invocations == 0, "Can not switch after a token is minted.");
if (projects[_projectId].dynamic) {
projects[_projectId].useHashString = false;
} else {
projects[_projectId].useHashString = true;
}
projects[_projectId].dynamic = !projects[_projectId].dynamic;
}
function overrideTokenDynamicImageWithIpfsLink(uint256 _tokenId, string memory _ipfsHash) onlyArtist(tokenIdToProjectId[_tokenId]) public {
staticIpfsImageLink[_tokenId] = _ipfsHash;
}
function clearTokenIpfsImageUri(uint256 _tokenId) onlyArtist(tokenIdToProjectId[_tokenId]) public {
delete staticIpfsImageLink[tokenIdToProjectId[_tokenId]];
}
function projectDetails(uint256 _projectId) view public returns (string memory projectName, string memory artist, string memory description, string memory website, string memory license, bool dynamic) {
projectName = projects[_projectId].name;
artist = projects[_projectId].artist;
description = projects[_projectId].description;
website = projects[_projectId].website;
license = projects[_projectId].license;
dynamic = projects[_projectId].dynamic;
}
function projectTokenInfo(uint256 _projectId) view public returns (address artistAddress, uint256 pricePerTokenInWei, uint256 invocations, uint256 maxInvocations, bool active, address additionalPayee, uint256 additionalPayeePercentage ,string memory currency, address currencyAddress) {
artistAddress = projectIdToArtistAddress[_projectId];
pricePerTokenInWei = projectIdToPricePerTokenInWei[_projectId];
invocations = projects[_projectId].invocations;
maxInvocations = projects[_projectId].maxInvocations;
active = projects[_projectId].active;
additionalPayee = projectIdToAdditionalPayee[_projectId];
additionalPayeePercentage = projectIdToAdditionalPayeePercentage[_projectId];
currency = projectIdToCurrencySymbol[_projectId];
currencyAddress = projectIdToCurrencyAddress[_projectId];
}
function projectScriptInfo(uint256 _projectId) view public returns (string memory scriptJSON, uint256 scriptCount, bool useHashString, string memory ipfsHash, bool locked, bool paused) {
scriptJSON = projects[_projectId].scriptJSON;
scriptCount = projects[_projectId].scriptCount;
useHashString = projects[_projectId].useHashString;
ipfsHash = projects[_projectId].ipfsHash;
locked = projects[_projectId].locked;
paused = projects[_projectId].paused;
}
function projectScriptByIndex(uint256 _projectId, uint256 _index) view public returns (string memory){
return projects[_projectId].scripts[_index];
}
function projectURIInfo(uint256 _projectId) view public returns (string memory projectBaseURI, string memory projectBaseIpfsURI, bool useIpfs) {
projectBaseURI = projects[_projectId].projectBaseURI;
projectBaseIpfsURI = projects[_projectId].projectBaseIpfsURI;
useIpfs = projects[_projectId].useIpfs;
}
function projectShowAllTokens(uint _projectId) public view returns (uint256[] memory){
return projectIdToTokenIds[_projectId];
}
function tokensOfOwner(address owner) external view returns (uint256[] memory) {
return _tokensOfOwner(owner);
}
function getRoyaltyData(uint256 _tokenId) public view returns (address artistAddress, address additionalPayee, uint256 additionalPayeePercentage, uint256 royaltyFeeByID) {
artistAddress = projectIdToArtistAddress[tokenIdToProjectId[_tokenId]];
additionalPayee = projectIdToAdditionalPayee[tokenIdToProjectId[_tokenId]];
additionalPayeePercentage = projectIdToAdditionalPayeePercentage[tokenIdToProjectId[_tokenId]];
royaltyFeeByID = projectIdToSecondaryMarketRoyaltyPercentage[tokenIdToProjectId[_tokenId]];
}
function tokenURI(uint256 _tokenId) external view onlyValidTokenId(_tokenId) returns (string memory) {
if (bytes(staticIpfsImageLink[_tokenId]).length > 0) {
return Strings.strConcat(projects[tokenIdToProjectId[_tokenId]].projectBaseIpfsURI, staticIpfsImageLink[_tokenId]);
}
if (!projects[tokenIdToProjectId[_tokenId]].dynamic && projects[tokenIdToProjectId[_tokenId]].useIpfs) {
return Strings.strConcat(projects[tokenIdToProjectId[_tokenId]].projectBaseIpfsURI, projects[tokenIdToProjectId[_tokenId]].ipfsHash);
}
return Strings.strConcat(projects[tokenIdToProjectId[_tokenId]].projectBaseURI, Strings.uint2str(_tokenId));
}
}
Read Contract
admin 0xf851a440 → address
artblocksAddress 0x3949f906 → address
artblocksPercentage 0x4f029c39 → uint256
balanceOf 0x70a08231 → uint256
getApproved 0x081812fc → address
getRoyaltyData 0xa65ff74c → address, address, uint256, uint256
hashToTokenId 0xf51f74a9 → uint256
isApprovedForAll 0xe985e9c5 → bool
isMintWhitelisted 0xad0305ce → bool
isWhitelisted 0x3af32abf → bool
name 0x06fdde03 → string
nextProjectId 0xe935b7b1 → uint256
ownerOf 0x6352211e → address
projectDetails 0x8dd91a56 → string, string, string, string, string, bool
projectIdToAdditionalPayee 0xd7b044b6 → address
projectIdToAdditionalPayeePercentage 0xcc74234b → uint256
projectIdToArtistAddress 0xa47d29cb → address
projectIdToCurrencyAddress 0x498dd0c1 → address
projectIdToCurrencySymbol 0x20927ec9 → string
projectIdToPricePerTokenInWei 0xf70c0f04 → uint256
projectIdToSecondaryMarketRoyaltyPercentage 0xed8abfda → uint256
projectScriptByIndex 0x8c3c9cdd → string
projectScriptInfo 0x4aa6d417 → string, uint256, bool, string, bool, bool
projectShowAllTokens 0xbee04f9c → uint256[]
projectTokenInfo 0x8c2c3622 → address, uint256, uint256, uint256, bool, address, uint256, string, address
projectURIInfo 0x2d9c0205 → string, string, bool
randomizerContract 0x36c7c12c → address
staticIpfsImageLink 0x261eb4e5 → string
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
tokenByIndex 0x4f6ccce7 → uint256
tokenIdToHash 0x621a1f74 → bytes32
tokenIdToProjectId 0x1b689c0b → uint256
tokenOfOwnerByIndex 0x2f745c59 → uint256
tokenURI 0xc87b56dd → string
tokensOfOwner 0x8462151c → uint256[]
totalSupply 0x18160ddd → uint256
Write Contract 40 functions
These functions modify contract state and require a wallet transaction to execute.
addMintWhitelisted 0x8bddb0a6
address _address
addProject 0xe3f59c44
string _projectName
address _artistAddress
uint256 _pricePerTokenInWei
bool _dynamic
addProjectScript 0xacad0124
uint256 _projectId
string _script
addWhitelisted 0x10154bad
address _address
approve 0x095ea7b3
address to
uint256 tokenId
clearTokenIpfsImageUri 0x27901822
uint256 _tokenId
mint 0x0d4d1513
address _to
uint256 _projectId
address _by
returns: uint256
overrideTokenDynamicImageWithIpfsLink 0x93961c66
uint256 _tokenId
string _ipfsHash
removeMintWhitelisted 0x867f1a3b
address _address
removeProjectLastScript 0xdb2ff861
uint256 _projectId
removeWhitelisted 0x291d9549
address _address
safeTransferFrom 0x42842e0e
address from
address to
uint256 tokenId
safeTransferFrom 0xb88d4fde
address from
address to
uint256 tokenId
bytes _data
setApprovalForAll 0xa22cb465
address to
bool approved
toggleProjectIsActive 0xd03c390c
uint256 _projectId
toggleProjectIsDynamic 0x3bdbd5c4
uint256 _projectId
toggleProjectIsLocked 0x8ba8f14d
uint256 _projectId
toggleProjectIsPaused 0xa11ec70a
uint256 _projectId
toggleProjectUseHashString 0xdce5d858
uint256 _projectId
toggleProjectUseIpfsForStatic 0x5c088dcc
uint256 _projectId
transferFrom 0x23b872dd
address from
address to
uint256 tokenId
updateArtblocksAddress 0x06e1db17
address _artblocksAddress
updateArtblocksPercentage 0xed6df982
uint256 _artblocksPercentage
updateProjectAdditionalPayeeInfo 0xe13208b4
uint256 _projectId
address _additionalPayee
uint256 _additionalPayeePercentage
updateProjectArtistAddress 0x69d14faf
uint256 _projectId
address _artistAddress
updateProjectArtistName 0xb7b04fae
uint256 _projectId
string _projectArtistName
updateProjectBaseIpfsURI 0x6bd5d591
uint256 _projectId
string _projectBaseIpfsURI
updateProjectBaseURI 0x3e48e848
uint256 _projectId
string _newBaseURI
updateProjectCurrencyInfo 0xd195b365
uint256 _projectId
string _currencySymbol
address _currencyAddress
updateProjectDescription 0xa3b2cca6
uint256 _projectId
string _projectDescription
updateProjectIpfsHash 0x3fef6c2a
uint256 _projectId
string _ipfsHash
updateProjectLicense 0x25b75d68
uint256 _projectId
string _projectLicense
updateProjectMaxInvocations 0x826fc391
uint256 _projectId
uint256 _maxInvocations
updateProjectName 0x0d170673
uint256 _projectId
string _projectName
updateProjectPricePerTokenInWei 0x97dc86cf
uint256 _projectId
uint256 _pricePerTokenInWei
updateProjectScript 0xb1656ba3
uint256 _projectId
uint256 _scriptId
string _script
updateProjectScriptJSON 0xc6d73231
uint256 _projectId
string _projectScriptJSON
updateProjectSecondaryMarketRoyaltyPercentage 0xc34a03b5
uint256 _projectId
uint256 _secondMarketRoyalty
updateProjectWebsite 0x37859963
uint256 _projectId
string _projectWebsite
updateRandomizerAddress 0x6c907b7f
address _randomizerAddress
Recent Transactions
No transactions found for this address