Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Default Roya... | 6851130 | 11 days ago | IN | 0 APE | 0.00071805 | ||||
Toggle Mint | 6850976 | 11 days ago | IN | 0 APE | 0.00060219 | ||||
Toggle Mint | 6850957 | 11 days ago | IN | 0 APE | 0.0011589 | ||||
Toggle Mint | 6850440 | 11 days ago | IN | 0 APE | 0.00060219 | ||||
Toggle Mint | 6850407 | 11 days ago | IN | 0 APE | 0.0011589 | ||||
Set Transfer Val... | 6850404 | 11 days ago | IN | 0 APE | 0.00199252 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FattyPenguins
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at apescan.io on 2024-12-18 */ // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @limitbreak/creator-token-standards/src/access/OwnablePermissions.sol pragma solidity ^0.8.4; abstract contract OwnablePermissions is Context { function _requireCallerIsContractOwner() internal view virtual; } // File: @limitbreak/creator-token-standards/src/utils/AutomaticValidatorTransferApproval.sol pragma solidity ^0.8.4; /** * @title AutomaticValidatorTransferApproval * @author Limit Break, Inc. * @notice Base contract mix-in that provides boilerplate code giving the contract owner the * option to automatically approve a 721-C transfer validator implementation for transfers. */ abstract contract AutomaticValidatorTransferApproval is OwnablePermissions { /// @dev Emitted when the automatic approval flag is modified by the creator. event AutomaticApprovalOfTransferValidatorSet(bool autoApproved); /// @dev If true, the collection's transfer validator is automatically approved to transfer holder's tokens. bool public autoApproveTransfersFromValidator; /** * @notice Sets if the transfer validator is automatically approved as an operator for all token owners. * * @dev Throws when the caller is not the contract owner. * * @param autoApprove If true, the collection's transfer validator will be automatically approved to * transfer holder's tokens. */ function setAutomaticApprovalOfTransfersFromValidator(bool autoApprove) external { _requireCallerIsContractOwner(); autoApproveTransfersFromValidator = autoApprove; emit AutomaticApprovalOfTransferValidatorSet(autoApprove); } } // File: @limitbreak/creator-token-standards/src/interfaces/ICreatorToken.sol pragma solidity ^0.8.4; interface ICreatorToken { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction); } // File: @limitbreak/creator-token-standards/src/interfaces/ICreatorTokenLegacy.sol pragma solidity ^0.8.4; interface ICreatorTokenLegacy { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; } // File: @limitbreak/creator-token-standards/src/interfaces/ITransferValidator.sol pragma solidity ^0.8.4; interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external; function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external; function afterAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransfer(address operator, address token) external; function afterAuthorizedTransfer(address token) external; function beforeAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external; function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; } // File: @limitbreak/creator-token-standards/src/utils/TransferValidation.sol pragma solidity ^0.8.4; /** * @title TransferValidation * @author Limit Break, Inc. * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks. * Openzeppelin's ERC721 contract only provides hooks for before and after transfer. This allows * developers to validate or customize transfers within the context of a mint, a burn, or a transfer. */ abstract contract TransferValidation is Context { /// @dev Thrown when the from and to address are both the zero address. error ShouldNotMintToBurnAddress(); /*************************************************************************/ /* Transfers Without Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /*************************************************************************/ /* Transfers With Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} } // File: @limitbreak/creator-token-standards/src/interfaces/ITransferValidatorSetTokenType.sol pragma solidity ^0.8.4; interface ITransferValidatorSetTokenType { function setTokenTypeOfCollection(address collection, uint16 tokenType) external; } // File: @limitbreak/creator-token-standards/src/utils/CreatorTokenBase.sol pragma solidity ^0.8.4; /** * @title CreatorTokenBase * @author Limit Break, Inc. * @notice CreatorTokenBaseV3 is an abstract contract that provides basic functionality for managing token * transfer policies through an implementation of ICreatorTokenTransferValidator/ICreatorTokenTransferValidatorV2/ICreatorTokenTransferValidatorV3. * This contract is intended to be used as a base for creator-specific token contracts, enabling customizable transfer * restrictions and security policies. * * <h4>Features:</h4> * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul> * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul> * * <h4>Benefits:</h4> * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul> * <ul>Allows creators to enforce policies such as account and codehash blacklists, whitelists, and graylists.</ul> * <ul>Can be easily integrated into other token contracts as a base contract.</ul> * * <h4>Intended Usage:</h4> * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and * security policies.</ul> * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the * creator token.</ul> * * <h4>Compatibility:</h4> * <ul>Backward and Forward Compatible - V1/V2/V3 Creator Token Base will work with V1/V2/V3 Transfer Validators.</ul> */ abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken { /// @dev Thrown when setting a transfer validator address that has no deployed code. error CreatorTokenBase__InvalidTransferValidatorContract(); /// @dev The default transfer validator that will be used if no transfer validator has been set by the creator. address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x721C002B0059009a671D00aD1700c9748146cd1B); /// @dev Used to determine if the default transfer validator is applied. /// @dev Set to true when the creator sets a transfer validator address. bool private isValidatorInitialized; /// @dev Address of the transfer validator to apply to transactions. address private transferValidator; constructor() { _emitDefaultTransferValidator(); _registerTokenType(DEFAULT_TRANSFER_VALIDATOR); } /** * @notice Sets the transfer validator for the token contract. * * @dev Throws when provided validator contract is not the zero address and does not have code. * @dev Throws when the caller is not the contract owner. * * @dev <h4>Postconditions:</h4> * 1. The transferValidator address is updated. * 2. The `TransferValidatorUpdated` event is emitted. * * @param transferValidator_ The address of the transfer validator contract. */ function setTransferValidator(address transferValidator_) public { _requireCallerIsContractOwner(); bool isValidTransferValidator = transferValidator_.code.length > 0; if(transferValidator_ != address(0) && !isValidTransferValidator) { revert CreatorTokenBase__InvalidTransferValidatorContract(); } emit TransferValidatorUpdated(address(getTransferValidator()), transferValidator_); isValidatorInitialized = true; transferValidator = transferValidator_; _registerTokenType(transferValidator_); } /** * @notice Returns the transfer validator contract address for this token contract. */ function getTransferValidator() public view override returns (address validator) { validator = transferValidator; if (validator == address(0)) { if (!isValidatorInitialized) { validator = DEFAULT_TRANSFER_VALIDATOR; } } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId); } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Used for ERC20 and ERC1155 token transfers which have an amount value to validate in the transfer validator. * @dev The `tokenId` for ERC20 tokens should be set to `0`. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. * @param amount The amount of token being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId, amount); } } function _tokenType() internal virtual pure returns(uint16); function _registerTokenType(address validator) internal { if (validator != address(0)) { uint256 validatorCodeSize; assembly { validatorCodeSize := extcodesize(validator) } if(validatorCodeSize > 0) { try ITransferValidatorSetTokenType(validator).setTokenTypeOfCollection(address(this), _tokenType()) { } catch { } } } } /** * @dev Used during contract deployment for constructable and cloneable creator tokens * @dev to emit the `TransferValidatorUpdated` event signaling the validator for the contract * @dev is the default transfer validator. */ function _emitDefaultTransferValidator() internal { emit TransferValidatorUpdated(address(0), DEFAULT_TRANSFER_VALIDATOR); } } // File: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.3.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); /** * `_sequentialUpTo()` must be greater than `_startTokenId()`. */ error SequentialUpToTooSmall(); /** * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`. */ error SequentialMintExceedsLimit(); /** * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`. */ error SpotMintTokenIdTooSmall(); /** * Cannot mint over a token that already exists. */ error TokenAlreadyExists(); /** * The feature is not compatible with spot mints. */ error NotCompatibleWithSpotMints(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // 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 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.3.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * The `_sequentialUpTo()` function can be overriden to enable spot mints * (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // The amount of tokens minted above `_sequentialUpTo()`. // We call these spot mints (i.e. non-sequential mints). uint256 private _spotMinted; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID for sequential mints. * * Override this function to change the starting token ID for sequential mints. * * Note: The value returned must never change after any tokens have been minted. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the maximum token ID (inclusive) for sequential mints. * * Override this function to return a value less than 2**256 - 1, * but greater than `_startTokenId()`, to enable spot (non-sequential) mints. * * Note: The value returned must never change after any tokens have been minted. */ function _sequentialUpTo() internal view virtual returns (uint256) { return type(uint256).max; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256 result) { // Counter underflow is impossible as `_burnCounter` cannot be incremented // more than `_currentIndex + _spotMinted - _startTokenId()` times. unchecked { // With spot minting, the intermediate `result` can be temporarily negative, // and the computation must be unchecked. result = _currentIndex - _burnCounter - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256 result) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { result = _currentIndex - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } /** * @dev Returns the total number of tokens that are spot-minted. */ function _totalSpotMinted() internal view virtual returns (uint256) { return _spotMinted; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // 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 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. * An uninitialized slot does not necessarily mean that the slot has no owner. */ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * @dev Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = _packedOwnerships[tokenId]; if (tokenId > _sequentialUpTo()) { if (_packedOwnershipExists(packed)) return packed; _revert(OwnerQueryForNonexistentToken.selector); } // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = _packedOwnerships[--tokenId]; } if (packed == 0) continue; if (packed & _BITMASK_BURNED == 0) return packed; // Otherwise, the token is burned, and we must revert. // This handles the case of batch burned tokens, where only the burned bit // of the starting slot is set, and remaining slots are left uninitialized. _revert(OwnerQueryForNonexistentToken.selector); } } // Otherwise, the data exists and we can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. // If the token is not burned, return `packed`. Otherwise, revert. if (packed & _BITMASK_BURNED == 0) return packed; } _revert(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool result) { if (_startTokenId() <= tokenId) { if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]); if (tokenId < _currentIndex) { uint256 packed; while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId; result = packed & _BITMASK_BURNED == 0; } } } /** * @dev Returns whether `packed` represents a token that exists. */ function _packedOwnershipExists(uint256 packed) private pure returns (bool result) { assembly { // The following is equivalent to `owner != address(0) && burned == false`. // Symbolically tested. result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED)) } } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS)); if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. from, // `from`. toMasked, // `to`. tokenId // `tokenId`. ) } if (toMasked == 0) _revert(TransferToZeroAddress.selector); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { _revert(TransferToNonERC721ReceiverImplementer.selector); } assembly { revert(add(32, reason), mload(reason)) } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) _revert(MintZeroQuantity.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); uint256 end = startTokenId + quantity; uint256 tokenId = startTokenId; if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); do { assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } // The `!=` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. } while (++tokenId != end); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) _revert(MintToZeroAddress.selector); if (quantity == 0) _revert(MintZeroQuantity.selector); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } while (index < end); // This prevents reentrancy to `_safeMint`. // It does not prevent reentrancy to `_safeMintSpot`. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } /** * @dev Mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * Emits a {Transfer} event for each mint. */ function _mintSpot(address to, uint256 tokenId) internal virtual { if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector); uint256 prevOwnershipPacked = _packedOwnerships[tokenId]; if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector); _beforeTokenTransfers(address(0), to, tokenId, 1); // Overflows are incredibly unrealistic. // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1. // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `true` (as `quantity == 1`). _packedOwnerships[tokenId] = _packOwnershipData( to, _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked) ); // Updates: // - `balance += 1`. // - `numberMinted += 1`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1; // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } ++_spotMinted; } _afterTokenTransfers(address(0), to, tokenId, 1); } /** * @dev Safely mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * See {_mintSpot}. * * Emits a {Transfer} event. */ function _safeMintSpot( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mintSpot(to, tokenId); unchecked { if (to.code.length != 0) { uint256 currentSpotMinted = _spotMinted; if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } // This prevents reentrancy to `_safeMintSpot`. // It does not prevent reentrancy to `_safeMint`. if (_spotMinted != currentSpotMinted) revert(); } } } /** * @dev Equivalent to `_safeMintSpot(to, tokenId, '')`. */ function _safeMintSpot(address to, uint256 tokenId) internal virtual { _safeMintSpot(to, tokenId, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck && _msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { _revert(ApprovalCallerNotOwnerNorApproved.selector); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as `_burnCounter` cannot be exceed `_currentIndex + _spotMinted` times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } } // File: @limitbreak/permit-c/src/Constants.sol pragma solidity ^0.8.4; /// @dev Constant bytes32 value of 0x000...000 bytes32 constant ZERO_BYTES32 = bytes32(0); /// @dev Constant value of 0 uint256 constant ZERO = 0; /// @dev Constant value of 1 uint256 constant ONE = 1; /// @dev Constant value representing an open order in storage uint8 constant ORDER_STATE_OPEN = 0; /// @dev Constant value representing a filled order in storage uint8 constant ORDER_STATE_FILLED = 1; /// @dev Constant value representing a cancelled order in storage uint8 constant ORDER_STATE_CANCELLED = 2; /// @dev Constant value representing the ERC721 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC721 = 721; /// @dev Constant value representing the ERC1155 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC1155 = 1155; /// @dev Constant value representing the ERC20 token type for signatures and transfer hooks uint256 constant TOKEN_TYPE_ERC20 = 20; /// @dev Constant value to mask the upper bits of a signature that uses a packed `vs` value to extract `s` bytes32 constant UPPER_BIT_MASK = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /// @dev EIP-712 typehash used for validating signature based stored approvals bytes32 constant UPDATE_APPROVAL_TYPEHASH = keccak256("UpdateApprovalBySignature(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 approvalExpiration,uint256 sigDeadline,uint256 masterNonce)"); /// @dev EIP-712 typehash used for validating a single use permit without additional data bytes32 constant SINGLE_USE_PERMIT_TYPEHASH = keccak256("PermitTransferFrom(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce)"); /// @dev EIP-712 typehash used for validating a single use permit with additional data string constant SINGLE_USE_PERMIT_TRANSFER_ADVANCED_TYPEHASH_STUB = "PermitTransferFromWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce,"; /// @dev EIP-712 typehash used for validating an order permit that updates storage as it fills string constant PERMIT_ORDER_ADVANCED_TYPEHASH_STUB = "PermitOrderWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 salt,address operator,uint256 expiration,uint256 masterNonce,"; /// @dev Pausable flag for stored approval transfers of ERC721 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC721 = 1 << 0; /// @dev Pausable flag for stored approval transfers of ERC1155 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC1155 = 1 << 1; /// @dev Pausable flag for stored approval transfers of ERC20 assets uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC20 = 1 << 2; /// @dev Pausable flag for single use permit transfers of ERC721 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC721 = 1 << 3; /// @dev Pausable flag for single use permit transfers of ERC1155 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC1155 = 1 << 4; /// @dev Pausable flag for single use permit transfers of ERC20 assets uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC20 = 1 << 5; /// @dev Pausable flag for order fill transfers of ERC1155 assets uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC1155 = 1 << 6; /// @dev Pausable flag for order fill transfers of ERC20 assets uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC20 = 1 << 7; // File: @limitbreak/creator-token-standards/src/erc721c/ERC721AC.sol pragma solidity ^0.8.4; /** * @title ERC721AC * @author Limit Break, Inc. * @notice Extends Azuki's ERC721-A implementation with Creator Token functionality, which * allows the contract owner to update the transfer validation logic by managing a security policy in * an external transfer validation security policy registry. See {CreatorTokenTransferValidator}. */ abstract contract ERC721AC is ERC721A, CreatorTokenBase, AutomaticValidatorTransferApproval { constructor(string memory name_, string memory symbol_) CreatorTokenBase() ERC721A(name_, symbol_) {} /** * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved * for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { isApproved = super.isApprovedForAll(owner, operator); if (!isApproved) { if (autoApproveTransfersFromValidator) { isApproved = operator == address(getTransferValidator()); } } } /** * @notice Indicates whether the contract implements the specified interface. * @dev Overrides supportsInterface in ERC165. * @param interfaceId The interface id * @return true if the contract implements the specified interface, false otherwise */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || interfaceId == type(ICreatorTokenLegacy).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Returns the function selector for the transfer validator's validation function to be called * @notice for transaction simulation. */ function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)")); isViewFunction = true; } /// @dev Ties the erc721a _beforeTokenTransfers hook to more granular transfer validation logic function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual override { for (uint256 i = 0; i < quantity;) { _validateBeforeTransfer(from, to, startTokenId + i); unchecked { ++i; } } } /// @dev Ties the erc721a _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual override { for (uint256 i = 0; i < quantity;) { _validateAfterTransfer(from, to, startTokenId + i); unchecked { ++i; } } } function _msgSenderERC721A() internal view virtual override returns (address) { return _msgSender(); } function _tokenType() internal pure override returns(uint16) { return uint16(TOKEN_TYPE_ERC721); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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); } // File: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. * * NOTE: ERC-2981 allows setting the royalty to 100% of the price. In that case all the price would be sent to the * royalty receiver and 0 tokens to the seller. Contracts dealing with royalty should consider empty transfers. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the ERC. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) public view virtual returns (address receiver, uint256 amount) { RoyaltyInfo storage _royaltyInfo = _tokenRoyaltyInfo[tokenId]; address royaltyReceiver = _royaltyInfo.receiver; uint96 royaltyFraction = _royaltyInfo.royaltyFraction; if (royaltyReceiver == address(0)) { royaltyReceiver = _defaultRoyaltyInfo.receiver; royaltyFraction = _defaultRoyaltyInfo.royaltyFraction; } uint256 royaltyAmount = (salePrice * royaltyFraction) / _feeDenominator(); return (royaltyReceiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File: @limitbreak/creator-token-standards/src/programmable-royalties/BasicRoyalties.sol pragma solidity ^0.8.4; /** * @title BasicRoyaltiesBase * @author Limit Break, Inc. * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties. */ abstract contract BasicRoyaltiesBase is ERC2981 { event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator); event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator); function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { super._setDefaultRoyalty(receiver, feeNumerator); emit DefaultRoyaltySet(receiver, feeNumerator); } function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override { super._setTokenRoyalty(tokenId, receiver, feeNumerator); emit TokenRoyaltySet(tokenId, receiver, feeNumerator); } } /** * @title BasicRoyalties * @author Limit Break, Inc. * @notice Constructable BasicRoyalties Contract implementation. */ abstract contract BasicRoyalties is BasicRoyaltiesBase { constructor(address receiver, uint96 feeNumerator) { _setDefaultRoyalty(receiver, feeNumerator); } } /** * @title BasicRoyaltiesInitializable * @author Limit Break, Inc. * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. */ abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {} // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @limitbreak/creator-token-standards/src/access/OwnableBasic.sol pragma solidity ^0.8.4; abstract contract OwnableBasic is OwnablePermissions, Ownable { function _requireCallerIsContractOwner() internal view virtual override { _checkOwner(); } } // File: @openzeppelin/contracts/utils/Panic.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // File: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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 SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // 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-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: contracts/FattyPenguins.sol pragma solidity ^0.8.26; error NotOwnerOfToken(); error MintNotLive(); error NotEnoughAPE(); error NoneLeft(); error TokenDoesNotExist(); error WithdrawalFailed(); contract FattyPenguins is OwnableBasic, ERC721AC, BasicRoyalties { using Strings for uint256; string private _baseTokenURI; bool public mintEnabled = false; uint256 public maxSupply = 4444; uint256 public price = 1 ether; constructor() ERC721AC("Fatty Penguins", "FATTY") BasicRoyalties(msg.sender, 500) Ownable(msg.sender) { } function mint(uint256 amount) external payable { if (!mintEnabled) { revert MintNotLive(); } if (msg.value < amount * price) { revert NotEnoughAPE(); } if (totalSupply() + amount > maxSupply) { revert NoneLeft(); } _mint(msg.sender, amount); } function setPrice(uint256 price_) external onlyOwner { price = price_; } function reserve(uint256 amount, address to) external onlyOwner { if (totalSupply() + amount > maxSupply) { revert NoneLeft(); } _mint(to, amount); } function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner { _setDefaultRoyalty(receiver, feeNumerator); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721AC, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) public onlyOwner { _setTokenRoyalty(tokenId, receiver, feeNumerator); } function setBaseURI(string calldata baseURI) external onlyOwner { _baseTokenURI = baseURI; } function _baseURI() internal view override returns (string memory) { return _baseTokenURI; } function tokenURI(uint256 tokenId) public view override returns (string memory) { if (!_exists(tokenId)) revert TokenDoesNotExist(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : ""; } function toggleMint() external onlyOwner { mintEnabled = !mintEnabled; } function withdraw() public onlyOwner { uint256 balance = address(this).balance; if (balance <= 0) { revert NotEnoughAPE(); } _withdraw(_msgSender(), address(this).balance); } function _withdraw(address _address, uint256 _amount) private { (bool success, ) = _address.call{value: _amount}(""); if (!success) { revert WithdrawalFailed(); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintNotLive","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NoneLeft","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[],"name":"NotEnoughAPE","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WithdrawalFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"autoApproved","type":"bool"}],"name":"AutomaticApprovalOfTransferValidatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"autoApproveTransfersFromValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferValidationFunction","outputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"},{"internalType":"bool","name":"isViewFunction","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"address","name":"validator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isApproved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"autoApprove","type":"bool"}],"name":"setAutomaticApprovalOfTransfersFromValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600e805460ff1916905561115c600f55670de0b6b3a764000060105534801561002b575f80fd5b50336101f46040518060400160405280600e81526020016d46617474792050656e6775696e7360901b81525060405180604001604052806005815260200164464154545960d81b815250338282816002908161008791906103b4565b50600361009482826103b4565b50505f8055506001600160a01b0381166100c857604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6100d18161010b565b506100da61015c565b6100f773721c002b0059009a671d00ad1700c9748146cd1b6101aa565b5061010490508282610226565b505061046e565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b604080515f815273721c002b0059009a671d00ad1700c9748146cd1b60208201527fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac910160405180910390a1565b6001600160a01b0381161561022357803b8015610221576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b15801561020e575f80fd5b505af192505050801561021f575060015b505b505b50565b610230828261027b565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6127106001600160601b0382168110156102ba57604051636f483d0960e01b81526001600160601b0383166004820152602481018290526044016100bf565b6001600160a01b0383166102e357604051635b6cc80560e11b81525f60048201526024016100bf565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600b55565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061034557607f821691505b60208210810361036357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561021f57805f5260205f20601f840160051c8101602085101561038e5750805b601f840160051c820191505b818110156103ad575f815560010161039a565b5050505050565b81516001600160401b038111156103cd576103cd61031d565b6103e1816103db8454610331565b84610369565b6020601f821160018114610413575f83156103fc5750848201515b5f19600385901b1c1916600184901b1784556103ad565b5f84815260208120601f198516915b828110156104425787850151825560209485019460019092019101610422565b508482101561045f57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b611e438061047b5f395ff3fe6080604052600436106101fc575f3560e01c80636352211e11610113578063a22cb4651161009d578063d12397301161006d578063d123973014610591578063d3dd5fe0146105aa578063d5abeb01146105be578063e985e9c5146105d3578063f2fde38b146105f2575f80fd5b8063a22cb46514610521578063a9fc664e14610540578063b88d4fde1461055f578063c87b56dd14610572575f80fd5b806391b7f5ed116100e357806391b7f5ed146104a757806395d89b41146104c65780639e05d240146104da578063a035b1fe146104f9578063a0712d681461050e575f80fd5b80636352211e1461043857806370a0823114610457578063715018a6146104765780638da5cb5b1461048a575f80fd5b80630d705df6116101945780633ccfd60b116101645780633ccfd60b146103b357806342842e0e146103c757806355f804b3146103da5780635944c753146103f95780636221d13c14610418575f80fd5b80630d705df61461031a57806318160ddd1461034157806323b872dd146103625780632a55205a14610375575f80fd5b806306fdde03116101cf57806306fdde03146102b3578063081812fc146102d4578063095ea7b3146102f3578063098144d414610306575f80fd5b8063014635461461020057806301ffc9a71461024457806303339bcb1461027357806304634d8d14610294575b5f80fd5b34801561020b575f80fd5b5061022773721c002b0059009a671d00ad1700c9748146cd1b81565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561024f575f80fd5b5061026361025e366004611832565b610611565b604051901515815260200161023b565b34801561027e575f80fd5b5061029261028d366004611863565b610621565b005b34801561029f575f80fd5b506102926102ae3660046118a3565b610670565b3480156102be575f80fd5b506102c7610682565b60405161023b91906118f9565b3480156102df575f80fd5b506102276102ee36600461190b565b610712565b610292610301366004611922565b61074b565b348015610311575f80fd5b50610227610757565b348015610325575f80fd5b506040805163657711f560e11b8152600160208201520161023b565b34801561034c575f80fd5b506001545f54035b60405190815260200161023b565b61029261037036600461194a565b610793565b348015610380575f80fd5b5061039461038f366004611984565b610907565b604080516001600160a01b03909316835260208301919091520161023b565b3480156103be575f80fd5b5061029261098a565b6102926103d536600461194a565b6109be565b3480156103e5575f80fd5b506102926103f43660046119a4565b6109dd565b348015610404575f80fd5b50610292610413366004611a12565b6109f2565b348015610423575f80fd5b50600a5461026390600160a01b900460ff1681565b348015610443575f80fd5b5061022761045236600461190b565b610a05565b348015610462575f80fd5b50610354610471366004611a4b565b610a0f565b348015610481575f80fd5b50610292610a53565b348015610495575f80fd5b506009546001600160a01b0316610227565b3480156104b2575f80fd5b506102926104c136600461190b565b610a66565b3480156104d1575f80fd5b506102c7610a73565b3480156104e5575f80fd5b506102926104f4366004611a73565b610a82565b348015610504575f80fd5b5061035460105481565b61029261051c36600461190b565b610ae2565b34801561052c575f80fd5b5061029261053b366004611a8c565b610b75565b34801561054b575f80fd5b5061029261055a366004611a4b565b610bed565b61029261056d366004611ac8565b610cb2565b34801561057d575f80fd5b506102c761058c36600461190b565b610cf3565b34801561059c575f80fd5b50600e546102639060ff1681565b3480156105b5575f80fd5b50610292610d74565b3480156105c9575f80fd5b50610354600f5481565b3480156105de575f80fd5b506102636105ed366004611ba5565b610d90565b3480156105fd575f80fd5b5061029261060c366004611a4b565b610df3565b5f61061b82610e32565b92915050565b610629610e66565b600f54826106396001545f540390565b6106439190611be1565b1115610662576040516367309b4560e11b815260040160405180910390fd5b61066c8183610e93565b5050565b610678610e66565b61066c8282610f62565b60606002805461069190611bf4565b80601f01602080910402602001604051908101604052809291908181526020018280546106bd90611bf4565b80156107085780601f106106df57610100808354040283529160200191610708565b820191905f5260205f20905b8154815290600101906020018083116106eb57829003601f168201915b5050505050905090565b5f61071c82610fb7565b610730576107306333d1c03960e21b610ff9565b505f908152600660205260409020546001600160a01b031690565b61066c82826001611001565b600a546001600160a01b03168061079057600954600160a01b900460ff16610790575073721c002b0059009a671d00ad1700c9748146cd1b5b90565b5f61079d826110a2565b6001600160a01b0394851694909150811684146107c3576107c362a1148160e81b610ff9565b5f8281526006602052604090208054338082146001600160a01b03881690911417610806576107f28633610d90565b61080657610806632ce44b5f60e11b610ff9565b6108138686866001611131565b801561081d575f82555b6001600160a01b038681165f9081526005602052604080822080545f19019055918716808252919020805460010190554260a01b17600160e11b175f85815260046020526040812091909155600160e11b841690036108a957600184015f8181526004602052604081205490036108a7575f5481146108a7575f8181526004602052604090208490555b505b6001600160a01b0385168481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4805f036108f1576108f1633a954ecd60e21b610ff9565b6108fe878787600161115e565b50505050505050565b5f828152600c6020526040812080548291906001600160a01b03811690600160a01b90046001600160601b03168161095a575050600b546001600160a01b03811690600160a01b90046001600160601b03165b5f6127106109716001600160601b03841689611c2c565b61097b9190611c43565b92989297509195505050505050565b610992610e66565b47806109b1576040516371b981e760e01b815260040160405180910390fd5b6109bb3347611184565b50565b6109d883838360405180602001604052805f815250610cb2565b505050565b6109e5610e66565b600d6109d8828483611ca6565b6109fa610e66565b6109d88383836111f4565b5f61061b826110a2565b5f6001600160a01b038216610a2e57610a2e6323d3ad8160e21b610ff9565b506001600160a01b03165f9081526005602052604090205467ffffffffffffffff1690565b610a5b610e66565b610a645f61124d565b565b610a6e610e66565b601055565b60606003805461069190611bf4565b610a8a61129e565b600a8054821515600160a01b0260ff60a01b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc90610ad790831515815260200190565b60405180910390a150565b600e5460ff16610b0557604051630aea1c5d60e01b815260040160405180910390fd5b601054610b129082611c2c565b341015610b32576040516371b981e760e01b815260040160405180910390fd5b600f5481610b426001545f540390565b610b4c9190611be1565b1115610b6b576040516367309b4560e11b815260040160405180910390fd5b6109bb3382610e93565b335f8181526007602090815260408083206001600160a01b0387168085529252909120805460ff1916841515179055906001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610be1911515815260200190565b60405180910390a35050565b610bf561129e565b6001600160a01b038116803b15159015801590610c10575080155b15610c2e576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac610c57610757565b604080516001600160a01b03928316815291851660208301520160405180910390a16009805460ff60a01b1916600160a01b179055600a80546001600160a01b0384166001600160a01b031990911617905561066c826112a6565b610cbd848484610793565b6001600160a01b0383163b15610ced57610cd984848484611324565b610ced57610ced6368d2bf6b60e11b610ff9565b50505050565b6060610cfe82610fb7565b610d1b5760405163677510db60e11b815260040160405180910390fd5b5f610d24611402565b905080515f03610d425760405180602001604052805f815250610d6d565b80610d4c84611411565b604051602001610d5d929190611d77565b6040516020818303038152906040525b9392505050565b610d7c610e66565b600e805460ff19811660ff90911615179055565b6001600160a01b038281165f9081526007602090815260408083209385168352929052205460ff168061061b57600a54600160a01b900460ff161561061b57610dd7610757565b6001600160a01b0316826001600160a01b031614905092915050565b610dfb610e66565b6001600160a01b038116610e2957604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6109bb8161124d565b5f6001600160e01b0319821663152a902d60e11b148061061b57506301ffc9a760e01b6001600160e01b031983161461061b565b6009546001600160a01b03163314610a645760405163118cdaa760e01b8152336004820152602401610e20565b5f805490829003610eae57610eae63b562e8dd60e01b610ff9565b610eba5f848385611131565b5f8181526004602090815260408083206001600160a01b0387164260a01b6001881460e11b17811790915580845260059092528220805468010000000000000001860201905590819003610f1757610f17622e076360e81b610ff9565b818301825b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103610f1c57505f9081556109d8915084838561115e565b610f6c82826114a1565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b5f8054821015610ff4575f5b505f8281526004602052604081205490819003610fea57610fe383611da1565b9250610fc3565b600160e01b161590505b919050565b805f5260045ffd5b5f61100b83610a05565b90508180156110235750336001600160a01b03821614155b15611046576110328133610d90565b611046576110466367d9dca160e11b610ff9565b5f8381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b5f81815260046020526040902054805f0361110f575f5482106110cf576110cf636f96cda160e11b610ff9565b5b505f19015f8181526004602052604090205480156110d057600160e01b81165f036110fa57919050565b61110a636f96cda160e11b610ff9565b6110d0565b600160e01b81165f0361112157919050565b610ff4636f96cda160e11b610ff9565b5f5b818110156111575761114f858561114a8487611be1565b611543565b600101611133565b5050505050565b5f5b818110156111575761117c85856111778487611be1565b611599565b600101611160565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f81146111cd576040519150601f19603f3d011682016040523d82523d5f602084013e6111d2565b606091505b50509050806109d8576040516327fcd9d160e01b815260040160405180910390fd5b6111ff8383836115e1565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c9060200160405180910390a3505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b610a64610e66565b6001600160a01b038116156109bb57803b801561066c576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b15801561130a575f80fd5b505af192505050801561131b575060015b1561066c575050565b604051630a85bd0160e11b81525f906001600160a01b0385169063150b7a0290611358903390899088908890600401611db6565b6020604051808303815f875af1925050508015611392575060408051601f3d908101601f1916820190925261138f91810190611df2565b60015b6113e5573d8080156113bf576040519150601f19603f3d011682016040523d82523d5f602084013e6113c4565b606091505b5080515f036113dd576113dd6368d2bf6b60e11b610ff9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600d805461069190611bf4565b60605f61141d836116a1565b60010190505f8167ffffffffffffffff81111561143c5761143c611ab4565b6040519080825280601f01601f191660200182016040528015611466576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461147057509392505050565b6127106001600160601b0382168110156114e057604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610e20565b6001600160a01b03831661150957604051635b6cc80560e11b81525f6004820152602401610e20565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600b55565b6001600160a01b03838116159083161581801561155d5750805b1561157b57604051635cbd944160e01b815260040160405180910390fd5b8115611587575b611157565b80611582576111573386868634611778565b6001600160a01b0383811615908316158180156115b35750805b156115d157604051635cbd944160e01b815260040160405180910390fd5b8161158257801561158257611582565b6127106001600160601b0382168110156116275760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610e20565b6001600160a01b03831661165757604051634b4f842960e11b8152600481018590525f6024820152604401610e20565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182525f968752600c90529190942093519051909116600160a01b029116179055565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106116df5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061170b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061172957662386f26fc10000830492506010015b6305f5e1008310611741576305f5e100830492506008015b612710831061175557612710830492506004015b60648310611767576064830492506002015b600a831061061b5760010192915050565b5f611781610757565b90506001600160a01b03811615611815576001600160a01b03811633036117a85750611157565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea906084015f6040518083038186803b1580156117fe575f80fd5b505afa158015611810573d5f803e3d5ffd5b505050505b505050505050565b6001600160e01b0319811681146109bb575f80fd5b5f60208284031215611842575f80fd5b8135610d6d8161181d565b80356001600160a01b0381168114610ff4575f80fd5b5f8060408385031215611874575f80fd5b823591506118846020840161184d565b90509250929050565b80356001600160601b0381168114610ff4575f80fd5b5f80604083850312156118b4575f80fd5b6118bd8361184d565b91506118846020840161188d565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610d6d60208301846118cb565b5f6020828403121561191b575f80fd5b5035919050565b5f8060408385031215611933575f80fd5b61193c8361184d565b946020939093013593505050565b5f805f6060848603121561195c575f80fd5b6119658461184d565b92506119736020850161184d565b929592945050506040919091013590565b5f8060408385031215611995575f80fd5b50508035926020909101359150565b5f80602083850312156119b5575f80fd5b823567ffffffffffffffff8111156119cb575f80fd5b8301601f810185136119db575f80fd5b803567ffffffffffffffff8111156119f1575f80fd5b856020828401011115611a02575f80fd5b6020919091019590945092505050565b5f805f60608486031215611a24575f80fd5b83359250611a346020850161184d565b9150611a426040850161188d565b90509250925092565b5f60208284031215611a5b575f80fd5b610d6d8261184d565b80358015158114610ff4575f80fd5b5f60208284031215611a83575f80fd5b610d6d82611a64565b5f8060408385031215611a9d575f80fd5b611aa68361184d565b915061188460208401611a64565b634e487b7160e01b5f52604160045260245ffd5b5f805f8060808587031215611adb575f80fd5b611ae48561184d565b9350611af26020860161184d565b925060408501359150606085013567ffffffffffffffff811115611b14575f80fd5b8501601f81018713611b24575f80fd5b803567ffffffffffffffff811115611b3e57611b3e611ab4565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715611b6d57611b6d611ab4565b604052818152828201602001891015611b84575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f8060408385031215611bb6575f80fd5b611bbf8361184d565b91506118846020840161184d565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561061b5761061b611bcd565b600181811c90821680611c0857607f821691505b602082108103611c2657634e487b7160e01b5f52602260045260245ffd5b50919050565b808202811582820484141761061b5761061b611bcd565b5f82611c5d57634e487b7160e01b5f52601260045260245ffd5b500490565b601f8211156109d857805f5260205f20601f840160051c81016020851015611c875750805b601f840160051c820191505b81811015611157575f8155600101611c93565b67ffffffffffffffff831115611cbe57611cbe611ab4565b611cd283611ccc8354611bf4565b83611c62565b5f601f841160018114611d03575f8515611cec5750838201355b5f19600387901b1c1916600186901b178355611157565b5f83815260208120601f198716915b82811015611d325786850135825560209485019460019092019101611d12565b5086821015611d4e575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f81518060208401855e5f93019283525090919050565b5f611d8b611d858386611d60565b84611d60565b64173539b7b760d91b8152600501949350505050565b5f81611daf57611daf611bcd565b505f190190565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611de8908301846118cb565b9695505050505050565b5f60208284031215611e02575f80fd5b8151610d6d8161181d56fea26469706673582212203b92024bfa896626bb67e615f43df74b4656691d79184405e3a05d3ff63ab4d964736f6c634300081a0033
Deployed Bytecode
0x6080604052600436106101fc575f3560e01c80636352211e11610113578063a22cb4651161009d578063d12397301161006d578063d123973014610591578063d3dd5fe0146105aa578063d5abeb01146105be578063e985e9c5146105d3578063f2fde38b146105f2575f80fd5b8063a22cb46514610521578063a9fc664e14610540578063b88d4fde1461055f578063c87b56dd14610572575f80fd5b806391b7f5ed116100e357806391b7f5ed146104a757806395d89b41146104c65780639e05d240146104da578063a035b1fe146104f9578063a0712d681461050e575f80fd5b80636352211e1461043857806370a0823114610457578063715018a6146104765780638da5cb5b1461048a575f80fd5b80630d705df6116101945780633ccfd60b116101645780633ccfd60b146103b357806342842e0e146103c757806355f804b3146103da5780635944c753146103f95780636221d13c14610418575f80fd5b80630d705df61461031a57806318160ddd1461034157806323b872dd146103625780632a55205a14610375575f80fd5b806306fdde03116101cf57806306fdde03146102b3578063081812fc146102d4578063095ea7b3146102f3578063098144d414610306575f80fd5b8063014635461461020057806301ffc9a71461024457806303339bcb1461027357806304634d8d14610294575b5f80fd5b34801561020b575f80fd5b5061022773721c002b0059009a671d00ad1700c9748146cd1b81565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561024f575f80fd5b5061026361025e366004611832565b610611565b604051901515815260200161023b565b34801561027e575f80fd5b5061029261028d366004611863565b610621565b005b34801561029f575f80fd5b506102926102ae3660046118a3565b610670565b3480156102be575f80fd5b506102c7610682565b60405161023b91906118f9565b3480156102df575f80fd5b506102276102ee36600461190b565b610712565b610292610301366004611922565b61074b565b348015610311575f80fd5b50610227610757565b348015610325575f80fd5b506040805163657711f560e11b8152600160208201520161023b565b34801561034c575f80fd5b506001545f54035b60405190815260200161023b565b61029261037036600461194a565b610793565b348015610380575f80fd5b5061039461038f366004611984565b610907565b604080516001600160a01b03909316835260208301919091520161023b565b3480156103be575f80fd5b5061029261098a565b6102926103d536600461194a565b6109be565b3480156103e5575f80fd5b506102926103f43660046119a4565b6109dd565b348015610404575f80fd5b50610292610413366004611a12565b6109f2565b348015610423575f80fd5b50600a5461026390600160a01b900460ff1681565b348015610443575f80fd5b5061022761045236600461190b565b610a05565b348015610462575f80fd5b50610354610471366004611a4b565b610a0f565b348015610481575f80fd5b50610292610a53565b348015610495575f80fd5b506009546001600160a01b0316610227565b3480156104b2575f80fd5b506102926104c136600461190b565b610a66565b3480156104d1575f80fd5b506102c7610a73565b3480156104e5575f80fd5b506102926104f4366004611a73565b610a82565b348015610504575f80fd5b5061035460105481565b61029261051c36600461190b565b610ae2565b34801561052c575f80fd5b5061029261053b366004611a8c565b610b75565b34801561054b575f80fd5b5061029261055a366004611a4b565b610bed565b61029261056d366004611ac8565b610cb2565b34801561057d575f80fd5b506102c761058c36600461190b565b610cf3565b34801561059c575f80fd5b50600e546102639060ff1681565b3480156105b5575f80fd5b50610292610d74565b3480156105c9575f80fd5b50610354600f5481565b3480156105de575f80fd5b506102636105ed366004611ba5565b610d90565b3480156105fd575f80fd5b5061029261060c366004611a4b565b610df3565b5f61061b82610e32565b92915050565b610629610e66565b600f54826106396001545f540390565b6106439190611be1565b1115610662576040516367309b4560e11b815260040160405180910390fd5b61066c8183610e93565b5050565b610678610e66565b61066c8282610f62565b60606002805461069190611bf4565b80601f01602080910402602001604051908101604052809291908181526020018280546106bd90611bf4565b80156107085780601f106106df57610100808354040283529160200191610708565b820191905f5260205f20905b8154815290600101906020018083116106eb57829003601f168201915b5050505050905090565b5f61071c82610fb7565b610730576107306333d1c03960e21b610ff9565b505f908152600660205260409020546001600160a01b031690565b61066c82826001611001565b600a546001600160a01b03168061079057600954600160a01b900460ff16610790575073721c002b0059009a671d00ad1700c9748146cd1b5b90565b5f61079d826110a2565b6001600160a01b0394851694909150811684146107c3576107c362a1148160e81b610ff9565b5f8281526006602052604090208054338082146001600160a01b03881690911417610806576107f28633610d90565b61080657610806632ce44b5f60e11b610ff9565b6108138686866001611131565b801561081d575f82555b6001600160a01b038681165f9081526005602052604080822080545f19019055918716808252919020805460010190554260a01b17600160e11b175f85815260046020526040812091909155600160e11b841690036108a957600184015f8181526004602052604081205490036108a7575f5481146108a7575f8181526004602052604090208490555b505b6001600160a01b0385168481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4805f036108f1576108f1633a954ecd60e21b610ff9565b6108fe878787600161115e565b50505050505050565b5f828152600c6020526040812080548291906001600160a01b03811690600160a01b90046001600160601b03168161095a575050600b546001600160a01b03811690600160a01b90046001600160601b03165b5f6127106109716001600160601b03841689611c2c565b61097b9190611c43565b92989297509195505050505050565b610992610e66565b47806109b1576040516371b981e760e01b815260040160405180910390fd5b6109bb3347611184565b50565b6109d883838360405180602001604052805f815250610cb2565b505050565b6109e5610e66565b600d6109d8828483611ca6565b6109fa610e66565b6109d88383836111f4565b5f61061b826110a2565b5f6001600160a01b038216610a2e57610a2e6323d3ad8160e21b610ff9565b506001600160a01b03165f9081526005602052604090205467ffffffffffffffff1690565b610a5b610e66565b610a645f61124d565b565b610a6e610e66565b601055565b60606003805461069190611bf4565b610a8a61129e565b600a8054821515600160a01b0260ff60a01b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc90610ad790831515815260200190565b60405180910390a150565b600e5460ff16610b0557604051630aea1c5d60e01b815260040160405180910390fd5b601054610b129082611c2c565b341015610b32576040516371b981e760e01b815260040160405180910390fd5b600f5481610b426001545f540390565b610b4c9190611be1565b1115610b6b576040516367309b4560e11b815260040160405180910390fd5b6109bb3382610e93565b335f8181526007602090815260408083206001600160a01b0387168085529252909120805460ff1916841515179055906001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610be1911515815260200190565b60405180910390a35050565b610bf561129e565b6001600160a01b038116803b15159015801590610c10575080155b15610c2e576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac610c57610757565b604080516001600160a01b03928316815291851660208301520160405180910390a16009805460ff60a01b1916600160a01b179055600a80546001600160a01b0384166001600160a01b031990911617905561066c826112a6565b610cbd848484610793565b6001600160a01b0383163b15610ced57610cd984848484611324565b610ced57610ced6368d2bf6b60e11b610ff9565b50505050565b6060610cfe82610fb7565b610d1b5760405163677510db60e11b815260040160405180910390fd5b5f610d24611402565b905080515f03610d425760405180602001604052805f815250610d6d565b80610d4c84611411565b604051602001610d5d929190611d77565b6040516020818303038152906040525b9392505050565b610d7c610e66565b600e805460ff19811660ff90911615179055565b6001600160a01b038281165f9081526007602090815260408083209385168352929052205460ff168061061b57600a54600160a01b900460ff161561061b57610dd7610757565b6001600160a01b0316826001600160a01b031614905092915050565b610dfb610e66565b6001600160a01b038116610e2957604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6109bb8161124d565b5f6001600160e01b0319821663152a902d60e11b148061061b57506301ffc9a760e01b6001600160e01b031983161461061b565b6009546001600160a01b03163314610a645760405163118cdaa760e01b8152336004820152602401610e20565b5f805490829003610eae57610eae63b562e8dd60e01b610ff9565b610eba5f848385611131565b5f8181526004602090815260408083206001600160a01b0387164260a01b6001881460e11b17811790915580845260059092528220805468010000000000000001860201905590819003610f1757610f17622e076360e81b610ff9565b818301825b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103610f1c57505f9081556109d8915084838561115e565b610f6c82826114a1565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b5f8054821015610ff4575f5b505f8281526004602052604081205490819003610fea57610fe383611da1565b9250610fc3565b600160e01b161590505b919050565b805f5260045ffd5b5f61100b83610a05565b90508180156110235750336001600160a01b03821614155b15611046576110328133610d90565b611046576110466367d9dca160e11b610ff9565b5f8381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b5f81815260046020526040902054805f0361110f575f5482106110cf576110cf636f96cda160e11b610ff9565b5b505f19015f8181526004602052604090205480156110d057600160e01b81165f036110fa57919050565b61110a636f96cda160e11b610ff9565b6110d0565b600160e01b81165f0361112157919050565b610ff4636f96cda160e11b610ff9565b5f5b818110156111575761114f858561114a8487611be1565b611543565b600101611133565b5050505050565b5f5b818110156111575761117c85856111778487611be1565b611599565b600101611160565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f81146111cd576040519150601f19603f3d011682016040523d82523d5f602084013e6111d2565b606091505b50509050806109d8576040516327fcd9d160e01b815260040160405180910390fd5b6111ff8383836115e1565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c9060200160405180910390a3505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b610a64610e66565b6001600160a01b038116156109bb57803b801561066c576040805163fb2de5d760e01b81523060048201526102d1602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b15801561130a575f80fd5b505af192505050801561131b575060015b1561066c575050565b604051630a85bd0160e11b81525f906001600160a01b0385169063150b7a0290611358903390899088908890600401611db6565b6020604051808303815f875af1925050508015611392575060408051601f3d908101601f1916820190925261138f91810190611df2565b60015b6113e5573d8080156113bf576040519150601f19603f3d011682016040523d82523d5f602084013e6113c4565b606091505b5080515f036113dd576113dd6368d2bf6b60e11b610ff9565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600d805461069190611bf4565b60605f61141d836116a1565b60010190505f8167ffffffffffffffff81111561143c5761143c611ab4565b6040519080825280601f01601f191660200182016040528015611466576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461147057509392505050565b6127106001600160601b0382168110156114e057604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610e20565b6001600160a01b03831661150957604051635b6cc80560e11b81525f6004820152602401610e20565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600b55565b6001600160a01b03838116159083161581801561155d5750805b1561157b57604051635cbd944160e01b815260040160405180910390fd5b8115611587575b611157565b80611582576111573386868634611778565b6001600160a01b0383811615908316158180156115b35750805b156115d157604051635cbd944160e01b815260040160405180910390fd5b8161158257801561158257611582565b6127106001600160601b0382168110156116275760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610e20565b6001600160a01b03831661165757604051634b4f842960e11b8152600481018590525f6024820152604401610e20565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182525f968752600c90529190942093519051909116600160a01b029116179055565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106116df5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061170b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061172957662386f26fc10000830492506010015b6305f5e1008310611741576305f5e100830492506008015b612710831061175557612710830492506004015b60648310611767576064830492506002015b600a831061061b5760010192915050565b5f611781610757565b90506001600160a01b03811615611815576001600160a01b03811633036117a85750611157565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea906084015f6040518083038186803b1580156117fe575f80fd5b505afa158015611810573d5f803e3d5ffd5b505050505b505050505050565b6001600160e01b0319811681146109bb575f80fd5b5f60208284031215611842575f80fd5b8135610d6d8161181d565b80356001600160a01b0381168114610ff4575f80fd5b5f8060408385031215611874575f80fd5b823591506118846020840161184d565b90509250929050565b80356001600160601b0381168114610ff4575f80fd5b5f80604083850312156118b4575f80fd5b6118bd8361184d565b91506118846020840161188d565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610d6d60208301846118cb565b5f6020828403121561191b575f80fd5b5035919050565b5f8060408385031215611933575f80fd5b61193c8361184d565b946020939093013593505050565b5f805f6060848603121561195c575f80fd5b6119658461184d565b92506119736020850161184d565b929592945050506040919091013590565b5f8060408385031215611995575f80fd5b50508035926020909101359150565b5f80602083850312156119b5575f80fd5b823567ffffffffffffffff8111156119cb575f80fd5b8301601f810185136119db575f80fd5b803567ffffffffffffffff8111156119f1575f80fd5b856020828401011115611a02575f80fd5b6020919091019590945092505050565b5f805f60608486031215611a24575f80fd5b83359250611a346020850161184d565b9150611a426040850161188d565b90509250925092565b5f60208284031215611a5b575f80fd5b610d6d8261184d565b80358015158114610ff4575f80fd5b5f60208284031215611a83575f80fd5b610d6d82611a64565b5f8060408385031215611a9d575f80fd5b611aa68361184d565b915061188460208401611a64565b634e487b7160e01b5f52604160045260245ffd5b5f805f8060808587031215611adb575f80fd5b611ae48561184d565b9350611af26020860161184d565b925060408501359150606085013567ffffffffffffffff811115611b14575f80fd5b8501601f81018713611b24575f80fd5b803567ffffffffffffffff811115611b3e57611b3e611ab4565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715611b6d57611b6d611ab4565b604052818152828201602001891015611b84575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f8060408385031215611bb6575f80fd5b611bbf8361184d565b91506118846020840161184d565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561061b5761061b611bcd565b600181811c90821680611c0857607f821691505b602082108103611c2657634e487b7160e01b5f52602260045260245ffd5b50919050565b808202811582820484141761061b5761061b611bcd565b5f82611c5d57634e487b7160e01b5f52601260045260245ffd5b500490565b601f8211156109d857805f5260205f20601f840160051c81016020851015611c875750805b601f840160051c820191505b81811015611157575f8155600101611c93565b67ffffffffffffffff831115611cbe57611cbe611ab4565b611cd283611ccc8354611bf4565b83611c62565b5f601f841160018114611d03575f8515611cec5750838201355b5f19600387901b1c1916600186901b178355611157565b5f83815260208120601f198716915b82811015611d325786850135825560209485019460019092019101611d12565b5086821015611d4e575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f81518060208401855e5f93019283525090919050565b5f611d8b611d858386611d60565b84611d60565b64173539b7b760d91b8152600501949350505050565b5f81611daf57611daf611bcd565b505f190190565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611de8908301846118cb565b9695505050505050565b5f60208284031215611e02575f80fd5b8151610d6d8161181d56fea26469706673582212203b92024bfa896626bb67e615f43df74b4656691d79184405e3a05d3ff63ab4d964736f6c634300081a0033
Deployed Bytecode Sourcemap
175179:2675:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13592:104;;;;;;;;;;;;13653:42;13592:104;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;13592:104:0;;;;;;;;176412:172;;;;;;;;;;-1:-1:-1;176412:172:0;;;;;:::i;:::-;;:::i;:::-;;;773:14:1;;766:22;748:41;;736:2;721:18;176412:172:0;608:187:1;176058:194:0;;;;;;;;;;-1:-1:-1;176058:194:0;;;;;:::i;:::-;;:::i;:::-;;176260:144;;;;;;;;;;-1:-1:-1;176260:144:0;;;;;:::i;:::-;;:::i;41282:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;48522:227::-;;;;;;;;;;-1:-1:-1;48522:227:0;;;;;:::i;:::-;;:::i;48239:124::-;;;;;;:::i;:::-;;:::i;15390:298::-;;;;;;;;;;;;;:::i;86273:252::-;;;;;;;;;;-1:-1:-1;86273:252:0;;;-1:-1:-1;;;2973:52:1;;86513:4:0;3056:2:1;3041:18;;3034:50;2946:18;86273:252:0;2807:283:1;36484:573:0;;;;;;;;;;-1:-1:-1;36928:12:0;;36545:14;36912:13;:28;36484:573;;;3241:25:1;;;3229:2;3214:18;36484:573:0;3095:177:1;52794:3523:0;;;;;;:::i;:::-;;:::i;93032:673::-;;;;;;;;;;-1:-1:-1;93032:673:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4199:32:1;;;4181:51;;4263:2;4248:18;;4241:34;;;;4154:18;93032:673:0;4007:274:1;177406:228:0;;;;;;;;;;;;;:::i;56413:193::-;;;;;;:::i;:::-;;:::i;176767:106::-;;;;;;;;;;-1:-1:-1;176767:106:0;;;;;:::i;:::-;;:::i;176592:166::-;;;;;;;;;;-1:-1:-1;176592:166:0;;;;;:::i;:::-;;:::i;2017:45::-;;;;;;;;;;-1:-1:-1;2017:45:0;;;;-1:-1:-1;;;2017:45:0;;;;;;42684:152;;;;;;;;;;-1:-1:-1;42684:152:0;;;;;:::i;:::-;;:::i;38208:242::-;;;;;;;;;;-1:-1:-1;38208:242:0;;;;;:::i;:::-;;:::i;100038:103::-;;;;;;;;;;;;;:::i;99363:87::-;;;;;;;;;;-1:-1:-1;99436:6:0;;-1:-1:-1;;;;;99436:6:0;99363:87;;175964:86;;;;;;;;;;-1:-1:-1;175964:86:0;;;;;:::i;:::-;;:::i;41458:104::-;;;;;;;;;;;;;:::i;2442:257::-;;;;;;;;;;-1:-1:-1;2442:257:0;;;;;:::i;:::-;;:::i;175408:40::-;;;;;;;;;;;;;;;;175604:352;;;;;;:::i;:::-;;:::i;49089:234::-;;;;;;;;;;-1:-1:-1;49089:234:0;;;;;:::i;:::-;;:::i;14680:595::-;;;;;;;;;;-1:-1:-1;14680:595:0;;;;;:::i;:::-;;:::i;57204:416::-;;;;;;:::i;:::-;;:::i;176995:309::-;;;;;;;;;;-1:-1:-1;176995:309:0;;;;;:::i;:::-;;:::i;175319:38::-;;;;;;;;;;-1:-1:-1;175319:38:0;;;;;;;;177312:86;;;;;;;;;;;;;:::i;175364:37::-;;;;;;;;;;;;;;;;85140:370;;;;;;;;;;-1:-1:-1;85140:370:0;;;;;:::i;:::-;;:::i;100296:220::-;;;;;;;;;;-1:-1:-1;100296:220:0;;;;;:::i;:::-;;:::i;176412:172::-;176516:4;176540:36;176564:11;176540:23;:36::i;:::-;176533:43;176412:172;-1:-1:-1;;176412:172:0:o;176058:194::-;99249:13;:11;:13::i;:::-;176162:9:::1;;176153:6;176137:13;36928:12:::0;;36545:14;36912:13;:28;15390:298;;176137:13:::1;:22;;;;:::i;:::-;:34;176133:84;;;176195:10;;-1:-1:-1::0;;;176195:10:0::1;;;;;;;;;;;176133:84;176227:17;176233:2;176237:6;176227:5;:17::i;:::-;176058:194:::0;;:::o;176260:144::-;99249:13;:11;:13::i;:::-;176354:42:::1;176373:8;176383:12;176354:18;:42::i;41282:100::-:0;41336:13;41369:5;41362:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41282:100;:::o;48522:227::-;48598:7;48623:16;48631:7;48623;:16::i;:::-;48618:73;;48641:50;-1:-1:-1;;;48641:7:0;:50::i;:::-;-1:-1:-1;48711:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;48711:30:0;;48522:227::o;48239:124::-;48328:27;48337:2;48341:7;48350:4;48328:8;:27::i;15390:298::-;15494:17;;-1:-1:-1;;;;;15494:17:0;;15524:157;;15573:22;;-1:-1:-1;;;15573:22:0;;;;15568:102;;-1:-1:-1;13653:42:0;15568:102;15390:298;:::o;52794:3523::-;52936:27;52966;52985:7;52966:18;:27::i;:::-;-1:-1:-1;;;;;53121:22:0;;;;52936:57;;-1:-1:-1;53181:45:0;;;;53177:95;;53228:44;-1:-1:-1;;;53228:7:0;:44::i;:::-;53286:27;51902:24;;;:15;:24;;;;;52130:26;;775:10;51527:30;;;-1:-1:-1;;;;;51220:28:0;;51505:20;;;51502:56;53472:189;;53565:43;53582:4;775:10;85140:370;:::i;53565:43::-;53560:101;;53610:51;-1:-1:-1;;;53610:7:0;:51::i;:::-;53674:43;53696:4;53702:2;53706:7;53715:1;53674:21;:43::i;:::-;53810:15;53807:160;;;53950:1;53929:19;53922:30;53807:160;-1:-1:-1;;;;;54347:24:0;;;;;;;:18;:24;;;;;;54345:26;;-1:-1:-1;;54345:26:0;;;54416:22;;;;;;;;;54414:24;;-1:-1:-1;54414:24:0;;;47341:11;47316:23;47312:41;47299:63;-1:-1:-1;;;47299:63:0;54709:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;55004:47:0;;:52;;55000:627;;55109:1;55099:11;;55077:19;55232:30;;;:17;:30;;;;;;:35;;55228:384;;55370:13;;55355:11;:28;55351:242;;55517:30;;;;:17;:30;;;;;:52;;;55351:242;55058:569;55000:627;-1:-1:-1;;;;;55759:20:0;;56139:7;55759:20;56069:4;56011:25;55740:16;;55876:299;56200:8;56212:1;56200:13;56196:58;;56215:39;-1:-1:-1;;;56215:7:0;:39::i;:::-;56267:42;56288:4;56294:2;56298:7;56307:1;56267:20;:42::i;:::-;52925:3392;;;;52794:3523;;;:::o;93032:673::-;93143:16;93223:26;;;:17;:26;;;;;93286:21;;93143:16;;93223:26;-1:-1:-1;;;;;93286:21:0;;;-1:-1:-1;;;93343:28:0;;-1:-1:-1;;;;;93343:28:0;93286:21;93384:176;;-1:-1:-1;;93452:19:0;:28;-1:-1:-1;;;;;93452:28:0;;;-1:-1:-1;;;93513:35:0;;-1:-1:-1;;;;;93513:35:0;93384:176;93572:21;94071:5;93597:27;-1:-1:-1;;;;;93597:27:0;;:9;:27;:::i;:::-;93596:49;;;;:::i;:::-;93666:15;;;;-1:-1:-1;93032:673:0;;-1:-1:-1;;;;;;93032:673:0:o;177406:228::-;99249:13;:11;:13::i;:::-;177472:21:::1;177508:12:::0;177504:66:::1;;177544:14;;-1:-1:-1::0;;;177544:14:0::1;;;;;;;;;;;177504:66;177580:46;775:10:::0;177604:21:::1;177580:9;:46::i;:::-;177443:191;177406:228::o:0;56413:193::-;56559:39;56576:4;56582:2;56586:7;56559:39;;;;;;;;;;;;:16;:39::i;:::-;56413:193;;;:::o;176767:106::-;99249:13;:11;:13::i;:::-;176842::::1;:23;176858:7:::0;;176842:13;:23:::1;:::i;176592:166::-:0;99249:13;:11;:13::i;:::-;176701:49:::1;176718:7;176727:8;176737:12;176701:16;:49::i;42684:152::-:0;42756:7;42799:27;42818:7;42799:18;:27::i;38208:242::-;38280:7;-1:-1:-1;;;;;38304:19:0;;38300:69;;38325:44;-1:-1:-1;;;38325:7:0;:44::i;:::-;-1:-1:-1;;;;;;38387:25:0;;;;;:18;:25;;;;;;30968:13;38387:55;;38208:242::o;100038:103::-;99249:13;:11;:13::i;:::-;100103:30:::1;100130:1;100103:18;:30::i;:::-;100038:103::o:0;175964:86::-;99249:13;:11;:13::i;:::-;176028:5:::1;:14:::0;175964:86::o;41458:104::-;41514:13;41547:7;41540:14;;;;;:::i;2442:257::-;2534:31;:29;:31::i;:::-;2576:33;:47;;;;;-1:-1:-1;;;2576:47:0;-1:-1:-1;;;;2576:47:0;;;;;;2639:52;;;;;;2612:11;773:14:1;766:22;748:41;;736:2;721:18;;608:187;2639:52:0;;;;;;;;2442:257;:::o;175604:352::-;175667:11;;;;175662:65;;175702:13;;-1:-1:-1;;;175702:13:0;;;;;;;;;;;175662:65;175762:5;;175753:14;;:6;:14;:::i;:::-;175741:9;:26;175737:80;;;175791:14;;-1:-1:-1;;;175791:14:0;;;;;;;;;;;175737:80;175856:9;;175847:6;175831:13;36928:12;;36545:14;36912:13;:28;15390:298;;175831:13;:22;;;;:::i;:::-;:34;175827:84;;;175889:10;;-1:-1:-1;;;175889:10:0;;;;;;;;;;;175827:84;175923:25;175929:10;175941:6;175923:5;:25::i;49089:234::-;775:10;49184:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;49184:49:0;;;;;;;;;;:60;;-1:-1:-1;;49184:60:0;;;;;;;:49;-1:-1:-1;;;;;49260:55:0;;49306:8;49260:55;;;;773:14:1;766:22;748:41;;736:2;721:18;;608:187;49260:55:0;;;;;;;;49089:234;;:::o;14680:595::-;14756:31;:29;:31::i;:::-;-1:-1:-1;;;;;14832:30:0;;;;:34;;;14882:32;;;;:61;;;14919:24;14918:25;14882:61;14879:152;;;14967:52;;-1:-1:-1;;;14967:52:0;;;;;;;;;;;14879:152;15048:77;15081:22;:20;:22::i;:::-;15048:77;;;-1:-1:-1;;;;;11053:32:1;;;11035:51;;11122:32;;;11117:2;11102:18;;11095:60;11008:18;15048:77:0;;;;;;;15138:22;:29;;-1:-1:-1;;;;15138:29:0;-1:-1:-1;;;15138:29:0;;;15178:17;:38;;-1:-1:-1;;;;;15178:38:0;;-1:-1:-1;;;;;;15178:38:0;;;;;;15229;15198:18;15229;:38::i;57204:416::-;57379:31;57392:4;57398:2;57402:7;57379:12;:31::i;:::-;-1:-1:-1;;;;;57425:14:0;;;:19;57421:192;;57464:56;57495:4;57501:2;57505:7;57514:5;57464:30;:56::i;:::-;57459:154;;57541:56;-1:-1:-1;;;57541:7:0;:56::i;:::-;57204:416;;;;:::o;176995:309::-;177060:13;177091:16;177099:7;177091;:16::i;:::-;177086:49;;177116:19;;-1:-1:-1;;;177116:19:0;;;;;;;;;;;177086:49;177148:21;177172:10;:8;:10::i;:::-;177148:34;;177206:7;177200:21;177225:1;177200:26;:96;;;;;;;;;;;;;;;;;177253:7;177262:18;:7;:16;:18::i;:::-;177236:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;177200:96;177193:103;176995:309;-1:-1:-1;;;176995:309:0:o;177312:86::-;99249:13;:11;:13::i;:::-;177379:11:::1;::::0;;-1:-1:-1;;177364:26:0;::::1;177379:11;::::0;;::::1;177378:12;177364:26;::::0;;177312:86::o;85140:370::-;-1:-1:-1;;;;;49601:25:0;;;85237:15;49601:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;85330:173;;85366:33;;-1:-1:-1;;;85366:33:0;;;;85362:130;;;85453:22;:20;:22::i;:::-;-1:-1:-1;;;;;85433:43:0;:8;-1:-1:-1;;;;;85433:43:0;;85420:56;;85140:370;;;;:::o;100296:220::-;99249:13;:11;:13::i;:::-;-1:-1:-1;;;;;100381:22:0;::::1;100377:93;;100427:31;::::0;-1:-1:-1;;;100427:31:0;;100455:1:::1;100427:31;::::0;::::1;160:51:1::0;133:18;;100427:31:0::1;;;;;;;;100377:93;100480:28;100499:8;100480:18;:28::i;92762:215::-:0;92864:4;-1:-1:-1;;;;;;92888:41:0;;-1:-1:-1;;;92888:41:0;;:81;;-1:-1:-1;;;;;;;;;;90634:40:0;;;92933:36;90534:148;99528:166;99436:6;;-1:-1:-1;;;;;99436:6:0;775:10;99588:23;99584:103;;99635:40;;-1:-1:-1;;;99635:40:0;;775:10;99635:40;;;160:51:1;133:18;;99635:40:0;14:203:1;60857:2399:0;60930:20;60953:13;;;60981;;;60977:53;;60996:34;-1:-1:-1;;;60996:7:0;:34::i;:::-;61043:61;61073:1;61077:2;61081:12;61095:8;61043:21;:61::i;:::-;61543:31;;;;:17;:31;;;;;;;;-1:-1:-1;;;;;47167:28:0;;47341:11;47316:23;47312:41;47785:1;47772:15;;47746:24;47742:46;47309:52;47299:63;;61543:173;;;61934:22;;;:18;:22;;;;;:71;;61972:32;61960:45;;61934:71;;;47167:28;62195:13;;;62191:54;;62210:35;-1:-1:-1;;;62210:7:0;:35::i;:::-;62276:23;;;;62455:676;62874:7;62830:8;62785:1;62719:25;62656:1;62591;62560:358;63126:3;63113:9;;;;;;:16;62455:676;;-1:-1:-1;63147:13:0;:19;;;63188:60;;-1:-1:-1;63221:2:0;63225:12;63239:8;63188:20;:60::i;96655:217::-;96759:48;96784:8;96794:12;96759:24;:48::i;:::-;96823:41;;-1:-1:-1;;;;;11975:39:1;;11957:58;;-1:-1:-1;;;;;96823:41:0;;;;;11945:2:1;11930:18;96823:41:0;;;;;;;96655:217;;:::o;49902:475::-;49967:11;50159:13;;50149:7;:23;50145:214;;;50193:14;50226:60;-1:-1:-1;50243:26:0;;;;:17;:26;;;;;;;50233:42;;;50226:60;;50277:9;;;:::i;:::-;;;50226:60;;;-1:-1:-1;;;50314:24:0;:29;;-1:-1:-1;50145:214:0;49902:475;;;:::o;80411:165::-;80512:13;80506:4;80499:27;80553:4;80547;80540:18;71826:474;71955:13;71971:16;71979:7;71971;:16::i;:::-;71955:32;;72004:13;:45;;;;-1:-1:-1;775:10:0;-1:-1:-1;;;;;72021:28:0;;;;72004:45;72000:201;;;72069:44;72086:5;775:10;85140:370;:::i;72069:44::-;72064:137;;72134:51;-1:-1:-1;;;72134:7:0;:51::i;:::-;72213:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;72213:35:0;-1:-1:-1;;;;;72213:35:0;;;;;;;;;72264:28;;72213:24;;72264:28;;;;;;;71944:356;71826:474;;;:::o;44169:2213::-;44319:26;;;;:17;:26;;;;;;44646:6;44656:1;44646:11;44642:1292;;44693:13;;44682:7;:24;44678:77;;44708:47;-1:-1:-1;;;44708:7:0;:47::i;:::-;45312:607;-1:-1:-1;;;45408:9:0;45390:28;;;;:17;:28;;;;;;45464:25;;45312:607;45464:25;-1:-1:-1;;;45516:6:0;:24;45544:1;45516:29;45512:48;;44169:2213;;;:::o;45512:48::-;45852:47;-1:-1:-1;;;45852:7:0;:47::i;:::-;45312:607;;44642:1292;-1:-1:-1;;;46261:6:0;:24;46289:1;46261:29;46257:48;;44169:2213;;;:::o;46257:48::-;46327:47;-1:-1:-1;;;46327:7:0;:47::i;86634:359::-;86816:9;86811:175;86835:8;86831:1;:12;86811:175;;;86861:51;86885:4;86891:2;86895:16;86910:1;86895:12;:16;:::i;:::-;86861:23;:51::i;:::-;86956:3;;86811:175;;;;86634:359;;;;:::o;87100:357::-;87281:9;87276:174;87300:8;87296:1;:12;87276:174;;;87326:50;87349:4;87355:2;87359:16;87374:1;87359:12;:16;:::i;:::-;87326:22;:50::i;:::-;87420:3;;87276:174;;177642:209;177716:12;177734:8;-1:-1:-1;;;;;177734:13:0;177755:7;177734:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;177715:52;;;177783:7;177778:66;;177814:18;;-1:-1:-1;;;177814:18:0;;;;;;;;;;;96880:246;96999:55;97022:7;97031:8;97041:12;96999:22;:55::i;:::-;97070:48;;-1:-1:-1;;;;;11975:39:1;;11957:58;;-1:-1:-1;;;;;97070:48:0;;;97086:7;;97070:48;;11945:2:1;11930:18;97070:48:0;;;;;;;96880:246;;;:::o;100676:191::-;100769:6;;;-1:-1:-1;;;;;100786:17:0;;;-1:-1:-1;;;;;;100786:17:0;;;;;;;100819:40;;100769:6;;;100786:17;100769:6;;100819:40;;100750:16;;100819:40;100739:128;100676:191;:::o;101054:104::-;101137:13;:11;:13::i;18920:459::-;-1:-1:-1;;;;;18991:23:0;;;18987:385;;19120:22;;19174:21;;19171:190;;19220:95;;;-1:-1:-1;;;19220:95:0;;19295:4;19220:95;;;12549:51:1;81323:3:0;12616:18:1;;;12609:47;19220:95:0;;-1:-1:-1;;;;;19220:66:0;;;;;12522:18:1;;;;;-1:-1:-1;;19220:95:0;;;;;;;-1:-1:-1;19220:66:0;:95;;;;;;;;;;;;;;;;;;;;;;;;;19216:130;;;19016:356;18920:459;:::o;59704:691::-;59888:88;;-1:-1:-1;;;59888:88:0;;59867:4;;-1:-1:-1;;;;;59888:45:0;;;;;:88;;775:10;;59955:4;;59961:7;;59970:5;;59888:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59888:88:0;;;;;;;;-1:-1:-1;;59888:88:0;;;;;;;;;;;;:::i;:::-;;;59884:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60171:6;:13;60188:1;60171:18;60167:115;;60210:56;-1:-1:-1;;;60210:7:0;:56::i;:::-;60354:6;60348:13;60339:6;60335:2;60331:15;60324:38;59884:504;-1:-1:-1;;;;;;60047:64:0;-1:-1:-1;;;60047:64:0;;-1:-1:-1;59704:691:0;;;;;;:::o;176881:106::-;176933:13;176966;176959:20;;;;;:::i;171564:650::-;171620:13;171671:14;171688:17;171699:5;171688:10;:17::i;:::-;171708:1;171688:21;171671:38;;171724:20;171758:6;171747:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;171747:18:0;-1:-1:-1;171724:41:0;-1:-1:-1;171857:28:0;;;171873:2;171857:28;171914:254;-1:-1:-1;;171946:5:0;-1:-1:-1;;;172047:2:0;172036:14;;172031:32;171946:5;172018:46;172110:2;172101:11;;;-1:-1:-1;172131:21:0;171914:254;172131:21;-1:-1:-1;172189:6:0;171564:650;-1:-1:-1;;;171564:650:0:o;94355:518::-;94071:5;-1:-1:-1;;;;;94504:26:0;;;-1:-1:-1;94500:176:0;;;94609:55;;-1:-1:-1;;;94609:55:0;;-1:-1:-1;;;;;13613:39:1;;94609:55:0;;;13595:58:1;13669:18;;;13662:34;;;13568:18;;94609:55:0;13422:280:1;94500:176:0;-1:-1:-1;;;;;94690:22:0;;94686:110;;94736:48;;-1:-1:-1;;;94736:48:0;;94781:1;94736:48;;;160:51:1;133:18;;94736:48:0;14:203:1;94686:110:0;-1:-1:-1;94830:35:0;;;;;;;;;-1:-1:-1;;;;;94830:35:0;;;;;;-1:-1:-1;;;;;94830:35:0;;;;;;;;;;-1:-1:-1;;;94808:57:0;;;;:19;:57;94355:518::o;5762:623::-;-1:-1:-1;;;;;5889:18:0;;;;;5939:16;;;5889:18;5971:32;;;;;5990:13;5971:32;5968:410;;;6027:28;;-1:-1:-1;;;6027:28:0;;;;;;;;;;;5968:410;6076:15;6073:305;;;6108:54;6073:305;;;6183:13;6213:56;6180:198;6302:64;775:10;6337:4;6343:2;6347:7;6356:9;6302:20;:64::i;6518:625::-;-1:-1:-1;;;;;6644:18:0;;;;;6694:16;;;6644:18;6726:32;;;;;6745:13;6726:32;6723:413;;;6782:28;;-1:-1:-1;;;6782:28:0;;;;;;;;;;;6723:413;6831:15;6863:55;6828:308;6939:13;6936:200;;;6969:57;177406:228::o;95324:554::-;94071:5;-1:-1:-1;;;;;95488:26:0;;;-1:-1:-1;95484:183:0;;;95593:62;;-1:-1:-1;;;95593:62:0;;;;;13908:25:1;;;-1:-1:-1;;;;;13969:39:1;;13949:18;;;13942:67;14025:18;;;14018:34;;;13881:18;;95593:62:0;13707:351:1;95484:183:0;-1:-1:-1;;;;;95681:22:0;;95677:117;;95727:55;;-1:-1:-1;;;95727:55:0;;;;;14237:25:1;;;95779:1:0;14278:18:1;;;14271:60;14210:18;;95727:55:0;14063:274:1;95677:117:0;-1:-1:-1;95835:35:0;;;;;;;;-1:-1:-1;;;;;95835:35:0;;;;;-1:-1:-1;;;;;95835:35:0;;;;;;;;;;-1:-1:-1;95806:26:0;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;95806:64:0;;;;;;95324:554::o;165209:948::-;165262:7;;-1:-1:-1;;;165340:17:0;;165336:106;;-1:-1:-1;;;165378:17:0;;;-1:-1:-1;165424:2:0;165414:12;165336:106;165469:8;165460:5;:17;165456:106;;165507:8;165498:17;;;-1:-1:-1;165544:2:0;165534:12;165456:106;165589:8;165580:5;:17;165576:106;;165627:8;165618:17;;;-1:-1:-1;165664:2:0;165654:12;165576:106;165709:7;165700:5;:16;165696:103;;165746:7;165737:16;;;-1:-1:-1;165782:1:0;165772:11;165696:103;165826:7;165817:5;:16;165813:103;;165863:7;165854:16;;;-1:-1:-1;165899:1:0;165889:11;165813:103;165943:7;165934:5;:16;165930:103;;165980:7;165971:16;;;-1:-1:-1;166016:1:0;166006:11;165930:103;166060:7;166051:5;:16;166047:68;;166098:1;166088:11;166143:6;165209:948;-1:-1:-1;;165209:948:0:o;16648:472::-;16843:17;16863:22;:20;:22::i;:::-;16843:42;-1:-1:-1;;;;;;16902:23:0;;;16898:215;;-1:-1:-1;;;;;16946:23:0;;:10;:23;16942:70;;16990:7;;;16942:70;17028:73;;-1:-1:-1;;;17028:73:0;;-1:-1:-1;;;;;14591:32:1;;;17028:73:0;;;14573:51:1;14660:32;;;14640:18;;;14633:60;14729:32;;;14709:18;;;14702:60;14778:18;;;14771:34;;;17028:46:0;;;;;14545:19:1;;17028:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16898:215;16832:288;16648:472;;;;;:::o;222:131:1:-;-1:-1:-1;;;;;;296:32:1;;286:43;;276:71;;343:1;340;333:12;358:245;416:6;469:2;457:9;448:7;444:23;440:32;437:52;;;485:1;482;475:12;437:52;524:9;511:23;543:30;567:5;543:30;:::i;800:173::-;868:20;;-1:-1:-1;;;;;917:31:1;;907:42;;897:70;;963:1;960;953:12;978:300;1046:6;1054;1107:2;1095:9;1086:7;1082:23;1078:32;1075:52;;;1123:1;1120;1113:12;1075:52;1168:23;;;-1:-1:-1;1234:38:1;1268:2;1253:18;;1234:38;:::i;:::-;1224:48;;978:300;;;;;:::o;1283:179::-;1350:20;;-1:-1:-1;;;;;1399:38:1;;1389:49;;1379:77;;1452:1;1449;1442:12;1467:258;1534:6;1542;1595:2;1583:9;1574:7;1570:23;1566:32;1563:52;;;1611:1;1608;1601:12;1563:52;1634:29;1653:9;1634:29;:::i;:::-;1624:39;;1682:37;1715:2;1704:9;1700:18;1682:37;:::i;1730:300::-;1783:3;1821:5;1815:12;1848:6;1843:3;1836:19;1904:6;1897:4;1890:5;1886:16;1879:4;1874:3;1870:14;1864:47;1956:1;1949:4;1940:6;1935:3;1931:16;1927:27;1920:38;2019:4;2012:2;2008:7;2003:2;1995:6;1991:15;1987:29;1982:3;1978:39;1974:50;1967:57;;;1730:300;;;;:::o;2035:231::-;2184:2;2173:9;2166:21;2147:4;2204:56;2256:2;2245:9;2241:18;2233:6;2204:56;:::i;2271:226::-;2330:6;2383:2;2371:9;2362:7;2358:23;2354:32;2351:52;;;2399:1;2396;2389:12;2351:52;-1:-1:-1;2444:23:1;;2271:226;-1:-1:-1;2271:226:1:o;2502:300::-;2570:6;2578;2631:2;2619:9;2610:7;2606:23;2602:32;2599:52;;;2647:1;2644;2637:12;2599:52;2670:29;2689:9;2670:29;:::i;:::-;2660:39;2768:2;2753:18;;;;2740:32;;-1:-1:-1;;;2502:300:1:o;3277:374::-;3354:6;3362;3370;3423:2;3411:9;3402:7;3398:23;3394:32;3391:52;;;3439:1;3436;3429:12;3391:52;3462:29;3481:9;3462:29;:::i;:::-;3452:39;;3510:38;3544:2;3533:9;3529:18;3510:38;:::i;:::-;3277:374;;3500:48;;-1:-1:-1;;;3617:2:1;3602:18;;;;3589:32;;3277:374::o;3656:346::-;3724:6;3732;3785:2;3773:9;3764:7;3760:23;3756:32;3753:52;;;3801:1;3798;3791:12;3753:52;-1:-1:-1;;3846:23:1;;;3966:2;3951:18;;;3938:32;;-1:-1:-1;3656:346:1:o;4286:587::-;4357:6;4365;4418:2;4406:9;4397:7;4393:23;4389:32;4386:52;;;4434:1;4431;4424:12;4386:52;4474:9;4461:23;4507:18;4499:6;4496:30;4493:50;;;4539:1;4536;4529:12;4493:50;4562:22;;4615:4;4607:13;;4603:27;-1:-1:-1;4593:55:1;;4644:1;4641;4634:12;4593:55;4684:2;4671:16;4710:18;4702:6;4699:30;4696:50;;;4742:1;4739;4732:12;4696:50;4787:7;4782:2;4773:6;4769:2;4765:15;4761:24;4758:37;4755:57;;;4808:1;4805;4798:12;4755:57;4839:2;4831:11;;;;;4861:6;;-1:-1:-1;4286:587:1;-1:-1:-1;;;4286:587:1:o;4878:372::-;4954:6;4962;4970;5023:2;5011:9;5002:7;4998:23;4994:32;4991:52;;;5039:1;5036;5029:12;4991:52;5084:23;;;-1:-1:-1;5150:38:1;5184:2;5169:18;;5150:38;:::i;:::-;5140:48;;5207:37;5240:2;5229:9;5225:18;5207:37;:::i;:::-;5197:47;;4878:372;;;;;:::o;5255:186::-;5314:6;5367:2;5355:9;5346:7;5342:23;5338:32;5335:52;;;5383:1;5380;5373:12;5335:52;5406:29;5425:9;5406:29;:::i;5446:160::-;5511:20;;5567:13;;5560:21;5550:32;;5540:60;;5596:1;5593;5586:12;5611:180;5667:6;5720:2;5708:9;5699:7;5695:23;5691:32;5688:52;;;5736:1;5733;5726:12;5688:52;5759:26;5775:9;5759:26;:::i;5796:254::-;5861:6;5869;5922:2;5910:9;5901:7;5897:23;5893:32;5890:52;;;5938:1;5935;5928:12;5890:52;5961:29;5980:9;5961:29;:::i;:::-;5951:39;;6009:35;6040:2;6029:9;6025:18;6009:35;:::i;6055:127::-;6116:10;6111:3;6107:20;6104:1;6097:31;6147:4;6144:1;6137:15;6171:4;6168:1;6161:15;6187:1207;6282:6;6290;6298;6306;6359:3;6347:9;6338:7;6334:23;6330:33;6327:53;;;6376:1;6373;6366:12;6327:53;6399:29;6418:9;6399:29;:::i;:::-;6389:39;;6447:38;6481:2;6470:9;6466:18;6447:38;:::i;:::-;6437:48;-1:-1:-1;6554:2:1;6539:18;;6526:32;;-1:-1:-1;6633:2:1;6618:18;;6605:32;6660:18;6649:30;;6646:50;;;6692:1;6689;6682:12;6646:50;6715:22;;6768:4;6760:13;;6756:27;-1:-1:-1;6746:55:1;;6797:1;6794;6787:12;6746:55;6837:2;6824:16;6863:18;6855:6;6852:30;6849:56;;;6885:18;;:::i;:::-;6934:2;6928:9;7026:2;6988:17;;-1:-1:-1;;6984:31:1;;;7017:2;6980:40;6976:54;6964:67;;7061:18;7046:34;;7082:22;;;7043:62;7040:88;;;7108:18;;:::i;:::-;7144:2;7137:22;7168;;;7209:15;;;7226:2;7205:24;7202:37;-1:-1:-1;7199:57:1;;;7252:1;7249;7242:12;7199:57;7308:6;7303:2;7299;7295:11;7290:2;7282:6;7278:15;7265:50;7361:1;7356:2;7347:6;7339;7335:19;7331:28;7324:39;7382:6;7372:16;;;;;6187:1207;;;;;;;:::o;7399:260::-;7467:6;7475;7528:2;7516:9;7507:7;7503:23;7499:32;7496:52;;;7544:1;7541;7534:12;7496:52;7567:29;7586:9;7567:29;:::i;:::-;7557:39;;7615:38;7649:2;7638:9;7634:18;7615:38;:::i;7664:127::-;7725:10;7720:3;7716:20;7713:1;7706:31;7756:4;7753:1;7746:15;7780:4;7777:1;7770:15;7796:125;7861:9;;;7882:10;;;7879:36;;;7895:18;;:::i;7926:380::-;8005:1;8001:12;;;;8048;;;8069:61;;8123:4;8115:6;8111:17;8101:27;;8069:61;8176:2;8168:6;8165:14;8145:18;8142:38;8139:161;;8222:10;8217:3;8213:20;8210:1;8203:31;8257:4;8254:1;8247:15;8285:4;8282:1;8275:15;8139:161;;7926:380;;;:::o;8311:168::-;8384:9;;;8415;;8432:15;;;8426:22;;8412:37;8402:71;;8453:18;;:::i;8616:217::-;8656:1;8682;8672:132;;8726:10;8721:3;8717:20;8714:1;8707:31;8761:4;8758:1;8751:15;8789:4;8786:1;8779:15;8672:132;-1:-1:-1;8818:9:1;;8616:217::o;8964:518::-;9066:2;9061:3;9058:11;9055:421;;;9102:5;9099:1;9092:16;9146:4;9143:1;9133:18;9216:2;9204:10;9200:19;9197:1;9193:27;9187:4;9183:38;9252:4;9240:10;9237:20;9234:47;;;-1:-1:-1;9275:4:1;9234:47;9330:2;9325:3;9321:12;9318:1;9314:20;9308:4;9304:31;9294:41;;9385:81;9403:2;9396:5;9393:13;9385:81;;;9462:1;9448:16;;9429:1;9418:13;9385:81;;9658:1198;9782:18;9777:3;9774:27;9771:53;;;9804:18;;:::i;:::-;9833:94;9923:3;9883:38;9915:4;9909:11;9883:38;:::i;:::-;9877:4;9833:94;:::i;:::-;9953:1;9978:2;9973:3;9970:11;9995:1;9990:608;;;;10642:1;10659:3;10656:93;;;-1:-1:-1;10715:19:1;;;10702:33;10656:93;-1:-1:-1;;9615:1:1;9611:11;;;9607:24;9603:29;9593:40;9639:1;9635:11;;;9590:57;10762:78;;9963:887;;9990:608;8911:1;8904:14;;;8948:4;8935:18;;-1:-1:-1;;10026:17:1;;;10141:229;10155:7;10152:1;10149:14;10141:229;;;10244:19;;;10231:33;10216:49;;10351:4;10336:20;;;;10304:1;10292:14;;;;10171:12;10141:229;;;10145:3;10398;10389:7;10386:16;10383:159;;;10522:1;10518:6;10512:3;10506;10503:1;10499:11;10495:21;10491:34;10487:39;10474:9;10469:3;10465:19;10452:33;10448:79;10440:6;10433:95;10383:159;;;10585:1;10579:3;10576:1;10572:11;10568:19;10562:4;10555:33;9963:887;;9658:1198;;;:::o;11166:212::-;11208:3;11246:5;11240:12;11290:6;11283:4;11276:5;11272:16;11267:3;11261:36;11352:1;11316:16;;11341:13;;;-1:-1:-1;11316:16:1;;11166:212;-1:-1:-1;11166:212:1:o;11383:425::-;11663:3;11691:57;11717:30;11743:3;11735:6;11717:30;:::i;:::-;11709:6;11691:57;:::i;:::-;-1:-1:-1;;;11757:19:1;;11800:1;11792:10;;11383:425;-1:-1:-1;;;;11383:425:1:o;12026:136::-;12065:3;12093:5;12083:39;;12102:18;;:::i;:::-;-1:-1:-1;;;12138:18:1;;12026:136::o;12667:496::-;-1:-1:-1;;;;;12898:32:1;;;12880:51;;12967:32;;12962:2;12947:18;;12940:60;13031:2;13016:18;;13009:34;;;13079:3;13074:2;13059:18;;13052:31;;;-1:-1:-1;;13100:57:1;;13137:19;;13129:6;13100:57;:::i;:::-;13092:65;12667:496;-1:-1:-1;;;;;;12667:496:1:o;13168:249::-;13237:6;13290:2;13278:9;13269:7;13265:23;13261:32;13258:52;;;13306:1;13303;13296:12;13258:52;13338:9;13332:16;13357:30;13381:5;13357:30;:::i
Swarm Source
ipfs://3b92024bfa896626bb67e615f43df74b4656691d79184405e3a05d3ff63ab4d9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
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.