Address Contract Verified
Address
0x7AD52eceFFcb3bD41BC434a9AcFECdBC8Ef8450e
Balance
0 ETH
Nonce
1
Code Size
8825 bytes
Creator
0x3527a204...4e6C at tx 0xc455381d...98f26a
Indexed Transactions
0 (1 on-chain, 0.7% indexed)
Contract Bytecode
8825 bytes
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c8063715018a61161010f578063b88d4fde116100a2578063e985e9c511610071578063e985e9c51461041b578063ed459df214610457578063f2fde38b1461046a578063ffbdc8cb1461047d57600080fd5b8063b88d4fde146103da578063c87b56dd146103ed578063e2e784d514610400578063e8a3d4851461041357600080fd5b80638da5cb5b116100de5780638da5cb5b146103995780638f32d59b146103ac57806395d89b41146103bf578063a22cb465146103c757600080fd5b8063715018a61461035957806379ba5097146103615780638a71bb2d146103695780638b6854a21461037257600080fd5b806342842e0e116101875780636352211e116101565780636352211e14610322578063646c2e33146103355780636c0360eb1461033e57806370a082311461034657600080fd5b806342842e0e146102d657806342966c68146102e95780634c00de82146102fc5780636039dca91461030f57600080fd5b806318160ddd116101c357806318160ddd1461027257806323452b9c1461028957806323b872dd146102915780632a55205a146102a457600080fd5b806301ffc9a7146101f557806306fdde031461021d578063081812fc14610232578063095ea7b31461025d575b600080fd5b610208610203366004611b65565b610492565b60405190151581526020015b60405180910390f35b6102256105c3565b6040516102149190611be1565b610245610240366004611bf4565b610651565b6040516001600160a01b039091168152602001610214565b61027061026b366004611c32565b6106f7565b005b61027b60065481565b604051908152602001610214565b610270610847565b61027061029f366004611c5e565b6108b3565b6102b76102b2366004611c9f565b61093a565b604080516001600160a01b039093168352602083019190915201610214565b6102706102e4366004611c5e565b610970565b6102706102f7366004611bf4565b61098b565b600c54610245906001600160a01b031681565b61027061031d366004611da6565b610a13565b610245610330366004611bf4565b610cf2565b61027b60055481565b610225610dbb565b61027b610354366004611ee2565b610dc8565b610270610e62565b610270610ec6565b61027b600d5481565b6102457f0000000000000000000000000e1c07384dd2ada007e4b819816fd34afb4678f181565b600054610245906001600160a01b031681565b6000546001600160a01b03163314610208565b610225610f8e565b6102706103d5366004611eff565b610f9b565b6102706103e8366004611f2b565b611061565b6102256103fb366004611bf4565b6110ef565b61027061040e366004611c32565b611123565b6102256111d8565b610208610429366004611fab565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205460ff1690565b6001546001600160a01b03163314610208565b610270610478366004611ee2565b611200565b61027b61048b366004611bf4565b5060055490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061052557507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061057157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b806105bd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000145b92915050565b600280546105d090611fe4565b80601f01602080910402602001604051908101604052809291908181526020018280546105fc90611fe4565b80156106495780601f1061061e57610100808354040283529160200191610649565b820191906000526020600020905b81548152906001019060200180831161062c57829003601f168201915b505050505081565b60008181526007602052604081205460ff16156106db5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152600a60205260409020546001600160a01b031690565b600061070282610cf2565b9050806001600160a01b0316836001600160a01b0316141561078c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016106d2565b336001600160a01b03821614806107c657506001600160a01b0381166000908152600b6020908152604080832033845290915290205460ff165b6108385760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016106d2565b61084283836112d2565b505050565b6000546001600160a01b031633146108a15760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064016106d2565b600180546001600160a01b0319169055565b6108bd3382611340565b61092f5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016106d2565b610842838383611443565b600c54600d546001600160a01b03909116906000906127109061095d9085612035565b610967919061206a565b90509250929050565b61084283838360405180602001604052806000815250611061565b6109953382611340565b610a075760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016106d2565b610a1081611613565b50565b303b15610a1f57600080fd5b88518051610a3591600291602090910190611a9e565b506020808a01518051610a4c926003920190611a9e565b5060408901518051610a6691600491602090910190611a9e565b5060608901516005556080890151600655610a826000896116c3565b600c80546001600160a01b0319166001600160a01b0388811691909117909155600d86905560808a01519089169060009081907fdeaa91b6123d068f5821d0fb0678463d1a8a6079fe8af5de3ce5e896dcf9133d90610ae39060019061207e565b60405190815260200160405180910390a46006546001600160a01b0389166000908152600960205260409020558215610ce7577f0000000000000000000000000e1c07384dd2ada007e4b819816fd34afb4678f16001600160a01b0316637d762af3604051806101000160405280306001600160a01b03168152602001600081526020016001600654610b76919061207e565b81526020018b6001600160a01b031681526020018a6001600160a01b031681526020018781526020018515158152602001848152506040518263ffffffff1660e01b8152600401610c2c91906000610100820190506001600160a01b0380845116835260208401516020840152604084015160408401528060608501511660608401528060808501511660808401525060a083015160a083015260c0830151151560c083015260e083015160e083015292915050565b600060405180830381600087803b158015610c4657600080fd5b505af1158015610c5a573d6000803e3d6000fd5b505050506001600160a01b038881166000818152600b602090815260408083207f0000000000000000000000000e1c07384dd2ada007e4b819816fd34afb4678f190951680845294825291829020805460ff1916600190811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35b505050505050505050565b6000818152600860205260408120546001600160a01b031680158015610d27575060008381526007602052604090205460ff16155b15610d3f5750506000546001600160a01b0316919050565b6001600160a01b0381166105bd5760405162461bcd60e51b815260206004820152602360248201527f4552433732313a20717565727920666f72206e6f6e6578697374656e7420746f60448201527f6b656e000000000000000000000000000000000000000000000000000000000060648201526084016106d2565b600480546105d090611fe4565b60006001600160a01b038216610e465760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016106d2565b506001600160a01b031660009081526009602052604090205490565b6000546001600160a01b03163314610ebc5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064016106d2565b610ec4611712565b565b6001546001600160a01b03163314610f465760405162461bcd60e51b815260206004820152602c60248201527f63757272656e74206f776e6572206d757374207365742063616c6c657220617360448201527f206e657874206f776e65722e000000000000000000000000000000000000000060648201526084016106d2565b600180546001600160a01b0319908116909155600080543392168217815560405182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3565b600380546105d090611fe4565b6001600160a01b038216331415610ff45760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016106d2565b336000818152600b602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3191015b60405180910390a35050565b61106b3383611340565b6110dd5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016106d2565b6110e98484848461174e565b50505050565b606060046110fc836117d7565b60405160200161110d92919061212f565b6040516020818303038152906040529050919050565b6000546001600160a01b0316331461117d5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064016106d2565b600c80546001600160a01b0319166001600160a01b038416908117909155600d829055604080518381526020810184905282917f880886fe0560f4b0a18941fe4c443a499c03fd9491832ddfc895278ac7e8878c9101611055565b606060046040516020016111ec9190612154565b604051602081830303815290604052905090565b6000546001600160a01b0316331461125a5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064016106d2565b6001600160a01b0381166112b05760405162461bcd60e51b815260206004820152601f60248201527f4e657874206f776e657220697320746865207a65726f20616464726573732e0060448201526064016106d2565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600a6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061130782610cf2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526007602052604081205460ff16156113c55760405162461bcd60e51b815260206004820152602360248201527f4552433732313a20717565727920666f72206e6f6e6578697374656e7420746f60448201527f6b656e000000000000000000000000000000000000000000000000000000000060648201526084016106d2565b60006113d083610cf2565b9050806001600160a01b0316846001600160a01b0316148061140b5750836001600160a01b031661140084610651565b6001600160a01b0316145b8061143b57506001600160a01b038082166000908152600b602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661145682610cf2565b6001600160a01b0316146114d25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016106d2565b6001600160a01b03821661154e5760405162461bcd60e51b815260206004820152603760248201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573732028757365206275726e20696e73746561642900000000000000000060648201526084016106d2565b6115596000826112d2565b6001600160a01b038316600090815260096020526040812080546001929061158290849061207e565b9091555050600081815260086020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600990915281208054600192906115ce90849061218d565b909155505060405181906001600160a01b0380851691908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050565b600061161e82610cf2565b905061162b6000836112d2565b6001600160a01b038116600090815260096020526040812080546001929061165490849061207e565b9091555050600082815260086020908152604080832080546001600160a01b03191690556007909152808220805460ff19166001179055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080546001600160a01b0319166001600160a01b0383811691821783556040519192908516917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080546001600160a01b031916815560405181907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3565b611759848484611443565b61176584848484611909565b6110e95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016106d2565b60608161181757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611841578061182b816121a5565b915061183a9050600a8361206a565b915061181b565b60008167ffffffffffffffff81111561185c5761185c611cc1565b6040519080825280601f01601f191660200182016040528015611886576020820181803683370190505b5090505b841561143b5761189b60018361207e565b91506118a8600a866121c0565b6118b390603061218d565b60f81b8183815181106118c8576118c86121d4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611902600a8661206a565b945061188a565b6000833b15611a93576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a029061195d9033908990889088906004016121ea565b6020604051808303816000875af1925050508015611998575060408051601f3d908101601f1916820190925261199591810190612226565b60015b611a48573d8080156119c6576040519150601f19603f3d011682016040523d82523d6000602084013e6119cb565b606091505b508051611a405760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016106d2565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a020000000000000000000000000000000000000000000000000000000014905061143b565b506001949350505050565b828054611aaa90611fe4565b90600052602060002090601f016020900481019282611acc5760008555611b12565b82601f10611ae557805160ff1916838001178555611b12565b82800160010185558215611b12579182015b82811115611b12578251825591602001919060010190611af7565b50611b1e929150611b22565b5090565b5b80821115611b1e5760008155600101611b23565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610a1057600080fd5b600060208284031215611b7757600080fd5b8135611b8281611b37565b9392505050565b60005b83811015611ba4578181015183820152602001611b8c565b838111156110e95750506000910152565b60008151808452611bcd816020860160208601611b89565b601f01601f19169290920160200192915050565b602081526000611b826020830184611bb5565b600060208284031215611c0657600080fd5b5035919050565b6001600160a01b0381168114610a1057600080fd5b8035611c2d81611c0d565b919050565b60008060408385031215611c4557600080fd5b8235611c5081611c0d565b946020939093013593505050565b600080600060608486031215611c7357600080fd5b8335611c7e81611c0d565b92506020840135611c8e81611c0d565b929592945050506040919091013590565b60008060408385031215611cb257600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715611cfa57611cfa611cc1565b60405290565b600067ffffffffffffffff80841115611d1b57611d1b611cc1565b604051601f8501601f19908116603f01168101908282118183101715611d4357611d43611cc1565b81604052809350858152868686011115611d5c57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112611d8757600080fd5b611b8283833560208501611d00565b80358015158114611c2d57600080fd5b60008060008060008060008060006101208a8c031215611dc557600080fd5b893567ffffffffffffffff80821115611ddd57600080fd5b908b019060a0828e031215611df157600080fd5b611df9611cd7565b823582811115611e0857600080fd5b611e148f828601611d76565b825250602083013582811115611e2957600080fd5b611e358f828601611d76565b602083015250604083013582811115611e4d57600080fd5b611e598f828601611d76565b6040830152506060830135606082015260808301356080820152809b50505050611e8560208b01611c22565b9750611e9360408b01611c22565b9650611ea160608b01611c22565b955060808a0135945060a08a01359350611ebd60c08b01611d96565b9250611ecb60e08b01611d96565b91506101008a013590509295985092959850929598565b600060208284031215611ef457600080fd5b8135611b8281611c0d565b60008060408385031215611f1257600080fd5b8235611f1d81611c0d565b915061096760208401611d96565b60008060008060808587031215611f4157600080fd5b8435611f4c81611c0d565b93506020850135611f5c81611c0d565b925060408501359150606085013567ffffffffffffffff811115611f7f57600080fd5b8501601f81018713611f9057600080fd5b611f9f87823560208401611d00565b91505092959194509250565b60008060408385031215611fbe57600080fd5b8235611fc981611c0d565b91506020830135611fd981611c0d565b809150509250929050565b600181811c90821680611ff857607f821691505b6020821081141561201957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561204f5761204f61201f565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261207957612079612054565b500490565b6000828210156120905761209061201f565b500390565b8054600090600181811c90808316806120af57607f831692505b60208084108214156120d157634e487b7160e01b600052602260045260246000fd5b8180156120e557600181146120f657612123565b60ff19861689528489019650612123565b60008881526020902060005b8681101561211b5781548b820152908501908301612102565b505084890196505b50505050505092915050565b600061213b8285612095565b835161214b818360208801611b89565b01949350505050565b60006121608284612095565b7f6d6574616461746100000000000000000000000000000000000000000000000081526008019392505050565b600082198211156121a0576121a061201f565b500190565b60006000198214156121b9576121b961201f565b5060010190565b6000826121cf576121cf612054565b500690565b634e487b7160e01b600052603260045260246000fd5b60006001600160a01b0380871683528086166020840152508360408301526080606083015261221c6080830184611bb5565b9695505050505050565b60006020828403121561223857600080fd5b8151611b8281611b3756fea2646970667358221220cb19a8ac90fbb5247db8e82c8531344781baa74579b708b1bf8097993d93df4764736f6c634300080a0033
Verified Source Code Full Match
Compiler: v0.8.10+commit.fc410830
EVM: london
Optimization: Yes (2000 runs)
Ownable.sol 93 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IOwnableEvents {
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
}
contract Ownable is IOwnableEvents {
address public owner;
address private nextOwner;
// modifiers
modifier onlyOwner() {
require(isOwner(), "caller is not the owner.");
_;
}
modifier onlyNextOwner() {
require(isNextOwner(), "current owner must set caller as next owner.");
_;
}
/**
* @dev Initialize contract by setting transaction submitter as initial owner.
*/
constructor(address owner_) {
owner = owner_;
emit OwnershipTransferred(address(0), owner);
}
/**
* @dev Initiate ownership transfer by setting nextOwner.
*/
function transferOwnership(address nextOwner_) external onlyOwner {
require(nextOwner_ != address(0), "Next owner is the zero address.");
nextOwner = nextOwner_;
}
/**
* @dev Cancel ownership transfer by deleting nextOwner.
*/
function cancelOwnershipTransfer() external onlyOwner {
delete nextOwner;
}
/**
* @dev Accepts ownership transfer by setting owner.
*/
function acceptOwnership() external onlyNextOwner {
delete nextOwner;
owner = msg.sender;
emit OwnershipTransferred(owner, msg.sender);
}
/**
* @dev Renounce ownership by setting owner to zero address.
*/
function renounceOwnership() external onlyOwner {
_renounceOwnership();
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return msg.sender == owner;
}
/**
* @dev Returns true if the caller is the next owner.
*/
function isNextOwner() public view returns (bool) {
return msg.sender == nextOwner;
}
function _setOwner(address previousOwner, address newOwner) internal {
owner = newOwner;
emit OwnershipTransferred(previousOwner, owner);
}
function _renounceOwnership() internal {
owner = address(0);
emit OwnershipTransferred(owner, address(0));
}
}
IERC165.sol 18 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return interfaceId == type(IERC165).interfaceId;
}
}
IERC721.sol 89 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IERC721 {
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId)
external
view
returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
interface IERC721Events {
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
);
}
interface IERC721Metadata {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
interface IERC721Burnable is IERC721 {
function burn(uint256 tokenId) external;
}
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
interface IERC721Royalties {
function getFeeRecipients(uint256 id)
external
view
returns (address payable[] memory);
function getFeeBps(uint256 id) external view returns (uint256[] memory);
}
IERC2309.sol 11 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IERC2309 {
event ConsecutiveTransfer(
uint256 indexed fromTokenId,
uint256 toTokenId,
address indexed fromAddress,
address indexed toAddress
);
}
IERC2981.sol 23 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
/**
* @title IERC2981
* @notice Interface for the NFT Royalty Standard
*/
interface IERC2981 {
// / bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
/**
* @notice Called with the sale price to determine how much royalty
* is owed and to whom.
* @param _tokenId - the NFT asset queried for royalty information
* @param _salePrice - the sale price of the NFT asset specified by _tokenId
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for _salePrice
*/
function royaltyInfo(uint256 _tokenId, uint256 _salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
IMirrorOpenSaleV0.sol 73 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IMirrorOpenSaleV0Events {
event RegisteredSale(
bytes32 h,
address indexed token,
uint256 startTokenId,
uint256 endTokenId,
address indexed operator,
address indexed recipient,
uint256 price,
bool open,
uint256 feePercentage
);
event Purchase(
bytes32 h,
address indexed token,
uint256 tokenId,
address indexed buyer,
address indexed recipient
);
event Withdraw(
bytes32 h,
uint256 amount,
uint256 fee,
address indexed recipient
);
event OpenSale(bytes32 h);
event CloseSale(bytes32 h);
}
interface IMirrorOpenSaleV0 {
struct Sale {
bool registered;
bool open;
uint256 sold;
address operator;
}
struct SaleConfig {
address token;
uint256 startTokenId;
uint256 endTokenId;
address operator;
address recipient;
uint256 price;
bool open;
uint256 feePercentage;
}
function treasuryConfig() external returns (address);
function feeRegistry() external returns (address);
function tributaryRegistry() external returns (address);
function sale(bytes32 h) external view returns (Sale memory);
function register(SaleConfig calldata saleConfig_) external;
function close(SaleConfig calldata saleConfig_) external;
function open(SaleConfig calldata saleConfig_) external;
function purchase(SaleConfig calldata saleConfig_, address recipient)
external
payable;
}
MirrorAllocatedEditionsLogic.sol 515 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
import {Ownable} from "../../lib/Ownable.sol";
import {IMirrorAllocatedEditionsLogic} from "./interface/IMirrorAllocatedEditionsLogic.sol";
import {IERC721, IERC721Events, IERC721Receiver, IERC721Metadata} from "../../lib/ERC721/interface/IERC721.sol";
import {IERC165} from "../../lib/ERC165/interface/IERC165.sol";
import {IERC2981} from "../../lib/ERC2981/interface/IERC2981.sol";
import {IMirrorOpenSaleV0} from "../../distributors/open-sale/interface/IMirrorOpenSaleV0.sol";
import {IERC2309} from "../../lib/ERC2309/interface/IERC2309.sol";
/**
* @title MirrorAllocatedEditionsLogic
* @author MirrorXYZ
*/
contract MirrorAllocatedEditionsLogic is
Ownable,
IMirrorAllocatedEditionsLogic,
IERC721,
IERC721Events,
IERC165,
IERC721Metadata,
IERC2309,
IERC2981
{
/// @notice Token name
string public override name;
/// @notice Token symbol
string public override symbol;
/// @notice Token baseURI
string public baseURI;
/// @notice Token contentHash
bytes32 public contentHash;
/// @notice Token supply
uint256 public totalSupply;
/// @notice Burned tokens
mapping(uint256 => bool) internal _burned;
/// @notice Token owners
mapping(uint256 => address) internal _owners;
/// @notice Token balances
mapping(address => uint256) internal _balances;
/// @notice Token approvals
mapping(uint256 => address) internal _tokenApprovals;
/// @notice Token operator approvals
mapping(address => mapping(address => bool)) internal _operatorApprovals;
/// @notice Mirror open sale address
address public immutable mirrorOpenSale;
// ============ Royalty Info (ERC2981) ============
/// @notice Account that will receive royalties
/// @dev set address(0) to avoid royalties
address public royaltyRecipient;
/// @notice Royalty percentage
uint256 public royaltyPercentage;
/// @dev Sets zero address as owner since this is a logic contract
/// @param mirrorOpenSale_ sale contract address
constructor(address mirrorOpenSale_) Ownable(address(0)) {
mirrorOpenSale = mirrorOpenSale_;
}
// ============ Constructor ============
/// @dev Initialize contract
/// @param metadata ERC721Metadata parameters
/// @param owner_ owner of this contract
/// @param fundingRecipient_ account that will receive funds from sales
/// @param royaltyRecipient_ account that will receive royalties
/// @param royaltyPercentage_ royalty percentage
/// @param price sale listing price
/// @param list whether to list on sale contract
/// @param open whether to list with a closed or open sale
/// @dev Initialize parameters, mint total suppply to owner. Reverts if called
/// after contract deployment. If list is true, the open sale contract gets approval
/// for all tokens.
function initialize(
NFTMetadata memory metadata,
address owner_,
address payable fundingRecipient_,
address payable royaltyRecipient_,
uint256 royaltyPercentage_,
uint256 price,
bool list,
bool open,
uint256 feePercentage
) external override {
// ensure that this function is only callable during contract construction.
assembly {
if extcodesize(address()) {
revert(0, 0)
}
}
// NFT Metadata
name = metadata.name;
symbol = metadata.symbol;
baseURI = metadata.baseURI;
contentHash = metadata.contentHash;
totalSupply = metadata.quantity;
// Set owner
_setOwner(address(0), owner_);
// Royalties
royaltyRecipient = royaltyRecipient_;
royaltyPercentage = royaltyPercentage_;
emit ConsecutiveTransfer(
// fromTokenId
0,
// toTokenId
metadata.quantity - 1,
// fromAddress
address(0),
// toAddress
owner_
);
_balances[owner_] = totalSupply;
if (list) {
IMirrorOpenSaleV0(mirrorOpenSale).register(
IMirrorOpenSaleV0.SaleConfig({
token: address(this),
startTokenId: 0,
endTokenId: totalSupply - 1,
operator: owner_,
recipient: fundingRecipient_,
price: price,
open: open,
feePercentage: feePercentage
})
);
_operatorApprovals[owner_][mirrorOpenSale] = true;
emit ApprovalForAll(
// owner
owner_,
// operator
mirrorOpenSale,
// approved
true
);
}
}
// ============ ERC721 Methods ============
function balanceOf(address owner_) public view override returns (uint256) {
require(
owner_ != address(0),
"ERC721: balance query for the zero address"
);
return _balances[owner_];
}
function ownerOf(uint256 tokenId) public view override returns (address) {
address _owner = _owners[tokenId];
// if there is not owner set, and the token is not burned, the operator owns it
if (_owner == address(0) && !_burned[tokenId]) {
return owner;
}
require(_owner != address(0), "ERC721: query for nonexistent token");
return _owner;
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public override {
//solhint-disable-next-line max-line-length
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public override {
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_safeTransfer(from, to, tokenId, _data);
}
function approve(address to, uint256 tokenId) public override {
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"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId)
public
view
override
returns (address)
{
require(
_exists(tokenId),
"ERC721: approved query for nonexistent token"
);
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved)
public
override
{
require(operator != msg.sender, "ERC721: approve to caller");
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(
// owner
msg.sender,
// operator
operator,
// approved
approved
);
}
function isApprovedForAll(address owner_, address operator_)
public
view
override
returns (bool)
{
return _operatorApprovals[owner_][operator_];
}
// ============ ERC721 Metadata Methods ============
function tokenURI(uint256 tokenId)
public
view
override
returns (string memory)
{
return string(abi.encodePacked(baseURI, _toString(tokenId)));
}
function contractURI() public view returns (string memory) {
return string(abi.encodePacked(baseURI, "metadata"));
}
function getContentHash(uint256) public view returns (bytes32) {
return contentHash;
}
// ============ Burn Method ============
function burn(uint256 tokenId) public {
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_burn(tokenId);
}
// ============ ERC2981 Methods ============
/// @notice Get royalty info
function royaltyInfo(uint256 _tokenId, uint256 _salePrice)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
receiver = royaltyRecipient;
royaltyAmount = (_salePrice * royaltyPercentage) / 10_000;
}
function setRoyaltyInfo(
address payable royaltyRecipient_,
uint256 royaltyPercentage_
) external override onlyOwner {
royaltyRecipient = royaltyRecipient_;
royaltyPercentage = royaltyPercentage_;
emit RoyaltyChange(
// oldRoyaltyRecipient
royaltyRecipient,
// oldRoyaltyPercentage
royaltyPercentage,
// newRoyaltyRecipient
royaltyRecipient_,
// newRoyaltyPercentage
royaltyPercentage_
);
}
// ============ IERC165 Method ============
function supportsInterface(bytes4 interfaceId)
public
pure
override
returns (bool)
{
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
interfaceId == type(IERC165).interfaceId ||
interfaceId == type(IERC2981).interfaceId;
}
// ============ Internal Methods ============
function _transfer(
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 (use burn instead)"
);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_owners[tokenId] = to;
_balances[to] += 1;
emit Transfer(
// from
from,
// to
to,
// tokenId
tokenId
);
}
function _exists(uint256 tokenId) internal view returns (bool) {
return !_burned[tokenId];
}
function _burn(uint256 tokenId) internal {
address owner_ = ownerOf(tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner_] -= 1;
delete _owners[tokenId];
_burned[tokenId] = true;
emit Transfer(
// from
owner_,
// to
address(0),
// tokenId
tokenId
);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal {
_transfer(from, to, tokenId);
require(
_checkOnERC721Received(from, to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _isApprovedOrOwner(address spender, uint256 tokenId)
internal
view
returns (bool)
{
require(_exists(tokenId), "ERC721: query for nonexistent token");
address owner_ = ownerOf(tokenId);
return (spender == owner_ ||
getApproved(tokenId) == spender ||
isApprovedForAll(owner_, spender));
}
function _approve(address to, uint256 tokenId) internal {
_tokenApprovals[tokenId] = to;
emit Approval(
// owner
ownerOf(tokenId),
// approved
to,
// tokenId
tokenId
);
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (_isContract(to)) {
try
IERC721Receiver(to).onERC721Received(
msg.sender,
from,
tokenId,
_data
)
returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert(
"ERC721: transfer to non ERC721Receiver implementer"
);
} else {
// solhint-disable-next-line no-inline-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7f6a1666fac8ecff5dd467d0938069bc221ea9e0/contracts/utils/Address.sol
function _isContract(address account) internal view returns (bool) {
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly {
size := extcodesize(account)
}
return size > 0;
}
// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol
function _toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
}
IMirrorAllocatedEditionsLogic.sol 36 lines
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.10;
interface IMirrorAllocatedEditionsLogic {
event RoyaltyChange(
address indexed oldRoyaltyRecipient,
uint256 oldRoyaltyPercentage,
address indexed newRoyaltyRecipient,
uint256 newRoyaltyPercentage
);
struct NFTMetadata {
string name;
string symbol;
string baseURI;
bytes32 contentHash;
uint256 quantity;
}
function initialize(
NFTMetadata memory metadata,
address operator_,
address payable fundingRecipient_,
address payable royaltyRecipient_,
uint256 royaltyPercentage_,
uint256 price,
bool list,
bool open,
uint256 feePercentage
) external;
function setRoyaltyInfo(
address payable royaltyRecipient_,
uint256 royaltyPercentage_
) external;
}
Read Contract
balanceOf 0x70a08231 → uint256
baseURI 0x6c0360eb → string
contentHash 0x646c2e33 → bytes32
contractURI 0xe8a3d485 → string
getApproved 0x081812fc → address
getContentHash 0xffbdc8cb → bytes32
isApprovedForAll 0xe985e9c5 → bool
isNextOwner 0xed459df2 → bool
isOwner 0x8f32d59b → bool
mirrorOpenSale 0x8b6854a2 → address
name 0x06fdde03 → string
owner 0x8da5cb5b → address
ownerOf 0x6352211e → address
royaltyInfo 0x2a55205a → address, uint256
royaltyPercentage 0x8a71bb2d → uint256
royaltyRecipient 0x4c00de82 → address
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
tokenURI 0xc87b56dd → string
totalSupply 0x18160ddd → uint256
Write Contract 12 functions
These functions modify contract state and require a wallet transaction to execute.
acceptOwnership 0x79ba5097
No parameters
approve 0x095ea7b3
address to
uint256 tokenId
burn 0x42966c68
uint256 tokenId
cancelOwnershipTransfer 0x23452b9c
No parameters
initialize 0x71bbf622
tuple metadata
address owner_
address fundingRecipient_
address royaltyRecipient_
uint256 royaltyPercentage_
uint256 price
bool list
bool open
uint256 feePercentage
renounceOwnership 0x715018a6
No parameters
safeTransferFrom 0x42842e0e
address from
address to
uint256 tokenId
safeTransferFrom 0xb88d4fde
address from
address to
uint256 tokenId
bytes _data
setApprovalForAll 0xa22cb465
address operator
bool approved
setRoyaltyInfo 0xe2e784d5
address royaltyRecipient_
uint256 royaltyPercentage_
transferFrom 0x23b872dd
address from
address to
uint256 tokenId
transferOwnership 0xf2fde38b
address nextOwner_
Recent Transactions
This address has 1 on-chain transactions, but only 0.7% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →