Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
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 Empty space reserved for future updates.
uint256[43] 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 2
// function reInitialize() public reinitializer(2) {
// }
function claim(
address payToken,
PinDataParams memory pinData,
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) revert AlreadyClaimed();
if (!isValidSignature(pinData, signedAt, cid, signature)) revert IncorrectSignature();
uint256 fee = fee[payToken];
if (fee == 0) revert IncorrectPayToken(payToken);
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;
// Fee collection
// When there is no msg.value, try transferring ERC20
// When there is msg.value, ensure it's the correct amount
if (msg.value == 0) treasury.sendTokenFrom(msg.sender, payToken, fee);
else if (msg.value != fee) revert IncorrectFee(msg.value, fee);
else treasury.sendEther(fee);
_safeMint(pinData.receiver, tokenId);
emit Claimed(pinData.receiver, pinData.guildAction, pinData.guildId);
}
function burn(GuildAction guildAction, uint256 guildId) external {
uint256 tokenId = claimedTokens[msg.sender][guildAction][guildId];
claimedTokens[msg.sender][guildAction][guildId] = 0;
delete claimedTokensDetails[tokenId];
delete cids[tokenId];
_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, signedAt, newCid, signature)) revert IncorrectSignature();
uint256 tokenId = claimedTokens[pinData.receiver][pinData.guildAction][pinData.guildId];
if (tokenId == 0) revert NonExistentToken(tokenId);
cids[tokenId] = newCid;
emit TokenURIUpdated(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 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,
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,
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 on-chain proof that you joined",
// "This is an on-chain proof that you're the owner of",
// "This is an on-chain 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 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 payToken The address of the token that's used for paying the minting fees. 0 for ether.
/// @param pinData The Guild-related data, see {PinDataParams}.
/// @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(
address payToken,
PinDataParams memory pinData,
uint256 signedAt,
string calldata cid,
bytes calldata signature
) external payable;
/// @notice Burns a token from the sender.
/// @param guildAction The action to which the token belongs to.
/// @param guildId The id of the guild where the token belongs to.
function burn(GuildAction guildAction, uint256 guildId) external;
/// @notice Updates a minted token's cid.
/// @dev Only callable 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 Only callable 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 whenever a token's cid is updated.
/// @param tokenId The id of the updated token.
event TokenURIUpdated(uint256 tokenId);
/// @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 such a token is attempted to be used for paying that has no fee set.
/// @dev The owner should set a fee for the token to solve this issue.
/// @param token The address of the token that cannot be used.
error IncorrectPayToken(address token);
/// @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();
/// @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);
}// 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 { 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";
/* solhint-enable max-line-length */
/// @title An enumerable soulbound ERC721.
/// @notice Allowance and transfer-related functions are disabled.
contract SoulboundERC721 is ERC721Upgradeable, ERC721EnumerableUpgradeable {
/// @notice Empty space reserved for future updates.
uint256[50] private __gap;
/// @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) returns (bool) {
return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
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.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;
mapping(address token => uint256 fee) 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(address token, uint256 newFee) external onlyOwner {
fee[token] = newFee;
emit FeeChanged(token, 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 for a given token used for paying.
/// @dev Callable only by the owner.
/// @param token The token whose fee is set.
/// @param newFee The new fee in base units.
function setFee(address token, 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.
/// @param token The token used for paying.
/// @return fee The amount of the fee in base units.
function fee(address token) external view returns (uint256 fee);
/// @notice Returns the address that receives the fees.
function treasury() external view returns (address payable);
/// @notice Event emitted when a token's fee is changed.
/// @param token The address of the token whose fee was changed. 0 for ether.
/// @param newFee The new amount of fee in base units.
event FeeChanged(address token, 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
Contract ABI
API[{"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":[{"internalType":"address","name":"token","type":"address"}],"name":"IncorrectPayToken","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"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"TransferFailed","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":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":"address","name":"token","type":"address"},{"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":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":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenURIUpdated","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":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":"enum IGuildPin.GuildAction","name":"guildAction","type":"uint8"},{"internalType":"uint256","name":"guildId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payToken","type":"address"},{"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":"cid","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"fee","outputs":[{"internalType":"uint256","name":"fee","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":"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":[],"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":"address","name":"token","type":"address"},{"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
60a06040523060805234801561001457600080fd5b50608051613efe61004c60003960008181610a1401528181610a5401528181610af301528181610b330152610c5b0152613efe6000f3fe6080604052600436106102045760003560e01c806359c4235c11610118578063a22cb465116100a0578063e55156b51161006f578063e55156b514610594578063e985e9c5146105b4578063f0f44260146105d4578063f2fde38b146105f4578063fdda2b211461061457600080fd5b8063a22cb4651461052b578063b88d4fde14610546578063c87b56dd14610561578063df6e943b1461058157600080fd5b806370a08231116100e757806370a08231146104a3578063715018a6146104c35780638da5cb5b146104d85780638f15b414146104f657806395d89b411461051657600080fd5b806359c4235c1461041457806361d027b3146104345780636352211e146104555780636fcca69b1461047557600080fd5b80631cc7d7431161019b5780633659cfe61161016a5780633659cfe6146103ac57806342842e0e1461035b5780634f1ef286146103cc5780634f6ccce7146103df57806352d1902d146103ff57600080fd5b80631cc7d7431461033a57806323b872dd1461035b5780632a73dead146103765780632f745c591461038c57600080fd5b8063095ea7b3116101d7578063095ea7b3146102ba5780630eceb3f3146102da57806312d8b659146102fa57806318160ddd1461031a57600080fd5b806301ffc9a71461020957806306fdde031461023e57806307d8ca9914610260578063081812fc14610282575b600080fd5b34801561021557600080fd5b50610229610224366004612e50565b610634565b60405190151581526020015b60405180910390f35b34801561024a57600080fd5b5061025361065f565b6040516102359190612ebd565b34801561026c57600080fd5b5061028061027b366004612f86565b6106f1565b005b34801561028e57600080fd5b506102a261029d36600461303f565b610794565b6040516001600160a01b039091168152602001610235565b3480156102c657600080fd5b506102806102d536600461306d565b6107bb565b3480156102e657600080fd5b506102806102f5366004613183565b6107d4565b34801561030657600080fd5b50610280610315366004613220565b610915565b34801561032657600080fd5b5061012f545b604051908152602001610235565b34801561034657600080fd5b506101c3546102a2906001600160a01b031681565b34801561036757600080fd5b506102806102d536600461323d565b34801561038257600080fd5b5061032c610e1081565b34801561039857600080fd5b5061032c6103a736600461306d565b610973565b3480156103b857600080fd5b506102806103c7366004613220565b610a0a565b6102806103da36600461327e565b610ae9565b3480156103eb57600080fd5b5061032c6103fa36600461303f565b610bb9565b34801561040b57600080fd5b5061032c610c4e565b34801561042057600080fd5b5061028061042f3660046132cd565b610d01565b34801561044057600080fd5b50610191546102a2906001600160a01b031681565b34801561046157600080fd5b506102a261047036600461303f565b610dfa565b34801561048157600080fd5b5061032c610490366004613220565b6101926020526000908152604090205481565b3480156104af57600080fd5b5061032c6104be366004613220565b610e5a565b3480156104cf57600080fd5b50610280610ee0565b3480156104e457600080fd5b506065546001600160a01b03166102a2565b34801561050257600080fd5b506102806105113660046132e9565b610ef4565b34801561052257600080fd5b50610253611040565b34801561053757600080fd5b506102806102d536600461337f565b34801561055257600080fd5b506102806102d53660046133b8565b34801561056d57600080fd5b5061025361057c36600461303f565b61104f565b61028061058f366004613423565b611399565b3480156105a057600080fd5b506102806105af36600461306d565b6117be565b3480156105c057600080fd5b506102296105cf3660046134d3565b611818565b3480156105e057600080fd5b506102806105ef366004613220565b611833565b34801561060057600080fd5b5061028061060f366004613220565b61188a565b34801561062057600080fd5b5061022961062f366004613501565b611900565b60006001600160e01b0319821663780e9d6360e01b148061065957506106598261196a565b92915050565b606060fb805461066e9061353f565b80601f016020809104026020016040519081016040528092919081815260200182805461069a9061353f565b80156106e75780601f106106bc576101008083540402835291602001916106e7565b820191906000526020600020905b8154815290600101906020018083116106ca57829003601f168201915b5050505050905090565b6106f961198f565b806101c8600084600281111561071157610711613579565b600281111561072257610722613579565b815260208101919091526040016000208151819061074090826135dd565b506020820151600182019061075590826135dd565b509050507fe25b659a5fa3c64284364ec8c25d34ef8a9ac8d29add13cacd6cb9c1698a5b418260405161078891906136be565b60405180910390a15050565b600061079f826119e9565b50600090815260ff60205260409020546001600160a01b031690565b60405163a4420a9560e01b815260040160405180910390fd5b6107e0610e10426136e2565b8510156108005760405163df4cc36d60e01b815260040160405180910390fd5b61080e868686868686611a48565b61082b5760405163c1606c2f60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c5602090815260408220908801518290600281111561085e5761085e613579565b600281111561086f5761086f613579565b8152602001908152602001600020600088606001518152602001908152602001600020549050806000036108be576040516338077a2b60e01b8152600481018290526024015b60405180910390fd5b60008181526101c4602052604090206108d88587836136f5565b506040518181527fa85e1ce873ce6b209f809efc55c1e1e191c909bebb68cd8a5cc1b374adb4d42d9060200160405180910390a150505050505050565b61091d61198f565b6101c380546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b600061097e83610e5a565b82106109e05760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016108b5565b506001600160a01b0391909116600090815261012d60209081526040808320938352929052205490565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a525760405162461bcd60e51b81526004016108b5906137b4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610a9b600080516020613e42833981519152546001600160a01b031690565b6001600160a01b031614610ac15760405162461bcd60e51b81526004016108b590613800565b610aca81611b5f565b60408051600080825260208201909252610ae691839190611b67565b50565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610b315760405162461bcd60e51b81526004016108b5906137b4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b7a600080516020613e42833981519152546001600160a01b031690565b6001600160a01b031614610ba05760405162461bcd60e51b81526004016108b590613800565b610ba982611b5f565b610bb582826001611b67565b5050565b6000610bc561012f5490565b8210610c285760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016108b5565b61012f8281548110610c3c57610c3c61384c565b90600052602060002001549050919050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cee5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108b5565b50600080516020613e4283398151915290565b3360009081526101c56020526040812081846002811115610d2457610d24613579565b6002811115610d3557610d35613579565b8152602080820192909252604090810160009081208582528352818120543382526101c59093529081209192509081856002811115610d7657610d76613579565b6002811115610d8757610d87613579565b8152602080820192909252604090810160009081208682528352818120939093558383526101c6909152812081815590610dc46001830182612dec565b5060006002820181905560039091018190558181526101c460205260408120610dec91612dec565b610df581611cd2565b505050565b600081815260fd60205260408120546001600160a01b0316806106595760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108b5565b60006001600160a01b038216610ec45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016108b5565b506001600160a01b0316600090815260fe602052604090205490565b610ee861198f565b610ef26000611d75565b565b600054610100900460ff1615808015610f145750600054600160ff909116105b80610f2e5750303b158015610f2e575060005460ff166001145b610f915760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108b5565b6000805460ff191660011790558015610fb4576000805461ff0019166101001790555b6101c380546001600160a01b0319166001600160a01b038416179055610fd8611dc7565b610fe0611df6565b610fea8585611e1d565b610ff383611e56565b8015611039576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606060fc805461066e9061353f565b600081815260fd60205260409020546060906001600160a01b031661108a576040516338077a2b60e01b8152600481018390526024016108b5565b60008281526101c6602090815260408083208151610100810190925280546001600160a01b03811683529192909190830190600160a01b900460ff1660028111156110d7576110d7613579565b60028111156110e8576110e8613579565b81528154600160a81b90046001600160581b031660208201526001820180546040909201916111169061353f565b80601f01602080910402602001604051908101604052809291908181526020018280546111429061353f565b801561118f5780601f106111645761010080835404028352916020019161118f565b820191906000526020600020905b81548152906001019060200180831161117257829003601f168201915b50505091835250506002828101546001600160801b03808216602080860191909152600160801b9283900482166040860152600390950154808216606086015291909104166080909201919091529082015191925060009161136e916101c891849181111561120057611200613579565b600281111561121157611211613579565b815260200190815260200160002060000183606001516101c860008660200151600281111561124257611242613579565b600281111561125357611253613579565b815260200190815260200160002060010185606001516101c460008a81526020019081526020016000206101c860008960200151600281111561129857611298613579565b60028111156112a9576112a9613579565b81526020019081526020016000206000016112d089608001516001600160801b0316611ea0565b6112e68a604001516001600160581b0316611ea0565b6112fc8b60c001516001600160801b0316611ea0565b6113128c60e001516001600160801b0316611ea0565b6101c9548f1161132a576113258f611ea0565b611340565b6113408d60a001516001600160801b0316611ea0565b60405160200161135a9b9a999897969594939291906138f1565b604051602081830303815290604052611f32565b9050806040516020016113819190613bb9565b60405160208183030381529060405292505050919050565b6113a5610e10426136e2565b8510156113c55760405163df4cc36d60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c56020908152604082209088015190919060028111156113f9576113f9613579565b600281111561140a5761140a613579565b81526020019081526020016000206000876060015181526020019081526020016000205460001461144e57604051630c8d9eab60e31b815260040160405180910390fd5b61145c868686868686611a48565b6114795760405163c1606c2f60e01b815260040160405180910390fd5b6001600160a01b03871660009081526101926020526040812054908190036114bf57604051630cc82c5760e21b81526001600160a01b03891660048201526024016108b5565b60006114cb61012f5490565b6114d6906001613bfe565b606089015160009081526101c760209081526040808320805460010190558b516001600160a01b031683526101c582528220908b01519293508392909190600281111561152557611525613579565b600281111561153657611536613579565b815260200190815260200160002060008a6060015181526020019081526020016000208190555060405180610100016040528089600001516001600160a01b031681526020018960200151600281111561159257611592613579565b81526040808b01516001600160581b03166020808401919091526080808d0151838501526060808e0180516001600160801b03908116928701929092525160009081526101c784528481205482169286019290925242811660a0808701919091528e01511660c0909401939093528483526101c681529120825181546001600160a01b039091166001600160a01b031982168117835592840151919283916001600160a81b03191617600160a01b83600281111561165257611652613579565b0217905550604082015181546001600160581b03909116600160a81b026001600160a81b039091161781556060820151600182019061169190826135dd565b50608082015160a08301516001600160801b03918216600160801b918316820217600284015560c084015160e09094015193821693909116029190911760039091015560008181526101c4602052604090206116ee8688836136f5565b50346000036117155761019154611710906001600160a01b0316338b85612084565b611755565b81341461173e5760405163dcf6afcb60e01b8152346004820152602481018390526044016108b5565b61019154611755906001600160a01b03168361212a565b875161176190826121a9565b87606001518860200151600281111561177c5761177c613579565b89516040516001600160a01b03909116907fc73092756e22756fd0b15b2f803bd49db35ee23e7ae171c4d414ab7a61fa8b7c90600090a4505050505050505050565b6117c661198f565b6001600160a01b03821660008181526101926020908152604091829020849055815192835282018390527f6e45e8484c7deb5bc88cf53584446a1413266c28a965d4d134ca03c5d3f998e49101610788565b600060405163a4420a9560e01b815260040160405180910390fd5b61183b61198f565b61019180546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890602001610968565b61189261198f565b6001600160a01b0381166118f75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108b5565b610ae681611d75565b6001600160a01b03831660009081526101c5602052604081208184600281111561192c5761192c613579565b600281111561193d5761193d613579565b81526020019081526020016000206000838152602001908152602001600020546000141590509392505050565b60006001600160e01b0319821663780e9d6360e01b14806106595750610659826121c3565b6065546001600160a01b03163314610ef25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108b5565b600081815260fd60205260409020546001600160a01b0316610ae65760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108b5565b600060418214611a6b5760405163c1606c2f60e01b815260040160405180910390fd5b6000611af6886000015189602001518a604001518b606001518c608001518d60a001518d8d8d4630604051602001611aad9b9a99989796959493929190613c11565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b6101c354604080516020601f88018190048102820181019092528681529293506001600160a01b0390911691611b4991879087908190840183828082843760009201919091525086939250506122139050565b6001600160a01b03161498975050505050505050565b610ae661198f565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611b9a57610df583612237565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611bf4575060408051601f3d908101601f19168201909252611bf191810190613cb3565b60015b611c575760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108b5565b600080516020613e428339815191528114611cc65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108b5565b50610df58383836122d3565b6000611cdd82610dfa565b9050611ced8160008460016122f8565b611cf682610dfa565b600083815260ff6020908152604080832080546001600160a01b03199081169091556001600160a01b03851680855260fe8452828520805460001901905587855260fd909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611dee5760405162461bcd60e51b81526004016108b590613ccc565b610ef2612304565b600054610100900460ff16610ef25760405162461bcd60e51b81526004016108b590613ccc565b600054610100900460ff16611e445760405162461bcd60e51b81526004016108b590613ccc565b611e4e8282612334565b610bb5611df6565b600054610100900460ff16611e7d5760405162461bcd60e51b81526004016108b590613ccc565b61019180546001600160a01b0319166001600160a01b0392909216919091179055565b60606000611ead83612365565b60010190506000816001600160401b03811115611ecc57611ecc612ee4565b6040519080825280601f01601f191660200182016040528015611ef6576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611f0057509392505050565b60608151600003611f5157505060408051602081019091526000815290565b6000604051806060016040528060408152602001613e626040913990506000600384516002611f809190613bfe565b611f8a9190613d17565b611f95906004613d39565b6001600160401b03811115611fac57611fac612ee4565b6040519080825280601f01601f191660200182016040528015611fd6576020820181803683370190505b509050600182016020820185865187015b80821015612042576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611fe7565b505060038651066001811461205e576002811461207157612079565b603d6001830353603d6002830353612079565b603d60018303535b509195945050505050565b6040516323b872dd60e01b81526001600160a01b0384811660048301528581166024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156120db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ff9190613d50565b6121245760405163291e1d5560e11b81523360048201523060248201526044016108b5565b50505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612177576040519150601f19603f3d011682016040523d82523d6000602084013e61217c565b606091505b5050905080610df557604051632499e3bb60e11b81526001600160a01b03841660048201526024016108b5565b610bb582826040518060200160405280600081525061243d565b60006001600160e01b031982166380ac58cd60e01b14806121f457506001600160e01b03198216635b5e139f60e01b145b8061065957506301ffc9a760e01b6001600160e01b0319831614610659565b60008060006122228585612470565b9150915061222f816124b5565b509392505050565b6001600160a01b0381163b6122a45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108b5565b600080516020613e4283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6122dc836125ff565b6000825111806122e95750805b15610df557612124838361263f565b6121248484848461266b565b600054610100900460ff1661232b5760405162461bcd60e51b81526004016108b590613ccc565b610ef233611d75565b600054610100900460ff1661235b5760405162461bcd60e51b81526004016108b590613ccc565b610bb5828261279a565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106123a45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106123d0576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106123ee57662386f26fc10000830492506010015b6305f5e1008310612406576305f5e100830492506008015b612710831061241a57612710830492506004015b6064831061242c576064830492506002015b600a83106106595760010192915050565b61244783836127da565b6124546000848484612973565b610df55760405162461bcd60e51b81526004016108b590613d6d565b60008082516041036124a65760208301516040840151606085015160001a61249a87828585612a75565b945094505050506124ae565b506000905060025b9250929050565b60008160048111156124c9576124c9613579565b036124d15750565b60018160048111156124e5576124e5613579565b036125325760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108b5565b600281600481111561254657612546613579565b036125935760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108b5565b60038160048111156125a7576125a7613579565b03610ae65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108b5565b61260881612237565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606126648383604051806060016040528060278152602001613ea260279139612b39565b9392505050565b60018111156126da5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b60648201526084016108b5565b816001600160a01b038516612738576127338161012f8054600083815261013060205260408120829055600182018355919091527f232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f9790155565b61275b565b836001600160a01b0316856001600160a01b03161461275b5761275b8582612bb1565b6001600160a01b0384166127775761277281612c53565b611039565b846001600160a01b0316846001600160a01b031614611039576110398482612d08565b600054610100900460ff166127c15760405162461bcd60e51b81526004016108b590613ccc565b60fb6127cd83826135dd565b5060fc610df582826135dd565b6001600160a01b0382166128305760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108b5565b600081815260fd60205260409020546001600160a01b0316156128955760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108b5565b6128a36000838360016122f8565b600081815260fd60205260409020546001600160a01b0316156129085760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108b5565b6001600160a01b038216600081815260fe602090815260408083208054600101905584835260fd90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15612a6957604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906129b7903390899088908890600401613dbf565b6020604051808303816000875af19250505080156129f2575060408051601f3d908101601f191682019092526129ef91810190613df2565b60015b612a4f573d808015612a20576040519150601f19603f3d011682016040523d82523d6000602084013e612a25565b606091505b508051600003612a475760405162461bcd60e51b81526004016108b590613d6d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a6d565b5060015b949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612aac5750600090506003612b30565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612b00573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612b2957600060019250925050612b30565b9150600090505b94509492505050565b6060600080856001600160a01b031685604051612b569190613e0f565b600060405180830381855af49150503d8060008114612b91576040519150601f19603f3d011682016040523d82523d6000602084013e612b96565b606091505b5091509150612ba786838387612d4e565b9695505050505050565b60006001612bbe84610e5a565b612bc891906136e2565b600083815261012e6020526040902054909150808214612c1e576001600160a01b038416600090815261012d60209081526040808320858452825280832054848452818420819055835261012e90915290208190555b50600091825261012e602090815260408084208490556001600160a01b03909416835261012d81528383209183525290812055565b61012f54600090612c66906001906136e2565b6000838152610130602052604081205461012f8054939450909284908110612c9057612c9061384c565b906000526020600020015490508061012f8381548110612cb257612cb261384c565b6000918252602080832090910192909255828152610130909152604080822084905585825281205561012f805480612cec57612cec613e2b565b6001900381819060005260206000200160009055905550505050565b6000612d1383610e5a565b6001600160a01b03909316600090815261012d60209081526040808320868452825280832085905593825261012e9052919091209190915550565b60608315612dbd578251600003612db6576001600160a01b0385163b612db65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108b5565b5081612a6d565b612a6d8383815115612dd25781518083602001fd5b8060405162461bcd60e51b81526004016108b59190612ebd565b508054612df89061353f565b6000825580601f10612e08575050565b601f016020900490600052602060002090810190610ae691905b80821115612e365760008155600101612e22565b5090565b6001600160e01b031981168114610ae657600080fd5b600060208284031215612e6257600080fd5b813561266481612e3a565b60005b83811015612e88578181015183820152602001612e70565b50506000910152565b60008151808452612ea9816020860160208601612e6d565b601f01601f19169290920160200192915050565b6020815260006126646020830184612e91565b803560038110612edf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112612f0b57600080fd5b81356001600160401b0380821115612f2557612f25612ee4565b604051601f8301601f19908116603f01168101908282118183101715612f4d57612f4d612ee4565b81604052838152866020858801011115612f6657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215612f9957600080fd5b612fa283612ed0565b915060208301356001600160401b0380821115612fbe57600080fd5b9084019060408287031215612fd257600080fd5b604051604081018181108382111715612fed57612fed612ee4565b604052823582811115612fff57600080fd5b61300b88828601612efa565b82525060208301358281111561302057600080fd5b61302c88828601612efa565b6020830152508093505050509250929050565b60006020828403121561305157600080fd5b5035919050565b6001600160a01b0381168114610ae657600080fd5b6000806040838503121561308057600080fd5b823561308b81613058565b946020939093013593505050565b600060c082840312156130ab57600080fd5b60405160c081016001600160401b0382821081831117156130ce576130ce612ee4565b81604052829350843591506130e282613058565b8183526130f160208601612ed0565b60208401526040850135604084015260608501356060840152608085013591508082111561311e57600080fd5b5061312b85828601612efa565b60808301525060a083013560a08201525092915050565b60008083601f84011261315457600080fd5b5081356001600160401b0381111561316b57600080fd5b6020830191508360208285010111156124ae57600080fd5b6000806000806000806080878903121561319c57600080fd5b86356001600160401b03808211156131b357600080fd5b6131bf8a838b01613099565b97506020890135965060408901359150808211156131dc57600080fd5b6131e88a838b01613142565b9096509450606089013591508082111561320157600080fd5b5061320e89828a01613142565b979a9699509497509295939492505050565b60006020828403121561323257600080fd5b813561266481613058565b60008060006060848603121561325257600080fd5b833561325d81613058565b9250602084013561326d81613058565b929592945050506040919091013590565b6000806040838503121561329157600080fd5b823561329c81613058565b915060208301356001600160401b038111156132b757600080fd5b6132c385828601612efa565b9150509250929050565b600080604083850312156132e057600080fd5b61308b83612ed0565b600080600080608085870312156132ff57600080fd5b84356001600160401b038082111561331657600080fd5b61332288838901612efa565b9550602087013591508082111561333857600080fd5b5061334587828801612efa565b935050604085013561335681613058565b9150606085013561336681613058565b939692955090935050565b8015158114610ae657600080fd5b6000806040838503121561339257600080fd5b823561339d81613058565b915060208301356133ad81613371565b809150509250929050565b600080600080608085870312156133ce57600080fd5b84356133d981613058565b935060208501356133e981613058565b92506040850135915060608501356001600160401b0381111561340b57600080fd5b61341787828801612efa565b91505092959194509250565b600080600080600080600060a0888a03121561343e57600080fd5b873561344981613058565b965060208801356001600160401b038082111561346557600080fd5b6134718b838c01613099565b975060408a0135965060608a013591508082111561348e57600080fd5b61349a8b838c01613142565b909650945060808a01359150808211156134b357600080fd5b506134c08a828b01613142565b989b979a50959850939692959293505050565b600080604083850312156134e657600080fd5b82356134f181613058565b915060208301356133ad81613058565b60008060006060848603121561351657600080fd5b833561352181613058565b925061352f60208501612ed0565b9150604084013590509250925092565b600181811c9082168061355357607f821691505b60208210810361357357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b601f821115610df557600081815260208120601f850160051c810160208610156135b65750805b601f850160051c820191505b818110156135d5578281556001016135c2565b505050505050565b81516001600160401b038111156135f6576135f6612ee4565b61360a81613604845461353f565b8461358f565b602080601f83116001811461363f57600084156136275750858301515b600019600386901b1c1916600185901b1785556135d5565b600085815260208120601f198616915b8281101561366e5788860151825594840194600190910190840161364f565b508582101561368c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600381106136ba57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610659828461369c565b634e487b7160e01b600052601160045260246000fd5b81810381811115610659576106596136cc565b6001600160401b0383111561370c5761370c612ee4565b6137208361371a835461353f565b8361358f565b6000601f841160018114613754576000851561373c5750838201355b600019600387901b1c1916600186901b178355611039565b600083815260209020601f19861690835b828110156137855786850135825560209485019460019092019101613765565b50868210156137a25760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000815461386f8161353f565b60018281168015613887576001811461389c576138cb565b60ff19841687528215158302870194506138cb565b8560005260208060002060005b858110156138c25781548a8201529084019082016138a9565b50505082870194505b5050505092915050565b600081516138e7818560208601612e6d565b9290920192915050565b693d913730b6b2911d101160b11b81526000613910600a83018e613862565b600160fd1b8152613924600182018e6138d5565b72111610113232b9b1b934b83a34b7b7111d101160691b8152905061394c601382018d613862565b600160fd1b815290506139a261399c613968600184018e6138d5565b7f206f6e204775696c642e78797a2e222c2022696d616765223a2022697066733a8152612f2f60f01b602082015260220190565b8b613862565b71222c202261747472696275746573223a205b60701b815290507f207b202274726169745f74797065223a202274797065222c000000000000000060128201526a10113b30b63ab2911d101160a91b602a820152613a03603582018a613862565b7f227d2c207b202274726169745f74797065223a20226775696c644964222c0000815290506a10113b30b63ab2911d101160a91b601e820152613a90613a8a613a4f602984018b6138d5565b7f22207d2c207b202274726169745f74797065223a2022757365724964222c20228152683b30b63ab2911d101160b91b602082015260290190565b886138d5565b7f22207d2c207b202274726169745f74797065223a20226d696e7444617465222c815290507f2022646973706c61795f74797065223a202264617465222c202276616c75652260208201526101d160f51b6040820152613b98613b92613b5a613a8a613aff604286018b6138d5565b7f207d2c207b202274726169745f74797065223a2022616374696f6e446174652281527f2c2022646973706c61795f74797065223a202264617465222c202276616c75656020820152620111d160ed1b604082015260430190565b7f207d2c207b202274726169745f74797065223a202272616e6b222c202276616c8152653ab2911d101160d11b602082015260260190565b856138d5565b65227d205d207d60d01b81526006019e9d5050505050505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613bf181601d850160208701612e6d565b91909101601d0192915050565b80820180821115610659576106596136cc565b6001600160a01b038c1681526000610140613c2f602084018e61369c565b8b60408401528a6060840152806080840152613c4d8184018b612e91565b90508860a08401528760c084015282810360e0840152858152858760208301376000602087830101526020601f19601f88011682010191505083610100830152613ca36101208301846001600160a01b03169052565b9c9b505050505050505050505050565b600060208284031215613cc557600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082613d3457634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610659576106596136cc565b600060208284031215613d6257600080fd5b815161266481613371565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ba790830184612e91565b600060208284031215613e0457600080fd5b815161266481612e3a565b60008251613e21818460208701612e6d565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a9eb1fd32ab9fb079174c721408e8abe1c134ec2b0edd03a8cfbae9f9323557364736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102045760003560e01c806359c4235c11610118578063a22cb465116100a0578063e55156b51161006f578063e55156b514610594578063e985e9c5146105b4578063f0f44260146105d4578063f2fde38b146105f4578063fdda2b211461061457600080fd5b8063a22cb4651461052b578063b88d4fde14610546578063c87b56dd14610561578063df6e943b1461058157600080fd5b806370a08231116100e757806370a08231146104a3578063715018a6146104c35780638da5cb5b146104d85780638f15b414146104f657806395d89b411461051657600080fd5b806359c4235c1461041457806361d027b3146104345780636352211e146104555780636fcca69b1461047557600080fd5b80631cc7d7431161019b5780633659cfe61161016a5780633659cfe6146103ac57806342842e0e1461035b5780634f1ef286146103cc5780634f6ccce7146103df57806352d1902d146103ff57600080fd5b80631cc7d7431461033a57806323b872dd1461035b5780632a73dead146103765780632f745c591461038c57600080fd5b8063095ea7b3116101d7578063095ea7b3146102ba5780630eceb3f3146102da57806312d8b659146102fa57806318160ddd1461031a57600080fd5b806301ffc9a71461020957806306fdde031461023e57806307d8ca9914610260578063081812fc14610282575b600080fd5b34801561021557600080fd5b50610229610224366004612e50565b610634565b60405190151581526020015b60405180910390f35b34801561024a57600080fd5b5061025361065f565b6040516102359190612ebd565b34801561026c57600080fd5b5061028061027b366004612f86565b6106f1565b005b34801561028e57600080fd5b506102a261029d36600461303f565b610794565b6040516001600160a01b039091168152602001610235565b3480156102c657600080fd5b506102806102d536600461306d565b6107bb565b3480156102e657600080fd5b506102806102f5366004613183565b6107d4565b34801561030657600080fd5b50610280610315366004613220565b610915565b34801561032657600080fd5b5061012f545b604051908152602001610235565b34801561034657600080fd5b506101c3546102a2906001600160a01b031681565b34801561036757600080fd5b506102806102d536600461323d565b34801561038257600080fd5b5061032c610e1081565b34801561039857600080fd5b5061032c6103a736600461306d565b610973565b3480156103b857600080fd5b506102806103c7366004613220565b610a0a565b6102806103da36600461327e565b610ae9565b3480156103eb57600080fd5b5061032c6103fa36600461303f565b610bb9565b34801561040b57600080fd5b5061032c610c4e565b34801561042057600080fd5b5061028061042f3660046132cd565b610d01565b34801561044057600080fd5b50610191546102a2906001600160a01b031681565b34801561046157600080fd5b506102a261047036600461303f565b610dfa565b34801561048157600080fd5b5061032c610490366004613220565b6101926020526000908152604090205481565b3480156104af57600080fd5b5061032c6104be366004613220565b610e5a565b3480156104cf57600080fd5b50610280610ee0565b3480156104e457600080fd5b506065546001600160a01b03166102a2565b34801561050257600080fd5b506102806105113660046132e9565b610ef4565b34801561052257600080fd5b50610253611040565b34801561053757600080fd5b506102806102d536600461337f565b34801561055257600080fd5b506102806102d53660046133b8565b34801561056d57600080fd5b5061025361057c36600461303f565b61104f565b61028061058f366004613423565b611399565b3480156105a057600080fd5b506102806105af36600461306d565b6117be565b3480156105c057600080fd5b506102296105cf3660046134d3565b611818565b3480156105e057600080fd5b506102806105ef366004613220565b611833565b34801561060057600080fd5b5061028061060f366004613220565b61188a565b34801561062057600080fd5b5061022961062f366004613501565b611900565b60006001600160e01b0319821663780e9d6360e01b148061065957506106598261196a565b92915050565b606060fb805461066e9061353f565b80601f016020809104026020016040519081016040528092919081815260200182805461069a9061353f565b80156106e75780601f106106bc576101008083540402835291602001916106e7565b820191906000526020600020905b8154815290600101906020018083116106ca57829003601f168201915b5050505050905090565b6106f961198f565b806101c8600084600281111561071157610711613579565b600281111561072257610722613579565b815260208101919091526040016000208151819061074090826135dd565b506020820151600182019061075590826135dd565b509050507fe25b659a5fa3c64284364ec8c25d34ef8a9ac8d29add13cacd6cb9c1698a5b418260405161078891906136be565b60405180910390a15050565b600061079f826119e9565b50600090815260ff60205260409020546001600160a01b031690565b60405163a4420a9560e01b815260040160405180910390fd5b6107e0610e10426136e2565b8510156108005760405163df4cc36d60e01b815260040160405180910390fd5b61080e868686868686611a48565b61082b5760405163c1606c2f60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c5602090815260408220908801518290600281111561085e5761085e613579565b600281111561086f5761086f613579565b8152602001908152602001600020600088606001518152602001908152602001600020549050806000036108be576040516338077a2b60e01b8152600481018290526024015b60405180910390fd5b60008181526101c4602052604090206108d88587836136f5565b506040518181527fa85e1ce873ce6b209f809efc55c1e1e191c909bebb68cd8a5cc1b374adb4d42d9060200160405180910390a150505050505050565b61091d61198f565b6101c380546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b600061097e83610e5a565b82106109e05760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016108b5565b506001600160a01b0391909116600090815261012d60209081526040808320938352929052205490565b6001600160a01b037f0000000000000000000000007af3204224cba6cae696dbcf5952461f6c332e29163003610a525760405162461bcd60e51b81526004016108b5906137b4565b7f0000000000000000000000007af3204224cba6cae696dbcf5952461f6c332e296001600160a01b0316610a9b600080516020613e42833981519152546001600160a01b031690565b6001600160a01b031614610ac15760405162461bcd60e51b81526004016108b590613800565b610aca81611b5f565b60408051600080825260208201909252610ae691839190611b67565b50565b6001600160a01b037f0000000000000000000000007af3204224cba6cae696dbcf5952461f6c332e29163003610b315760405162461bcd60e51b81526004016108b5906137b4565b7f0000000000000000000000007af3204224cba6cae696dbcf5952461f6c332e296001600160a01b0316610b7a600080516020613e42833981519152546001600160a01b031690565b6001600160a01b031614610ba05760405162461bcd60e51b81526004016108b590613800565b610ba982611b5f565b610bb582826001611b67565b5050565b6000610bc561012f5490565b8210610c285760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016108b5565b61012f8281548110610c3c57610c3c61384c565b90600052602060002001549050919050565b6000306001600160a01b037f0000000000000000000000007af3204224cba6cae696dbcf5952461f6c332e291614610cee5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108b5565b50600080516020613e4283398151915290565b3360009081526101c56020526040812081846002811115610d2457610d24613579565b6002811115610d3557610d35613579565b8152602080820192909252604090810160009081208582528352818120543382526101c59093529081209192509081856002811115610d7657610d76613579565b6002811115610d8757610d87613579565b8152602080820192909252604090810160009081208682528352818120939093558383526101c6909152812081815590610dc46001830182612dec565b5060006002820181905560039091018190558181526101c460205260408120610dec91612dec565b610df581611cd2565b505050565b600081815260fd60205260408120546001600160a01b0316806106595760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108b5565b60006001600160a01b038216610ec45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016108b5565b506001600160a01b0316600090815260fe602052604090205490565b610ee861198f565b610ef26000611d75565b565b600054610100900460ff1615808015610f145750600054600160ff909116105b80610f2e5750303b158015610f2e575060005460ff166001145b610f915760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108b5565b6000805460ff191660011790558015610fb4576000805461ff0019166101001790555b6101c380546001600160a01b0319166001600160a01b038416179055610fd8611dc7565b610fe0611df6565b610fea8585611e1d565b610ff383611e56565b8015611039576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606060fc805461066e9061353f565b600081815260fd60205260409020546060906001600160a01b031661108a576040516338077a2b60e01b8152600481018390526024016108b5565b60008281526101c6602090815260408083208151610100810190925280546001600160a01b03811683529192909190830190600160a01b900460ff1660028111156110d7576110d7613579565b60028111156110e8576110e8613579565b81528154600160a81b90046001600160581b031660208201526001820180546040909201916111169061353f565b80601f01602080910402602001604051908101604052809291908181526020018280546111429061353f565b801561118f5780601f106111645761010080835404028352916020019161118f565b820191906000526020600020905b81548152906001019060200180831161117257829003601f168201915b50505091835250506002828101546001600160801b03808216602080860191909152600160801b9283900482166040860152600390950154808216606086015291909104166080909201919091529082015191925060009161136e916101c891849181111561120057611200613579565b600281111561121157611211613579565b815260200190815260200160002060000183606001516101c860008660200151600281111561124257611242613579565b600281111561125357611253613579565b815260200190815260200160002060010185606001516101c460008a81526020019081526020016000206101c860008960200151600281111561129857611298613579565b60028111156112a9576112a9613579565b81526020019081526020016000206000016112d089608001516001600160801b0316611ea0565b6112e68a604001516001600160581b0316611ea0565b6112fc8b60c001516001600160801b0316611ea0565b6113128c60e001516001600160801b0316611ea0565b6101c9548f1161132a576113258f611ea0565b611340565b6113408d60a001516001600160801b0316611ea0565b60405160200161135a9b9a999897969594939291906138f1565b604051602081830303815290604052611f32565b9050806040516020016113819190613bb9565b60405160208183030381529060405292505050919050565b6113a5610e10426136e2565b8510156113c55760405163df4cc36d60e01b815260040160405180910390fd5b85516001600160a01b031660009081526101c56020908152604082209088015190919060028111156113f9576113f9613579565b600281111561140a5761140a613579565b81526020019081526020016000206000876060015181526020019081526020016000205460001461144e57604051630c8d9eab60e31b815260040160405180910390fd5b61145c868686868686611a48565b6114795760405163c1606c2f60e01b815260040160405180910390fd5b6001600160a01b03871660009081526101926020526040812054908190036114bf57604051630cc82c5760e21b81526001600160a01b03891660048201526024016108b5565b60006114cb61012f5490565b6114d6906001613bfe565b606089015160009081526101c760209081526040808320805460010190558b516001600160a01b031683526101c582528220908b01519293508392909190600281111561152557611525613579565b600281111561153657611536613579565b815260200190815260200160002060008a6060015181526020019081526020016000208190555060405180610100016040528089600001516001600160a01b031681526020018960200151600281111561159257611592613579565b81526040808b01516001600160581b03166020808401919091526080808d0151838501526060808e0180516001600160801b03908116928701929092525160009081526101c784528481205482169286019290925242811660a0808701919091528e01511660c0909401939093528483526101c681529120825181546001600160a01b039091166001600160a01b031982168117835592840151919283916001600160a81b03191617600160a01b83600281111561165257611652613579565b0217905550604082015181546001600160581b03909116600160a81b026001600160a81b039091161781556060820151600182019061169190826135dd565b50608082015160a08301516001600160801b03918216600160801b918316820217600284015560c084015160e09094015193821693909116029190911760039091015560008181526101c4602052604090206116ee8688836136f5565b50346000036117155761019154611710906001600160a01b0316338b85612084565b611755565b81341461173e5760405163dcf6afcb60e01b8152346004820152602481018390526044016108b5565b61019154611755906001600160a01b03168361212a565b875161176190826121a9565b87606001518860200151600281111561177c5761177c613579565b89516040516001600160a01b03909116907fc73092756e22756fd0b15b2f803bd49db35ee23e7ae171c4d414ab7a61fa8b7c90600090a4505050505050505050565b6117c661198f565b6001600160a01b03821660008181526101926020908152604091829020849055815192835282018390527f6e45e8484c7deb5bc88cf53584446a1413266c28a965d4d134ca03c5d3f998e49101610788565b600060405163a4420a9560e01b815260040160405180910390fd5b61183b61198f565b61019180546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890602001610968565b61189261198f565b6001600160a01b0381166118f75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108b5565b610ae681611d75565b6001600160a01b03831660009081526101c5602052604081208184600281111561192c5761192c613579565b600281111561193d5761193d613579565b81526020019081526020016000206000838152602001908152602001600020546000141590509392505050565b60006001600160e01b0319821663780e9d6360e01b14806106595750610659826121c3565b6065546001600160a01b03163314610ef25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108b5565b600081815260fd60205260409020546001600160a01b0316610ae65760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108b5565b600060418214611a6b5760405163c1606c2f60e01b815260040160405180910390fd5b6000611af6886000015189602001518a604001518b606001518c608001518d60a001518d8d8d4630604051602001611aad9b9a99989796959493929190613c11565b604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b6101c354604080516020601f88018190048102820181019092528681529293506001600160a01b0390911691611b4991879087908190840183828082843760009201919091525086939250506122139050565b6001600160a01b03161498975050505050505050565b610ae661198f565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611b9a57610df583612237565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611bf4575060408051601f3d908101601f19168201909252611bf191810190613cb3565b60015b611c575760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108b5565b600080516020613e428339815191528114611cc65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108b5565b50610df58383836122d3565b6000611cdd82610dfa565b9050611ced8160008460016122f8565b611cf682610dfa565b600083815260ff6020908152604080832080546001600160a01b03199081169091556001600160a01b03851680855260fe8452828520805460001901905587855260fd909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611dee5760405162461bcd60e51b81526004016108b590613ccc565b610ef2612304565b600054610100900460ff16610ef25760405162461bcd60e51b81526004016108b590613ccc565b600054610100900460ff16611e445760405162461bcd60e51b81526004016108b590613ccc565b611e4e8282612334565b610bb5611df6565b600054610100900460ff16611e7d5760405162461bcd60e51b81526004016108b590613ccc565b61019180546001600160a01b0319166001600160a01b0392909216919091179055565b60606000611ead83612365565b60010190506000816001600160401b03811115611ecc57611ecc612ee4565b6040519080825280601f01601f191660200182016040528015611ef6576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611f0057509392505050565b60608151600003611f5157505060408051602081019091526000815290565b6000604051806060016040528060408152602001613e626040913990506000600384516002611f809190613bfe565b611f8a9190613d17565b611f95906004613d39565b6001600160401b03811115611fac57611fac612ee4565b6040519080825280601f01601f191660200182016040528015611fd6576020820181803683370190505b509050600182016020820185865187015b80821015612042576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611fe7565b505060038651066001811461205e576002811461207157612079565b603d6001830353603d6002830353612079565b603d60018303535b509195945050505050565b6040516323b872dd60e01b81526001600160a01b0384811660048301528581166024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156120db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ff9190613d50565b6121245760405163291e1d5560e11b81523360048201523060248201526044016108b5565b50505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612177576040519150601f19603f3d011682016040523d82523d6000602084013e61217c565b606091505b5050905080610df557604051632499e3bb60e11b81526001600160a01b03841660048201526024016108b5565b610bb582826040518060200160405280600081525061243d565b60006001600160e01b031982166380ac58cd60e01b14806121f457506001600160e01b03198216635b5e139f60e01b145b8061065957506301ffc9a760e01b6001600160e01b0319831614610659565b60008060006122228585612470565b9150915061222f816124b5565b509392505050565b6001600160a01b0381163b6122a45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108b5565b600080516020613e4283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6122dc836125ff565b6000825111806122e95750805b15610df557612124838361263f565b6121248484848461266b565b600054610100900460ff1661232b5760405162461bcd60e51b81526004016108b590613ccc565b610ef233611d75565b600054610100900460ff1661235b5760405162461bcd60e51b81526004016108b590613ccc565b610bb5828261279a565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106123a45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106123d0576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106123ee57662386f26fc10000830492506010015b6305f5e1008310612406576305f5e100830492506008015b612710831061241a57612710830492506004015b6064831061242c576064830492506002015b600a83106106595760010192915050565b61244783836127da565b6124546000848484612973565b610df55760405162461bcd60e51b81526004016108b590613d6d565b60008082516041036124a65760208301516040840151606085015160001a61249a87828585612a75565b945094505050506124ae565b506000905060025b9250929050565b60008160048111156124c9576124c9613579565b036124d15750565b60018160048111156124e5576124e5613579565b036125325760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108b5565b600281600481111561254657612546613579565b036125935760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108b5565b60038160048111156125a7576125a7613579565b03610ae65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108b5565b61260881612237565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606126648383604051806060016040528060278152602001613ea260279139612b39565b9392505050565b60018111156126da5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b60648201526084016108b5565b816001600160a01b038516612738576127338161012f8054600083815261013060205260408120829055600182018355919091527f232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f9790155565b61275b565b836001600160a01b0316856001600160a01b03161461275b5761275b8582612bb1565b6001600160a01b0384166127775761277281612c53565b611039565b846001600160a01b0316846001600160a01b031614611039576110398482612d08565b600054610100900460ff166127c15760405162461bcd60e51b81526004016108b590613ccc565b60fb6127cd83826135dd565b5060fc610df582826135dd565b6001600160a01b0382166128305760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108b5565b600081815260fd60205260409020546001600160a01b0316156128955760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108b5565b6128a36000838360016122f8565b600081815260fd60205260409020546001600160a01b0316156129085760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108b5565b6001600160a01b038216600081815260fe602090815260408083208054600101905584835260fd90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b15612a6957604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906129b7903390899088908890600401613dbf565b6020604051808303816000875af19250505080156129f2575060408051601f3d908101601f191682019092526129ef91810190613df2565b60015b612a4f573d808015612a20576040519150601f19603f3d011682016040523d82523d6000602084013e612a25565b606091505b508051600003612a475760405162461bcd60e51b81526004016108b590613d6d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a6d565b5060015b949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612aac5750600090506003612b30565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612b00573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612b2957600060019250925050612b30565b9150600090505b94509492505050565b6060600080856001600160a01b031685604051612b569190613e0f565b600060405180830381855af49150503d8060008114612b91576040519150601f19603f3d011682016040523d82523d6000602084013e612b96565b606091505b5091509150612ba786838387612d4e565b9695505050505050565b60006001612bbe84610e5a565b612bc891906136e2565b600083815261012e6020526040902054909150808214612c1e576001600160a01b038416600090815261012d60209081526040808320858452825280832054848452818420819055835261012e90915290208190555b50600091825261012e602090815260408084208490556001600160a01b03909416835261012d81528383209183525290812055565b61012f54600090612c66906001906136e2565b6000838152610130602052604081205461012f8054939450909284908110612c9057612c9061384c565b906000526020600020015490508061012f8381548110612cb257612cb261384c565b6000918252602080832090910192909255828152610130909152604080822084905585825281205561012f805480612cec57612cec613e2b565b6001900381819060005260206000200160009055905550505050565b6000612d1383610e5a565b6001600160a01b03909316600090815261012d60209081526040808320868452825280832085905593825261012e9052919091209190915550565b60608315612dbd578251600003612db6576001600160a01b0385163b612db65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108b5565b5081612a6d565b612a6d8383815115612dd25781518083602001fd5b8060405162461bcd60e51b81526004016108b59190612ebd565b508054612df89061353f565b6000825580601f10612e08575050565b601f016020900490600052602060002090810190610ae691905b80821115612e365760008155600101612e22565b5090565b6001600160e01b031981168114610ae657600080fd5b600060208284031215612e6257600080fd5b813561266481612e3a565b60005b83811015612e88578181015183820152602001612e70565b50506000910152565b60008151808452612ea9816020860160208601612e6d565b601f01601f19169290920160200192915050565b6020815260006126646020830184612e91565b803560038110612edf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112612f0b57600080fd5b81356001600160401b0380821115612f2557612f25612ee4565b604051601f8301601f19908116603f01168101908282118183101715612f4d57612f4d612ee4565b81604052838152866020858801011115612f6657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215612f9957600080fd5b612fa283612ed0565b915060208301356001600160401b0380821115612fbe57600080fd5b9084019060408287031215612fd257600080fd5b604051604081018181108382111715612fed57612fed612ee4565b604052823582811115612fff57600080fd5b61300b88828601612efa565b82525060208301358281111561302057600080fd5b61302c88828601612efa565b6020830152508093505050509250929050565b60006020828403121561305157600080fd5b5035919050565b6001600160a01b0381168114610ae657600080fd5b6000806040838503121561308057600080fd5b823561308b81613058565b946020939093013593505050565b600060c082840312156130ab57600080fd5b60405160c081016001600160401b0382821081831117156130ce576130ce612ee4565b81604052829350843591506130e282613058565b8183526130f160208601612ed0565b60208401526040850135604084015260608501356060840152608085013591508082111561311e57600080fd5b5061312b85828601612efa565b60808301525060a083013560a08201525092915050565b60008083601f84011261315457600080fd5b5081356001600160401b0381111561316b57600080fd5b6020830191508360208285010111156124ae57600080fd5b6000806000806000806080878903121561319c57600080fd5b86356001600160401b03808211156131b357600080fd5b6131bf8a838b01613099565b97506020890135965060408901359150808211156131dc57600080fd5b6131e88a838b01613142565b9096509450606089013591508082111561320157600080fd5b5061320e89828a01613142565b979a9699509497509295939492505050565b60006020828403121561323257600080fd5b813561266481613058565b60008060006060848603121561325257600080fd5b833561325d81613058565b9250602084013561326d81613058565b929592945050506040919091013590565b6000806040838503121561329157600080fd5b823561329c81613058565b915060208301356001600160401b038111156132b757600080fd5b6132c385828601612efa565b9150509250929050565b600080604083850312156132e057600080fd5b61308b83612ed0565b600080600080608085870312156132ff57600080fd5b84356001600160401b038082111561331657600080fd5b61332288838901612efa565b9550602087013591508082111561333857600080fd5b5061334587828801612efa565b935050604085013561335681613058565b9150606085013561336681613058565b939692955090935050565b8015158114610ae657600080fd5b6000806040838503121561339257600080fd5b823561339d81613058565b915060208301356133ad81613371565b809150509250929050565b600080600080608085870312156133ce57600080fd5b84356133d981613058565b935060208501356133e981613058565b92506040850135915060608501356001600160401b0381111561340b57600080fd5b61341787828801612efa565b91505092959194509250565b600080600080600080600060a0888a03121561343e57600080fd5b873561344981613058565b965060208801356001600160401b038082111561346557600080fd5b6134718b838c01613099565b975060408a0135965060608a013591508082111561348e57600080fd5b61349a8b838c01613142565b909650945060808a01359150808211156134b357600080fd5b506134c08a828b01613142565b989b979a50959850939692959293505050565b600080604083850312156134e657600080fd5b82356134f181613058565b915060208301356133ad81613058565b60008060006060848603121561351657600080fd5b833561352181613058565b925061352f60208501612ed0565b9150604084013590509250925092565b600181811c9082168061355357607f821691505b60208210810361357357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b601f821115610df557600081815260208120601f850160051c810160208610156135b65750805b601f850160051c820191505b818110156135d5578281556001016135c2565b505050505050565b81516001600160401b038111156135f6576135f6612ee4565b61360a81613604845461353f565b8461358f565b602080601f83116001811461363f57600084156136275750858301515b600019600386901b1c1916600185901b1785556135d5565b600085815260208120601f198616915b8281101561366e5788860151825594840194600190910190840161364f565b508582101561368c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600381106136ba57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610659828461369c565b634e487b7160e01b600052601160045260246000fd5b81810381811115610659576106596136cc565b6001600160401b0383111561370c5761370c612ee4565b6137208361371a835461353f565b8361358f565b6000601f841160018114613754576000851561373c5750838201355b600019600387901b1c1916600186901b178355611039565b600083815260209020601f19861690835b828110156137855786850135825560209485019460019092019101613765565b50868210156137a25760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000815461386f8161353f565b60018281168015613887576001811461389c576138cb565b60ff19841687528215158302870194506138cb565b8560005260208060002060005b858110156138c25781548a8201529084019082016138a9565b50505082870194505b5050505092915050565b600081516138e7818560208601612e6d565b9290920192915050565b693d913730b6b2911d101160b11b81526000613910600a83018e613862565b600160fd1b8152613924600182018e6138d5565b72111610113232b9b1b934b83a34b7b7111d101160691b8152905061394c601382018d613862565b600160fd1b815290506139a261399c613968600184018e6138d5565b7f206f6e204775696c642e78797a2e222c2022696d616765223a2022697066733a8152612f2f60f01b602082015260220190565b8b613862565b71222c202261747472696275746573223a205b60701b815290507f207b202274726169745f74797065223a202274797065222c000000000000000060128201526a10113b30b63ab2911d101160a91b602a820152613a03603582018a613862565b7f227d2c207b202274726169745f74797065223a20226775696c644964222c0000815290506a10113b30b63ab2911d101160a91b601e820152613a90613a8a613a4f602984018b6138d5565b7f22207d2c207b202274726169745f74797065223a2022757365724964222c20228152683b30b63ab2911d101160b91b602082015260290190565b886138d5565b7f22207d2c207b202274726169745f74797065223a20226d696e7444617465222c815290507f2022646973706c61795f74797065223a202264617465222c202276616c75652260208201526101d160f51b6040820152613b98613b92613b5a613a8a613aff604286018b6138d5565b7f207d2c207b202274726169745f74797065223a2022616374696f6e446174652281527f2c2022646973706c61795f74797065223a202264617465222c202276616c75656020820152620111d160ed1b604082015260430190565b7f207d2c207b202274726169745f74797065223a202272616e6b222c202276616c8152653ab2911d101160d11b602082015260260190565b856138d5565b65227d205d207d60d01b81526006019e9d5050505050505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613bf181601d850160208701612e6d565b91909101601d0192915050565b80820180821115610659576106596136cc565b6001600160a01b038c1681526000610140613c2f602084018e61369c565b8b60408401528a6060840152806080840152613c4d8184018b612e91565b90508860a08401528760c084015282810360e0840152858152858760208301376000602087830101526020601f19601f88011682010191505083610100830152613ca36101208301846001600160a01b03169052565b9c9b505050505050505050505050565b600060208284031215613cc557600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082613d3457634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610659576106596136cc565b600060208284031215613d6257600080fd5b815161266481613371565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ba790830184612e91565b600060208284031215613e0457600080fd5b815161266481612e3a565b60008251613e21818460208701612e6d565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a9eb1fd32ab9fb079174c721408e8abe1c134ec2b0edd03a8cfbae9f9323557364736f6c63430008130033
Deployed Bytecode Sourcemap
979:8225:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1334:278:4;;;;;;;;;;-1:-1:-1;1334:278:4;;;;;:::i;:::-;;:::i;:::-;;;565:14:30;;558:22;540:41;;528:2;513:18;1334:278:4;;;;;;;;2932:98:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;5982:201:0:-;;;;;;;;;;-1:-1:-1;5982:201:0;;;;;:::i;:::-;;:::i;:::-;;4407:167:13;;;;;;;;;;-1:-1:-1;4407:167:13;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3871:32:30;;;3853:51;;3841:2;3826:18;4407:167:13;3707:203:30;1618:178:4;;;;;;;;;;-1:-1:-1;1618:178:4;;;;;:::i;:::-;;:::i;5383:593:0:-;;;;;;;;;;-1:-1:-1;5383:593:0;;;;;:::i;:::-;;:::i;5216:161::-;;;;;;;;;;-1:-1:-1;5216:161:0;;;;;:::i;:::-;;:::i;1950:111:16:-;;;;;;;;;;-1:-1:-1;2037:10:16;:17;1950:111;;;7122:25:30;;;7110:2;7095:18;1950:111:16;6976:177:30;1363:26:0;;;;;;;;;;-1:-1:-1;1363:26:0;;;;-1:-1:-1;;;;;1363:26:0;;;2217:211:4;;;;;;;;;;-1:-1:-1;2217:211:4;;;;;:::i;1305:52:0:-;;;;;;;;;;;;1350:7;1305:52;;1615:264:16;;;;;;;;;;-1:-1:-1;1615:264:16;;;;;:::i;:::-;;:::i;3387:195:12:-;;;;;;;;;;-1:-1:-1;3387:195:12;;;;;:::i;:::-;;:::i;3901:220::-;;;;;;:::i;:::-;;:::i;2133:241:16:-;;;;;;;;;;-1:-1:-1;2133:241:16;;;;;:::i;:::-;;:::i;3006:131:12:-;;;;;;;;;;;;;:::i;4900:310:0:-;;;;;;;;;;-1:-1:-1;4900:310:0;;;;;:::i;:::-;;:::i;480:31:5:-;;;;;;;;;;-1:-1:-1;480:31:5;;;;-1:-1:-1;;;;;480:31:5;;;2651:219:13;;;;;;;;;;-1:-1:-1;2651:219:13;;;;;:::i;:::-;;:::i;518:48:5:-;;;;;;;;;;-1:-1:-1;518:48:5;;;;;:::i;:::-;;;;;;;;;;;;;;2390:204:13;;;;;;;;;;-1:-1:-1;2390:204:13;;;;;:::i;:::-;;:::i;2064:101:6:-;;;;;;;;;;;;;:::i;1441:85::-;;;;;;;;;;-1:-1:-1;1513:6:6;;-1:-1:-1;;;;;1513:6:6;1441:85;;2722:358:0;;;;;;;;;;-1:-1:-1;2722:358:0;;;;;:::i;:::-;;:::i;3094:102:13:-;;;;;;;;;;;;;:::i;1802:192:4:-;;;;;;;;;;-1:-1:-1;1802:192:4;;;;;:::i;2655:248::-;;;;;;;;;;-1:-1:-1;2655:248:4;;;;;:::i;6374:1883:0:-;;;;;;;;;;-1:-1:-1;6374:1883:0;;;;;:::i;:::-;;:::i;3221:1673::-;;;;;;:::i;:::-;;:::i;908:142:5:-;;;;;;;;;;-1:-1:-1;908:142:5;;;;;:::i;:::-;;:::i;2000:211:4:-;;;;;;;;;;-1:-1:-1;2000:211:4;;;;;:::i;:::-;;:::i;1056:151:5:-;;;;;;;;;;-1:-1:-1;1056:151:5;;;;;:::i;:::-;;:::i;2314:198:6:-;;;;;;;;;;-1:-1:-1;2314:198:6;;;;;:::i;:::-;;:::i;6189:179:0:-;;;;;;;;;;-1:-1:-1;6189:179:0;;;;;:::i;:::-;;:::i;1334:278:4:-;1481:4;-1:-1:-1;;;;;;1504:61:4;;-1:-1:-1;;;1504:61:4;;:101;;;1569:36;1593:11;1569:23;:36::i;:::-;1497:108;1334:278;-1:-1:-1;;1334:278:4:o;2932:98:13:-;2986:13;3018:5;3011:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2932:98;:::o;5982:201:0:-;1334:13:6;:11;:13::i;:::-;6125:10:0::1;6087:22;:35;6110:11;6087:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;6087:35:0;:48;;:35;;:48:::1;::::0;:35;:48:::1;:::i;:::-;-1:-1:-1::0;6087:48:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;6150:26;6164:11;6150:26;;;;;;:::i;:::-;;;;;;;;5982:201:::0;;:::o;4407:167:13:-;4483:7;4502:23;4517:7;4502:14;:23::i;:::-;-1:-1:-1;4543:24:13;;;;:15;:24;;;;;;-1:-1:-1;;;;;4543:24:13;;4407:167::o;1618:178:4:-;1778:11;;-1:-1:-1;;;1778:11:4;;;;;;;;;;;5383:593:0;5577:36;1350:7;5577:15;:36;:::i;:::-;5566:8;:47;5562:78;;;5622:18;;-1:-1:-1;;;5622:18:0;;;;;;;;;;;5562:78;5655:54;5672:7;5681:8;5691:6;;5699:9;;5655:16;:54::i;:::-;5650:88;;5718:20;;-1:-1:-1;;;5718:20:0;;;;;;;;;;;5650:88;5781:16;;-1:-1:-1;;;;;5767:31:0;5749:15;5767:31;;;:13;:31;;;;;;;5799:19;;;;5749:15;;5767:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;5820:7;:15;;;5767:69;;;;;;;;;;;;5749:87;;5850:7;5861:1;5850:12;5846:50;;5871:25;;-1:-1:-1;;;5871:25:0;;;;;7122::30;;;7095:18;;5871:25:0;;;;;;;;5846:50;5907:13;;;;:4;:13;;;;;:22;5923:6;;5907:13;:22;:::i;:::-;-1:-1:-1;5945:24:0;;7122:25:30;;;5945:24:0;;7110:2:30;7095:18;5945:24:0;;;;;;;5552:424;5383:593;;;;;;:::o;5216:161::-;1334:13:6;:11;:13::i;:::-;5293:11:0::1;:28:::0;;-1:-1:-1;;;;;;5293:28:0::1;-1:-1:-1::0;;;;;5293:28:0;::::1;::::0;;::::1;::::0;;;5336:34:::1;::::0;3853:51:30;;;5336:34:0::1;::::0;3841:2:30;3826:18;5336:34:0::1;;;;;;;;5216:161:::0;:::o;1615:264:16:-;1712:7;1747:34;1775:5;1747:27;:34::i;:::-;1739:5;:42;1731:98;;;;-1:-1:-1;;;1731:98:16;;17877:2:30;1731:98:16;;;17859:21:30;17916:2;17896:18;;;17889:30;17955:34;17935:18;;;17928:62;-1:-1:-1;;;18006:18:30;;;17999:41;18057:19;;1731:98:16;17675:407:30;1731:98:16;-1:-1:-1;;;;;;1846:19:16;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1615:264::o;3387:195:12:-;-1:-1:-1;;;;;1898:6:12;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:12;;;;;;;:::i;:::-;1995:6;-1:-1:-1;;;;;1971:30:12;:20;-1:-1:-1;;;;;;;;;;;1536:65:9;-1:-1:-1;;;;;1536:65:9;;1457:151;1971:20:12;-1:-1:-1;;;;;1971:30:12;;1963:87;;;;-1:-1:-1;;;1963:87:12;;;;;;;:::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:12;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:12;;;;;;;:::i;:::-;1995:6;-1:-1:-1;;;;;1971:30:12;:20;-1:-1:-1;;;;;;;;;;;1536:65:9;-1:-1:-1;;;;;1536:65:9;;1457:151;1971:20:12;-1:-1:-1;;;;;1971:30:12;;1963:87;;;;-1:-1:-1;;;1963:87:12;;;;;;;:::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:16:-;2208:7;2243:41;2037:10;:17;;1950:111;2243:41;2235:5;:49;2227:106;;;;-1:-1:-1;;;2227:106:16;;19115:2:30;2227:106:16;;;19097:21:30;19154:2;19134:18;;;19127:30;19193:34;19173:18;;;19166:62;-1:-1:-1;;;19244:18:30;;;19237:42;19296:19;;2227:106:16;18913:408:30;2227:106:16;2350:10;2361:5;2350:17;;;;;;;;:::i;:::-;;;;;;;;;2343:24;;2133:241;;;:::o;3006:131:12:-;3084:7;2324:4;-1:-1:-1;;;;;2333:6:12;2316:23;;2308:92;;;;-1:-1:-1;;;2308:92:12;;19660:2:30;2308:92:12;;;19642:21:30;19699:2;19679:18;;;19672:30;19738:34;19718:18;;;19711:62;19809:26;19789:18;;;19782:54;19853:19;;2308:92:12;19458:420:30;2308:92:12;-1:-1:-1;;;;;;;;;;;;3006:131:12;:::o;4900:310:0:-;5007:10;4975:15;4993:25;;;:13;:25;;;;;4975:15;5019:11;4993:38;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;4993:38:0;;;:47;;;;;;;;;5065:10;5051:25;;:13;:25;;;;;;4993:47;;-1:-1:-1;;;5077:11:0;5051:38;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5051:38:0;;;:47;;;;;;;;:51;;;;5119:29;;;:20;:29;;;;;5112:36;;;5119:29;5112:36;;;;-1:-1:-1;5112:36:0;:::i;:::-;-1:-1:-1;5112:36:0;;;;;;;;;;;;;;5165:13;;;:4;:13;;;;;5158:20;;;:::i;:::-;5189:14;5195:7;5189:5;:14::i;:::-;4965:245;4900:310;;:::o;2651:219:13:-;2723:7;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:13;;2785:56;;;;-1:-1:-1;;;2785:56:13;;20085:2:30;2785:56:13;;;20067:21:30;20124:2;20104:18;;;20097:30;-1:-1:-1;;;20143:18:30;;;20136:54;20207:18;;2785:56:13;19883:348:30;2390:204:13;2462:7;-1:-1:-1;;;;;2489:19:13;;2481:73;;;;-1:-1:-1;;;2481:73:13;;20438:2:30;2481:73:13;;;20420:21:30;20477:2;20457:18;;;20450:30;20516:34;20496:18;;;20489:62;-1:-1:-1;;;20567:18:30;;;20560:39;20616:19;;2481:73:13;20236:405:30;2481:73:13;-1:-1:-1;;;;;;2571:16:13;;;;;:9;:16;;;;;;;2390:204::o;2064:101:6:-;1334:13;:11;:13::i;:::-;2128:30:::1;2155:1;2128:18;:30::i;:::-;2064:101::o:0;2722:358:0:-;3279:19:11;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:11;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:11;1713:19:19;:23;;;3387:66:11;;-1:-1:-1;3436:12:11;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:11;;20848:2:30;3325:201:11;;;20830:21:30;20887:2;20867:18;;;20860:30;20926:34;20906:18;;;20899:62;-1:-1:-1;;;20977:18:30;;;20970:44;21031:19;;3325:201:11;20646:410:30;3325:201:11;3536:12;:16;;-1:-1:-1;;3536:16:11;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:11;;;;;3562:65;2899:11:0::1;:26:::0;;-1:-1:-1;;;;;;2899:26:0::1;-1:-1:-1::0;;;;;2899:26:0;::::1;;::::0;;2935:16:::1;:14;:16::i;:::-;2961:24;:22;:24::i;:::-;2995:36;3018:4;3024:6;2995:22;:36::i;:::-;3041:32;3064:8;3041:22;:32::i;:::-;3651:14:11::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:11;;;3721:14;;-1:-1:-1;21213:36:30;;3721:14:11;;21201:2:30;21186:18;3721:14:11;;;;;;;3647:99;3269:483;2722:358:0;;;;:::o;3094:102:13:-;3150:13;3182:7;3175:14;;;;;:::i;6374:1883:0:-;7657:4:13;7266:16;;;:7;:16;;;;;;6439:13:0;;-1:-1:-1;;;;;7266:16:13;6464:55:0;;6494:25;;-1:-1:-1;;;6494:25:0;;;;;7122::30;;;7095:18;;6494:25:0;6976:177:30;6464:55:0;6530:18;6551:29;;;:20;:29;;;;;;;;6530:50;;;;;;;;;;-1:-1:-1;;;;;6530:50:0;;;;;;6551:29;;6530:50;;;;-1:-1:-1;;;6530:50:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;6530:50:0;;-1:-1:-1;;;;;6530:50:0;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;6530:50:0;;;-1:-1:-1;;6530:50:0;;;;;-1:-1:-1;;;;;6530:50:0;;;;;;;;;;;-1:-1:-1;;;6530:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6799:10;;;;6530:50;;-1:-1:-1;6530:50:0;;6646:1501;;6776:22;;6530:50;;6776:34;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:45;;6868:3;:13;;;6946:22;:34;6969:3;:10;;;6946:34;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:46;;7039:3;:13;;;7132:4;:13;7137:7;7132:13;;;;;;;;;;;7292:22;:34;7315:3;:10;;;7292:34;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:45;;7448:26;7456:3;:6;;;-1:-1:-1;;;;;7448:15:0;:24;:26::i;:::-;7561:30;7569:3;:10;;;-1:-1:-1;;;;;7561:19:0;:28;:30::i;:::-;7727:32;7735:3;:12;;;-1:-1:-1;;;;;7727:21:0;:30;:32::i;:::-;7872:33;7880:3;:13;;;-1:-1:-1;;;;;7872:22:0;:31;:33::i;:::-;7999:19;;7989:7;:29;:86;;8057:18;:7;:16;:18::i;:::-;7989:86;;;8021:33;8029:3;:13;;;-1:-1:-1;;;;;8021:22:0;:31;:33::i;:::-;6707:1416;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6646:24;:1501::i;:::-;6625:1522;;8245:4;8198:52;;;;;;;;:::i;:::-;;;;;;;;;;;;;8191:59;;;;6374:1883;;;:::o;3221:1673::-;3437:36;1350:7;3437:15;:36;:::i;:::-;3426:8;:47;3422:78;;;3482:18;;-1:-1:-1;;;3482:18:0;;;;;;;;;;;3422:78;3528:16;;-1:-1:-1;;;;;3514:31:0;;;;;:13;:31;;;;;;;3546:19;;;;3514:31;;;:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;3567:7;:15;;;3514:69;;;;;;;;;;;;3587:1;3514:74;3510:103;;3597:16;;-1:-1:-1;;;3597:16:0;;;;;;;;;;;3510:103;3628:51;3645:7;3654:8;3664:3;;3669:9;;3628:16;:51::i;:::-;3623:85;;3688:20;;-1:-1:-1;;;3688:20:0;;;;;;;;;;;3623:85;-1:-1:-1;;;;;3733:13:0;;3719:11;3733:13;;;:3;:13;;;;;;;3760:8;;;3756:48;;3777:27;;-1:-1:-1;;;3777:27:0;;-1:-1:-1;;;;;3871:32:30;;3777:27:0;;;3853:51:30;3826:18;;3777:27:0;3707:203:30;3756:48:0;3815:15;3833:13;2037:10:16;:17;;1950:111;3833:13:0;:17;;3849:1;3833:17;:::i;:::-;3907:15;;;;3887:36;;;;:19;:36;;;;;;;;3885:38;;;;;;3958:16;;-1:-1:-1;;;;;3944:31:0;;;:13;:31;;;;3976:19;;;;3815:35;;-1:-1:-1;3815:35:0;;3944:31;;3887:36;3944:52;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:69;3997:7;:15;;;3944:69;;;;;;;;;;;:79;;;;4065:322;;;;;;;;4086:7;:16;;;-1:-1:-1;;;;;4065:322:0;;;;;4116:7;:19;;;4065:322;;;;;;;;:::i;:::-;;;4156:14;;;;;-1:-1:-1;;;;;4065:322:0;;;;;;;;;4185:17;;;;;4065:322;;;;;4224:15;;;;;-1:-1:-1;;;;;4065:322:0;;;;;;;;;;4282:15;-1:-1:-1;4262:36:0;;;:19;:36;;;;;;4065:322;;;;;;;;;4321:15;4065:322;;;;;;;;;;4359:17;;;4065:322;;;;;;;;;4033:29;;;:20;:29;;;;:354;;;;-1:-1:-1;;;;;4033:354:0;;;-1:-1:-1;;;;;;4033:354:0;;;;;;;;;;:29;;;;-1:-1:-1;;;;;;4033:354:0;;-1:-1:-1;;;4033:354:0;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;4033:354:0;;;;;;-1:-1:-1;;;;;4033:354:0;;;-1:-1:-1;;;4033:354:0;-1:-1:-1;;;;;4033:354:0;;;;;;;;;;-1:-1:-1;4033:354:0;;;;;;;:::i;:::-;-1:-1:-1;4033:354:0;;;;;;;;-1:-1:-1;;;;;4033:354:0;;;-1:-1:-1;;;4033:354:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4397:13:0;;;:4;:13;;;;;:19;4413:3;;4397:13;:19;:::i;:::-;;4586:9;4599:1;4586:14;4582:179;;4602:8;;:49;;-1:-1:-1;;;;;4602:8:0;4625:10;4637:8;4647:3;4602:22;:49::i;:::-;4582:179;;;4683:3;4670:9;:16;4666:95;;4695:28;;-1:-1:-1;;;4695:28:0;;4708:9;4695:28;;;28704:25:30;28745:18;;;28738:34;;;28677:18;;4695:28:0;28530:248:30;4666:95:0;4738:8;;:23;;-1:-1:-1;;;;;4738:8:0;4757:3;4738:18;:23::i;:::-;4782:16;;4772:36;;4800:7;4772:9;:36::i;:::-;4871:7;:15;;;4850:7;:19;;;4824:63;;;;;;;;:::i;:::-;4832:16;;4824:63;;-1:-1:-1;;;;;4824:63:0;;;;;;4832:16;;4824:63;3412:1482;;3221:1673;;;;;;;:::o;908:142:5:-;1334:13:6;:11;:13::i;:::-;-1:-1:-1;;;;;984:10:5;::::1;;::::0;;;:3:::1;:10;::::0;;;;;;;;:19;;;1018:25;;28957:51:30;;;29024:18;;29017:34;;;1018:25:5::1;::::0;28930:18:30;1018:25:5::1;28783:274:30::0;2000:211:4;2170:4;2193:11;;-1:-1:-1;;;2193:11:4;;;;;;;;;;;1056:151:5;1334:13:6;:11;:13::i;:::-;1135:8:5::1;:22:::0;;-1:-1:-1;;;;;;1135:22:5::1;-1:-1:-1::0;;;;;1135:22:5;::::1;::::0;;::::1;::::0;;;1172:28:::1;::::0;3853:51:30;;;1172:28:5::1;::::0;3841:2:30;3826:18;1172:28:5::1;3707:203:30::0;2314:198:6;1334:13;:11;:13::i;:::-;-1:-1:-1;;;;;2402:22:6;::::1;2394:73;;;::::0;-1:-1:-1;;;2394:73:6;;29480:2:30;2394:73:6::1;::::0;::::1;29462:21:30::0;29519:2;29499:18;;;29492:30;29558:34;29538:18;;;29531:62;-1:-1:-1;;;29609:18:30;;;29602:36;29655:19;;2394:73:6::1;29278:402:30::0;2394:73:6::1;2477:28;2496:8;2477:18;:28::i;6189:179:0:-:0;-1:-1:-1;;;;;6317:22:0;;6286:12;6317:22;;;:13;:22;;;;;6286:12;6340:11;6317:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;:39;6353:2;6317:39;;;;;;;;;;;;6360:1;6317:44;;6310:51;;6189:179;;;;;:::o;1281:255:16:-;1405:4;-1:-1:-1;;;;;;1428:61:16;;-1:-1:-1;;;1428:61:16;;:101;;;1493:36;1517:11;1493:23;:36::i;1599:130:6:-;1513:6;;-1:-1:-1;;;;;1513:6:6;929:10:21;1662:23:6;1654:68;;;;-1:-1:-1;;;1654:68:6;;29887:2:30;1654:68:6;;;29869:21:30;;;29906:18;;;29899:30;29965:34;29945:18;;;29938:62;30017:18;;1654:68:6;29685:356:30;13778:133:13;7657:4;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:13;13851:53;;;;-1:-1:-1;;;13851:53:13;;20085:2:30;13851:53:13;;;20067:21:30;20124:2;20104:18;;;20097:30;-1:-1:-1;;;20143:18:30;;;20136:54;20207:18;;13851:53:13;19883:348:30;8459:743:0;8641:4;8681:2;8661:22;;8657:55;;8692:20;;-1:-1:-1;;;8692:20:0;;;;;;;;;;;8657:55;8722:15;8740:397;8791:7;:16;;;8825:7;:19;;;8862:7;:14;;;8894:7;:15;;;8927:7;:17;;;8962:7;:17;;;8997:8;9023:3;;9044:13;9083:4;8763:339;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;8740:372;;;;;;7411:34:24;7211:15;7398:48;;;7466:4;7459:18;;;;7517:4;7501:21;;;7142:396;8740:397:0;9184:11;;9154:26;;;;;;;;;;;;;;;;;;;;;;8722:415;;-1:-1:-1;;;;;;9184:11:0;;;;9154:26;;9170:9;;;;;;9154:26;;9170:9;;;;9154:26;;;;;;;;;-1:-1:-1;9154:7:0;;:26;-1:-1:-1;;9154:15:0;:26;-1:-1:-1;9154:26:0:i;:::-;-1:-1:-1;;;;;9154:41:0;;;8459:743;-1:-1:-1;;;;;;;;8459:743:0:o;8312:66::-;1334:13:6;:11;:13::i;2820:944:9:-;971:66;3236:59;;;3232:526;;;3311:37;3330:17;3311:18;:37::i;3232:526::-;3412:17;-1:-1:-1;;;;;3383:61:9;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3383:63:9;;;;;;;;-1:-1:-1;;3383:63:9;;;;;;;;;;;;:::i;:::-;;;3379:302;;3610:56;;-1:-1:-1;;;3610:56:9;;31667:2:30;3610:56:9;;;31649:21:30;31706:2;31686:18;;;31679:30;31745:34;31725:18;;;31718:62;-1:-1:-1;;;31796:18:30;;;31789:44;31850:19;;3610:56:9;31465:410:30;3379:302:9;-1:-1:-1;;;;;;;;;;;3496:28:9;;3488:82;;;;-1:-1:-1;;;3488:82:9;;32082:2:30;3488:82:9;;;32064:21:30;32121:2;32101:18;;;32094:30;32160:34;32140:18;;;32133:62;-1:-1:-1;;;32211:18:30;;;32204:39;32260:19;;3488:82:9;31880:405:30;3488:82:9;3447:138;3694:53;3712:17;3731:4;3737:9;3694:17;:53::i;10654:784:13:-;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:13;;;;;;-1:-1:-1;;;;;11254:16:13;;;;;:9;:16;;;;;:21;;-1:-1:-1;;11254:21:13;;;11302:16;;;:7;:16;;;;;;11295:23;;;;;;;11334:36;10927:42;;-1:-1:-1;11030:7:13;;11334:36;;11014:24;;11334:36;3901:220:12;;:::o;2666:187:6:-;2758:6;;;-1:-1:-1;;;;;2774:17:6;;;-1:-1:-1;;;;;;2774:17:6;;;;;;;2806:40;;2758:6;;;2774:17;2758:6;;2806:40;;2739:16;;2806:40;2729:124;2666:187;:::o;1003:95::-;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;1065:26:6::1;:24;:26::i;1042:67:12:-:0;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;1097:183:4:-;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;1209:29:4::1;1223:5;1230:7;1209:13;:29::i;:::-;1248:25;:23;:25::i;780:122:5:-:0;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;875:8:5::1;:20:::0;;-1:-1:-1;;;;;;875:20:5::1;-1:-1:-1::0;;;;;875:20:5;;;::::1;::::0;;;::::1;::::0;;780:122::o;480:707:23:-;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:23;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;671:18:23;-1:-1:-1;648:41:23;-1:-1:-1;809:28:23;;;825:2;809:28;864:280;-1:-1:-1;;895:5:23;-1:-1:-1;;;1029:2:23;1018:14;;1013:30;895:5;1000:44;1088:2;1079:11;;;-1:-1:-1;1108:21:23;864:280;1108:21;-1:-1:-1;1164:6:23;480:707;-1:-1:-1;;;480:707:23:o;516:3026:20:-;574:13;806:4;:11;821:1;806:16;802:31;;-1:-1:-1;;824:9:20;;;;;;;;;-1:-1:-1;824:9:20;;;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:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1337:39:20;;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:20;;516:3026;-1:-1:-1;;;;;516:3026:20:o;1944:205:3:-;2048:44;;-1:-1:-1;;;2048:44:3;;-1:-1:-1;;;;;33487:15:30;;;2048:44:3;;;33469:34:30;33539:15;;;33519:18;;;33512:43;33571:18;;;33564:34;;;2048:26:3;;;;;33404:18:30;;2048:44:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2043:99;;2101:41;;-1:-1:-1;;;2101:41:3;;2116:10;2101:41;;;34071:34:30;2136:4:3;34121:18:30;;;34114:43;34006:18;;2101:41:3;33859:304:30;2043:99:3;1944:205;;;;:::o;806:260::-;947:12;965:9;-1:-1:-1;;;;;965:14:3;988:6;965:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;946:54;;;1015:7;1010:49;;1031:28;;-1:-1:-1;;;1031:28:3;;-1:-1:-1;;;;;3871:32:30;;1031:28:3;;;3853:51:30;3826:18;;1031:28:3;3707:203:30;8478:108:13;8553:26;8563:2;8567:7;8553:26;;;;;;;;;;;;:9;:26::i;1987:344::-;2111:4;-1:-1:-1;;;;;;2146:51:13;;-1:-1:-1;;;2146:51:13;;:126;;-1:-1:-1;;;;;;;2213:59:13;;-1:-1:-1;;;2213:59:13;2146:126;:178;;;-1:-1:-1;;;;;;;;;;1168:51:25;;;2288:36:13;1060:166:25;3683:227:24;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:24;3683:227;-1:-1:-1;;;3683:227:24:o;1699:281:9:-;-1:-1:-1;;;;;1713:19:19;;;1772:106:9;;;;-1:-1:-1;;;1772:106:9;;34580:2:30;1772:106:9;;;34562:21:30;34619:2;34599:18;;;34592:30;34658:34;34638:18;;;34631:62;-1:-1:-1;;;34709:18:30;;;34702:43;34762:19;;1772:106:9;34378:409:30;1772:106:9;-1:-1:-1;;;;;;;;;;;1888:85:9;;-1:-1:-1;;;;;;1888:85:9;-1:-1:-1;;;;;1888:85:9;;;;;;;;;;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;2954:287:4:-;3173:61;3200:4;3206:2;3210:12;3224:9;3173:26;:61::i;1104:111:6:-;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;1176:32:6::1;929:10:21::0;1176:18:6::1;:32::i;1605:149:13:-:0;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;1708:39:13::1;1732:5;1739:7;1708:23;:39::i;10150:916:27:-:0;10203:7;;-1:-1:-1;;;10278:17:27;;10274:103;;-1:-1:-1;;;10315:17:27;;;-1:-1:-1;10360:2:27;10350:12;10274:103;10403:8;10394:5;:17;10390:103;;10440:8;10431:17;;;-1:-1:-1;10476:2:27;10466:12;10390:103;10519:8;10510:5;:17;10506:103;;10556:8;10547:17;;;-1:-1:-1;10592:2:27;10582:12;10506:103;10635:7;10626:5;:16;10622:100;;10671:7;10662:16;;;-1:-1:-1;10706:1:27;10696:11;10622:100;10748:7;10739:5;:16;10735:100;;10784:7;10775:16;;;-1:-1:-1;10819:1:27;10809:11;10735:100;10861:7;10852:5;:16;10848:100;;10897:7;10888:16;;;-1:-1:-1;10932:1:27;10922:11;10848:100;10974:7;10965:5;:16;10961:66;;11011:1;11001:11;11053:6;10150:916;-1:-1:-1;;10150:916:27:o;8807:279:13:-;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:13;;;;;;;:::i;2167:730:24:-;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:24;;-1:-1:-1;2844:35:24;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:24;;35413:2:30;810:34:24;;;35395:21:30;35452:2;35432:18;;;35425:30;35491:26;35471:18;;;35464:54;35535:18;;810:34:24;35211:348:30;752:345:24;874:35;865:5;:44;;;;;;;;:::i;:::-;;861:236;;925:41;;-1:-1:-1;;;925:41:24;;35766:2:30;925:41:24;;;35748:21:30;35805:2;35785:18;;;35778:30;35844:33;35824:18;;;35817:61;35895:18;;925:41:24;35564:355:30;861:236:24;996:30;987:5;:39;;;;;;;;:::i;:::-;;983:114;;1042:44;;-1:-1:-1;;;1042:44:24;;36126:2:30;1042:44:24;;;36108:21:30;36165:2;36145:18;;;36138:30;36204:34;36184:18;;;36177:62;-1:-1:-1;;;36255:18:30;;;36248:32;36297:19;;1042:44:24;35924:398:30;2086:152:9;2152:37;2171:17;2152:18;:37::i;:::-;2204:27;;-1:-1:-1;;;;;2204:27:9;;;;;;;;2086:152;:::o;6685:198:19:-;6768:12;6799:77;6820:6;6828:4;6799:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6792:84;6685:198;-1:-1:-1;;;6685:198:19:o;2443:890:16:-;2702:1;2690:9;:13;2686:219;;;2831:63;;-1:-1:-1;;;2831:63:16;;36529:2:30;2831:63:16;;;36511:21:30;36568:2;36548:18;;;36541:30;36607:34;36587:18;;;36580:62;-1:-1:-1;;;36658:18:30;;;36651:51;36719:19;;2831:63:16;36327:417:30;2686:219:16;2933:12;-1:-1:-1;;;;;2960:18:16;;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:16;:4;-1:-1:-1;;;;;3055:10:16;;3051:88;;3081:47;3114:4;3120:7;3081:32;:47::i;:::-;-1:-1:-1;;;;;3152:16:16;;3148:179;;3184:45;3221:7;3184:36;:45::i;:::-;3148:179;;;3256:4;-1:-1:-1;;;;;3250:10:16;:2;-1:-1:-1;;;;;3250:10:16;;3246:81;;3276:40;3304:2;3308:7;3276:27;:40::i;1760:160:13:-;5374:13:11;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:11;;;;;;;:::i;:::-;1873:5:13::1;:13;1881:5:::0;1873;:13:::1;:::i;:::-;-1:-1:-1::0;1896:7:13::1;:17;1906:7:::0;1896;:17:::1;:::i;9408:920::-:0;-1:-1:-1;;;;;9487:16:13;;9479:61;;;;-1:-1:-1;;;9479:61:13;;36951:2:30;9479:61:13;;;36933:21:30;;;36970:18;;;36963:30;37029:34;37009:18;;;37002:62;37081:18;;9479:61:13;36749:356:30;9479:61:13;7657:4;7266:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7266:16:13;7680:31;9550:58;;;;-1:-1:-1;;;9550:58:13;;37312:2:30;9550:58:13;;;37294:21:30;37351:2;37331:18;;;37324:30;37390;37370:18;;;37363:58;37438:18;;9550:58:13;37110:352:30;9550:58:13;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:13;7680:31;9754:58;;;;-1:-1:-1;;;9754:58:13;;37312:2:30;9754:58:13;;;37294:21:30;37351:2;37331:18;;;37324:30;37390;37370:18;;;37363:58;37438:18;;9754:58:13;37110:352:30;9754:58:13;-1:-1:-1;;;;;10154:13:13;;;;;;:9;:13;;;;;;;;:18;;10171:1;10154:18;;;10193:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10193:21:13;;;;;10230:33;10201:7;;10154:13;;10230:33;;10154:13;;10230:33;3901:220:12;;:::o;14463:853:13:-;14612:4;-1:-1:-1;;;;;14632:13:13;;1713:19:19;:23;14628:682:13;;14667:82;;-1:-1:-1;;;14667:82:13;;-1:-1:-1;;;;;14667:47:13;;;;;:82;;929:10:21;;14729:4:13;;14735:7;;14744:4;;14667:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14667:82:13;;;;;;;;-1:-1:-1;;14667:82:13;;;;;;;;;;;;:::i;:::-;;;14663:595;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14927:6;:13;14944:1;14927:18;14923:321;;14969:60;;-1:-1:-1;;;14969:60:13;;;;;;;:::i;14923:321::-;15196:6;15190:13;15181:6;15177:2;15173:15;15166:38;14663:595;-1:-1:-1;;;;;;14799:62:13;-1:-1:-1;;;14799:62:13;;-1:-1:-1;14792:69:13;;14628:682;-1:-1:-1;15295:4:13;14628:682;14463:853;;;;;;:::o;5031:1456:24:-;5119:7;;6043:66;6030:79;;6026:161;;;-1:-1:-1;6141:1:24;;-1:-1:-1;6145:30:24;6125:51;;6026:161;6298:24;;;6281:14;6298:24;;;;;;;;;38453:25:30;;;38526:4;38514:17;;38494:18;;;38487:45;;;;38548:18;;;38541:34;;;38591:18;;;38584:34;;;6298:24:24;;38425:19:30;;6298:24:24;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6298:24:24;;-1:-1:-1;;6298:24:24;;;-1:-1:-1;;;;;;;6336:20:24;;6332:101;;6388:1;6392:29;6372:50;;;;;;;6332:101;6451:6;-1:-1:-1;6459:20:24;;-1:-1:-1;5031:1456:24;;;;;;;;:::o;7069:325:19:-;7210:12;7235;7249:23;7276:6;-1:-1:-1;;;;;7276:19:19;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:19:o;4828:981:16:-;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:16;;;5309:323;;-1:-1:-1;;;;;5379:18:16;;5357:19;5379:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5428:30;;;;;;:44;;;5544:30;;:17;:30;;;;;:43;;;5309:323;-1:-1:-1;5725:26:16;;;;:17;:26;;;;;;;;5718:33;;;-1:-1:-1;;;;;5768:18:16;;;;;: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:16;;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:16;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3813:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3627:228:16:o;7682:628:19:-;7862:12;7890:7;7886:418;;;7917:10;:17;7938:1;7917:22;7913:286;;-1:-1:-1;;;;;1713:19:19;;;8124:60;;;;-1:-1:-1;;;8124:60:19;;39255:2:30;8124:60:19;;;39237:21:30;39294:2;39274:18;;;39267:30;39333:31;39313:18;;;39306:59;39382:18;;8124:60:19;39053:353:30;8124:60:19;-1:-1:-1;8219:10:19;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:19;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:30:-;-1:-1:-1;;;;;;88:32:30;;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:30;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:30;1077:39;;;;1118:4;1073:50;;847:282;-1:-1:-1;;847:282:30: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:30;1868;1865:10;1862:36;;;1878:18;;:::i;:::-;1953:2;1947:9;1921:2;2007:13;;-1:-1:-1;;2003:22:30;;;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:30;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:30;;3413:180;-1:-1:-1;3413:180:30:o;3915:131::-;-1:-1:-1;;;;;3990:31:30;;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:30: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:30;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:30;;-1:-1:-1;;;;;5532:30:30;;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:30;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:30;-1:-1:-1;6514:2:30;6499:18;;6486:32;;-1:-1:-1;6530:16:30;;;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:30;;-1:-1:-1;5696:1023:30;;6678:8;;5696:1023;-1:-1:-1;;;5696:1023:30: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:30;7470:18;;7457:32;7498:33;7457:32;7498:33;:::i;:::-;7158:456;;7550:7;;-1:-1:-1;;;7604:2:30;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:30;7922:18;;7909:32;-1:-1:-1;;;;;7953:30:30;;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;8262:278::-;8345:6;8353;8406:2;8394:9;8385:7;8381:23;8377:32;8374:52;;;8422:1;8419;8412:12;8374:52;8445:38;8473:9;8445:38;:::i;8769:828::-;8883:6;8891;8899;8907;8960:3;8948:9;8939:7;8935:23;8931:33;8928:53;;;8977:1;8974;8967:12;8928:53;9017:9;9004:23;-1:-1:-1;;;;;9087:2:30;9079:6;9076:14;9073:34;;;9103:1;9100;9093:12;9073:34;9126:50;9168:7;9159:6;9148:9;9144:22;9126:50;:::i;:::-;9116:60;;9229:2;9218:9;9214:18;9201:32;9185:48;;9258:2;9248:8;9245:16;9242:36;;;9274:1;9271;9264:12;9242:36;;9297:52;9341:7;9330:8;9319:9;9315:24;9297:52;:::i;:::-;9287:62;;;9399:2;9388:9;9384:18;9371:32;9412:31;9437:5;9412:31;:::i;:::-;9462:5;-1:-1:-1;9519:2:30;9504:18;;9491:32;9532:33;9491:32;9532:33;:::i;:::-;8769:828;;;;-1:-1:-1;8769:828:30;;-1:-1:-1;;8769:828:30:o;9602:118::-;9688:5;9681:13;9674:21;9667:5;9664:32;9654:60;;9710:1;9707;9700:12;9725:382;9790:6;9798;9851:2;9839:9;9830:7;9826:23;9822:32;9819:52;;;9867:1;9864;9857:12;9819:52;9906:9;9893:23;9925:31;9950:5;9925:31;:::i;:::-;9975:5;-1:-1:-1;10032:2:30;10017:18;;10004:32;10045:30;10004:32;10045:30;:::i;:::-;10094:7;10084:17;;;9725:382;;;;;:::o;10112:666::-;10207:6;10215;10223;10231;10284:3;10272:9;10263:7;10259:23;10255:33;10252:53;;;10301:1;10298;10291:12;10252:53;10340:9;10327:23;10359:31;10384:5;10359:31;:::i;:::-;10409:5;-1:-1:-1;10466:2:30;10451:18;;10438:32;10479:33;10438:32;10479:33;:::i;:::-;10531:7;-1:-1:-1;10585:2:30;10570:18;;10557:32;;-1:-1:-1;10640:2:30;10625:18;;10612:32;-1:-1:-1;;;;;10656:30:30;;10653:50;;;10699:1;10696;10689:12;10653:50;10722;10764:7;10755:6;10744:9;10740:22;10722:50;:::i;:::-;10712:60;;;10112:666;;;;;;;:::o;10783:1159::-;10931:6;10939;10947;10955;10963;10971;10979;11032:3;11020:9;11011:7;11007:23;11003:33;11000:53;;;11049:1;11046;11039:12;11000:53;11088:9;11075:23;11107:31;11132:5;11107:31;:::i;:::-;11157:5;-1:-1:-1;11213:2:30;11198:18;;11185:32;-1:-1:-1;;;;;11266:14:30;;;11263:34;;;11293:1;11290;11283:12;11263:34;11316:64;11372:7;11363:6;11352:9;11348:22;11316:64;:::i;:::-;11306:74;;11427:2;11416:9;11412:18;11399:32;11389:42;;11484:2;11473:9;11469:18;11456:32;11440:48;;11513:2;11503:8;11500:16;11497:36;;;11529:1;11526;11519:12;11497:36;11568:61;11621:7;11610:8;11599:9;11595:24;11568:61;:::i;:::-;11648:8;;-1:-1:-1;11542:87:30;-1:-1:-1;11736:3:30;11721:19;;11708:33;;-1:-1:-1;11753:16:30;;;11750:36;;;11782:1;11779;11772:12;11750:36;;11821:61;11874:7;11863:8;11852:9;11848:24;11821:61;:::i;:::-;10783:1159;;;;-1:-1:-1;10783:1159:30;;-1:-1:-1;10783:1159:30;;;;11795:87;;-1:-1:-1;;;10783:1159:30:o;11947:388::-;12015:6;12023;12076:2;12064:9;12055:7;12051:23;12047:32;12044:52;;;12092:1;12089;12082:12;12044:52;12131:9;12118:23;12150:31;12175:5;12150:31;:::i;:::-;12200:5;-1:-1:-1;12257:2:30;12242:18;;12229:32;12270:33;12229:32;12270:33;:::i;12600:413::-;12692:6;12700;12708;12761:2;12749:9;12740:7;12736:23;12732:32;12729:52;;;12777:1;12774;12767:12;12729:52;12816:9;12803:23;12835:31;12860:5;12835:31;:::i;:::-;12885:5;-1:-1:-1;12909:47:30;12952:2;12937:18;;12909:47;:::i;:::-;12899:57;;13003:2;12992:9;12988:18;12975:32;12965:42;;12600:413;;;;;:::o;13018:380::-;13097:1;13093:12;;;;13140;;;13161:61;;13215:4;13207:6;13203:17;13193:27;;13161:61;13268:2;13260:6;13257:14;13237:18;13234:38;13231:161;;13314:10;13309:3;13305:20;13302:1;13295:31;13349:4;13346:1;13339:15;13377:4;13374:1;13367:15;13231:161;;13018:380;;;:::o;13403:127::-;13464:10;13459:3;13455:20;13452:1;13445:31;13495:4;13492:1;13485:15;13519:4;13516:1;13509:15;13661:545;13763:2;13758:3;13755:11;13752:448;;;13799:1;13824:5;13820:2;13813:17;13869:4;13865:2;13855:19;13939:2;13927:10;13923:19;13920:1;13916:27;13910:4;13906:38;13975:4;13963:10;13960:20;13957:47;;;-1:-1:-1;13998:4:30;13957:47;14053:2;14048:3;14044:12;14041:1;14037:20;14031:4;14027:31;14017:41;;14108:82;14126:2;14119:5;14116:13;14108:82;;;14171:17;;;14152:1;14141:13;14108:82;;;14112:3;;;13661:545;;;:::o;14382:1352::-;14508:3;14502:10;-1:-1:-1;;;;;14527:6:30;14524:30;14521:56;;;14557:18;;:::i;:::-;14586:97;14676:6;14636:38;14668:4;14662:11;14636:38;:::i;:::-;14630:4;14586:97;:::i;:::-;14738:4;;14802:2;14791:14;;14819:1;14814:663;;;;15521:1;15538:6;15535:89;;;-1:-1:-1;15590:19:30;;;15584:26;15535:89;-1:-1:-1;;14339:1:30;14335:11;;;14331:24;14327:29;14317:40;14363:1;14359:11;;;14314:57;15637:81;;14784:944;;14814:663;13608:1;13601:14;;;13645:4;13632:18;;-1:-1:-1;;14850:20:30;;;14968:236;14982:7;14979:1;14976:14;14968:236;;;15071:19;;;15065:26;15050:42;;15163:27;;;;15131:1;15119:14;;;;14998:19;;14968:236;;;14972:3;15232:6;15223:7;15220:19;15217:201;;;15293:19;;;15287:26;-1:-1:-1;;15376:1:30;15372:14;;;15388:3;15368:24;15364:37;15360:42;15345:58;15330:74;;15217:201;-1:-1:-1;;;;;15464:1:30;15448:14;;;15444:22;15431:36;;-1:-1:-1;14382:1352:30:o;15739:239::-;15822:1;15815:5;15812:12;15802:143;;15867:10;15862:3;15858:20;15855:1;15848:31;15902:4;15899:1;15892:15;15930:4;15927:1;15920:15;15802:143;15954:18;;15739:239::o;15983:211::-;16130:2;16115:18;;16142:46;16119:9;16170:6;16142:46;:::i;16199:127::-;16260:10;16255:3;16251:20;16248:1;16241:31;16291:4;16288:1;16281:15;16315:4;16312:1;16305:15;16331:128;16398:9;;;16419:11;;;16416:37;;;16433:18;;:::i;16464:1206::-;-1:-1:-1;;;;;16583:3:30;16580:27;16577:53;;;16610:18;;:::i;:::-;16639:94;16729:3;16689:38;16721:4;16715:11;16689:38;:::i;:::-;16683:4;16639:94;:::i;:::-;16759:1;16784:2;16779:3;16776:11;16801:1;16796:616;;;;17456:1;17473:3;17470:93;;;-1:-1:-1;17529:19:30;;;17516:33;17470:93;-1:-1:-1;;14339:1:30;14335:11;;;14331:24;14327:29;14317:40;14363:1;14359:11;;;14314:57;17576:78;;16769:895;;16796:616;13608:1;13601:14;;;13645:4;13632:18;;-1:-1:-1;;16832:17:30;;;16933:9;16955:229;16969:7;16966:1;16963:14;16955:229;;;17058:19;;;17045:33;17030:49;;17165:4;17150:20;;;;17118:1;17106:14;;;;16985:12;16955:229;;;16959:3;17212;17203:7;17200:16;17197:159;;;17336:1;17332:6;17326:3;17320;17317:1;17313:11;17309:21;17305:34;17301:39;17288:9;17283:3;17279:19;17266:33;17262:79;17254:6;17247:95;17197:159;;;17399:1;17393:3;17390:1;17386:11;17382:19;17376:4;17369:33;16769:895;;16464:1206;;;:::o;18087:408::-;18289:2;18271:21;;;18328:2;18308:18;;;18301:30;18367:34;18362:2;18347:18;;18340:62;-1:-1:-1;;;18433:2:30;18418:18;;18411:42;18485:3;18470:19;;18087:408::o;18500:::-;18702:2;18684:21;;;18741:2;18721:18;;;18714:30;18780:34;18775:2;18760:18;;18753:62;-1:-1:-1;;;18846:2:30;18831:18;;18824:42;18898:3;18883:19;;18500:408::o;19326:127::-;19387:10;19382:3;19378:20;19375:1;19368:31;19418:4;19415:1;19408:15;19442:4;19439:1;19432:15;21374:722;21424:3;21465:5;21459:12;21494:36;21520:9;21494:36;:::i;:::-;21549:1;21566:18;;;21593:133;;;;21740:1;21735:355;;;;21559:531;;21593:133;-1:-1:-1;;21626:24:30;;21614:37;;21699:14;;21692:22;21680:35;;21671:45;;;-1:-1:-1;21593:133:30;;21735:355;21766:5;21763:1;21756:16;21795:4;21840:2;21837:1;21827:16;21865:1;21879:165;21893:6;21890:1;21887:13;21879:165;;;21971:14;;21958:11;;;21951:35;22014:16;;;;21908:10;;21879:165;;;21883:3;;;22073:6;22068:3;22064:16;22057:23;;21559:531;;;;;21374:722;;;;:::o;22174:198::-;22216:3;22254:5;22248:12;22269:65;22327:6;22322:3;22315:4;22308:5;22304:16;22269:65;:::i;:::-;22350:16;;;;;22174:198;-1:-1:-1;;22174:198:30:o;24544:3395::-;-1:-1:-1;;;21318:45:30;;26647:3;26721:47;26764:2;26759:3;26755:12;26747:6;26721:47;:::i;:::-;-1:-1:-1;;;22151:16:30;;26835:40;26872:1;26865:5;26861:13;26853:6;26835:40;:::i;:::-;-1:-1:-1;;;22435:63:30;;26822:53;-1:-1:-1;26942:49:30;26987:2;26980:5;26976:14;26968:6;26942:49;:::i;:::-;-1:-1:-1;;;22151:16:30;;26929:62;-1:-1:-1;27058:106:30;27092:71;27122:40;27159:1;27152:5;27148:13;27140:6;27122:40;:::i;:::-;22586:66;22574:79;;-1:-1:-1;;;22678:2:30;22669:12;;22662:26;22713:2;22704:12;;22509:213;27092:71;27084:6;27058:106;:::i;:::-;-1:-1:-1;;;22785:61:30;;27045:119;-1:-1:-1;22927:66:30;27259:2;27248:14;;22915:79;-1:-1:-1;;;27313:2:30;27302:14;;23063:47;27339:49;27384:2;27377:5;27373:14;27365:6;27339:49;:::i;:::-;23191:66;23179:79;;27326:62;-1:-1:-1;;;;27483:2:30;27472:14;;23063:47;27509:99;27535:72;27565:41;27602:2;27595:5;27591:14;27583:6;27565:41;:::i;:::-;23346:66;23334:79;;-1:-1:-1;;;23438:2:30;23429:12;;23422:52;23499:2;23490:12;;23269:239;27535:72;27527:6;27509:99;:::i;:::-;23583:66;23571:79;;27496:112;-1:-1:-1;23738:66:30;27850:2;27839:14;;23726:79;-1:-1:-1;;;23821:12:30;;;23814:26;27675:184;27702:156;27727:130;27753:103;27783:72;23856:12;;;27801:6;27783:72;:::i;:::-;23956:66;23944:79;;24053:66;24048:2;24039:12;;24032:88;-1:-1:-1;;;24145:2:30;24136:12;;24129:37;24191:2;24182:12;;23879:321;27727:130;24277:66;24265:79;;-1:-1:-1;;;24369:2:30;24360:12;;24353:46;24424:2;24415:12;;24205:228;27702:156;27693:7;27675:184;:::i;:::-;-1:-1:-1;;;24496:37:30;;27931:1;27920:13;;;-1:-1:-1;;;;;;;;;;;;;;24544:3395:30:o;27944:451::-;28196:31;28191:3;28184:44;28166:3;28257:6;28251:13;28273:75;28341:6;28336:2;28331:3;28327:12;28320:4;28312:6;28308:17;28273:75;:::i;:::-;28368:16;;;;28386:2;28364:25;;27944:451;-1:-1:-1;;27944:451:30:o;28400:125::-;28465:9;;;28486:10;;;28483:36;;;28499:18;;:::i;30046:1225::-;-1:-1:-1;;;;;30513:32:30;;30495:51;;30454:4;30483:3;30555:55;30606:2;30591:18;;30583:6;30555:55;:::i;:::-;30646:6;30641:2;30630:9;30626:18;30619:34;30689:6;30684:2;30673:9;30669:18;30662:34;30733:2;30727:3;30716:9;30712:19;30705:31;30759:56;30811:2;30800:9;30796:18;30788:6;30759:56;:::i;:::-;30745:70;;30852:6;30846:3;30835:9;30831:19;30824:35;30896:6;30890:3;30879:9;30875:19;30868:35;30952:9;30944:6;30940:22;30934:3;30923:9;30919:19;30912:51;30987:6;30979;30972:22;31041:6;31033;31028:2;31020:6;31016:15;31003:45;31094:1;31089:2;31080:6;31072;31068:19;31064:28;31057:39;31161:2;31154;31150:7;31145:2;31137:6;31133:15;31129:29;31121:6;31117:42;31113:51;31105:59;;;31201:6;31195:3;31184:9;31180:19;31173:35;31217:48;31260:3;31249:9;31245:19;31236:7;-1:-1:-1;;;;;3664:31:30;3652:44;;3598:104;31217:48;30046:1225;;;;;;;;;;;;;;:::o;31276:184::-;31346:6;31399:2;31387:9;31378:7;31374:23;31370:32;31367:52;;;31415:1;31412;31405:12;31367:52;-1:-1:-1;31438:16:30;;31276:184;-1:-1:-1;31276:184:30:o;32290:407::-;32492:2;32474:21;;;32531:2;32511:18;;;32504:30;32570:34;32565:2;32550:18;;32543:62;-1:-1:-1;;;32636:2:30;32621:18;;32614:41;32687:3;32672:19;;32290:407::o;32834:217::-;32874:1;32900;32890:132;;32944:10;32939:3;32935:20;32932:1;32925:31;32979:4;32976:1;32969:15;33007:4;33004:1;32997:15;32890:132;-1:-1:-1;33036:9:30;;32834:217::o;33056:168::-;33129:9;;;33160;;33177:15;;;33171:22;;33157:37;33147:71;;33198:18;;:::i;33609:245::-;33676:6;33729:2;33717:9;33708:7;33704:23;33700:32;33697:52;;;33745:1;33742;33735:12;33697:52;33777:9;33771:16;33796:28;33818:5;33796:28;:::i;34792:414::-;34994:2;34976:21;;;35033:2;35013:18;;;35006:30;35072:34;35067:2;35052:18;;35045:62;-1:-1:-1;;;35138:2:30;35123:18;;35116:48;35196:3;35181:19;;34792:414::o;37467:500::-;-1:-1:-1;;;;;37736:15:30;;;37718:34;;37788:15;;37783:2;37768:18;;37761:43;37835:2;37820:18;;37813:34;;;37883:3;37878:2;37863:18;;37856:31;;;37661:4;;37904:57;;37941:19;;37933:6;37904:57;:::i;37972:249::-;38041:6;38094:2;38082:9;38073:7;38069:23;38065:32;38062:52;;;38110:1;38107;38100:12;38062:52;38142:9;38136:16;38161:30;38185:5;38161:30;:::i;38629:287::-;38758:3;38796:6;38790:13;38812:66;38871:6;38866:3;38859:4;38851:6;38847:17;38812:66;:::i;:::-;38894:16;;;;;38629:287;-1:-1:-1;;38629:287:30:o;38921:127::-;38982:10;38977:3;38973:20;38970:1;38963:31;39013:4;39010:1;39003:15;39037:4;39034:1;39027:15
Swarm Source
ipfs://a9eb1fd32ab9fb079174c721408e8abe1c134ec2b0edd03a8cfbae9f93235573
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.