Source Code
Overview
ETH Balance
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 24604674 | 101 days ago | 0 ETH | ||||
| 24604674 | 101 days ago | 0 ETH | ||||
| 24604647 | 101 days ago | 0 ETH | ||||
| 24604647 | 101 days ago | 0 ETH | ||||
| 24604623 | 101 days ago | 0 ETH | ||||
| 24604623 | 101 days ago | 0 ETH | ||||
| 24273444 | 110 days ago | 0 ETH | ||||
| 24273444 | 110 days ago | 0 ETH | ||||
| 23266731 | 134 days ago | 0 ETH | ||||
| 23266731 | 134 days ago | 0 ETH | ||||
| 23115472 | 138 days ago | 0 ETH | ||||
| 23115472 | 138 days ago | 0 ETH | ||||
| 22741493 | 147 days ago | 0 ETH | ||||
| 22741493 | 147 days ago | 0 ETH | ||||
| 22712546 | 148 days ago | 0 ETH | ||||
| 22712546 | 148 days ago | 0 ETH | ||||
| 22465323 | 154 days ago | 0 ETH | ||||
| 22465323 | 154 days ago | 0 ETH | ||||
| 22462035 | 154 days ago | 0 ETH | ||||
| 22462035 | 154 days ago | 0 ETH | ||||
| 22277827 | 158 days ago | 0 ETH | ||||
| 22277827 | 158 days ago | 0 ETH | ||||
| 22253666 | 159 days ago | 0 ETH | ||||
| 22253666 | 159 days ago | 0 ETH | ||||
| 22161669 | 161 days ago | 0 ETH |
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:
GuildRewardNFTFactory
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 { IBasicGuildRewardNFT } from "./interfaces/IBasicGuildRewardNFT.sol";
import { IConfigurableGuildRewardNFT } from "./interfaces/IConfigurableGuildRewardNFT.sol";
import { IGuildRewardNFTFactory } from "./interfaces/IGuildRewardNFTFactory.sol";
import { TreasuryManager } from "./utils/TreasuryManager.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ClonesUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
/// @title A simple factory deploying minimal proxy contracts for Guild reward NFTs.
contract GuildRewardNFTFactory is
IGuildRewardNFTFactory,
Initializable,
UUPSUpgradeable,
OwnableUpgradeable,
TreasuryManager
{
address public validSigner;
mapping(ContractType contractType => address contractAddress) public nftImplementations;
mapping(address deployer => Deployment[] tokens) internal deployedTokenContracts;
/// @notice Empty space reserved for future updates.
uint256[47] private __gap;
function initialize(address payable treasuryAddress, uint256 fee, address validSignerAddress) public initializer {
validSigner = validSignerAddress;
__Ownable_init();
__TreasuryManager_init(treasuryAddress, fee);
}
function deployBasicNFT(
string calldata name,
string calldata symbol,
string calldata cid,
address tokenOwner,
address payable tokenTreasury,
uint256 tokenFee
) external {
ContractType contractType = ContractType.BASIC_NFT;
address deployedCloneAddress = ClonesUpgradeable.clone(nftImplementations[contractType]);
IBasicGuildRewardNFT deployedClone = IBasicGuildRewardNFT(deployedCloneAddress);
deployedClone.initialize(name, symbol, cid, tokenOwner, tokenTreasury, tokenFee, address(this));
deployedTokenContracts[msg.sender].push(
Deployment({ contractAddress: deployedCloneAddress, contractType: contractType })
);
emit RewardNFTDeployed(msg.sender, deployedCloneAddress, contractType);
}
function deployConfigurableNFT(ConfigurableNFTConfig memory nftConfig) external {
ContractType contractType = ContractType.CONFIGURABLE_NFT;
address deployedCloneAddress = ClonesUpgradeable.clone(nftImplementations[contractType]);
IConfigurableGuildRewardNFT deployedClone = IConfigurableGuildRewardNFT(deployedCloneAddress);
deployedClone.initialize(nftConfig, address(this));
deployedTokenContracts[msg.sender].push(
Deployment({ contractAddress: deployedCloneAddress, contractType: contractType })
);
emit RewardNFTDeployed(msg.sender, deployedCloneAddress, contractType);
}
function setNFTImplementation(ContractType contractType, address newNFT) external onlyOwner {
nftImplementations[contractType] = newNFT;
emit ImplementationChanged(contractType, newNFT);
}
function setValidSigner(address newValidSigner) external onlyOwner {
validSigner = newValidSigner;
emit ValidSignerChanged(newValidSigner);
}
function getDeployedTokenContracts(address deployer) external view returns (Deployment[] memory tokens) {
return deployedTokenContracts[deployer];
}
// solhint-disable-next-line no-empty-blocks
function _authorizeUpgrade(address) internal override onlyOwner {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title An NFT distributed as a reward for Guild.xyz users.
interface IBasicGuildRewardNFT {
/// @notice The address of the proxy to be used when interacting with the factory.
/// @dev Used to access the factory's address when interacting through minimal proxies.
/// @return factoryAddress The address of the factory.
function factoryProxy() external view returns (address factoryAddress);
/// @notice Returns true if the address has already claimed their token.
/// @param account The user's address.
/// @return claimed Whether the address has claimed their token.
function hasClaimed(address account) external view returns (bool claimed);
/// @notice Whether a userId has claimed a token.
/// @dev Used to prevent double claims in the same block.
/// @param userId The id of the user on Guild.
/// @return claimed Whether the userId has claimed any tokens.
function hasTheUserIdClaimed(uint256 userId) external view returns (bool claimed);
/// @notice Sets metadata and the associated addresses.
/// @dev Initializer function callable only once.
/// @param name The name of the token.
/// @param symbol The symbol of the token.
/// @param cid The cid used to construct the tokenURI for the token to be deployed.
/// @param tokenOwner The address that will be the owner of the token.
/// @param treasury The address that will receive the price paid for the token.
/// @param tokenFee The price of every claim in wei.
/// @param factoryProxyAddress The address of the factory.
function initialize(
string memory name,
string memory symbol,
string calldata cid,
address tokenOwner,
address payable treasury,
uint256 tokenFee,
address factoryProxyAddress
) external;
/// @notice Claims tokens to the given address.
/// @param receiver The address that receives the token.
/// @param userId The id of the user on Guild.
/// @param signature The following signed by validSigner: receiver, userId, chainId, the contract's address.
function claim(address receiver, uint256 userId, bytes calldata signature) external payable;
/// @notice Burns a token from the sender.
/// @param tokenId The id of the token to burn.
/// @param userId The id of the user on Guild.
/// @param signature The following signed by validSigner: receiver, userId, chainId, the contract's address.
function burn(uint256 tokenId, uint256 userId, bytes calldata signature) external;
/// @notice Updates the cid for tokenURI.
/// @dev Only callable by the owner.
/// @param newCid The new cid that points to the updated image.
function updateTokenURI(string calldata newCid) external;
/// @notice Event emitted whenever a claim succeeds.
/// @param receiver The address that received the tokens.
/// @param tokenId The id of the token.
event Claimed(address indexed receiver, uint256 tokenId);
/// @notice Event emitted whenever the cid is updated.
event MetadataUpdate();
/// @notice Error thrown when the token is already claimed.
error AlreadyClaimed();
/// @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 claiming.
error IncorrectFee(uint256 paid, uint256 requiredAmount);
/// @notice Error thrown when the sender is not permitted to do a specific action.
error IncorrectSender();
/// @notice Error thrown when the supplied signature is invalid.
error IncorrectSignature();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IGuildRewardNFTFactory } from "./IGuildRewardNFTFactory.sol";
import { IMaxSupply } from "./IMaxSupply.sol";
/// @title An NFT distributed as a reward for Guild.xyz users.
interface IConfigurableGuildRewardNFT is IMaxSupply {
/// @notice The address of the proxy to be used when interacting with the factory.
/// @dev Used to access the factory's address when interacting through minimal proxies.
/// @return factoryAddress The address of the factory.
function factoryProxy() external view returns (address factoryAddress);
/// @notice The maximum amount of tokens a Guild user can claim from the token.
/// @dev Doesn't matter if they are claimed in the same transaction or separately.
/// @return mintableAmountPerUser The amount of tokens. Unlimited if zero.
function mintableAmountPerUser() external view returns (uint256 mintableAmountPerUser);
/// @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);
/// @notice Returns the number of tokens the user claimed.
/// @dev Analogous to balanceOf(address), but works with Guild user ids.
/// @param userId The id of the user on Guild.
/// @return amount The number of tokens the userId has claimed.
function balanceOf(uint256 userId) external view returns (uint256 amount);
/// @notice Sets metadata and the associated addresses.
/// @dev Initializer function callable only once.
/// @param nftConfig See struct ConfigurableNFTConfig in IGuildRewardNFTFactory.
/// @param factoryProxyAddress The address of the factory.
function initialize(
IGuildRewardNFTFactory.ConfigurableNFTConfig memory nftConfig,
address factoryProxyAddress
) external;
// Disable solhint for the next functions because this seems to be the only way the docgen plugin works correctly.
// solhint-disable max-line-length
/// @notice Claims tokens to the given address.
/// @param amount The amount of tokens to mint. Should be less or equal to mintableAmountPerUser.
/// @param receiver The address that receives the token.
/// @param userId The id of the user on Guild.
/// @param signedAt The timestamp marking the time when the data were signed.
/// @param signature The following signed by validSigner: amount, signedAt, receiver, userId, chainId, the contract's address.
function claim(
uint256 amount,
address receiver,
uint256 userId,
uint256 signedAt,
bytes calldata signature
) external payable;
/// @notice Burns tokens from the sender.
/// @param tokenIds The tokenIds to burn. All of them should belong to userId.
/// @param userId The id of the user on Guild.
/// @param signedAt The timestamp marking the time when the data were signed.
/// @param signature The following signed by validSigner: amount, signedAt, receiver, userId, chainId, the contract's address.
function burn(uint256[] calldata tokenIds, uint256 userId, uint256 signedAt, bytes calldata signature) external;
// solhint-enable max-line-length
/// @notice Sets the locked (i.e. soulboundness) status of all of the tokens in this NFT.
/// @dev Only callable by the owner.
/// @param newLocked Whether the token should be soulbound or not.
function setLocked(bool newLocked) external;
/// @notice Sets the amount of tokens a user can mint from the token.
/// @dev Only callable by the owner.
/// @param newAmount The new amount a user can mint from the token. Unlimited if zero.
function setMintableAmountPerUser(uint256 newAmount) external;
/// @notice Updates the cid for tokenURI.
/// @dev Only callable by the owner.
/// @param newCid The new cid that points to the updated image.
function updateTokenURI(string calldata newCid) external;
/// @notice Event emitted whenever a claim succeeds.
/// @param receiver The address that received the tokens.
/// @param tokenId The id of the token.
event Claimed(address indexed receiver, uint256 tokenId);
/// @notice Event emitted whenever the cid is updated.
event MetadataUpdate();
/// @notice Event emitted when the mintableAmountPerUser is changed.
/// @param newAmount The new amount a user can mint from the token.
event MintableAmountPerUserChanged(uint256 newAmount);
/// @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 claiming a single token.
error IncorrectFee(uint256 paid, uint256 requiredAmount);
/// @notice Error thrown when the sender is not permitted to do a specific action.
error IncorrectSender();
/// @notice Error thrown when the supplied signature is invalid.
error IncorrectSignature();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title A simple factory deploying minimal proxy contracts for Guild reward NFTs.
interface IGuildRewardNFTFactory {
/// @notice The type of the contract.
/// @dev Used as an identifier. Should be expanded in future updates.
enum ContractType {
BASIC_NFT,
CONFIGURABLE_NFT
}
/// @notice Input parameters of the deployConfigurableNFT function.
/// @dev Needed to prevent "stack too deep" errors.
/// @param name The name of the NFT to be created.
/// @param symbol The symbol of the NFT to be created.
/// @param cid The cid used to construct the tokenURI of the NFT to be created.
/// @param tokenOwner The address that will be the owner of the deployed token.
/// @param tokenTreasury The address that will collect the prices of the minted tokens.
/// @param tokenFee The price of every mint in wei.
/// @param soulbound Whether the token should be soulbound.
/// @param maxSupply The maximum number of tokens that users will ever be able to mint.
/// @param mintableAmountPerUser The maximum amount a user will be able to mint from the deployed token.
struct ConfigurableNFTConfig {
string name;
string symbol;
string cid;
address tokenOwner;
address payable treasury;
uint256 tokenFee;
bool soulbound;
uint256 maxSupply;
uint256 mintableAmountPerUser;
}
/// @notice Information about a specific deployment.
/// @param contractAddress The address where the contract/clone is deployed.
/// @param contractType The type of the contract.
struct Deployment {
address contractAddress;
ContractType contractType;
}
/// @return signer The address that signs the metadata.
function validSigner() external view returns (address signer);
/// @notice Maps deployed implementation contract addresses to contract types.
/// @param contractType The type of the contract.
/// @return contractAddress The address of the deployed NFT contract.
function nftImplementations(ContractType contractType) external view returns (address contractAddress);
/// @notice Sets the associated addresses.
/// @dev Initializer function callable only once.
/// @param treasuryAddress The address that will receive the fees.
/// @param fee The Guild base fee for every deployment.
/// @param validSignerAddress The address that will sign the metadata.
function initialize(address payable treasuryAddress, uint256 fee, address validSignerAddress) external;
/// @notice Deploys a minimal proxy for a basic NFT.
/// @param name The name of the NFT to be created.
/// @param symbol The symbol of the NFT to be created.
/// @param cid The cid used to construct the tokenURI of the NFT to be created.
/// @param tokenOwner The address that will be the owner of the deployed token.
/// @param tokenTreasury The address that will collect the prices of the minted tokens.
/// @param tokenFee The price of every mint in wei.
function deployBasicNFT(
string calldata name,
string calldata symbol,
string calldata cid,
address tokenOwner,
address payable tokenTreasury,
uint256 tokenFee
) external;
/// @notice Deploys a minimal proxy for a configurable NFT.
/// @param nftConfig The config to initialize the token to be deployed with.
function deployConfigurableNFT(ConfigurableNFTConfig memory nftConfig) external;
/// @notice Returns the reward NFT addresses for a guild.
/// @param deployer The address that deployed the tokens.
/// @return tokens The addresses of the tokens deployed by deployer.
function getDeployedTokenContracts(address deployer) external view returns (Deployment[] memory tokens);
/// @notice Sets the address that signs the metadata.
/// @dev Callable only by the owner.
/// @param newValidSigner The new address of validSigner.
function setValidSigner(address newValidSigner) external;
/// @notice Sets the address of the contract where a specific NFT is implemented.
/// @dev Callable only by the owner.
/// @param contractType The type of the contract.
/// @param newNFT The address of the deployed NFT contract.
function setNFTImplementation(ContractType contractType, address newNFT) external;
/// @notice Event emitted when an NFT implementation is changed.
/// @param contractType The type of the contract.
/// @param newNFT The new address of the NFT implementation.
event ImplementationChanged(ContractType contractType, address newNFT);
/// @notice Event emitted when a new NFT is deployed.
/// @param deployer The address that deployed the token.
/// @param tokenAddress The address of the token.
/// @param contractType The type of the NFT deployed.
event RewardNFTDeployed(address deployer, address tokenAddress, ContractType contractType);
/// @notice Event emitted when the validSigner is changed.
/// @param newValidSigner The new address of validSigner.
event ValidSignerChanged(address newValidSigner);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IMaxSupply {
/// @notice The maximum number of tokens that can ever be minted.
/// @return count The number of tokens. Unlimited if zero.
function maxSupply() external view returns (uint256 count);
/// @notice Sets the maximum number of tokens that can ever be minted.
/// @dev Only callable by the owner.
/// @param newMaxSupply The number of tokens. Unlimited if zero.
function setMaxSupply(uint256 newMaxSupply) external;
/// @notice Event emitted when the maxSupply is changed.
/// @param newMaxSupply The number of tokens.
event MaxSupplyChanged(uint256 newMaxSupply);
/// @notice Error thrown when the tokenId is higher than the maximum supply.
/// @param maxSupply The maximum supply of the token.
error MaxSupplyReached(uint256 maxSupply);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import { ITreasuryManager } from "../interfaces/ITreasuryManager.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
/// @title A contract that manages fee-related functionality.
contract TreasuryManager is ITreasuryManager, Initializable, OwnableUpgradeable {
address payable public treasury;
uint256 public fee;
/// @notice Empty space reserved for future updates.
uint256[48] private __gap;
/// @param treasury_ The address that will receive the fees.
/// @param fee_ The fee amount in wei.
// solhint-disable-next-line func-name-mixedcase
function __TreasuryManager_init(address payable treasury_, uint256 fee_) internal onlyInitializing {
treasury = treasury_;
fee = fee_;
}
function setFee(uint256 newFee) external onlyOwner {
fee = newFee;
emit FeeChanged(newFee);
}
function setTreasury(address payable newTreasury) external onlyOwner {
treasury = newTreasury;
emit TreasuryChanged(newTreasury);
}
function getFeeData() external view returns (uint256 tokenFee, address payable treasuryAddress) {
return (fee, treasury);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title A contract that manages fee-related functionality.
interface ITreasuryManager {
/// @notice Sets the minting fee.
/// @dev Callable only by the owner.
/// @param newFee The new fee in base units.
function setFee(uint256 newFee) external;
/// @notice Sets the address that receives the fees.
/// @dev Callable only by the owner.
/// @param newTreasury The new address of the treasury.
function setTreasury(address payable newTreasury) external;
/// @notice The minting fee of a token.
/// @return fee The amount of the fee in base units.
function fee() external view returns (uint256 fee);
/// @notice Gets both the fee and the treasury address for optimization purposes.
/// @return tokenFee The fee for the token in base units.
/// @return treasuryAddress The address of the treasury.
function getFeeData() external view returns (uint256 tokenFee, address payable treasuryAddress);
/// @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 newFee The new amount of fee in base units.
event FeeChanged(uint256 newFee);
/// @notice Event emitted when the treasury address is changed.
/// @param newTreasury The new address of the treasury.
event TreasuryChanged(address newTreasury);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import {Initializable} from "../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 (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
/**
* @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/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library ClonesUpgradeable {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := keccak256(add(ptr, 0x43), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: 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} from "./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 {
/// @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");
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @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 {Initializable} from "../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 {
// 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;
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
/**
* @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
}
}
}{
"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[{"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":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IGuildRewardNFTFactory.ContractType","name":"contractType","type":"uint8"},{"indexed":false,"internalType":"address","name":"newNFT","type":"address"}],"name":"ImplementationChanged","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":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"enum IGuildRewardNFTFactory.ContractType","name":"contractType","type":"uint8"}],"name":"RewardNFTDeployed","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":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"cid","type":"string"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address payable","name":"tokenTreasury","type":"address"},{"internalType":"uint256","name":"tokenFee","type":"uint256"}],"name":"deployBasicNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"cid","type":"string"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address payable","name":"treasury","type":"address"},{"internalType":"uint256","name":"tokenFee","type":"uint256"},{"internalType":"bool","name":"soulbound","type":"bool"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"mintableAmountPerUser","type":"uint256"}],"internalType":"struct IGuildRewardNFTFactory.ConfigurableNFTConfig","name":"nftConfig","type":"tuple"}],"name":"deployConfigurableNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"getDeployedTokenContracts","outputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"enum IGuildRewardNFTFactory.ContractType","name":"contractType","type":"uint8"}],"internalType":"struct IGuildRewardNFTFactory.Deployment[]","name":"tokens","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeData","outputs":[{"internalType":"uint256","name":"tokenFee","type":"uint256"},{"internalType":"address payable","name":"treasuryAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"treasuryAddress","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"validSignerAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IGuildRewardNFTFactory.ContractType","name":"contractType","type":"uint8"}],"name":"nftImplementations","outputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","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":"uint256","name":"newFee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IGuildRewardNFTFactory.ContractType","name":"contractType","type":"uint8"},{"internalType":"address","name":"newNFT","type":"address"}],"name":"setNFTImplementation","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":"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":[{"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
60a06040523060805234801561001457600080fd5b50608051611bb361004c600039600081816105b2015281816105fb0152818161069a015281816106da015261076d0152611bb36000f3fe6080604052600436106101145760003560e01c806369fe0e2d116100a0578063c350a1b511610064578063c350a1b514610314578063ddca3f4314610334578063f0f442601461034a578063f2fde38b1461036a578063fd7c37b41461038a57600080fd5b806369fe0e2d14610274578063715018a6146102945780637e43f2d1146102a95780638da5cb5b146102c9578063a3af41a8146102e757600080fd5b80633659cfe6116100e75780633659cfe6146101c85780634f1ef286146101e857806352d1902d146101fb57806356acf19d1461021e57806361d027b31461025457600080fd5b806312d8b659146101195780631cc7d7431461013b5780631f9f4d6b14610178578063256a493514610198575b600080fd5b34801561012557600080fd5b50610139610134366004611322565b6103aa565b005b34801561014757600080fd5b5060fb5461015b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561018457600080fd5b50610139610193366004611425565b610407565b3480156101a457600080fd5b5060ca5460c954604080519283526001600160a01b0390911660208301520161016f565b3480156101d457600080fd5b506101396101e3366004611322565b6105a8565b6101396101f636600461152f565b610690565b34801561020757600080fd5b50610210610760565b60405190815260200161016f565b34801561022a57600080fd5b5061015b6102393660046115a2565b60fc602052600090815260409020546001600160a01b031681565b34801561026057600080fd5b5060c95461015b906001600160a01b031681565b34801561028057600080fd5b5061013961028f3660046115bd565b610813565b3480156102a057600080fd5b50610139610850565b3480156102b557600080fd5b506101396102c436600461161f565b610864565b3480156102d557600080fd5b506097546001600160a01b031661015b565b3480156102f357600080fd5b50610307610302366004611322565b6109f0565b60405161016f9190611720565b34801561032057600080fd5b5061013961032f366004611781565b610aa8565b34801561034057600080fd5b5061021060ca5481565b34801561035657600080fd5b50610139610365366004611322565b610bdd565b34801561037657600080fd5b50610139610385366004611322565b610c33565b34801561039657600080fd5b506101396103a53660046117c3565b610ca9565b6103b2610d48565b60fb80546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b6001600061044360fc82845b6001811115610424576104246116e8565b81526020810191909152604001600020546001600160a01b0316610da2565b60405163e2bdca4f60e01b815290915081906001600160a01b0382169063e2bdca4f90610476908790309060040161184a565b600060405180830381600087803b15801561049057600080fd5b505af11580156104a4573d6000803e3d6000fd5b5050505060fd6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060400160405280846001600160a01b031681526020018560018111156104f9576104f96116e8565b905281546001808201845560009384526020938490208351920180546001600160a01b031981166001600160a01b03909416938417825594840151939490939284926001600160a81b03199092161790600160a01b908490811115610560576105606116e8565b021790555050507f16b0c01de8461e2fd978cf9d7cd7562f1f5920c0e03de710eb1225006308b33d33838560405161059a93929190611923565b60405180910390a150505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036105f95760405162461bcd60e51b81526004016105f090611948565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610642600080516020611b37833981519152546001600160a01b031690565b6001600160a01b0316146106685760405162461bcd60e51b81526004016105f090611994565b61067181610e3c565b6040805160008082526020820190925261068d91839190610e44565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036106d85760405162461bcd60e51b81526004016105f090611948565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610721600080516020611b37833981519152546001600160a01b031690565b6001600160a01b0316146107475760405162461bcd60e51b81526004016105f090611994565b61075082610e3c565b61075c82826001610e44565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016105f0565b50600080516020611b3783398151915290565b61081b610d48565b60ca8190556040518181527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3906020016103fc565b610858610d48565b6108626000610fb4565b565b60008061087360fc8280610413565b604051632eb730e560e11b815290915081906001600160a01b03821690635d6e61ca906108b6908f908f908f908f908f908f908f908f908f903090600401611a09565b600060405180830381600087803b1580156108d057600080fd5b505af11580156108e4573d6000803e3d6000fd5b5050505060fd6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060400160405280846001600160a01b03168152602001856001811115610939576109396116e8565b905281546001808201845560009384526020938490208351920180546001600160a01b031981166001600160a01b03909416938417825594840151939490939284926001600160a81b03199092161790600160a01b9084908111156109a0576109a06116e8565b021790555050507f16b0c01de8461e2fd978cf9d7cd7562f1f5920c0e03de710eb1225006308b33d3383856040516109da93929190611923565b60405180910390a1505050505050505050505050565b6001600160a01b038116600090815260fd60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610a9d5760008481526020908190206040805180820190915290840180546001600160a01b03811683529192909190830190600160a01b900460ff166001811115610a7957610a796116e8565b6001811115610a8a57610a8a6116e8565b8152505081526020019060010190610a28565b505050509050919050565b600054610100900460ff1615808015610ac85750600054600160ff909116105b80610ae25750303b158015610ae2575060005460ff166001145b610b455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105f0565b6000805460ff191660011790558015610b68576000805461ff0019166101001790555b60fb80546001600160a01b0319166001600160a01b038416179055610b8b611006565b610b958484611035565b8015610bd7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200161059a565b50505050565b610be5610d48565b60c980546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f608906020016103fc565b610c3b610d48565b6001600160a01b038116610ca05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105f0565b61068d81610fb4565b610cb1610d48565b8060fc6000846001811115610cc857610cc86116e8565b6001811115610cd957610cd96116e8565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f209ee1cca29d8cb121d84438eff8a3148751f32436e76569f31aae0e4a89bf6a8282604051610d3c929190611a7d565b60405180910390a15050565b6097546001600160a01b031633146108625760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105f0565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116610e375760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b60448201526064016105f0565b919050565b61068d610d48565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610e7c57610e7783611082565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610ed6575060408051601f3d908101601f19168201909252610ed391810190611aa3565b60015b610f395760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016105f0565b600080516020611b378339815191528114610fa85760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016105f0565b50610e7783838361111e565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff1661102d5760405162461bcd60e51b81526004016105f090611abc565b610862611143565b600054610100900460ff1661105c5760405162461bcd60e51b81526004016105f090611abc565b60c980546001600160a01b0319166001600160a01b03939093169290921790915560ca55565b6001600160a01b0381163b6110ef5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016105f0565b600080516020611b3783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61112783611173565b6000825111806111345750805b15610e7757610bd783836111b3565b600054610100900460ff1661116a5760405162461bcd60e51b81526004016105f090611abc565b61086233610fb4565b61117c81611082565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606111d88383604051806060016040528060278152602001611b57602791396111df565b9392505050565b6060600080856001600160a01b0316856040516111fc9190611b07565b600060405180830381855af49150503d8060008114611237576040519150601f19603f3d011682016040523d82523d6000602084013e61123c565b606091505b509150915061124d86838387611257565b9695505050505050565b606083156112c65782516000036112bf576001600160a01b0385163b6112bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f0565b50816112d0565b6112d083836112d8565b949350505050565b8151156112e85781518083602001fd5b8060405162461bcd60e51b81526004016105f09190611b23565b6001600160a01b038116811461068d57600080fd5b8035610e3781611302565b60006020828403121561133457600080fd5b81356111d881611302565b634e487b7160e01b600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156113795761137961133f565b60405290565b600067ffffffffffffffff8084111561139a5761139a61133f565b604051601f8501601f19908116603f011681019082821181831017156113c2576113c261133f565b816040528093508581528686860111156113db57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261140657600080fd5b6111d88383356020850161137f565b80358015158114610e3757600080fd5b60006020828403121561143757600080fd5b813567ffffffffffffffff8082111561144f57600080fd5b90830190610120828603121561146457600080fd5b61146c611355565b82358281111561147b57600080fd5b611487878286016113f5565b82525060208301358281111561149c57600080fd5b6114a8878286016113f5565b6020830152506040830135828111156114c057600080fd5b6114cc878286016113f5565b6040830152506114de60608401611317565b60608201526114ef60808401611317565b608082015260a083013560a082015261150a60c08401611415565b60c082015260e083810135908201526101009283013592810192909252509392505050565b6000806040838503121561154257600080fd5b823561154d81611302565b9150602083013567ffffffffffffffff81111561156957600080fd5b8301601f8101851361157a57600080fd5b6115898582356020840161137f565b9150509250929050565b803560028110610e3757600080fd5b6000602082840312156115b457600080fd5b6111d882611593565b6000602082840312156115cf57600080fd5b5035919050565b60008083601f8401126115e857600080fd5b50813567ffffffffffffffff81111561160057600080fd5b60208301915083602082850101111561161857600080fd5b9250929050565b600080600080600080600080600060c08a8c03121561163d57600080fd5b893567ffffffffffffffff8082111561165557600080fd5b6116618d838e016115d6565b909b50995060208c013591508082111561167a57600080fd5b6116868d838e016115d6565b909950975060408c013591508082111561169f57600080fd5b506116ac8c828d016115d6565b90965094505060608a01356116c081611302565b925060808a01356116d081611302565b8092505060a08a013590509295985092959850929598565b634e487b7160e01b600052602160045260246000fd5b6002811061171c57634e487b7160e01b600052602160045260246000fd5b9052565b602080825282518282018190526000919060409081850190868401855b8281101561177457815180516001600160a01b03168552860151611763878601826116fe565b50928401929085019060010161173d565b5091979650505050505050565b60008060006060848603121561179657600080fd5b83356117a181611302565b92506020840135915060408401356117b881611302565b809150509250925092565b600080604083850312156117d657600080fd5b6117df83611593565b915060208301356117ef81611302565b809150509250929050565b60005b838110156118155781810151838201526020016117fd565b50506000910152565b600081518084526118368160208601602086016117fa565b601f01601f19169290920160200192915050565b604081526000835161012080604085015261186961016085018361181e565b91506020860151603f1980868503016060870152611887848361181e565b93506040880151915080868503016080870152506118a5838261181e565b92505060608601516118c260a08601826001600160a01b03169052565b5060808601516001600160a01b03811660c08601525060a086015160e085015260c08601516101006118f78187018315159052565b60e088015192860192909252508501516101408401526001600160a01b038416602084015290506111d8565b6001600160a01b03848116825283166020820152606081016112d060408301846116fe565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60e081526000611a1d60e083018c8e6119e0565b8281036020840152611a30818b8d6119e0565b90508281036040840152611a4581898b6119e0565b6001600160a01b0397881660608501529587166080840152505060a081019290925290921660c0909201919091529695505050505050565b60408101611a8b82856116fe565b6001600160a01b039290921660209190910152919050565b600060208284031215611ab557600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251611b198184602087016117fa565b9190910192915050565b6020815260006111d8602083018461181e56fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220257129f4e7b21ede59110981ac54860a00082988b4dd214ef83a84837db2664664736f6c63430008130033
Deployed Bytecode
0x6080604052600436106101145760003560e01c806369fe0e2d116100a0578063c350a1b511610064578063c350a1b514610314578063ddca3f4314610334578063f0f442601461034a578063f2fde38b1461036a578063fd7c37b41461038a57600080fd5b806369fe0e2d14610274578063715018a6146102945780637e43f2d1146102a95780638da5cb5b146102c9578063a3af41a8146102e757600080fd5b80633659cfe6116100e75780633659cfe6146101c85780634f1ef286146101e857806352d1902d146101fb57806356acf19d1461021e57806361d027b31461025457600080fd5b806312d8b659146101195780631cc7d7431461013b5780631f9f4d6b14610178578063256a493514610198575b600080fd5b34801561012557600080fd5b50610139610134366004611322565b6103aa565b005b34801561014757600080fd5b5060fb5461015b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561018457600080fd5b50610139610193366004611425565b610407565b3480156101a457600080fd5b5060ca5460c954604080519283526001600160a01b0390911660208301520161016f565b3480156101d457600080fd5b506101396101e3366004611322565b6105a8565b6101396101f636600461152f565b610690565b34801561020757600080fd5b50610210610760565b60405190815260200161016f565b34801561022a57600080fd5b5061015b6102393660046115a2565b60fc602052600090815260409020546001600160a01b031681565b34801561026057600080fd5b5060c95461015b906001600160a01b031681565b34801561028057600080fd5b5061013961028f3660046115bd565b610813565b3480156102a057600080fd5b50610139610850565b3480156102b557600080fd5b506101396102c436600461161f565b610864565b3480156102d557600080fd5b506097546001600160a01b031661015b565b3480156102f357600080fd5b50610307610302366004611322565b6109f0565b60405161016f9190611720565b34801561032057600080fd5b5061013961032f366004611781565b610aa8565b34801561034057600080fd5b5061021060ca5481565b34801561035657600080fd5b50610139610365366004611322565b610bdd565b34801561037657600080fd5b50610139610385366004611322565b610c33565b34801561039657600080fd5b506101396103a53660046117c3565b610ca9565b6103b2610d48565b60fb80546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3a45a79b2d77631258297d008a7191793950c864ee1a142b02af72654728cad906020015b60405180910390a150565b6001600061044360fc82845b6001811115610424576104246116e8565b81526020810191909152604001600020546001600160a01b0316610da2565b60405163e2bdca4f60e01b815290915081906001600160a01b0382169063e2bdca4f90610476908790309060040161184a565b600060405180830381600087803b15801561049057600080fd5b505af11580156104a4573d6000803e3d6000fd5b5050505060fd6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060400160405280846001600160a01b031681526020018560018111156104f9576104f96116e8565b905281546001808201845560009384526020938490208351920180546001600160a01b031981166001600160a01b03909416938417825594840151939490939284926001600160a81b03199092161790600160a01b908490811115610560576105606116e8565b021790555050507f16b0c01de8461e2fd978cf9d7cd7562f1f5920c0e03de710eb1225006308b33d33838560405161059a93929190611923565b60405180910390a150505050565b6001600160a01b037f00000000000000000000000013ec6b98362e43add08f7cc4f6befd02fa52ee011630036105f95760405162461bcd60e51b81526004016105f090611948565b60405180910390fd5b7f00000000000000000000000013ec6b98362e43add08f7cc4f6befd02fa52ee016001600160a01b0316610642600080516020611b37833981519152546001600160a01b031690565b6001600160a01b0316146106685760405162461bcd60e51b81526004016105f090611994565b61067181610e3c565b6040805160008082526020820190925261068d91839190610e44565b50565b6001600160a01b037f00000000000000000000000013ec6b98362e43add08f7cc4f6befd02fa52ee011630036106d85760405162461bcd60e51b81526004016105f090611948565b7f00000000000000000000000013ec6b98362e43add08f7cc4f6befd02fa52ee016001600160a01b0316610721600080516020611b37833981519152546001600160a01b031690565b6001600160a01b0316146107475760405162461bcd60e51b81526004016105f090611994565b61075082610e3c565b61075c82826001610e44565b5050565b6000306001600160a01b037f00000000000000000000000013ec6b98362e43add08f7cc4f6befd02fa52ee0116146108005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016105f0565b50600080516020611b3783398151915290565b61081b610d48565b60ca8190556040518181527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3906020016103fc565b610858610d48565b6108626000610fb4565b565b60008061087360fc8280610413565b604051632eb730e560e11b815290915081906001600160a01b03821690635d6e61ca906108b6908f908f908f908f908f908f908f908f908f903090600401611a09565b600060405180830381600087803b1580156108d057600080fd5b505af11580156108e4573d6000803e3d6000fd5b5050505060fd6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060400160405280846001600160a01b03168152602001856001811115610939576109396116e8565b905281546001808201845560009384526020938490208351920180546001600160a01b031981166001600160a01b03909416938417825594840151939490939284926001600160a81b03199092161790600160a01b9084908111156109a0576109a06116e8565b021790555050507f16b0c01de8461e2fd978cf9d7cd7562f1f5920c0e03de710eb1225006308b33d3383856040516109da93929190611923565b60405180910390a1505050505050505050505050565b6001600160a01b038116600090815260fd60209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610a9d5760008481526020908190206040805180820190915290840180546001600160a01b03811683529192909190830190600160a01b900460ff166001811115610a7957610a796116e8565b6001811115610a8a57610a8a6116e8565b8152505081526020019060010190610a28565b505050509050919050565b600054610100900460ff1615808015610ac85750600054600160ff909116105b80610ae25750303b158015610ae2575060005460ff166001145b610b455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105f0565b6000805460ff191660011790558015610b68576000805461ff0019166101001790555b60fb80546001600160a01b0319166001600160a01b038416179055610b8b611006565b610b958484611035565b8015610bd7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200161059a565b50505050565b610be5610d48565b60c980546001600160a01b0319166001600160a01b0383169081179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f608906020016103fc565b610c3b610d48565b6001600160a01b038116610ca05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105f0565b61068d81610fb4565b610cb1610d48565b8060fc6000846001811115610cc857610cc86116e8565b6001811115610cd957610cd96116e8565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507f209ee1cca29d8cb121d84438eff8a3148751f32436e76569f31aae0e4a89bf6a8282604051610d3c929190611a7d565b60405180910390a15050565b6097546001600160a01b031633146108625760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105f0565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116610e375760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b60448201526064016105f0565b919050565b61068d610d48565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610e7c57610e7783611082565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610ed6575060408051601f3d908101601f19168201909252610ed391810190611aa3565b60015b610f395760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016105f0565b600080516020611b378339815191528114610fa85760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016105f0565b50610e7783838361111e565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff1661102d5760405162461bcd60e51b81526004016105f090611abc565b610862611143565b600054610100900460ff1661105c5760405162461bcd60e51b81526004016105f090611abc565b60c980546001600160a01b0319166001600160a01b03939093169290921790915560ca55565b6001600160a01b0381163b6110ef5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016105f0565b600080516020611b3783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61112783611173565b6000825111806111345750805b15610e7757610bd783836111b3565b600054610100900460ff1661116a5760405162461bcd60e51b81526004016105f090611abc565b61086233610fb4565b61117c81611082565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606111d88383604051806060016040528060278152602001611b57602791396111df565b9392505050565b6060600080856001600160a01b0316856040516111fc9190611b07565b600060405180830381855af49150503d8060008114611237576040519150601f19603f3d011682016040523d82523d6000602084013e61123c565b606091505b509150915061124d86838387611257565b9695505050505050565b606083156112c65782516000036112bf576001600160a01b0385163b6112bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f0565b50816112d0565b6112d083836112d8565b949350505050565b8151156112e85781518083602001fd5b8060405162461bcd60e51b81526004016105f09190611b23565b6001600160a01b038116811461068d57600080fd5b8035610e3781611302565b60006020828403121561133457600080fd5b81356111d881611302565b634e487b7160e01b600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156113795761137961133f565b60405290565b600067ffffffffffffffff8084111561139a5761139a61133f565b604051601f8501601f19908116603f011681019082821181831017156113c2576113c261133f565b816040528093508581528686860111156113db57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261140657600080fd5b6111d88383356020850161137f565b80358015158114610e3757600080fd5b60006020828403121561143757600080fd5b813567ffffffffffffffff8082111561144f57600080fd5b90830190610120828603121561146457600080fd5b61146c611355565b82358281111561147b57600080fd5b611487878286016113f5565b82525060208301358281111561149c57600080fd5b6114a8878286016113f5565b6020830152506040830135828111156114c057600080fd5b6114cc878286016113f5565b6040830152506114de60608401611317565b60608201526114ef60808401611317565b608082015260a083013560a082015261150a60c08401611415565b60c082015260e083810135908201526101009283013592810192909252509392505050565b6000806040838503121561154257600080fd5b823561154d81611302565b9150602083013567ffffffffffffffff81111561156957600080fd5b8301601f8101851361157a57600080fd5b6115898582356020840161137f565b9150509250929050565b803560028110610e3757600080fd5b6000602082840312156115b457600080fd5b6111d882611593565b6000602082840312156115cf57600080fd5b5035919050565b60008083601f8401126115e857600080fd5b50813567ffffffffffffffff81111561160057600080fd5b60208301915083602082850101111561161857600080fd5b9250929050565b600080600080600080600080600060c08a8c03121561163d57600080fd5b893567ffffffffffffffff8082111561165557600080fd5b6116618d838e016115d6565b909b50995060208c013591508082111561167a57600080fd5b6116868d838e016115d6565b909950975060408c013591508082111561169f57600080fd5b506116ac8c828d016115d6565b90965094505060608a01356116c081611302565b925060808a01356116d081611302565b8092505060a08a013590509295985092959850929598565b634e487b7160e01b600052602160045260246000fd5b6002811061171c57634e487b7160e01b600052602160045260246000fd5b9052565b602080825282518282018190526000919060409081850190868401855b8281101561177457815180516001600160a01b03168552860151611763878601826116fe565b50928401929085019060010161173d565b5091979650505050505050565b60008060006060848603121561179657600080fd5b83356117a181611302565b92506020840135915060408401356117b881611302565b809150509250925092565b600080604083850312156117d657600080fd5b6117df83611593565b915060208301356117ef81611302565b809150509250929050565b60005b838110156118155781810151838201526020016117fd565b50506000910152565b600081518084526118368160208601602086016117fa565b601f01601f19169290920160200192915050565b604081526000835161012080604085015261186961016085018361181e565b91506020860151603f1980868503016060870152611887848361181e565b93506040880151915080868503016080870152506118a5838261181e565b92505060608601516118c260a08601826001600160a01b03169052565b5060808601516001600160a01b03811660c08601525060a086015160e085015260c08601516101006118f78187018315159052565b60e088015192860192909252508501516101408401526001600160a01b038416602084015290506111d8565b6001600160a01b03848116825283166020820152606081016112d060408301846116fe565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60e081526000611a1d60e083018c8e6119e0565b8281036020840152611a30818b8d6119e0565b90508281036040840152611a4581898b6119e0565b6001600160a01b0397881660608501529587166080840152505060a081019290925290921660c0909201919091529695505050505050565b60408101611a8b82856116fe565b6001600160a01b039290921660209190910152919050565b600060208284031215611ab557600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251611b198184602087016117fa565b9190910192915050565b6020815260006111d8602083018461181e56fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220257129f4e7b21ede59110981ac54860a00082988b4dd214ef83a84837db2664664736f6c63430008130033
Deployed Bytecode Sourcemap
864:2849:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3263:161;;;;;;;;;;-1:-1:-1;3263:161:0;;;;;:::i;:::-;;:::i;:::-;;1016:26;;;;;;;;;;-1:-1:-1;1016:26:0;;;;-1:-1:-1;;;;;1016:26:0;;;;;;-1:-1:-1;;;;;814:32:18;;;796:51;;784:2;769:18;1016:26:0;;;;;;;;2391:652;;;;;;;;;;-1:-1:-1;2391:652:0;;;;;:::i;:::-;;:::i;1231:135:6:-;;;;;;;;;;-1:-1:-1;1345:3:6;;1350:8;;1231:135;;;3827:25:18;;;-1:-1:-1;;;;;1350:8:6;;;3883:2:18;3868:18;;3861:60;3800:18;1231:135:6;3637:290:18;3408:195:14;;;;;;;;;;-1:-1:-1;3408:195:14;;;;;:::i;:::-;;:::i;3922:220::-;;;;;;:::i;:::-;;:::i;3027:131::-;;;;;;;;;;;;;:::i;:::-;;;4668:25:18;;;4656:2;4641:18;3027:131:14;4522:177:18;1049:87:0;;;;;;;;;;-1:-1:-1;1049:87:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1049:87:0;;;480:31:6;;;;;;;;;;-1:-1:-1;480:31:6;;;;-1:-1:-1;;;;;480:31:6;;;955:113;;;;;;;;;;-1:-1:-1;955:113:6;;;;;:::i;:::-;;:::i;2085:101:7:-;;;;;;;;;;;;;:::i;1566:819:0:-;;;;;;;;;;-1:-1:-1;1566:819:0;;;;;:::i;:::-;;:::i;1462:85:7:-;;;;;;;;;;-1:-1:-1;1534:6:7;;-1:-1:-1;;;;;1534:6:7;1462:85;;3430:160:0;;;;;;;;;;-1:-1:-1;3430:160:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1318:242::-;;;;;;;;;;-1:-1:-1;1318:242:0;;;;;:::i;:::-;;:::i;518:18:6:-;;;;;;;;;;;;;;;;1074:151;;;;;;;;;;-1:-1:-1;1074:151:6;;;;;:::i;:::-;;:::i;2335:198:7:-;;;;;;;;;;-1:-1:-1;2335:198:7;;;;;:::i;:::-;;:::i;3049:208:0:-;;;;;;;;;;-1:-1:-1;3049:208:0;;;;;:::i;:::-;;:::i;3263:161::-;1355:13:7;:11;:13::i;:::-;3340:11:0::1;:28:::0;;-1:-1:-1;;;;;;3340:28:0::1;-1:-1:-1::0;;;;;3340:28:0;::::1;::::0;;::::1;::::0;;;3383:34:::1;::::0;796:51:18;;;3383:34:0::1;::::0;784:2:18;769:18;3383:34:0::1;;;;;;;;3263:161:::0;:::o;2391:652::-;2509:29;2481:25;2579:57;2603:18;2481:25;2509:29;2603:32;;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;2603:32:0;;-1:-1:-1;;;;;2603:32:0;2579:23;:57::i;:::-;2750:50;;-1:-1:-1;;;2750:50:0;;2548:88;;-1:-1:-1;2548:88:0;;-1:-1:-1;;;;;2750:24:0;;;;;:50;;2775:9;;2794:4;;2750:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2811:22;:34;2834:10;-1:-1:-1;;;;;2811:34:0;-1:-1:-1;;;;;2811:34:0;;;;;;;;;;;;2864:81;;;;;;;;2894:20;-1:-1:-1;;;;;2864:81:0;;;;;2930:12;2864:81;;;;;;;;:::i;:::-;;;2811:144;;;;;;;;-1:-1:-1;2811:144:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;2811:144:0;;-1:-1:-1;;;;;2811:144:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2811:144:0;;;;;-1:-1:-1;;;2811:144:0;;;;;;;;;;:::i;:::-;;;;;;;;2971:65;2989:10;3001:20;3023:12;2971:65;;;;;;;;:::i;:::-;;;;;;;;2471:572;;;2391:652;:::o;3408:195:14:-;-1:-1:-1;;;;;1764:6:14;1747:23;1755:4;1747:23;1739:80;;;;-1:-1:-1;;;1739:80:14;;;;;;;:::i;:::-;;;;;;;;;1861:6;-1:-1:-1;;;;;1837:30:14;:20;-1:-1:-1;;;;;;;;;;;1557:65:11;-1:-1:-1;;;;;1557:65:11;;1478:151;1837:20:14;-1:-1:-1;;;;;1837:30:14;;1829:87;;;;-1:-1:-1;;;1829:87:14;;;;;;;:::i;:::-;3489:36:::1;3507:17;3489;:36::i;:::-;3576:12;::::0;;3586:1:::1;3576:12:::0;;;::::1;::::0;::::1;::::0;;;3535:61:::1;::::0;3557:17;;3576:12;3535:21:::1;:61::i;:::-;3408:195:::0;:::o;3922:220::-;-1:-1:-1;;;;;1764:6:14;1747:23;1755:4;1747:23;1739:80;;;;-1:-1:-1;;;1739:80:14;;;;;;;:::i;:::-;1861:6;-1:-1:-1;;;;;1837:30:14;:20;-1:-1:-1;;;;;;;;;;;1557:65:11;-1:-1:-1;;;;;1557:65:11;;1478:151;1837:20:14;-1:-1:-1;;;;;1837:30:14;;1829:87;;;;-1:-1:-1;;;1829:87:14;;;;;;;:::i;:::-;4037:36:::1;4055:17;4037;:36::i;:::-;4083:52;4105:17;4124:4;4130;4083:21;:52::i;:::-;3922:220:::0;;:::o;3027:131::-;3105:7;2190:4;-1:-1:-1;;;;;2199:6:14;2182:23;;2174:92;;;;-1:-1:-1;;;2174:92:14;;13271:2:18;2174:92:14;;;13253:21:18;13310:2;13290:18;;;13283:30;13349:34;13329:18;;;13322:62;13420:26;13400:18;;;13393:54;13464:19;;2174:92:14;13069:420:18;2174:92:14;-1:-1:-1;;;;;;;;;;;;3027:131:14;:::o;955:113:6:-;1355:13:7;:11;:13::i;:::-;1016:3:6::1;:12:::0;;;1043:18:::1;::::0;4668:25:18;;;1043:18:6::1;::::0;4656:2:18;4641:18;1043::6::1;4522:177:18::0;2085:101:7;1355:13;:11;:13::i;:::-;2149:30:::1;2176:1;2149:18;:30::i;:::-;2085:101::o:0;1566:819:0:-;1799:25;;1890:57;1914:18;1799:25;;1914:32;;1890:57;2047:95;;-1:-1:-1;;;2047:95:0;;1859:88;;-1:-1:-1;1859:88:0;;-1:-1:-1;;;;;2047:24:0;;;;;:95;;2072:4;;;;2078:6;;;;2086:3;;;;2091:10;;2103:13;;2118:8;;2136:4;;2047:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2153:22;:34;2176:10;-1:-1:-1;;;;;2153:34:0;-1:-1:-1;;;;;2153:34:0;;;;;;;;;;;;2206:81;;;;;;;;2236:20;-1:-1:-1;;;;;2206:81:0;;;;;2272:12;2206:81;;;;;;;;:::i;:::-;;;2153:144;;;;;;;;-1:-1:-1;2153:144:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;2153:144:0;;-1:-1:-1;;;;;2153:144:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2153:144:0;;;;;-1:-1:-1;;;2153:144:0;;;;;;;;;;:::i;:::-;;;;;;;;2313:65;2331:10;2343:20;2365:12;2313:65;;;;;;;;:::i;:::-;;;;;;;;1789:596;;;1566:819;;;;;;;;;:::o;3430:160::-;-1:-1:-1;;;;;3551:32:0;;;;;;:22;:32;;;;;;;;3544:39;;;;;;;;;;;;;;;;;3506:26;;3544:39;;3551:32;;3544:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3544:39:0;;;;;;;;;;;;-1:-1:-1;;;3544:39:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;3430:160;;;:::o;1318:242::-;3279:19:13;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:13;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:13;1713:19:15;:23;;;3387:66:13;;-1:-1:-1;3436:12:13;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:13;;14970:2:18;3325:201:13;;;14952:21:18;15009:2;14989:18;;;14982:30;15048:34;15028:18;;;15021:62;-1:-1:-1;;;15099:18:18;;;15092:44;15153:19;;3325:201:13;14768:410:18;3325:201:13;3536:12;:16;;-1:-1:-1;;3536:16:13;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:13;;;;;3562:65;1441:11:0::1;:32:::0;;-1:-1:-1;;;;;;1441:32:0::1;-1:-1:-1::0;;;;;1441:32:0;::::1;;::::0;;1483:16:::1;:14;:16::i;:::-;1509:44;1532:15;1549:3;1509:22;:44::i;:::-;3651:14:13::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:13;;;3721:14;;-1:-1:-1;15335:36:18;;3721:14:13;;15323:2:18;15308:18;3721:14:13;15183:194:18;3647:99:13;3269:483;1318:242:0;;;:::o;1074:151:6:-;1355:13:7;:11;:13::i;:::-;1153:8:6::1;:22:::0;;-1:-1:-1;;;;;;1153:22:6::1;-1:-1:-1::0;;;;;1153:22:6;::::1;::::0;;::::1;::::0;;;1190:28:::1;::::0;796:51:18;;;1190:28:6::1;::::0;784:2:18;769:18;1190:28:6::1;650:203:18::0;2335:198:7;1355:13;:11;:13::i;:::-;-1:-1:-1;;;;;2423:22:7;::::1;2415:73;;;::::0;-1:-1:-1;;;2415:73:7;;15800:2:18;2415:73:7::1;::::0;::::1;15782:21:18::0;15839:2;15819:18;;;15812:30;15878:34;15858:18;;;15851:62;-1:-1:-1;;;15929:18:18;;;15922:36;15975:19;;2415:73:7::1;15598:402:18::0;2415:73:7::1;2498:28;2517:8;2498:18;:28::i;3049:208:0:-:0;1355:13:7;:11;:13::i;:::-;3186:6:0::1;3151:18;:32;3170:12;3151:32;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:41;;;;;-1:-1:-1::0;;;;;3151:41:0::1;;;;;-1:-1:-1::0;;;;;3151:41:0::1;;;;;;3207:43;3229:12;3243:6;3207:43;;;;;;;:::i;:::-;;;;;;;;3049:208:::0;;:::o;1620:130:7:-;1534:6;;-1:-1:-1;;;;;1534:6:7;965:10:16;1683:23:7;1675:68;;;;-1:-1:-1;;;1675:68:7;;16522:2:18;1675:68:7;;;16504:21:18;;;16541:18;;;16534:30;16600:34;16580:18;;;16573:62;16652:18;;1675:68:7;16320:356:18;984:759:10;1041:16;1373:48;1355:14;1349:4;1345:25;1339:4;1335:36;1332:90;1326:4;1319:104;1580:32;1563:14;1557:4;1553:25;1550:63;1544:4;1537:77;1655:4;1649;1646:1;1639:21;1627:33;-1:-1:-1;;;;;;1687:22:10;;1679:57;;;;-1:-1:-1;;;1679:57:10;;16883:2:18;1679:57:10;;;16865:21:18;16922:2;16902:18;;;16895:30;-1:-1:-1;;;16941:18:18;;;16934:52;17003:18;;1679:57:10;16681:346:18;1679:57:10;984:759;;;:::o;3645:66:0:-;1355:13:7;:11;:13::i;2841:944:11:-;839:66;3257:59;;;3253:526;;;3332:37;3351:17;3332:18;:37::i;:::-;2841:944;;;:::o;3253:526::-;3433:17;-1:-1:-1;;;;;3404:61:11;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3404:63:11;;;;;;;;-1:-1:-1;;3404:63:11;;;;;;;;;;;;:::i;:::-;;;3400:302;;3631:56;;-1:-1:-1;;;3631:56:11;;17423:2:18;3631:56:11;;;17405:21:18;17462:2;17442:18;;;17435:30;17501:34;17481:18;;;17474:62;-1:-1:-1;;;17552:18:18;;;17545:44;17606:19;;3631:56:11;17221:410:18;3400:302:11;-1:-1:-1;;;;;;;;;;;3517:28:11;;3509:82;;;;-1:-1:-1;;;3509:82:11;;17838:2:18;3509:82:11;;;17820:21:18;17877:2;17857:18;;;17850:30;17916:34;17896:18;;;17889:62;-1:-1:-1;;;17967:18:18;;;17960:39;18016:19;;3509:82:11;17636:405:18;3509:82:11;3468:138;3715:53;3733:17;3752:4;3758:9;3715:17;:53::i;2687:187:7:-;2779:6;;;-1:-1:-1;;;;;2795:17:7;;;-1:-1:-1;;;;;;2795:17:7;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;1024:95::-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1086:26:7::1;:24;:26::i;793:156:6:-:0;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;902:8:6::1;:20:::0;;-1:-1:-1;;;;;;902:20:6::1;-1:-1:-1::0;;;;;902:20:6;;;::::1;::::0;;;::::1;::::0;;;932:3:::1;:10:::0;793:156::o;1720:281:11:-;-1:-1:-1;;;;;1713:19:15;;;1793:106:11;;;;-1:-1:-1;;;1793:106:11;;18660:2:18;1793:106:11;;;18642:21:18;18699:2;18679:18;;;18672:30;18738:34;18718:18;;;18711:62;-1:-1:-1;;;18789:18:18;;;18782:43;18842:19;;1793:106:11;18458:409:18;1793:106:11;-1:-1:-1;;;;;;;;;;;1909:85:11;;-1:-1:-1;;;;;;1909:85:11;-1:-1:-1;;;;;1909:85:11;;;;;;;;;;1720:281::o;2393:276::-;2501:29;2512:17;2501:10;:29::i;:::-;2558:1;2544:4;:11;:15;:28;;;;2563:9;2544:28;2540:123;;;2588:64;2628:17;2647:4;2588:39;:64::i;1125:111:7:-;5374:13:13;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:13;;;;;;;:::i;:::-;1197:32:7::1;965:10:16::0;1197:18:7::1;:32::i;2107:152:11:-:0;2173:37;2192:17;2173:18;:37::i;:::-;2225:27;;-1:-1:-1;;;;;2225:27:11;;;;;;;;2107:152;:::o;6685:198:15:-;6768:12;6799:77;6820:6;6828:4;6799:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6792:84;6685:198;-1:-1:-1;;;6685:198:15:o;7069:325::-;7210:12;7235;7249:23;7276:6;-1:-1:-1;;;;;7276:19:15;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:15:o;7682:628::-;7862:12;7890:7;7886:418;;;7917:10;:17;7938:1;7917:22;7913:286;;-1:-1:-1;;;;;1713:19:15;;;8124:60;;;;-1:-1:-1;;;8124:60:15;;19366:2:18;8124:60:15;;;19348:21:18;19405:2;19385:18;;;19378:30;19444:31;19424:18;;;19417:59;19493:18;;8124:60:15;19164:353:18;8124:60:15;-1:-1:-1;8219:10:15;8212:17;;7886:418;8260:33;8268:10;8280:12;8260:7;:33::i;:::-;7682:628;;;;;;:::o;8832:540::-;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:15;;;;;;;;:::i;14:131:18:-;-1:-1:-1;;;;;89:31:18;;79:42;;69:70;;135:1;132;125:12;150:134;218:20;;247:31;218:20;247:31;:::i;289:247::-;348:6;401:2;389:9;380:7;376:23;372:32;369:52;;;417:1;414;407:12;369:52;456:9;443:23;475:31;500:5;475:31;:::i;858:127::-;919:10;914:3;910:20;907:1;900:31;950:4;947:1;940:15;974:4;971:1;964:15;990:250;1057:2;1051:9;1099:6;1087:19;;1136:18;1121:34;;1157:22;;;1118:62;1115:88;;;1183:18;;:::i;:::-;1219:2;1212:22;990:250;:::o;1245:632::-;1310:5;1340:18;1381:2;1373:6;1370:14;1367:40;;;1387:18;;:::i;:::-;1462:2;1456:9;1430:2;1516:15;;-1:-1:-1;;1512:24:18;;;1538:2;1508:33;1504:42;1492:55;;;1562:18;;;1582:22;;;1559:46;1556:72;;;1608:18;;:::i;:::-;1648:10;1644:2;1637:22;1677:6;1668:15;;1707:6;1699;1692:22;1747:3;1738:6;1733:3;1729:16;1726:25;1723:45;;;1764:1;1761;1754:12;1723:45;1814:6;1809:3;1802:4;1794:6;1790:17;1777:44;1869:1;1862:4;1853:6;1845;1841:19;1837:30;1830:41;;;;1245:632;;;;;:::o;1882:222::-;1925:5;1978:3;1971:4;1963:6;1959:17;1955:27;1945:55;;1996:1;1993;1986:12;1945:55;2018:80;2094:3;2085:6;2072:20;2065:4;2057:6;2053:17;2018:80;:::i;2109:160::-;2174:20;;2230:13;;2223:21;2213:32;;2203:60;;2259:1;2256;2249:12;2274:1358;2371:6;2424:2;2412:9;2403:7;2399:23;2395:32;2392:52;;;2440:1;2437;2430:12;2392:52;2480:9;2467:23;2509:18;2550:2;2542:6;2539:14;2536:34;;;2566:1;2563;2556:12;2536:34;2589:22;;;;2645:6;2627:16;;;2623:29;2620:49;;;2665:1;2662;2655:12;2620:49;2691:17;;:::i;:::-;2746:2;2733:16;2774:2;2764:8;2761:16;2758:36;;;2790:1;2787;2780:12;2758:36;2817:45;2854:7;2843:8;2839:2;2835:17;2817:45;:::i;:::-;2810:5;2803:60;;2909:2;2905;2901:11;2888:25;2938:2;2928:8;2925:16;2922:36;;;2954:1;2951;2944:12;2922:36;2990:45;3027:7;3016:8;3012:2;3008:17;2990:45;:::i;:::-;2985:2;2978:5;2974:14;2967:69;;3082:2;3078;3074:11;3061:25;3111:2;3101:8;3098:16;3095:36;;;3127:1;3124;3117:12;3095:36;3163:45;3200:7;3189:8;3185:2;3181:17;3163:45;:::i;:::-;3158:2;3151:5;3147:14;3140:69;;3241:31;3268:2;3264;3260:11;3241:31;:::i;:::-;3236:2;3229:5;3225:14;3218:55;3306:32;3333:3;3329:2;3325:12;3306:32;:::i;:::-;3300:3;3293:5;3289:15;3282:57;3393:3;3389:2;3385:12;3372:26;3366:3;3359:5;3355:15;3348:51;3432:29;3456:3;3452:2;3448:12;3432:29;:::i;:::-;3426:3;3415:15;;3408:54;3516:3;3508:12;;;3495:26;3478:15;;;3471:51;3541:3;3589:11;;;3576:25;3560:14;;;3553:49;;;;-1:-1:-1;3419:5:18;2274:1358;-1:-1:-1;;;2274:1358:18:o;3932:585::-;4009:6;4017;4070:2;4058:9;4049:7;4045:23;4041:32;4038:52;;;4086:1;4083;4076:12;4038:52;4125:9;4112:23;4144:31;4169:5;4144:31;:::i;:::-;4194:5;-1:-1:-1;4250:2:18;4235:18;;4222:32;4277:18;4266:30;;4263:50;;;4309:1;4306;4299:12;4263:50;4332:22;;4385:4;4377:13;;4373:27;-1:-1:-1;4363:55:18;;4414:1;4411;4404:12;4363:55;4437:74;4503:7;4498:2;4485:16;4480:2;4476;4472:11;4437:74;:::i;:::-;4427:84;;;3932:585;;;;;:::o;4704:153::-;4782:20;;4831:1;4821:12;;4811:40;;4847:1;4844;4837:12;4862:212;4937:6;4990:2;4978:9;4969:7;4965:23;4961:32;4958:52;;;5006:1;5003;4996:12;4958:52;5029:39;5058:9;5029:39;:::i;5303:180::-;5362:6;5415:2;5403:9;5394:7;5390:23;5386:32;5383:52;;;5431:1;5428;5421:12;5383:52;-1:-1:-1;5454:23:18;;5303:180;-1:-1:-1;5303:180:18:o;5488:348::-;5540:8;5550:6;5604:3;5597:4;5589:6;5585:17;5581:27;5571:55;;5622:1;5619;5612:12;5571:55;-1:-1:-1;5645:20:18;;5688:18;5677:30;;5674:50;;;5720:1;5717;5710:12;5674:50;5757:4;5749:6;5745:17;5733:29;;5809:3;5802:4;5793:6;5785;5781:19;5777:30;5774:39;5771:59;;;5826:1;5823;5816:12;5771:59;5488:348;;;;;:::o;5841:1365::-;5989:6;5997;6005;6013;6021;6029;6037;6045;6053;6106:3;6094:9;6085:7;6081:23;6077:33;6074:53;;;6123:1;6120;6113:12;6074:53;6163:9;6150:23;6192:18;6233:2;6225:6;6222:14;6219:34;;;6249:1;6246;6239:12;6219:34;6288:59;6339:7;6330:6;6319:9;6315:22;6288:59;:::i;:::-;6366:8;;-1:-1:-1;6262:85:18;-1:-1:-1;6454:2:18;6439:18;;6426:32;;-1:-1:-1;6470:16:18;;;6467:36;;;6499:1;6496;6489:12;6467:36;6538:61;6591:7;6580:8;6569:9;6565:24;6538:61;:::i;:::-;6618:8;;-1:-1:-1;6512:87:18;-1:-1:-1;6706:2:18;6691:18;;6678:32;;-1:-1:-1;6722:16:18;;;6719:36;;;6751:1;6748;6741:12;6719:36;;6790:61;6843:7;6832:8;6821:9;6817:24;6790:61;:::i;:::-;6870:8;;-1:-1:-1;6764:87:18;-1:-1:-1;;6955:2:18;6940:18;;6927:32;6968:31;6927:32;6968:31;:::i;:::-;7018:5;-1:-1:-1;7075:3:18;7060:19;;7047:33;7089;7047;7089;:::i;:::-;7141:7;7131:17;;;7195:3;7184:9;7180:19;7167:33;7157:43;;5841:1365;;;;;;;;;;;:::o;7211:127::-;7272:10;7267:3;7263:20;7260:1;7253:31;7303:4;7300:1;7293:15;7327:4;7324:1;7317:15;7343:240;7427:1;7420:5;7417:12;7407:143;;7472:10;7467:3;7463:20;7460:1;7453:31;7507:4;7504:1;7497:15;7535:4;7532:1;7525:15;7407:143;7559:18;;7343:240::o;7588:885::-;7813:2;7865:21;;;7935:13;;7838:18;;;7957:22;;;7784:4;;7813:2;7998;;8016:18;;;;8057:15;;;7784:4;8100:347;8114:6;8111:1;8108:13;8100:347;;;8173:13;;8215:9;;-1:-1:-1;;;;;8211:35:18;8199:48;;8286:11;;8280:18;8311:56;8354:12;;;8280:18;8311:56;:::i;:::-;-1:-1:-1;8387:12:18;;;;8422:15;;;;8136:1;8129:9;8100:347;;;-1:-1:-1;8464:3:18;;7588:885;-1:-1:-1;;;;;;;7588:885:18:o;8478:464::-;8563:6;8571;8579;8632:2;8620:9;8611:7;8607:23;8603:32;8600:52;;;8648:1;8645;8638:12;8600:52;8687:9;8674:23;8706:31;8731:5;8706:31;:::i;:::-;8756:5;-1:-1:-1;8808:2:18;8793:18;;8780:32;;-1:-1:-1;8864:2:18;8849:18;;8836:32;8877:33;8836:32;8877:33;:::i;:::-;8929:7;8919:17;;;8478:464;;;;;:::o;9389:347::-;9473:6;9481;9534:2;9522:9;9513:7;9509:23;9505:32;9502:52;;;9550:1;9547;9540:12;9502:52;9573:39;9602:9;9573:39;:::i;:::-;9563:49;;9662:2;9651:9;9647:18;9634:32;9675:31;9700:5;9675:31;:::i;:::-;9725:5;9715:15;;;9389:347;;;;;:::o;9741:250::-;9826:1;9836:113;9850:6;9847:1;9844:13;9836:113;;;9926:11;;;9920:18;9907:11;;;9900:39;9872:2;9865:10;9836:113;;;-1:-1:-1;;9983:1:18;9965:16;;9958:27;9741:250::o;9996:271::-;10038:3;10076:5;10070:12;10103:6;10098:3;10091:19;10119:76;10188:6;10181:4;10176:3;10172:14;10165:4;10158:5;10154:16;10119:76;:::i;:::-;10249:2;10228:15;-1:-1:-1;;10224:29:18;10215:39;;;;10256:4;10211:50;;9996:271;-1:-1:-1;;9996:271:18:o;10368:1454::-;10601:2;10590:9;10583:21;10564:4;10639:6;10633:13;10665:6;10707:2;10702;10691:9;10687:18;10680:30;10733:52;10780:3;10769:9;10765:19;10751:12;10733:52;:::i;:::-;10719:66;;10834:4;10826:6;10822:17;10816:24;10863:2;10859:7;10930:2;10918:9;10910:6;10906:22;10902:31;10897:2;10886:9;10882:18;10875:59;10957:41;10991:6;10975:14;10957:41;:::i;:::-;10943:55;;11047:2;11039:6;11035:15;11029:22;11007:44;;11116:2;11104:9;11096:6;11092:22;11088:31;11082:3;11071:9;11067:19;11060:60;;11143:41;11177:6;11161:14;11143:41;:::i;:::-;11129:55;;;11233:2;11225:6;11221:15;11215:22;11246:55;11296:3;11285:9;11281:19;11265:14;-1:-1:-1;;;;;607:31:18;595:44;;541:104;11246:55;-1:-1:-1;11350:3:18;11338:16;;11332:23;-1:-1:-1;;;;;607:31:18;;11414:3;11399:19;;595:44;11364:55;11474:3;11466:6;11462:16;11456:23;11450:3;11439:9;11435:19;11428:52;11529:3;11521:6;11517:16;11511:23;11553:3;11565:51;11612:2;11601:9;11597:18;11581:14;10342:13;10335:21;10323:34;;10272:91;11565:51;11670:3;11658:16;;11652:23;11632:18;;;11625:51;;;;-1:-1:-1;11719:15:18;;11713:22;11707:3;11692:19;;11685:51;-1:-1:-1;;;;;607:31:18;;11810:4;11795:20;;595:44;11753:6;-1:-1:-1;11768:48:18;541:104;11827:411;-1:-1:-1;;;;;12099:15:18;;;12081:34;;12151:15;;12146:2;12131:18;;12124:43;12031:2;12016:18;;12176:56;12228:2;12213:18;;12205:6;12176:56;:::i;12243:408::-;12445:2;12427:21;;;12484:2;12464:18;;;12457:30;12523:34;12518:2;12503:18;;12496:62;-1:-1:-1;;;12589:2:18;12574:18;;12567:42;12641:3;12626:19;;12243:408::o;12656:::-;12858:2;12840:21;;;12897:2;12877:18;;;12870:30;12936:34;12931:2;12916:18;;12909:62;-1:-1:-1;;;13002:2:18;12987:18;;12980:42;13054:3;13039:19;;12656:408::o;13494:267::-;13583:6;13578:3;13571:19;13635:6;13628:5;13621:4;13616:3;13612:14;13599:43;-1:-1:-1;13687:1:18;13662:16;;;13680:4;13658:27;;;13651:38;;;;13743:2;13722:15;;;-1:-1:-1;;13718:29:18;13709:39;;;13705:50;;13494:267::o;13766:997::-;14169:3;14158:9;14151:22;14132:4;14196:63;14254:3;14243:9;14239:19;14231:6;14223;14196:63;:::i;:::-;14307:9;14299:6;14295:22;14290:2;14279:9;14275:18;14268:50;14341;14384:6;14376;14368;14341:50;:::i;:::-;14327:64;;14439:9;14431:6;14427:22;14422:2;14411:9;14407:18;14400:50;14467;14510:6;14502;14494;14467:50;:::i;:::-;-1:-1:-1;;;;;14591:15:18;;;14586:2;14571:18;;14564:43;14644:15;;;14638:3;14623:19;;14616:44;-1:-1:-1;;14544:3:18;14676:19;;14669:35;;;;14741:15;;;14735:3;14720:19;;;14713:44;;;;14459:58;13766:997;-1:-1:-1;;;;;;13766:997:18:o;16005:310::-;16181:2;16166:18;;16193:47;16170:9;16222:6;16193:47;:::i;:::-;-1:-1:-1;;;;;16276:32:18;;;;16271:2;16256:18;;;;16249:60;16005:310;;-1:-1:-1;16005:310:18:o;17032:184::-;17102:6;17155:2;17143:9;17134:7;17130:23;17126:32;17123:52;;;17171:1;17168;17161:12;17123:52;-1:-1:-1;17194:16:18;;17032:184;-1:-1:-1;17032:184:18:o;18046:407::-;18248:2;18230:21;;;18287:2;18267:18;;;18260:30;18326:34;18321:2;18306:18;;18299:62;-1:-1:-1;;;18392:2:18;18377:18;;18370:41;18443:3;18428:19;;18046:407::o;18872:287::-;19001:3;19039:6;19033:13;19055:66;19114:6;19109:3;19102:4;19094:6;19090:17;19055:66;:::i;:::-;19137:16;;;;;18872:287;-1:-1:-1;;18872:287:18:o;19522:220::-;19671:2;19660:9;19653:21;19634:4;19691:45;19732:2;19721:9;19717:18;19709:6;19691:45;:::i
Swarm Source
ipfs://257129f4e7b21ede59110981ac54860a00082988b4dd214ef83a84837db26646
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$294.20
Net Worth in ETH
Token Allocations
USDC
76.44%
ETH
19.80%
USDBC
3.40%
Others
0.36%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.