Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
Latest 25 from a total of 101 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Collectio... | 21837575 | 29 hrs ago | IN | 0 ETH | 0.00028734 | ||||
Create Collectio... | 21817975 | 3 days ago | IN | 0 ETH | 0.00046907 | ||||
Create Collectio... | 21817585 | 4 days ago | IN | 0 ETH | 0.00027708 | ||||
Create Collectio... | 21725246 | 16 days ago | IN | 0 ETH | 0.00127063 | ||||
Create Collectio... | 21716155 | 18 days ago | IN | 0 ETH | 0.00291022 | ||||
Create Collectio... | 21690362 | 21 days ago | IN | 0 ETH | 0.00207513 | ||||
Create Collectio... | 21631979 | 29 days ago | IN | 0 ETH | 0.0034773 | ||||
Create Collectio... | 21623271 | 31 days ago | IN | 0 ETH | 0.0023556 | ||||
Create Collectio... | 21538698 | 42 days ago | IN | 0 ETH | 0.0027765 | ||||
Create Collectio... | 21430488 | 58 days ago | IN | 0 ETH | 0.00663394 | ||||
Create Collectio... | 21425660 | 58 days ago | IN | 0 ETH | 0.00292768 | ||||
Create Collectio... | 21422961 | 59 days ago | IN | 0 ETH | 0.00910412 | ||||
Create Collectio... | 21421645 | 59 days ago | IN | 0 ETH | 0.00255724 | ||||
Create Collectio... | 21386712 | 64 days ago | IN | 0 ETH | 0.00550436 | ||||
Create Collectio... | 21383186 | 64 days ago | IN | 0 ETH | 0.00308689 | ||||
Create Collectio... | 21371147 | 66 days ago | IN | 0 ETH | 0.00429175 | ||||
Create Collectio... | 21366468 | 67 days ago | IN | 0 ETH | 0.00700752 | ||||
Create Collectio... | 21350008 | 69 days ago | IN | 0 ETH | 0.00305657 | ||||
Create Collectio... | 21323015 | 73 days ago | IN | 0 ETH | 0.00822985 | ||||
Create Collectio... | 21281173 | 78 days ago | IN | 0 ETH | 0.00572461 | ||||
Create Collectio... | 21274127 | 79 days ago | IN | 0 ETH | 0.00275007 | ||||
Create Collectio... | 21273341 | 80 days ago | IN | 0 ETH | 0.00318801 | ||||
Create Collectio... | 21272773 | 80 days ago | IN | 0 ETH | 0.00428685 | ||||
Create Collectio... | 21272367 | 80 days ago | IN | 0 ETH | 0.00411724 | ||||
Create Collectio... | 21268240 | 80 days ago | IN | 0 ETH | 0.00216093 |
Latest 25 internal transactions (View All)
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
LondonTokenFactory
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./Clones.sol"; import "./LondonTokenBase.sol"; /** * @title LondonTokenFactory * @notice This contract is used to create new instances of LondonTokenBase contracts. * Each new instance represents a new collection of tokens. */ contract LondonTokenFactory { event NewCollection(address); /** * @dev Address of the token implementation which will be used as a template for clones. */ address immutable tokenImplementation; /** * @notice Constructor initializes a new instance of LondonTokenBase as the template for future clones. */ constructor() { tokenImplementation = address(new LondonTokenBase()); } /** * @notice Creates a new collection of London tokens. * @dev Deploys a clone of the LondonTokenBase and initializes it with the provided parameters. * @param uri_ The URI for the metadata of the collection. * @param minter_ The address allowed to mint new tokens in this collection. * @param gatewayManager_ The address of the gateway manager for cross-chain functionalities. * @param contractName_ The name of the new token contract. * @param royaltyValue_ The royalty value for secondary sales. * @param owner_ The owner of the new token collection. */ function createCollection( string memory uri_, address minter_, address gatewayManager_, string memory contractName_, uint256 royaltyValue_, address owner_ ) external { address clone = Clones.clone(tokenImplementation); LondonTokenBase(clone).initialize( uri_, minter_, gatewayManager_, contractName_, royaltyValue_, owner_ ); emit NewCollection(clone); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./Ownable.sol"; import "./ERC721.sol"; import "./ERC2981PerTokenRoyalties.sol"; import "./OnchainFileStorage.sol"; /// @custom:security-contact [email protected] contract LondonTokenBase is ERC721, Ownable, ERC2981PerTokenRoyalties, OnchainFileStorage { constructor() ERC721("", "VERSE", "") {} /** * @dev Initializes key parameters of the contract, ensuring it's only done once. * @param uri_ The base URI for token metadata. * @param minter_ The address with the ability to mint new tokens. * @param gatewayManager_ The address of the gateway manager. * @param contractName_ The name of the contract. * @param royaltyValue_ The royalty value for each token. * @param owner_ The initial owner of the contract. */ function initialize( string memory uri_, address minter_, address gatewayManager_, string memory contractName_, uint256 royaltyValue_, address owner_ ) public { require(bytes(_name).length == 0, "Already initialized"); _name = contractName_; _baseUri = uri_; mintingManager = minter_; gatewayManager = gatewayManager_; _setTokenRoyalty(owner_, royaltyValue_); creator = owner_; _transferOwnership(owner_); } /** @notice The total number of tokens in existence. */ uint256 public totalSupply; /** @notice Address of the creator of the tokens. */ address public creator; /** @notice Address responsible for minting new tokens. */ address public mintingManager; /** @notice Address responsible for managing gateways. */ address public gatewayManager; /** @notice Stores payloads for each token by their ID. */ mapping(uint256 => string) public _payloads; /** @notice Name of the artist associated with the tokens. */ string public artistName; /** @notice Description of the project for which the tokens are minted. */ string public projectDescription; /** @notice Year of the token creation or release. */ string public year; /** @notice Licensing information for the token. */ string public license; /** * @dev Sets Artist Name for the collection. * */ function setArtistName(string memory artistName_) public onlyOwner { artistName = artistName_; } /** * @dev Sets Collection Name for the collection. * */ function setCollectionName(string memory name_) public onlyOwner { _name = name_; } /** * @dev Sets Description for the collection. * */ function setDescription(string memory description_) public onlyOwner { projectDescription = description_; } /** * @dev Sets Year for the collection. * */ function setYear(string memory year_) public onlyOwner { year = year_; } /** * @dev Sets License for the collection. * */ function setLicense(string memory license_) public onlyOwner { license = license_; } /** * @dev Creates a token with `id`, and assigns them to `to`. * Method emits two transfer events. * * Emits a {Transfer} event. * * Requirements: * * - `to` cannot be the zero address. */ function mint(address to, uint256 tokenId) public onlyMinter { require(to != address(0), "mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _balances[to] += 1; totalSupply += 1; _owners[tokenId] = to; emit Transfer(address(0), creator, tokenId); emit Transfer(creator, to, tokenId); } /** * @dev Creates a token with `id`, and assigns them to `to`. * Method emits two transfer events. * * Emits a {Transfer} event. * * Requirements: * * - `to` cannot be the zero address. */ function mintWithPayload( address to, uint256 tokenId, string memory payload ) public onlyMinter { require(to != address(0), "mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _balances[to] += 1; totalSupply += 1; _owners[tokenId] = to; _payloads[tokenId] = payload; emit Transfer(address(0), creator, tokenId); emit Transfer(creator, to, tokenId); } /** * @dev Creates a token with `id`, and assigns them to `to`. * Method emits two transfer events. * * Emits a {Transfer} events for intermediate artist. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function mintBatch( address[] memory to, uint256[] memory tokenIds ) public onlyMinter { require(tokenIds.length == to.length, "Arrays length mismatch"); for (uint256 i = 0; i < tokenIds.length; i++) { mint(to[i], tokenIds[i]); } } /** * @dev Creates a token with `id`, and assigns them to `to`. * Method emits two transfer events. * * Emits a {Transfer} events for intermediate artist. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function mintBatchWithPayload( address[] memory to, uint256[] memory tokenIds, string[] memory payloads ) public onlyMinter { require(tokenIds.length == to.length, "Arrays length mismatch"); for (uint256 i = 0; i < tokenIds.length; i++) { mintWithPayload(to[i], tokenIds[i], payloads[i]); } } /** * @dev Modifier for Minter role. * */ modifier onlyMinter() { require(msg.sender == mintingManager, "Permission denied"); _; } /** * @dev Modified for Gateway Manager role. * */ modifier onlyGatewayManager() { require(msg.sender == gatewayManager, "Permission denied"); _; } /** * @dev Updates the token URI. * */ function tokenURI( uint256 tokenId ) public view override(ERC721) returns (string memory) { return super.tokenURI(tokenId); } /** * @dev Returns payload for the token. * */ function getPayload(uint256 tokenId) public view returns (string memory) { return _payloads[tokenId]; } /** * @dev Sets the payload for a given token ID. * @param tokenId The ID of the token. * @param payload The payload to be stored. */ function setPayload(uint256 tokenId, string memory payload) public onlyOwner { _payloads[tokenId] = payload; } /** * @dev Checks for supported interface. * */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721, ERC2981Base) returns (bool) { return super.supportsInterface(interfaceId); } /** * @dev Sets royalties for `tokenId` and `tokenRecipient` with royalty value `royaltyValue`. * */ function setRoyalties( address royaltyRecipient, uint256 royaltyValue ) public onlyOwner { _setTokenRoyalty(royaltyRecipient, royaltyValue); } /** * @dev Sets new minter for the contract. * */ function setMintingManager(address minter_) public onlyOwner { mintingManager = minter_; } /** * @dev Sets new gateway manager for the contract. * */ function setGatewayManager(address gatewayManager_) public onlyOwner { gatewayManager = gatewayManager_; } /** * @dev Sets base URI for metadata. * */ function setURI(string memory newuri) public onlyGatewayManager { _setURI(newuri); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
//SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; /** * @title Onchain File Storage * @notice Introduces file handling to place utilities onchain * @author highlight.xyz */ import "./Ownable.sol"; abstract contract OnchainFileStorage is Ownable { /** * @notice File existence errors */ error FileAlreadyRegistered(); error FileNotRegistered(); /** * @notice File storage * @dev File-scoped bytecode addresses (pointers) holding contents */ mapping(bytes => address[]) private _fileStorage; /** * @notice File storage path names * @dev Store registered file names (all will be present as keys in `fileStorage`) */ bytes[] private _files; /** * @notice Add a file via its name and associated storage bytecode addresses */ function addFile( string calldata fileName, address[] calldata fileStorageAddresses ) external onlyOwner { bytes memory _fileName = bytes(fileName); if (_fileStorage[_fileName].length != 0) { _revert(FileAlreadyRegistered.selector); } _files.push(_fileName); _fileStorage[_fileName] = fileStorageAddresses; } /** * @notice Remove a file from registered list of file names, and its associated storage bytecode addresses */ function removeFile(string calldata fileName) external onlyOwner { bytes memory _fileName = bytes(fileName); if (_fileStorage[_fileName].length == 0) { _revert(FileNotRegistered.selector); } bytes[] memory oldFiles = _files; bytes[] memory newFiles = new bytes[](oldFiles.length - 1); uint256 fileIndexOffset = 0; uint256 oldFilesLength = oldFiles.length; for (uint256 i = 0; i < oldFilesLength; i++) { if (keccak256(oldFiles[i]) == keccak256(_fileName)) { fileIndexOffset = 1; } else { newFiles[i - fileIndexOffset] = oldFiles[i]; } } _files = newFiles; delete _fileStorage[_fileName]; } /** * @notice Return registered file names */ function files() external view returns (string[] memory) { bytes[] memory fileNames = _files; string[] memory fileNamesHumanReadable = new string[](fileNames.length); for (uint256 i = 0; i < fileNames.length; i++) { fileNamesHumanReadable[i] = string(fileNames[i]); } return fileNamesHumanReadable; } /** * @notice Return storage bytecode addresses for a file */ function fileStorage( string calldata fileName ) external view returns (address[] memory) { bytes memory _fileName = bytes(fileName); if (_fileStorage[_fileName].length == 0) { _revert(FileNotRegistered.selector); } return _fileStorage[bytes(fileName)]; } /** * @notice Return file contents */ function fileContents( string calldata fileName ) external view returns (bytes memory) { bytes memory _fileName = bytes(fileName); if (_fileStorage[_fileName].length == 0) { _revert(FileNotRegistered.selector); } address[] memory fileStorageAddresses = _fileStorage[bytes(fileName)]; uint256 fileStorageAddressesLength = fileStorageAddresses.length; bytes memory contents = ""; for (uint256 i = 0; i < fileStorageAddressesLength; i++) { contents = abi.encodePacked( contents, string( _readBytecode( fileStorageAddresses[i], 1, fileStorageAddresses[i].code.length - 1 ) ) ); } return contents; } /** * @notice Read bytecode at an address * @ author SOLMATE */ function _readBytecode( address pointer, uint256 start, uint256 size ) private view returns (bytes memory data) { /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. data := mload(0x40) // Update the free memory pointer to prevent overriding our data. // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). // Adding 31 to size and running the result through the logic above ensures // the memory pointer remains word-aligned, following the Solidity convention. mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) // Store the size of the data in the first 32 byte chunk of free memory. mstore(data, size) // Copy the code into memory right after the 32 bytes we used to store the size. extcodecopy(pointer, add(data, 32), start, size) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure virtual { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./ERC165.sol"; import "./ERC2981Base.sol"; /// @dev This is a contract used to add ERC2981 support to ERC721 and 1155 abstract contract ERC2981PerTokenRoyalties is ERC2981Base { RoyaltyInfo _royalties; /// @dev Sets token royalties /// @param recipient recipient of the royalties /// @param value percentage (using 2 decimals - 10000 = 100, 0 = 0) function _setTokenRoyalty(address recipient, uint256 value) internal { require(value <= 10000, "ERC2981Royalties: Too high"); _royalties = RoyaltyInfo(recipient, uint24(value)); } /// @inheritdoc IERC2981Royalties function royaltyInfo( uint256 /* tokenId */, uint256 value ) external view override returns (address receiver, uint256 royaltyAmount) { RoyaltyInfo memory royalties = _royalties; receiver = royalties.recipient; royaltyAmount = (value * royalties.amount) / 10000; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity 0.8.13; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./IERC721Metadata.sol"; import "./Address.sol"; import "./Context.sol"; import "./Strings.sol"; import "./ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string public _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) public _owners; // Mapping owner address to token count mapping(address => uint256) public _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Metadata Update event event MetadataUpdate(uint256 _tokenId); // Used as the URI for all token types by relying on ID substitution, e.g. string public _baseUri; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor( string memory name_, string memory symbol_, string memory uri_ ) { _name = name_; _symbol = symbol_; _baseUri = uri_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf( address owner ) public view virtual override returns (uint256) { require( owner != address(0), "ERC721: address zero is not a valid owner" ); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf( uint256 tokenId ) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI( uint256 tokenId ) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseUri; return bytes(baseURI).length > 0 ? string.concat(baseURI, "/", Strings.toString(tokenId)) : ""; } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism */ function _setURI(string memory newuri_) internal virtual { _baseUri = newuri_; emit MetadataUpdate(type(uint256).max); } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved( uint256 tokenId ) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll( address operator, bool approved ) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll( address owner, address operator ) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @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 (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner( address spender, uint256 tokenId ) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received( _msgSender(), from, tokenId, data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert( "ERC721: transfer to non ERC721Receiver implementer" ); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 /* firstTokenId */, uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./Math.sol"; import "./SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(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) { 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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); 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 Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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`. * * 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 calldata data) external; /** * @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 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) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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; /** * @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; /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./ERC165.sol"; import "./IERC2981Royalties.sol"; /// @dev This is a contract used to add ERC2981 support to ERC721 and 1155 abstract contract ERC2981Base is ERC165, IERC2981Royalties { struct RoyaltyInfo { address recipient; uint24 amount; } /// @inheritdoc ERC165 function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC2981Royalties).interfaceId || super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return 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 { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return 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 up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev 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^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) 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^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv 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. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); 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^256 / 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^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. 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^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // 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^256. Since the preconditions guarantee that the outcome is // less than 2^256, 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; } } /** * @notice 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) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * 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; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; /// @title IERC2981Royalties /// @dev Interface for the ERC2981 - Token Royalty standard interface IERC2981Royalties { /// @notice Called with the sale price to determine how much royalty // is owed and to whom. /// @param _value - the sale price of the NFT asset specified by _tokenId /// @return _receiver - address of who should be sent the royalty payment /// @return _royaltyAmount - the royalty payment amount for value sale price function royaltyInfo( uint256 _tokenId, uint256 _value ) external view returns (address _receiver, uint256 _royaltyAmount); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"","type":"address"}],"name":"NewCollection","type":"event"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"},{"internalType":"address","name":"minter_","type":"address"},{"internalType":"address","name":"gatewayManager_","type":"address"},{"internalType":"string","name":"contractName_","type":"string"},{"internalType":"uint256","name":"royaltyValue_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"}],"name":"createCollection","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b5060405161001d90610072565b604051809103906000f080158015610039573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505061007f565b615e4d8061070683390190565b60805161066d61009960003960006053015261066d6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806366f8f34714610030575b600080fd5b61004a600480360381019061004591906103d6565b61004c565b005b60006100777f000000000000000000000000000000000000000000000000000000000000000061012e565b90508073ffffffffffffffffffffffffffffffffffffffff1663378dfba48888888888886040518763ffffffff1660e01b81526004016100bc96959493929190610541565b600060405180830381600087803b1580156100d657600080fd5b505af11580156100ea573d6000803e3d6000fd5b505050507f703fdf4fec8b6ba710f9f4fa396f0ea0045ee5f6bf7be6e4d49f4f5ea0d927468160405161011d91906105b0565b60405180910390a150505050505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f09050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101da90610617565b60405180910390fd5b919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61024f82610206565b810181811067ffffffffffffffff8211171561026e5761026d610217565b5b80604052505050565b60006102816101e8565b905061028d8282610246565b919050565b600067ffffffffffffffff8211156102ad576102ac610217565b5b6102b682610206565b9050602081019050919050565b82818337600083830152505050565b60006102e56102e084610292565b610277565b90508281526020810184848401111561030157610300610201565b5b61030c8482856102c3565b509392505050565b600082601f830112610329576103286101fc565b5b81356103398482602086016102d2565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061036d82610342565b9050919050565b61037d81610362565b811461038857600080fd5b50565b60008135905061039a81610374565b92915050565b6000819050919050565b6103b3816103a0565b81146103be57600080fd5b50565b6000813590506103d0816103aa565b92915050565b60008060008060008060c087890312156103f3576103f26101f2565b5b600087013567ffffffffffffffff811115610411576104106101f7565b5b61041d89828a01610314565b965050602061042e89828a0161038b565b955050604061043f89828a0161038b565b945050606087013567ffffffffffffffff8111156104605761045f6101f7565b5b61046c89828a01610314565b935050608061047d89828a016103c1565b92505060a061048e89828a0161038b565b9150509295509295509295565b600081519050919050565b600082825260208201905092915050565b60005b838110156104d55780820151818401526020810190506104ba565b838111156104e4576000848401525b50505050565b60006104f58261049b565b6104ff81856104a6565b935061050f8185602086016104b7565b61051881610206565b840191505092915050565b61052c81610362565b82525050565b61053b816103a0565b82525050565b600060c082019050818103600083015261055b81896104ea565b905061056a6020830188610523565b6105776040830187610523565b818103606083015261058981866104ea565b90506105986080830185610532565b6105a560a0830184610523565b979650505050505050565b60006020820190506105c56000830184610523565b92915050565b7f455243313136373a20637265617465206661696c656400000000000000000000600082015250565b60006106016016836104a6565b915061060c826105cb565b602082019050919050565b60006020820190508181036000830152610630816105f4565b905091905056fea2646970667358221220fd634f15fa353faab3b809bace484cc91ff9d3201d9ad042e42812a86b2e01ff64736f6c634300080d003360806040523480156200001157600080fd5b50604051806020016040528060008152506040518060400160405280600581526020017f564552534500000000000000000000000000000000000000000000000000000081525060405180602001604052806000815250826000908051906020019062000080929190620001aa565b50816001908051906020019062000099929190620001aa565b508060069080519060200190620000b2929190620001aa565b50505050620000d6620000ca620000dc60201b60201c565b620000e460201b60201c565b620002be565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001b89062000289565b90600052602060002090601f016020900481019282620001dc576000855562000228565b82601f10620001f757805160ff191683800117855562000228565b8280016001018555821562000228579182015b82811115620002275782518255916020019190600101906200020a565b5b5090506200023791906200023b565b5090565b5b80821115620002565760008160009055506001016200023c565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002a257607f821691505b602082108103620002b857620002b76200025a565b5b50919050565b615b7f80620002ce6000396000f3fe608060405234801561001057600080fd5b50600436106102f15760003560e01c80636ebcf6071161019d578063a22cb465116100e9578063d28d8852116100a2578063ea888a881161007c578063ea888a8814610913578063f1afe04d14610943578063f2fde38b1461095f578063f32697161461097b576102f1565b8063d28d8852146108a9578063da990d4c146108c7578063e985e9c5146108e3576102f1565b8063a22cb465146107eb578063b4837d9e14610807578063b88d4fde14610823578063c21a8f671461083f578063c87b56dd1461085b578063d0414c9d1461088b576102f1565b80638278cb661161015657806390c3f38f1161013057806390c3f38f1461076557806395d89b4114610781578063992924a61461079f5780639c5643e7146107cf576102f1565b80638278cb661461070f5780638c7ea24b1461072b5780638da5cb5b14610747576102f1565b80636ebcf6071461064d57806370a082311461067d578063715018a6146106ad578063755f047b146106b75780637c39601d146106d55780637c88e3d9146106f3576102f1565b80633113cca01161025c57806342b611b7116102155780635b2f515b116101ef5780635b2f515b146105c55780636352211e146105e35780636b87d24c146106135780636c52c3fb14610631576102f1565b806342b611b71461056f578063588844321461058b5780635a3c7d26146105a9576102f1565b80633113cca0146104c5578063378dfba4146104e15780633a330022146104fd5780633e63eb2a1461051957806340c10f191461053757806342842e0e14610553576102f1565b8063095ea7b3116102ae578063095ea7b3146103de57806318160ddd146103fa5780631d2db6c81461041857806323b872dd146104485780632a55205a146104645780632b566c2a14610495576102f1565b806301ffc9a7146102f657806302d05d3f1461032657806302ee12111461034457806302fe53051461037457806306fdde0314610390578063081812fc146103ae575b600080fd5b610310600480360381019061030b9190613f02565b610999565b60405161031d9190613f4a565b60405180910390f35b61032e6109ab565b60405161033b9190613fa6565b60405180910390f35b61035e60048036038101906103599190614026565b6109d1565b60405161036b9190614131565b60405180910390f35b61038e60048036038101906103899190614294565b610b04565b005b610398610ba0565b6040516103a59190614365565b60405180910390f35b6103c860048036038101906103c391906143bd565b610c32565b6040516103d59190613fa6565b60405180910390f35b6103f860048036038101906103f39190614416565b610c78565b005b610402610d8f565b60405161040f9190614465565b60405180910390f35b610432600480360381019061042d91906143bd565b610d95565b60405161043f9190614365565b60405180910390f35b610462600480360381019061045d9190614480565b610e3a565b005b61047e600480360381019061047991906144d3565b610e9a565b60405161048c929190614513565b60405180910390f35b6104af60048036038101906104aa9190614026565b610f5a565b6040516104bc9190614591565b60405180910390f35b6104df60048036038101906104da9190614609565b611153565b005b6104fb60048036038101906104f6919061468a565b61124f565b005b6105176004803603810190610512919061474f565b6113ab565b005b6105216113f7565b60405161052e9190614365565b60405180910390f35b610551600480360381019061054c9190614416565b611485565b005b61056d60048036038101906105689190614480565b61178f565b005b6105896004803603810190610584919061477c565b6117af565b005b610593611ae2565b6040516105a09190613fa6565b60405180910390f35b6105c360048036038101906105be9190614294565b611b08565b005b6105cd611b2a565b6040516105da9190614365565b60405180910390f35b6105fd60048036038101906105f891906143bd565b611bb8565b60405161060a9190613fa6565b60405180910390f35b61061b611c3e565b6040516106289190614365565b60405180910390f35b61064b6004803603810190610646919061474f565b611ccc565b005b6106676004803603810190610662919061474f565b611d18565b6040516106749190614465565b60405180910390f35b6106976004803603810190610692919061474f565b611d30565b6040516106a49190614465565b60405180910390f35b6106b5611de7565b005b6106bf611dfb565b6040516106cc9190614365565b60405180910390f35b6106dd611e89565b6040516106ea91906148f7565b60405180910390f35b61070d60048036038101906107089190614a9f565b612015565b005b61072960048036038101906107249190614294565b61214b565b005b61074560048036038101906107409190614416565b61216d565b005b61074f612183565b60405161075c9190613fa6565b60405180910390f35b61077f600480360381019061077a9190614294565b6121ad565b005b6107896121cf565b6040516107969190614365565b60405180910390f35b6107b960048036038101906107b491906143bd565b612261565b6040516107c69190613fa6565b60405180910390f35b6107e960048036038101906107e49190614bf8565b612294565b005b61080560048036038101906108009190614ccb565b6123e6565b005b610821600480360381019061081c9190614294565b6123fc565b005b61083d60048036038101906108389190614dac565b61241e565b005b61085960048036038101906108549190614294565b612480565b005b610875600480360381019061087091906143bd565b6124a2565b6040516108829190614365565b60405180910390f35b6108936124b4565b6040516108a09190613fa6565b60405180910390f35b6108b16124da565b6040516108be9190614365565b60405180910390f35b6108e160048036038101906108dc9190614e2f565b612568565b005b6108fd60048036038101906108f89190614e8b565b61259c565b60405161090a9190613f4a565b60405180910390f35b61092d600480360381019061092891906143bd565b612630565b60405161093a9190614365565b60405180910390f35b61095d60048036038101906109589190614026565b6126d0565b005b6109796004803603810190610974919061474f565b61297d565b005b610983612a00565b6040516109909190614365565b60405180910390f35b60006109a482612a8e565b9050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000600982604051610a2e9190614f07565b90815260200160405180910390208054905003610a5657610a5563263d05cc60e01b612b08565b5b60098484604051610a68929190614f43565b9081526020016040518091039020805480602002602001604051908101604052809291908181526020018280548015610af657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610aac575b505050505091505092915050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8b90614fa8565b60405180910390fd5b610b9d81612b12565b50565b606060008054610baf90614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054610bdb90614ff7565b8015610c285780601f10610bfd57610100808354040283529160200191610c28565b820191906000526020600020905b815481529060010190602001808311610c0b57829003601f168201915b5050505050905090565b6000610c3d82612b83565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c8382611bb8565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610cf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cea9061509a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610d12612bce565b73ffffffffffffffffffffffffffffffffffffffff161480610d415750610d4081610d3b612bce565b61259c565b5b610d80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d779061512c565b60405180910390fd5b610d8a8383612bd6565b505050565b600b5481565b6060600f60008381526020019081526020016000208054610db590614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054610de190614ff7565b8015610e2e5780601f10610e0357610100808354040283529160200191610e2e565b820191906000526020600020905b815481529060010190602001808311610e1157829003601f168201915b50505050509050919050565b610e4b610e45612bce565b82612c8f565b610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e81906151be565b60405180910390fd5b610e95838383612d24565b505050565b600080600060086040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900462ffffff1662ffffff1662ffffff1681525050905080600001519250612710816020015162ffffff1685610f46919061520d565b610f509190615296565b9150509250929050565b6060600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000600982604051610fb79190614f07565b90815260200160405180910390208054905003610fdf57610fde63263d05cc60e01b612b08565b5b600060098585604051610ff3929190614f43565b908152602001604051809103902080548060200260200160405190810160405280929190818152602001828054801561108157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611037575b50505050509050600081519050600060405180602001604052806000815250905060005b8281101561114557816111108583815181106110c4576110c36152c7565b5b60200260200101516001808886815181106110e2576110e16152c7565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff163b61110b91906152f6565b61301d565b604051602001611121929190615366565b6040516020818303038152906040529150808061113d9061538a565b9150506110a5565b508094505050505092915050565b61115b613046565b600084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060006009826040516111b69190614f07565b908152602001604051809103902080549050146111de576111dd63aa2fa7cb60e01b612b08565b5b600a81908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190611219929190613be8565b50828260098360405161122c9190614f07565b90815260200160405180910390209190611247929190613c6e565b505050505050565b600080805461125d90614ff7565b90501461129f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112969061541e565b60405180910390fd5b82600090805190602001906112b5929190613d0e565b5085600690805190602001906112cc929190613d0e565b5084600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061135981836130c4565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113a3816131ae565b505050505050565b6113b3613046565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6006805461140490614ff7565b80601f016020809104026020016040519081016040528092919081815260200182805461143090614ff7565b801561147d5780601f106114525761010080835404028352916020019161147d565b820191906000526020600020905b81548152906001019060200180831161146057829003601f168201915b505050505081565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150c90614fa8565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157b9061548a565b60405180910390fd5b61158d81613274565b156115cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c4906154f6565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461161d9190615516565b925050819055506001600b60008282546116379190615516565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808273ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6117aa8383836040518060200160405280600081525061241e565b505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461183f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183690614fa8565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a59061548a565b60405180910390fd5b6118b782613274565b156118f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ee906154f6565b60405180910390fd5b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119479190615516565b925050819055506001600b60008282546119619190615516565b92505081905550826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f600084815260200190815260200160002090805190602001906119e1929190613d0e565b5081600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4818373ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611b10613046565b8060139080519060200190611b26929190613d0e565b5050565b60108054611b3790614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6390614ff7565b8015611bb05780601f10611b8557610100808354040283529160200191611bb0565b820191906000526020600020905b815481529060010190602001808311611b9357829003601f168201915b505050505081565b600080611bc4836132b5565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2c906155b8565b60405180910390fd5b80915050919050565b60138054611c4b90614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7790614ff7565b8015611cc45780601f10611c9957610100808354040283529160200191611cc4565b820191906000526020600020905b815481529060010190602001808311611ca757829003601f168201915b505050505081565b611cd4613046565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60036020528060005260406000206000915090505481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611da0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d979061564a565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611def613046565b611df960006131ae565b565b60118054611e0890614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3490614ff7565b8015611e815780601f10611e5657610100808354040283529160200191611e81565b820191906000526020600020905b815481529060010190602001808311611e6457829003601f168201915b505050505081565b60606000600a805480602002602001604051908101604052809291908181526020016000905b82821015611f5b578382906000526020600020018054611ece90614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054611efa90614ff7565b8015611f475780601f10611f1c57610100808354040283529160200191611f47565b820191906000526020600020905b815481529060010190602001808311611f2a57829003601f168201915b505050505081526020019060010190611eaf565b5050505090506000815167ffffffffffffffff811115611f7e57611f7d614169565b5b604051908082528060200260200182016040528015611fb157816020015b6060815260200190600190039081611f9c5790505b50905060005b825181101561200c57828181518110611fd357611fd26152c7565b5b6020026020010151828281518110611fee57611fed6152c7565b5b602002602001018190525080806120049061538a565b915050611fb7565b50809250505090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146120a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209c90614fa8565b60405180910390fd5b81518151146120e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120e0906156b6565b60405180910390fd5b60005b81518110156121465761213383828151811061210b5761210a6152c7565b5b6020026020010151838381518110612126576121256152c7565b5b6020026020010151611485565b808061213e9061538a565b9150506120ec565b505050565b612153613046565b8060009080519060200190612169929190613d0e565b5050565b612175613046565b61217f82826130c4565b5050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6121b5613046565b80601190805190602001906121cb929190613d0e565b5050565b6060600180546121de90614ff7565b80601f016020809104026020016040519081016040528092919081815260200182805461220a90614ff7565b80156122575780601f1061222c57610100808354040283529160200191612257565b820191906000526020600020905b81548152906001019060200180831161223a57829003601f168201915b5050505050905090565b60026020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231b90614fa8565b60405180910390fd5b8251825114612368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161235f906156b6565b60405180910390fd5b60005b82518110156123e0576123cd84828151811061238a576123896152c7565b5b60200260200101518483815181106123a5576123a46152c7565b5b60200260200101518484815181106123c0576123bf6152c7565b5b60200260200101516117af565b80806123d89061538a565b91505061236b565b50505050565b6123f86123f1612bce565b83836132f2565b5050565b612404613046565b806010908051906020019061241a929190613d0e565b5050565b61242f612429612bce565b83612c8f565b61246e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612465906151be565b60405180910390fd5b61247a8484848461345e565b50505050565b612488613046565b806012908051906020019061249e929190613d0e565b5050565b60606124ad826134ba565b9050919050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080546124e790614ff7565b80601f016020809104026020016040519081016040528092919081815260200182805461251390614ff7565b80156125605780601f1061253557610100808354040283529160200191612560565b820191906000526020600020905b81548152906001019060200180831161254357829003601f168201915b505050505081565b612570613046565b80600f60008481526020019081526020016000209080519060200190612597929190613d0e565b505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600f602052806000526040600020600091509050805461264f90614ff7565b80601f016020809104026020016040519081016040528092919081815260200182805461267b90614ff7565b80156126c85780601f1061269d576101008083540402835291602001916126c8565b820191906000526020600020905b8154815290600101906020018083116126ab57829003601f168201915b505050505081565b6126d8613046565b600082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060006009826040516127339190614f07565b9081526020016040518091039020805490500361275b5761275a63263d05cc60e01b612b08565b5b6000600a805480602002602001604051908101604052809291908181526020016000905b8282101561282b57838290600052602060002001805461279e90614ff7565b80601f01602080910402602001604051908101604052809291908181526020018280546127ca90614ff7565b80156128175780601f106127ec57610100808354040283529160200191612817565b820191906000526020600020905b8154815290600101906020018083116127fa57829003601f168201915b50505050508152602001906001019061277f565b50505050905060006001825161284191906152f6565b67ffffffffffffffff81111561285a57612859614169565b5b60405190808252806020026020018201604052801561288d57816020015b60608152602001906001900390816128785790505b5090506000808351905060005b818110156129325785805190602001208582815181106128bd576128bc6152c7565b5b602002602001015180519060200120036128da576001925061291f565b8481815181106128ed576128ec6152c7565b5b602002602001015184848361290291906152f6565b81518110612913576129126152c7565b5b60200260200101819052505b808061292a9061538a565b91505061289a565b5082600a9080519060200190612949929190613d94565b5060098560405161295a9190614f07565b908152602001604051809103902060006129749190613df4565b50505050505050565b612985613046565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036129f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129eb90615748565b60405180910390fd5b6129fd816131ae565b50565b60128054612a0d90614ff7565b80601f0160208091040260200160405190810160405280929190818152602001828054612a3990614ff7565b8015612a865780601f10612a5b57610100808354040283529160200191612a86565b820191906000526020600020905b815481529060010190602001808311612a6957829003601f168201915b505050505081565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612b015750612b00826135a5565b5b9050919050565b8060005260046000fd5b8060069080519060200190612b28929190613d0e565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604051612b789190614465565b60405180910390a150565b612b8c81613274565b612bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc2906155b8565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612c4983611bb8565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080612c9b83611bb8565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612cdd5750612cdc818561259c565b5b80612d1b57508373ffffffffffffffffffffffffffffffffffffffff16612d0384610c32565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612d4482611bb8565b73ffffffffffffffffffffffffffffffffffffffff1614612d9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d91906157da565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e009061586c565b60405180910390fd5b612e168383836001613687565b8273ffffffffffffffffffffffffffffffffffffffff16612e3682611bb8565b73ffffffffffffffffffffffffffffffffffffffff1614612e8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e83906157da565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461301883838360016137ad565b505050565b60606040519050601f19601f6020840101168101604052818152818360208301863c9392505050565b61304e612bce565b73ffffffffffffffffffffffffffffffffffffffff1661306c612183565b73ffffffffffffffffffffffffffffffffffffffff16146130c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130b9906158d8565b60405180910390fd5b565b612710811115613109576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161310090615944565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff1681526020018262ffffff16815250600860008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548162ffffff021916908362ffffff1602179055509050505050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008073ffffffffffffffffffffffffffffffffffffffff16613296836132b5565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613360576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613357906159b0565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516134519190613f4a565b60405180910390a3505050565b613469848484612d24565b613475848484846137b3565b6134b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134ab90615a42565b60405180910390fd5b50505050565b60606134c582612b83565b6000600680546134d490614ff7565b80601f016020809104026020016040519081016040528092919081815260200182805461350090614ff7565b801561354d5780601f106135225761010080835404028352916020019161354d565b820191906000526020600020905b81548152906001019060200180831161353057829003601f168201915b505050505090506000815111613572576040518060200160405280600081525061359d565b8061357c8461393a565b60405160200161358d929190615a88565b6040516020818303038152906040525b915050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061367057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613680575061367f82613a08565b5b9050919050565b60018111156137a757600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461371b5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461371391906152f6565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146137a65780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461379e9190615516565b925050819055505b5b50505050565b50505050565b60006137d48473ffffffffffffffffffffffffffffffffffffffff16613a72565b1561392d578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026137fd612bce565b8786866040518563ffffffff1660e01b815260040161381f9493929190615abb565b6020604051808303816000875af192505050801561385b57506040513d601f19601f820116820180604052508101906138589190615b1c565b60015b6138dd573d806000811461388b576040519150601f19603f3d011682016040523d82523d6000602084013e613890565b606091505b5060008151036138d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138cc90615a42565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613932565b600190505b949350505050565b60606000600161394984613a95565b01905060008167ffffffffffffffff81111561396857613967614169565b5b6040519080825280601f01601f19166020018201604052801561399a5781602001600182028036833780820191505090505b509050600082602001820190505b6001156139fd578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816139f1576139f0615267565b5b049450600085036139a8575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613af3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ae957613ae8615267565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613b30576d04ee2d6d415b85acef81000000008381613b2657613b25615267565b5b0492506020810190505b662386f26fc100008310613b5f57662386f26fc100008381613b5557613b54615267565b5b0492506010810190505b6305f5e1008310613b88576305f5e1008381613b7e57613b7d615267565b5b0492506008810190505b6127108310613bad576127108381613ba357613ba2615267565b5b0492506004810190505b60648310613bd05760648381613bc657613bc5615267565b5b0492506002810190505b600a8310613bdf576001810190505b80915050919050565b828054613bf490614ff7565b90600052602060002090601f016020900481019282613c165760008555613c5d565b82601f10613c2f57805160ff1916838001178555613c5d565b82800160010185558215613c5d579182015b82811115613c5c578251825591602001919060010190613c41565b5b509050613c6a9190613e15565b5090565b828054828255906000526020600020908101928215613cfd579160200282015b82811115613cfc57823573ffffffffffffffffffffffffffffffffffffffff168260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190613c8e565b5b509050613d0a9190613e15565b5090565b828054613d1a90614ff7565b90600052602060002090601f016020900481019282613d3c5760008555613d83565b82601f10613d5557805160ff1916838001178555613d83565b82800160010185558215613d83579182015b82811115613d82578251825591602001919060010190613d67565b5b509050613d909190613e15565b5090565b828054828255906000526020600020908101928215613de3579160200282015b82811115613de2578251829080519060200190613dd2929190613be8565b5091602001919060010190613db4565b5b509050613df09190613e32565b5090565b5080546000825590600052602060002090810190613e129190613e15565b50565b5b80821115613e2e576000816000905550600101613e16565b5090565b5b80821115613e525760008181613e499190613e56565b50600101613e33565b5090565b508054613e6290614ff7565b6000825580601f10613e745750613e93565b601f016020900490600052602060002090810190613e929190613e15565b5b50565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613edf81613eaa565b8114613eea57600080fd5b50565b600081359050613efc81613ed6565b92915050565b600060208284031215613f1857613f17613ea0565b5b6000613f2684828501613eed565b91505092915050565b60008115159050919050565b613f4481613f2f565b82525050565b6000602082019050613f5f6000830184613f3b565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f9082613f65565b9050919050565b613fa081613f85565b82525050565b6000602082019050613fbb6000830184613f97565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613fe657613fe5613fc1565b5b8235905067ffffffffffffffff81111561400357614002613fc6565b5b60208301915083600182028301111561401f5761401e613fcb565b5b9250929050565b6000806020838503121561403d5761403c613ea0565b5b600083013567ffffffffffffffff81111561405b5761405a613ea5565b5b61406785828601613fd0565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6140a881613f85565b82525050565b60006140ba838361409f565b60208301905092915050565b6000602082019050919050565b60006140de82614073565b6140e8818561407e565b93506140f38361408f565b8060005b8381101561412457815161410b88826140ae565b9750614116836140c6565b9250506001810190506140f7565b5085935050505092915050565b6000602082019050818103600083015261414b81846140d3565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6141a182614158565b810181811067ffffffffffffffff821117156141c0576141bf614169565b5b80604052505050565b60006141d3613e96565b90506141df8282614198565b919050565b600067ffffffffffffffff8211156141ff576141fe614169565b5b61420882614158565b9050602081019050919050565b82818337600083830152505050565b6000614237614232846141e4565b6141c9565b90508281526020810184848401111561425357614252614153565b5b61425e848285614215565b509392505050565b600082601f83011261427b5761427a613fc1565b5b813561428b848260208601614224565b91505092915050565b6000602082840312156142aa576142a9613ea0565b5b600082013567ffffffffffffffff8111156142c8576142c7613ea5565b5b6142d484828501614266565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156143175780820151818401526020810190506142fc565b83811115614326576000848401525b50505050565b6000614337826142dd565b61434181856142e8565b93506143518185602086016142f9565b61435a81614158565b840191505092915050565b6000602082019050818103600083015261437f818461432c565b905092915050565b6000819050919050565b61439a81614387565b81146143a557600080fd5b50565b6000813590506143b781614391565b92915050565b6000602082840312156143d3576143d2613ea0565b5b60006143e1848285016143a8565b91505092915050565b6143f381613f85565b81146143fe57600080fd5b50565b600081359050614410816143ea565b92915050565b6000806040838503121561442d5761442c613ea0565b5b600061443b85828601614401565b925050602061444c858286016143a8565b9150509250929050565b61445f81614387565b82525050565b600060208201905061447a6000830184614456565b92915050565b60008060006060848603121561449957614498613ea0565b5b60006144a786828701614401565b93505060206144b886828701614401565b92505060406144c9868287016143a8565b9150509250925092565b600080604083850312156144ea576144e9613ea0565b5b60006144f8858286016143a8565b9250506020614509858286016143a8565b9150509250929050565b60006040820190506145286000830185613f97565b6145356020830184614456565b9392505050565b600081519050919050565b600082825260208201905092915050565b60006145638261453c565b61456d8185614547565b935061457d8185602086016142f9565b61458681614158565b840191505092915050565b600060208201905081810360008301526145ab8184614558565b905092915050565b60008083601f8401126145c9576145c8613fc1565b5b8235905067ffffffffffffffff8111156145e6576145e5613fc6565b5b60208301915083602082028301111561460257614601613fcb565b5b9250929050565b6000806000806040858703121561462357614622613ea0565b5b600085013567ffffffffffffffff81111561464157614640613ea5565b5b61464d87828801613fd0565b9450945050602085013567ffffffffffffffff8111156146705761466f613ea5565b5b61467c878288016145b3565b925092505092959194509250565b60008060008060008060c087890312156146a7576146a6613ea0565b5b600087013567ffffffffffffffff8111156146c5576146c4613ea5565b5b6146d189828a01614266565b96505060206146e289828a01614401565b95505060406146f389828a01614401565b945050606087013567ffffffffffffffff81111561471457614713613ea5565b5b61472089828a01614266565b935050608061473189828a016143a8565b92505060a061474289828a01614401565b9150509295509295509295565b60006020828403121561476557614764613ea0565b5b600061477384828501614401565b91505092915050565b60008060006060848603121561479557614794613ea0565b5b60006147a386828701614401565b93505060206147b4868287016143a8565b925050604084013567ffffffffffffffff8111156147d5576147d4613ea5565b5b6147e186828701614266565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b6000614833826142dd565b61483d8185614817565b935061484d8185602086016142f9565b61485681614158565b840191505092915050565b600061486d8383614828565b905092915050565b6000602082019050919050565b600061488d826147eb565b61489781856147f6565b9350836020820285016148a985614807565b8060005b858110156148e557848403895281516148c68582614861565b94506148d183614875565b925060208a019950506001810190506148ad565b50829750879550505050505092915050565b600060208201905081810360008301526149118184614882565b905092915050565b600067ffffffffffffffff82111561493457614933614169565b5b602082029050602081019050919050565b600061495861495384614919565b6141c9565b9050808382526020820190506020840283018581111561497b5761497a613fcb565b5b835b818110156149a457806149908882614401565b84526020840193505060208101905061497d565b5050509392505050565b600082601f8301126149c3576149c2613fc1565b5b81356149d3848260208601614945565b91505092915050565b600067ffffffffffffffff8211156149f7576149f6614169565b5b602082029050602081019050919050565b6000614a1b614a16846149dc565b6141c9565b90508083825260208201905060208402830185811115614a3e57614a3d613fcb565b5b835b81811015614a675780614a5388826143a8565b845260208401935050602081019050614a40565b5050509392505050565b600082601f830112614a8657614a85613fc1565b5b8135614a96848260208601614a08565b91505092915050565b60008060408385031215614ab657614ab5613ea0565b5b600083013567ffffffffffffffff811115614ad457614ad3613ea5565b5b614ae0858286016149ae565b925050602083013567ffffffffffffffff811115614b0157614b00613ea5565b5b614b0d85828601614a71565b9150509250929050565b600067ffffffffffffffff821115614b3257614b31614169565b5b602082029050602081019050919050565b6000614b56614b5184614b17565b6141c9565b90508083825260208201905060208402830185811115614b7957614b78613fcb565b5b835b81811015614bc057803567ffffffffffffffff811115614b9e57614b9d613fc1565b5b808601614bab8982614266565b85526020850194505050602081019050614b7b565b5050509392505050565b600082601f830112614bdf57614bde613fc1565b5b8135614bef848260208601614b43565b91505092915050565b600080600060608486031215614c1157614c10613ea0565b5b600084013567ffffffffffffffff811115614c2f57614c2e613ea5565b5b614c3b868287016149ae565b935050602084013567ffffffffffffffff811115614c5c57614c5b613ea5565b5b614c6886828701614a71565b925050604084013567ffffffffffffffff811115614c8957614c88613ea5565b5b614c9586828701614bca565b9150509250925092565b614ca881613f2f565b8114614cb357600080fd5b50565b600081359050614cc581614c9f565b92915050565b60008060408385031215614ce257614ce1613ea0565b5b6000614cf085828601614401565b9250506020614d0185828601614cb6565b9150509250929050565b600067ffffffffffffffff821115614d2657614d25614169565b5b614d2f82614158565b9050602081019050919050565b6000614d4f614d4a84614d0b565b6141c9565b905082815260208101848484011115614d6b57614d6a614153565b5b614d76848285614215565b509392505050565b600082601f830112614d9357614d92613fc1565b5b8135614da3848260208601614d3c565b91505092915050565b60008060008060808587031215614dc657614dc5613ea0565b5b6000614dd487828801614401565b9450506020614de587828801614401565b9350506040614df6878288016143a8565b925050606085013567ffffffffffffffff811115614e1757614e16613ea5565b5b614e2387828801614d7e565b91505092959194509250565b60008060408385031215614e4657614e45613ea0565b5b6000614e54858286016143a8565b925050602083013567ffffffffffffffff811115614e7557614e74613ea5565b5b614e8185828601614266565b9150509250929050565b60008060408385031215614ea257614ea1613ea0565b5b6000614eb085828601614401565b9250506020614ec185828601614401565b9150509250929050565b600081905092915050565b6000614ee18261453c565b614eeb8185614ecb565b9350614efb8185602086016142f9565b80840191505092915050565b6000614f138284614ed6565b915081905092915050565b6000614f2a8385614ecb565b9350614f37838584614215565b82840190509392505050565b6000614f50828486614f1e565b91508190509392505050565b7f5065726d697373696f6e2064656e696564000000000000000000000000000000600082015250565b6000614f926011836142e8565b9150614f9d82614f5c565b602082019050919050565b60006020820190508181036000830152614fc181614f85565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061500f57607f821691505b60208210810361502257615021614fc8565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006150846021836142e8565b915061508f82615028565b604082019050919050565b600060208201905081810360008301526150b381615077565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000615116603d836142e8565b9150615121826150ba565b604082019050919050565b6000602082019050818103600083015261514581615109565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b60006151a8602d836142e8565b91506151b38261514c565b604082019050919050565b600060208201905081810360008301526151d78161519b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061521882614387565b915061522383614387565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561525c5761525b6151de565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006152a182614387565b91506152ac83614387565b9250826152bc576152bb615267565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061530182614387565b915061530c83614387565b92508282101561531f5761531e6151de565b5b828203905092915050565b600081905092915050565b6000615340826142dd565b61534a818561532a565b935061535a8185602086016142f9565b80840191505092915050565b60006153728285614ed6565b915061537e8284615335565b91508190509392505050565b600061539582614387565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153c7576153c66151de565b5b600182019050919050565b7f416c726561647920696e697469616c697a656400000000000000000000000000600082015250565b60006154086013836142e8565b9150615413826153d2565b602082019050919050565b60006020820190508181036000830152615437816153fb565b9050919050565b7f6d696e7420746f20746865207a65726f20616464726573730000000000000000600082015250565b60006154746018836142e8565b915061547f8261543e565b602082019050919050565b600060208201905081810360008301526154a381615467565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006154e0601c836142e8565b91506154eb826154aa565b602082019050919050565b6000602082019050818103600083015261550f816154d3565b9050919050565b600061552182614387565b915061552c83614387565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615561576155606151de565b5b828201905092915050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006155a26018836142e8565b91506155ad8261556c565b602082019050919050565b600060208201905081810360008301526155d181615595565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006156346029836142e8565b915061563f826155d8565b604082019050919050565b6000602082019050818103600083015261566381615627565b9050919050565b7f417272617973206c656e677468206d69736d6174636800000000000000000000600082015250565b60006156a06016836142e8565b91506156ab8261566a565b602082019050919050565b600060208201905081810360008301526156cf81615693565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006157326026836142e8565b915061573d826156d6565b604082019050919050565b6000602082019050818103600083015261576181615725565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006157c46025836142e8565b91506157cf82615768565b604082019050919050565b600060208201905081810360008301526157f3816157b7565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006158566024836142e8565b9150615861826157fa565b604082019050919050565b6000602082019050818103600083015261588581615849565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006158c26020836142e8565b91506158cd8261588c565b602082019050919050565b600060208201905081810360008301526158f1816158b5565b9050919050565b7f45524332393831526f79616c746965733a20546f6f2068696768000000000000600082015250565b600061592e601a836142e8565b9150615939826158f8565b602082019050919050565b6000602082019050818103600083015261595d81615921565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061599a6019836142e8565b91506159a582615964565b602082019050919050565b600060208201905081810360008301526159c98161598d565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000615a2c6032836142e8565b9150615a37826159d0565b604082019050919050565b60006020820190508181036000830152615a5b81615a1f565b9050919050565b7f2f00000000000000000000000000000000000000000000000000000000000000815250565b6000615a948285615335565b9150615a9f82615a62565b600182019150615aaf8284615335565b91508190509392505050565b6000608082019050615ad06000830187613f97565b615add6020830186613f97565b615aea6040830185614456565b8181036060830152615afc8184614558565b905095945050505050565b600081519050615b1681613ed6565b92915050565b600060208284031215615b3257615b31613ea0565b5b6000615b4084828501615b07565b9150509291505056fea2646970667358221220981fd8f70a284ee0024e32c71d3471b0d5aa56be45dc3583a7393f47519fe74f64736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806366f8f34714610030575b600080fd5b61004a600480360381019061004591906103d6565b61004c565b005b60006100777f000000000000000000000000a968ab882ad106b14c3d2c60686315a7c4d0d2f461012e565b90508073ffffffffffffffffffffffffffffffffffffffff1663378dfba48888888888886040518763ffffffff1660e01b81526004016100bc96959493929190610541565b600060405180830381600087803b1580156100d657600080fd5b505af11580156100ea573d6000803e3d6000fd5b505050507f703fdf4fec8b6ba710f9f4fa396f0ea0045ee5f6bf7be6e4d49f4f5ea0d927468160405161011d91906105b0565b60405180910390a150505050505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f09050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101da90610617565b60405180910390fd5b919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61024f82610206565b810181811067ffffffffffffffff8211171561026e5761026d610217565b5b80604052505050565b60006102816101e8565b905061028d8282610246565b919050565b600067ffffffffffffffff8211156102ad576102ac610217565b5b6102b682610206565b9050602081019050919050565b82818337600083830152505050565b60006102e56102e084610292565b610277565b90508281526020810184848401111561030157610300610201565b5b61030c8482856102c3565b509392505050565b600082601f830112610329576103286101fc565b5b81356103398482602086016102d2565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061036d82610342565b9050919050565b61037d81610362565b811461038857600080fd5b50565b60008135905061039a81610374565b92915050565b6000819050919050565b6103b3816103a0565b81146103be57600080fd5b50565b6000813590506103d0816103aa565b92915050565b60008060008060008060c087890312156103f3576103f26101f2565b5b600087013567ffffffffffffffff811115610411576104106101f7565b5b61041d89828a01610314565b965050602061042e89828a0161038b565b955050604061043f89828a0161038b565b945050606087013567ffffffffffffffff8111156104605761045f6101f7565b5b61046c89828a01610314565b935050608061047d89828a016103c1565b92505060a061048e89828a0161038b565b9150509295509295509295565b600081519050919050565b600082825260208201905092915050565b60005b838110156104d55780820151818401526020810190506104ba565b838111156104e4576000848401525b50505050565b60006104f58261049b565b6104ff81856104a6565b935061050f8185602086016104b7565b61051881610206565b840191505092915050565b61052c81610362565b82525050565b61053b816103a0565b82525050565b600060c082019050818103600083015261055b81896104ea565b905061056a6020830188610523565b6105776040830187610523565b818103606083015261058981866104ea565b90506105986080830185610532565b6105a560a0830184610523565b979650505050505050565b60006020820190506105c56000830184610523565b92915050565b7f455243313136373a20637265617465206661696c656400000000000000000000600082015250565b60006106016016836104a6565b915061060c826105cb565b602082019050919050565b60006020820190508181036000830152610630816105f4565b905091905056fea2646970667358221220fd634f15fa353faab3b809bace484cc91ff9d3201d9ad042e42812a86b2e01ff64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.