Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
106495112 | 583 days ago | 0 ETH |
Loading...
Loading
Contract Name:
ThalesRoyalePassport
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; import "../interfaces/IThalesRoyale.sol"; import "../interfaces/IPassportPosition.sol"; import "../utils/libraries/NFTSVG.sol"; import "../utils/libraries/NFTDescriptor.sol"; contract ThalesRoyalePassport is ERC721EnumerableUpgradeable, PausableUpgradeable, AccessControlUpgradeable, ERC721BurnableUpgradeable, OwnableUpgradeable { /* ========== LIBRARIES ========== */ using CountersUpgradeable for CountersUpgradeable.Counter; /* ========== STATE VARIABLES ========== */ CountersUpgradeable.Counter private _tokenIdCounter; IThalesRoyale public thalesRoyale; mapping(uint => uint) public tokenTimestamps; string public baseUri; /* ========== CONSTRUCTOR ========== */ function initialize(address _thalesRoyaleAddress, string memory _baseUri) public initializer { __Ownable_init(); __ERC721_init("Thales Royale Passport", "TRS"); thalesRoyale = IThalesRoyale(_thalesRoyaleAddress); baseUri = _baseUri; } function safeMint(address recipient) external whenNotPaused onlyRoyale returns (uint tokenId) { _tokenIdCounter.increment(); tokenId = _tokenIdCounter.current(); _safeMint(recipient, tokenId); tokenTimestamps[tokenId] = block.timestamp; emit ThalesRoyalePassportMinted(recipient, tokenId); } function burn(uint tokenId) public override canBeBurned(tokenId) { _burn(tokenId); emit ThalesRoyalePassportBurned(tokenId); } /* ========== VIEW ========== */ function tokenURI(uint tokenId) public view override returns (string memory imageURI) { require(_exists(tokenId), "Passport doesn't exist"); address player = ownerOf(tokenId); uint timestamp = tokenTimestamps[tokenId]; uint season = thalesRoyale.tokenSeason(tokenId); uint currentRound = thalesRoyale.roundInASeason(season); bool alive = thalesRoyale.isTokenAliveInASpecificSeason(tokenId, season); IPassportPosition.Position[] memory positions = thalesRoyale.getTokenPositions(tokenId); bool seasonFinished = thalesRoyale.seasonFinished(season); imageURI = NFTDescriptor.constructTokenURI( NFTSVG.SVGParams(player, timestamp, tokenId, season, currentRound, positions, alive, seasonFinished) ); } /* ========== CONTRACT MANAGEMENT ========== */ function pause() external onlyOwner { _pause(); emit ThalesRoyalePassportPaused(true); } function unpause() external onlyOwner { _unpause(); emit ThalesRoyalePassportPaused(false); } function setThalesRoyale(address _thalesRoyaleAddress) external onlyOwner { require(_thalesRoyaleAddress != address(0), "Invalid address"); thalesRoyale = IThalesRoyale(_thalesRoyaleAddress); emit ThalesRoyaleAddressChanged(_thalesRoyaleAddress); } function setBaseURI(string memory _baseUri) external onlyOwner { baseUri = _baseUri; emit BaseUriChanged(_baseUri); } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal override(ERC721EnumerableUpgradeable, ERC721Upgradeable) whenNotPaused { super._beforeTokenTransfer(from, to, tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721EnumerableUpgradeable, ERC721Upgradeable, AccessControlUpgradeable) returns (bool) { return super.supportsInterface(interfaceId); } /* ========== MODIFIERS ========== */ modifier canBeBurned(uint tokenId) { require(_exists(tokenId), "Passport doesn't exist"); require(_isApprovedOrOwner(msg.sender, tokenId), "Must be owner or approver"); _; } modifier onlyRoyale() { require(msg.sender == address(thalesRoyale), "Invalid address"); _; } /* ========== EVENTS ========== */ event ThalesRoyalePassportMinted(address _recipient, uint _tokenId); event ThalesRoyalePassportBurned(uint _tokenId); event ThalesRoyaleAddressChanged(address _thalesRoyaleAddress); event ThalesRoyalePassportPaused(bool _state); event BaseUriChanged(string _baseURI); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721Upgradeable.sol"; import "./IERC721EnumerableUpgradeable.sol"; import "../../../proxy/utils/Initializable.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 ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable { function __ERC721Enumerable_init() internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __ERC721Enumerable_init_unchained(); } function __ERC721Enumerable_init_unchained() internal onlyInitializing { } // 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(IERC165Upgradeable, ERC721Upgradeable) returns (bool) { return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721Upgradeable.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 < ERC721EnumerableUpgradeable.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 = ERC721Upgradeable.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 = ERC721Upgradeable.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(); } uint256[46] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_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 { _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); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol) pragma solidity ^0.8.0; import "../ERC721Upgradeable.sol"; import "../../../utils/ContextUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ abstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable { function __ERC721Burnable_init() internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __ERC721Burnable_init_unchained(); } function __ERC721Burnable_init_unchained() internal onlyInitializing { } /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); _burn(tokenId); } uint256[50] private __gap; }
// 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 CountersUpgradeable { 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 pragma solidity >=0.5.16; pragma experimental ABIEncoderV2; import "../interfaces/IPassportPosition.sol"; interface IThalesRoyale { /* ========== VIEWS / VARIABLES ========== */ function getBuyInAmount() external view returns (uint); function season() external view returns (uint); function tokenSeason(uint tokenId) external view returns (uint); function seasonFinished(uint _season) external view returns (bool); function roundInASeason(uint _round) external view returns (uint); function roundResultPerSeason(uint _season, uint round) external view returns (uint); function isTokenAliveInASpecificSeason(uint tokenId, uint _season) external view returns (bool); function hasParticipatedInCurrentOrLastRoyale(address _player) external view returns (bool); function getTokenPositions(uint tokenId) external view returns (IPassportPosition.Position[] memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.16; interface IPassportPosition { struct Position { uint round; uint position; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-4.4.1/utils/Strings.sol"; import "base64-sol/base64.sol"; import "../../interfaces/IPassportPosition.sol"; /// @title NFTSVG /// @notice Provides a function for generating an SVG associated with a ThalesRoyalePassport NFT library NFTSVG { using Strings for uint; struct SVGParams { address player; uint timestamp; uint tokenId; uint season; uint round; IPassportPosition.Position[] positions; bool alive; bool seasonFinished; } function generateSVG(SVGParams memory params) internal pure returns (string memory svg) { if (!params.alive) { svg = string(abi.encodePacked(generateSVGEliminated(params.season, params.tokenId))); } else { svg = string( abi.encodePacked( generateSVGBase(), generateSVGData(params.player, params.tokenId, params.timestamp, params.season, params.seasonFinished), generateSVGStamps(params.positions, params.round, params.seasonFinished), generateSVGBackground() ) ); } } function generateSVGBase() private pure returns (string memory svg) { svg = string( abi.encodePacked( '<svg viewBox="0 0 350 550" fill="none" xmlns="http://www.w3.org/2000/svg">', '<g class="background">', '<path id="gornji" d="M350 0H0V275H350V0Z" fill="url(#paint0_linear_44_340)"/>', '<path id="donji" d="M350 275H0V550H350V275Z" fill="url(#paint1_linear_44_340)"/>', "</g>", '<g class="logoRoyale">', '<rect id="rectangle" x="123.113" y="33.2568" width="27" height="27" stroke="#7F6F6F" stroke-width="3.35159"/>', '<circle id="krug" cx="224.402" cy="47.0822" r="13.4064" stroke="#7F6F6F" stroke-width="3.35159"/>', '<path id="triangle" d="M168.589 59.5459L182.557 35.3516L196.526 59.5459H168.589Z" stroke="#7F6F6F" stroke-width="3.35159"/></g>', '<text x="36" y="85" font-family="Courier New" font-size="21" fill="#7F6F6F">Thales Royale Passport</text>' ) ); } function generateSVGEliminated(uint season, uint tokenId) private pure returns (string memory svg) { svg = string( abi.encodePacked( generateSVGBase(), '<text x="120" y="115" font-family="Helvetica" font-size="24" fill="#7F6F6F">SEASON ', Strings.toString(season), '</text>', '<text x="60" y="240" font-family="Courier New" font-size="38" fill="#D10019" text-decoration="line-through">ELIMINATED</text>', '<text x="50" y="520" font-family="Courier New" font-size="20" fill="#7F6F6F">Passport No: #', Strings.toString(tokenId), '</text>', generateSVGBackground() ) ); } function generateSVGData( address player, uint tokenId, uint timestamp, uint season, bool seasonFinished ) private pure returns (string memory svg) { svg = string( abi.encodePacked( '<text x="', seasonFinished ? '63' : '120', '" y="115" font-family="Helvetica" font-size="24" fill="#7F6F6F">', seasonFinished ? 'WINNER SEASON ' : 'SEASON ', Strings.toString(season), '</text>', '<text x="10" y="460" font-family="Courier New" font-size="13" fill="#7F6F6F">', addressToString(player), '</text>', '<text x="30" y="490" font-family="Courier New" font-size="20" fill="#7F6F6F">Issued On: ', Strings.toString(timestamp), '</text>', '<text x="50" y="520" font-family="Courier New" font-size="20" fill="#7F6F6F">Passport No: #', Strings.toString(tokenId), '</text>' ) ); } function generateSVGStamps(IPassportPosition.Position[] memory positions, uint currentRound, bool seasonFinished) private pure returns (string memory stamps) { stamps = string(abi.encodePacked("")); uint rounds = seasonFinished ? currentRound - 1 : currentRound; for (uint i = 0; i < positions.length; i++) { uint position = positions[i].position; uint round = positions[i].round; if (rounds >= round) { string memory stamp = generateSVGStamp(round, position); stamps = string(abi.encodePacked(stamps, stamp)); } } } function generateSVGStamp( uint round, uint position ) private pure returns (string memory stamp) { string memory item = ""; if (round == 1) { item = position == 1 ? '<circle cx="72.5005" cy="200.5" r="28" transform="rotate(-9.01508 72.5005 200.5)" stroke="#D10019"/><text x="63" y="215" font-family="Courier New" font-size="40" rotate="-9" fill="#D10019">1</text>' : '<path d="M41.7387 226.599L69.954 167.136L107.343 221.302L41.7387 226.599Z" stroke="#00957E"/><text x="63" y="215" font-family="Courier New" font-size="40" rotate="-9" fill="#00957E">1</text>'; } else if (round == 2) { item = position == 1 ? '<circle cx="72.9395" cy="288.94" r="28" transform="rotate(12.3593 72.9395 288.94)" stroke="#D10019"/><text x="59" y="299" font-family="Courier New" font-size="40" rotate="13" fill="#D10019">2</text>' : '<path d="M35.7644 295.445L80.2057 246.896L100.029 309.658L35.7644 295.445Z" stroke="#00957E"/><text x="59" y="293" font-family="Courier New" font-size="40" rotate="15" fill="#00957E">2</text>'; } else if (round == 3) { item = position == 1 ? '<circle cx="145.903" cy="304.902" r="28" transform="rotate(-14.9925 145.903 304.902)" stroke="#D10019"/><text x="139" y="322" font-family="Courier New" font-size="40" rotate="-18" fill="#D10019">3</text>' : '<path d="M128.895 330.635L145.93 267.059L192.47 313.6L128.895 330.635Z" stroke="#00957E"/><text x="147" y="319" font-family="Courier New" font-size="40" rotate="-18" fill="#00957E">3</text>'; } else if (round == 4) { item = position == 1 ? '<circle cx="175.979" cy="262.979" r="28" transform="rotate(3.05675 175.979 262.979)" stroke="#D10019"/><text x="162" y="276" font-family="Courier New" font-size="40" rotate="3" fill="#D10019">4</text>' : '<path d="M150.739 289.599L178.954 230.136L216.343 284.302L150.739 289.599Z" stroke="#00957E"/><text x="170" y="281" font-family="Courier New" font-size="40" rotate="-7" fill="#00957E">4</text>'; } else if (round == 5) { item = position == 1 ? '<circle cx="279.614" cy="230.614" r="28" transform="rotate(-9.01508 279.614 230.614)" stroke="#D10019"/><text x="271" y="246" font-family="Courier New" font-size="40" rotate="-9" fill="#D10019">5</text>' : '<path d="M233.007 266.845L266.205 210.013L298.824 267.18L233.007 266.845Z" stroke="#00957E"/><text x="255" y="260" font-family="Courier New" font-size="40" fill="#00957E">5</text>'; } else { item = position == 1 ? '<circle cx="273.833" cy="332.833" r="28" transform="rotate(14.7947 273.833 332.833)" stroke="#D10019"/><text x="258" y="343" font-family="Courier New" font-size="40" rotate="9" fill="#D10019">6</text>' : '<path d="M203.483 347.285L240.321 292.742L269.138 351.916L203.483 347.285Z" stroke="#00957E"/><text x="224" y="342" font-family="Courier New" font-size="40" fill="#00957E">6</text>'; } stamp = string(abi.encodePacked(item)); } function generateSVGBackground() internal pure returns (string memory) { return string( abi.encodePacked( '<defs><linearGradient id="paint0_linear_44_340" x1="174.381" y1="274.968" x2="175.554" y2="36.6047" gradientUnits="userSpaceOnUse">', '<stop stop-color="#E3D4C7"/><stop offset="0.0547" stop-color="#E6D9CE"/><stop offset="0.2045" stop-color="#ECE2D9"/><stop offset="0.4149" stop-color="#EFE7E0"/>', '<stop offset="1" stop-color="#F0E8E2"/></linearGradient>', '<linearGradient id="paint1_linear_44_340" x1="0.00270863" y1="412.497" x2="350.002" y2="412.497" gradientUnits="userSpaceOnUse">' '<stop stop-color="#EEE4DC"/><stop offset="1" stop-color="#F7F3EF"/></linearGradient></defs></svg>' ) ); } function addressToString(address _addr) internal pure returns (string memory) { bytes memory s = new bytes(40); for (uint i = 0; i < 20; i++) { bytes1 b = bytes1(uint8(uint256(uint160(_addr)) / (2**(8 * (19 - i))))); bytes1 hi = bytes1(uint8(b) / 16); bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi)); s[2 * i] = _char(hi); s[2 * i + 1] = _char(lo); } return string(abi.encodePacked("0x", string(s))); } function _char(bytes1 b) private pure returns (bytes1 c) { if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); else return bytes1(uint8(b) + 0x57); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-4.4.1/utils/Strings.sol"; import "./NFTSVG.sol"; import "base64-sol/base64.sol"; library NFTDescriptor { function constructTokenURI(NFTSVG.SVGParams memory params) internal pure returns (string memory) { string memory svg = generateSVGImage(params); string memory imageURI = generateImageURI(svg); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode( bytes( abi.encodePacked( '{"name":"', "Thales Royale Passport", '", "description": "', generateDescription(params.season), '", "attributes":"", "image":"', imageURI, '"}' ) ) ) ) ); } function generateDescription(uint season) private pure returns (string memory) { return string(abi.encodePacked("Thales Royale Passport - season ", Strings.toString(season))); } function generateSVGImage(NFTSVG.SVGParams memory params) private pure returns (string memory svg) { return NFTSVG.generateSVG( NFTSVG.SVGParams( params.player, params.timestamp, params.tokenId, params.season, params.round, params.positions, params.alive, params.seasonFinished ) ); } function generateImageURI(string memory svg) private pure returns (string memory) { string memory baseURL = "data:image/svg+xml;base64,"; string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(svg)))); return string(abi.encodePacked(baseURL, svgBase64Encoded)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721Upgradeable.sol"; import "./IERC721ReceiverUpgradeable.sol"; import "./extensions/IERC721MetadataUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../utils/StringsUpgradeable.sol"; import "../../utils/introspection/ERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.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 ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable 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. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).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 = ERC721Upgradeable.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 { _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: 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 = ERC721Upgradeable.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 = ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {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 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 IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.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 {} uint256[44] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 IERC721ReceiverUpgradeable { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @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 v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.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 ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; }
// 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 IERC165Upgradeable { /** * @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 v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ 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); } }
// SPDX-License-Identifier: MIT /// @title Base64 /// @author Brecht Devos - <[email protected]> /// @notice Provides a function for encoding some bytes in base64 library Base64 { string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function encode(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; // load the table into memory string memory table = TABLE; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((data.length + 2) / 3); // add some extra buffer at the end required for the writing string memory result = new string(encodedLen + 32); assembly { // set the actual output length mstore(result, encodedLen) // prepare the lookup table let tablePtr := add(table, 1) // input ptr let dataPtr := data let endPtr := add(dataPtr, mload(data)) // result ptr, jump over length let resultPtr := add(result, 32) // run over the input, 3 bytes at a time for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) // read 3 bytes let input := mload(dataPtr) // write 4 characters mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) resultPtr := add(resultPtr, 1) } // padding with '=' switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_baseURI","type":"string"}],"name":"BaseUriChanged","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_thalesRoyaleAddress","type":"address"}],"name":"ThalesRoyaleAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ThalesRoyalePassportBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ThalesRoyalePassportMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_state","type":"bool"}],"name":"ThalesRoyalePassportPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"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":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_thalesRoyaleAddress","type":"address"},{"internalType":"string","name":"_baseUri","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","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":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"safeMint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"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":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","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":"_baseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_thalesRoyaleAddress","type":"address"}],"name":"setThalesRoyale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thalesRoyale","outputs":[{"internalType":"contract IThalesRoyale","name":"","type":"address"}],"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":"","type":"uint256"}],"name":"tokenTimestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"imageURI","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":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614ffb806100206000396000f3fe608060405234801561001057600080fd5b506004361061021c5760003560e01c80636352211e11610125578063a22cb465116100ad578063d547741f1161007c578063d547741f14610472578063e5a6ab9714610485578063e985e9c514610498578063f2fde38b146104d4578063f399e22e146104e757600080fd5b8063a22cb46514610425578063a3c4a50b14610438578063b88d4fde1461044c578063c87b56dd1461045f57600080fd5b80638da5cb5b116100f45780638da5cb5b146103e857806391d14854146103fa57806395d89b411461040d5780639abc832014610415578063a217fddf1461041d57600080fd5b80636352211e146103b257806370a08231146103c5578063715018a6146103d85780638456cb59146103e057600080fd5b80632f745c59116101a857806342842e0e1161017757806342842e0e1461035b57806342966c681461036e5780634f6ccce71461038157806355f804b3146103945780635c975abb146103a757600080fd5b80632f745c591461031a57806336568abe1461032d5780633f4ba83a1461034057806340d097c31461034857600080fd5b806318160ddd116101ef57806318160ddd1461029e57806323b872dd146102b0578063248a9ca3146102c35780632c043bdf146102e65780632f2ff15d1461030757600080fd5b806301ffc9a71461022157806306fdde0314610249578063081812fc1461025e578063095ea7b314610289575b600080fd5b61023461022f3660046133ff565b6104fa565b60405190151581526020015b60405180910390f35b61025161050b565b60405161024091906141ce565b61027161026c3660046133c5565b61059d565b6040516001600160a01b039091168152602001610240565b61029c6102973660046132b6565b610637565b005b6099545b604051908152602001610240565b61029c6102be366004613180565b61074d565b6102a26102d13660046133c5565b600090815260fb602052604090206001015490565b6102a26102f43660046133c5565b6101936020526000908152604090205481565b61029c6103153660046133dd565b61077e565b6102a26103283660046132b6565b6107a4565b61029c61033b3660046133dd565b61083a565b61029c6108b8565b6102a2610356366004613134565b610922565b61029c610369366004613180565b610a12565b61029c61037c3660046133c5565b610a2d565b6102a261038f3660046133c5565b610b22565b61029c6103a2366004613437565b610bc3565b60c95460ff16610234565b6102716103c03660046133c5565b610c3d565b6102a26103d3366004613134565b610cb4565b61029c610d3b565b61029c610d72565b61015f546001600160a01b0316610271565b6102346104083660046133dd565b610dd6565b610251610e01565b610251610e10565b6102a2600081565b61029c610433366004613234565b610e9f565b61019254610271906001600160a01b031681565b61029c61045a3660046131bb565b610eaa565b61025161046d3660046133c5565b610ee2565b61029c6104803660046133dd565b611252565b61029c610493366004613134565b611278565b6102346104a636600461314e565b6001600160a01b039182166000908152606a6020908152604080832093909416825291909152205460ff1690565b61029c6104e2366004613134565b61133a565b61029c6104f536600461326a565b6113d6565b60006105058261151c565b92915050565b60606065805461051a906145a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610546906145a3565b80156105935780601f1061056857610100808354040283529160200191610593565b820191906000526020600020905b81548152906001019060200180831161057657829003601f168201915b5050505050905090565b6000818152606760205260408120546001600160a01b031661061b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152606960205260409020546001600160a01b031690565b600061064282610c3d565b9050806001600160a01b0316836001600160a01b031614156106b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610612565b336001600160a01b03821614806106cc57506106cc81336104a6565b61073e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610612565b6107488383611541565b505050565b61075733826115af565b6107735760405162461bcd60e51b815260040161061290614292565b6107488383836116a6565b600082815260fb602052604090206001015461079a8133611851565b61074883836118b5565b60006107af83610cb4565b82106108115760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610612565b506001600160a01b03919091166000908152609760209081526040808320938352929052205490565b6001600160a01b03811633146108aa5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610612565b6108b4828261193b565b5050565b61015f546001600160a01b031633146108e35760405162461bcd60e51b81526004016106129061425d565b6108eb6119a2565b604051600081527f409e871c0bd55a50c69b290e362b9f868b683de93b66b36250d6f99ef4cef7a5906020015b60405180910390a1565b600061093060c95460ff1690565b1561094d5760405162461bcd60e51b815260040161061290614233565b610192546001600160a01b0316331461099a5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610612565b6109a961019180546001019055565b50610191546109b88282611a30565b6000818152610193602090815260409182902042905581516001600160a01b03851681529081018390527fde8317d4b743bc551ee2e135cf15b8066c4d4ec3d072e7db3d3d937e8f4c0fc6910160405180910390a1919050565b61074883838360405180602001604052806000815250610eaa565b60008181526067602052604090205481906001600160a01b0316610a8c5760405162461bcd60e51b815260206004820152601660248201527514185cdcdc1bdc9d08191bd95cdb89dd08195e1a5cdd60521b6044820152606401610612565b610a9633826115af565b610ae25760405162461bcd60e51b815260206004820152601960248201527f4d757374206265206f776e6572206f7220617070726f766572000000000000006044820152606401610612565b610aeb82611a4a565b6040518281527f073666f33e3218b342fab90adfc0fae0327786dedfb76201b7137cdb12b027969060200160405180910390a15050565b6000610b2d60995490565b8210610b905760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610612565b60998281548110610bb157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b61015f546001600160a01b03163314610bee5760405162461bcd60e51b81526004016106129061425d565b8051610c029061019490602084019061300d565b507f87cdeaffd8e70903d6ce7cc983fac3b09ca79e83818124c98e47a1d70f8027d681604051610c3291906141ce565b60405180910390a150565b6000818152606760205260408120546001600160a01b0316806105055760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610612565b60006001600160a01b038216610d1f5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610612565b506001600160a01b031660009081526068602052604090205490565b61015f546001600160a01b03163314610d665760405162461bcd60e51b81526004016106129061425d565b610d706000611af1565b565b61015f546001600160a01b03163314610d9d5760405162461bcd60e51b81526004016106129061425d565b610da5611b44565b604051600181527f409e871c0bd55a50c69b290e362b9f868b683de93b66b36250d6f99ef4cef7a590602001610918565b600091825260fb602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606066805461051a906145a3565b6101948054610e1e906145a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4a906145a3565b8015610e975780601f10610e6c57610100808354040283529160200191610e97565b820191906000526020600020905b815481529060010190602001808311610e7a57829003601f168201915b505050505081565b6108b4338383611b9c565b610eb433836115af565b610ed05760405162461bcd60e51b815260040161061290614292565b610edc84848484611c6b565b50505050565b6000818152606760205260409020546060906001600160a01b0316610f425760405162461bcd60e51b815260206004820152601660248201527514185cdcdc1bdc9d08191bd95cdb89dd08195e1a5cdd60521b6044820152606401610612565b6000610f4d83610c3d565b600084815261019360205260408082205461019254915163073340eb60e21b815260048101889052939450926001600160a01b0390911690631ccd03ac9060240160206040518083038186803b158015610fa657600080fd5b505afa158015610fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fde919061346a565b61019254604051630340db6d60e31b8152600481018390529192506000916001600160a01b0390911690631a06db689060240160206040518083038186803b15801561102957600080fd5b505afa15801561103d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611061919061346a565b6101925460405163ce4b7eeb60e01b815260048101899052602481018590529192506000916001600160a01b039091169063ce4b7eeb9060440160206040518083038186803b1580156110b357600080fd5b505afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb91906133a9565b6101925460405162bc77f160e41b8152600481018a90529192506000916001600160a01b0390911690630bc77f109060240160006040518083038186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261117191908101906132df565b61019254604051634285253560e01b8152600481018790529192506000916001600160a01b039091169063428525359060240160206040518083038186803b1580156111bc57600080fd5b505afa1580156111d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f491906133a9565b9050611245604051806101000160405280896001600160a01b031681526020018881526020018b81526020018781526020018681526020018481526020018515158152602001831515815250611c9e565b9998505050505050505050565b600082815260fb602052604090206001015461126e8133611851565b610748838361193b565b61015f546001600160a01b031633146112a35760405162461bcd60e51b81526004016106129061425d565b6001600160a01b0381166112eb5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610612565b61019280546001600160a01b0319166001600160a01b0383169081179091556040519081527fa6f6a897b8257a5b528068e657971c4b077cb36c88b7962c3965ace9fd7556b790602001610c32565b61015f546001600160a01b031633146113655760405162461bcd60e51b81526004016106129061425d565b6001600160a01b0381166113ca5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610612565b6113d381611af1565b50565b600054610100900460ff166113f15760005460ff16156113f5565b303b155b6114585760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610612565b600054610100900460ff1615801561147a576000805461ffff19166101011790555b611482611d18565b6114d560405180604001604052806016815260200175151a185b195cc8149bde585b194814185cdcdc1bdc9d60521b8152506040518060400160405280600381526020016254525360e81b815250611d4f565b61019280546001600160a01b0319166001600160a01b03851617905581516115059061019490602085019061300d565b508015610748576000805461ff0019169055505050565b60006001600160e01b03198216637965db0b60e01b1480610505575061050582611d90565b600081815260696020526040902080546001600160a01b0319166001600160a01b038416908117909155819061157682610c3d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152606760205260408120546001600160a01b03166116285760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610612565b600061163383610c3d565b9050806001600160a01b0316846001600160a01b0316148061166e5750836001600160a01b03166116638461059d565b6001600160a01b0316145b8061169e57506001600160a01b038082166000908152606a602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166116b982610c3d565b6001600160a01b0316146117215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610612565b6001600160a01b0382166117835760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610612565b61178e838383611db5565b611799600082611541565b6001600160a01b03831660009081526068602052604081208054600192906117c2908490614526565b90915550506001600160a01b03821660009081526068602052604081208054600192906117f0908490614388565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61185b8282610dd6565b6108b457611873816001600160a01b03166014611de3565b61187e836020611de3565b60405160200161188f9291906140d7565b60408051601f198184030181529082905262461bcd60e51b8252610612916004016141ce565b6118bf8282610dd6565b6108b457600082815260fb602090815260408083206001600160a01b03851684529091529020805460ff191660011790556118f73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6119458282610dd6565b156108b457600082815260fb602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60c95460ff166119eb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610612565b60c9805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b039091168152602001610918565b6108b4828260405180602001604052806000815250611fcc565b6000611a5582610c3d565b9050611a6381600084611db5565b611a6e600083611541565b6001600160a01b0381166000908152606860205260408120805460019290611a97908490614526565b909155505060008281526067602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b61015f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60c95460ff1615611b675760405162461bcd60e51b815260040161061290614233565b60c9805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a183390565b816001600160a01b0316836001600160a01b03161415611bfe5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610612565b6001600160a01b038381166000818152606a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611c768484846116a6565b611c8284848484611fff565b610edc5760405162461bcd60e51b8152600401610612906141e1565b60606000611cab8361210c565b90506000611cb88261217d565b9050611cf0611cca85606001516121e4565b82604051602001611cdc929190613769565b604051602081830303815290604052612215565b604051602001611d009190613a11565b60405160208183030381529060405292505050919050565b600054610100900460ff16611d3f5760405162461bcd60e51b8152600401610612906142e3565b611d4761238b565b610d706123b2565b600054610100900460ff16611d765760405162461bcd60e51b8152600401610612906142e3565b611d7e61238b565b611d8661238b565b6108b482826123e2565b60006001600160e01b0319821663780e9d6360e01b1480610505575061050582612430565b60c95460ff1615611dd85760405162461bcd60e51b815260040161061290614233565b610748838383612480565b60606000611df28360026144e6565b611dfd906002614388565b67ffffffffffffffff811115611e2357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611e4d576020820181803683370190505b509050600360fc1b81600081518110611e7657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611eb357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000611ed78460026144e6565b611ee2906001614388565b90505b6001811115611f76576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611f2457634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110611f4857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93611f6f8161458c565b9050611ee5565b508315611fc55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610612565b9392505050565b611fd68383612538565b611fe36000848484611fff565b6107485760405162461bcd60e51b8152600401610612906141e1565b60006001600160a01b0384163b1561210157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612043903390899088908890600401614191565b602060405180830381600087803b15801561205d57600080fd5b505af192505050801561208d575060408051601f3d908101601f1916820190925261208a9181019061341b565b60015b6120e7573d8080156120bb576040519150601f19603f3d011682016040523d82523d6000602084013e6120c0565b606091505b5080516120df5760405162461bcd60e51b8152600401610612906141e1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061169e565b506001949350505050565b606061050560405180610100016040528084600001516001600160a01b03168152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460a0015181526020018460c00151151581526020018460e001511515815250612686565b606060006040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000815250905060006121cf84604051602001611cdc919061353f565b90508181604051602001611d0092919061355b565b60606121ef82612713565b6040516020016121ff919061414c565b6040516020818303038152906040529050919050565b606081516000141561223557505060408051602081019091526000815290565b6000604051806060016040528060408152602001614b0560409139905060006003845160026122649190614388565b61226e91906143c5565b6122799060046144e6565b90506000612288826020614388565b67ffffffffffffffff8111156122ae57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156122d8576020820181803683370190505b509050818152600183018586518101602084015b818310156123465760039283018051603f601282901c811687015160f890811b8552600c83901c8216880151811b6001860152600683901c8216880151811b60028601529116860151901b938201939093526004016122ec565b60038951066001811461236057600281146123715761237d565b613d3d60f01b60011983015261237d565b603d60f81b6000198301525b509398975050505050505050565b600054610100900460ff16610d705760405162461bcd60e51b8152600401610612906142e3565b600054610100900460ff166123d95760405162461bcd60e51b8152600401610612906142e3565b610d7033611af1565b600054610100900460ff166124095760405162461bcd60e51b8152600401610612906142e3565b815161241c90606590602085019061300d565b50805161074890606690602084019061300d565b60006001600160e01b031982166380ac58cd60e01b148061246157506001600160e01b03198216635b5e139f60e01b145b8061050557506301ffc9a760e01b6001600160e01b0319831614610505565b6001600160a01b0383166124db576124d681609980546000838152609a60205260408120829055600182018355919091527f72a152ddfb8e864297c917af52ea6c1c68aead0fee1a62673fcc7e0c94979d000155565b6124fe565b816001600160a01b0316836001600160a01b0316146124fe576124fe838261282d565b6001600160a01b03821661251557610748816128ca565b826001600160a01b0316826001600160a01b0316146107485761074882826129a3565b6001600160a01b03821661258e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610612565b6000818152606760205260409020546001600160a01b0316156125f35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610612565b6125ff60008383611db5565b6001600160a01b0382166000908152606860205260408120805460019290612628908490614388565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608160c001516126b3576126a3826060015183604001516129e7565b6040516020016121ff919061353f565b6126bb612a35565b6126dc83600001518460400151856020015186606001518760e00151612a5a565b6126f38460a0015185608001518660e00151612b43565b6126fb612c31565b6040516020016121ff949392919061358a565b919050565b6060816127375750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612761578061274b816145de565b915061275a9050600a836143c5565b915061273b565b60008167ffffffffffffffff81111561278a57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156127b4576020820181803683370190505b5090505b841561169e576127c9600183614526565b91506127d6600a866145f9565b6127e1906030614388565b60f81b81838151811061280457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612826600a866143c5565b94506127b8565b6000600161283a84610cb4565b6128449190614526565b600083815260986020526040902054909150808214612897576001600160a01b03841660009081526097602090815260408083208584528252808320548484528184208190558352609890915290208190555b5060009182526098602090815260408084208490556001600160a01b039094168352609781528383209183525290812055565b6099546000906128dc90600190614526565b6000838152609a60205260408120546099805493945090928490811061291257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806099838154811061294157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152609a9091526040808220849055858252812055609980548061298757634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b60006129ae83610cb4565b6001600160a01b039093166000908152609760209081526040808320868452825280832085905593825260989052919091209190915550565b60606129f1612a35565b6129fa84612713565b612a0384612713565b612a0b612c31565b604051602001612a1e94939291906135e1565b604051602081830303815290604052905092915050565b6060604051602001612a4690613a56565b604051602081830303815290604052905090565b606081612a82576040518060400160405280600381526020016203132360ec1b815250612a9e565b60405180604001604052806002815260200161363360f01b8152505b82612ac85760405180604001604052806007815260200166029a2a0a9a7a7160cd1b815250612af0565b6040518060400160405280600e81526020016d02ba4a72722a91029a2a0a9a7a7160951b8152505b612af985612713565b612b0289612c42565b612b0b88612713565b612b148a612713565b604051602001612b299695949392919061384b565b604051602081830303815290604052905095945050505050565b604080516000808252602082019092529082612b5f5783612b6a565b612b6a600185614526565b905060005b8551811015612c28576000868281518110612b9a57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015190506000878381518110612bca57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001519050808410612c13576000612beb8284612dc7565b90508581604051602001612c0092919061355b565b6040516020818303038152906040529550505b50508080612c20906145de565b915050612b6f565b50509392505050565b6060604051602001612a4690613e01565b60408051602880825260608281019093526000919060208201818036833701905050905060005b6014811015612d9e576000612c7f826013614526565b612c8a9060086144e6565b612c9590600261443e565b612ca8906001600160a01b0387166143c5565b60f81b9050600060108260f81c612cbf91906143d9565b60f81b905060008160f81c6010612cd69190614505565b8360f81c612ce4919061453d565b60f81b9050612cf282612fd7565b85612cfe8660026144e6565b81518110612d1c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612d3c81612fd7565b85612d488660026144e6565b612d53906001614388565b81518110612d7157634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053505050508080612d96906145de565b915050612c69565b5080604051602001612db09190613821565b604051602081830303815290604052915050919050565b6040805160208101909152600081526060906001841415612e2a5782600114612e08576040518060e0016040528060be8152602001614c0a60be9139612e23565b60405180610100016040528060c58152602001614b4560c591395b9050612fae565b8360021415612e7a5782600114612e59576040518060e0016040528060bf8152602001614d9260bf9139612e23565b60405180610100016040528060c681526020016148b760c691399050612fae565b8360031415612eca5782600114612ea9576040518060e0016040528060bd815260200161497d60bd9139612e23565b60405180610100016040528060cb8152602001614a3a60cb91399050612fae565b8360041415612f1a5782600114612ef9576040518060e0016040528060c08152602001614f0660c09139612e23565b60405180610100016040528060c881526020016147ef60c891399050612fae565b8360051415612f6a5782600114612f49576040518060e0016040528060b3815260200161467460b39139612e23565b60405180610100016040528060ca8152602001614cc860ca91399050612fae565b82600114612f90576040518060e0016040528060b58152602001614e5160b59139612fab565b60405180610100016040528060c8815260200161472760c891395b90505b80604051602001612fbf919061353f565b60405160208183030381529060405291505092915050565b6000600a60f883901c1015612ffe57612ff560f883901c60306143a0565b60f81b92915050565b612ff560f883901c60576143a0565b828054613019906145a3565b90600052602060002090601f01602090048101928261303b5760008555613081565b82601f1061305457805160ff1916838001178555613081565b82800160010185558215613081579182015b82811115613081578251825591602001919060010190613066565b5061308d929150613091565b5090565b5b8082111561308d5760008155600101613092565b600067ffffffffffffffff8311156130c0576130c0614639565b6130d3601f8401601f1916602001614357565b90508281528383830111156130e757600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461270e57600080fd5b600082601f830112613125578081fd5b611fc5838335602085016130a6565b600060208284031215613145578081fd5b611fc5826130fe565b60008060408385031215613160578081fd5b613169836130fe565b9150613177602084016130fe565b90509250929050565b600080600060608486031215613194578081fd5b61319d846130fe565b92506131ab602085016130fe565b9150604084013590509250925092565b600080600080608085870312156131d0578081fd5b6131d9856130fe565b93506131e7602086016130fe565b925060408501359150606085013567ffffffffffffffff811115613209578182fd5b8501601f81018713613219578182fd5b613228878235602084016130a6565b91505092959194509250565b60008060408385031215613246578182fd5b61324f836130fe565b9150602083013561325f8161464f565b809150509250929050565b6000806040838503121561327c578182fd5b613285836130fe565b9150602083013567ffffffffffffffff8111156132a0578182fd5b6132ac85828601613115565b9150509250929050565b600080604083850312156132c8578182fd5b6132d1836130fe565b946020939093013593505050565b600060208083850312156132f1578182fd5b825167ffffffffffffffff80821115613308578384fd5b818501915085601f83011261331b578384fd5b81518181111561332d5761332d614639565b61333b848260051b01614357565b8181528481019250838501600683901b8501860189101561335a578687fd5b8694505b8285101561339d57604080828b031215613376578788fd5b61337e61432e565b825181528783015188820152855260019590950194938601930161335e565b50979650505050505050565b6000602082840312156133ba578081fd5b8151611fc58161464f565b6000602082840312156133d6578081fd5b5035919050565b600080604083850312156133ef578182fd5b82359150613177602084016130fe565b600060208284031215613410578081fd5b8135611fc58161465d565b60006020828403121561342c578081fd5b8151611fc58161465d565b600060208284031215613448578081fd5b813567ffffffffffffffff81111561345e578182fd5b61169e84828501613115565b60006020828403121561347b578081fd5b5051919050565b6000815180845261349a816020860160208601614560565b601f01601f19169290920160200192915050565b600081516134c0818560208601614560565b9290920192915050565b7f3c7465787420783d2235302220793d223532302220666f6e742d66616d696c7981527f3d22436f7572696572204e65772220666f6e742d73697a653d2232302220666960208201527f6c6c3d2223374636463646223e50617373706f7274204e6f3a202300000000006040820152605b0190565b60008251613551818460208701614560565b9190910192915050565b6000835161356d818460208801614560565b835190830190613581818360208801614560565b01949350505050565b6000855161359c818460208a01614560565b8551908301906135b0818360208a01614560565b85519101906135c3818360208901614560565b84519101906135d6818360208801614560565b019695505050505050565b600085516135f3818460208a01614560565b80830190507f3c7465787420783d223132302220793d223131352220666f6e742d66616d696c81527f793d2248656c7665746963612220666f6e742d73697a653d223234222066696c6020820152720361e91119ba31b231b23111f29a2a0a9a7a71606d1b60408201528551613670816053840160208a01614560565b661e17ba32bc3a1f60c91b605392909101918201527f3c7465787420783d2236302220793d223234302220666f6e742d66616d696c79605a8201527f3d22436f7572696572204e65772220666f6e742d73697a653d22333822206669607a8201527f6c6c3d22234431303031392220746578742d6465636f726174696f6e3d226c69609a8201527f6e652d7468726f756768223e454c494d494e415445443c2f746578743e00000060ba82015261372960d782016134ca565b9050845161373b818360208901614560565b61375d613757828401661e17ba32bc3a1f60c91b815260070190565b866134ae565b98975050505050505050565b683d913730b6b2911d1160b91b815275151a185b195cc8149bde585b194814185cdcdc1bdc9d60521b600982015272111610113232b9b1b934b83a34b7b7111d101160691b601f82015282516000906137c9816032850160208801614560565b7f222c202261747472696275746573223a22222c2022696d616765223a22000000603291840191820152835161380681604f840160208801614560565b61227d60f01b604f9290910191820152605101949350505050565b61060f60f31b81526000825161383e816002850160208701614560565b9190910160020192915050565b681e3a32bc3a103c1e9160b91b81528651600090613870816009850160208c01614560565b7f2220793d223131352220666f6e742d66616d696c793d2248656c7665746963616009918401918201527f2220666f6e742d73697a653d223234222066696c6c3d2223374636463646223e602982015287516138d3816049840160208c01614560565b87519101906138e9816049840160208b01614560565b661e17ba32bc3a1f60c91b604992909101918201527f3c7465787420783d2231302220793d223436302220666f6e742d66616d696c7960508201527f3d22436f7572696572204e65772220666f6e742d73697a653d2231332220666960708201526c36361e91119ba31b231b23111f60991b609082015261124561397e613757613a0c82613a0661399182609d89018e6134ae565b661e17ba32bc3a1f60c91b815260070190565b7f3c7465787420783d2233302220793d223439302220666f6e742d66616d696c7981527f3d22436f7572696572204e65772220666f6e742d73697a653d2232302220666960208201527f6c6c3d2223374636463646223e497373756564204f6e3a200000000000000000604082015260580190565b8a6134ae565b6134ca565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613a4981601d850160208701614560565b91909101601d0192915050565b7f3c7376672076696577426f783d223020302033353020353530222066696c6c3d81527f226e6f6e652220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f6020820152691918181817b9bb33911f60b11b6040820152751e339031b630b9b99e913130b1b5b3b937bab732111f60511b604a8201527f3c706174682069643d22676f726e6a692220643d224d3335302030483056323760608201527f354833353056305a222066696c6c3d2275726c28237061696e74305f6c696e6560808201526c30b92f9a1a2f999a181491179f60991b60a08201527f3c706174682069643d22646f6e6a692220643d224d333530203237354830563560ad8201527f353048333530563237355a222066696c6c3d2275726c28237061696e74315f6c60cd8201526f34b732b0b92f9a1a2f999a181491179f60811b60ed820152631e17b39f60e11b60fd820152751e339031b630b9b99e913637b3b7a937bcb0b632911f60511b6101018201527f3c726563742069643d2272656374616e676c652220783d223132332e313133226101178201527f20793d2233332e32353638222077696474683d22323722206865696768743d226101378201527f323722207374726f6b653d222337463646364622207374726f6b652d776964746101578201526c341e911997199a989a9c91179f60991b6101778201527f3c636972636c652069643d226b727567222063783d223232342e3430322220636101848201527f793d2234372e303832322220723d2231332e3430363422207374726f6b653d226101a48201527f2337463646364622207374726f6b652d77696474683d22332e3335313539222f6101c4820152601f60f91b6101e48201527f3c706174682069643d22747269616e676c652220643d224d3136382e353839206101e58201527f35392e353435394c3138322e3535372033352e333531364c3139362e353236206102058201527f35392e35343539483136382e3538395a22207374726f6b653d222337463646366102258201527f4622207374726f6b652d77696474683d22332e3335313539222f3e3c2f673e006102458201527f3c7465787420783d2233362220793d2238352220666f6e742d66616d696c793d6102648201527f22436f7572696572204e65772220666f6e742d73697a653d223231222066696c6102848201527f6c3d2223374636463646223e5468616c657320526f79616c652050617373706f6102a482015268393a1e17ba32bc3a1f60b91b6102c482015260006102cd8201610505565b7f3c646566733e3c6c696e6561724772616469656e742069643d227061696e743081527f5f6c696e6561725f34345f333430222078313d223137342e333831222079313d60208201527f223237342e393638222078323d223137352e353534222079323d2233362e363060408201527f343722206772616469656e74556e6974733d227573657253706163654f6e557360608201526232911f60e91b60808201527f3c73746f702073746f702d636f6c6f723d2223453344344337222f3e3c73746f60838201527f70206f66667365743d22302e30353437222073746f702d636f6c6f723d22234560a38201527f3644394345222f3e3c73746f70206f66667365743d22302e323034352220737460c38201527f6f702d636f6c6f723d2223454345324439222f3e3c73746f70206f666673657460e38201527f3d22302e34313439222073746f702d636f6c6f723d2223454645374530222f3e6101038201527f3c73746f70206f66667365743d2231222073746f702d636f6c6f723d222346306101238201527f45384532222f3e3c2f6c696e6561724772616469656e743e00000000000000006101438201527f3c6c696e6561724772616469656e742069643d227061696e74315f6c696e656161015b8201527f725f34345f333430222078313d22302e3030323730383633222079313d22343161017b8201527f322e343937222078323d223335302e303032222079323d223431322e3439372261019b8201527f206772616469656e74556e6974733d227573657253706163654f6e557365223e6101bb8201527f3c73746f702073746f702d636f6c6f723d2223454545344443222f3e3c73746f6101db8201527f70206f66667365743d2231222073746f702d636f6c6f723d22234637463345466101fb8201527f222f3e3c2f6c696e6561724772616469656e743e3c2f646566733e3c2f73766761021b820152601f60f91b61023b820152600061023c8201610505565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161410f816017850160208801614560565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614140816028840160208801614560565b01602801949350505050565b7f5468616c657320526f79616c652050617373706f7274202d20736561736f6e20815260008251614184816020850160208701614560565b9190910160200192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906141c490830184613482565b9695505050505050565b602081526000611fc56020830184613482565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6040805190810167ffffffffffffffff8111828210171561435157614351614639565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561438057614380614639565b604052919050565b6000821982111561439b5761439b61460d565b500190565b600060ff821660ff84168060ff038211156143bd576143bd61460d565b019392505050565b6000826143d4576143d4614623565b500490565b600060ff8316806143ec576143ec614623565b8060ff84160491505092915050565b600181815b8085111561443657816000190482111561441c5761441c61460d565b8085161561442957918102915b93841c9390800290614400565b509250929050565b6000611fc5838360008261445457506001610505565b8161446157506000610505565b816001811461447757600281146144815761449d565b6001915050610505565b60ff8411156144925761449261460d565b50506001821b610505565b5060208310610133831016604e8410600b84101617156144c0575081810a610505565b6144ca83836143fb565b80600019048211156144de576144de61460d565b029392505050565b60008160001904831182151516156145005761450061460d565b500290565b600060ff821660ff84168160ff04811182151516156144de576144de61460d565b6000828210156145385761453861460d565b500390565b600060ff821660ff8416808210156145575761455761460d565b90039392505050565b60005b8381101561457b578181015183820152602001614563565b83811115610edc5750506000910152565b60008161459b5761459b61460d565b506000190190565b600181811c908216806145b757607f821691505b602082108114156145d857634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156145f2576145f261460d565b5060010190565b60008261460857614608614623565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146113d357600080fd5b6001600160e01b0319811681146113d357600080fdfe3c7061746820643d224d3233332e303037203236362e3834354c3236362e323035203231302e3031334c3239382e383234203236372e31384c3233332e303037203236362e3834355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223235352220793d223236302220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d223430222066696c6c3d2223303039353745223e353c2f746578743e3c636972636c652063783d223237332e383333222063793d223333322e3833332220723d22323822207472616e73666f726d3d22726f746174652831342e37393437203237332e383333203333322e3833332922207374726f6b653d2223443130303139222f3e3c7465787420783d223235382220793d223334332220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d2239222066696c6c3d2223443130303139223e363c2f746578743e3c636972636c652063783d223137352e393739222063793d223236322e3937392220723d22323822207472616e73666f726d3d22726f7461746528332e3035363735203137352e393739203236322e3937392922207374726f6b653d2223443130303139222f3e3c7465787420783d223136322220793d223237362220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d2233222066696c6c3d2223443130303139223e343c2f746578743e3c636972636c652063783d2237322e39333935222063793d223238382e39342220723d22323822207472616e73666f726d3d22726f746174652831322e333539332037322e39333935203238382e39342922207374726f6b653d2223443130303139222f3e3c7465787420783d2235392220793d223239392220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d223133222066696c6c3d2223443130303139223e323c2f746578743e3c7061746820643d224d3132382e383935203333302e3633354c3134352e3933203236372e3035394c3139322e3437203331332e364c3132382e383935203333302e3633355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223134372220793d223331392220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d3138222066696c6c3d2223303039353745223e333c2f746578743e3c636972636c652063783d223134352e393033222063793d223330342e3930322220723d22323822207472616e73666f726d3d22726f74617465282d31342e39393235203134352e393033203330342e3930322922207374726f6b653d2223443130303139222f3e3c7465787420783d223133392220793d223332322220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d3138222066696c6c3d2223443130303139223e333c2f746578743e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c636972636c652063783d2237322e35303035222063793d223230302e352220723d22323822207472616e73666f726d3d22726f74617465282d392e30313530382037322e35303035203230302e352922207374726f6b653d2223443130303139222f3e3c7465787420783d2236332220793d223231352220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223443130303139223e313c2f746578743e3c7061746820643d224d34312e37333837203232362e3539394c36392e393534203136372e3133364c3130372e333433203232312e3330324c34312e37333837203232362e3539395a22207374726f6b653d2223303039353745222f3e3c7465787420783d2236332220793d223231352220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223303039353745223e313c2f746578743e3c636972636c652063783d223237392e363134222063793d223233302e3631342220723d22323822207472616e73666f726d3d22726f74617465282d392e3031353038203237392e363134203233302e3631342922207374726f6b653d2223443130303139222f3e3c7465787420783d223237312220793d223234362220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223443130303139223e353c2f746578743e3c7061746820643d224d33352e37363434203239352e3434354c38302e32303537203234362e3839364c3130302e303239203330392e3635384c33352e37363434203239352e3434355a22207374726f6b653d2223303039353745222f3e3c7465787420783d2235392220793d223239332220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d223135222066696c6c3d2223303039353745223e323c2f746578743e3c7061746820643d224d3230332e343833203334372e3238354c3234302e333231203239322e3734324c3236392e313338203335312e3931364c3230332e343833203334372e3238355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223232342220793d223334322220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d22343022202066696c6c3d2223303039353745223e363c2f746578743e3c7061746820643d224d3135302e373339203238392e3539394c3137382e393534203233302e3133364c3231362e333433203238342e3330324c3135302e373339203238392e3539395a22207374726f6b653d2223303039353745222f3e3c7465787420783d223137302220793d223238312220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d37222066696c6c3d2223303039353745223e343c2f746578743ea2646970667358221220804efb95ed7aa26c4b8241ca0a539f7d450db6c7b94989abbebe3dd19feb8f7964736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061021c5760003560e01c80636352211e11610125578063a22cb465116100ad578063d547741f1161007c578063d547741f14610472578063e5a6ab9714610485578063e985e9c514610498578063f2fde38b146104d4578063f399e22e146104e757600080fd5b8063a22cb46514610425578063a3c4a50b14610438578063b88d4fde1461044c578063c87b56dd1461045f57600080fd5b80638da5cb5b116100f45780638da5cb5b146103e857806391d14854146103fa57806395d89b411461040d5780639abc832014610415578063a217fddf1461041d57600080fd5b80636352211e146103b257806370a08231146103c5578063715018a6146103d85780638456cb59146103e057600080fd5b80632f745c59116101a857806342842e0e1161017757806342842e0e1461035b57806342966c681461036e5780634f6ccce71461038157806355f804b3146103945780635c975abb146103a757600080fd5b80632f745c591461031a57806336568abe1461032d5780633f4ba83a1461034057806340d097c31461034857600080fd5b806318160ddd116101ef57806318160ddd1461029e57806323b872dd146102b0578063248a9ca3146102c35780632c043bdf146102e65780632f2ff15d1461030757600080fd5b806301ffc9a71461022157806306fdde0314610249578063081812fc1461025e578063095ea7b314610289575b600080fd5b61023461022f3660046133ff565b6104fa565b60405190151581526020015b60405180910390f35b61025161050b565b60405161024091906141ce565b61027161026c3660046133c5565b61059d565b6040516001600160a01b039091168152602001610240565b61029c6102973660046132b6565b610637565b005b6099545b604051908152602001610240565b61029c6102be366004613180565b61074d565b6102a26102d13660046133c5565b600090815260fb602052604090206001015490565b6102a26102f43660046133c5565b6101936020526000908152604090205481565b61029c6103153660046133dd565b61077e565b6102a26103283660046132b6565b6107a4565b61029c61033b3660046133dd565b61083a565b61029c6108b8565b6102a2610356366004613134565b610922565b61029c610369366004613180565b610a12565b61029c61037c3660046133c5565b610a2d565b6102a261038f3660046133c5565b610b22565b61029c6103a2366004613437565b610bc3565b60c95460ff16610234565b6102716103c03660046133c5565b610c3d565b6102a26103d3366004613134565b610cb4565b61029c610d3b565b61029c610d72565b61015f546001600160a01b0316610271565b6102346104083660046133dd565b610dd6565b610251610e01565b610251610e10565b6102a2600081565b61029c610433366004613234565b610e9f565b61019254610271906001600160a01b031681565b61029c61045a3660046131bb565b610eaa565b61025161046d3660046133c5565b610ee2565b61029c6104803660046133dd565b611252565b61029c610493366004613134565b611278565b6102346104a636600461314e565b6001600160a01b039182166000908152606a6020908152604080832093909416825291909152205460ff1690565b61029c6104e2366004613134565b61133a565b61029c6104f536600461326a565b6113d6565b60006105058261151c565b92915050565b60606065805461051a906145a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610546906145a3565b80156105935780601f1061056857610100808354040283529160200191610593565b820191906000526020600020905b81548152906001019060200180831161057657829003601f168201915b5050505050905090565b6000818152606760205260408120546001600160a01b031661061b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152606960205260409020546001600160a01b031690565b600061064282610c3d565b9050806001600160a01b0316836001600160a01b031614156106b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610612565b336001600160a01b03821614806106cc57506106cc81336104a6565b61073e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610612565b6107488383611541565b505050565b61075733826115af565b6107735760405162461bcd60e51b815260040161061290614292565b6107488383836116a6565b600082815260fb602052604090206001015461079a8133611851565b61074883836118b5565b60006107af83610cb4565b82106108115760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610612565b506001600160a01b03919091166000908152609760209081526040808320938352929052205490565b6001600160a01b03811633146108aa5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610612565b6108b4828261193b565b5050565b61015f546001600160a01b031633146108e35760405162461bcd60e51b81526004016106129061425d565b6108eb6119a2565b604051600081527f409e871c0bd55a50c69b290e362b9f868b683de93b66b36250d6f99ef4cef7a5906020015b60405180910390a1565b600061093060c95460ff1690565b1561094d5760405162461bcd60e51b815260040161061290614233565b610192546001600160a01b0316331461099a5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610612565b6109a961019180546001019055565b50610191546109b88282611a30565b6000818152610193602090815260409182902042905581516001600160a01b03851681529081018390527fde8317d4b743bc551ee2e135cf15b8066c4d4ec3d072e7db3d3d937e8f4c0fc6910160405180910390a1919050565b61074883838360405180602001604052806000815250610eaa565b60008181526067602052604090205481906001600160a01b0316610a8c5760405162461bcd60e51b815260206004820152601660248201527514185cdcdc1bdc9d08191bd95cdb89dd08195e1a5cdd60521b6044820152606401610612565b610a9633826115af565b610ae25760405162461bcd60e51b815260206004820152601960248201527f4d757374206265206f776e6572206f7220617070726f766572000000000000006044820152606401610612565b610aeb82611a4a565b6040518281527f073666f33e3218b342fab90adfc0fae0327786dedfb76201b7137cdb12b027969060200160405180910390a15050565b6000610b2d60995490565b8210610b905760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610612565b60998281548110610bb157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b61015f546001600160a01b03163314610bee5760405162461bcd60e51b81526004016106129061425d565b8051610c029061019490602084019061300d565b507f87cdeaffd8e70903d6ce7cc983fac3b09ca79e83818124c98e47a1d70f8027d681604051610c3291906141ce565b60405180910390a150565b6000818152606760205260408120546001600160a01b0316806105055760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610612565b60006001600160a01b038216610d1f5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610612565b506001600160a01b031660009081526068602052604090205490565b61015f546001600160a01b03163314610d665760405162461bcd60e51b81526004016106129061425d565b610d706000611af1565b565b61015f546001600160a01b03163314610d9d5760405162461bcd60e51b81526004016106129061425d565b610da5611b44565b604051600181527f409e871c0bd55a50c69b290e362b9f868b683de93b66b36250d6f99ef4cef7a590602001610918565b600091825260fb602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606066805461051a906145a3565b6101948054610e1e906145a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4a906145a3565b8015610e975780601f10610e6c57610100808354040283529160200191610e97565b820191906000526020600020905b815481529060010190602001808311610e7a57829003601f168201915b505050505081565b6108b4338383611b9c565b610eb433836115af565b610ed05760405162461bcd60e51b815260040161061290614292565b610edc84848484611c6b565b50505050565b6000818152606760205260409020546060906001600160a01b0316610f425760405162461bcd60e51b815260206004820152601660248201527514185cdcdc1bdc9d08191bd95cdb89dd08195e1a5cdd60521b6044820152606401610612565b6000610f4d83610c3d565b600084815261019360205260408082205461019254915163073340eb60e21b815260048101889052939450926001600160a01b0390911690631ccd03ac9060240160206040518083038186803b158015610fa657600080fd5b505afa158015610fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fde919061346a565b61019254604051630340db6d60e31b8152600481018390529192506000916001600160a01b0390911690631a06db689060240160206040518083038186803b15801561102957600080fd5b505afa15801561103d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611061919061346a565b6101925460405163ce4b7eeb60e01b815260048101899052602481018590529192506000916001600160a01b039091169063ce4b7eeb9060440160206040518083038186803b1580156110b357600080fd5b505afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb91906133a9565b6101925460405162bc77f160e41b8152600481018a90529192506000916001600160a01b0390911690630bc77f109060240160006040518083038186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261117191908101906132df565b61019254604051634285253560e01b8152600481018790529192506000916001600160a01b039091169063428525359060240160206040518083038186803b1580156111bc57600080fd5b505afa1580156111d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f491906133a9565b9050611245604051806101000160405280896001600160a01b031681526020018881526020018b81526020018781526020018681526020018481526020018515158152602001831515815250611c9e565b9998505050505050505050565b600082815260fb602052604090206001015461126e8133611851565b610748838361193b565b61015f546001600160a01b031633146112a35760405162461bcd60e51b81526004016106129061425d565b6001600160a01b0381166112eb5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610612565b61019280546001600160a01b0319166001600160a01b0383169081179091556040519081527fa6f6a897b8257a5b528068e657971c4b077cb36c88b7962c3965ace9fd7556b790602001610c32565b61015f546001600160a01b031633146113655760405162461bcd60e51b81526004016106129061425d565b6001600160a01b0381166113ca5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610612565b6113d381611af1565b50565b600054610100900460ff166113f15760005460ff16156113f5565b303b155b6114585760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610612565b600054610100900460ff1615801561147a576000805461ffff19166101011790555b611482611d18565b6114d560405180604001604052806016815260200175151a185b195cc8149bde585b194814185cdcdc1bdc9d60521b8152506040518060400160405280600381526020016254525360e81b815250611d4f565b61019280546001600160a01b0319166001600160a01b03851617905581516115059061019490602085019061300d565b508015610748576000805461ff0019169055505050565b60006001600160e01b03198216637965db0b60e01b1480610505575061050582611d90565b600081815260696020526040902080546001600160a01b0319166001600160a01b038416908117909155819061157682610c3d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152606760205260408120546001600160a01b03166116285760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610612565b600061163383610c3d565b9050806001600160a01b0316846001600160a01b0316148061166e5750836001600160a01b03166116638461059d565b6001600160a01b0316145b8061169e57506001600160a01b038082166000908152606a602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166116b982610c3d565b6001600160a01b0316146117215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610612565b6001600160a01b0382166117835760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610612565b61178e838383611db5565b611799600082611541565b6001600160a01b03831660009081526068602052604081208054600192906117c2908490614526565b90915550506001600160a01b03821660009081526068602052604081208054600192906117f0908490614388565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61185b8282610dd6565b6108b457611873816001600160a01b03166014611de3565b61187e836020611de3565b60405160200161188f9291906140d7565b60408051601f198184030181529082905262461bcd60e51b8252610612916004016141ce565b6118bf8282610dd6565b6108b457600082815260fb602090815260408083206001600160a01b03851684529091529020805460ff191660011790556118f73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6119458282610dd6565b156108b457600082815260fb602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60c95460ff166119eb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610612565b60c9805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b039091168152602001610918565b6108b4828260405180602001604052806000815250611fcc565b6000611a5582610c3d565b9050611a6381600084611db5565b611a6e600083611541565b6001600160a01b0381166000908152606860205260408120805460019290611a97908490614526565b909155505060008281526067602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b61015f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60c95460ff1615611b675760405162461bcd60e51b815260040161061290614233565b60c9805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a183390565b816001600160a01b0316836001600160a01b03161415611bfe5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610612565b6001600160a01b038381166000818152606a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611c768484846116a6565b611c8284848484611fff565b610edc5760405162461bcd60e51b8152600401610612906141e1565b60606000611cab8361210c565b90506000611cb88261217d565b9050611cf0611cca85606001516121e4565b82604051602001611cdc929190613769565b604051602081830303815290604052612215565b604051602001611d009190613a11565b60405160208183030381529060405292505050919050565b600054610100900460ff16611d3f5760405162461bcd60e51b8152600401610612906142e3565b611d4761238b565b610d706123b2565b600054610100900460ff16611d765760405162461bcd60e51b8152600401610612906142e3565b611d7e61238b565b611d8661238b565b6108b482826123e2565b60006001600160e01b0319821663780e9d6360e01b1480610505575061050582612430565b60c95460ff1615611dd85760405162461bcd60e51b815260040161061290614233565b610748838383612480565b60606000611df28360026144e6565b611dfd906002614388565b67ffffffffffffffff811115611e2357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611e4d576020820181803683370190505b509050600360fc1b81600081518110611e7657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611eb357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000611ed78460026144e6565b611ee2906001614388565b90505b6001811115611f76576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611f2457634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110611f4857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93611f6f8161458c565b9050611ee5565b508315611fc55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610612565b9392505050565b611fd68383612538565b611fe36000848484611fff565b6107485760405162461bcd60e51b8152600401610612906141e1565b60006001600160a01b0384163b1561210157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612043903390899088908890600401614191565b602060405180830381600087803b15801561205d57600080fd5b505af192505050801561208d575060408051601f3d908101601f1916820190925261208a9181019061341b565b60015b6120e7573d8080156120bb576040519150601f19603f3d011682016040523d82523d6000602084013e6120c0565b606091505b5080516120df5760405162461bcd60e51b8152600401610612906141e1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061169e565b506001949350505050565b606061050560405180610100016040528084600001516001600160a01b03168152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460a0015181526020018460c00151151581526020018460e001511515815250612686565b606060006040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000815250905060006121cf84604051602001611cdc919061353f565b90508181604051602001611d0092919061355b565b60606121ef82612713565b6040516020016121ff919061414c565b6040516020818303038152906040529050919050565b606081516000141561223557505060408051602081019091526000815290565b6000604051806060016040528060408152602001614b0560409139905060006003845160026122649190614388565b61226e91906143c5565b6122799060046144e6565b90506000612288826020614388565b67ffffffffffffffff8111156122ae57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156122d8576020820181803683370190505b509050818152600183018586518101602084015b818310156123465760039283018051603f601282901c811687015160f890811b8552600c83901c8216880151811b6001860152600683901c8216880151811b60028601529116860151901b938201939093526004016122ec565b60038951066001811461236057600281146123715761237d565b613d3d60f01b60011983015261237d565b603d60f81b6000198301525b509398975050505050505050565b600054610100900460ff16610d705760405162461bcd60e51b8152600401610612906142e3565b600054610100900460ff166123d95760405162461bcd60e51b8152600401610612906142e3565b610d7033611af1565b600054610100900460ff166124095760405162461bcd60e51b8152600401610612906142e3565b815161241c90606590602085019061300d565b50805161074890606690602084019061300d565b60006001600160e01b031982166380ac58cd60e01b148061246157506001600160e01b03198216635b5e139f60e01b145b8061050557506301ffc9a760e01b6001600160e01b0319831614610505565b6001600160a01b0383166124db576124d681609980546000838152609a60205260408120829055600182018355919091527f72a152ddfb8e864297c917af52ea6c1c68aead0fee1a62673fcc7e0c94979d000155565b6124fe565b816001600160a01b0316836001600160a01b0316146124fe576124fe838261282d565b6001600160a01b03821661251557610748816128ca565b826001600160a01b0316826001600160a01b0316146107485761074882826129a3565b6001600160a01b03821661258e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610612565b6000818152606760205260409020546001600160a01b0316156125f35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610612565b6125ff60008383611db5565b6001600160a01b0382166000908152606860205260408120805460019290612628908490614388565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608160c001516126b3576126a3826060015183604001516129e7565b6040516020016121ff919061353f565b6126bb612a35565b6126dc83600001518460400151856020015186606001518760e00151612a5a565b6126f38460a0015185608001518660e00151612b43565b6126fb612c31565b6040516020016121ff949392919061358a565b919050565b6060816127375750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612761578061274b816145de565b915061275a9050600a836143c5565b915061273b565b60008167ffffffffffffffff81111561278a57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156127b4576020820181803683370190505b5090505b841561169e576127c9600183614526565b91506127d6600a866145f9565b6127e1906030614388565b60f81b81838151811061280457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612826600a866143c5565b94506127b8565b6000600161283a84610cb4565b6128449190614526565b600083815260986020526040902054909150808214612897576001600160a01b03841660009081526097602090815260408083208584528252808320548484528184208190558352609890915290208190555b5060009182526098602090815260408084208490556001600160a01b039094168352609781528383209183525290812055565b6099546000906128dc90600190614526565b6000838152609a60205260408120546099805493945090928490811061291257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806099838154811061294157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152609a9091526040808220849055858252812055609980548061298757634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b60006129ae83610cb4565b6001600160a01b039093166000908152609760209081526040808320868452825280832085905593825260989052919091209190915550565b60606129f1612a35565b6129fa84612713565b612a0384612713565b612a0b612c31565b604051602001612a1e94939291906135e1565b604051602081830303815290604052905092915050565b6060604051602001612a4690613a56565b604051602081830303815290604052905090565b606081612a82576040518060400160405280600381526020016203132360ec1b815250612a9e565b60405180604001604052806002815260200161363360f01b8152505b82612ac85760405180604001604052806007815260200166029a2a0a9a7a7160cd1b815250612af0565b6040518060400160405280600e81526020016d02ba4a72722a91029a2a0a9a7a7160951b8152505b612af985612713565b612b0289612c42565b612b0b88612713565b612b148a612713565b604051602001612b299695949392919061384b565b604051602081830303815290604052905095945050505050565b604080516000808252602082019092529082612b5f5783612b6a565b612b6a600185614526565b905060005b8551811015612c28576000868281518110612b9a57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015190506000878381518110612bca57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001519050808410612c13576000612beb8284612dc7565b90508581604051602001612c0092919061355b565b6040516020818303038152906040529550505b50508080612c20906145de565b915050612b6f565b50509392505050565b6060604051602001612a4690613e01565b60408051602880825260608281019093526000919060208201818036833701905050905060005b6014811015612d9e576000612c7f826013614526565b612c8a9060086144e6565b612c9590600261443e565b612ca8906001600160a01b0387166143c5565b60f81b9050600060108260f81c612cbf91906143d9565b60f81b905060008160f81c6010612cd69190614505565b8360f81c612ce4919061453d565b60f81b9050612cf282612fd7565b85612cfe8660026144e6565b81518110612d1c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612d3c81612fd7565b85612d488660026144e6565b612d53906001614388565b81518110612d7157634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053505050508080612d96906145de565b915050612c69565b5080604051602001612db09190613821565b604051602081830303815290604052915050919050565b6040805160208101909152600081526060906001841415612e2a5782600114612e08576040518060e0016040528060be8152602001614c0a60be9139612e23565b60405180610100016040528060c58152602001614b4560c591395b9050612fae565b8360021415612e7a5782600114612e59576040518060e0016040528060bf8152602001614d9260bf9139612e23565b60405180610100016040528060c681526020016148b760c691399050612fae565b8360031415612eca5782600114612ea9576040518060e0016040528060bd815260200161497d60bd9139612e23565b60405180610100016040528060cb8152602001614a3a60cb91399050612fae565b8360041415612f1a5782600114612ef9576040518060e0016040528060c08152602001614f0660c09139612e23565b60405180610100016040528060c881526020016147ef60c891399050612fae565b8360051415612f6a5782600114612f49576040518060e0016040528060b3815260200161467460b39139612e23565b60405180610100016040528060ca8152602001614cc860ca91399050612fae565b82600114612f90576040518060e0016040528060b58152602001614e5160b59139612fab565b60405180610100016040528060c8815260200161472760c891395b90505b80604051602001612fbf919061353f565b60405160208183030381529060405291505092915050565b6000600a60f883901c1015612ffe57612ff560f883901c60306143a0565b60f81b92915050565b612ff560f883901c60576143a0565b828054613019906145a3565b90600052602060002090601f01602090048101928261303b5760008555613081565b82601f1061305457805160ff1916838001178555613081565b82800160010185558215613081579182015b82811115613081578251825591602001919060010190613066565b5061308d929150613091565b5090565b5b8082111561308d5760008155600101613092565b600067ffffffffffffffff8311156130c0576130c0614639565b6130d3601f8401601f1916602001614357565b90508281528383830111156130e757600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461270e57600080fd5b600082601f830112613125578081fd5b611fc5838335602085016130a6565b600060208284031215613145578081fd5b611fc5826130fe565b60008060408385031215613160578081fd5b613169836130fe565b9150613177602084016130fe565b90509250929050565b600080600060608486031215613194578081fd5b61319d846130fe565b92506131ab602085016130fe565b9150604084013590509250925092565b600080600080608085870312156131d0578081fd5b6131d9856130fe565b93506131e7602086016130fe565b925060408501359150606085013567ffffffffffffffff811115613209578182fd5b8501601f81018713613219578182fd5b613228878235602084016130a6565b91505092959194509250565b60008060408385031215613246578182fd5b61324f836130fe565b9150602083013561325f8161464f565b809150509250929050565b6000806040838503121561327c578182fd5b613285836130fe565b9150602083013567ffffffffffffffff8111156132a0578182fd5b6132ac85828601613115565b9150509250929050565b600080604083850312156132c8578182fd5b6132d1836130fe565b946020939093013593505050565b600060208083850312156132f1578182fd5b825167ffffffffffffffff80821115613308578384fd5b818501915085601f83011261331b578384fd5b81518181111561332d5761332d614639565b61333b848260051b01614357565b8181528481019250838501600683901b8501860189101561335a578687fd5b8694505b8285101561339d57604080828b031215613376578788fd5b61337e61432e565b825181528783015188820152855260019590950194938601930161335e565b50979650505050505050565b6000602082840312156133ba578081fd5b8151611fc58161464f565b6000602082840312156133d6578081fd5b5035919050565b600080604083850312156133ef578182fd5b82359150613177602084016130fe565b600060208284031215613410578081fd5b8135611fc58161465d565b60006020828403121561342c578081fd5b8151611fc58161465d565b600060208284031215613448578081fd5b813567ffffffffffffffff81111561345e578182fd5b61169e84828501613115565b60006020828403121561347b578081fd5b5051919050565b6000815180845261349a816020860160208601614560565b601f01601f19169290920160200192915050565b600081516134c0818560208601614560565b9290920192915050565b7f3c7465787420783d2235302220793d223532302220666f6e742d66616d696c7981527f3d22436f7572696572204e65772220666f6e742d73697a653d2232302220666960208201527f6c6c3d2223374636463646223e50617373706f7274204e6f3a202300000000006040820152605b0190565b60008251613551818460208701614560565b9190910192915050565b6000835161356d818460208801614560565b835190830190613581818360208801614560565b01949350505050565b6000855161359c818460208a01614560565b8551908301906135b0818360208a01614560565b85519101906135c3818360208901614560565b84519101906135d6818360208801614560565b019695505050505050565b600085516135f3818460208a01614560565b80830190507f3c7465787420783d223132302220793d223131352220666f6e742d66616d696c81527f793d2248656c7665746963612220666f6e742d73697a653d223234222066696c6020820152720361e91119ba31b231b23111f29a2a0a9a7a71606d1b60408201528551613670816053840160208a01614560565b661e17ba32bc3a1f60c91b605392909101918201527f3c7465787420783d2236302220793d223234302220666f6e742d66616d696c79605a8201527f3d22436f7572696572204e65772220666f6e742d73697a653d22333822206669607a8201527f6c6c3d22234431303031392220746578742d6465636f726174696f6e3d226c69609a8201527f6e652d7468726f756768223e454c494d494e415445443c2f746578743e00000060ba82015261372960d782016134ca565b9050845161373b818360208901614560565b61375d613757828401661e17ba32bc3a1f60c91b815260070190565b866134ae565b98975050505050505050565b683d913730b6b2911d1160b91b815275151a185b195cc8149bde585b194814185cdcdc1bdc9d60521b600982015272111610113232b9b1b934b83a34b7b7111d101160691b601f82015282516000906137c9816032850160208801614560565b7f222c202261747472696275746573223a22222c2022696d616765223a22000000603291840191820152835161380681604f840160208801614560565b61227d60f01b604f9290910191820152605101949350505050565b61060f60f31b81526000825161383e816002850160208701614560565b9190910160020192915050565b681e3a32bc3a103c1e9160b91b81528651600090613870816009850160208c01614560565b7f2220793d223131352220666f6e742d66616d696c793d2248656c7665746963616009918401918201527f2220666f6e742d73697a653d223234222066696c6c3d2223374636463646223e602982015287516138d3816049840160208c01614560565b87519101906138e9816049840160208b01614560565b661e17ba32bc3a1f60c91b604992909101918201527f3c7465787420783d2231302220793d223436302220666f6e742d66616d696c7960508201527f3d22436f7572696572204e65772220666f6e742d73697a653d2231332220666960708201526c36361e91119ba31b231b23111f60991b609082015261124561397e613757613a0c82613a0661399182609d89018e6134ae565b661e17ba32bc3a1f60c91b815260070190565b7f3c7465787420783d2233302220793d223439302220666f6e742d66616d696c7981527f3d22436f7572696572204e65772220666f6e742d73697a653d2232302220666960208201527f6c6c3d2223374636463646223e497373756564204f6e3a200000000000000000604082015260580190565b8a6134ae565b6134ca565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613a4981601d850160208701614560565b91909101601d0192915050565b7f3c7376672076696577426f783d223020302033353020353530222066696c6c3d81527f226e6f6e652220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f6020820152691918181817b9bb33911f60b11b6040820152751e339031b630b9b99e913130b1b5b3b937bab732111f60511b604a8201527f3c706174682069643d22676f726e6a692220643d224d3335302030483056323760608201527f354833353056305a222066696c6c3d2275726c28237061696e74305f6c696e6560808201526c30b92f9a1a2f999a181491179f60991b60a08201527f3c706174682069643d22646f6e6a692220643d224d333530203237354830563560ad8201527f353048333530563237355a222066696c6c3d2275726c28237061696e74315f6c60cd8201526f34b732b0b92f9a1a2f999a181491179f60811b60ed820152631e17b39f60e11b60fd820152751e339031b630b9b99e913637b3b7a937bcb0b632911f60511b6101018201527f3c726563742069643d2272656374616e676c652220783d223132332e313133226101178201527f20793d2233332e32353638222077696474683d22323722206865696768743d226101378201527f323722207374726f6b653d222337463646364622207374726f6b652d776964746101578201526c341e911997199a989a9c91179f60991b6101778201527f3c636972636c652069643d226b727567222063783d223232342e3430322220636101848201527f793d2234372e303832322220723d2231332e3430363422207374726f6b653d226101a48201527f2337463646364622207374726f6b652d77696474683d22332e3335313539222f6101c4820152601f60f91b6101e48201527f3c706174682069643d22747269616e676c652220643d224d3136382e353839206101e58201527f35392e353435394c3138322e3535372033352e333531364c3139362e353236206102058201527f35392e35343539483136382e3538395a22207374726f6b653d222337463646366102258201527f4622207374726f6b652d77696474683d22332e3335313539222f3e3c2f673e006102458201527f3c7465787420783d2233362220793d2238352220666f6e742d66616d696c793d6102648201527f22436f7572696572204e65772220666f6e742d73697a653d223231222066696c6102848201527f6c3d2223374636463646223e5468616c657320526f79616c652050617373706f6102a482015268393a1e17ba32bc3a1f60b91b6102c482015260006102cd8201610505565b7f3c646566733e3c6c696e6561724772616469656e742069643d227061696e743081527f5f6c696e6561725f34345f333430222078313d223137342e333831222079313d60208201527f223237342e393638222078323d223137352e353534222079323d2233362e363060408201527f343722206772616469656e74556e6974733d227573657253706163654f6e557360608201526232911f60e91b60808201527f3c73746f702073746f702d636f6c6f723d2223453344344337222f3e3c73746f60838201527f70206f66667365743d22302e30353437222073746f702d636f6c6f723d22234560a38201527f3644394345222f3e3c73746f70206f66667365743d22302e323034352220737460c38201527f6f702d636f6c6f723d2223454345324439222f3e3c73746f70206f666673657460e38201527f3d22302e34313439222073746f702d636f6c6f723d2223454645374530222f3e6101038201527f3c73746f70206f66667365743d2231222073746f702d636f6c6f723d222346306101238201527f45384532222f3e3c2f6c696e6561724772616469656e743e00000000000000006101438201527f3c6c696e6561724772616469656e742069643d227061696e74315f6c696e656161015b8201527f725f34345f333430222078313d22302e3030323730383633222079313d22343161017b8201527f322e343937222078323d223335302e303032222079323d223431322e3439372261019b8201527f206772616469656e74556e6974733d227573657253706163654f6e557365223e6101bb8201527f3c73746f702073746f702d636f6c6f723d2223454545344443222f3e3c73746f6101db8201527f70206f66667365743d2231222073746f702d636f6c6f723d22234637463345466101fb8201527f222f3e3c2f6c696e6561724772616469656e743e3c2f646566733e3c2f73766761021b820152601f60f91b61023b820152600061023c8201610505565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161410f816017850160208801614560565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614140816028840160208801614560565b01602801949350505050565b7f5468616c657320526f79616c652050617373706f7274202d20736561736f6e20815260008251614184816020850160208701614560565b9190910160200192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906141c490830184613482565b9695505050505050565b602081526000611fc56020830184613482565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6040805190810167ffffffffffffffff8111828210171561435157614351614639565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561438057614380614639565b604052919050565b6000821982111561439b5761439b61460d565b500190565b600060ff821660ff84168060ff038211156143bd576143bd61460d565b019392505050565b6000826143d4576143d4614623565b500490565b600060ff8316806143ec576143ec614623565b8060ff84160491505092915050565b600181815b8085111561443657816000190482111561441c5761441c61460d565b8085161561442957918102915b93841c9390800290614400565b509250929050565b6000611fc5838360008261445457506001610505565b8161446157506000610505565b816001811461447757600281146144815761449d565b6001915050610505565b60ff8411156144925761449261460d565b50506001821b610505565b5060208310610133831016604e8410600b84101617156144c0575081810a610505565b6144ca83836143fb565b80600019048211156144de576144de61460d565b029392505050565b60008160001904831182151516156145005761450061460d565b500290565b600060ff821660ff84168160ff04811182151516156144de576144de61460d565b6000828210156145385761453861460d565b500390565b600060ff821660ff8416808210156145575761455761460d565b90039392505050565b60005b8381101561457b578181015183820152602001614563565b83811115610edc5750506000910152565b60008161459b5761459b61460d565b506000190190565b600181811c908216806145b757607f821691505b602082108114156145d857634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156145f2576145f261460d565b5060010190565b60008261460857614608614623565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146113d357600080fd5b6001600160e01b0319811681146113d357600080fdfe3c7061746820643d224d3233332e303037203236362e3834354c3236362e323035203231302e3031334c3239382e383234203236372e31384c3233332e303037203236362e3834355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223235352220793d223236302220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d223430222066696c6c3d2223303039353745223e353c2f746578743e3c636972636c652063783d223237332e383333222063793d223333322e3833332220723d22323822207472616e73666f726d3d22726f746174652831342e37393437203237332e383333203333322e3833332922207374726f6b653d2223443130303139222f3e3c7465787420783d223235382220793d223334332220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d2239222066696c6c3d2223443130303139223e363c2f746578743e3c636972636c652063783d223137352e393739222063793d223236322e3937392220723d22323822207472616e73666f726d3d22726f7461746528332e3035363735203137352e393739203236322e3937392922207374726f6b653d2223443130303139222f3e3c7465787420783d223136322220793d223237362220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d2233222066696c6c3d2223443130303139223e343c2f746578743e3c636972636c652063783d2237322e39333935222063793d223238382e39342220723d22323822207472616e73666f726d3d22726f746174652831322e333539332037322e39333935203238382e39342922207374726f6b653d2223443130303139222f3e3c7465787420783d2235392220793d223239392220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d223133222066696c6c3d2223443130303139223e323c2f746578743e3c7061746820643d224d3132382e383935203333302e3633354c3134352e3933203236372e3035394c3139322e3437203331332e364c3132382e383935203333302e3633355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223134372220793d223331392220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d3138222066696c6c3d2223303039353745223e333c2f746578743e3c636972636c652063783d223134352e393033222063793d223330342e3930322220723d22323822207472616e73666f726d3d22726f74617465282d31342e39393235203134352e393033203330342e3930322922207374726f6b653d2223443130303139222f3e3c7465787420783d223133392220793d223332322220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d3138222066696c6c3d2223443130303139223e333c2f746578743e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c636972636c652063783d2237322e35303035222063793d223230302e352220723d22323822207472616e73666f726d3d22726f74617465282d392e30313530382037322e35303035203230302e352922207374726f6b653d2223443130303139222f3e3c7465787420783d2236332220793d223231352220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223443130303139223e313c2f746578743e3c7061746820643d224d34312e37333837203232362e3539394c36392e393534203136372e3133364c3130372e333433203232312e3330324c34312e37333837203232362e3539395a22207374726f6b653d2223303039353745222f3e3c7465787420783d2236332220793d223231352220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223303039353745223e313c2f746578743e3c636972636c652063783d223237392e363134222063793d223233302e3631342220723d22323822207472616e73666f726d3d22726f74617465282d392e3031353038203237392e363134203233302e3631342922207374726f6b653d2223443130303139222f3e3c7465787420783d223237312220793d223234362220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d39222066696c6c3d2223443130303139223e353c2f746578743e3c7061746820643d224d33352e37363434203239352e3434354c38302e32303537203234362e3839364c3130302e303239203330392e3635384c33352e37363434203239352e3434355a22207374726f6b653d2223303039353745222f3e3c7465787420783d2235392220793d223239332220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d223135222066696c6c3d2223303039353745223e323c2f746578743e3c7061746820643d224d3230332e343833203334372e3238354c3234302e333231203239322e3734324c3236392e313338203335312e3931364c3230332e343833203334372e3238355a22207374726f6b653d2223303039353745222f3e3c7465787420783d223232342220793d223334322220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d22343022202066696c6c3d2223303039353745223e363c2f746578743e3c7061746820643d224d3135302e373339203238392e3539394c3137382e393534203233302e3133364c3231362e333433203238342e3330324c3135302e373339203238392e3539395a22207374726f6b653d2223303039353745222f3e3c7465787420783d223137302220793d223238312220666f6e742d66616d696c793d22436f7572696572204e65772220666f6e742d73697a653d2234302220726f746174653d222d37222066696c6c3d2223303039353745223e343c2f746578743ea2646970667358221220804efb95ed7aa26c4b8241ca0a539f7d450db6c7b94989abbebe3dd19feb8f7964736f6c63430008040033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.