Overview
ETH Balance
0 ETH
ETH Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
GuildPin
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; import { IGuildPin } from "./interfaces/IGuildPin.sol"; import { LibTransfer } from "./lib/LibTransfer.sol"; import { SoulboundERC721 } from "./token/SoulboundERC721.sol"; import { TreasuryManager } from "./utils/TreasuryManager.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { Base64Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol"; import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; import { StringsUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; /// @title An NFT representing actions taken by Guild.xyz users. contract GuildPin is IGuildPin, Initializable, OwnableUpgradeable, UUPSUpgradeable, SoulboundERC721, TreasuryManager { using ECDSAUpgradeable for bytes32; using StringsUpgradeable for address; using StringsUpgradeable for uint256; using LibTransfer for address; using LibTransfer for address payable; uint256 public constant SIGNATURE_VALIDITY = 1 hours; address public validSigner; /// @notice Maps the tokenIds to cids (for tokenURIs). mapping(uint256 tokenId => string cid) internal cids; /// @notice Maps the Guild-related parameters to a tokenId. mapping(address holder => mapping(GuildAction action => mapping(uint256 guildId => uint256 tokenId))) internal claimedTokens; /// @notice Maps the tokenIds to Guild-related parameters. mapping(uint256 tokenId => PinData pin) internal claimedTokensDetails; /// @notice Maps the guildIds to the amount of tokens minted in that guild. mapping(uint256 guildId => uint256 amountMinted) internal totalMintedPerGuild; /// @notice Maps the GuildAction enum to pretty strings for metadata. mapping(GuildAction action => PinStrings prettyStrings) internal guildActionPrettyNames; /// @notice The number of tokens minted in the first version of the contract. uint256 internal initialTokensMinted; /// @notice Maps whether a specific pin has been claimed to a userId. mapping(uint256 userId => mapping(GuildAction action => mapping(uint256 guildId => bool claimed))) internal claimerUserIds; /// @notice Empty space reserved for future updates. uint256[42] private __gap; /// @notice Sets metadata and the associated addresses. /// @param name The name of the token. /// @param symbol The symbol of the token. /// @param treasury The address where the collected fees will be sent. /// @param _validSigner The address that should sign the parameters for certain functions. function initialize( string memory name, string memory symbol, address payable treasury, address _validSigner ) public initializer { validSigner = _validSigner; __Ownable_init(); __UUPSUpgradeable_init(); __SoulboundERC721_init(name, symbol); __TreasuryManager_init(treasury); } // Note: the reInitialize function was last used with version 3 // function reInitialize() public reinitializer(3) {} function claim( PinDataParams memory pinData, address payable adminTreasury, uint256 adminFee, uint256 signedAt, string calldata cid, bytes calldata signature ) external payable { if (signedAt < block.timestamp - SIGNATURE_VALIDITY) revert ExpiredSignature(); if ( claimedTokens[pinData.receiver][pinData.guildAction][pinData.guildId] != 0 || claimerUserIds[pinData.userId][pinData.guildAction][pinData.guildId] ) revert AlreadyClaimed(); if (!isValidSignature(pinData, adminTreasury, adminFee, signedAt, cid, signature)) revert IncorrectSignature(); uint256 tokenId = totalSupply() + 1; unchecked { ++totalMintedPerGuild[pinData.guildId]; } claimedTokens[pinData.receiver][pinData.guildAction][pinData.guildId] = tokenId; claimedTokensDetails[tokenId] = PinData( pinData.receiver, pinData.guildAction, uint88(pinData.userId), pinData.guildName, uint128(pinData.guildId), uint128(totalMintedPerGuild[pinData.guildId]), uint128(block.timestamp), uint128(pinData.createdAt) ); cids[tokenId] = cid; claimerUserIds[pinData.userId][pinData.guildAction][pinData.guildId] = true; // Fee collection uint256 guildFee = fee; if (msg.value == guildFee + adminFee) { treasury.sendEther(guildFee); if (adminTreasury != address(0)) adminTreasury.sendEther(adminFee); } else revert IncorrectFee(msg.value, guildFee + adminFee); _safeMint(pinData.receiver, tokenId); emit Locked(tokenId); emit Claimed(pinData.receiver, pinData.guildAction, pinData.guildId); } function burn(uint256 userId, GuildAction guildAction, uint256 guildId) external { uint256 tokenId = claimedTokens[msg.sender][guildAction][guildId]; claimedTokens[msg.sender][guildAction][guildId] = 0; delete claimedTokensDetails[tokenId]; delete cids[tokenId]; delete claimerUserIds[userId][guildAction][guildId]; _burn(tokenId); } function setValidSigner(address newValidSigner) external onlyOwner { validSigner = newValidSigner; emit ValidSignerChanged(newValidSigner); } function updateImageURI( PinDataParams memory pinData, uint256 signedAt, string calldata newCid, bytes calldata signature ) external { if (signedAt < block.timestamp - SIGNATURE_VALIDITY) revert ExpiredSignature(); if (!isValidSignature(pinData, payable(address(0)), 0, signedAt, newCid, signature)) revert IncorrectSignature(); uint256 tokenId = claimedTokens[pinData.receiver][pinData.guildAction][pinData.guildId]; if (tokenId == 0) revert NonExistentToken(tokenId); cids[tokenId] = newCid; emit MetadataUpdate(tokenId); } function setPinStrings(GuildAction guildAction, PinStrings memory pinStrings) public onlyOwner { guildActionPrettyNames[guildAction] = pinStrings; emit PinStringsSet(guildAction); } function hasClaimed(address account, GuildAction guildAction, uint256 id) external view returns (bool claimed) { return claimedTokens[account][guildAction][id] != 0; } function hasTheUserIdClaimed( uint256 userId, GuildAction guildAction, uint256 id ) external view returns (bool claimed) { return claimerUserIds[userId][guildAction][id]; } function tokenURI(uint256 tokenId) public view override returns (string memory) { if (!_exists(tokenId)) revert NonExistentToken(tokenId); PinData memory pin = claimedTokensDetails[tokenId]; // solhint-disable quotes string memory json = Base64Upgradeable.encode( bytes( string.concat( '{"name": "', guildActionPrettyNames[pin.action].actionName, " ", pin.guildName, '", "description": "', guildActionPrettyNames[pin.action].description, " ", pin.guildName, ' on Guild.xyz.", "image": "ipfs://', cids[tokenId], '", "attributes": [', ' { "trait_type": "type",', ' "value": "', guildActionPrettyNames[pin.action].actionName, '"}, { "trait_type": "guildId",', ' "value": "', uint256(pin.id).toString(), '" }, { "trait_type": "userId", "value": "', uint256(pin.userId).toString(), '" }, { "trait_type": "mintDate",', ' "display_type": "date", "value": ', uint256(pin.mintDate).toString(), ' }, { "trait_type": "actionDate", "display_type": "date", "value": ', uint256(pin.createdAt).toString(), ' }, { "trait_type": "rank", "value": "', tokenId > initialTokensMinted ? uint256(pin.pinNumber).toString() : tokenId.toString(), '"} ] }' ) ) ); // solhint-enable quotes return string.concat("data:application/json;base64,", json); } // solhint-disable-next-line no-empty-blocks function _authorizeUpgrade(address) internal override onlyOwner {} /// @notice Checks the validity of the signature for the given params. function isValidSignature( PinDataParams memory pinData, address payable adminTreasury, uint256 adminFee, uint256 signedAt, string calldata cid, bytes calldata signature ) internal view returns (bool) { if (signature.length != 65) revert IncorrectSignature(); bytes32 message = keccak256( abi.encode( pinData.receiver, pinData.guildAction, pinData.userId, pinData.guildId, pinData.guildName, pinData.createdAt, adminTreasury, adminFee, signedAt, cid, block.chainid, address(this) ) ).toEthSignedMessageHash(); return message.recover(signature) == validSigner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title An NFT representing actions taken by Guild.xyz users. interface IGuildPin { /// @notice Actions taken on Guild that can be rewarded with a pin. enum GuildAction { JOINED_GUILD, IS_OWNER, IS_ADMIN } /// @notice Guild-related data assigned to every token. struct PinData { address holder; GuildAction action; uint88 userId; string guildName; uint128 id; // guildId/roleId uint128 pinNumber; uint128 mintDate; uint128 createdAt; } /// @notice The same as {PinData}, but without the mintDate and the pinNumber, used as a function argument. struct PinDataParams { address receiver; GuildAction guildAction; uint256 userId; uint256 guildId; // guildId/roleId string guildName; uint256 createdAt; } /// @notice Pretty strings for GuildActions. Used for metadata. struct PinStrings { // "Joined", "Created", "Admin of" string actionName; // "This is an onchain proof that you joined", // "This is an onchain proof that you're the owner of", // "This is an onchain proof that you're an admin of", string description; } /// @notice Returns true if the address has already claimed their token. /// @param account The user's address. /// @param guildAction The action the pin was minted for. /// @param id The id of the guild or role the token was minted for. /// @return claimed Whether the address has claimed their token. function hasClaimed(address account, GuildAction guildAction, uint256 id) external view returns (bool claimed); /// @notice Whether a userId has minted a specific pin. /// @dev Used to prevent double mints in the same block. /// @param userId The id of the user on Guild. /// @param guildAction The action the pin was minted for. /// @param id The id of the guild or role the token was minted for. /// @return claimed Whether the userId has claimed the pin for the given action/guildId combination. function hasTheUserIdClaimed( uint256 userId, GuildAction guildAction, uint256 id ) external view returns (bool claimed); /// @notice The time interval while a signature is valid. /// @return validity The time interval in seconds. // solhint-disable func-name-mixedcase function SIGNATURE_VALIDITY() external pure returns (uint256 validity); /// @return signer The address that signs the metadata. function validSigner() external view returns (address signer); /// @notice Claims tokens to the given address. /// @dev The contract needs to be approved if ERC20 tokens are used. /// @param pinData The Guild-related data, see {PinDataParams}. /// @param adminTreasury The address where the pinned guild collects fees paid to them. /// @param adminFee The fee to pay to the guild where the Pin is minted. /// @param signedAt The timestamp marking the time when the data were signed. /// @param cid The cid used to construct the tokenURI for the token to be minted. /// @param signature The following signed by validSigner: pinData, signedAt, cid, chainId, the contract's address. function claim( PinDataParams memory pinData, address payable adminTreasury, uint256 adminFee, uint256 signedAt, string calldata cid, bytes calldata signature ) external payable; /// @notice Burns a token from the sender. /// @param userId The id of the user on Guild. /// @param guildAction The action to which the token belongs to. /// @param guildId The id of the guild where the token belongs to. function burn(uint256 userId, GuildAction guildAction, uint256 guildId) external; /// @notice Sets the address that signs the metadata. /// @dev Callable only by the owner. /// @param newValidSigner The new address of validSigner. function setValidSigner(address newValidSigner) external; /// @notice Updates a minted token's cid. /// @dev Callable only by the owner of the token. /// @param pinData The Guild-related data, see {PinDataParams}. /// @param signedAt The timestamp marking the time when the data were signed. /// @param newCid The new cid that points to the updated image. /// @param signature The following signed by validSigner: pinData, signedAt, cid, chainId, the contract's address. function updateImageURI( PinDataParams memory pinData, uint256 signedAt, string calldata newCid, bytes calldata signature ) external; /// @notice Set the pretty strings displayed in metadata for name and description. /// @dev Callable only by the owner. /// @param guildAction The action the strings are set for. /// @param pinStrings The strings to set. See {PinStrings}. function setPinStrings(GuildAction guildAction, PinStrings memory pinStrings) external; /// @notice Event emitted whenever a claim succeeds. /// @param receiver The address that received the tokens. /// @param guildAction The action the pin was minted for. /// @param guildId The id the token has been claimed for. event Claimed(address indexed receiver, GuildAction indexed guildAction, uint256 indexed guildId); /// @notice Event emitted when pretty strings are set for a GuildAction. /// @param guildAction The action whose strings were set. event PinStringsSet(GuildAction guildAction); /// @notice Event emitted when the validSigner is changed. /// @param newValidSigner The new address of validSigner. event ValidSignerChanged(address newValidSigner); /// @notice Error thrown when the token is already claimed. error AlreadyClaimed(); /// @notice Error thrown when the signature is already expired. error ExpiredSignature(); /// @notice Error thrown when an incorrect amount of fee is attempted to be paid. /// @param paid The amount of funds received. /// @param requiredAmount The amount of fees required for minting. error IncorrectFee(uint256 paid, uint256 requiredAmount); /// @notice Error thrown when the sender is not permitted to do a specific action. error IncorrectSender(); /// @notice Error thrown when the supplied signature is invalid. error IncorrectSignature(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @title Library for functions related to transfers. library LibTransfer { /// @notice Error thrown when sending ether fails. /// @param recipient The address that could not receive the ether. error FailedToSendEther(address recipient); /// @notice Error thrown when an ERC20 transfer failed. /// @param from The sender of the token. /// @param to The recipient of the token. error TransferFailed(address from, address to); /// @notice Sends ether to an address, forwarding all available gas and reverting on errors. /// @param recipient The recipient of the ether. /// @param amount The amount of ether to send in base units. function sendEther(address payable recipient, uint256 amount) internal { // solhint-disable-next-line avoid-low-level-calls (bool success, ) = recipient.call{ value: amount }(""); if (!success) revert FailedToSendEther(recipient); } /// @notice Sends an ERC20 token to an address and reverts if the transfer returns false. /// @dev Wrapper for {IERC20-transfer}. /// @param to The recipient of the tokens. /// @param token The address of the token to send. /// @param amount The amount of the token to send in base units. function sendToken(address to, address token, uint256 amount) internal { if (!IERC20(token).transfer(to, amount)) revert TransferFailed(msg.sender, address(this)); } /// @notice Sends an ERC20 token to an address from another address and reverts if transferFrom returns false. /// @dev Wrapper for {IERC20-transferFrom}. /// @param to The recipient of the tokens. /// @param token The address of the token to send. /// @param from The source of the tokens. /// @param amount The amount of the token to send in base units. function sendTokenFrom(address to, address from, address token, uint256 amount) internal { if (!IERC20(token).transferFrom(from, to, amount)) revert TransferFailed(msg.sender, address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; /* solhint-disable max-line-length */ import { IERC4906 } from "../interfaces/IERC4906.sol"; import { IERC5192 } from "../interfaces/IERC5192.sol"; import { ERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { IERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; import { ERC721EnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; import { IERC721EnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol"; import { IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol"; /* solhint-enable max-line-length */ /// @title An enumerable soulbound ERC721. /// @notice Allowance and transfer-related functions are disabled. contract SoulboundERC721 is ERC721Upgradeable, ERC721EnumerableUpgradeable, IERC4906, IERC5192 { /// @notice Empty space reserved for future updates. uint256[50] private __gap; /// @notice Error thrown when trying to query info about a token that's not (yet) minted. /// @param tokenId The queried id. error NonExistentToken(uint256 tokenId); /// @notice Error thrown when a function's execution is not possible, because this is a soulbound NFT. error Soulbound(); // solhint-disable-next-line func-name-mixedcase function __SoulboundERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init(name_, symbol_); __ERC721Enumerable_init(); } /// @inheritdoc ERC721EnumerableUpgradeable function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721EnumerableUpgradeable, ERC721Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == 0x49064906 || // ERC4906 interfaceId == type(IERC5192).interfaceId || interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } function locked(uint256 tokenId) external view returns (bool) { if (!_exists(tokenId)) revert NonExistentToken(tokenId); return true; } function approve( address /* to */, uint256 /* tokenId */ ) public virtual override(IERC721Upgradeable, ERC721Upgradeable) { revert Soulbound(); } function setApprovalForAll( address /* operator */, bool /* approved */ ) public virtual override(IERC721Upgradeable, ERC721Upgradeable) { revert Soulbound(); } function isApprovedForAll( address /* owner */, address /* operator */ ) public view virtual override(IERC721Upgradeable, ERC721Upgradeable) returns (bool) { revert Soulbound(); } function transferFrom( address /* from */, address /* to */, uint256 /* tokenId */ ) public virtual override(IERC721Upgradeable, ERC721Upgradeable) { revert Soulbound(); } function safeTransferFrom( address /* from */, address /* to */, uint256 /* tokenId */ ) public virtual override(IERC721Upgradeable, ERC721Upgradeable) { revert Soulbound(); } function safeTransferFrom( address /* from */, address /* to */, uint256 /* tokenId */, bytes memory /* data */ ) public virtual override(IERC721Upgradeable, ERC721Upgradeable) { revert Soulbound(); } /// @dev Still used for minting/burning. function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override(ERC721EnumerableUpgradeable, ERC721Upgradeable) { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; import { IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol"; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165Upgradeable, IERC721Upgradeable { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; interface IERC5192 { /// @notice Emitted when the locking status is changed to locked. /// @dev If a token is minted and the status is locked, this event should be emitted. /// @param tokenId The identifier for a token. event Locked(uint256 tokenId); /// @notice Emitted when the locking status is changed to unlocked. /// @dev If a token is minted and the status is unlocked, this event should be emitted. /// @param tokenId The identifier for a token. event Unlocked(uint256 tokenId); /// @notice Returns the locking status of an Soulbound Token /// @dev SBTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param tokenId The identifier for an SBT. function locked(uint256 tokenId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import { ITreasuryManager } from "../interfaces/ITreasuryManager.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /// @title A contract that manages fee-related functionality. contract TreasuryManager is ITreasuryManager, Initializable, OwnableUpgradeable { address payable public treasury; uint256 public fee; /// @notice Empty space reserved for future updates. uint256[48] private __gap; /// @param treasury_ The address that will receive the fees. // solhint-disable-next-line func-name-mixedcase function __TreasuryManager_init(address payable treasury_) internal onlyInitializing { treasury = treasury_; } function setFee(uint256 newFee) external onlyOwner { fee = newFee; emit FeeChanged(newFee); } function setTreasury(address payable newTreasury) external onlyOwner { treasury = newTreasury; emit TreasuryChanged(newTreasury); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title A contract that manages fee-related functionality. interface ITreasuryManager { /// @notice Sets the minting fee forwarded to Guild's treasury. /// @dev Callable only by the owner. /// @param newFee The new fee in base units. function setFee(uint256 newFee) external; /// @notice Sets the address that receives the fees. /// @dev Callable only by the owner. /// @param newTreasury The new address of the treasury. function setTreasury(address payable newTreasury) external; /// @notice The minting fee of a token. /// @return fee The amount of the fee in base units. function fee() external view returns (uint256 fee); /// @notice Returns the address that receives the fees. function treasury() external view returns (address payable); /// @notice Event emitted when the fee is changed. /// @param newFee The new amount of fee in base units. event FeeChanged(uint256 newFee); /// @notice Event emitted when the treasury address is changed. /// @param newTreasury The new address of the treasury. event TreasuryChanged(address newTreasury); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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 { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// 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 { } 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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; 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 proxied contracts do not make use of 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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * 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 prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library 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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/IERC1967Upgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967Upgradeable { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64Upgradeable { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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 { __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: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721Upgradeable.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try 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 { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[44] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // 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 (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface 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 `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../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/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 { } 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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (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 { } 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 See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; 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(); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[46] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (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); /** * @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); }
{ "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"FailedToSendEther","type":"error"},{"inputs":[{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"requiredAmount","type":"uint256"}],"name":"IncorrectFee","type":"error"},{"inputs":[],"name":"IncorrectSender","type":"error"},{"inputs":[],"name":"IncorrectSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NonExistentToken","type":"error"},{"inputs":[],"name":"Soulbound","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"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":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"guildId","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","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":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"}],"name":"PinStringsSet","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":"newTreasury","type":"address"}],"name":"TreasuryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValidSigner","type":"address"}],"name":"ValidSignerChanged","type":"event"},{"inputs":[],"name":"SIGNATURE_VALIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"guildId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"guildId","type":"uint256"},{"internalType":"string","name":"guildName","type":"string"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct IGuildPin.PinDataParams","name":"pinData","type":"tuple"},{"internalType":"address payable","name":"adminTreasury","type":"address"},{"internalType":"uint256","name":"adminFee","type":"uint256"},{"internalType":"uint256","name":"signedAt","type":"uint256"},{"internalType":"string","name":"cid","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"hasTheUserIdClaimed","outputs":[{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address payable","name":"treasury","type":"address"},{"internalType":"address","name":"_validSigner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"locked","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":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"components":[{"internalType":"string","name":"actionName","type":"string"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct IGuildPin.PinStrings","name":"pinStrings","type":"tuple"}],"name":"setPinStrings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValidSigner","type":"address"}],"name":"setValidSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","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":"treasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"guildId","type":"uint256"},{"internalType":"string","name":"guildName","type":"string"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct IGuildPin.PinDataParams","name":"pinData","type":"tuple"},{"internalType":"uint256","name":"signedAt","type":"uint256"},{"internalType":"string","name":"newCid","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"updateImageURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"validSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523060805234801561001457600080fd5b506080516140a461004c60003960008181610a8c01528181610acc01528181610b6b01528181610bab0152610cd301526140a46000f3fe60806040526004361061021a5760003560e01c80636352211e11610123578063b45a3c0e116100ab578063e111a4581161006f578063e111a458146105d3578063e985e9c5146105f3578063f0f4426014610613578063f2fde38b14610633578063fdda2b211461065357600080fd5b8063b45a3c0e1461054e578063b88d4fde1461056e578063c87b56dd14610589578063dc4b201d146105a9578063ddca3f43146105bc57600080fd5b8063715018a6116100f2578063715018a6146104cb5780638da5cb5b146104e05780638f15b414146104fe57806395d89b411461051e578063a22cb4651461053357600080fd5b80636352211e1461044b57806366c8f9951461046b57806369fe0e2d1461048b57806370a08231146104ab57600080fd5b806323b872dd116101a657806342842e0e1161017557806342842e0e146103715780634f1ef286146103e25780634f6ccce7146103f557806352d1902d1461041557806361d027b31461042a57600080fd5b806323b872dd146103715780632a73dead1461038c5780632f745c59146103a25780633659cfe6146103c257600080fd5b8063095ea7b3116101ed578063095ea7b3146102d05780630eceb3f3146102f057806312d8b6591461031057806318160ddd146103305780631cc7d7431461035057600080fd5b806301ffc9a71461021f57806306fdde031461025457806307d8ca9914610276578063081812fc14610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004612fed565b610673565b60405190151581526020015b60405180910390f35b34801561026057600080fd5b506102696106d4565b60405161024b919061305a565b34801561028257600080fd5b50610296610291366004613123565b610766565b005b3480156102a457600080fd5b506102b86102b33660046131dc565b610809565b6040516001600160a01b03909116815260200161024b565b3480156102dc57600080fd5b506102966102eb36600461320a565b610830565b3480156102fc57600080fd5b5061029661030b366004613320565b610849565b34801561031c57600080fd5b5061029661032b3660046133bd565b61098d565b34801561033c57600080fd5b5061012f545b60405190815260200161024b565b34801561035c57600080fd5b506101c3546102b8906001600160a01b031681565b34801561037d57600080fd5b506102966102eb3660046133da565b34801561039857600080fd5b50610342610e1081565b3480156103ae57600080fd5b506103426103bd36600461320a565b6109eb565b3480156103ce57600080fd5b506102966103dd3660046133bd565b610a82565b6102966103f036600461341b565b610b61565b34801561040157600080fd5b506103426104103660046131dc565b610c31565b34801561042157600080fd5b50610342610cc6565b34801561043657600080fd5b50610191546102b8906001600160a01b031681565b34801561045757600080fd5b506102b86104663660046131dc565b610d79565b34801561047757600080fd5b5061023f61048636600461346a565b610dd9565b34801561049757600080fd5b506102966104a63660046131dc565b610e36565b3480156104b757600080fd5b506103426104c63660046133bd565b610e74565b3480156104d757600080fd5b50610296610efa565b3480156104ec57600080fd5b506065546001600160a01b03166102b8565b34801561050a57600080fd5b5061029661051936600461349f565b610f0e565b34801561052a57600080fd5b5061026961105a565b34801561053f57600080fd5b506102966102eb366004613527565b34801561055a57600080fd5b5061023f6105693660046131dc565b611069565b34801561057a57600080fd5b506102966102eb366004613565565b34801561059557600080fd5b506102696105a43660046131dc565b6110a9565b6102966105b73660046135d0565b6113f3565b3480156105c857600080fd5b506103426101925481565b3480156105df57600080fd5b506102966105ee36600461346a565b6118fe565b3480156105ff57600080fd5b5061023f61060e36600461368b565b611a50565b34801561061f57600080fd5b5061029661062e3660046133bd565b611a6b565b34801561063f57600080fd5b5061029661064e3660046133bd565b611ac2565b34801561065f57600080fd5b5061023f61066e3660046136b9565b611b38565b6000632483248360e11b6001600160e01b0319831614806106a457506001600160e01b03198216635a2d1e0760e11b145b806106bf57506001600160e01b0319821663780e9d6360e01b145b806106ce57506106ce82611ba2565b92915050565b606060fb80546106e3906136e7565b80601f016020809104026020016040519081016040528092919081815260200182805461070f906136e7565b801561075c5780601f106107315761010080835404028352916020019161075c565b820191906000526020600020905b81548152906001019060200180831161073f57829003601f168201915b5050505050905090565b61076e611bc7565b806101c8600084600281111561078657610786613721565b600281111561079757610797613721565b81526020810191909152604001600020815181906107b59082613785565b50602082015160018201906107ca9082613785565b509050507fe25b659a5fa3c64284364ec8c25d34ef8a9ac8d29add13cacd6cb9c1698a5b41826040516107fd9190613866565b60405180910390a15050565b600061081482611c21565b50600090815260ff60205260409020546001600160a01b031690565b60405163a4420a9560e01b815260040160405180910390fd5b610855610e104261388a565b8510156108755760405163df4cc36d60e01b815260040160405180910390fd5b610886866000808888888888611c80565b6108a35760405163c1606c2f60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c560209081526040822090880151829060028111156108d6576108d6613721565b60028111156108e7576108e7613721565b815260200190815260200160002060008860600151815260200190815260200160002054905080600003610936576040516338077a2b60e01b8152600481018290526024015b60405180910390fd5b60008181526101c46020526040902061095085878361389d565b506040518181527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a150505050505050565b610995611bc7565b6101c380546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b60006109f683610e74565b8210610a585760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161092d565b506001600160a01b0391909116600090815261012d60209081526040808320938352929052205490565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610aca5760405162461bcd60e51b815260040161092d9061395c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b13600080516020613fe8833981519152546001600160a01b031690565b6001600160a01b031614610b395760405162461bcd60e51b815260040161092d906139a8565b610b4281611d9d565b60408051600080825260208201909252610b5e91839190611da5565b50565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610ba95760405162461bcd60e51b815260040161092d9061395c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610bf2600080516020613fe8833981519152546001600160a01b031690565b6001600160a01b031614610c185760405162461bcd60e51b815260040161092d906139a8565b610c2182611d9d565b610c2d82826001611da5565b5050565b6000610c3d61012f5490565b8210610ca05760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161092d565b61012f8281548110610cb457610cb46139f4565b90600052602060002001549050919050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d665760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161092d565b50600080516020613fe883398151915290565b600081815260fd60205260408120546001600160a01b0316806106ce5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161092d565b60008381526101ca6020526040812081846002811115610dfb57610dfb613721565b6002811115610e0c57610e0c613721565b81526020808201929092526040908101600090812085825290925290205460ff1690509392505050565b610e3e611bc7565b6101928190556040518181527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3906020016109e0565b60006001600160a01b038216610ede5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161092d565b506001600160a01b0316600090815260fe602052604090205490565b610f02611bc7565b610f0c6000611f15565b565b600054610100900460ff1615808015610f2e5750600054600160ff909116105b80610f485750303b158015610f48575060005460ff166001145b610fab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161092d565b6000805460ff191660011790558015610fce576000805461ff0019166101001790555b6101c380546001600160a01b0319166001600160a01b038416179055610ff2611f67565b610ffa611f96565b6110048585611fbd565b61100d83611ff6565b8015611053576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606060fc80546106e3906136e7565b600081815260fd60205260408120546001600160a01b03166110a1576040516338077a2b60e01b81526004810183905260240161092d565b506001919050565b600081815260fd60205260409020546060906001600160a01b03166110e4576040516338077a2b60e01b81526004810183905260240161092d565b60008281526101c6602090815260408083208151610100810190925280546001600160a01b03811683529192909190830190600160a01b900460ff16600281111561113157611131613721565b600281111561114257611142613721565b81528154600160a81b90046001600160581b03166020820152600182018054604090920191611170906136e7565b80601f016020809104026020016040519081016040528092919081815260200182805461119c906136e7565b80156111e95780601f106111be576101008083540402835291602001916111e9565b820191906000526020600020905b8154815290600101906020018083116111cc57829003601f168201915b50505091835250506002828101546001600160801b03808216602080860191909152600160801b928390048216604086015260039095015480821660608601529190910416608090920191909152908201519192506000916113c8916101c891849181111561125a5761125a613721565b600281111561126b5761126b613721565b815260200190815260200160002060000183606001516101c860008660200151600281111561129c5761129c613721565b60028111156112ad576112ad613721565b815260200190815260200160002060010185606001516101c460008a81526020019081526020016000206101c86000896020015160028111156112f2576112f2613721565b600281111561130357611303613721565b815260200190815260200160002060000161132a89608001516001600160801b0316612040565b6113408a604001516001600160581b0316612040565b6113568b60c001516001600160801b0316612040565b61136c8c60e001516001600160801b0316612040565b6101c9548f116113845761137f8f612040565b61139a565b61139a8d60a001516001600160801b0316612040565b6040516020016113b49b9a99989796959493929190613a99565b6040516020818303038152906040526120d2565b9050806040516020016113db9190613d61565b60405160208183030381529060405292505050919050565b6113ff610e104261388a565b85101561141f5760405163df4cc36d60e01b815260040160405180910390fd5b87516001600160a01b031660009081526101c5602090815260408220908a0151909190600281111561145357611453613721565b600281111561146457611464613721565b81526020019081526020016000206000896060015181526020019081526020016000205460001415806114f4575060408089015160009081526101ca6020908152918120918a015160028111156114bd576114bd613721565b60028111156114ce576114ce613721565b81526020808201929092526040908101600090812060608c0151825290925290205460ff165b1561151257604051630c8d9eab60e31b815260040160405180910390fd5b6115228888888888888888611c80565b61153f5760405163c1606c2f60e01b815260040160405180910390fd5b600061154b61012f5490565b611556906001613da6565b60608a015160009081526101c760209081526040808320805460010190558c516001600160a01b031683526101c582528220908c0151929350839290919060028111156115a5576115a5613721565b60028111156115b6576115b6613721565b815260200190815260200160002060008b606001518152602001908152602001600020819055506040518061010001604052808a600001516001600160a01b031681526020018a60200151600281111561161257611612613721565b81526040808c01516001600160581b03166020808401919091526080808e0151838501526060808f0180516001600160801b03908116928701929092525160009081526101c784528481205482169286019290925242811660a0808701919091528f01511660c0909401939093528483526101c681529120825181546001600160a01b039091166001600160a01b031982168117835592840151919283916001600160a81b03191617600160a01b8360028111156116d2576116d2613721565b0217905550604082015181546001600160581b03909116600160a81b026001600160a81b03909116178155606082015160018201906117119082613785565b50608082015160a08301516001600160801b03918216600160801b918316820217600284015560c084015160e09094015193821693909116029190911760039091015560008181526101c46020526040902061176e85878361389d565b5060016101ca60008b60400151815260200190815260200160002060008b6020015160028111156117a1576117a1613721565b60028111156117b2576117b2613721565b81526020808201929092526040908101600090812060608e015182529092529020805460ff1916911515919091179055610192546117f08882613da6565b3403611834576101915461180d906001600160a01b031682612224565b6001600160a01b0389161561182f5761182f6001600160a01b038a1689612224565b611861565b3461183f8983613da6565b60405163dcf6afcb60e01b81526004810192909252602482015260440161092d565b895161186d90836122a3565b6040518281527f032bc66be43dbccb7487781d168eb7bda224628a3b2c3388bdf69b532a3a16119060200160405180910390a189606001518a6020015160028111156118bb576118bb613721565b8b516040516001600160a01b03909116907fc73092756e22756fd0b15b2f803bd49db35ee23e7ae171c4d414ab7a61fa8b7c90600090a450505050505050505050565b3360009081526101c5602052604081208184600281111561192157611921613721565b600281111561193257611932613721565b8152602080820192909252604090810160009081208582528352818120543382526101c5909352908120919250908185600281111561197357611973613721565b600281111561198457611984613721565b8152602080820192909252604090810160009081208682528352818120939093558383526101c69091528120818155906119c16001830182612f89565b5060006002820181905560039091018190558181526101c4602052604081206119e991612f89565b60008481526101ca6020526040812090846002811115611a0b57611a0b613721565b6002811115611a1c57611a1c613721565b8152602080820192909252604090810160009081208582529092529020805460ff19169055611a4a816122bd565b50505050565b600060405163a4420a9560e01b815260040160405180910390fd5b611a73611bc7565b61019180546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f608906020016109e0565b611aca611bc7565b6001600160a01b038116611b2f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161092d565b610b5e81611f15565b6001600160a01b03831660009081526101c56020526040812081846002811115611b6457611b64613721565b6002811115611b7557611b75613721565b81526020019081526020016000206000838152602001908152602001600020546000141590509392505050565b60006001600160e01b0319821663780e9d6360e01b14806106ce57506106ce82612360565b6065546001600160a01b03163314610f0c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161092d565b600081815260fd60205260409020546001600160a01b0316610b5e5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161092d565b600060418214611ca35760405163c1606c2f60e01b815260040160405180910390fd5b6000611d328a600001518b602001518c604001518d606001518e608001518f60a001518f8f8f8f8f4630604051602001611ce99d9c9b9a99989796959493929190613db9565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b6101c354604080516020601f88018190048102820181019092528681529293506001600160a01b0390911691611d8591879087908190840183828082843760009201919091525086939250506123b09050565b6001600160a01b0316149a9950505050505050505050565b610b5e611bc7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611ddd57611dd8836123d4565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e37575060408051601f3d908101601f19168201909252611e3491810190613e76565b60015b611e9a5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161092d565b600080516020613fe88339815191528114611f095760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161092d565b50611dd8838383612470565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611f8e5760405162461bcd60e51b815260040161092d90613e8f565b610f0c612495565b600054610100900460ff16610f0c5760405162461bcd60e51b815260040161092d90613e8f565b600054610100900460ff16611fe45760405162461bcd60e51b815260040161092d90613e8f565b611fee82826124c5565b610c2d611f96565b600054610100900460ff1661201d5760405162461bcd60e51b815260040161092d90613e8f565b61019180546001600160a01b0319166001600160a01b0392909216919091179055565b6060600061204d836124f6565b60010190506000816001600160401b0381111561206c5761206c613081565b6040519080825280601f01601f191660200182016040528015612096576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846120a057509392505050565b606081516000036120f157505060408051602081019091526000815290565b600060405180606001604052806040815260200161400860409139905060006003845160026121209190613da6565b61212a9190613eda565b612135906004613efc565b6001600160401b0381111561214c5761214c613081565b6040519080825280601f01601f191660200182016040528015612176576020820181803683370190505b509050600182016020820185865187015b808210156121e2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250612187565b50506003865106600181146121fe576002811461221157612219565b603d6001830353603d6002830353612219565b603d60018303535b509195945050505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612271576040519150601f19603f3d011682016040523d82523d6000602084013e612276565b606091505b5050905080611dd857604051632499e3bb60e11b81526001600160a01b038416600482015260240161092d565b610c2d8282604051806020016040528060008152506125ce565b60006122c882610d79565b90506122d8816000846001612601565b6122e182610d79565b600083815260ff6020908152604080832080546001600160a01b03199081169091556001600160a01b03851680855260fe8452828520805460001901905587855260fd909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b031982166380ac58cd60e01b148061239157506001600160e01b03198216635b5e139f60e01b145b806106ce57506301ffc9a760e01b6001600160e01b03198316146106ce565b60008060006123bf858561260d565b915091506123cc81612652565b509392505050565b6001600160a01b0381163b6124415760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161092d565b600080516020613fe883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6124798361279c565b6000825111806124865750805b15611dd857611a4a83836127dc565b600054610100900460ff166124bc5760405162461bcd60e51b815260040161092d90613e8f565b610f0c33611f15565b600054610100900460ff166124ec5760405162461bcd60e51b815260040161092d90613e8f565b610c2d8282612808565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106125355772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612561576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061257f57662386f26fc10000830492506010015b6305f5e1008310612597576305f5e100830492506008015b61271083106125ab57612710830492506004015b606483106125bd576064830492506002015b600a83106106ce5760010192915050565b6125d88383612848565b6125e560008484846129e1565b611dd85760405162461bcd60e51b815260040161092d90613f13565b611a4a84848484612ae3565b60008082516041036126435760208301516040840151606085015160001a61263787828585612c12565b9450945050505061264b565b506000905060025b9250929050565b600081600481111561266657612666613721565b0361266e5750565b600181600481111561268257612682613721565b036126cf5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161092d565b60028160048111156126e3576126e3613721565b036127305760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161092d565b600381600481111561274457612744613721565b03610b5e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161092d565b6127a5816123d4565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060612801838360405180606001604052806027815260200161404860279139612cd6565b9392505050565b600054610100900460ff1661282f5760405162461bcd60e51b815260040161092d90613e8f565b60fb61283b8382613785565b5060fc611dd88282613785565b6001600160a01b03821661289e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161092d565b600081815260fd60205260409020546001600160a01b0316156129035760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161092d565b612911600083836001612601565b600081815260fd60205260409020546001600160a01b0316156129765760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161092d565b6001600160a01b038216600081815260fe602090815260408083208054600101905584835260fd90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15612ad757604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a25903390899088908890600401613f65565b6020604051808303816000875af1925050508015612a60575060408051601f3d908101601f19168201909252612a5d91810190613f98565b60015b612abd573d808015612a8e576040519150601f19603f3d011682016040523d82523d6000602084013e612a93565b606091505b508051600003612ab55760405162461bcd60e51b815260040161092d90613f13565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612adb565b5060015b949350505050565b6001811115612b525760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161092d565b816001600160a01b038516612bb057612bab8161012f8054600083815261013060205260408120829055600182018355919091527f232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f9790155565b612bd3565b836001600160a01b0316856001600160a01b031614612bd357612bd38582612d4e565b6001600160a01b038416612bef57612bea81612df0565b611053565b846001600160a01b0316846001600160a01b031614611053576110538482612ea5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c495750600090506003612ccd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c9d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612cc657600060019250925050612ccd565b9150600090505b94509492505050565b6060600080856001600160a01b031685604051612cf39190613fb5565b600060405180830381855af49150503d8060008114612d2e576040519150601f19603f3d011682016040523d82523d6000602084013e612d33565b606091505b5091509150612d4486838387612eeb565b9695505050505050565b60006001612d5b84610e74565b612d65919061388a565b600083815261012e6020526040902054909150808214612dbb576001600160a01b038416600090815261012d60209081526040808320858452825280832054848452818420819055835261012e90915290208190555b50600091825261012e602090815260408084208490556001600160a01b03909416835261012d81528383209183525290812055565b61012f54600090612e039060019061388a565b6000838152610130602052604081205461012f8054939450909284908110612e2d57612e2d6139f4565b906000526020600020015490508061012f8381548110612e4f57612e4f6139f4565b6000918252602080832090910192909255828152610130909152604080822084905585825281205561012f805480612e8957612e89613fd1565b6001900381819060005260206000200160009055905550505050565b6000612eb083610e74565b6001600160a01b03909316600090815261012d60209081526040808320868452825280832085905593825261012e9052919091209190915550565b60608315612f5a578251600003612f53576001600160a01b0385163b612f535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161092d565b5081612adb565b612adb8383815115612f6f5781518083602001fd5b8060405162461bcd60e51b815260040161092d919061305a565b508054612f95906136e7565b6000825580601f10612fa5575050565b601f016020900490600052602060002090810190610b5e91905b80821115612fd35760008155600101612fbf565b5090565b6001600160e01b031981168114610b5e57600080fd5b600060208284031215612fff57600080fd5b813561280181612fd7565b60005b8381101561302557818101518382015260200161300d565b50506000910152565b6000815180845261304681602086016020860161300a565b601f01601f19169290920160200192915050565b602081526000612801602083018461302e565b80356003811061307c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126130a857600080fd5b81356001600160401b03808211156130c2576130c2613081565b604051601f8301601f19908116603f011681019082821181831017156130ea576130ea613081565b8160405283815286602085880101111561310357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561313657600080fd5b61313f8361306d565b915060208301356001600160401b038082111561315b57600080fd5b908401906040828703121561316f57600080fd5b60405160408101818110838211171561318a5761318a613081565b60405282358281111561319c57600080fd5b6131a888828601613097565b8252506020830135828111156131bd57600080fd5b6131c988828601613097565b6020830152508093505050509250929050565b6000602082840312156131ee57600080fd5b5035919050565b6001600160a01b0381168114610b5e57600080fd5b6000806040838503121561321d57600080fd5b8235613228816131f5565b946020939093013593505050565b600060c0828403121561324857600080fd5b60405160c081016001600160401b03828210818311171561326b5761326b613081565b816040528293508435915061327f826131f5565b81835261328e6020860161306d565b6020840152604085013560408401526060850135606084015260808501359150808211156132bb57600080fd5b506132c885828601613097565b60808301525060a083013560a08201525092915050565b60008083601f8401126132f157600080fd5b5081356001600160401b0381111561330857600080fd5b60208301915083602082850101111561264b57600080fd5b6000806000806000806080878903121561333957600080fd5b86356001600160401b038082111561335057600080fd5b61335c8a838b01613236565b975060208901359650604089013591508082111561337957600080fd5b6133858a838b016132df565b9096509450606089013591508082111561339e57600080fd5b506133ab89828a016132df565b979a9699509497509295939492505050565b6000602082840312156133cf57600080fd5b8135612801816131f5565b6000806000606084860312156133ef57600080fd5b83356133fa816131f5565b9250602084013561340a816131f5565b929592945050506040919091013590565b6000806040838503121561342e57600080fd5b8235613439816131f5565b915060208301356001600160401b0381111561345457600080fd5b61346085828601613097565b9150509250929050565b60008060006060848603121561347f57600080fd5b8335925061348f6020850161306d565b9150604084013590509250925092565b600080600080608085870312156134b557600080fd5b84356001600160401b03808211156134cc57600080fd5b6134d888838901613097565b955060208701359150808211156134ee57600080fd5b506134fb87828801613097565b935050604085013561350c816131f5565b9150606085013561351c816131f5565b939692955090935050565b6000806040838503121561353a57600080fd5b8235613545816131f5565b91506020830135801515811461355a57600080fd5b809150509250929050565b6000806000806080858703121561357b57600080fd5b8435613586816131f5565b93506020850135613596816131f5565b92506040850135915060608501356001600160401b038111156135b857600080fd5b6135c487828801613097565b91505092959194509250565b60008060008060008060008060c0898b0312156135ec57600080fd5b88356001600160401b038082111561360357600080fd5b61360f8c838d01613236565b995060208b01359150613621826131f5565b90975060408a0135965060608a0135955060808a0135908082111561364557600080fd5b6136518c838d016132df565b909650945060a08b013591508082111561366a57600080fd5b506136778b828c016132df565b999c989b5096995094979396929594505050565b6000806040838503121561369e57600080fd5b82356136a9816131f5565b9150602083013561355a816131f5565b6000806000606084860312156136ce57600080fd5b83356136d9816131f5565b925061348f6020850161306d565b600181811c908216806136fb57607f821691505b60208210810361371b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b601f821115611dd857600081815260208120601f850160051c8101602086101561375e5750805b601f850160051c820191505b8181101561377d5782815560010161376a565b505050505050565b81516001600160401b0381111561379e5761379e613081565b6137b2816137ac84546136e7565b84613737565b602080601f8311600181146137e757600084156137cf5750858301515b600019600386901b1c1916600185901b17855561377d565b600085815260208120601f198616915b82811015613816578886015182559484019460019091019084016137f7565b50858210156138345787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6003811061386257634e487b7160e01b600052602160045260246000fd5b9052565b602081016106ce8284613844565b634e487b7160e01b600052601160045260246000fd5b818103818111156106ce576106ce613874565b6001600160401b038311156138b4576138b4613081565b6138c8836138c283546136e7565b83613737565b6000601f8411600181146138fc57600085156138e45750838201355b600019600387901b1c1916600186901b178355611053565b600083815260209020601f19861690835b8281101561392d578685013582556020948501946001909201910161390d565b508682101561394a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60008154613a17816136e7565b60018281168015613a2f5760018114613a4457613a73565b60ff1984168752821515830287019450613a73565b8560005260208060002060005b85811015613a6a5781548a820152908401908201613a51565b50505082870194505b5050505092915050565b60008151613a8f81856020860161300a565b9290920192915050565b693d913730b6b2911d101160b11b81526000613ab8600a83018e613a0a565b600160fd1b8152613acc600182018e613a7d565b72111610113232b9b1b934b83a34b7b7111d101160691b81529050613af4601382018d613a0a565b600160fd1b81529050613b4a613b44613b10600184018e613a7d565b7f206f6e204775696c642e78797a2e222c2022696d616765223a2022697066733a8152612f2f60f01b602082015260220190565b8b613a0a565b71222c202261747472696275746573223a205b60701b815290507f207b202274726169745f74797065223a202274797065222c000000000000000060128201526a10113b30b63ab2911d101160a91b602a820152613bab603582018a613a0a565b7f227d2c207b202274726169745f74797065223a20226775696c644964222c0000815290506a10113b30b63ab2911d101160a91b601e820152613c38613c32613bf7602984018b613a7d565b7f22207d2c207b202274726169745f74797065223a2022757365724964222c20228152683b30b63ab2911d101160b91b602082015260290190565b88613a7d565b7f22207d2c207b202274726169745f74797065223a20226d696e7444617465222c815290507f2022646973706c61795f74797065223a202264617465222c202276616c75652260208201526101d160f51b6040820152613d40613d3a613d02613c32613ca7604286018b613a7d565b7f207d2c207b202274726169745f74797065223a2022616374696f6e446174652281527f2c2022646973706c61795f74797065223a202264617465222c202276616c75656020820152620111d160ed1b604082015260430190565b7f207d2c207b202274726169745f74797065223a202272616e6b222c202276616c8152653ab2911d101160d11b602082015260260190565b85613a7d565b65227d205d207d60d01b81526006019e9d5050505050505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613d9981601d85016020870161300a565b91909101601d0192915050565b808201808211156106ce576106ce613874565b6001600160a01b038e168152613dd2602082018e613844565b8b60408201528a606082015261018060808201526000613df661018083018c61302e565b60a083018b90526001600160a01b038a1660c084015260e083018990526101008301889052828103610120840152858152858760208301376000602087830101526020601f19601f88011682010191505083610140830152613e646101608301846001600160a01b03169052565b9e9d5050505050505050505050505050565b600060208284031215613e8857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082613ef757634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176106ce576106ce613874565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d449083018461302e565b600060208284031215613faa57600080fd5b815161280181612fd7565b60008251613fc781846020870161300a565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a2945a2b31cee972719ab26eb163febe33e8e88b7d558cb243f0895bc8a6803b64736f6c63430008130033
Deployed Bytecode
0x60806040526004361061021a5760003560e01c80636352211e11610123578063b45a3c0e116100ab578063e111a4581161006f578063e111a458146105d3578063e985e9c5146105f3578063f0f4426014610613578063f2fde38b14610633578063fdda2b211461065357600080fd5b8063b45a3c0e1461054e578063b88d4fde1461056e578063c87b56dd14610589578063dc4b201d146105a9578063ddca3f43146105bc57600080fd5b8063715018a6116100f2578063715018a6146104cb5780638da5cb5b146104e05780638f15b414146104fe57806395d89b411461051e578063a22cb4651461053357600080fd5b80636352211e1461044b57806366c8f9951461046b57806369fe0e2d1461048b57806370a08231146104ab57600080fd5b806323b872dd116101a657806342842e0e1161017557806342842e0e146103715780634f1ef286146103e25780634f6ccce7146103f557806352d1902d1461041557806361d027b31461042a57600080fd5b806323b872dd146103715780632a73dead1461038c5780632f745c59146103a25780633659cfe6146103c257600080fd5b8063095ea7b3116101ed578063095ea7b3146102d05780630eceb3f3146102f057806312d8b6591461031057806318160ddd146103305780631cc7d7431461035057600080fd5b806301ffc9a71461021f57806306fdde031461025457806307d8ca9914610276578063081812fc14610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004612fed565b610673565b60405190151581526020015b60405180910390f35b34801561026057600080fd5b506102696106d4565b60405161024b919061305a565b34801561028257600080fd5b50610296610291366004613123565b610766565b005b3480156102a457600080fd5b506102b86102b33660046131dc565b610809565b6040516001600160a01b03909116815260200161024b565b3480156102dc57600080fd5b506102966102eb36600461320a565b610830565b3480156102fc57600080fd5b5061029661030b366004613320565b610849565b34801561031c57600080fd5b5061029661032b3660046133bd565b61098d565b34801561033c57600080fd5b5061012f545b60405190815260200161024b565b34801561035c57600080fd5b506101c3546102b8906001600160a01b031681565b34801561037d57600080fd5b506102966102eb3660046133da565b34801561039857600080fd5b50610342610e1081565b3480156103ae57600080fd5b506103426103bd36600461320a565b6109eb565b3480156103ce57600080fd5b506102966103dd3660046133bd565b610a82565b6102966103f036600461341b565b610b61565b34801561040157600080fd5b506103426104103660046131dc565b610c31565b34801561042157600080fd5b50610342610cc6565b34801561043657600080fd5b50610191546102b8906001600160a01b031681565b34801561045757600080fd5b506102b86104663660046131dc565b610d79565b34801561047757600080fd5b5061023f61048636600461346a565b610dd9565b34801561049757600080fd5b506102966104a63660046131dc565b610e36565b3480156104b757600080fd5b506103426104c63660046133bd565b610e74565b3480156104d757600080fd5b50610296610efa565b3480156104ec57600080fd5b506065546001600160a01b03166102b8565b34801561050a57600080fd5b5061029661051936600461349f565b610f0e565b34801561052a57600080fd5b5061026961105a565b34801561053f57600080fd5b506102966102eb366004613527565b34801561055a57600080fd5b5061023f6105693660046131dc565b611069565b34801561057a57600080fd5b506102966102eb366004613565565b34801561059557600080fd5b506102696105a43660046131dc565b6110a9565b6102966105b73660046135d0565b6113f3565b3480156105c857600080fd5b506103426101925481565b3480156105df57600080fd5b506102966105ee36600461346a565b6118fe565b3480156105ff57600080fd5b5061023f61060e36600461368b565b611a50565b34801561061f57600080fd5b5061029661062e3660046133bd565b611a6b565b34801561063f57600080fd5b5061029661064e3660046133bd565b611ac2565b34801561065f57600080fd5b5061023f61066e3660046136b9565b611b38565b6000632483248360e11b6001600160e01b0319831614806106a457506001600160e01b03198216635a2d1e0760e11b145b806106bf57506001600160e01b0319821663780e9d6360e01b145b806106ce57506106ce82611ba2565b92915050565b606060fb80546106e3906136e7565b80601f016020809104026020016040519081016040528092919081815260200182805461070f906136e7565b801561075c5780601f106107315761010080835404028352916020019161075c565b820191906000526020600020905b81548152906001019060200180831161073f57829003601f168201915b5050505050905090565b61076e611bc7565b806101c8600084600281111561078657610786613721565b600281111561079757610797613721565b81526020810191909152604001600020815181906107b59082613785565b50602082015160018201906107ca9082613785565b509050507fe25b659a5fa3c64284364ec8c25d34ef8a9ac8d29add13cacd6cb9c1698a5b41826040516107fd9190613866565b60405180910390a15050565b600061081482611c21565b50600090815260ff60205260409020546001600160a01b031690565b60405163a4420a9560e01b815260040160405180910390fd5b610855610e104261388a565b8510156108755760405163df4cc36d60e01b815260040160405180910390fd5b610886866000808888888888611c80565b6108a35760405163c1606c2f60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c560209081526040822090880151829060028111156108d6576108d6613721565b60028111156108e7576108e7613721565b815260200190815260200160002060008860600151815260200190815260200160002054905080600003610936576040516338077a2b60e01b8152600481018290526024015b60405180910390fd5b60008181526101c46020526040902061095085878361389d565b506040518181527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a150505050505050565b610995611bc7565b6101c380546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b60006109f683610e74565b8210610a585760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161092d565b506001600160a01b0391909116600090815261012d60209081526040808320938352929052205490565b6001600160a01b037f000000000000000000000000326f14942f8899406e3224bd63e9f250d275a52e163003610aca5760405162461bcd60e51b815260040161092d9061395c565b7f000000000000000000000000326f14942f8899406e3224bd63e9f250d275a52e6001600160a01b0316610b13600080516020613fe8833981519152546001600160a01b031690565b6001600160a01b031614610b395760405162461bcd60e51b815260040161092d906139a8565b610b4281611d9d565b60408051600080825260208201909252610b5e91839190611da5565b50565b6001600160a01b037f000000000000000000000000326f14942f8899406e3224bd63e9f250d275a52e163003610ba95760405162461bcd60e51b815260040161092d9061395c565b7f000000000000000000000000326f14942f8899406e3224bd63e9f250d275a52e6001600160a01b0316610bf2600080516020613fe8833981519152546001600160a01b031690565b6001600160a01b031614610c185760405162461bcd60e51b815260040161092d906139a8565b610c2182611d9d565b610c2d82826001611da5565b5050565b6000610c3d61012f5490565b8210610ca05760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161092d565b61012f8281548110610cb457610cb46139f4565b90600052602060002001549050919050565b6000306001600160a01b037f000000000000000000000000326f14942f8899406e3224bd63e9f250d275a52e1614610d665760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161092d565b50600080516020613fe883398151915290565b600081815260fd60205260408120546001600160a01b0316806106ce5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161092d565b60008381526101ca6020526040812081846002811115610dfb57610dfb613721565b6002811115610e0c57610e0c613721565b81526020808201929092526040908101600090812085825290925290205460ff1690509392505050565b610e3e611bc7565b6101928190556040518181527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3906020016109e0565b60006001600160a01b038216610ede5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161092d565b506001600160a01b0316600090815260fe602052604090205490565b610f02611bc7565b610f0c6000611f15565b565b600054610100900460ff1615808015610f2e5750600054600160ff909116105b80610f485750303b158015610f48575060005460ff166001145b610fab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161092d565b6000805460ff191660011790558015610fce576000805461ff0019166101001790555b6101c380546001600160a01b0319166001600160a01b038416179055610ff2611f67565b610ffa611f96565b6110048585611fbd565b61100d83611ff6565b8015611053576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606060fc80546106e3906136e7565b600081815260fd60205260408120546001600160a01b03166110a1576040516338077a2b60e01b81526004810183905260240161092d565b506001919050565b600081815260fd60205260409020546060906001600160a01b03166110e4576040516338077a2b60e01b81526004810183905260240161092d565b60008281526101c6602090815260408083208151610100810190925280546001600160a01b03811683529192909190830190600160a01b900460ff16600281111561113157611131613721565b600281111561114257611142613721565b81528154600160a81b90046001600160581b03166020820152600182018054604090920191611170906136e7565b80601f016020809104026020016040519081016040528092919081815260200182805461119c906136e7565b80156111e95780601f106111be576101008083540402835291602001916111e9565b820191906000526020600020905b8154815290600101906020018083116111cc57829003601f168201915b50505091835250506002828101546001600160801b03808216602080860191909152600160801b928390048216604086015260039095015480821660608601529190910416608090920191909152908201519192506000916113c8916101c891849181111561125a5761125a613721565b600281111561126b5761126b613721565b815260200190815260200160002060000183606001516101c860008660200151600281111561129c5761129c613721565b60028111156112ad576112ad613721565b815260200190815260200160002060010185606001516101c460008a81526020019081526020016000206101c86000896020015160028111156112f2576112f2613721565b600281111561130357611303613721565b815260200190815260200160002060000161132a89608001516001600160801b0316612040565b6113408a604001516001600160581b0316612040565b6113568b60c001516001600160801b0316612040565b61136c8c60e001516001600160801b0316612040565b6101c9548f116113845761137f8f612040565b61139a565b61139a8d60a001516001600160801b0316612040565b6040516020016113b49b9a99989796959493929190613a99565b6040516020818303038152906040526120d2565b9050806040516020016113db9190613d61565b60405160208183030381529060405292505050919050565b6113ff610e104261388a565b85101561141f5760405163df4cc36d60e01b815260040160405180910390fd5b87516001600160a01b031660009081526101c5602090815260408220908a0151909190600281111561145357611453613721565b600281111561146457611464613721565b81526020019081526020016000206000896060015181526020019081526020016000205460001415806114f4575060408089015160009081526101ca6020908152918120918a015160028111156114bd576114bd613721565b60028111156114ce576114ce613721565b81526020808201929092526040908101600090812060608c0151825290925290205460ff165b1561151257604051630c8d9eab60e31b815260040160405180910390fd5b6115228888888888888888611c80565b61153f5760405163c1606c2f60e01b815260040160405180910390fd5b600061154b61012f5490565b611556906001613da6565b60608a015160009081526101c760209081526040808320805460010190558c516001600160a01b031683526101c582528220908c0151929350839290919060028111156115a5576115a5613721565b60028111156115b6576115b6613721565b815260200190815260200160002060008b606001518152602001908152602001600020819055506040518061010001604052808a600001516001600160a01b031681526020018a60200151600281111561161257611612613721565b81526040808c01516001600160581b03166020808401919091526080808e0151838501526060808f0180516001600160801b03908116928701929092525160009081526101c784528481205482169286019290925242811660a0808701919091528f01511660c0909401939093528483526101c681529120825181546001600160a01b039091166001600160a01b031982168117835592840151919283916001600160a81b03191617600160a01b8360028111156116d2576116d2613721565b0217905550604082015181546001600160581b03909116600160a81b026001600160a81b03909116178155606082015160018201906117119082613785565b50608082015160a08301516001600160801b03918216600160801b918316820217600284015560c084015160e09094015193821693909116029190911760039091015560008181526101c46020526040902061176e85878361389d565b5060016101ca60008b60400151815260200190815260200160002060008b6020015160028111156117a1576117a1613721565b60028111156117b2576117b2613721565b81526020808201929092526040908101600090812060608e015182529092529020805460ff1916911515919091179055610192546117f08882613da6565b3403611834576101915461180d906001600160a01b031682612224565b6001600160a01b0389161561182f5761182f6001600160a01b038a1689612224565b611861565b3461183f8983613da6565b60405163dcf6afcb60e01b81526004810192909252602482015260440161092d565b895161186d90836122a3565b6040518281527f032bc66be43dbccb7487781d168eb7bda224628a3b2c3388bdf69b532a3a16119060200160405180910390a189606001518a6020015160028111156118bb576118bb613721565b8b516040516001600160a01b03909116907fc73092756e22756fd0b15b2f803bd49db35ee23e7ae171c4d414ab7a61fa8b7c90600090a450505050505050505050565b3360009081526101c5602052604081208184600281111561192157611921613721565b600281111561193257611932613721565b8152602080820192909252604090810160009081208582528352818120543382526101c5909352908120919250908185600281111561197357611973613721565b600281111561198457611984613721565b8152602080820192909252604090810160009081208682528352818120939093558383526101c69091528120818155906119c16001830182612f89565b5060006002820181905560039091018190558181526101c4602052604081206119e991612f89565b60008481526101ca6020526040812090846002811115611a0b57611a0b613721565b6002811115611a1c57611a1c613721565b8152602080820192909252604090810160009081208582529092529020805460ff19169055611a4a816122bd565b50505050565b600060405163a4420a9560e01b815260040160405180910390fd5b611a73611bc7565b61019180546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f608906020016109e0565b611aca611bc7565b6001600160a01b038116611b2f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161092d565b610b5e81611f15565b6001600160a01b03831660009081526101c56020526040812081846002811115611b6457611b64613721565b6002811115611b7557611b75613721565b81526020019081526020016000206000838152602001908152602001600020546000141590509392505050565b60006001600160e01b0319821663780e9d6360e01b14806106ce57506106ce82612360565b6065546001600160a01b03163314610f0c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161092d565b600081815260fd60205260409020546001600160a01b0316610b5e5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161092d565b600060418214611ca35760405163c1606c2f60e01b815260040160405180910390fd5b6000611d328a600001518b602001518c604001518d606001518e608001518f60a001518f8f8f8f8f4630604051602001611ce99d9c9b9a99989796959493929190613db9565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b6101c354604080516020601f88018190048102820181019092528681529293506001600160a01b0390911691611d8591879087908190840183828082843760009201919091525086939250506123b09050565b6001600160a01b0316149a9950505050505050505050565b610b5e611bc7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611ddd57611dd8836123d4565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e37575060408051601f3d908101601f19168201909252611e3491810190613e76565b60015b611e9a5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161092d565b600080516020613fe88339815191528114611f095760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161092d565b50611dd8838383612470565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611f8e5760405162461bcd60e51b815260040161092d90613e8f565b610f0c612495565b600054610100900460ff16610f0c5760405162461bcd60e51b815260040161092d90613e8f565b600054610100900460ff16611fe45760405162461bcd60e51b815260040161092d90613e8f565b611fee82826124c5565b610c2d611f96565b600054610100900460ff1661201d5760405162461bcd60e51b815260040161092d90613e8f565b61019180546001600160a01b0319166001600160a01b0392909216919091179055565b6060600061204d836124f6565b60010190506000816001600160401b0381111561206c5761206c613081565b6040519080825280601f01601f191660200182016040528015612096576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846120a057509392505050565b606081516000036120f157505060408051602081019091526000815290565b600060405180606001604052806040815260200161400860409139905060006003845160026121209190613da6565b61212a9190613eda565b612135906004613efc565b6001600160401b0381111561214c5761214c613081565b6040519080825280601f01601f191660200182016040528015612176576020820181803683370190505b509050600182016020820185865187015b808210156121e2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250612187565b50506003865106600181146121fe576002811461221157612219565b603d6001830353603d6002830353612219565b603d60018303535b509195945050505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612271576040519150601f19603f3d011682016040523d82523d6000602084013e612276565b606091505b5050905080611dd857604051632499e3bb60e11b81526001600160a01b038416600482015260240161092d565b610c2d8282604051806020016040528060008152506125ce565b60006122c882610d79565b90506122d8816000846001612601565b6122e182610d79565b600083815260ff6020908152604080832080546001600160a01b03199081169091556001600160a01b03851680855260fe8452828520805460001901905587855260fd909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b031982166380ac58cd60e01b148061239157506001600160e01b03198216635b5e139f60e01b145b806106ce57506301ffc9a760e01b6001600160e01b03198316146106ce565b60008060006123bf858561260d565b915091506123cc81612652565b509392505050565b6001600160a01b0381163b6124415760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161092d565b600080516020613fe883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6124798361279c565b6000825111806124865750805b15611dd857611a4a83836127dc565b600054610100900460ff166124bc5760405162461bcd60e51b815260040161092d90613e8f565b610f0c33611f15565b600054610100900460ff166124ec5760405162461bcd60e51b815260040161092d90613e8f565b610c2d8282612808565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106125355772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612561576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061257f57662386f26fc10000830492506010015b6305f5e1008310612597576305f5e100830492506008015b61271083106125ab57612710830492506004015b606483106125bd576064830492506002015b600a83106106ce5760010192915050565b6125d88383612848565b6125e560008484846129e1565b611dd85760405162461bcd60e51b815260040161092d90613f13565b611a4a84848484612ae3565b60008082516041036126435760208301516040840151606085015160001a61263787828585612c12565b9450945050505061264b565b506000905060025b9250929050565b600081600481111561266657612666613721565b0361266e5750565b600181600481111561268257612682613721565b036126cf5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161092d565b60028160048111156126e3576126e3613721565b036127305760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161092d565b600381600481111561274457612744613721565b03610b5e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161092d565b6127a5816123d4565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060612801838360405180606001604052806027815260200161404860279139612cd6565b9392505050565b600054610100900460ff1661282f5760405162461bcd60e51b815260040161092d90613e8f565b60fb61283b8382613785565b5060fc611dd88282613785565b6001600160a01b03821661289e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161092d565b600081815260fd60205260409020546001600160a01b0316156129035760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161092d565b612911600083836001612601565b600081815260fd60205260409020546001600160a01b0316156129765760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161092d565b6001600160a01b038216600081815260fe602090815260408083208054600101905584835260fd90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15612ad757604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a25903390899088908890600401613f65565b6020604051808303816000875af1925050508015612a60575060408051601f3d908101601f19168201909252612a5d91810190613f98565b60015b612abd573d808015612a8e576040519150601f19603f3d011682016040523d82523d6000602084013e612a93565b606091505b508051600003612ab55760405162461bcd60e51b815260040161092d90613f13565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612adb565b5060015b949350505050565b6001811115612b525760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161092d565b816001600160a01b038516612bb057612bab8161012f8054600083815261013060205260408120829055600182018355919091527f232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f9790155565b612bd3565b836001600160a01b0316856001600160a01b031614612bd357612bd38582612d4e565b6001600160a01b038416612bef57612bea81612df0565b611053565b846001600160a01b0316846001600160a01b031614611053576110538482612ea5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c495750600090506003612ccd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c9d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612cc657600060019250925050612ccd565b9150600090505b94509492505050565b6060600080856001600160a01b031685604051612cf39190613fb5565b600060405180830381855af49150503d8060008114612d2e576040519150601f19603f3d011682016040523d82523d6000602084013e612d33565b606091505b5091509150612d4486838387612eeb565b9695505050505050565b60006001612d5b84610e74565b612d65919061388a565b600083815261012e6020526040902054909150808214612dbb576001600160a01b038416600090815261012d60209081526040808320858452825280832054848452818420819055835261012e90915290208190555b50600091825261012e602090815260408084208490556001600160a01b03909416835261012d81528383209183525290812055565b61012f54600090612e039060019061388a565b6000838152610130602052604081205461012f8054939450909284908110612e2d57612e2d6139f4565b906000526020600020015490508061012f8381548110612e4f57612e4f6139f4565b6000918252602080832090910192909255828152610130909152604080822084905585825281205561012f805480612e8957612e89613fd1565b6001900381819060005260206000200160009055905550505050565b6000612eb083610e74565b6001600160a01b03909316600090815261012d60209081526040808320868452825280832085905593825261012e9052919091209190915550565b60608315612f5a578251600003612f53576001600160a01b0385163b612f535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161092d565b5081612adb565b612adb8383815115612f6f5781518083602001fd5b8060405162461bcd60e51b815260040161092d919061305a565b508054612f95906136e7565b6000825580601f10612fa5575050565b601f016020900490600052602060002090810190610b5e91905b80821115612fd35760008155600101612fbf565b5090565b6001600160e01b031981168114610b5e57600080fd5b600060208284031215612fff57600080fd5b813561280181612fd7565b60005b8381101561302557818101518382015260200161300d565b50506000910152565b6000815180845261304681602086016020860161300a565b601f01601f19169290920160200192915050565b602081526000612801602083018461302e565b80356003811061307c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126130a857600080fd5b81356001600160401b03808211156130c2576130c2613081565b604051601f8301601f19908116603f011681019082821181831017156130ea576130ea613081565b8160405283815286602085880101111561310357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561313657600080fd5b61313f8361306d565b915060208301356001600160401b038082111561315b57600080fd5b908401906040828703121561316f57600080fd5b60405160408101818110838211171561318a5761318a613081565b60405282358281111561319c57600080fd5b6131a888828601613097565b8252506020830135828111156131bd57600080fd5b6131c988828601613097565b6020830152508093505050509250929050565b6000602082840312156131ee57600080fd5b5035919050565b6001600160a01b0381168114610b5e57600080fd5b6000806040838503121561321d57600080fd5b8235613228816131f5565b946020939093013593505050565b600060c0828403121561324857600080fd5b60405160c081016001600160401b03828210818311171561326b5761326b613081565b816040528293508435915061327f826131f5565b81835261328e6020860161306d565b6020840152604085013560408401526060850135606084015260808501359150808211156132bb57600080fd5b506132c885828601613097565b60808301525060a083013560a08201525092915050565b60008083601f8401126132f157600080fd5b5081356001600160401b0381111561330857600080fd5b60208301915083602082850101111561264b57600080fd5b6000806000806000806080878903121561333957600080fd5b86356001600160401b038082111561335057600080fd5b61335c8a838b01613236565b975060208901359650604089013591508082111561337957600080fd5b6133858a838b016132df565b9096509450606089013591508082111561339e57600080fd5b506133ab89828a016132df565b979a9699509497509295939492505050565b6000602082840312156133cf57600080fd5b8135612801816131f5565b6000806000606084860312156133ef57600080fd5b83356133fa816131f5565b9250602084013561340a816131f5565b929592945050506040919091013590565b6000806040838503121561342e57600080fd5b8235613439816131f5565b915060208301356001600160401b0381111561345457600080fd5b61346085828601613097565b9150509250929050565b60008060006060848603121561347f57600080fd5b8335925061348f6020850161306d565b9150604084013590509250925092565b600080600080608085870312156134b557600080fd5b84356001600160401b03808211156134cc57600080fd5b6134d888838901613097565b955060208701359150808211156134ee57600080fd5b506134fb87828801613097565b935050604085013561350c816131f5565b9150606085013561351c816131f5565b939692955090935050565b6000806040838503121561353a57600080fd5b8235613545816131f5565b91506020830135801515811461355a57600080fd5b809150509250929050565b6000806000806080858703121561357b57600080fd5b8435613586816131f5565b93506020850135613596816131f5565b92506040850135915060608501356001600160401b038111156135b857600080fd5b6135c487828801613097565b91505092959194509250565b60008060008060008060008060c0898b0312156135ec57600080fd5b88356001600160401b038082111561360357600080fd5b61360f8c838d01613236565b995060208b01359150613621826131f5565b90975060408a0135965060608a0135955060808a0135908082111561364557600080fd5b6136518c838d016132df565b909650945060a08b013591508082111561366a57600080fd5b506136778b828c016132df565b999c989b5096995094979396929594505050565b6000806040838503121561369e57600080fd5b82356136a9816131f5565b9150602083013561355a816131f5565b6000806000606084860312156136ce57600080fd5b83356136d9816131f5565b925061348f6020850161306d565b600181811c908216806136fb57607f821691505b60208210810361371b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b601f821115611dd857600081815260208120601f850160051c8101602086101561375e5750805b601f850160051c820191505b8181101561377d5782815560010161376a565b505050505050565b81516001600160401b0381111561379e5761379e613081565b6137b2816137ac84546136e7565b84613737565b602080601f8311600181146137e757600084156137cf5750858301515b600019600386901b1c1916600185901b17855561377d565b600085815260208120601f198616915b82811015613816578886015182559484019460019091019084016137f7565b50858210156138345787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6003811061386257634e487b7160e01b600052602160045260246000fd5b9052565b602081016106ce8284613844565b634e487b7160e01b600052601160045260246000fd5b818103818111156106ce576106ce613874565b6001600160401b038311156138b4576138b4613081565b6138c8836138c283546136e7565b83613737565b6000601f8411600181146138fc57600085156138e45750838201355b600019600387901b1c1916600186901b178355611053565b600083815260209020601f19861690835b8281101561392d578685013582556020948501946001909201910161390d565b508682101561394a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60008154613a17816136e7565b60018281168015613a2f5760018114613a4457613a73565b60ff1984168752821515830287019450613a73565b8560005260208060002060005b85811015613a6a5781548a820152908401908201613a51565b50505082870194505b5050505092915050565b60008151613a8f81856020860161300a565b9290920192915050565b693d913730b6b2911d101160b11b81526000613ab8600a83018e613a0a565b600160fd1b8152613acc600182018e613a7d565b72111610113232b9b1b934b83a34b7b7111d101160691b81529050613af4601382018d613a0a565b600160fd1b81529050613b4a613b44613b10600184018e613a7d565b7f206f6e204775696c642e78797a2e222c2022696d616765223a2022697066733a8152612f2f60f01b602082015260220190565b8b613a0a565b71222c202261747472696275746573223a205b60701b815290507f207b202274726169745f74797065223a202274797065222c000000000000000060128201526a10113b30b63ab2911d101160a91b602a820152613bab603582018a613a0a565b7f227d2c207b202274726169745f74797065223a20226775696c644964222c0000815290506a10113b30b63ab2911d101160a91b601e820152613c38613c32613bf7602984018b613a7d565b7f22207d2c207b202274726169745f74797065223a2022757365724964222c20228152683b30b63ab2911d101160b91b602082015260290190565b88613a7d565b7f22207d2c207b202274726169745f74797065223a20226d696e7444617465222c815290507f2022646973706c61795f74797065223a202264617465222c202276616c75652260208201526101d160f51b6040820152613d40613d3a613d02613c32613ca7604286018b613a7d565b7f207d2c207b202274726169745f74797065223a2022616374696f6e446174652281527f2c2022646973706c61795f74797065223a202264617465222c202276616c75656020820152620111d160ed1b604082015260430190565b7f207d2c207b202274726169745f74797065223a202272616e6b222c202276616c8152653ab2911d101160d11b602082015260260190565b85613a7d565b65227d205d207d60d01b81526006019e9d5050505050505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613d9981601d85016020870161300a565b91909101601d0192915050565b808201808211156106ce576106ce613874565b6001600160a01b038e168152613dd2602082018e613844565b8b60408201528a606082015261018060808201526000613df661018083018c61302e565b60a083018b90526001600160a01b038a1660c084015260e083018990526101008301889052828103610120840152858152858760208301376000602087830101526020601f19601f88011682010191505083610140830152613e646101608301846001600160a01b03169052565b9e9d5050505050505050505050505050565b600060208284031215613e8857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082613ef757634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176106ce576106ce613874565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d449083018461302e565b600060208284031215613faa57600080fd5b815161280181612fd7565b60008251613fc781846020870161300a565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a2945a2b31cee972719ab26eb163febe33e8e88b7d558cb243f0895bc8a6803b64736f6c63430008130033
Deployed Bytecode Sourcemap
979:9022:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1760:431:6;;;;;;;;;;-1:-1:-1;1760:431:6;;;;;:::i;:::-;;:::i;:::-;;;565:14:32;;558:22;540:41;;528:2;513:18;1760:431:6;;;;;;;;2932:98:15;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;6439:201:0:-;;;;;;;;;;-1:-1:-1;6439:201:0;;;;;:::i;:::-;;:::i;:::-;;4407:167:15;;;;;;;;;;-1:-1:-1;4407:167:15;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3871:32:32;;;3853:51;;3841:2;3826:18;4407:167:15;3707:203:32;2358:178:6;;;;;;;;;;-1:-1:-1;2358:178:6;;;;;:::i;:::-;;:::i;5805:628:0:-;;;;;;;;;;-1:-1:-1;5805:628:0;;;;;:::i;:::-;;:::i;5638:161::-;;;;;;;;;;-1:-1:-1;5638:161:0;;;;;:::i;:::-;;:::i;1950:111:18:-;;;;;;;;;;-1:-1:-1;2037:10:18;:17;1950:111;;;7122:25:32;;;7110:2;7095:18;1950:111:18;6976:177:32;1363:26:0;;;;;;;;;;-1:-1:-1;1363:26:0;;;;-1:-1:-1;;;;;1363:26:0;;;2957:211:6;;;;;;;;;;-1:-1:-1;2957:211:6;;;;;:::i;1305:52:0:-;;;;;;;;;;;;1350:7;1305:52;;1615:264:18;;;;;;;;;;-1:-1:-1;1615:264:18;;;;;:::i;:::-;;:::i;3387:195:14:-;;;;;;;;;;-1:-1:-1;3387:195:14;;;;;:::i;:::-;;:::i;3901:220::-;;;;;;:::i;:::-;;:::i;2133:241:18:-;;;;;;;;;;-1:-1:-1;2133:241:18;;;;;:::i;:::-;;:::i;3006:131:14:-;;;;;;;;;;;;;:::i;480:31:7:-;;;;;;;;;;-1:-1:-1;480:31:7;;;;-1:-1:-1;;;;;480:31:7;;;2651:219:15;;;;;;;;;;-1:-1:-1;2651:219:15;;;;;:::i;:::-;;:::i;6831:212:0:-;;;;;;;;;;-1:-1:-1;6831:212:0;;;;;:::i;:::-;;:::i;878:113:7:-;;;;;;;;;;-1:-1:-1;878:113:7;;;;;:::i;:::-;;:::i;2390:204:15:-;;;;;;;;;;-1:-1:-1;2390:204:15;;;;;:::i;:::-;;:::i;2064:101:8:-;;;;;;;;;;;;;:::i;1441:85::-;;;;;;;;;;-1:-1:-1;1513:6:8;;-1:-1:-1;;;;;1513:6:8;1441:85;;2933:358:0;;;;;;;;;;-1:-1:-1;2933:358:0;;;;;:::i;:::-;;:::i;3094:102:15:-;;;;;;;;;;;;;:::i;2542:192:6:-;;;;;;;;;;-1:-1:-1;2542:192:6;;;;;:::i;2197:155::-;;;;;;;;;;-1:-1:-1;2197:155:6;;;;;:::i;:::-;;:::i;3395:248::-;;;;;;;;;;-1:-1:-1;3395:248:6;;;;;:::i;7049:1883:0:-;;;;;;;;;;-1:-1:-1;7049:1883:0;;;;;:::i;:::-;;:::i;3424:1815::-;;;;;;:::i;:::-;;:::i;518:18:7:-;;;;;;;;;;;;;;;;5245:387:0;;;;;;;;;;-1:-1:-1;5245:387:0;;;;;:::i;:::-;;:::i;2740:211:6:-;;;;;;;;;;-1:-1:-1;2740:211:6;;;;;:::i;:::-;;:::i;997:151:7:-;;;;;;;;;;-1:-1:-1;997:151:7;;;;;:::i;:::-;;:::i;2314:198:8:-;;;;;;;;;;-1:-1:-1;2314:198:8;;;;;:::i;:::-;;:::i;6646:179:0:-;;;;;;;;;;-1:-1:-1;6646:179:0;;;;;:::i;:::-;;:::i;1760:431:6:-;1927:4;-1:-1:-1;;;;;;;;;1962:25:6;;;;:93;;-1:-1:-1;;;;;;;2014:41:6;;-1:-1:-1;;;2014:41:6;1962:93;:170;;;-1:-1:-1;;;;;;;2071:61:6;;-1:-1:-1;;;2071:61:6;1962:170;:222;;;;2148:36;2172:11;2148:23;:36::i;:::-;1943:241;1760:431;-1:-1:-1;;1760:431:6:o;2932:98:15:-;2986:13;3018:5;3011:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2932:98;:::o;6439:201:0:-;1334:13:8;:11;:13::i;:::-;6582:10:0::1;6544:22;:35;6567:11;6544:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;6544:35:0;:48;;:35;;:48:::1;::::0;:35;:48:::1;:::i;:::-;-1:-1:-1::0;6544:48:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;6607:26;6621:11;6607:26;;;;;;:::i;:::-;;;;;;;;6439:201:::0;;:::o;4407:167:15:-;4483:7;4502:23;4517:7;4502:14;:23::i;:::-;-1:-1:-1;4543:24:15;;;;:15;:24;;;;;;-1:-1:-1;;;;;4543:24:15;;4407:167::o;2358:178:6:-;2518:11;;-1:-1:-1;;;2518:11:6;;;;;;;;;;;5805:628:0;5999:36;1350:7;5999:15;:36;:::i;:::-;5988:8;:47;5984:78;;;6044:18;;-1:-1:-1;;;6044:18:0;;;;;;;;;;;5984:78;6077;6094:7;6119:1;6124;6127:8;6137:6;;6145:9;;6077:16;:78::i;:::-;6072:124;;6176:20;;-1:-1:-1;;;6176:20:0;;;;;;;;;;;6072:124;6239:16;;-1:-1:-1;;;;;6225:31:0;6207:15;6225:31;;;:13;:31;;;;;;;6257:19;;;;6207:15;;6225:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;6278:7;:15;;;6225:69;;;;;;;;;;;;6207:87;;6308:7;6319:1;6308:12;6304:50;;6329:25;;-1:-1:-1;;;6329:25:0;;;;;7122::32;;;7095:18;;6329:25:0;;;;;;;;6304:50;6365:13;;;;:4;:13;;;;;:22;6381:6;;6365:13;:22;:::i;:::-;-1:-1:-1;6403:23:0;;7122:25:32;;;6403:23:0;;7110:2:32;7095:18;6403:23:0;;;;;;;5974:459;5805:628;;;;;;:::o;5638:161::-;1334:13:8;:11;:13::i;:::-;5715:11:0::1;:28:::0;;-1:-1:-1;;;;;;5715:28:0::1;-1:-1:-1::0;;;;;5715:28:0;::::1;::::0;;::::1;::::0;;;5758:34:::1;::::0;3853:51:32;;;5758:34:0::1;::::0;3841:2:32;3826:18;5758:34:0::1;;;;;;;;5638:161:::0;:::o;1615:264:18:-;1712:7;1747:34;1775:5;1747:27;:34::i;:::-;1739:5;:42;1731:98;;;;-1:-1:-1;;;1731:98:18;;17933:2:32;1731:98:18;;;17915:21:32;17972:2;17952:18;;;17945:30;18011:34;17991:18;;;17984:62;-1:-1:-1;;;18062:18:32;;;18055:41;18113:19;;1731:98:18;17731:407:32;1731:98:18;-1:-1:-1;;;;;;1846:19:18;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1615:264::o;3387:195:14:-;-1:-1:-1;;;;;1898:6:14;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:14;;;;;;;:::i;:::-;1995:6;-1:-1:-1;;;;;1971:30:14;:20;-1:-1:-1;;;;;;;;;;;1536:65:11;-1:-1:-1;;;;;1536:65:11;;1457:151;1971:20:14;-1:-1:-1;;;;;1971:30:14;;1963:87;;;;-1:-1:-1;;;1963:87:14;;;;;;;:::i;:::-;3468:36:::1;3486:17;3468;:36::i;:::-;3555:12;::::0;;3565:1:::1;3555:12:::0;;;::::1;::::0;::::1;::::0;;;3514:61:::1;::::0;3536:17;;3555:12;3514:21:::1;:61::i;:::-;3387:195:::0;:::o;3901:220::-;-1:-1:-1;;;;;1898:6:14;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:14;;;;;;;:::i;:::-;1995:6;-1:-1:-1;;;;;1971:30:14;:20;-1:-1:-1;;;;;;;;;;;1536:65:11;-1:-1:-1;;;;;1536:65:11;;1457:151;1971:20:14;-1:-1:-1;;;;;1971:30:14;;1963:87;;;;-1:-1:-1;;;1963:87:14;;;;;;;:::i;:::-;4016:36:::1;4034:17;4016;:36::i;:::-;4062:52;4084:17;4103:4;4109;4062:21;:52::i;:::-;3901:220:::0;;:::o;2133:241:18:-;2208:7;2243:41;2037:10;:17;;1950:111;2243:41;2235:5;:49;2227:106;;;;-1:-1:-1;;;2227:106:18;;19171:2:32;2227:106:18;;;19153:21:32;19210:2;19190:18;;;19183:30;19249:34;19229:18;;;19222:62;-1:-1:-1;;;19300:18:32;;;19293:42;19352:19;;2227:106:18;18969:408:32;2227:106:18;2350:10;2361:5;2350:17;;;;;;;;:::i;:::-;;;;;;;;;2343:24;;2133:241;;;:::o;3006:131:14:-;3084:7;2324:4;-1:-1:-1;;;;;2333:6:14;2316:23;;2308:92;;;;-1:-1:-1;;;2308:92:14;;19716:2:32;2308:92:14;;;19698:21:32;19755:2;19735:18;;;19728:30;19794:34;19774:18;;;19767:62;19865:26;19845:18;;;19838:54;19909:19;;2308:92:14;19514:420:32;2308:92:14;-1:-1:-1;;;;;;;;;;;;3006:131:14;:::o;2651:219:15:-;2723:7;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:15;;2785:56;;;;-1:-1:-1;;;2785:56:15;;20141:2:32;2785:56:15;;;20123:21:32;20180:2;20160:18;;;20153:30;-1:-1:-1;;;20199:18:32;;;20192:54;20263:18;;2785:56:15;19939:348:32;6831:212:0;6966:12;6997:22;;;:14;:22;;;;;6966:12;7020:11;6997:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;6997:35:0;;;:39;;;;;;;;;;;;-1:-1:-1;6831:212:0;;;;;:::o;878:113:7:-;1334:13:8;:11;:13::i;:::-;939:3:7::1;:12:::0;;;966:18:::1;::::0;7122:25:32;;;966:18:7::1;::::0;7110:2:32;7095:18;966::7::1;6976:177:32::0;2390:204:15;2462:7;-1:-1:-1;;;;;2489:19:15;;2481:73;;;;-1:-1:-1;;;2481:73:15;;20494:2:32;2481:73:15;;;20476:21:32;20533:2;20513:18;;;20506:30;20572:34;20552:18;;;20545:62;-1:-1:-1;;;20623:18:32;;;20616:39;20672:19;;2481:73:15;20292:405:32;2481:73:15;-1:-1:-1;;;;;;2571:16:15;;;;;:9;:16;;;;;;;2390:204::o;2064:101:8:-;1334:13;:11;:13::i;:::-;2128:30:::1;2155:1;2128:18;:30::i;:::-;2064:101::o:0;2933:358:0:-;3279:19:13;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:13;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:13;1713:19:21;:23;;;3387:66:13;;-1:-1:-1;3436:12:13;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:13;;20904:2:32;3325:201:13;;;20886:21:32;20943:2;20923:18;;;20916:30;20982:34;20962:18;;;20955:62;-1:-1:-1;;;21033:18:32;;;21026:44;21087:19;;3325:201:13;20702:410:32;3325:201:13;3536:12;:16;;-1:-1:-1;;3536:16:13;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:13;;;;;3562:65;3110:11:0::1;:26:::0;;-1:-1:-1;;;;;;3110:26:0::1;-1:-1:-1::0;;;;;3110:26:0;::::1;;::::0;;3146:16:::1;:14;:16::i;:::-;3172:24;:22;:24::i;:::-;3206:36;3229:4;3235:6;3206:22;:36::i;:::-;3252:32;3275:8;3252:22;:32::i;:::-;3651:14:13::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:13;;;3721:14;;-1:-1:-1;21269:36:32;;3721:14:13;;21257:2:32;21242:18;3721:14:13;;;;;;;3647:99;3269:483;2933:358:0;;;;:::o;3094:102:15:-;3150:13;3182:7;3175:14;;;;;:::i;2197:155:6:-;2253:4;7266:16:15;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:15;2269:55:6;;2299:25;;-1:-1:-1;;;2299:25:6;;;;;7122::32;;;7095:18;;2299:25:6;6976:177:32;2269:55:6;-1:-1:-1;2341:4:6;;2197:155;-1:-1:-1;2197:155:6:o;7049:1883:0:-;7657:4:15;7266:16;;;:7;:16;;;;;;7114:13:0;;-1:-1:-1;;;;;7266:16:15;7139:55:0;;7169:25;;-1:-1:-1;;;7169:25:0;;;;;7122::32;;;7095:18;;7169:25:0;6976:177:32;7139:55:0;7205:18;7226:29;;;:20;:29;;;;;;;;7205:50;;;;;;;;;;-1:-1:-1;;;;;7205:50:0;;;;;;7226:29;;7205:50;;;;-1:-1:-1;;;7205:50:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;7205:50:0;;-1:-1:-1;;;;;7205:50:0;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7205:50:0;;;-1:-1:-1;;7205:50:0;;;;;-1:-1:-1;;;;;7205:50:0;;;;;;;;;;;-1:-1:-1;;;7205:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7474:10;;;;7205:50;;-1:-1:-1;7205:50:0;;7321:1501;;7451:22;;7205:50;;7451:34;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:45;;7543:3;:13;;;7621:22;:34;7644:3;:10;;;7621:34;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:46;;7714:3;:13;;;7807:4;:13;7812:7;7807:13;;;;;;;;;;;7967:22;:34;7990:3;:10;;;7967:34;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:45;;8123:26;8131:3;:6;;;-1:-1:-1;;;;;8123:15:0;:24;:26::i;:::-;8236:30;8244:3;:10;;;-1:-1:-1;;;;;8236:19:0;:28;:30::i;:::-;8402:32;8410:3;:12;;;-1:-1:-1;;;;;8402:21:0;:30;:32::i;:::-;8547:33;8555:3;:13;;;-1:-1:-1;;;;;8547:22:0;:31;:33::i;:::-;8674:19;;8664:7;:29;:86;;8732:18;:7;:16;:18::i;:::-;8664:86;;;8696:33;8704:3;:13;;;-1:-1:-1;;;;;8696:22:0;:31;:33::i;:::-;7382:1416;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7321:24;:1501::i;:::-;7300:1522;;8920:4;8873:52;;;;;;;;:::i;:::-;;;;;;;;;;;;;8866:59;;;;7049:1883;;;:::o;3424:1815::-;3679:36;1350:7;3679:15;:36;:::i;:::-;3668:8;:47;3664:78;;;3724:18;;-1:-1:-1;;;3724:18:0;;;;;;;;;;;3664:78;3783:16;;-1:-1:-1;;;;;3769:31:0;;;;;:13;:31;;;;;;;3801:19;;;;3769:31;;;:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;3822:7;:15;;;3769:69;;;;;;;;;;;;3842:1;3769:74;;:158;;;-1:-1:-1;3874:14:0;;;;;3859:30;;;;:14;:30;;;;;;;3890:19;;;;3859:51;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;3859:51:0;;;3911:15;;;;3859:68;;;;;;;;;;3769:158;3752:209;;;3945:16;;-1:-1:-1;;;3945:16:0;;;;;;;;;;;3752:209;3976:76;3993:7;4002:13;4017:8;4027;4037:3;;4042:9;;3976:16;:76::i;:::-;3971:110;;4061:20;;-1:-1:-1;;;4061:20:0;;;;;;;;;;;3971:110;4092:15;4110:13;2037:10:18;:17;;1950:111;4110:13:0;:17;;4126:1;4110:17;:::i;:::-;4184:15;;;;4164:36;;;;:19;:36;;;;;;;;4162:38;;;;;;4235:16;;-1:-1:-1;;;;;4221:31:0;;;:13;:31;;;;4253:19;;;;4092:35;;-1:-1:-1;4092:35:0;;4221:31;;4164:36;4221:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;4274:7;:15;;;4221:69;;;;;;;;;;;:79;;;;4342:322;;;;;;;;4363:7;:16;;;-1:-1:-1;;;;;4342:322:0;;;;;4393:7;:19;;;4342:322;;;;;;;;:::i;:::-;;;4433:14;;;;;-1:-1:-1;;;;;4342:322:0;;;;;;;;;4462:17;;;;;4342:322;;;;;4501:15;;;;;-1:-1:-1;;;;;4342:322:0;;;;;;;;;;4559:15;-1:-1:-1;4539:36:0;;;:19;:36;;;;;;4342:322;;;;;;;;;4598:15;4342:322;;;;;;;;;;4636:17;;;4342:322;;;;;;;;;4310:29;;;:20;:29;;;;:354;;;;-1:-1:-1;;;;;4310:354:0;;;-1:-1:-1;;;;;;4310:354:0;;;;;;;;;;:29;;;;-1:-1:-1;;;;;;4310:354:0;;-1:-1:-1;;;4310:354:0;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;4310:354:0;;;;;;-1:-1:-1;;;;;4310:354:0;;;-1:-1:-1;;;4310:354:0;-1:-1:-1;;;;;4310:354:0;;;;;;;;;;-1:-1:-1;4310:354:0;;;;;;;:::i;:::-;-1:-1:-1;4310:354:0;;;;;;;;-1:-1:-1;;;;;4310:354:0;;;-1:-1:-1;;;4310:354:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4674:13:0;;;:4;:13;;;;;:19;4690:3;;4674:13;:19;:::i;:::-;;4774:4;4703:14;:30;4718:7;:14;;;4703:30;;;;;;;;;;;:51;4734:7;:19;;;4703:51;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;4703:51:0;;;4755:15;;;;4703:68;;;;;;;:75;;-1:-1:-1;;4703:75:0;;;;;;;;;;4834:3;;4864:19;4875:8;4834:3;4864:19;:::i;:::-;4851:9;:32;4847:228;;4899:8;;:28;;-1:-1:-1;;;;;4899:8:0;4918;4899:18;:28::i;:::-;-1:-1:-1;;;;;4945:27:0;;;4941:66;;4974:33;-1:-1:-1;;;;;4974:23:0;;4998:8;4974:23;:33::i;:::-;4847:228;;;5044:9;5055:19;5066:8;5055;:19;:::i;:::-;5031:44;;-1:-1:-1;;;5031:44:0;;;;;28760:25:32;;;;28801:18;;;28794:34;28733:18;;5031:44:0;28586:248:32;4847:228:0;5096:16;;5086:36;;5114:7;5086:9;:36::i;:::-;5138:15;;7122:25:32;;;5138:15:0;;7110:2:32;7095:18;5138:15:0;;;;;;;5216:7;:15;;;5195:7;:19;;;5169:63;;;;;;;;:::i;:::-;5177:16;;5169:63;;-1:-1:-1;;;;;5169:63:0;;;;;;5177:16;;5169:63;3654:1585;;3424:1815;;;;;;;;:::o;5245:387::-;5368:10;5336:15;5354:25;;;:13;:25;;;;;5336:15;5380:11;5354:38;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5354:38:0;;;:47;;;;;;;;;5426:10;5412:25;;:13;:25;;;;;;5354:47;;-1:-1:-1;;;5438:11:0;5412:38;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5412:38:0;;;:47;;;;;;;;:51;;;;5480:29;;;:20;:29;;;;;5473:36;;;5480:29;5473:36;;;;-1:-1:-1;5473:36:0;:::i;:::-;-1:-1:-1;5473:36:0;;;;;;;;;;;;;;5526:13;;;:4;:13;;;;;5519:20;;;:::i;:::-;5556:22;;;;:14;:22;;;;;;5579:11;5556:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5556:35:0;;;:44;;;;;;;;5549:51;;-1:-1:-1;;5549:51:0;;;5611:14;5617:7;5611:5;:14::i;:::-;5326:306;5245:387;;;:::o;2740:211:6:-;2910:4;2933:11;;-1:-1:-1;;;2933:11:6;;;;;;;;;;;997:151:7;1334:13:8;:11;:13::i;:::-;1076:8:7::1;:22:::0;;-1:-1:-1;;;;;;1076:22:7::1;-1:-1:-1::0;;;;;1076:22:7;::::1;::::0;;::::1;::::0;;;1113:28:::1;::::0;3853:51:32;;;1113:28:7::1;::::0;3841:2:32;3826:18;1113:28:7::1;3707:203:32::0;2314:198:8;1334:13;:11;:13::i;:::-;-1:-1:-1;;;;;2402:22:8;::::1;2394:73;;;::::0;-1:-1:-1;;;2394:73:8;;29257:2:32;2394:73:8::1;::::0;::::1;29239:21:32::0;29296:2;29276:18;;;29269:30;29335:34;29315:18;;;29308:62;-1:-1:-1;;;29386:18:32;;;29379:36;29432:19;;2394:73:8::1;29055:402:32::0;2394:73:8::1;2477:28;2496:8;2477:18;:28::i;6646:179:0:-:0;-1:-1:-1;;;;;6774:22:0;;6743:12;6774:22;;;:13;:22;;;;;6743:12;6797:11;6774:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:39;6810:2;6774:39;;;;;;;;;;;;6817:1;6774:44;;6767:51;;6646:179;;;;;:::o;1281:255:18:-;1405:4;-1:-1:-1;;;;;;1428:61:18;;-1:-1:-1;;;1428:61:18;;:101;;;1493:36;1517:11;1493:23;:36::i;1599:130:8:-;1513:6;;-1:-1:-1;;;;;1513:6:8;929:10:23;1662:23:8;1654:68;;;;-1:-1:-1;;;1654:68:8;;29664:2:32;1654:68:8;;;29646:21:32;;;29683:18;;;29676:30;29742:34;29722:18;;;29715:62;29794:18;;1654:68:8;29462:356:32;13778:133:15;7657:4;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:15;13851:53;;;;-1:-1:-1;;;13851:53:15;;20141:2:32;13851:53:15;;;20123:21:32;20180:2;20160:18;;;20153:30;-1:-1:-1;;;20199:18:32;;;20192:54;20263:18;;13851:53:15;19939:348:32;9134:865:0;9381:4;9421:2;9401:22;;9397:55;;9432:20;;-1:-1:-1;;;9432:20:0;;;;;;;;;;;9397:55;9462:15;9480:454;9531:7;:16;;;9565:7;:19;;;9602:7;:14;;;9634:7;:15;;;9667:7;:17;;;9702:7;:17;;;9737:13;9768:8;9794;9820:3;;9841:13;9880:4;9503:396;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;9480:429;;;;;;7411:34:26;7211:15;7398:48;;;7466:4;7459:18;;;;7517:4;7501:21;;;7142:396;9480:454:0;9981:11;;9951:26;;;;;;;;;;;;;;;;;;;;;;9462:472;;-1:-1:-1;;;;;;9981:11:0;;;;9951:26;;9967:9;;;;;;9951:26;;9967:9;;;;9951:26;;;;;;;;;-1:-1:-1;9951:7:0;;:26;-1:-1:-1;;9951:15:0;:26;-1:-1:-1;9951:26:0:i;:::-;-1:-1:-1;;;;;9951:41:0;;;9134:865;-1:-1:-1;;;;;;;;;;9134:865:0:o;8987:66::-;1334:13:8;:11;:13::i;2820:944:11:-;971:66;3236:59;;;3232:526;;;3311:37;3330:17;3311:18;:37::i;:::-;2820:944;;;:::o;3232:526::-;3412:17;-1:-1:-1;;;;;3383:61:11;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3383:63:11;;;;;;;;-1:-1:-1;;3383:63:11;;;;;;;;;;;;:::i;:::-;;;3379:302;;3610:56;;-1:-1:-1;;;3610:56:11;;31617:2:32;3610:56:11;;;31599:21:32;31656:2;31636:18;;;31629:30;31695:34;31675:18;;;31668:62;-1:-1:-1;;;31746:18:32;;;31739:44;31800:19;;3610:56:11;31415:410:32;3379:302:11;-1:-1:-1;;;;;;;;;;;3496:28:11;;3488:82;;;;-1:-1:-1;;;3488:82:11;;32032:2:32;3488:82:11;;;32014:21:32;32071:2;32051:18;;;32044:30;32110:34;32090:18;;;32083:62;-1:-1:-1;;;32161:18:32;;;32154:39;32210:19;;3488:82:11;31830:405:32;3488:82:11;3447:138;3694:53;3712:17;3731:4;3737:9;3694:17;:53::i;2666:187:8:-;2758:6;;;-1:-1:-1;;;;;2774:17:8;;;-1:-1:-1;;;;;;2774:17:8;;;;;;;2806:40;;2758:6;;;2774:17;2758:6;;2806:40;;2739:16;;2806:40;2729:124;2666:187;:::o;1003:95::-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1065:26:8::1;:24;:26::i;1042:67:14:-:0;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;1523:183:6:-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1635:29:6::1;1649:5;1656:7;1635:13;:29::i;:::-;1674:25;:23;:25::i;750:122:7:-:0;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;845:8:7::1;:20:::0;;-1:-1:-1;;;;;;845:20:7::1;-1:-1:-1::0;;;;;845:20:7;;;::::1;::::0;;;::::1;::::0;;750:122::o;480:707:25:-;536:13;585:14;602:28;624:5;602:21;:28::i;:::-;633:1;602:32;585:49;;648:20;682:6;-1:-1:-1;;;;;671:18:25;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;671:18:25;-1:-1:-1;648:41:25;-1:-1:-1;809:28:25;;;825:2;809:28;864:280;-1:-1:-1;;895:5:25;-1:-1:-1;;;1029:2:25;1018:14;;1013:30;895:5;1000:44;1088:2;1079:11;;;-1:-1:-1;1108:21:25;864:280;1108:21;-1:-1:-1;1164:6:25;480:707;-1:-1:-1;;;480:707:25:o;516:3026:22:-;574:13;806:4;:11;821:1;806:16;802:31;;-1:-1:-1;;824:9:22;;;;;;;;;-1:-1:-1;824:9:22;;;516:3026::o;802:31::-;883:19;905:6;;;;;;;;;;;;;;;;;883:28;;1314:20;1373:1;1354:4;:11;1368:1;1354:15;;;;:::i;:::-;1353:21;;;;:::i;:::-;1348:27;;:1;:27;:::i;:::-;-1:-1:-1;;;;;1337:39:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1337:39:22;;1314:62;;1551:1;1544:5;1540:13;1652:2;1644:6;1640:15;1759:4;1810;1804:11;1798:4;1794:22;1722:1403;1843:6;1834:7;1831:19;1722:1403;;;1945:1;1936:7;1932:15;1921:26;;1983:7;1977:14;2626:4;2618:5;2614:2;2610:14;2606:25;2596:8;2592:40;2586:47;2575:9;2567:67;2679:1;2668:9;2664:17;2651:30;;2769:4;2761:5;2757:2;2753:14;2749:25;2739:8;2735:40;2729:47;2718:9;2710:67;2822:1;2811:9;2807:17;2794:30;;2911:4;2903:5;2900:1;2896:13;2892:24;2882:8;2878:39;2872:46;2861:9;2853:66;2964:1;2953:9;2949:17;2936:30;;3045:4;3038:5;3034:16;3024:8;3020:31;3014:38;3003:9;2995:58;;3098:1;3087:9;3083:17;3070:30;;1722:1403;;;1726:104;;3283:1;3276:4;3270:11;3266:19;3303:1;3298:120;;;;3436:1;3431:71;;;;3259:243;;3298:120;3350:4;3346:1;3335:9;3331:17;3323:32;3399:4;3395:1;3384:9;3380:17;3372:32;3298:120;;3431:71;3483:4;3479:1;3468:9;3464:17;3456:32;3259:243;-1:-1:-1;3529:6:22;;516:3026;-1:-1:-1;;;;;516:3026:22:o;806:260:5:-;947:12;965:9;-1:-1:-1;;;;;965:14:5;988:6;965:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;946:54;;;1015:7;1010:49;;1031:28;;-1:-1:-1;;;1031:28:5;;-1:-1:-1;;;;;3871:32:32;;1031:28:5;;;3853:51:32;3826:18;;1031:28:5;3707:203:32;8478:108:15;8553:26;8563:2;8567:7;8553:26;;;;;;;;;;;;:9;:26::i;10654:784::-;10713:13;10729:34;10755:7;10729:25;:34::i;:::-;10713:50;;10774:51;10795:5;10810:1;10814:7;10823:1;10774:20;:51::i;:::-;10935:34;10961:7;10935:25;:34::i;:::-;11014:24;;;;:15;:24;;;;;;;;11007:31;;-1:-1:-1;;;;;;11007:31:15;;;;;;-1:-1:-1;;;;;11254:16:15;;;;;:9;:16;;;;;:21;;-1:-1:-1;;11254:21:15;;;11302:16;;;:7;:16;;;;;;11295:23;;;;;;;11334:36;10927:42;;-1:-1:-1;11030:7:15;;11334:36;;11014:24;;11334:36;3901:220:14;;:::o;1987:344:15:-;2111:4;-1:-1:-1;;;;;;2146:51:15;;-1:-1:-1;;;2146:51:15;;:126;;-1:-1:-1;;;;;;;2213:59:15;;-1:-1:-1;;;2213:59:15;2146:126;:178;;;-1:-1:-1;;;;;;;;;;1168:51:27;;;2288:36:15;1060:166:27;3683:227:26;3761:7;3781:17;3800:18;3822:27;3833:4;3839:9;3822:10;:27::i;:::-;3780:69;;;;3859:18;3871:5;3859:11;:18::i;:::-;-1:-1:-1;3894:9:26;3683:227;-1:-1:-1;;;3683:227:26:o;1699:281:11:-;-1:-1:-1;;;;;1713:19:21;;;1772:106:11;;;;-1:-1:-1;;;1772:106:11;;33591:2:32;1772:106:11;;;33573:21:32;33630:2;33610:18;;;33603:30;33669:34;33649:18;;;33642:62;-1:-1:-1;;;33720:18:32;;;33713:43;33773:19;;1772:106:11;33389:409:32;1772:106:11;-1:-1:-1;;;;;;;;;;;1888:85:11;;-1:-1:-1;;;;;;1888:85:11;-1:-1:-1;;;;;1888:85:11;;;;;;;;;;1699:281::o;2372:276::-;2480:29;2491:17;2480:10;:29::i;:::-;2537:1;2523:4;:11;:15;:28;;;;2542:9;2523:28;2519:123;;;2567:64;2607:17;2626:4;2567:39;:64::i;1104:111:8:-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1176:32:8::1;929:10:23::0;1176:18:8::1;:32::i;1605:149:15:-:0;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1708:39:15::1;1732:5;1739:7;1708:23;:39::i;10150:916:29:-:0;10203:7;;-1:-1:-1;;;10278:17:29;;10274:103;;-1:-1:-1;;;10315:17:29;;;-1:-1:-1;10360:2:29;10350:12;10274:103;10403:8;10394:5;:17;10390:103;;10440:8;10431:17;;;-1:-1:-1;10476:2:29;10466:12;10390:103;10519:8;10510:5;:17;10506:103;;10556:8;10547:17;;;-1:-1:-1;10592:2:29;10582:12;10506:103;10635:7;10626:5;:16;10622:100;;10671:7;10662:16;;;-1:-1:-1;10706:1:29;10696:11;10622:100;10748:7;10739:5;:16;10735:100;;10784:7;10775:16;;;-1:-1:-1;10819:1:29;10809:11;10735:100;10861:7;10852:5;:16;10848:100;;10897:7;10888:16;;;-1:-1:-1;10932:1:29;10922:11;10848:100;10974:7;10965:5;:16;10961:66;;11011:1;11001:11;11053:6;10150:916;-1:-1:-1;;10150:916:29:o;8807:279:15:-;8901:18;8907:2;8911:7;8901:5;:18::i;:::-;8950:53;8981:1;8985:2;8989:7;8998:4;8950:22;:53::i;:::-;8929:150;;;;-1:-1:-1;;;8929:150:15;;;;;;;:::i;3694:287:6:-;3913:61;3940:4;3946:2;3950:12;3964:9;3913:26;:61::i;2167:730:26:-;2248:7;2257:12;2285:9;:16;2305:2;2285:22;2281:610;;2621:4;2606:20;;2600:27;2670:4;2655:20;;2649:27;2727:4;2712:20;;2706:27;2323:9;2698:36;2768:25;2779:4;2698:36;2600:27;2649;2768:10;:25::i;:::-;2761:32;;;;;;;;;2281:610;-1:-1:-1;2840:1:26;;-1:-1:-1;2844:35:26;2281:610;2167:730;;;;;:::o;592:511::-;669:20;660:5;:29;;;;;;;;:::i;:::-;;656:441;;592:511;:::o;656:441::-;765:29;756:5;:38;;;;;;;;:::i;:::-;;752:345;;810:34;;-1:-1:-1;;;810:34:26;;34424:2:32;810:34:26;;;34406:21:32;34463:2;34443:18;;;34436:30;34502:26;34482:18;;;34475:54;34546:18;;810:34:26;34222:348:32;752:345:26;874:35;865:5;:44;;;;;;;;:::i;:::-;;861:236;;925:41;;-1:-1:-1;;;925:41:26;;34777:2:32;925:41:26;;;34759:21:32;34816:2;34796:18;;;34789:30;34855:33;34835:18;;;34828:61;34906:18;;925:41:26;34575:355:32;861:236:26;996:30;987:5;:39;;;;;;;;:::i;:::-;;983:114;;1042:44;;-1:-1:-1;;;1042:44:26;;35137:2:32;1042:44:26;;;35119:21:32;35176:2;35156:18;;;35149:30;35215:34;35195:18;;;35188:62;-1:-1:-1;;;35266:18:32;;;35259:32;35308:19;;1042:44:26;34935:398:32;2086:152:11;2152:37;2171:17;2152:18;:37::i;:::-;2204:27;;-1:-1:-1;;;;;2204:27:11;;;;;;;;2086:152;:::o;6685:198:21:-;6768:12;6799:77;6820:6;6828:4;6799:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6792:84;6685:198;-1:-1:-1;;;6685:198:21:o;1760:160:15:-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1873:5:15::1;:13;1881:5:::0;1873;:13:::1;:::i;:::-;-1:-1:-1::0;1896:7:15::1;:17;1906:7:::0;1896;:17:::1;:::i;9408:920::-:0;-1:-1:-1;;;;;9487:16:15;;9479:61;;;;-1:-1:-1;;;9479:61:15;;35540:2:32;9479:61:15;;;35522:21:32;;;35559:18;;;35552:30;35618:34;35598:18;;;35591:62;35670:18;;9479:61:15;35338:356:32;9479:61:15;7657:4;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:15;7680:31;9550:58;;;;-1:-1:-1;;;9550:58:15;;35901:2:32;9550:58:15;;;35883:21:32;35940:2;35920:18;;;35913:30;35979;35959:18;;;35952:58;36027:18;;9550:58:15;35699:352:32;9550:58:15;9619:48;9648:1;9652:2;9656:7;9665:1;9619:20;:48::i;:::-;7657:4;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:15;7680:31;9754:58;;;;-1:-1:-1;;;9754:58:15;;35901:2:32;9754:58:15;;;35883:21:32;35940:2;35920:18;;;35913:30;35979;35959:18;;;35952:58;36027:18;;9754:58:15;35699:352:32;9754:58:15;-1:-1:-1;;;;;10154:13:15;;;;;;:9;:13;;;;;;;;:18;;10171:1;10154:18;;;10193:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10193:21:15;;;;;10230:33;10201:7;;10154:13;;10230:33;;10154:13;;10230:33;3901:220:14;;:::o;14463:853:15:-;14612:4;-1:-1:-1;;;;;14632:13:15;;1713:19:21;:23;14628:682:15;;14667:82;;-1:-1:-1;;;14667:82:15;;-1:-1:-1;;;;;14667:47:15;;;;;:82;;929:10:23;;14729:4:15;;14735:7;;14744:4;;14667:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14667:82:15;;;;;;;;-1:-1:-1;;14667:82:15;;;;;;;;;;;;:::i;:::-;;;14663:595;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14927:6;:13;14944:1;14927:18;14923:321;;14969:60;;-1:-1:-1;;;14969:60:15;;;;;;;:::i;14923:321::-;15196:6;15190:13;15181:6;15177:2;15173:15;15166:38;14663:595;-1:-1:-1;;;;;;14799:62:15;-1:-1:-1;;;14799:62:15;;-1:-1:-1;14792:69:15;;14628:682;-1:-1:-1;15295:4:15;14628:682;14463:853;;;;;;:::o;2443:890:18:-;2702:1;2690:9;:13;2686:219;;;2831:63;;-1:-1:-1;;;2831:63:18;;37017:2:32;2831:63:18;;;36999:21:32;37056:2;37036:18;;;37029:30;37095:34;37075:18;;;37068:62;-1:-1:-1;;;37146:18:32;;;37139:51;37207:19;;2831:63:18;36815:417:32;2686:219:18;2933:12;-1:-1:-1;;;;;2960:18:18;;2956:183;;2994:40;3026:7;4153:10;:17;;4126:24;;;;:15;:24;;;;;:44;;;4180:24;;;;;;;;;;;;4050:161;2994:40;2956:183;;;3063:2;-1:-1:-1;;;;;3055:10:18;:4;-1:-1:-1;;;;;3055:10:18;;3051:88;;3081:47;3114:4;3120:7;3081:32;:47::i;:::-;-1:-1:-1;;;;;3152:16:18;;3148:179;;3184:45;3221:7;3184:36;:45::i;:::-;3148:179;;;3256:4;-1:-1:-1;;;;;3250:10:18;:2;-1:-1:-1;;;;;3250:10:18;;3246:81;;3276:40;3304:2;3308:7;3276:27;:40::i;5031:1456:26:-;5119:7;;6043:66;6030:79;;6026:161;;;-1:-1:-1;6141:1:26;;-1:-1:-1;6145:30:26;6125:51;;6026:161;6298:24;;;6281:14;6298:24;;;;;;;;;37464:25:32;;;37537:4;37525:17;;37505:18;;;37498:45;;;;37559:18;;;37552:34;;;37602:18;;;37595:34;;;6298:24:26;;37436:19:32;;6298:24:26;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6298:24:26;;-1:-1:-1;;6298:24:26;;;-1:-1:-1;;;;;;;6336:20:26;;6332:101;;6388:1;6392:29;6372:50;;;;;;;6332:101;6451:6;-1:-1:-1;6459:20:26;;-1:-1:-1;5031:1456:26;;;;;;;;:::o;7069:325:21:-;7210:12;7235;7249:23;7276:6;-1:-1:-1;;;;;7276:19:21;7296:4;7276:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7234:67;;;;7318:69;7345:6;7353:7;7362:10;7374:12;7318:26;:69::i;:::-;7311:76;7069:325;-1:-1:-1;;;;;;7069:325:21:o;4828:981:18:-;5090:22;5151:1;5115:33;5143:4;5115:27;:33::i;:::-;:37;;;;:::i;:::-;5162:18;5183:26;;;:17;:26;;;;;;5090:62;;-1:-1:-1;5313:28:18;;;5309:323;;-1:-1:-1;;;;;5379:18:18;;5357:19;5379:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5428:30;;;;;;:44;;;5544:30;;:17;:30;;;;;:43;;;5309:323;-1:-1:-1;5725:26:18;;;;:17;:26;;;;;;;;5718:33;;;-1:-1:-1;;;;;5768:18:18;;;;;:12;:18;;;;;:34;;;;;;;5761:41;4828:981::o;6097:1061::-;6371:10;:17;6346:22;;6371:21;;6391:1;;6371:21;:::i;:::-;6402:18;6423:24;;;:15;:24;;;;;;6791:10;:26;;6346:46;;-1:-1:-1;6423:24:18;;6346:46;;6791:26;;;;;;:::i;:::-;;;;;;;;;6769:48;;6853:11;6828:10;6839;6828:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6932:28;;;:15;:28;;;;;;;:41;;;7101:24;;;;;7094:31;7135:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6168:990;;;6097:1061;:::o;3627:228::-;3711:14;3728:31;3756:2;3728:27;:31::i;:::-;-1:-1:-1;;;;;3769:16:18;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3813:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3627:228:18:o;7682:628:21:-;7862:12;7890:7;7886:418;;;7917:10;:17;7938:1;7917:22;7913:286;;-1:-1:-1;;;;;1713:19:21;;;8124:60;;;;-1:-1:-1;;;8124:60:21;;38266:2:32;8124:60:21;;;38248:21:32;38305:2;38285:18;;;38278:30;38344:31;38324:18;;;38317:59;38393:18;;8124:60:21;38064:353:32;8124:60:21;-1:-1:-1;8219:10:21;8212:17;;7886:418;8260:33;8268:10;8280:12;8991:17;;:21;8987:379;;9219:10;9213:17;9275:15;9262:10;9258:2;9254:19;9247:44;8987:379;9342:12;9335:20;;-1:-1:-1;;;9335:20:21;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:32:-;-1:-1:-1;;;;;;88:32:32;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:32;816:16;;809:27;592:250::o;847:282::-;900:3;938:5;932:12;965:6;960:3;953:19;981:76;1050:6;1043:4;1038:3;1034:14;1027:4;1020:5;1016:16;981:76;:::i;:::-;1111:2;1090:15;-1:-1:-1;;1086:29:32;1077:39;;;;1118:4;1073:50;;847:282;-1:-1:-1;;847:282:32:o;1134:231::-;1283:2;1272:9;1265:21;1246:4;1303:56;1355:2;1344:9;1340:18;1332:6;1303:56;:::i;1370:152::-;1447:20;;1496:1;1486:12;;1476:40;;1512:1;1509;1502:12;1476:40;1370:152;;;:::o;1527:127::-;1588:10;1583:3;1579:20;1576:1;1569:31;1619:4;1616:1;1609:15;1643:4;1640:1;1633:15;1659:719;1702:5;1755:3;1748:4;1740:6;1736:17;1732:27;1722:55;;1773:1;1770;1763:12;1722:55;1809:6;1796:20;-1:-1:-1;;;;;1872:2:32;1868;1865:10;1862:36;;;1878:18;;:::i;:::-;1953:2;1947:9;1921:2;2007:13;;-1:-1:-1;;2003:22:32;;;2027:2;1999:31;1995:40;1983:53;;;2051:18;;;2071:22;;;2048:46;2045:72;;;2097:18;;:::i;:::-;2137:10;2133:2;2126:22;2172:2;2164:6;2157:18;2218:3;2211:4;2206:2;2198:6;2194:15;2190:26;2187:35;2184:55;;;2235:1;2232;2225:12;2184:55;2299:2;2292:4;2284:6;2280:17;2273:4;2265:6;2261:17;2248:54;2346:1;2339:4;2334:2;2326:6;2322:15;2318:26;2311:37;2366:6;2357:15;;;;;;1659:719;;;;:::o;2383:1025::-;2493:6;2501;2554:2;2542:9;2533:7;2529:23;2525:32;2522:52;;;2570:1;2567;2560:12;2522:52;2593:38;2621:9;2593:38;:::i;:::-;2583:48;;2682:2;2671:9;2667:18;2654:32;-1:-1:-1;;;;;2746:2:32;2738:6;2735:14;2732:34;;;2762:1;2759;2752:12;2732:34;2785:22;;;;2841:2;2823:16;;;2819:25;2816:45;;;2857:1;2854;2847:12;2816:45;2890:2;2884:9;2932:2;2924:6;2920:15;2985:6;2973:10;2970:22;2965:2;2953:10;2950:18;2947:46;2944:72;;;2996:18;;:::i;:::-;3032:2;3025:22;3072:16;;3100;;;3097:36;;;3129:1;3126;3119:12;3097:36;3157:45;3194:7;3183:8;3179:2;3175:17;3157:45;:::i;:::-;3149:6;3142:61;;3249:2;3245;3241:11;3228:25;3278:2;3268:8;3265:16;3262:36;;;3294:1;3291;3284:12;3262:36;3331:45;3368:7;3357:8;3353:2;3349:17;3331:45;:::i;:::-;3326:2;3318:6;3314:15;3307:70;;3396:6;3386:16;;;;;2383:1025;;;;;:::o;3413:180::-;3472:6;3525:2;3513:9;3504:7;3500:23;3496:32;3493:52;;;3541:1;3538;3531:12;3493:52;-1:-1:-1;3564:23:32;;3413:180;-1:-1:-1;3413:180:32:o;3915:131::-;-1:-1:-1;;;;;3990:31:32;;3980:42;;3970:70;;4036:1;4033;4026:12;4051:315;4119:6;4127;4180:2;4168:9;4159:7;4155:23;4151:32;4148:52;;;4196:1;4193;4186:12;4148:52;4235:9;4222:23;4254:31;4279:5;4254:31;:::i;:::-;4304:5;4356:2;4341:18;;;;4328:32;;-1:-1:-1;;;4051:315:32:o;4371:967::-;4431:5;4479:4;4467:9;4462:3;4458:19;4454:30;4451:50;;;4497:1;4494;4487:12;4451:50;4530:2;4524:9;4572:4;4564:6;4560:17;-1:-1:-1;;;;;4664:6:32;4652:10;4649:22;4644:2;4632:10;4629:18;4626:46;4623:72;;;4675:18;;:::i;:::-;4715:10;4711:2;4704:22;4744:6;4735:15;;4787:9;4774:23;4759:38;;4806:33;4831:7;4806:33;:::i;:::-;4863:7;4855:6;4848:23;4904:47;4947:2;4936:9;4932:18;4904:47;:::i;:::-;4899:2;4891:6;4887:15;4880:72;5013:2;5002:9;4998:18;4985:32;4980:2;4972:6;4968:15;4961:57;5079:2;5068:9;5064:18;5051:32;5046:2;5038:6;5034:15;5027:57;5135:3;5124:9;5120:19;5107:33;5093:47;;5163:2;5155:6;5152:14;5149:34;;;5179:1;5176;5169:12;5149:34;;5217:46;5259:3;5250:6;5239:9;5235:22;5217:46;:::i;:::-;5211:3;5203:6;5199:16;5192:72;;5326:3;5315:9;5311:19;5298:33;5292:3;5284:6;5280:16;5273:59;;4371:967;;;;:::o;5343:348::-;5395:8;5405:6;5459:3;5452:4;5444:6;5440:17;5436:27;5426:55;;5477:1;5474;5467:12;5426:55;-1:-1:-1;5500:20:32;;-1:-1:-1;;;;;5532:30:32;;5529:50;;;5575:1;5572;5565:12;5529:50;5612:4;5604:6;5600:17;5588:29;;5664:3;5657:4;5648:6;5640;5636:19;5632:30;5629:39;5626:59;;;5681:1;5678;5671:12;5696:1023;5835:6;5843;5851;5859;5867;5875;5928:3;5916:9;5907:7;5903:23;5899:33;5896:53;;;5945:1;5942;5935:12;5896:53;5985:9;5972:23;-1:-1:-1;;;;;6055:2:32;6047:6;6044:14;6041:34;;;6071:1;6068;6061:12;6041:34;6094:64;6150:7;6141:6;6130:9;6126:22;6094:64;:::i;:::-;6084:74;;6205:2;6194:9;6190:18;6177:32;6167:42;;6262:2;6251:9;6247:18;6234:32;6218:48;;6291:2;6281:8;6278:16;6275:36;;;6307:1;6304;6297:12;6275:36;6346:61;6399:7;6388:8;6377:9;6373:24;6346:61;:::i;:::-;6426:8;;-1:-1:-1;6320:87:32;-1:-1:-1;6514:2:32;6499:18;;6486:32;;-1:-1:-1;6530:16:32;;;6527:36;;;6559:1;6556;6549:12;6527:36;;6598:61;6651:7;6640:8;6629:9;6625:24;6598:61;:::i;:::-;5696:1023;;;;-1:-1:-1;5696:1023:32;;-1:-1:-1;5696:1023:32;;6678:8;;5696:1023;-1:-1:-1;;;5696:1023:32:o;6724:247::-;6783:6;6836:2;6824:9;6815:7;6811:23;6807:32;6804:52;;;6852:1;6849;6842:12;6804:52;6891:9;6878:23;6910:31;6935:5;6910:31;:::i;7158:456::-;7235:6;7243;7251;7304:2;7292:9;7283:7;7279:23;7275:32;7272:52;;;7320:1;7317;7310:12;7272:52;7359:9;7346:23;7378:31;7403:5;7378:31;:::i;:::-;7428:5;-1:-1:-1;7485:2:32;7470:18;;7457:32;7498:33;7457:32;7498:33;:::i;:::-;7158:456;;7550:7;;-1:-1:-1;;;7604:2:32;7589:18;;;;7576:32;;7158:456::o;7619:::-;7696:6;7704;7757:2;7745:9;7736:7;7732:23;7728:32;7725:52;;;7773:1;7770;7763:12;7725:52;7812:9;7799:23;7831:31;7856:5;7831:31;:::i;:::-;7881:5;-1:-1:-1;7937:2:32;7922:18;;7909:32;-1:-1:-1;;;;;7953:30:32;;7950:50;;;7996:1;7993;7986:12;7950:50;8019;8061:7;8052:6;8041:9;8037:22;8019:50;:::i;:::-;8009:60;;;7619:456;;;;;:::o;8486:346::-;8578:6;8586;8594;8647:2;8635:9;8626:7;8622:23;8618:32;8615:52;;;8663:1;8660;8653:12;8615:52;8699:9;8686:23;8676:33;;8728:47;8771:2;8760:9;8756:18;8728:47;:::i;:::-;8718:57;;8822:2;8811:9;8807:18;8794:32;8784:42;;8486:346;;;;;:::o;8837:828::-;8951:6;8959;8967;8975;9028:3;9016:9;9007:7;9003:23;8999:33;8996:53;;;9045:1;9042;9035:12;8996:53;9085:9;9072:23;-1:-1:-1;;;;;9155:2:32;9147:6;9144:14;9141:34;;;9171:1;9168;9161:12;9141:34;9194:50;9236:7;9227:6;9216:9;9212:22;9194:50;:::i;:::-;9184:60;;9297:2;9286:9;9282:18;9269:32;9253:48;;9326:2;9316:8;9313:16;9310:36;;;9342:1;9339;9332:12;9310:36;;9365:52;9409:7;9398:8;9387:9;9383:24;9365:52;:::i;:::-;9355:62;;;9467:2;9456:9;9452:18;9439:32;9480:31;9505:5;9480:31;:::i;:::-;9530:5;-1:-1:-1;9587:2:32;9572:18;;9559:32;9600:33;9559:32;9600:33;:::i;:::-;8837:828;;;;-1:-1:-1;8837:828:32;;-1:-1:-1;;8837:828:32:o;9670:416::-;9735:6;9743;9796:2;9784:9;9775:7;9771:23;9767:32;9764:52;;;9812:1;9809;9802:12;9764:52;9851:9;9838:23;9870:31;9895:5;9870:31;:::i;:::-;9920:5;-1:-1:-1;9977:2:32;9962:18;;9949:32;10019:15;;10012:23;10000:36;;9990:64;;10050:1;10047;10040:12;9990:64;10073:7;10063:17;;;9670:416;;;;;:::o;10091:666::-;10186:6;10194;10202;10210;10263:3;10251:9;10242:7;10238:23;10234:33;10231:53;;;10280:1;10277;10270:12;10231:53;10319:9;10306:23;10338:31;10363:5;10338:31;:::i;:::-;10388:5;-1:-1:-1;10445:2:32;10430:18;;10417:32;10458:33;10417:32;10458:33;:::i;:::-;10510:7;-1:-1:-1;10564:2:32;10549:18;;10536:32;;-1:-1:-1;10619:2:32;10604:18;;10591:32;-1:-1:-1;;;;;10635:30:32;;10632:50;;;10678:1;10675;10668:12;10632:50;10701;10743:7;10734:6;10723:9;10719:22;10701:50;:::i;:::-;10691:60;;;10091:666;;;;;;;:::o;10762:1236::-;10927:6;10935;10943;10951;10959;10967;10975;10983;11036:3;11024:9;11015:7;11011:23;11007:33;11004:53;;;11053:1;11050;11043:12;11004:53;11093:9;11080:23;-1:-1:-1;;;;;11163:2:32;11155:6;11152:14;11149:34;;;11179:1;11176;11169:12;11149:34;11202:64;11258:7;11249:6;11238:9;11234:22;11202:64;:::i;:::-;11192:74;;11316:2;11305:9;11301:18;11288:32;11275:45;;11329:31;11354:5;11329:31;:::i;:::-;11379:5;;-1:-1:-1;11431:2:32;11416:18;;11403:32;;-1:-1:-1;11482:2:32;11467:18;;11454:32;;-1:-1:-1;11539:3:32;11524:19;;11511:33;;11556:16;;;11553:36;;;11585:1;11582;11575:12;11553:36;11624:61;11677:7;11666:8;11655:9;11651:24;11624:61;:::i;:::-;11704:8;;-1:-1:-1;11598:87:32;-1:-1:-1;11792:3:32;11777:19;;11764:33;;-1:-1:-1;11809:16:32;;;11806:36;;;11838:1;11835;11828:12;11806:36;;11877:61;11930:7;11919:8;11908:9;11904:24;11877:61;:::i;:::-;10762:1236;;;;-1:-1:-1;10762:1236:32;;-1:-1:-1;10762:1236:32;;;;;;11957:8;-1:-1:-1;;;10762:1236:32:o;12003:388::-;12071:6;12079;12132:2;12120:9;12111:7;12107:23;12103:32;12100:52;;;12148:1;12145;12138:12;12100:52;12187:9;12174:23;12206:31;12231:5;12206:31;:::i;:::-;12256:5;-1:-1:-1;12313:2:32;12298:18;;12285:32;12326:33;12285:32;12326:33;:::i;12656:413::-;12748:6;12756;12764;12817:2;12805:9;12796:7;12792:23;12788:32;12785:52;;;12833:1;12830;12823:12;12785:52;12872:9;12859:23;12891:31;12916:5;12891:31;:::i;:::-;12941:5;-1:-1:-1;12965:47:32;13008:2;12993:18;;12965:47;:::i;13074:380::-;13153:1;13149:12;;;;13196;;;13217:61;;13271:4;13263:6;13259:17;13249:27;;13217:61;13324:2;13316:6;13313:14;13293:18;13290:38;13287:161;;13370:10;13365:3;13361:20;13358:1;13351:31;13405:4;13402:1;13395:15;13433:4;13430:1;13423:15;13287:161;;13074:380;;;:::o;13459:127::-;13520:10;13515:3;13511:20;13508:1;13501:31;13551:4;13548:1;13541:15;13575:4;13572:1;13565:15;13717:545;13819:2;13814:3;13811:11;13808:448;;;13855:1;13880:5;13876:2;13869:17;13925:4;13921:2;13911:19;13995:2;13983:10;13979:19;13976:1;13972:27;13966:4;13962:38;14031:4;14019:10;14016:20;14013:47;;;-1:-1:-1;14054:4:32;14013:47;14109:2;14104:3;14100:12;14097:1;14093:20;14087:4;14083:31;14073:41;;14164:82;14182:2;14175:5;14172:13;14164:82;;;14227:17;;;14208:1;14197:13;14164:82;;;14168:3;;;13717:545;;;:::o;14438:1352::-;14564:3;14558:10;-1:-1:-1;;;;;14583:6:32;14580:30;14577:56;;;14613:18;;:::i;:::-;14642:97;14732:6;14692:38;14724:4;14718:11;14692:38;:::i;:::-;14686:4;14642:97;:::i;:::-;14794:4;;14858:2;14847:14;;14875:1;14870:663;;;;15577:1;15594:6;15591:89;;;-1:-1:-1;15646:19:32;;;15640:26;15591:89;-1:-1:-1;;14395:1:32;14391:11;;;14387:24;14383:29;14373:40;14419:1;14415:11;;;14370:57;15693:81;;14840:944;;14870:663;13664:1;13657:14;;;13701:4;13688:18;;-1:-1:-1;;14906:20:32;;;15024:236;15038:7;15035:1;15032:14;15024:236;;;15127:19;;;15121:26;15106:42;;15219:27;;;;15187:1;15175:14;;;;15054:19;;15024:236;;;15028:3;15288:6;15279:7;15276:19;15273:201;;;15349:19;;;15343:26;-1:-1:-1;;15432:1:32;15428:14;;;15444:3;15424:24;15420:37;15416:42;15401:58;15386:74;;15273:201;-1:-1:-1;;;;;15520:1:32;15504:14;;;15500:22;15487:36;;-1:-1:-1;14438:1352:32:o;15795:239::-;15878:1;15871:5;15868:12;15858:143;;15923:10;15918:3;15914:20;15911:1;15904:31;15958:4;15955:1;15948:15;15986:4;15983:1;15976:15;15858:143;16010:18;;15795:239::o;16039:211::-;16186:2;16171:18;;16198:46;16175:9;16226:6;16198:46;:::i;16255:127::-;16316:10;16311:3;16307:20;16304:1;16297:31;16347:4;16344:1;16337:15;16371:4;16368:1;16361:15;16387:128;16454:9;;;16475:11;;;16472:37;;;16489:18;;:::i;16520:1206::-;-1:-1:-1;;;;;16639:3:32;16636:27;16633:53;;;16666:18;;:::i;:::-;16695:94;16785:3;16745:38;16777:4;16771:11;16745:38;:::i;:::-;16739:4;16695:94;:::i;:::-;16815:1;16840:2;16835:3;16832:11;16857:1;16852:616;;;;17512:1;17529:3;17526:93;;;-1:-1:-1;17585:19:32;;;17572:33;17526:93;-1:-1:-1;;14395:1:32;14391:11;;;14387:24;14383:29;14373:40;14419:1;14415:11;;;14370:57;17632:78;;16825:895;;16852:616;13664:1;13657:14;;;13701:4;13688:18;;-1:-1:-1;;16888:17:32;;;16989:9;17011:229;17025:7;17022:1;17019:14;17011:229;;;17114:19;;;17101:33;17086:49;;17221:4;17206:20;;;;17174:1;17162:14;;;;17041:12;17011:229;;;17015:3;17268;17259:7;17256:16;17253:159;;;17392:1;17388:6;17382:3;17376;17373:1;17369:11;17365:21;17361:34;17357:39;17344:9;17339:3;17335:19;17322:33;17318:79;17310:6;17303:95;17253:159;;;17455:1;17449:3;17446:1;17442:11;17438:19;17432:4;17425:33;16825:895;;16520:1206;;;:::o;18143:408::-;18345:2;18327:21;;;18384:2;18364:18;;;18357:30;18423:34;18418:2;18403:18;;18396:62;-1:-1:-1;;;18489:2:32;18474:18;;18467:42;18541:3;18526:19;;18143:408::o;18556:::-;18758:2;18740:21;;;18797:2;18777:18;;;18770:30;18836:34;18831:2;18816:18;;18809:62;-1:-1:-1;;;18902:2:32;18887:18;;18880:42;18954:3;18939:19;;18556:408::o;19382:127::-;19443:10;19438:3;19434:20;19431:1;19424:31;19474:4;19471:1;19464:15;19498:4;19495:1;19488:15;21430:722;21480:3;21521:5;21515:12;21550:36;21576:9;21550:36;:::i;:::-;21605:1;21622:18;;;21649:133;;;;21796:1;21791:355;;;;21615:531;;21649:133;-1:-1:-1;;21682:24:32;;21670:37;;21755:14;;21748:22;21736:35;;21727:45;;;-1:-1:-1;21649:133:32;;21791:355;21822:5;21819:1;21812:16;21851:4;21896:2;21893:1;21883:16;21921:1;21935:165;21949:6;21946:1;21943:13;21935:165;;;22027:14;;22014:11;;;22007:35;22070:16;;;;21964:10;;21935:165;;;21939:3;;;22129:6;22124:3;22120:16;22113:23;;21615:531;;;;;21430:722;;;;:::o;22230:198::-;22272:3;22310:5;22304:12;22325:65;22383:6;22378:3;22371:4;22364:5;22360:16;22325:65;:::i;:::-;22406:16;;;;;22230:198;-1:-1:-1;;22230:198:32:o;24600:3395::-;-1:-1:-1;;;21374:45:32;;26703:3;26777:47;26820:2;26815:3;26811:12;26803:6;26777:47;:::i;:::-;-1:-1:-1;;;22207:16:32;;26891:40;26928:1;26921:5;26917:13;26909:6;26891:40;:::i;:::-;-1:-1:-1;;;22491:63:32;;26878:53;-1:-1:-1;26998:49:32;27043:2;27036:5;27032:14;27024:6;26998:49;:::i;:::-;-1:-1:-1;;;22207:16:32;;26985:62;-1:-1:-1;27114:106:32;27148:71;27178:40;27215:1;27208:5;27204:13;27196:6;27178:40;:::i;:::-;22642:66;22630:79;;-1:-1:-1;;;22734:2:32;22725:12;;22718:26;22769:2;22760:12;;22565:213;27148:71;27140:6;27114:106;:::i;:::-;-1:-1:-1;;;22841:61:32;;27101:119;-1:-1:-1;22983:66:32;27315:2;27304:14;;22971:79;-1:-1:-1;;;27369:2:32;27358:14;;23119:47;27395:49;27440:2;27433:5;27429:14;27421:6;27395:49;:::i;:::-;23247:66;23235:79;;27382:62;-1:-1:-1;;;;27539:2:32;27528:14;;23119:47;27565:99;27591:72;27621:41;27658:2;27651:5;27647:14;27639:6;27621:41;:::i;:::-;23402:66;23390:79;;-1:-1:-1;;;23494:2:32;23485:12;;23478:52;23555:2;23546:12;;23325:239;27591:72;27583:6;27565:99;:::i;:::-;23639:66;23627:79;;27552:112;-1:-1:-1;23794:66:32;27906:2;27895:14;;23782:79;-1:-1:-1;;;23877:12:32;;;23870:26;27731:184;27758:156;27783:130;27809:103;27839:72;23912:12;;;27857:6;27839:72;:::i;:::-;24012:66;24000:79;;24109:66;24104:2;24095:12;;24088:88;-1:-1:-1;;;24201:2:32;24192:12;;24185:37;24247:2;24238:12;;23935:321;27783:130;24333:66;24321:79;;-1:-1:-1;;;24425:2:32;24416:12;;24409:46;24480:2;24471:12;;24261:228;27758:156;27749:7;27731:184;:::i;:::-;-1:-1:-1;;;24552:37:32;;27987:1;27976:13;;;-1:-1:-1;;;;;;;;;;;;;;24600:3395:32:o;28000:451::-;28252:31;28247:3;28240:44;28222:3;28313:6;28307:13;28329:75;28397:6;28392:2;28387:3;28383:12;28376:4;28368:6;28364:17;28329:75;:::i;:::-;28424:16;;;;28442:2;28420:25;;28000:451;-1:-1:-1;;28000:451:32:o;28456:125::-;28521:9;;;28542:10;;;28539:36;;;28555:18;;:::i;29823:1398::-;-1:-1:-1;;;;;30342:32:32;;30324:51;;30384:55;30435:2;30420:18;;30412:6;30384:55;:::i;:::-;30475:6;30470:2;30459:9;30455:18;30448:34;30518:6;30513:2;30502:9;30498:18;30491:34;30562:3;30556;30545:9;30541:19;30534:32;30305:4;30589:57;30641:3;30630:9;30626:19;30618:6;30589:57;:::i;:::-;30677:3;30662:19;;30655:35;;;-1:-1:-1;;;;;30727:32:32;;30721:3;30706:19;;30699:61;30791:3;30776:19;;30769:35;;;30835:3;30820:19;;30813:35;;;30885:22;;;30879:3;30864:19;;30857:51;30917:23;;;30932:7;30979:6;30974:2;30962:15;;30949:46;31042:1;31037:2;31027:7;31019:6;31015:20;31011:29;31004:40;31110:2;31103;31099:7;31094:2;31085:7;31081:16;31077:30;31069:6;31065:43;31061:52;31053:60;;;31150:7;31144:3;31133:9;31129:19;31122:36;31167:48;31210:3;31199:9;31195:19;31186:7;-1:-1:-1;;;;;3664:31:32;3652:44;;3598:104;31167:48;29823:1398;;;;;;;;;;;;;;;;:::o;31226:184::-;31296:6;31349:2;31337:9;31328:7;31324:23;31320:32;31317:52;;;31365:1;31362;31355:12;31317:52;-1:-1:-1;31388:16:32;;31226:184;-1:-1:-1;31226:184:32:o;32240:407::-;32442:2;32424:21;;;32481:2;32461:18;;;32454:30;32520:34;32515:2;32500:18;;32493:62;-1:-1:-1;;;32586:2:32;32571:18;;32564:41;32637:3;32622:19;;32240:407::o;32784:217::-;32824:1;32850;32840:132;;32894:10;32889:3;32885:20;32882:1;32875:31;32929:4;32926:1;32919:15;32957:4;32954:1;32947:15;32840:132;-1:-1:-1;32986:9:32;;32784:217::o;33006:168::-;33079:9;;;33110;;33127:15;;;33121:22;;33107:37;33097:71;;33148:18;;:::i;33803:414::-;34005:2;33987:21;;;34044:2;34024:18;;;34017:30;34083:34;34078:2;34063:18;;34056:62;-1:-1:-1;;;34149:2:32;34134:18;;34127:48;34207:3;34192:19;;33803:414::o;36056:500::-;-1:-1:-1;;;;;36325:15:32;;;36307:34;;36377:15;;36372:2;36357:18;;36350:43;36424:2;36409:18;;36402:34;;;36472:3;36467:2;36452:18;;36445:31;;;36250:4;;36493:57;;36530:19;;36522:6;36493:57;:::i;36561:249::-;36630:6;36683:2;36671:9;36662:7;36658:23;36654:32;36651:52;;;36699:1;36696;36689:12;36651:52;36731:9;36725:16;36750:30;36774:5;36750:30;:::i;37640:287::-;37769:3;37807:6;37801:13;37823:66;37882:6;37877:3;37870:4;37862:6;37858:17;37823:66;:::i;:::-;37905:16;;;;;37640:287;-1:-1:-1;;37640:287:32:o;37932:127::-;37993:10;37988:3;37984:20;37981:1;37974:31;38024:4;38021:1;38014:15;38048:4;38045:1;38038:15
Swarm Source
ipfs://a2945a2b31cee972719ab26eb163febe33e8e88b7d558cb243f0895bc8a6803b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | 100.00% | $0.704835 | 0.00175 | $0.001233 |
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.