Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
ConsensualNonTransferableTokenManager2
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "../utils/Ownable.sol"; import "./InterfaceSupportEditionsTokenManager.sol"; import "./interfaces/IPostTransfer.sol"; import "./interfaces/IPostBurn.sol"; import "./interfaces/ITokenManagerEditions.sol"; /** * @author highlight.xyz * @notice A basic token manager that prevents transfers unless recipient is nft contract owner, and allows burns. Second version */ contract ConsensualNonTransferableTokenManager2 is ITokenManagerEditions, IPostTransfer, IPostBurn, InterfaceSupportEditionsTokenManager { /** * @notice See {ITokenManager-canUpdateMetadata} */ function canUpdateMetadata( address sender, uint256 /* id */, bytes calldata /* newTokenImageUri */ ) external view override returns (bool) { return Ownable(msg.sender).owner() == sender; } /** * @notice See {ITokenManagerEditions-canUpdateEditionsMetadata} */ function canUpdateEditionsMetadata( address editionsAddress, address sender, uint256 /* editionId */, bytes calldata /* newTokenImageUri */, FieldUpdated /* fieldUpdated */ ) external view override returns (bool) { return Ownable(editionsAddress).owner() == sender; } /** * @notice See {ITokenManager-canSwap} */ function canSwap( address sender, uint256 /* id */, address /* newTokenManager */ ) external view override returns (bool) { return Ownable(msg.sender).owner() == sender; } /** * @notice See {ITokenManager-canRemoveItself} */ function canRemoveItself(address sender, uint256 /* id */) external view override returns (bool) { return Ownable(msg.sender).owner() == sender; } /** * @notice See {IPostTransfer-postSafeTransferFrom} */ function postSafeTransferFrom( address /* operator */, address /* from */, address to, uint256 /* id */, bytes memory /* data */ ) external view override { if (to != Ownable(msg.sender).owner()) { revert("Transfers disallowed"); } } /** * @notice See {IPostTransfer-postTransferFrom} */ function postTransferFrom( address /* operator */, address /* from */, address to, uint256 /* id */ ) external view override { if (to != Ownable(msg.sender).owner()) { revert("Transfers disallowed"); } } /* solhint-disable no-empty-blocks */ /** * @notice See {IPostBurn-postBurn} */ function postBurn(address /* operator */, address /* sender */, uint256 /* id */) external pure override {} /* solhint-enable no-empty-blocks */ /** * @notice See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(InterfaceSupportEditionsTokenManager) returns (bool) { return interfaceId == type(IPostTransfer).interfaceId || interfaceId == type(IPostBurn).interfaceId || InterfaceSupportEditionsTokenManager.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /** * @author highlight.xyz * @notice If token managers implement this, transfer actions will call * postBurn on the token manager. */ interface IPostBurn { /** * @notice Hook called by contract after burn, if token manager of burned token implements this * interface. * @param operator Operator burning tokens * @param sender Msg sender * @param id Burned token's id or id of edition of token that is burned */ function postBurn(address operator, address sender, uint256 id) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /** * @author highlight.xyz * @notice If token managers implement this, transfer actions will call * postSafeTransferFrom or postTransferFrom on the token manager. */ interface IPostTransfer { /** * @notice Hook called by community after safe transfers, if token manager of transferred token implements this * interface. * @param operator Operator transferring tokens * @param from Token(s) sender * @param to Token(s) recipient * @param id Transferred token's id * @param data Arbitrary data */ function postSafeTransferFrom(address operator, address from, address to, uint256 id, bytes memory data) external; /** * @notice Hook called by community after transfers, if token manager of transferred token implements * this interface. * @param operator Operator transferring tokens * @param from Token(s) sender * @param to Token(s) recipient * @param id Transferred token's id */ function postTransferFrom(address operator, address from, address to, uint256 id) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title ITokenManager * @author highlight.xyz * @notice Enables interfacing with custom token managers */ interface ITokenManager { /** * @notice Returns whether metadata updater is allowed to update * @param sender Updater * @param id Token/edition who's uri is being updated * If id is 0, implementation should decide behaviour for base uri update * @param newData Token's new uri if called by general contract, and any metadata field if called by editions * @return If invocation can update metadata */ function canUpdateMetadata(address sender, uint256 id, bytes calldata newData) external returns (bool); /** * @notice Returns whether token manager can be swapped for another one by invocator * @notice Default token manager implementations should ignore id * @param sender Swapper * @param id Token grouping id (token id or edition id) * @param newTokenManager New token manager being swapped to * @return If invocation can swap token managers */ function canSwap(address sender, uint256 id, address newTokenManager) external returns (bool); /** * @notice Returns whether token manager can be removed * @notice Default token manager implementations should ignore id * @param sender Swapper * @param id Token grouping id (token id or edition id) * @return If invocation can remove token manager */ function canRemoveItself(address sender, uint256 id) external returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./ITokenManager.sol"; /** * @title ITokenManager * @author highlight.xyz * @notice Enables interfacing with custom token managers for editions contracts */ interface ITokenManagerEditions is ITokenManager { /** * @notice The updated field in metadata updates */ enum FieldUpdated { name, description, imageUrl, animationUrl, externalUrl, attributes, other } /** * @notice Returns whether metadata updater is allowed to update * @param editionsAddress Address of editions contract * @param sender Updater * @param editionId Token/edition who's uri is being updated * If id is 0, implementation should decide behaviour for base uri update * @param newData Token's new uri if called by general contract, and any metadata field if called by editions * @param fieldUpdated Which metadata field was updated * @return If invocation can update metadata */ function canUpdateEditionsMetadata( address editionsAddress, address sender, uint256 editionId, bytes calldata newData, FieldUpdated fieldUpdated ) external returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./InterfaceSupportTokenManager.sol"; import "./interfaces/ITokenManagerEditions.sol"; /** * @author highlight.xyz * @notice Abstract contract to be inherited by all valid editions token managers */ abstract contract InterfaceSupportEditionsTokenManager is InterfaceSupportTokenManager { /** * @notice See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(InterfaceSupportTokenManager) returns (bool) { return interfaceId == type(ITokenManagerEditions).interfaceId || InterfaceSupportTokenManager.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./interfaces/ITokenManager.sol"; import "../utils/ERC165/IERC165.sol"; /** * @author highlight.xyz * @notice Abstract contract to be inherited by all valid token managers */ abstract contract InterfaceSupportTokenManager { /** * @notice See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(ITokenManager).interfaceId || _supportsERC165Interface(interfaceId); } /** * @notice Used to show support for IERC165, without inheriting contract from IERC165 implementations */ function _supportsERC165Interface(bytes4 interfaceId) internal pure returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity 0.8.10; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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 * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity 0.8.10; import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ /* solhint-disable */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
{ "metadata": { "bytecodeHash": "none" }, "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"canRemoveItself","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"canSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"editionsAddress","type":"address"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"enum ITokenManagerEditions.FieldUpdated","name":"","type":"uint8"}],"name":"canUpdateEditionsMetadata","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"canUpdateMetadata","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"postBurn","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postSafeTransferFrom","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"postTransferFrom","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506108d7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100785760003560e01c806301ffc9a71461007d578063129dae8b146100a45780633d820a4d146100b95780637f1eaf85146100cc57806385e335b6146100df5780638af6791b146100f25780639d22e78e14610105578063ce2003a514610118575b600080fd5b61009061008b366004610503565b61012b565b604051901515815260200160405180910390f35b6100b76100b236600461054c565b505050565b005b6100906100c73660046105d5565b610171565b6100b76100da366004610630565b6101f2565b6100906100ed366004610681565b610293565b6100b76101003660046106d9565b610313565b6100906101133660046107cb565b6103ac565b610090610126366004610853565b61042f565b60006001600160e01b03198216637af46b4f60e11b148061015c57506001600160e01b0319821663129dae8b60e01b145b8061016b575061016b826104ae565b92915050565b6000846001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101df919061087f565b6001600160a01b03161495945050505050565b336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610230573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610254919061087f565b6001600160a01b0316826001600160a01b03161461028d5760405162461bcd60e51b81526004016102849061089c565b60405180910390fd5b50505050565b6000836001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610301919061087f565b6001600160a01b031614949350505050565b336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610351573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610375919061087f565b6001600160a01b0316836001600160a01b0316146103a55760405162461bcd60e51b81526004016102849061089c565b5050505050565b6000856001600160a01b0316876001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041a919061087f565b6001600160a01b031614979650505050505050565b6000826001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049d919061087f565b6001600160a01b0316149392505050565b60006001600160e01b03198216634e9173c760e11b148061016b575061016b8260006001600160e01b03198216633b209e2f60e11b148061016b57506301ffc9a760e01b6001600160e01b031983161461016b565b60006020828403121561051557600080fd5b81356001600160e01b03198116811461052d57600080fd5b9392505050565b6001600160a01b038116811461054957600080fd5b50565b60008060006060848603121561056157600080fd5b833561056c81610534565b9250602084013561057c81610534565b929592945050506040919091013590565b60008083601f84011261059f57600080fd5b5081356001600160401b038111156105b657600080fd5b6020830191508360208285010111156105ce57600080fd5b9250929050565b600080600080606085870312156105eb57600080fd5b84356105f681610534565b93506020850135925060408501356001600160401b0381111561061857600080fd5b6106248782880161058d565b95989497509550505050565b6000806000806080858703121561064657600080fd5b843561065181610534565b9350602085013561066181610534565b9250604085013561067181610534565b9396929550929360600135925050565b60008060006060848603121561069657600080fd5b83356106a181610534565b92506020840135915060408401356106b881610534565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a086880312156106f157600080fd5b85356106fc81610534565b9450602086013561070c81610534565b9350604086013561071c81610534565b92506060860135915060808601356001600160401b038082111561073f57600080fd5b818801915088601f83011261075357600080fd5b813581811115610765576107656106c3565b604051601f8201601f19908116603f0116810190838211818310171561078d5761078d6106c3565b816040528281528b60208487010111156107a657600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b60008060008060008060a087890312156107e457600080fd5b86356107ef81610534565b955060208701356107ff81610534565b94506040870135935060608701356001600160401b0381111561082157600080fd5b61082d89828a0161058d565b90945092505060808701356007811061084557600080fd5b809150509295509295509295565b6000806040838503121561086657600080fd5b823561087181610534565b946020939093013593505050565b60006020828403121561089157600080fd5b815161052d81610534565b602080825260149082015273151c985b9cd9995c9cc8191a5cd85b1b1bddd95960621b60408201526060019056fea164736f6c634300080a000a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100785760003560e01c806301ffc9a71461007d578063129dae8b146100a45780633d820a4d146100b95780637f1eaf85146100cc57806385e335b6146100df5780638af6791b146100f25780639d22e78e14610105578063ce2003a514610118575b600080fd5b61009061008b366004610503565b61012b565b604051901515815260200160405180910390f35b6100b76100b236600461054c565b505050565b005b6100906100c73660046105d5565b610171565b6100b76100da366004610630565b6101f2565b6100906100ed366004610681565b610293565b6100b76101003660046106d9565b610313565b6100906101133660046107cb565b6103ac565b610090610126366004610853565b61042f565b60006001600160e01b03198216637af46b4f60e11b148061015c57506001600160e01b0319821663129dae8b60e01b145b8061016b575061016b826104ae565b92915050565b6000846001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101df919061087f565b6001600160a01b03161495945050505050565b336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610230573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610254919061087f565b6001600160a01b0316826001600160a01b03161461028d5760405162461bcd60e51b81526004016102849061089c565b60405180910390fd5b50505050565b6000836001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610301919061087f565b6001600160a01b031614949350505050565b336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610351573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610375919061087f565b6001600160a01b0316836001600160a01b0316146103a55760405162461bcd60e51b81526004016102849061089c565b5050505050565b6000856001600160a01b0316876001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041a919061087f565b6001600160a01b031614979650505050505050565b6000826001600160a01b0316336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049d919061087f565b6001600160a01b0316149392505050565b60006001600160e01b03198216634e9173c760e11b148061016b575061016b8260006001600160e01b03198216633b209e2f60e11b148061016b57506301ffc9a760e01b6001600160e01b031983161461016b565b60006020828403121561051557600080fd5b81356001600160e01b03198116811461052d57600080fd5b9392505050565b6001600160a01b038116811461054957600080fd5b50565b60008060006060848603121561056157600080fd5b833561056c81610534565b9250602084013561057c81610534565b929592945050506040919091013590565b60008083601f84011261059f57600080fd5b5081356001600160401b038111156105b657600080fd5b6020830191508360208285010111156105ce57600080fd5b9250929050565b600080600080606085870312156105eb57600080fd5b84356105f681610534565b93506020850135925060408501356001600160401b0381111561061857600080fd5b6106248782880161058d565b95989497509550505050565b6000806000806080858703121561064657600080fd5b843561065181610534565b9350602085013561066181610534565b9250604085013561067181610534565b9396929550929360600135925050565b60008060006060848603121561069657600080fd5b83356106a181610534565b92506020840135915060408401356106b881610534565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a086880312156106f157600080fd5b85356106fc81610534565b9450602086013561070c81610534565b9350604086013561071c81610534565b92506060860135915060808601356001600160401b038082111561073f57600080fd5b818801915088601f83011261075357600080fd5b813581811115610765576107656106c3565b604051601f8201601f19908116603f0116810190838211818310171561078d5761078d6106c3565b816040528281528b60208487010111156107a657600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b60008060008060008060a087890312156107e457600080fd5b86356107ef81610534565b955060208701356107ff81610534565b94506040870135935060608701356001600160401b0381111561082157600080fd5b61082d89828a0161058d565b90945092505060808701356007811061084557600080fd5b809150509295509295509295565b6000806040838503121561086657600080fd5b823561087181610534565b946020939093013593505050565b60006020828403121561089157600080fd5b815161052d81610534565b602080825260149082015273151c985b9cd9995c9cc8191a5cd85b1b1bddd95960621b60408201526060019056fea164736f6c634300080a000a
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.