[ Download CSV Export ]
OVERVIEW
Raves Names is the first Web3 username system, and the first FNS on Fantom.
Latest 25 internal transaction
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x3951d7f2cc9b1693677b7c3ed2b05680c20b5f52
Contract Name:
Rave
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlisence pragma solidity >=0.8.16; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./string.sol"; import "hardhat/console.sol"; import {FantomsArtNameSystem as RaveV1} from "./Rave.sol"; import {RaveURIGenerator as URI} from "./RaveURIGenerator.sol"; interface wFTM is IERC20 { function deposit() external payable returns (uint256); } contract Rave is ERC721, ERC721Enumerable, Ownable { using Counters for Counters.Counter; using strings for *; uint public price; string public extension; Counters.Counter private _tokenIdCounter; address public treasury = 0x87f385d152944689f92Ed523e9e5E9Bd58Ea62ef; wFTM private wftm = wFTM(0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83); address public uri; mapping(bytes32 => bool) regsitered; mapping(uint256 => RaveName) tokenIdName; mapping(bytes32 => uint256) nameToTokenId; struct RaveName { string name; uint tokenId; string addresses; string avatar; } event Registered(string indexed name, address owner); event SetAddresses(string indexed name, string addresses); event SetAvatar(string indexed name, string avatar); event SetURI(address uri); event Migration(); constructor( string memory _extension, uint _price, address _uri ) ERC721(string.concat(string.concat("Rave Names .", _extension), " registry"), string.concat(".", _extension)) { price = _price; extension = _extension; uri = _uri; } // @notice Makes a keccak256 hash of a string // @param input string function _makeHash( string memory input ) internal pure returns(bytes32) { return keccak256(abi.encode(input)); } // @notice Makes a character lowercase // @param input char function __lower( bytes1 _b1 ) private pure returns (bytes1) { if (_b1 >= 0x41 && _b1 <= 0x5A) { return bytes1(uint8(_b1) + 32); } return _b1; } // @notice Makes a string lowercase // @param input string function _lower( string memory _base ) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { _baseBytes[i] = __lower(_baseBytes[i]); } return string(_baseBytes); } // @notice Register a name // @param name to register function registerName( string memory _name ) public payable { require(msg.value >= price, "Rave: You must pay the full price."); wftm.deposit{ value: msg.value }(); wftm.transfer(treasury, wftm.balanceOf(address(this))); string memory name = _lower(string.concat( string.concat(_name, "."), extension )); bytes32 _hashedName = _makeHash(name); require(!(regsitered[_hashedName]), "Rave: You cant register a name thats already owned."); RaveName memory constructedName = RaveName( name, _tokenIdCounter.current(), "", "" ); regsitered[_hashedName] = true; tokenIdName[_tokenIdCounter.current()] = constructedName; nameToTokenId[_hashedName] = _tokenIdCounter.current(); _safeMint(msg.sender, _tokenIdCounter.current()); _tokenIdCounter.increment(); emit Registered(name, msg.sender); } // @notice Register an array of names // @param names to register function bulkRegister( string[] memory names ) external payable { for (uint i = 0; i < names.length;) { registerName(names[i]); unchecked { i++; } } } // @notice register a name and send it to another address // @param name to register // @param address to send to function registerNameAndSend( string memory _name, address sendTo ) public payable { require(msg.value >= price, "Rave: You must pay the full price."); wftm.deposit{ value: msg.value }(); wftm.transfer(treasury, wftm.balanceOf(address(this))); string memory name = _lower(string.concat( string.concat(_name, "."), extension )); bytes32 _hashedName = _makeHash(name); require(!(regsitered[_hashedName]), string.concat("Rave: You cant register a name thats already owned: ", name)); RaveName memory constructedName = RaveName( name, _tokenIdCounter.current(), "", "" ); regsitered[_hashedName] = true; tokenIdName[_tokenIdCounter.current()] = constructedName; nameToTokenId[_hashedName] = _tokenIdCounter.current(); _safeMint(sendTo, _tokenIdCounter.current()); _tokenIdCounter.increment(); emit Registered(name, sendTo); } // @notice register multiple names and send to addresses // @param names to register // @param addresses to send to function bulkRegisterAndSend( string[] memory names, address[] memory addresses ) external payable { require(names.length == addresses.length, "Rave: The amount of addresses must be equal to the amount of names."); for (uint i = 0; i < names.length;) { registerNameAndSend(names[i], addresses[i]); unchecked { i++; } } } // @notice set multichain addresses // @param name to edit // @param addresses function setAddresses( string memory _name, string memory addresses ) external { string memory name = _lower(_name); bytes32 _hashedName = _makeHash(name); require(ownerOf(nameToTokenId[_hashedName]) == msg.sender, "Rave: You must own the name to set the addresses."); tokenIdName[nameToTokenId[_hashedName]].addresses = addresses; emit SetAddresses(name, addresses); } // @notice set avatar // @param name to edit // @param avatar URL function setAvatar( string memory _name, string memory avatar ) external { string memory name = _lower(_name); bytes32 _hashedName = _makeHash(name); require(ownerOf(nameToTokenId[_hashedName]) == msg.sender, "Rave: You must own the name to set the avatar."); tokenIdName[nameToTokenId[_hashedName]].avatar = avatar; emit SetAvatar(name, avatar); } function owned( string memory name ) external view returns(bool) { return regsitered[_makeHash(_lower(name))]; } function getAddresses( string memory name ) external view returns(string memory) { return tokenIdName[nameToTokenId[_makeHash(_lower(name))]].addresses; } function getAvatar( string memory name ) external view returns(string memory) { return tokenIdName[nameToTokenId[_makeHash(_lower(name))]].avatar; } function getOwner( string memory name ) external view returns(address) { return ownerOf(nameToTokenId[_makeHash(_lower(name))]); } function getName( address owner, uint index ) external view returns(string memory) { return tokenIdName[tokenOfOwnerByIndex(owner, index)].name; } function setURI( address newUri ) external onlyOwner { uri = newUri; emit SetURI(newUri); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function getNames( address owner ) external view returns(string[] memory) { string[] memory names = new string[](balanceOf(owner)); for (uint i = 0; i < balanceOf(owner);) { names[i] = (tokenIdName[tokenOfOwnerByIndex(owner, i)].name); unchecked { i++; } } return names; } function safeTransferFrom( address from, address to, string memory name ) external { safeTransferFrom(from, to, nameToTokenId[_makeHash(name)]); } function transferFrom( address from, address to, string memory name ) external { transferFrom(from, to, nameToTokenId[_makeHash(name)]); } function tokenURI( uint256 tokenId ) override public view returns (string memory) { return URI(uri).generate(tokenIdName[tokenId].name); } function changeName( string memory name ) public view returns(string memory) { if (name.toSlice().endsWith(".FTM".toSlice())) { return (_lower(name).toSlice().until(".ftm".toSlice())).toString(); } else { return name; } } function migrate( address ravev1, uint startAt, uint endAt ) external onlyOwner { require(_makeHash(extension) == _makeHash("ftm"), "Rave: You can only migrate .ftm names"); uint p = price; price = 0; for (uint i = startAt; i < endAt;) { // @dev removes .ftm from the end of a name string memory name = RaveV1(ravev1).getNameFromOwner(RaveV1(ravev1).ownerOf(i)); name = changeName(name); registerNameAndSend( name, RaveV1(ravev1).ownerOf(i) ); unchecked { i++; } } price = p; emit Migration(); } function f( uint p ) external onlyOwner { price = p; } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer( from, to, tokenId ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/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 private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _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; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @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 = _owners[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(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @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 nor 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 nor 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 nor 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 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 _owners[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 Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @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); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @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); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @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. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: Apache-2.0 library strings { struct slice { uint _len; uint _ptr; } function memcpy(uint dest, uint src, uint len) private pure { // Copy word-length chunks while possible for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = type(uint).max; if (len > 0) { mask = 256 ** (32 - len) - 1; } assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /* * @dev Returns a slice containing the entire string. * @param self The string to make a slice from. * @return A newly allocated slice containing the entire string. */ function toSlice(string memory self) internal pure returns (slice memory) { uint ptr; assembly { ptr := add(self, 0x20) } return slice(bytes(self).length, ptr); } /* * @dev Returns the length of a null-terminated bytes32 string. * @param self The value to find the length of. * @return The length of the string, from 0 to 32. */ function len(bytes32 self) internal pure returns (uint) { uint ret; if (self == 0) return 0; if (uint(self) & type(uint128).max == 0) { ret += 16; self = bytes32(uint(self) / 0x100000000000000000000000000000000); } if (uint(self) & type(uint64).max == 0) { ret += 8; self = bytes32(uint(self) / 0x10000000000000000); } if (uint(self) & type(uint32).max == 0) { ret += 4; self = bytes32(uint(self) / 0x100000000); } if (uint(self) & type(uint16).max == 0) { ret += 2; self = bytes32(uint(self) / 0x10000); } if (uint(self) & type(uint8).max == 0) { ret += 1; } return 32 - ret; } /* * @dev Returns a slice containing the entire bytes32, interpreted as a * null-terminated utf-8 string. * @param self The bytes32 value to convert to a slice. * @return A new slice containing the value of the input argument up to the * first null. */ function toSliceB32(bytes32 self) internal pure returns (slice memory ret) { // Allocate space for `self` in memory, copy it there, and point ret at it assembly { let ptr := mload(0x40) mstore(0x40, add(ptr, 0x20)) mstore(ptr, self) mstore(add(ret, 0x20), ptr) } ret._len = len(self); } /* * @dev Returns a new slice containing the same data as the current slice. * @param self The slice to copy. * @return A new slice containing the same data as `self`. */ function copy(slice memory self) internal pure returns (slice memory) { return slice(self._len, self._ptr); } /* * @dev Copies a slice to a new string. * @param self The slice to copy. * @return A newly allocated string containing the slice's text. */ function toString(slice memory self) internal pure returns (string memory) { string memory ret = new string(self._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); return ret; } /* * @dev Returns the length in runes of the slice. Note that this operation * takes time proportional to the length of the slice; avoid using it * in loops, and call `slice.empty()` if you only need to know whether * the slice is empty or not. * @param self The slice to operate on. * @return The length of the slice in runes. */ function len(slice memory self) internal pure returns (uint l) { // Starting at ptr-31 means the LSB will be the byte we care about uint ptr = self._ptr - 31; uint end = ptr + self._len; for (l = 0; ptr < end; l++) { uint8 b; assembly { b := and(mload(ptr), 0xFF) } if (b < 0x80) { ptr += 1; } else if(b < 0xE0) { ptr += 2; } else if(b < 0xF0) { ptr += 3; } else if(b < 0xF8) { ptr += 4; } else if(b < 0xFC) { ptr += 5; } else { ptr += 6; } } } /* * @dev Returns true if the slice is empty (has a length of 0). * @param self The slice to operate on. * @return True if the slice is empty, False otherwise. */ function empty(slice memory self) internal pure returns (bool) { return self._len == 0; } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two slices are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first slice to compare. * @param other The second slice to compare. * @return The result of the comparison. */ function compare(slice memory self, slice memory other) internal pure returns (int) { uint shortest = self._len; if (other._len < self._len) shortest = other._len; uint selfptr = self._ptr; uint otherptr = other._ptr; for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask = type(uint).max; // 0xffff... if(shortest < 32) { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } unchecked { uint diff = (a & mask) - (b & mask); if (diff != 0) return int(diff); } } selfptr += 32; otherptr += 32; } return int(self._len) - int(other._len); } /* * @dev Returns true if the two slices contain the same text. * @param self The first slice to compare. * @param self The second slice to compare. * @return True if the slices are equal, false otherwise. */ function equals(slice memory self, slice memory other) internal pure returns (bool) { return compare(self, other) == 0; } /* * @dev Extracts the first rune in the slice into `rune`, advancing the * slice to point to the next rune and returning `self`. * @param self The slice to operate on. * @param rune The slice that will contain the first rune. * @return `rune`. */ function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) { rune._ptr = self._ptr; if (self._len == 0) { rune._len = 0; return rune; } uint l; uint b; // Load the first byte of the rune into the LSBs of b assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) } if (b < 0x80) { l = 1; } else if(b < 0xE0) { l = 2; } else if(b < 0xF0) { l = 3; } else { l = 4; } // Check for truncated codepoints if (l > self._len) { rune._len = self._len; self._ptr += self._len; self._len = 0; return rune; } self._ptr += l; self._len -= l; rune._len = l; return rune; } /* * @dev Returns the first rune in the slice, advancing the slice to point * to the next rune. * @param self The slice to operate on. * @return A slice containing only the first rune from `self`. */ function nextRune(slice memory self) internal pure returns (slice memory ret) { nextRune(self, ret); } /* * @dev Returns the number of the first codepoint in the slice. * @param self The slice to operate on. * @return The number of the first codepoint in the slice. */ function ord(slice memory self) internal pure returns (uint ret) { if (self._len == 0) { return 0; } uint word; uint length; uint divisor = 2 ** 248; // Load the rune into the MSBs of b assembly { word:= mload(mload(add(self, 32))) } uint b = word / divisor; if (b < 0x80) { ret = b; length = 1; } else if(b < 0xE0) { ret = b & 0x1F; length = 2; } else if(b < 0xF0) { ret = b & 0x0F; length = 3; } else { ret = b & 0x07; length = 4; } // Check for truncated codepoints if (length > self._len) { return 0; } for (uint i = 1; i < length; i++) { divisor = divisor / 256; b = (word / divisor) & 0xFF; if (b & 0xC0 != 0x80) { // Invalid UTF-8 sequence return 0; } ret = (ret * 64) | (b & 0x3F); } return ret; } /* * @dev Returns the keccak-256 hash of the slice. * @param self The slice to hash. * @return The hash of the slice. */ function keccak(slice memory self) internal pure returns (bytes32 ret) { assembly { ret := keccak256(mload(add(self, 32)), mload(self)) } } /* * @dev Returns true if `self` starts with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function startsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } if (self._ptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` starts with `needle`, `needle` is removed from the * beginning of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } bool equal = true; if (self._ptr != needle._ptr) { assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; self._ptr += needle._len; } return self; } /* * @dev Returns true if the slice ends with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function endsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } uint selfptr = self._ptr + self._len - needle._len; if (selfptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` ends with `needle`, `needle` is removed from the * end of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function until(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } uint selfptr = self._ptr + self._len - needle._len; bool equal = true; if (selfptr != needle._ptr) { assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; } return self; } // Returns the memory address of the first byte of the first occurrence of // `needle` in `self`, or the first byte after `self` if not found. function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr = selfptr; uint idx; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask; if (needlelen > 0) { mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); } bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } uint end = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr >= end) return selfptr + selflen; ptr++; assembly { ptrdata := and(mload(ptr), mask) } } return ptr; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } for (idx = 0; idx <= selflen - needlelen; idx++) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr; ptr += 1; } } } return selfptr + selflen; } // Returns the memory address of the first byte after the last occurrence of // `needle` in `self`, or the address of `self` if not found. function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask; if (needlelen > 0) { mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); } bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } ptr = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr <= selfptr) return selfptr; ptr--; assembly { ptrdata := and(mload(ptr), mask) } } return ptr + needlelen; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } ptr = selfptr + (selflen - needlelen); while (ptr >= selfptr) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr + needlelen; ptr -= 1; } } } return selfptr; } /* * @dev Modifies `self` to contain everything from the first occurrence of * `needle` to the end of the slice. `self` is set to the empty slice * if `needle` is not found. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function find(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); self._len -= ptr - self._ptr; self._ptr = ptr; return self; } /* * @dev Modifies `self` to contain the part of the string from the start of * `self` to the end of the first occurrence of `needle`. If `needle` * is not found, `self` is set to the empty slice. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); self._len = ptr - self._ptr; return self; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and `token` to everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = self._ptr; token._len = ptr - self._ptr; if (ptr == self._ptr + self._len) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; self._ptr = ptr + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and returning everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` up to the first occurrence of `delim`. */ function split(slice memory self, slice memory needle) internal pure returns (slice memory token) { split(self, needle, token); } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and `token` to everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = ptr; token._len = self._len - (ptr - self._ptr); if (ptr == self._ptr) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and returning everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` after the last occurrence of `delim`. */ function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) { rsplit(self, needle, token); } /* * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return The number of occurrences of `needle` found in `self`. */ function count(slice memory self, slice memory needle) internal pure returns (uint cnt) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; while (ptr <= self._ptr + self._len) { cnt++; ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len; } } /* * @dev Returns True if `self` contains `needle`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return True if `needle` is found in `self`, false otherwise. */ function contains(slice memory self, slice memory needle) internal pure returns (bool) { return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; } /* * @dev Returns a newly allocated string containing the concatenation of * `self` and `other`. * @param self The first slice to concatenate. * @param other The second slice to concatenate. * @return The concatenation of the two strings. */ function concat(slice memory self, slice memory other) internal pure returns (string memory) { string memory ret = new string(self._len + other._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); memcpy(retptr + self._len, other._ptr, other._len); return ret; } /* * @dev Joins an array of slices, using `self` as a delimiter, returning a * newly allocated string. * @param self The delimiter to use. * @param parts A list of slices to join. * @return A newly allocated string containing all the slices in `parts`, * joined with `self`. */ function join(slice memory self, slice[] memory parts) internal pure returns (string memory) { if (parts.length == 0) return ""; uint length = self._len * (parts.length - 1); for(uint i = 0; i < parts.length; i++) length += parts[i]._len; string memory ret = new string(length); uint retptr; assembly { retptr := add(ret, 32) } for(uint i = 0; i < parts.length; i++) { memcpy(retptr, parts[i]._ptr, parts[i]._len); retptr += parts[i]._len; if (i < parts.length - 1) { memcpy(retptr, self._ptr, self._len); retptr += self._len; } } return ret; } }
// SPDX-License-Identifier: MIT pragma solidity >= 0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); } function logUint(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); } function log(uint p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); } function log(uint p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); } function log(uint p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); } function log(string memory p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); } function log(uint p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); } function log(uint p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); } function log(uint p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); } function log(uint p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); } function log(uint p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); } function log(uint p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); } function log(uint p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); } function log(uint p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); } function log(uint p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); } function log(uint p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); } function log(uint p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); } function log(uint p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); } function log(uint p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); } function log(uint p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); } function log(uint p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); } function log(string memory p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); } function log(string memory p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); } function log(string memory p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); } function log(string memory p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); } function log(bool p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); } function log(bool p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); } function log(bool p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); } function log(address p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); } function log(address p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); } function log(address p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
/** *Submitted for verification at FtmScan.com on 2022-02-26 */ /* _____ _ _ | __ \ | \ | | | |__) |__ ___ _____ | \| | __ _ _ __ ___ ___ ___ | _ // _` \ \ / / _ \ | . ` |/ _` | '_ ` _ \ / _ \/ __| | | \ \ (_| |\ V / __/ | |\ | (_| | | | | | | __/\__ \ |_| \_\__,_| \_/ \___| |_| \_|\__,_|_| |_| |_|\___||___/ .----------------. .----------------. .----------------. .----------------. .-----------------. .----------------. .----------------. .----------------. .----------------. | .--------------. || .--------------. || .--------------. || .--------------. | | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. | | | _______ | || | __ | || | ____ ____ | || | _________ | | | | ____ _____ | || | __ | || | ____ ____ | || | _________ | || | _______ | | | | |_ __ \ | || | / \ | || ||_ _| |_ _| | || | |_ ___ | | | | ||_ \|_ _| | || | / \ | || ||_ \ / _|| || | |_ ___ | | || | / ___ | | | | | | |__) | | || | / /\ \ | || | \ \ / / | || | | |_ \_| | | | | | \ | | | || | / /\ \ | || | | \/ | | || | | |_ \_| | || | | (__ \_| | | | | | __ / | || | / ____ \ | || | \ \ / / | || | | _| _ | | | | | |\ \| | | || | / ____ \ | || | | |\ /| | | || | | _| _ | || | '.___`-. | | | | _| | \ \_ | || | _/ / \ \_ | || | \ ' / | || | _| |___/ | | | | | _| |_\ |_ | || | _/ / \ \_ | || | _| |_\/_| |_ | || | _| |___/ | | || | |`\____) | | | | | |____| |___| | || ||____| |____|| || | \_/ | || | |_________| | | | ||_____|\____| | || ||____| |____|| || ||_____||_____|| || | |_________| | || | |_______.' | | | | | || | | || | | || | | | | | | || | | || | | || | | || | | | | '--------------' || '--------------' || '--------------' || '--------------' | | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' | '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' */ pragma solidity >=0.8.0 <0.9.0; //SPDX-License-Identifier: Unlisence //IERC20 interface interface IERC20 { function totalSupply() external view returns (uint); function balanceOf(address account) external view returns (uint); function transfer(address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint amount) external returns (bool); function transferFrom( address sender, address recipient, uint amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } library Strings2 { /** * Concat (High gas cost) * * Appends two strings together and returns a new value * * @param _base When being used for a data type this is the extended object * otherwise this is the string which will be the concatenated * prefix * @param _value The value to be the concatenated suffix * @return string The resulting string from combinging the base and value */ function concat(string memory _base, string memory _value) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); bytes memory _valueBytes = bytes(_value); assert(_valueBytes.length > 0); string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length); bytes memory _newValue = bytes(_tmpValue); uint i; uint j; for (i = 0; i < _baseBytes.length; i++) { _newValue[j++] = _baseBytes[i]; } for (i = 0; i < _valueBytes.length; i++) { _newValue[j++] = _valueBytes[i]; } return string(_newValue); } /** * Index Of * * Locates and returns the position of a character within a string * * @param _base When being used for a data type this is the extended object * otherwise this is the string acting as the haystack to be * searched * @param _value The needle to search for, at present this is currently * limited to one character * @return int The position of the needle starting from 0 and returning -1 * in the case of no matches found */ function indexOf(string memory _base, string memory _value) internal pure returns (int) { return _indexOf(_base, _value, 0); } /** * Index Of * * Locates and returns the position of a character within a string starting * from a defined offset * * @param _base When being used for a data type this is the extended object * otherwise this is the string acting as the haystack to be * searched * @param _value The needle to search for, at present this is currently * limited to one character * @param _offset The starting point to start searching from which can start * from 0, but must not exceed the length of the string * @return int The position of the needle starting from 0 and returning -1 * in the case of no matches found */ function _indexOf(string memory _base, string memory _value, uint _offset) internal pure returns (int) { bytes memory _baseBytes = bytes(_base); bytes memory _valueBytes = bytes(_value); assert(_valueBytes.length == 1); for (uint i = _offset; i < _baseBytes.length; i++) { if (_baseBytes[i] == _valueBytes[0]) { return int(i); } } return -1; } /** * Length * * Returns the length of the specified string * * @param _base When being used for a data type this is the extended object * otherwise this is the string to be measured * @return uint The length of the passed string */ function length(string memory _base) internal pure returns (uint) { bytes memory _baseBytes = bytes(_base); return _baseBytes.length; } /** * Sub String * * Extracts the beginning part of a string based on the desired length * * @param _base When being used for a data type this is the extended object * otherwise this is the string that will be used for * extracting the sub string from * @param _length The length of the sub string to be extracted from the base * @return string The extracted sub string */ function substring(string memory _base, int _length) internal pure returns (string memory) { return _substring(_base, _length, 0); } /** * Sub String * * Extracts the part of a string based on the desired length and offset. The * offset and length must not exceed the lenth of the base string. * * @param _base When being used for a data type this is the extended object * otherwise this is the string that will be used for * extracting the sub string from * @param _length The length of the sub string to be extracted from the base * @param _offset The starting point to extract the sub string from * @return string The extracted sub string */ function _substring(string memory _base, int _length, int _offset) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); assert(uint(_offset + _length) <= _baseBytes.length); string memory _tmp = new string(uint(_length)); bytes memory _tmpBytes = bytes(_tmp); uint j = 0; for (uint i = uint(_offset); i < uint(_offset + _length); i++) { _tmpBytes[j++] = _baseBytes[i]; } return string(_tmpBytes); } /** * String Split (Very high gas cost) * * Splits a string into an array of strings based off the delimiter value. * Please note this can be quite a gas expensive function due to the use of * storage so only use if really required. * * @param _base When being used for a data type this is the extended object * otherwise this is the string value to be split. * @param _value The delimiter to split the string on which must be a single * character */ function split(string memory _base, string memory _value) internal pure returns (string[] memory splitArr) { bytes memory _baseBytes = bytes(_base); uint _offset = 0; uint _splitsCount = 1; while (_offset < _baseBytes.length - 1) { int _limit = _indexOf(_base, _value, _offset); if (_limit == -1) break; else { _splitsCount++; _offset = uint(_limit) + 1; } } splitArr = new string[](_splitsCount); _offset = 0; _splitsCount = 0; while (_offset < _baseBytes.length - 1) { int _limit = _indexOf(_base, _value, _offset); if (_limit == - 1) { _limit = int(_baseBytes.length); } string memory _tmp = new string(uint(_limit) - _offset); bytes memory _tmpBytes = bytes(_tmp); uint j = 0; for (uint i = _offset; i < uint(_limit); i++) { _tmpBytes[j++] = _baseBytes[i]; } _offset = uint(_limit) + 1; splitArr[_splitsCount++] = string(_tmpBytes); } return splitArr; } /** * Compare To * * Compares the characters of two strings, to ensure that they have an * identical footprint * * @param _base When being used for a data type this is the extended object * otherwise this is the string base to compare against * @param _value The string the base is being compared to * @return bool Simply notates if the two string have an equivalent */ function compareTo(string memory _base, string memory _value) internal pure returns (bool) { bytes memory _baseBytes = bytes(_base); bytes memory _valueBytes = bytes(_value); if (_baseBytes.length != _valueBytes.length) { return false; } for (uint i = 0; i < _baseBytes.length; i++) { if (_baseBytes[i] != _valueBytes[i]) { return false; } } return true; } /** * Compare To Ignore Case (High gas cost) * * Compares the characters of two strings, converting them to the same case * where applicable to alphabetic characters to distinguish if the values * match. * * @param _base When being used for a data type this is the extended object * otherwise this is the string base to compare against * @param _value The string the base is being compared to * @return bool Simply notates if the two string have an equivalent value * discarding case */ function compareToIgnoreCase(string memory _base, string memory _value) internal pure returns (bool) { bytes memory _baseBytes = bytes(_base); bytes memory _valueBytes = bytes(_value); if (_baseBytes.length != _valueBytes.length) { return false; } for (uint i = 0; i < _baseBytes.length; i++) { if (_baseBytes[i] != _valueBytes[i] && _upper(_baseBytes[i]) != _upper(_valueBytes[i])) { return false; } } return true; } /** * Upper * * Converts all the values of a string to their corresponding upper case * value. * * @param _base When being used for a data type this is the extended object * otherwise this is the string base to convert to upper case * @return string */ function upper(string memory _base) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { _baseBytes[i] = _upper(_baseBytes[i]); } return string(_baseBytes); } /** * Lower * * Converts all the values of a string to their corresponding lower case * value. * * @param _base When being used for a data type this is the extended object * otherwise this is the string base to convert to lower case * @return string */ function lower(string memory _base) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { _baseBytes[i] = _lower(_baseBytes[i]); } return string(_baseBytes); } /** * Upper * * Convert an alphabetic character to upper case and return the original * value when not alphabetic * * @param _b1 The byte to be converted to upper case * @return bytes1 The converted value if the passed value was alphabetic * and in a lower case otherwise returns the original value */ function _upper(bytes1 _b1) private pure returns (bytes1) { if (_b1 >= 0x61 && _b1 <= 0x7A) { return bytes1(uint8(_b1) - 32); } return _b1; } /** * Lower * * Convert an alphabetic character to lower case and return the original * value when not alphabetic * * @param _b1 The byte to be converted to lower case * @return bytes1 The converted value if the passed value was alphabetic * and in a upper case otherwise returns the original value */ function _lower(bytes1 _b1) private pure returns (bytes1) { if (_b1 >= 0x41 && _b1 <= 0x5A) { return bytes1(uint8(_b1) + 32); } return _b1; } } 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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } 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() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } 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); } library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } abstract contract ERC165Storage is ERC165 { /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } 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`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; } interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } 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 `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } interface IWrappedFantom { // deposit wraps received FTM tokens as wFTM in 1:1 ratio by minting // the received amount of FTMs in wFTM on the sender's address. function deposit() external payable returns (uint256); } 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); } contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _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; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @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: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); 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) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @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 owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_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: transfer caller is not owner nor 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: transfer caller is not owner nor 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 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 _owners[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) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @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); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @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 of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @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 { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } interface IERC2981 is IERC165 { // ERC165 bytes to add to interface array - set in parent contract // implementing this standard // // bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a // bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; // _registerInterface(_INTERFACE_ID_ERC2981); // @notice Called with the sale price to determine how much royalty // is owed and to whom. // @param _tokenId - the NFT asset queried for royalty information // @param _salePrice - the sale price of the NFT asset specified by _tokenId // @return receiver - address of who should be sent the royalty payment // @return royaltyAmount - the royalty payment amount for _salePrice function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount); } abstract contract ERC2981Collection is IERC2981 { // Bytes4 Code for EIP-2981 bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; // Mappings _tokenID -> values address private recieverTemp; mapping(uint256 => address) receiverAddresses; mapping(uint256 => uint256) royaltyPercentage; // Set to be internal function _setReceiver function _setReceiver(uint256 _tokenId, address _address) internal { receiverAddresses[_tokenId] = _address; } // Set to be internal function _setRoyaltyPercentage function _setRoyaltyPercentage(uint256 _tokenId, uint256 _royaltyPercentage) internal { royaltyPercentage[_tokenId] = _royaltyPercentage; } // Override for royaltyInfo(uint256, uint256) // royaltyInfo(uint256,uint256) => 0x2a55205a function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) external view override(IERC2981) returns ( address receiver, uint256 royaltyAmount ) { receiver = receiverAddresses[_tokenId]; // This sets percentages by price * percentage / 100 royaltyAmount = _salePrice * royaltyPercentage[_tokenId] / 100; } } contract FantomsArtNameSystem is ERC721Enumerable, ERC165Storage, Ownable { using Counters for Counters.Counter; //using Address for address; Counters.Counter private _tokenIdCounter; address private constant wFTMa = 0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83; IWrappedFantom private constant wFTMc = IWrappedFantom(0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83); IERC20 private constant wFTM = IERC20(0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83); address private constant MULTISIG_TREASURY = 0x87f385d152944689f92Ed523e9e5E9Bd58Ea62ef; address private constant deployer = 0x3e522051A9B1958Aa1e828AC24Afba4a551DF37d; uint256 public FEE_AMT = 0 ether; // bytes4 constants for ERC165 bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; //event UpdatedFees(uint256 _newFee); event UpdatedURI(string _newURI); event NameTransferred(string _name, address _from, address _to); //event ConsoleLog(string _msg); event LinkUpdated(string _name, string _lnk); event AvatarUpdated(string _name, string _avatarLink); constructor() ERC721("fantoms.art Basic Fantom Name System", "FNS") { // ERC165 Interfaces Supported _registerInterface(_INTERFACE_ID_ERC721); } struct FantomsArtName { string _name; uint256 _tokenId; address _owner; bool _exists; string _IPFSAttrLink; string _avatar; //mapping(string => string) _more; } struct NameApproval { string _name; address _user; } mapping(uint256 => FantomsArtName) private _tokenIdToStruct; mapping(string => uint256) private _reverseSearch; mapping(address => string) private _search; mapping(address => bool) private _exists2; mapping(string => bool) private _nameExists; mapping(string => address) private _rSearch2; mapping(string => NameApproval) private _approvals; //function changeFee(uint256 _newFee) public onlyOwner { // FEE_AMT = _newFee; // emit UpdatedFees(_newFee); //} function changeFee(uint256 _newFee) public onlyOwner { FEE_AMT = _newFee; } function getNameFromOwner(address _owner) public view returns(string memory) { return _search[_owner]; } function getTokenIdFromName(string memory _name) public view returns(uint256) { return _reverseSearch[_name]; } function isOwnedByMapping(string memory _name) public view returns(bool) { return _nameExists[_name]; } function getOwnerOfName(string memory _name) public view returns(address) { _name = Strings2.upper(_name); uint256 _searchFor = _reverseSearch[_name]; FantomsArtName memory x = _tokenIdToStruct[_searchFor]; return x._owner; } function invertBool(bool _bool) private pure returns(bool) { if (_bool) { return false; } else { return true; } } // check why _nameExists[_name] isnt set to true function registerName(string memory _name) public payable { _name = Strings2.upper(_name); require(msg.value == FEE_AMT, "FNS: You need to pay the right amount >:(");// VvV require(invertBool(_nameExists[_name]), "FNS: You cant take other peoples name"); require(invertBool(_exists2[msg.sender]), "FNS: You cant own more than one name"); // the answer is --> NO <-- //wFTMc.deposit{value: msg.value}(); // /\ //wFTM.transfer(MULTISIG_TREASURY, wFTM.balanceOf(address(this))); FantomsArtName memory _tempName = FantomsArtName(_name,_tokenIdCounter.current(),msg.sender,true,"",""); _search[msg.sender] = _name; _rSearch2[_name] = msg.sender; _nameExists[_name] = true; _exists2[msg.sender] = true; _tokenIdToStruct[_tokenIdCounter.current()] = _tempName; _reverseSearch[_name] = _tokenIdCounter.current(); _safeMint(msg.sender, _tokenIdCounter.current()); _tokenIdCounter.increment(); } function approveName(string memory _name, address owner, address spender) public { address nOwner = _rSearch2[_name]; require(msg.sender == owner, "FNS: err. code 0002"); require(nOwner == owner, "FNS: err. code 0003"); NameApproval memory _tempApproval = NameApproval(_name,spender); _approvals[_name] = _tempApproval; } function isApprovedTo(string memory _name, address _to) public view returns(bool) { return (_approvals[_name]._user == _to); } /* function basicNameApproval(string memory _name, address _owner, address _spender) public { address nOwner = _rSearch2[_name]; require(msg.sender == owner); require(nOwner == owner); approveName(_name,_owner,_spender,block.timestamp + 30); } */ //function getOwnerOfTokenId(uint256 _tokenID) public view returns(address) { // return ownerOf(_tokenID); //} function sendFTMToName(string memory _name) public payable { _name = Strings2.upper(_name); payable(getOwnerOfName(_name)).transfer(msg.value); } function sendERC20ToName(address _token, uint256 _amount, string memory _name) public { _name = Strings2.upper(_name); IERC20(_token).transferFrom(msg.sender,getOwnerOfName(_name),_amount); } function sendERC721ToName(address _token, uint256 _tokenId, string memory _name) public { _name = Strings2.upper(_name); IERC721(_token).safeTransferFrom(msg.sender,getOwnerOfName(_name),_tokenId); } function transferName(address _from, address _to, string memory _name) public { require(invertBool(_exists2[_to]),"FNS: You cant overwrite someones name, idiot"); address nOwner = getOwnerOfName(_name); if (_approvals[_name]._user == msg.sender) { // do nothing } else { require(msg.sender == nOwner, "FNS: err. code 0003"); } string memory _searchFromOld = _search[_from]; uint256 _reverseFromOld = _reverseSearch[_searchFromOld]; //address _rSearch2Old = _rSearch2[_name]; //FantomsArtName memory _idk = _tokenIdToStruct[_reverseFromOld]; _rSearch2[_name] = _to; _exists2[_from] = false; _exists2[_to] = true; _search[_to] = _search[_from]; _search[_from] = string(abi.encodePacked(uint(0))); _tokenIdToStruct[_reverseSearch[_search[_to]]] = _tokenIdToStruct[_reverseFromOld]; _tokenIdToStruct[_reverseFromOld] = FantomsArtName(_name,_reverseSearch[_search[_to]],_to,true,"",""); transferFrom(_from,_to,_reverseFromOld); emit NameTransferred(_name,_from,_to); } function setIPFSAttrLink(string memory _name, string memory _lnk) public { require(_nameExists[_name],"FNS: You cant set a link for a non-existing name"); require(_tokenIdToStruct[_reverseSearch[_name]]._owner == msg.sender); _tokenIdToStruct[_reverseSearch[_name]]._IPFSAttrLink = _lnk; emit LinkUpdated(_name,_lnk); } function getAttrLink(string memory _name) public view returns(string memory) { return _tokenIdToStruct[_reverseSearch[_name]]._IPFSAttrLink; } function setAvatar(string memory _name, string memory _avatar) public { require(_nameExists[_name],"FNS: You cant set a link for a non-existing name"); require(_tokenIdToStruct[_reverseSearch[_name]]._owner == msg.sender); _tokenIdToStruct[_reverseSearch[_name]]._avatar = _avatar; emit AvatarUpdated(_name,_avatar); } function getAvatar(string memory _name) public view returns(string memory) { return _tokenIdToStruct[_reverseSearch[_name]]._avatar; } //function safeTransferFrom(address _from, address _to, string memory _name) public { // transferName(_from,_to,_name); //} // @notice solidity required override for supportsInterface(bytes4) function supportsInterface(bytes4 interfaceId) public view override(ERC165Storage,ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // Based on https://github.com/MasterSprouts/CawUsernames/blob/master/contracts/CawNameURI.sol // Credits go to MasterSprouts pragma solidity >=0.8.12; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; contract RaveURIGenerator is Ownable { string internal description = "Rave Names is the first web3 username system on Fantom"; function generate(string memory name) public view returns(string memory) { string[5] memory parts; uint8 length = uint8(bytes(name).length); uint8 fontSize = 22; if (length == 16) fontSize = 23; else if (length == 15) fontSize = 25; else if (length == 14) fontSize = 27; else if (length == 13) fontSize = 29; else if (length == 12) fontSize = 31; else if (length == 11) fontSize = 33; else if (length == 10) fontSize = 36; else if (length == 9) fontSize = 40; else if (length == 8) fontSize = 44; else if (length == 7) fontSize = 49; else if (length == 6) fontSize = 55; else if (length == 5) fontSize = 64; else if (length == 4) fontSize = 77; // xposition needs to be 89% else if (length == 3) fontSize = 99; else if (length == 2) fontSize = 133; // xposition needs to be 88% else if (length == 1) fontSize = 176; string memory xposition = '90'; if (length <= 2) xposition = '88'; else if (length <= 4) xposition = '89'; parts[0] = '<svg xmlns="http://www.w3.org/2000/svg" width="270" height="270" viewBox="0 0 270 270" fill="none" data-ember-extension="1"> <rect width="270" height="270" fill="url(#paint0_linear)"/> <defs> <filter id="dropShadow" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="270" width="270"> <feDropShadow dx="0" dy="1" stdDeviation="2" flood-opacity="0.225" width="200%" height="200%"/> </filter> </defs>'; parts[1] = '<text y="231" font-size="'; parts[2] = 'px" fill="white" filter="url(#dropShadow)" style="text-anchor: end;" x="'; parts[3] = '%">'; parts[4] = '</text> <defs> <style> text { font-family: monospace; font-style: normal; font-weight: bold; line-height: 34px; } </style> <linearGradient id="paint0_linear" x1="110.5" y1="140" x2="-30" gradientUnits="userSpaceOnUse" y42="37.5"> <stop stop-color="#03045e"/> <stop offset="1" stop-color="#ECc052"/> </linearGradient> <linearGradient id="paint1_linear" x1="0" y1="0" x2="269.553" y2="285.527" gradientUnits="userSpaceOnUse"> <stop stop-color="#000000"/> <stop offset="1" stop-color="#22222"/> </linearGradient> </defs> </svg>'; string memory output = string(abi.encodePacked(parts[0], parts[1], Strings.toString(fontSize), parts[2], xposition, parts[3], name, parts[4])); string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "', name, '", "description": "', description, '", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')))); output = string(abi.encodePacked('data:application/json;base64,', json)); return output; } function setDescription(string memory _description) public onlyOwner { description = _description; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @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 // 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 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.7.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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 (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 (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_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) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_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); } }
// 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 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 // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_extension","type":"string"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_uri","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"Migration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"addresses","type":"string"}],"name":"SetAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"avatar","type":"string"}],"name":"SetAvatar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"uri","type":"address"}],"name":"SetURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"names","type":"string[]"}],"name":"bulkRegister","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"bulkRegisterAndSend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"changeName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"p","type":"uint256"}],"name":"f","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"getAddresses","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"getAvatar","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getNames","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ravev1","type":"address"},{"internalType":"uint256","name":"startAt","type":"uint256"},{"internalType":"uint256","name":"endAt","type":"uint256"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"owned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"registerName","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"sendTo","type":"address"}],"name":"registerNameAndSend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"name","type":"string"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"addresses","type":"string"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"avatar","type":"string"}],"name":"setAvatar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newUri","type":"address"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"name","type":"string"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uri","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040527387f385d152944689f92ed523e9e5e9bd58ea62ef600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507321be370d5312f44cb42ce377bc9b8a0cef1a4c83600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550348015620000bb57600080fd5b5060405162006965380380620069658339818101604052810190620000e19190620004f0565b82604051602001620000f49190620005de565b6040516020818303038152906040526040516020016200011591906200062e565b604051602081830303815290604052836040516020016200013791906200067e565b6040516020818303038152906040528160009081620001579190620008de565b508060019081620001699190620008de565b5050506200018c62000180620001ef60201b60201c565b620001f760201b60201c565b81600b8190555082600c9081620001a49190620008de565b5080601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050620009c5565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200032682620002db565b810181811067ffffffffffffffff82111715620003485762000347620002ec565b5b80604052505050565b60006200035d620002bd565b90506200036b82826200031b565b919050565b600067ffffffffffffffff8211156200038e576200038d620002ec565b5b6200039982620002db565b9050602081019050919050565b60005b83811015620003c6578082015181840152602081019050620003a9565b60008484015250505050565b6000620003e9620003e38462000370565b62000351565b905082815260208101848484011115620004085762000407620002d6565b5b62000415848285620003a6565b509392505050565b600082601f830112620004355762000434620002d1565b5b815162000447848260208601620003d2565b91505092915050565b6000819050919050565b620004658162000450565b81146200047157600080fd5b50565b60008151905062000485816200045a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004b8826200048b565b9050919050565b620004ca81620004ab565b8114620004d657600080fd5b50565b600081519050620004ea81620004bf565b92915050565b6000806000606084860312156200050c576200050b620002c7565b5b600084015167ffffffffffffffff8111156200052d576200052c620002cc565b5b6200053b868287016200041d565b93505060206200054e8682870162000474565b92505060406200056186828701620004d9565b9150509250925092565b7f52617665204e616d6573202e0000000000000000000000000000000000000000815250565b600081519050919050565b600081905092915050565b6000620005b48262000591565b620005c081856200059c565b9350620005d2818560208601620003a6565b80840191505092915050565b6000620005eb826200056b565b600c82019150620005fd8284620005a7565b915081905092915050565b7f2072656769737472790000000000000000000000000000000000000000000000815250565b60006200063c8284620005a7565b9150620006498262000608565b60098201915081905092915050565b7f2e00000000000000000000000000000000000000000000000000000000000000815250565b60006200068b8262000658565b6001820191506200069d8284620005a7565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620006f057607f821691505b602082108103620007065762000705620006a8565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620007707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000731565b6200077c868362000731565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620007bf620007b9620007b38462000450565b62000794565b62000450565b9050919050565b6000819050919050565b620007db836200079e565b620007f3620007ea82620007c6565b8484546200073e565b825550505050565b600090565b6200080a620007fb565b62000817818484620007d0565b505050565b5b818110156200083f576200083360008262000800565b6001810190506200081d565b5050565b601f8211156200088e5762000858816200070c565b620008638462000721565b8101602085101562000873578190505b6200088b620008828562000721565b8301826200081c565b50505b505050565b600082821c905092915050565b6000620008b36000198460080262000893565b1980831691505092915050565b6000620008ce8383620008a0565b9150826002028217905092915050565b620008e98262000591565b67ffffffffffffffff811115620009055762000904620002ec565b5b620009118254620006d7565b6200091e82828562000843565b600060209050601f83116001811462000956576000841562000941578287015190505b6200094d8582620008c0565b865550620009bd565b601f19841662000966866200070c565b60005b82811015620009905784890151825560018201915060208501945060208101905062000969565b86831015620009b05784890151620009ac601f891682620008a0565b8355505b6001600288020188555050505b505050505050565b615f9080620009d56000396000f3fe6080604052600436106102465760003560e01c806370a0823111610139578063a833c64b116100b6578063db9042d11161007a578063db9042d1146108bf578063e1090cff146108db578063e985e9c514610918578063eac989f814610955578063f2fde38b14610980578063fc22d0e5146109a957610246565b8063a833c64b146107ca578063b3de648b14610807578063b88d4fde14610830578063c87b56dd14610859578063d3189e061461089657610246565b8063889825b5116100fd578063889825b5146106e35780638da5cb5b1461072057806395d89b411461074b578063a035b1fe14610776578063a22cb465146107a157610246565b806370a082311461061a578063715018a614610657578063791a26b41461066e5780637d840ed51461068a5780638558dbe8146106c757610246565b80633ebfc934116101c757806352adffd71161018b57806352adffd7146105235780635353a2d81461054c57806361d027b3146105895780636352211e146105b45780636c1a1779146105f157610246565b80633ebfc9341461042e57806342842e0e1461045757806345772035146104805780634aaf4a12146104a95780634f6ccce7146104e657610246565b806318160ddd1161020e57806318160ddd1461033557806323b872dd146103605780632d5537b0146103895780632f745c59146103b457806339b64c30146103f157610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b35780630830602b146102f0578063095ea7b31461030c575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613dac565b6109d2565b60405161027f9190613df4565b60405180910390f35b34801561029457600080fd5b5061029d6109e4565b6040516102aa9190613e9f565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d59190613ef7565b610a76565b6040516102e79190613f65565b60405180910390f35b61030a600480360381019061030591906140b5565b610abc565b005b34801561031857600080fd5b50610333600480360381019061032e919061412a565b610f25565b005b34801561034157600080fd5b5061034a61103c565b6040516103579190614179565b60405180910390f35b34801561036c57600080fd5b5061038760048036038101906103829190614194565b611049565b005b34801561039557600080fd5b5061039e6110a9565b6040516103ab9190613e9f565b60405180910390f35b3480156103c057600080fd5b506103db60048036038101906103d6919061412a565b611137565b6040516103e89190614179565b60405180910390f35b3480156103fd57600080fd5b50610418600480360381019061041391906140b5565b6111dc565b6040516104259190613e9f565b60405180910390f35b34801561043a57600080fd5b50610455600480360381019061045091906141e7565b6112a7565b005b34801561046357600080fd5b5061047e60048036038101906104799190614194565b6112d2565b005b34801561048c57600080fd5b506104a760048036038101906104a29190614256565b6112f2565b005b3480156104b557600080fd5b506104d060048036038101906104cb91906140b5565b61141f565b6040516104dd9190613f65565b60405180910390f35b3480156104f257600080fd5b5061050d60048036038101906105089190613ef7565b611454565b60405161051a9190614179565b60405180910390f35b34801561052f57600080fd5b5061054a600480360381019061054591906141e7565b6114c5565b005b34801561055857600080fd5b50610573600480360381019061056e91906140b5565b6114f0565b6040516105809190613e9f565b60405180910390f35b34801561059557600080fd5b5061059e6115c7565b6040516105ab9190613f65565b60405180910390f35b3480156105c057600080fd5b506105db60048036038101906105d69190613ef7565b6115ed565b6040516105e89190613f65565b60405180910390f35b3480156105fd57600080fd5b50610618600480360381019061061391906142ce565b61169e565b005b34801561062657600080fd5b50610641600480360381019061063c91906142ce565b611721565b60405161064e9190614179565b60405180910390f35b34801561066357600080fd5b5061066c6117d8565b005b610688600480360381019061068391906143e1565b6117ec565b005b34801561069657600080fd5b506106b160048036038101906106ac91906140b5565b61182c565b6040516106be9190613e9f565b60405180910390f35b6106e160048036038101906106dc919061442a565b6118f7565b005b3480156106ef57600080fd5b5061070a600480360381019061070591906140b5565b611d84565b6040516107179190613df4565b60405180910390f35b34801561072c57600080fd5b50610735611dbe565b6040516107429190613f65565b60405180910390f35b34801561075757600080fd5b50610760611de8565b60405161076d9190613e9f565b60405180910390f35b34801561078257600080fd5b5061078b611e7a565b6040516107989190614179565b60405180910390f35b3480156107ad57600080fd5b506107c860048036038101906107c391906144b2565b611e80565b005b3480156107d657600080fd5b506107f160048036038101906107ec91906142ce565b611e96565b6040516107fe91906145fe565b60405180910390f35b34801561081357600080fd5b5061082e60048036038101906108299190613ef7565b611fe2565b005b34801561083c57600080fd5b50610857600480360381019061085291906146c1565b611ff4565b005b34801561086557600080fd5b50610880600480360381019061087b9190613ef7565b612056565b60405161088d9190613e9f565b60405180910390f35b3480156108a257600080fd5b506108bd60048036038101906108b89190614256565b612115565b005b6108d960048036038101906108d49190614807565b612242565b005b3480156108e757600080fd5b5061090260048036038101906108fd919061412a565b6122e2565b60405161090f9190613e9f565b60405180910390f35b34801561092457600080fd5b5061093f600480360381019061093a919061487f565b612394565b60405161094c9190613df4565b60405180910390f35b34801561096157600080fd5b5061096a612428565b6040516109779190613f65565b60405180910390f35b34801561098c57600080fd5b506109a760048036038101906109a291906142ce565b61244e565b005b3480156109b557600080fd5b506109d060048036038101906109cb91906148bf565b6124d1565b005b60006109dd826127d9565b9050919050565b6060600080546109f390614941565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1f90614941565b8015610a6c5780601f10610a4157610100808354040283529160200191610a6c565b820191906000526020600020905b815481529060010190602001808311610a4f57829003601f168201915b5050505050905090565b6000610a8182612853565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600b54341015610b01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af8906149e4565b60405180910390fd5b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b815260040160206040518083038185885af1158015610b70573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610b959190614a19565b50600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c529190613f65565b602060405180830381865afa158015610c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c939190614a19565b6040518363ffffffff1660e01b8152600401610cb0929190614a46565b6020604051808303816000875af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190614a84565b506000610d4082604051602001610d0a9190614b13565b604051602081830303815290604052600c604051602001610d2c929190614bd1565b60405160208183030381529060405261289e565b90506000610d4d82612936565b90506011600082815260200190815260200160002060009054906101000a900460ff1615610db0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da790614c67565b60405180910390fd5b60006040518060800160405280848152602001610dcd600d612966565b815260200160405180602001604052806000815250815260200160405180602001604052806000815250815250905060016011600084815260200190815260200160002060006101000a81548160ff0219169083151502179055508060126000610e37600d612966565b81526020019081526020016000206000820151816000019081610e5a9190614e1e565b50602082015181600101556040820151816002019081610e7a9190614e1e565b506060820151816003019081610e909190614e1e565b50905050610e9e600d612966565b6013600084815260200190815260200160002081905550610ec833610ec3600d612966565b612974565b610ed2600d612992565b82604051610ee09190614ef0565b60405180910390207f50f74ca45caac8020b8d891bd13ea5a2d79564986ee6a839f0d914896388322d33604051610f179190613f65565b60405180910390a250505050565b6000610f30826115ed565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9790614f79565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610fbf6129a8565b73ffffffffffffffffffffffffffffffffffffffff161480610fee5750610fed81610fe86129a8565b612394565b5b61102d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110249061500b565b60405180910390fd5b61103783836129b0565b505050565b6000600880549050905090565b61105a6110546129a8565b82612a69565b611099576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110909061509d565b60405180910390fd5b6110a4838383612afe565b505050565b600c80546110b690614941565b80601f01602080910402602001604051908101604052809291908181526020018280546110e290614941565b801561112f5780601f106111045761010080835404028352916020019161112f565b820191906000526020600020905b81548152906001019060200180831161111257829003601f168201915b505050505081565b600061114283611721565b8210611183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117a9061512f565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b606060126000601360006111f76111f28761289e565b612936565b8152602001908152602001600020548152602001908152602001600020600201805461122290614941565b80601f016020809104026020016040519081016040528092919081815260200182805461124e90614941565b801561129b5780601f106112705761010080835404028352916020019161129b565b820191906000526020600020905b81548152906001019060200180831161127e57829003601f168201915b50505050509050919050565b6112cd8383601360006112b986612936565b815260200190815260200160002054611049565b505050565b6112ed83838360405180602001604052806000815250611ff4565b505050565b60006112fd8361289e565b9050600061130a82612936565b90503373ffffffffffffffffffffffffffffffffffffffff1661133f60136000848152602001908152602001600020546115ed565b73ffffffffffffffffffffffffffffffffffffffff1614611395576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138c906151c1565b60405180910390fd5b82601260006013600085815260200190815260200160002054815260200190815260200160002060020190816113cb9190614e1e565b50816040516113da9190614ef0565b60405180910390207f0952158521adedb55943f07d324b6cc91ea396ccef8119db7d08b5c966a7672c846040516114119190613e9f565b60405180910390a250505050565b600061144d601360006114396114348661289e565b612936565b8152602001908152602001600020546115ed565b9050919050565b600061145e61103c565b821061149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149690615253565b60405180910390fd5b600882815481106114b3576114b2615273565b5b90600052602060002001549050919050565b6114eb8383601360006114d786612936565b8152602001908152602001600020546112d2565b505050565b606061154a6115336040518060400160405280600481526020017f2e46544d00000000000000000000000000000000000000000000000000000000815250612d64565b61153c84612d64565b612d9290919063ffffffff16565b156115be576115b76115b26115936040518060400160405280600481526020017f2e66746d00000000000000000000000000000000000000000000000000000000815250612d64565b6115a461159f8661289e565b612d64565b612e0990919063ffffffff16565b612ea4565b90506115c2565b8190505b919050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168c906152ee565b60405180910390fd5b80915050919050565b6116a6612f20565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f1150f930a11acd3b9029b158a70b48bcb5fdffa8f9c5ea364d87b3bc2a6e60d6816040516117169190613f65565b60405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178890615380565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6117e0612f20565b6117ea6000612f9e565b565b60005b81518110156118285761181b82828151811061180e5761180d615273565b5b6020026020010151610abc565b80806001019150506117ef565b5050565b606060126000601360006118476118428761289e565b612936565b8152602001908152602001600020548152602001908152602001600020600301805461187290614941565b80601f016020809104026020016040519081016040528092919081815260200182805461189e90614941565b80156118eb5780601f106118c0576101008083540402835291602001916118eb565b820191906000526020600020905b8154815290600101906020018083116118ce57829003601f168201915b50505050509050919050565b600b5434101561193c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611933906149e4565b60405180910390fd5b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b815260040160206040518083038185885af11580156119ab573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906119d09190614a19565b50600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611a8d9190613f65565b602060405180830381865afa158015611aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ace9190614a19565b6040518363ffffffff1660e01b8152600401611aeb929190614a46565b6020604051808303816000875af1158015611b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2e9190614a84565b506000611b7b83604051602001611b459190614b13565b604051602081830303815290604052600c604051602001611b67929190614bd1565b60405160208183030381529060405261289e565b90506000611b8882612936565b90506011600082815260200190815260200160002060009054906101000a900460ff161582604051602001611bbd9190615412565b60405160208183030381529060405290611c0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c049190613e9f565b60405180910390fd5b5060006040518060800160405280848152602001611c2b600d612966565b815260200160405180602001604052806000815250815260200160405180602001604052806000815250815250905060016011600084815260200190815260200160002060006101000a81548160ff0219169083151502179055508060126000611c95600d612966565b81526020019081526020016000206000820151816000019081611cb89190614e1e565b50602082015181600101556040820151816002019081611cd89190614e1e565b506060820151816003019081611cee9190614e1e565b50905050611cfc600d612966565b6013600084815260200190815260200160002081905550611d2684611d21600d612966565b612974565b611d30600d612992565b82604051611d3e9190614ef0565b60405180910390207f50f74ca45caac8020b8d891bd13ea5a2d79564986ee6a839f0d914896388322d85604051611d759190613f65565b60405180910390a25050505050565b600060116000611d9b611d968561289e565b612936565b815260200190815260200160002060009054906101000a900460ff169050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054611df790614941565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2390614941565b8015611e705780601f10611e4557610100808354040283529160200191611e70565b820191906000526020600020905b815481529060010190602001808311611e5357829003601f168201915b5050505050905090565b600b5481565b611e92611e8b6129a8565b8383613064565b5050565b60606000611ea383611721565b67ffffffffffffffff811115611ebc57611ebb613f8a565b5b604051908082528060200260200182016040528015611eef57816020015b6060815260200190600190039081611eda5790505b50905060005b611efe84611721565b811015611fd85760126000611f138684611137565b81526020019081526020016000206000018054611f2f90614941565b80601f0160208091040260200160405190810160405280929190818152602001828054611f5b90614941565b8015611fa85780601f10611f7d57610100808354040283529160200191611fa8565b820191906000526020600020905b815481529060010190602001808311611f8b57829003601f168201915b5050505050828281518110611fc057611fbf615273565b5b60200260200101819052508080600101915050611ef5565b5080915050919050565b611fea612f20565b80600b8190555050565b612005611fff6129a8565b83612a69565b612044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203b9061509d565b60405180910390fd5b612050848484846131d0565b50505050565b6060601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3d670fe601260008581526020019081526020016000206000016040518263ffffffff1660e01b81526004016120c891906154b8565b600060405180830381865afa1580156120e5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061210e919061554a565b9050919050565b60006121208361289e565b9050600061212d82612936565b90503373ffffffffffffffffffffffffffffffffffffffff1661216260136000848152602001908152602001600020546115ed565b73ffffffffffffffffffffffffffffffffffffffff16146121b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121af90615605565b60405180910390fd5b82601260006013600085815260200190815260200160002054815260200190815260200160002060030190816121ee9190614e1e565b50816040516121fd9190614ef0565b60405180910390207f71584e829984a0c3375cf17140dd04adcaf0364d5b7eec080921e16519e4f219846040516122349190613e9f565b60405180910390a250505050565b8051825114612286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227d906156bd565b60405180910390fd5b60005b82518110156122dd576122d08382815181106122a8576122a7615273565b5b60200260200101518383815181106122c3576122c2615273565b5b60200260200101516118f7565b8080600101915050612289565b505050565b6060601260006122f28585611137565b8152602001908152602001600020600001805461230e90614941565b80601f016020809104026020016040519081016040528092919081815260200182805461233a90614941565b80156123875780601f1061235c57610100808354040283529160200191612387565b820191906000526020600020905b81548152906001019060200180831161236a57829003601f168201915b5050505050905092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612456612f20565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124bc9061574f565b60405180910390fd5b6124ce81612f9e565b50565b6124d9612f20565b6125176040518060400160405280600381526020017f66746d0000000000000000000000000000000000000000000000000000000000815250612936565b6125aa600c805461252790614941565b80601f016020809104026020016040519081016040528092919081815260200182805461255390614941565b80156125a05780601f10612575576101008083540402835291602001916125a0565b820191906000526020600020905b81548152906001019060200180831161258357829003601f168201915b5050505050612936565b146125ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e1906157e1565b60405180910390fd5b6000600b5490506000600b8190555060008390505b8281101561279f5760008573ffffffffffffffffffffffffffffffffffffffff1663817581298773ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161265e9190614179565b602060405180830381865afa15801561267b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269f9190615816565b6040518263ffffffff1660e01b81526004016126bb9190613f65565b600060405180830381865afa1580156126d8573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612701919061554a565b905061270c816114f0565b9050612791818773ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161274b9190614179565b602060405180830381865afa158015612768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278c9190615816565b6118f7565b8180600101925050506125ff565b5080600b819055507f1367a078b4435fe3fa4a46354a57663be6387576edee722ef204dc484fc8c3bd60405160405180910390a150505050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061284c575061284b8261322c565b5b9050919050565b61285c8161330e565b61289b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612892906152ee565b60405180910390fd5b50565b6060600082905060005b815181101561292c576128d78282815181106128c7576128c6615273565b5b602001015160f81c60f81b61337a565b8282815181106128ea576128e9615273565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061292490615872565b9150506128a8565b5080915050919050565b6000816040516020016129499190613e9f565b604051602081830303815290604052805190602001209050919050565b600081600001549050919050565b61298e828260405180602001604052806000815250613400565b5050565b6001816000016000828254019250508190555050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612a23836115ed565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080612a75836115ed565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612ab75750612ab68185612394565b5b80612af557508373ffffffffffffffffffffffffffffffffffffffff16612add84610a76565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612b1e826115ed565b73ffffffffffffffffffffffffffffffffffffffff1614612b74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6b9061592c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bda906159be565b60405180910390fd5b612bee83838361345b565b612bf96000826129b0565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612c4991906159de565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ca09190615a12565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612d5f83838361346b565b505050565b612d6c613d26565b600060208301905060405180604001604052808451815260200182815250915050919050565b6000816000015183600001511015612dad5760009050612e03565b6000826000015184600001518560200151612dc89190615a12565b612dd291906159de565b905082602001518103612de9576001915050612e03565b600083516020850151818120828520149250505080925050505b92915050565b612e11613d26565b816000015183600001511015612e2957829050612e9e565b6000826000015184600001518560200151612e449190615a12565b612e4e91906159de565b905060006001905083602001518214612e74578351602085015181812082852014925050505b8015612e9857836000015185600001818151612e9091906159de565b915081815250505b84925050505b92915050565b60606000826000015167ffffffffffffffff811115612ec657612ec5613f8a565b5b6040519080825280601f01601f191660200182016040528015612ef85781602001600182028036833780820191505090505b5090506000602082019050612f168185602001518660000151613470565b8192505050919050565b612f286129a8565b73ffffffffffffffffffffffffffffffffffffffff16612f46611dbe565b73ffffffffffffffffffffffffffffffffffffffff1614612f9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9390615a92565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036130d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130c990615afe565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516131c39190613df4565b60405180910390a3505050565b6131db848484612afe565b6131e78484848461351c565b613226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321d90615b90565b60405180910390fd5b50505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806132f757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806133075750613306826136a3565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000604160f81b827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156133d85750605a60f81b827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b156133f75760208260f81c6133ed9190615bbd565b60f81b90506133fb565b8190505b919050565b61340a838361370d565b613417600084848461351c565b613456576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161344d90615b90565b60405180910390fd5b505050565b6134668383836138e6565b505050565b505050565b5b602081106134af578151835260208361348a9190615a12565b92506020826134999190615a12565b91506020816134a891906159de565b9050613471565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060008211156135065760018260206134ec91906159de565b6101006134f99190615d25565b61350391906159de565b90505b8019835116818551168181178652505050505050565b600061353d8473ffffffffffffffffffffffffffffffffffffffff166139f8565b15613696578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026135666129a8565b8786866040518563ffffffff1660e01b81526004016135889493929190615dc5565b6020604051808303816000875af19250505080156135c457506040513d601f19601f820116820180604052508101906135c19190615e26565b60015b613646573d80600081146135f4576040519150601f19603f3d011682016040523d82523d6000602084013e6135f9565b606091505b50600081510361363e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161363590615b90565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061369b565b600190505b949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361377c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377390615e9f565b60405180910390fd5b6137858161330e565b156137c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137bc90615f0b565b60405180910390fd5b6137d16000838361345b565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546138219190615a12565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46138e26000838361346b565b5050565b6138f1838383613a1b565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036139335761392e81613a20565b613972565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613971576139708382613a69565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036139b4576139af81613bd6565b6139f3565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146139f2576139f18282613ca7565b5b5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001613a7684611721565b613a8091906159de565b9050600060076000848152602001908152602001600020549050818114613b65576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613bea91906159de565b9050600060096000848152602001908152602001600020549050600060088381548110613c1a57613c19615273565b5b906000526020600020015490508060088381548110613c3c57613c3b615273565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480613c8b57613c8a615f2b565b5b6001900381819060005260206000200160009055905550505050565b6000613cb283611721565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b604051806040016040528060008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613d8981613d54565b8114613d9457600080fd5b50565b600081359050613da681613d80565b92915050565b600060208284031215613dc257613dc1613d4a565b5b6000613dd084828501613d97565b91505092915050565b60008115159050919050565b613dee81613dd9565b82525050565b6000602082019050613e096000830184613de5565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613e49578082015181840152602081019050613e2e565b60008484015250505050565b6000601f19601f8301169050919050565b6000613e7182613e0f565b613e7b8185613e1a565b9350613e8b818560208601613e2b565b613e9481613e55565b840191505092915050565b60006020820190508181036000830152613eb98184613e66565b905092915050565b6000819050919050565b613ed481613ec1565b8114613edf57600080fd5b50565b600081359050613ef181613ecb565b92915050565b600060208284031215613f0d57613f0c613d4a565b5b6000613f1b84828501613ee2565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f4f82613f24565b9050919050565b613f5f81613f44565b82525050565b6000602082019050613f7a6000830184613f56565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fc282613e55565b810181811067ffffffffffffffff82111715613fe157613fe0613f8a565b5b80604052505050565b6000613ff4613d40565b90506140008282613fb9565b919050565b600067ffffffffffffffff8211156140205761401f613f8a565b5b61402982613e55565b9050602081019050919050565b82818337600083830152505050565b600061405861405384614005565b613fea565b90508281526020810184848401111561407457614073613f85565b5b61407f848285614036565b509392505050565b600082601f83011261409c5761409b613f80565b5b81356140ac848260208601614045565b91505092915050565b6000602082840312156140cb576140ca613d4a565b5b600082013567ffffffffffffffff8111156140e9576140e8613d4f565b5b6140f584828501614087565b91505092915050565b61410781613f44565b811461411257600080fd5b50565b600081359050614124816140fe565b92915050565b6000806040838503121561414157614140613d4a565b5b600061414f85828601614115565b925050602061416085828601613ee2565b9150509250929050565b61417381613ec1565b82525050565b600060208201905061418e600083018461416a565b92915050565b6000806000606084860312156141ad576141ac613d4a565b5b60006141bb86828701614115565b93505060206141cc86828701614115565b92505060406141dd86828701613ee2565b9150509250925092565b600080600060608486031215614200576141ff613d4a565b5b600061420e86828701614115565b935050602061421f86828701614115565b925050604084013567ffffffffffffffff8111156142405761423f613d4f565b5b61424c86828701614087565b9150509250925092565b6000806040838503121561426d5761426c613d4a565b5b600083013567ffffffffffffffff81111561428b5761428a613d4f565b5b61429785828601614087565b925050602083013567ffffffffffffffff8111156142b8576142b7613d4f565b5b6142c485828601614087565b9150509250929050565b6000602082840312156142e4576142e3613d4a565b5b60006142f284828501614115565b91505092915050565b600067ffffffffffffffff82111561431657614315613f8a565b5b602082029050602081019050919050565b600080fd5b600061433f61433a846142fb565b613fea565b9050808382526020820190506020840283018581111561436257614361614327565b5b835b818110156143a957803567ffffffffffffffff81111561438757614386613f80565b5b8086016143948982614087565b85526020850194505050602081019050614364565b5050509392505050565b600082601f8301126143c8576143c7613f80565b5b81356143d884826020860161432c565b91505092915050565b6000602082840312156143f7576143f6613d4a565b5b600082013567ffffffffffffffff81111561441557614414613d4f565b5b614421848285016143b3565b91505092915050565b6000806040838503121561444157614440613d4a565b5b600083013567ffffffffffffffff81111561445f5761445e613d4f565b5b61446b85828601614087565b925050602061447c85828601614115565b9150509250929050565b61448f81613dd9565b811461449a57600080fd5b50565b6000813590506144ac81614486565b92915050565b600080604083850312156144c9576144c8613d4a565b5b60006144d785828601614115565b92505060206144e88582860161449d565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061453a82613e0f565b614544818561451e565b9350614554818560208601613e2b565b61455d81613e55565b840191505092915050565b6000614574838361452f565b905092915050565b6000602082019050919050565b6000614594826144f2565b61459e81856144fd565b9350836020820285016145b08561450e565b8060005b858110156145ec57848403895281516145cd8582614568565b94506145d88361457c565b925060208a019950506001810190506145b4565b50829750879550505050505092915050565b600060208201905081810360008301526146188184614589565b905092915050565b600067ffffffffffffffff82111561463b5761463a613f8a565b5b61464482613e55565b9050602081019050919050565b600061466461465f84614620565b613fea565b9050828152602081018484840111156146805761467f613f85565b5b61468b848285614036565b509392505050565b600082601f8301126146a8576146a7613f80565b5b81356146b8848260208601614651565b91505092915050565b600080600080608085870312156146db576146da613d4a565b5b60006146e987828801614115565b94505060206146fa87828801614115565b935050604061470b87828801613ee2565b925050606085013567ffffffffffffffff81111561472c5761472b613d4f565b5b61473887828801614693565b91505092959194509250565b600067ffffffffffffffff82111561475f5761475e613f8a565b5b602082029050602081019050919050565b600061478361477e84614744565b613fea565b905080838252602082019050602084028301858111156147a6576147a5614327565b5b835b818110156147cf57806147bb8882614115565b8452602084019350506020810190506147a8565b5050509392505050565b600082601f8301126147ee576147ed613f80565b5b81356147fe848260208601614770565b91505092915050565b6000806040838503121561481e5761481d613d4a565b5b600083013567ffffffffffffffff81111561483c5761483b613d4f565b5b614848858286016143b3565b925050602083013567ffffffffffffffff81111561486957614868613d4f565b5b614875858286016147d9565b9150509250929050565b6000806040838503121561489657614895613d4a565b5b60006148a485828601614115565b92505060206148b585828601614115565b9150509250929050565b6000806000606084860312156148d8576148d7613d4a565b5b60006148e686828701614115565b93505060206148f786828701613ee2565b925050604061490886828701613ee2565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061495957607f821691505b60208210810361496c5761496b614912565b5b50919050565b7f526176653a20596f75206d75737420706179207468652066756c6c207072696360008201527f652e000000000000000000000000000000000000000000000000000000000000602082015250565b60006149ce602283613e1a565b91506149d982614972565b604082019050919050565b600060208201905081810360008301526149fd816149c1565b9050919050565b600081519050614a1381613ecb565b92915050565b600060208284031215614a2f57614a2e613d4a565b5b6000614a3d84828501614a04565b91505092915050565b6000604082019050614a5b6000830185613f56565b614a68602083018461416a565b9392505050565b600081519050614a7e81614486565b92915050565b600060208284031215614a9a57614a99613d4a565b5b6000614aa884828501614a6f565b91505092915050565b600081905092915050565b6000614ac782613e0f565b614ad18185614ab1565b9350614ae1818560208601613e2b565b80840191505092915050565b7f2e00000000000000000000000000000000000000000000000000000000000000815250565b6000614b1f8284614abc565b9150614b2a82614aed565b60018201915081905092915050565b60008190508160005260206000209050919050565b60008154614b5b81614941565b614b658186614ab1565b94506001821660008114614b805760018114614b9557614bc8565b60ff1983168652811515820286019350614bc8565b614b9e85614b39565b60005b83811015614bc057815481890152600182019150602081019050614ba1565b838801955050505b50505092915050565b6000614bdd8285614abc565b9150614be98284614b4e565b91508190509392505050565b7f526176653a20596f752063616e742072656769737465722061206e616d65207460008201527f6861747320616c7265616479206f776e65642e00000000000000000000000000602082015250565b6000614c51603383613e1a565b9150614c5c82614bf5565b604082019050919050565b60006020820190508181036000830152614c8081614c44565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614cd47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614c97565b614cde8683614c97565b95508019841693508086168417925050509392505050565b6000819050919050565b6000614d1b614d16614d1184613ec1565b614cf6565b613ec1565b9050919050565b6000819050919050565b614d3583614d00565b614d49614d4182614d22565b848454614ca4565b825550505050565b600090565b614d5e614d51565b614d69818484614d2c565b505050565b5b81811015614d8d57614d82600082614d56565b600181019050614d6f565b5050565b601f821115614dd257614da381614b39565b614dac84614c87565b81016020851015614dbb578190505b614dcf614dc785614c87565b830182614d6e565b50505b505050565b600082821c905092915050565b6000614df560001984600802614dd7565b1980831691505092915050565b6000614e0e8383614de4565b9150826002028217905092915050565b614e2782613e0f565b67ffffffffffffffff811115614e4057614e3f613f8a565b5b614e4a8254614941565b614e55828285614d91565b600060209050601f831160018114614e885760008415614e76578287015190505b614e808582614e02565b865550614ee8565b601f198416614e9686614b39565b60005b82811015614ebe57848901518255600182019150602085019450602081019050614e99565b86831015614edb5784890151614ed7601f891682614de4565b8355505b6001600288020188555050505b505050505050565b6000614efc8284614abc565b915081905092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f63602183613e1a565b9150614f6e82614f07565b604082019050919050565b60006020820190508181036000830152614f9281614f56565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614ff5603e83613e1a565b915061500082614f99565b604082019050919050565b6000602082019050818103600083015261502481614fe8565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000615087602e83613e1a565b91506150928261502b565b604082019050919050565b600060208201905081810360008301526150b68161507a565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000615119602b83613e1a565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f526176653a20596f75206d757374206f776e20746865206e616d6520746f207360008201527f657420746865206164647265737365732e000000000000000000000000000000602082015250565b60006151ab603183613e1a565b91506151b68261514f565b604082019050919050565b600060208201905081810360008301526151da8161519e565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b600061523d602c83613e1a565b9150615248826151e1565b604082019050919050565b6000602082019050818103600083015261526c81615230565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006152d8601883613e1a565b91506152e3826152a2565b602082019050919050565b60006020820190508181036000830152615307816152cb565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061536a602983613e1a565b91506153758261530e565b604082019050919050565b600060208201905081810360008301526153998161535d565b9050919050565b7f526176653a20596f752063616e742072656769737465722061206e616d65207460008201527f6861747320616c7265616479206f776e65643a20000000000000000000000000602082015250565b60006153fc603483614ab1565b9150615407826153a0565b603482019050919050565b600061541d826153ef565b91506154298284614abc565b915081905092915050565b6000815461544181614941565b61544b8186613e1a565b94506001821660008114615466576001811461547c576154af565b60ff1983168652811515602002860193506154af565b61548585614b39565b60005b838110156154a757815481890152600182019150602081019050615488565b808801955050505b50505092915050565b600060208201905081810360008301526154d28184615434565b905092915050565b60006154ed6154e884614005565b613fea565b90508281526020810184848401111561550957615508613f85565b5b615514848285613e2b565b509392505050565b600082601f83011261553157615530613f80565b5b81516155418482602086016154da565b91505092915050565b6000602082840312156155605761555f613d4a565b5b600082015167ffffffffffffffff81111561557e5761557d613d4f565b5b61558a8482850161551c565b91505092915050565b7f526176653a20596f75206d757374206f776e20746865206e616d6520746f207360008201527f657420746865206176617461722e000000000000000000000000000000000000602082015250565b60006155ef602e83613e1a565b91506155fa82615593565b604082019050919050565b6000602082019050818103600083015261561e816155e2565b9050919050565b7f526176653a2054686520616d6f756e74206f6620616464726573736573206d7560008201527f737420626520657175616c20746f2074686520616d6f756e74206f66206e616d60208201527f65732e0000000000000000000000000000000000000000000000000000000000604082015250565b60006156a7604383613e1a565b91506156b282615625565b606082019050919050565b600060208201905081810360008301526156d68161569a565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615739602683613e1a565b9150615744826156dd565b604082019050919050565b600060208201905081810360008301526157688161572c565b9050919050565b7f526176653a20596f752063616e206f6e6c79206d696772617465202e66746d2060008201527f6e616d6573000000000000000000000000000000000000000000000000000000602082015250565b60006157cb602583613e1a565b91506157d68261576f565b604082019050919050565b600060208201905081810360008301526157fa816157be565b9050919050565b600081519050615810816140fe565b92915050565b60006020828403121561582c5761582b613d4a565b5b600061583a84828501615801565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061587d82613ec1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036158af576158ae615843565b5b600182019050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615916602583613e1a565b9150615921826158ba565b604082019050919050565b6000602082019050818103600083015261594581615909565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006159a8602483613e1a565b91506159b38261594c565b604082019050919050565b600060208201905081810360008301526159d78161599b565b9050919050565b60006159e982613ec1565b91506159f483613ec1565b9250828203905081811115615a0c57615a0b615843565b5b92915050565b6000615a1d82613ec1565b9150615a2883613ec1565b9250828201905080821115615a4057615a3f615843565b5b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615a7c602083613e1a565b9150615a8782615a46565b602082019050919050565b60006020820190508181036000830152615aab81615a6f565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615ae8601983613e1a565b9150615af382615ab2565b602082019050919050565b60006020820190508181036000830152615b1781615adb565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000615b7a603283613e1a565b9150615b8582615b1e565b604082019050919050565b60006020820190508181036000830152615ba981615b6d565b9050919050565b600060ff82169050919050565b6000615bc882615bb0565b9150615bd383615bb0565b9250828201905060ff811115615bec57615beb615843565b5b92915050565b60008160011c9050919050565b6000808291508390505b6001851115615c4957808604811115615c2557615c24615843565b5b6001851615615c345780820291505b8081029050615c4285615bf2565b9450615c09565b94509492505050565b600082615c625760019050615d1e565b81615c705760009050615d1e565b8160018114615c865760028114615c9057615cbf565b6001915050615d1e565b60ff841115615ca257615ca1615843565b5b8360020a915084821115615cb957615cb8615843565b5b50615d1e565b5060208310610133831016604e8410600b8410161715615cf45782820a905083811115615cef57615cee615843565b5b615d1e565b615d018484846001615bff565b92509050818404811115615d1857615d17615843565b5b81810290505b9392505050565b6000615d3082613ec1565b9150615d3b83613ec1565b9250615d687fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484615c52565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000615d9782615d70565b615da18185615d7b565b9350615db1818560208601613e2b565b615dba81613e55565b840191505092915050565b6000608082019050615dda6000830187613f56565b615de76020830186613f56565b615df4604083018561416a565b8181036060830152615e068184615d8c565b905095945050505050565b600081519050615e2081613d80565b92915050565b600060208284031215615e3c57615e3b613d4a565b5b6000615e4a84828501615e11565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000615e89602083613e1a565b9150615e9482615e53565b602082019050919050565b60006020820190508181036000830152615eb881615e7c565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615ef5601c83613e1a565b9150615f0082615ebf565b602082019050919050565b60006020820190508181036000830152615f2481615ee8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220649b46896e6325372076d4557fdd081197fbe6ac9c18f39cede3845729afbda264736f6c63430008100033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000050000000000000000000000003a1488fedbc9f24e7f9c3b04bd3470fe4cff4c4f000000000000000000000000000000000000000000000000000000000000000366746d0000000000000000000000000000000000000000000000000000000000
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.