Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 2821356 | 416 days ago | IN | 0 ETH | 0.00865697 |
Loading...
Loading
Contract Name:
Intractopia
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; contract IntractopiaStorage { /* ============ TypeHashes and Constants ============ */ bytes32 public constant ERC1155_CLAIM_TYPEHASH = keccak256( "ERC1155Claim(uint96 rewardId,uint96 userId,uint256 tokenId,address userAddress,uint256 amountToClaim)" ); bytes32 public constant ERC1155_DUMMY_CLAIM_TYPEHASH = keccak256( "ERC1155DummyClaim(uint96 rewardId,uint96 userId,address userAddress)" ); /* ============ Events ============ */ event ERC1155SignerUpdate(address oldSigner, address newSigner); event ERC1155AdminAdded(uint256 tokenId, address admin); event ERC1155CollectionLaunch( uint256 indexed tokenId, address indexed creator, uint256 initialSupply ); event ERC1155Claim( uint96 rewardId, uint96 indexed userId, uint256 indexed tokenId, address indexed userAddress, uint256 amountToClaim ); event ERC1155DummyClaim( uint96 indexed rewardId, uint96 indexed userId, address userAddress ); /* ============ Structs ============ */ /* ============ State Variables ============ */ // Intract Signer address public intractSigner; // TokenId uint256 public currentTokenId; // Mapping from tokenId to creator address mapping (uint256 => address) public creator; // Mapping from tokenId to admin addresses mapping (uint256 => mapping (address => bool)) public isAdmin; // Mapping from tokenId to current token supply mapping (uint256 => uint256) public tokenSupply; // rewardId => userAddress => if he has claimed mapping(uint96 => mapping(address => bool)) public hasClaimed; // rewardId => userId => if he has claimed mapping(uint96 => mapping(uint96 => bool)) public hasClaimedUserId; // signature => if it has been used mapping(bytes32 => bool) public usedDummyClaimHashes; /** * @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; } contract Intractopia is Initializable, OwnableUpgradeable, PausableUpgradeable, EIP712Upgradeable, ReentrancyGuardUpgradeable, ERC1155Upgradeable, ERC2771ContextUpgradeable, IntractopiaStorage { /* ============ Modifiers ============ */ modifier tokenExists(uint256 _tokenId) { require(creator[_tokenId] != address(0), "Intractopia: TokenId does not exist"); _; } modifier onlyAdmin(uint256 _tokenId) { require(isAdmin[_tokenId][_msgSender()], "Intractopia: Only admin can call this function"); _; } /* ============ Initial setup ============ */ /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) ERC2771ContextUpgradeable(_trustedForwarder) {} function initialize(address _intractSigner, string calldata _uri) external initializer { require(_intractSigner != address(0), "Intractopia: Intract signer address must not be null address"); __Ownable_init(); __Pausable_init(); __EIP712_init("Intractopia", "1.0.0"); __ReentrancyGuard_init(); __ERC1155_init(_uri); intractSigner = _intractSigner; currentTokenId = 1; uint256 _id = currentTokenId; creator[_id] = _msgSender(); isAdmin[_id][_msgSender()] = true; _mint(_msgSender(), _id, 1, ""); tokenSupply[_id] = 1; emit ERC1155SignerUpdate(address(0), _intractSigner); } /* ============ External Functions ============ */ function createCollection( uint256 _initialSupply ) external virtual whenNotPaused nonReentrant returns (uint256) { currentTokenId += 1; uint256 _id = currentTokenId; creator[_id] = _msgSender(); isAdmin[_id][_msgSender()] = true; _mint(_msgSender(), _id, _initialSupply, ""); tokenSupply[_id] = _initialSupply; emit ERC1155CollectionLaunch(_id, _msgSender(), _initialSupply); return _id; } function claim( uint96 _rewardId, uint96 _userId, uint256 _tokenId, uint256 _amountToClaim, address _userAddress, bytes calldata _signature ) external virtual whenNotPaused nonReentrant tokenExists(_tokenId) { require(_rewardId > 0, "Intractopia: Invalid rewardId"); require(_userId > 0, "Intractopia: Invalid userId"); require(_tokenId > 0, "Intractopia: Invalid tokenId"); require(_amountToClaim > 0, "Intractopia: Invalid amount"); require(_userAddress != address(0), "Intractopia: Invalid userAddress"); require(!hasClaimed[_rewardId][_userAddress], "Intractopia: Already claimed"); require(!hasClaimedUserId[_rewardId][_userId], "Intractopia: Already claimed"); require(_verify( _hashClaim(_rewardId, _userId, _tokenId, _userAddress, _amountToClaim), _signature ), "Intractopia: Invalid signature"); hasClaimed[_rewardId][_userAddress] = true; hasClaimedUserId[_rewardId][_userId] = true; emit ERC1155Claim(_rewardId, _userId, _tokenId, _userAddress, _amountToClaim); tokenSupply[_tokenId] += _amountToClaim; _mint(_userAddress, _tokenId, _amountToClaim, ""); } function dummyClaim( uint96 _rewardId, uint96 _userId, address _userAddress, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_rewardId > 0, "Intractopia: Invalid rewardId"); require(_userId > 0, "Intractopia: Invalid userId"); require(_userAddress != address(0), "Intractopia: Invalid userAddress"); bytes32 hash = _hashDummyClaim(_rewardId, _userId, _userAddress); require(!usedDummyClaimHashes[hash], "Intractopia: Already claimed"); uint256 amountToClaim = 1; uint256 tokenId = 1; require(_verify( hash, _signature ), "Intractopia: Invalid signature"); usedDummyClaimHashes[hash] = true; emit ERC1155DummyClaim(_rewardId, _userId, _userAddress); tokenSupply[tokenId] += amountToClaim; _mint(_userAddress, tokenId, amountToClaim, ""); } function uri(uint256 _tokenId) public virtual override view returns (string memory) { return string(abi.encodePacked(super.uri(_tokenId), StringsUpgradeable.toString(_tokenId), ".json")); } /* ============ Owner Functions ============ */ function updateSigner(address _intractSigner) external onlyOwner { require(_intractSigner != address(0), "Intractopia: Invalid address"); emit ERC1155SignerUpdate(intractSigner, _intractSigner); intractSigner = _intractSigner; } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function setURI(string memory _uri) public onlyOwner { _setURI(_uri); } /* ============ Token Admin Functions ============ */ function mint( address _to, uint256 _tokenId, uint256 _amount, bytes memory _data ) external virtual nonReentrant onlyAdmin(_tokenId) { tokenSupply[_tokenId] += _amount; super._mint(_to, _tokenId, _amount, _data); } function mintBatch( address _to, uint256[] memory _tokenIds, uint256[] memory _amounts, bytes memory _data ) external virtual nonReentrant { for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 id = _tokenIds[i]; require(isAdmin[id][_msgSender()], "Intractopia: Only admin can call this function"); tokenSupply[id] += _amounts[i]; } super._mintBatch(_to, _tokenIds, _amounts, _data); } function addAdmin(uint256 _tokenId, address _admin) external virtual onlyAdmin(_tokenId) { require(_admin != address(0), "Intractopia: Invalid address"); isAdmin[_tokenId][_admin] = true; emit ERC1155AdminAdded(_tokenId, _admin); } /* ============ Fallback Functions ============ */ receive() external payable { // anonymous transfer: to admin (bool success, ) = payable(owner()).call{value: msg.value}( new bytes(0) ); require(success, "Intractopia: Transfer failed"); } fallback() external payable { if (msg.value > 0) { // call non exist function: send to admin (bool success, ) = payable(owner()).call{value: msg.value}(new bytes(0)); require(success, "Intractopia: Transfer failed"); } } /* ============ Internal Functions ============ */ function _hashClaim( uint96 _rewardId, uint96 _userId, uint256 _tokenId, address _userAddress, uint256 _amountToClaim ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC1155_CLAIM_TYPEHASH, _rewardId, _userId, _tokenId, _userAddress, _amountToClaim ) ) ); } function _hashDummyClaim( uint96 _rewardId, uint96 _userId, address _userAddress ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC1155_DUMMY_CLAIM_TYPEHASH, _rewardId, _userId, _userAddress ) ) ); } function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } function _verify(bytes32 hash, bytes calldata signature) internal view returns (bool) { return ECDSA.recover(hash, signature) == intractSigner; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @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.7.0) (metatx/ERC2771Context.sol) pragma solidity ^0.8.9; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Context variant with ERC2771 support. */ abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable address private immutable _trustedForwarder; /// @custom:oz-upgrades-unsafe-allow constructor constructor(address trustedForwarder) { _trustedForwarder = trustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } /** * @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.7.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] * ``` * 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. Equivalent to `reinitializer(1)`. */ 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. * * `initializer` is equivalent to `reinitializer(1)`, so 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. * * 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. */ 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. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @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.7.0) (token/ERC1155/ERC1155.sol) pragma solidity ^0.8.0; import "./IERC1155Upgradeable.sol"; import "./IERC1155ReceiverUpgradeable.sol"; import "./extensions/IERC1155MetadataURIUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../utils/introspection/ERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { using AddressUpgradeable for address; // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ function __ERC1155_init(string memory uri_) internal onlyInitializing { __ERC1155_init_unchained(uri_); } function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155Upgradeable).interfaceId || interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { require(account != address(0), "ERC1155: address zero is not a valid owner"); return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner nor approved" ); _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner nor approved" ); _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, to, ids, amounts, data); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn( address from, uint256 id, uint256 amount ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC1155: setting approval status for self"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non ERC1155Receiver implementer"); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non ERC1155Receiver implementer"); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } /** * @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[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library 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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) pragma solidity ^0.8.0; import "./ECDSAUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ * * @custom:storage-size 52 */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal onlyInitializing { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712NameHash() internal virtual view returns (bytes32) { return _HASHED_NAME; } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712VersionHash() internal virtual view returns (bytes32) { return _HASHED_VERSION; } /** * @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.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155Receiver.sol"; /** * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. * * @dev _Available since v3.1._ */ contract ERC1155Holder is ERC1155Receiver { function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155Receiver.sol"; import "../../../utils/introspection/ERC165.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../lib/CurrencyTransferLib.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract ERC20BulkSender is ReentrancyGuard, Ownable { using SafeERC20 for IERC20; uint256 public limit = 400; event AirdropERC20(address indexed tokenAddress, address indexed tokenOwner, address indexed recipient, uint256 amount, bool success); function setLimit(uint256 _limit) onlyOwner external { limit = _limit; } function airdrop(address tokenAddress, address[] calldata recipients, uint256[] calldata amounts) external payable nonReentrant { require(recipients.length == amounts.length, "ERC20BulkSender: Invalid input lengths"); require(recipients.length <= limit, "ERC20BulkSender: Too many recipients"); uint256 len = recipients.length; uint256 totalAmount; for (uint256 i = 0; i < amounts.length; i++) { totalAmount += amounts[i]; } if(tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { require(totalAmount == msg.value, "ERC20BulkSender: Incorrect native token amount"); } else { require(totalAmount <= IERC20(tokenAddress).allowance(msg.sender, address(this)), "ERC20BulkSender: Insufficient allowance"); } uint256 refundAmount; for (uint256 i = 0; i < len; i++) { bool success = CurrencyTransferLib.transferCurrencyWithReturnVal( tokenAddress, msg.sender, recipients[i], amounts[i] ); if (tokenAddress == CurrencyTransferLib.NATIVE_TOKEN && !success) { refundAmount += amounts[i]; } emit AirdropERC20(tokenAddress, msg.sender, recipients[i], amounts[i], success); } if (refundAmount > 0) { // refund failed payments' amount to contract admin address CurrencyTransferLib.safeTransferNativeToken(msg.sender, refundAmount); } } receive() external payable { // anonymous transfer: to admin (bool success, ) = payable(owner()).call{value: msg.value}( new bytes(0) ); require(success, "ERC20BulkSender: Transfer failed"); } fallback() external payable { if (msg.value > 0) { // call non exist function: send to admin (bool success, ) = payable(owner()).call{value: msg.value}(new bytes(0)); require(success, "ERC20BulkSender: Transfer failed"); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../lib/CurrencyTransferLib.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; contract ERC20QuestRewardsStorage { /* ============ TypeHashes and Constants ============ */ bytes32 public constant ERC20_ACTIVATE_CAMPAIGN_TYPEHASH = keccak256( "ERC20LaunchCampaign(uint96 cid,address admin,uint256 startTime,uint256 claimTime,CampaignReward[] campaignRewards)CampaignReward(uint96 rewardId,address tokenAddress,uint256 numRewards)" ); bytes32 public constant ERC20_CLAIM_TYPEHASH = keccak256( "ERC20Claim(uint96 rewardId,uint96 userId,address userAddress,uint256 amountToClaim)" ); bytes32 public constant ERC20_DUMMY_CLAIM_TYPEHASH = keccak256( "ERC20DummyClaim(uint96 cid,uint96 rewardId,uint96 userId,address userAddress)" ); bytes32 public constant ERC20_REWARD_CONFIG_TYPEHASH = keccak256( "CampaignReward(uint96 rewardId,address tokenAddress,uint256 numRewards)" ); /* ============ Events ============ */ event ERC20SignerUpdate(address oldSigner, address newSigner); event ERC20ClaimTimeUpdate(uint96 indexed cid, uint256 oldClaimTime, uint256 newClaimTime); event ERC20LaunchCampaign( uint96 indexed cid, address admin, uint256 startTime, uint256 claimTime, CampaignReward[] campaignRewards ); event ERC20Claim( uint96 indexed rewardId, uint96 indexed userId, address indexed userAddress, uint256 amountToClaim ); event ERC20DummyClaim( uint96 indexed cid, uint96 indexed rewardId, uint96 indexed userId, address userAddress ); event ERC20Withdraw( uint96 indexed cid, uint96 indexed rewardId, address indexed tokenAddress, address admin, uint256 amount ); /* ============ Structs ============ */ // Input when activating a campaign struct CampaignReward { uint96 rewardId; // reward id address tokenAddress; // token address uint256 numRewards; // number of reward tokens } struct CampaignConfig { address admin; // campaign admin, only admin can withdraw uint256 startTime; // campaign start time uint256 claimTime; // campaign claim time } struct RewardConfig { uint96 cid; // campaign id address tokenAddress; // token address uint256 numRewards; // number of reward tokens uint256 tokensClaimed; // number of tokens claimed uint256 usersClaimed; // total number of addresses who claimed } /* ============ State Variables ============ */ // Intract Signer address public intractSigner; // cid => Campaign configuration mapping(uint96 => CampaignConfig) public campaignConfigs; // cid => array of rewardIds // used only when admin wants to withdraw mapping(uint96 => uint96[]) public campaignToRewards; // rewardId => Reward configuration mapping(uint96 => RewardConfig) public rewardConfigs; // rewardId => userAddress => if he has claimed mapping(uint96 => mapping(address => bool)) public hasClaimed; // rewardId => userId => if he has claimed mapping(uint96 => mapping(uint96 => bool)) public hasClaimedUserId; // signature => if it has been used mapping(bytes32 => bool) public usedDummyClaimHashes; /** * @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; } contract ERC20QuestRewards is Initializable, OwnableUpgradeable, PausableUpgradeable, EIP712Upgradeable, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable, ERC20QuestRewardsStorage { using Address for address; /* ============ Initial setup ============ */ /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) ERC2771ContextUpgradeable(_trustedForwarder) {} function initialize(address _intractSigner) external initializer { require(_intractSigner != address(0), "ERC20QuestRewards: Intract signer address must not be null address"); __Ownable_init(); __Pausable_init(); __EIP712_init("IntractERC20QuestReward", "1.0.0"); __ReentrancyGuard_init(); intractSigner = _intractSigner; emit ERC20SignerUpdate(address(0), _intractSigner); } /* ============ External Functions ============ */ function launchCampaign( uint96 _cid, uint256 _startTime, uint256 _claimTime, CampaignReward[] calldata _campaignRewards, bytes calldata _signature ) external virtual payable whenNotPaused nonReentrant { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); require( _startTime > 0 && _startTime < _claimTime && block.timestamp < _claimTime, "ERC20QuestRewards: Invalid campaign time"); require(campaignConfigs[_cid].admin == address(0), "ERC20QuestRewards: Campaign has been activated"); uint256 nativeCoinsNeeded = 0; for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; require(numRewards > 0, "ERC20QuestRewards: Invalid number of reward tokens"); require(tokenAddress != address(0) && (tokenAddress.isContract() || tokenAddress == CurrencyTransferLib.NATIVE_TOKEN), "ERC20QuestRewards: Invalid token address"); if(tokenAddress == CurrencyTransferLib.NATIVE_TOKEN){ nativeCoinsNeeded += numRewards; } } require(msg.value == nativeCoinsNeeded, "ERC20QuestRewards: Launch campaign fail, not enough coins"); require( _verify( _hashLaunchCampaign(_cid, _msgSender(), _startTime, _claimTime, _campaignRewards), _signature ), "ERC20QuestRewards: Invalid signature" ); campaignConfigs[_cid] = CampaignConfig( _msgSender(), _startTime, _claimTime ); uint96[] memory rewardIdArr = new uint96[](_campaignRewards.length); for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; uint96 rewardId = _campaignRewards[i].rewardId; if(tokenAddress != CurrencyTransferLib.NATIVE_TOKEN){ bool deposit = IERC20(tokenAddress).transferFrom(_msgSender(), address(this), numRewards); require(deposit, "ERC20QuestRewards: Launch campaign fail, not enough tokens"); } rewardConfigs[rewardId] = RewardConfig( _cid, tokenAddress, numRewards, 0, 0 ); rewardIdArr[i] = _campaignRewards[i].rewardId; } campaignToRewards[_cid] = rewardIdArr; emit ERC20LaunchCampaign(_cid, _msgSender(), _startTime, _claimTime, _campaignRewards); } function claim( uint96 _rewardId, uint96 _userId, uint256 _amountToClaim, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_rewardId > 0, "ERC20QuestRewards: Invalid rewardId"); require(_userId > 0, "ERC20QuestRewards: Invalid userId"); require(_amountToClaim > 0, "ERC20QuestRewards: Invalid amount"); require(!hasClaimed[_rewardId][_msgSender()], "ERC20QuestRewards: Already claimed"); require(!hasClaimedUserId[_rewardId][_userId], "ERC20QuestRewards: Already claimed"); require( _verify( _hashClaim(_rewardId, _userId, _msgSender(), _amountToClaim), _signature ), "ERC20QuestRewards: Invalid signature" ); RewardConfig storage rewardConfig = rewardConfigs[_rewardId]; CampaignConfig storage campaignConfig = campaignConfigs[rewardConfig.cid]; require(rewardConfig.tokensClaimed + _amountToClaim <= rewardConfig.numRewards, "ERC20QuestRewards: Insufficient rewards available"); require(campaignConfig.startTime < block.timestamp, "ERC20QuestRewards: Claim phase not started"); require(block.timestamp < campaignConfig.claimTime, "ERC20QuestRewards: Claim phase ended"); hasClaimed[_rewardId][_msgSender()] = true; hasClaimedUserId[_rewardId][_userId] = true; rewardConfig.tokensClaimed = rewardConfig.tokensClaimed + _amountToClaim; rewardConfig.usersClaimed = rewardConfig.usersClaimed + 1; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { (bool success, ) = payable(_msgSender()).call{value: _amountToClaim}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(_msgSender(), _amountToClaim); require(success, "ERC20QuestRewards: Transfer failed"); } emit ERC20Claim(_rewardId, _userId, _msgSender(), _amountToClaim); } function dummyClaim( uint96 _cid, uint96 _rewardId, uint96 _userId, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_userId > 0, "ERC20QuestRewards: Invalid userId"); bytes32 hash = _hashDummyClaim(_cid, _rewardId, _userId, _msgSender()); require(!usedDummyClaimHashes[hash], "ERC20QuestRewards: Already claimed"); require( _verify( hash, _signature ), "ERC20QuestRewards: Invalid signature" ); uint96 dummyRewardId = 1; uint256 _amountToClaim = 1; RewardConfig storage rewardConfig = rewardConfigs[dummyRewardId]; require(rewardConfig.tokensClaimed + _amountToClaim <= rewardConfig.numRewards, "ERC20QuestRewards: Insufficient rewards available"); usedDummyClaimHashes[hash] = true; rewardConfig.tokensClaimed = rewardConfig.tokensClaimed + _amountToClaim; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { (bool success, ) = payable(_msgSender()).call{value: _amountToClaim}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(_msgSender(), _amountToClaim); require(success, "ERC20QuestRewards: Transfer failed"); } emit ERC20DummyClaim(_cid, _rewardId, _userId, _msgSender()); } function withdraw(uint96 _cid) external virtual whenNotPaused nonReentrant { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); CampaignConfig storage campaignConfig = campaignConfigs[_cid]; require(campaignConfig.admin != address(0), "ERC20QuestRewards: Campaign not found"); require(campaignConfig.startTime < block.timestamp, "ERC20QuestRewards: Withdraw phase not started"); require(campaignConfig.claimTime < block.timestamp, "ERC20QuestRewards: Claim phase still active"); uint96[] memory rewardIds = campaignToRewards[_cid]; uint256 nativeCoinsNeeded = 0; for(uint256 i = 0; i < rewardIds.length; i++) { RewardConfig storage rewardConfig = rewardConfigs[rewardIds[i]]; if(rewardConfig.tokensClaimed >= rewardConfig.numRewards) { continue; } uint256 tokensLeft = rewardConfig.numRewards - rewardConfig.tokensClaimed; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { nativeCoinsNeeded = nativeCoinsNeeded + tokensLeft; } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(campaignConfig.admin, tokensLeft); require(success, "ERC20QuestRewards: Transfer failed"); } rewardConfig.tokensClaimed = rewardConfig.numRewards; emit ERC20Withdraw(_cid, rewardIds[i], rewardConfig.tokenAddress, campaignConfig.admin, tokensLeft); } if(nativeCoinsNeeded > 0) { (bool success, ) = campaignConfig.admin.call{value: nativeCoinsNeeded}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } } /* ============ Owner Functions ============ */ function updateSigner(address _intractSigner) external onlyOwner { require(_intractSigner != address(0), "ERC20QuestRewards: Invalid address"); intractSigner = _intractSigner; emit ERC20SignerUpdate(intractSigner, _intractSigner); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function updateClaimTime(uint96 _cid, uint256 _newClaimTime) external onlyOwner { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); CampaignConfig storage campaignConfig = campaignConfigs[_cid]; require(campaignConfig.admin != address(0), "ERC20QuestRewards: Campaign not found"); uint256 oldClaimTime = campaignConfig.claimTime; campaignConfig.claimTime = _newClaimTime; emit ERC20ClaimTimeUpdate(_cid, oldClaimTime, _newClaimTime); } /* ============ Fallback Functions ============ */ receive() external payable { // anonymous transfer: to admin (bool success, ) = payable(owner()).call{value: msg.value}( new bytes(0) ); require(success, "ERC20QuestRewards: Transfer failed"); } fallback() external payable { if (msg.value > 0) { // call non exist function: send to admin (bool success, ) = payable(owner()).call{value: msg.value}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } } /* ============ Internal Functions ============ */ function _hashLaunchCampaign( uint96 _cid, address _admin, uint256 _startTime, uint256 _claimTime, CampaignReward[] calldata _campaignRewards ) internal view returns (bytes32) { bytes32[] memory encodedCamapignRewards = new bytes32[](_campaignRewards.length); for(uint256 i = 0; i < _campaignRewards.length; i++) { encodedCamapignRewards[i] = keccak256( abi.encode( ERC20_REWARD_CONFIG_TYPEHASH, _campaignRewards[i].rewardId, _campaignRewards[i].tokenAddress, _campaignRewards[i].numRewards ) ); } return _hashTypedDataV4( keccak256( abi.encode( ERC20_ACTIVATE_CAMPAIGN_TYPEHASH, _cid, _admin, _startTime, _claimTime, keccak256(abi.encodePacked(encodedCamapignRewards)) ) ) ); } function _hashClaim( uint96 _rewardId, uint96 _userId, address _userAddress, uint256 _amountToClaim ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC20_CLAIM_TYPEHASH, _rewardId, _userId, _userAddress, _amountToClaim ) ) ); } function _hashDummyClaim( uint96 _cid, uint96 _rewardId, uint96 _userId, address _userAddress ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC20_DUMMY_CLAIM_TYPEHASH, _cid, _rewardId, _userId, _userAddress ) ) ); } function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } function _verify(bytes32 hash, bytes calldata signature) internal view returns (bool) { return ECDSA.recover(hash, signature) == intractSigner; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IWETH { function deposit() external payable; function withdraw(uint256 amount) external; function transfer(address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /// @author thirdweb // Helper interfaces import { IWETH } from "../interfaces/IWETH.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; library CurrencyTransferLib { using SafeERC20 for IERC20; /// @dev The address interpreted as native token of the chain. address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /// @dev Transfers a given amount of currency. function transferCurrency( address _currency, address _from, address _to, uint256 _amount ) internal { if (_amount == 0) { return; } if (_currency == NATIVE_TOKEN) { safeTransferNativeToken(_to, _amount); } else { safeTransferERC20(_currency, _from, _to, _amount); } } /// @dev Transfers a given amount of currency. (With native token wrapping) function transferCurrencyWithWrapper( address _currency, address _from, address _to, uint256 _amount, address _nativeTokenWrapper ) internal { if (_amount == 0) { return; } if (_currency == NATIVE_TOKEN) { if (_from == address(this)) { // withdraw from weth then transfer withdrawn native token to recipient IWETH(_nativeTokenWrapper).withdraw(_amount); safeTransferNativeTokenWithWrapper(_to, _amount, _nativeTokenWrapper); } else if (_to == address(this)) { // store native currency in weth require(_amount == msg.value, "msg.value != amount"); IWETH(_nativeTokenWrapper).deposit{ value: _amount }(); } else { safeTransferNativeTokenWithWrapper(_to, _amount, _nativeTokenWrapper); } } else { safeTransferERC20(_currency, _from, _to, _amount); } } /// @dev Transfer `amount` of ERC20 token from `from` to `to`. function safeTransferERC20( address _currency, address _from, address _to, uint256 _amount ) internal { if (_from == _to) { return; } if (_from == address(this)) { IERC20(_currency).safeTransfer(_to, _amount); } else { IERC20(_currency).safeTransferFrom(_from, _to, _amount); } } /// @dev Transfers `amount` of native token to `to`. function safeTransferNativeToken(address to, uint256 value) internal { // solhint-disable avoid-low-level-calls // slither-disable-next-line low-level-calls (bool success, ) = to.call{ value: value }(""); require(success, "native token transfer failed"); } /// @dev Transfers `amount` of native token to `to`. (With native token wrapping) function safeTransferNativeTokenWithWrapper( address to, uint256 value, address _nativeTokenWrapper ) internal { // solhint-disable avoid-low-level-calls // slither-disable-next-line low-level-calls (bool success, ) = to.call{ value: value }(""); if (!success) { IWETH(_nativeTokenWrapper).deposit{ value: value }(); IERC20(_nativeTokenWrapper).safeTransfer(to, value); } } /// @dev Transfers ERC20 tokens and returns a boolean i.e. the status of the transfer. function transferCurrencyWithReturnVal( address _currency, address _from, address _to, uint256 _amount ) internal returns (bool success) { if (_amount == 0) { success = true; return success; } if (_currency == CurrencyTransferLib.NATIVE_TOKEN) { // solhint-disable avoid-low-level-calls // slither-disable-next-line low-level-calls (success, ) = _to.call{ value: _amount, gas: 80_000 }(""); } else { (bool success_, bytes memory data_) = _currency.call( abi.encodeWithSelector(IERC20.transferFrom.selector, _from, _to, _amount) ); success = success_; if (!success || (data_.length > 0 && !abi.decode(data_, (bool)))) { success = false; require( IERC20(_currency).balanceOf(_from) >= _amount && IERC20(_currency).allowance(_from, address(this)) >= _amount, "Not balance or allowance" ); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; contract BadAddress { receive() external payable { revert("Cannot accept ether"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "../erc20/ERC20BulkSender.sol"; contract BadAddress2 { address[] recipients = [address(this)]; uint256[] amounts = [0]; receive() external payable { ERC20BulkSender(payable(msg.sender)).airdrop(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, recipients, amounts); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; contract BadAddress3 { // no receive or fallback function function hello() public returns (bool) { return true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "../erc20/ERC20QuestRewards.sol"; import "hardhat/console.sol"; contract BadAddress4 { uint96 rewardId; uint96 userId; uint256 amountToClaim; bytes signature; function storeParams(uint96 _rewardId, uint96 _userId, uint256 _amountToClaim, bytes memory _signature) public { rewardId = _rewardId; userId = _userId; amountToClaim = _amountToClaim; signature = _signature; } receive() external payable { console.log("BadAddress4: msg.sender: %s", msg.sender); try ERC20QuestRewards(payable(msg.sender)).claim(rewardId, userId, amountToClaim, signature) { } catch Error(string memory reason) { // catch failing revert() and require() console.log("BadAddress4: Error: %s", reason); } catch (bytes memory reason) { // catch failing assert() console.logBytes(reason); } } function attack(address payable _target) public payable { ERC20QuestRewards(_target).claim(rewardId, userId, amountToClaim, signature); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "../erc1155/Intractopia.sol"; import "hardhat/console.sol"; import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; contract BadAddress5 is ERC1155Holder { uint96 rewardId; uint96 userId; uint256 tokenId; uint256 amountToClaim; bytes signature; function storeParams(uint96 _rewardId, uint96 _userId, uint256 _tokenId, uint256 _amountToClaim, bytes memory _signature) public { rewardId = _rewardId; userId = _userId; tokenId = _tokenId; amountToClaim = _amountToClaim; signature = _signature; } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { console.log("BadAddress5: msg.sender: %s", msg.sender); try Intractopia(payable(msg.sender)).claim(rewardId, userId, tokenId, amountToClaim, address(this), signature) { } catch Error(string memory reason) { // catch failing revert() and require() console.log("BadAddress5: Error: %s", reason); } catch (bytes memory reason) { // catch failing assert() console.logBytes(reason); } return this.onERC1155Received.selector; } function attack(address payable _target) public payable { Intractopia(_target).claim(rewardId, userId, tokenId, amountToClaim, address(this), signature); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract BadToken is ERC20 { address bulkSender; constructor(address _bulkSender) ERC20("Bad Token", "BT") { bulkSender = _bulkSender; } function _beforeTokenTransfer(address from, address to, uint256 amount) internal override { if(msg.sender == bulkSender) { revert("Bad Token"); } } function allowance(address owner, address spender) public view override returns (uint256) { return 10000 ether; } function mint(address to, uint256 amount) external { _mint(to, amount); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../lib/CurrencyTransferLib.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; contract ERC20QuestRewardsStorage { /* ============ TypeHashes and Constants ============ */ bytes32 public constant ERC20_ACTIVATE_CAMPAIGN_TYPEHASH = keccak256( "ERC20LaunchCampaign(uint96 cid,address admin,uint256 startTime,uint256 claimTime,CampaignReward[] campaignRewards)CampaignReward(uint96 rewardId,address tokenAddress,uint256 numRewards)" ); bytes32 public constant ERC20_CLAIM_TYPEHASH = keccak256( "ERC20Claim(uint96 rewardId,uint96 userId,address userAddress,uint256 amountToClaim)" ); bytes32 public constant ERC20_DUMMY_CLAIM_TYPEHASH = keccak256( "ERC20DummyClaim(uint96 cid,uint96 rewardId,uint96 userId,address userAddress)" ); bytes32 public constant ERC20_REWARD_CONFIG_TYPEHASH = keccak256( "CampaignReward(uint96 rewardId,address tokenAddress,uint256 numRewards)" ); /* ============ Events ============ */ event ERC20SignerUpdate(address oldSigner, address newSigner); event ERC20ClaimTimeUpdate(uint96 indexed cid, uint256 oldClaimTime, uint256 newClaimTime); event ERC20LaunchCampaign( uint96 indexed cid, address admin, uint256 startTime, uint256 claimTime, CampaignReward[] campaignRewards ); event ERC20Claim( uint96 indexed rewardId, uint96 indexed userId, address indexed userAddress, uint256 amountToClaim ); event ERC20DummyClaim( uint96 indexed cid, uint96 indexed rewardId, uint96 indexed userId, address userAddress ); event ERC20Withdraw( uint96 indexed cid, uint96 indexed rewardId, address indexed tokenAddress, address admin, uint256 amount ); /* ============ Structs ============ */ // Input when activating a campaign struct CampaignReward { uint96 rewardId; // reward id address tokenAddress; // token address uint256 numRewards; // number of reward tokens } struct CampaignConfig { address admin; // campaign admin, only admin can withdraw uint256 startTime; // campaign start time uint256 claimTime; // campaign claim time } struct RewardConfig { uint96 cid; // campaign id address tokenAddress; // token address uint256 numRewards; // number of reward tokens uint256 tokensClaimed; // number of tokens claimed uint256 usersClaimed; // total number of addresses who claimed } /* ============ State Variables ============ */ // Intract Signer address public intractSigner; // cid => Campaign configuration mapping(uint96 => CampaignConfig) public campaignConfigs; // cid => array of rewardIds // used only when admin wants to withdraw mapping(uint96 => uint96[]) public campaignToRewards; // rewardId => Reward configuration mapping(uint96 => RewardConfig) public rewardConfigs; // rewardId => userAddress => if he has claimed mapping(uint96 => mapping(address => bool)) public hasClaimed; // rewardId => userId => if he has claimed mapping(uint96 => mapping(uint96 => bool)) public hasClaimedUserId; // signature => if it has been used mapping(bytes32 => bool) public usedDummyClaimHashes; uint256 public newVariable; /** * @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[48] private __gap; } contract ERC20QuestRewards_ is Initializable, OwnableUpgradeable, PausableUpgradeable, EIP712Upgradeable, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable, ERC20QuestRewardsStorage { using Address for address; /* ============ Initial setup ============ */ /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) ERC2771ContextUpgradeable(_trustedForwarder) {} function initialize(address _intractSigner) external initializer { require(_intractSigner != address(0), "ERC20QuestRewards: Intract signer address must not be null address"); __Ownable_init(); __Pausable_init(); __EIP712_init("IntractERC20QuestReward", "1.0.0"); __ReentrancyGuard_init(); intractSigner = _intractSigner; emit ERC20SignerUpdate(address(0), _intractSigner); } /* ============ External Functions ============ */ function launchCampaign( uint96 _cid, uint256 _startTime, uint256 _claimTime, CampaignReward[] calldata _campaignRewards, bytes calldata _signature ) external virtual payable whenNotPaused nonReentrant { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); require( _startTime > 0 && _startTime < _claimTime && block.timestamp < _claimTime, "ERC20QuestRewards: Invalid campaign time"); require(campaignConfigs[_cid].admin == address(0), "ERC20QuestRewards: Campaign has been activated"); uint256 nativeCoinsNeeded = 0; for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; require(numRewards > 0, "ERC20QuestRewards: Invalid number of reward tokens"); require(tokenAddress != address(0) && (tokenAddress.isContract() || tokenAddress == CurrencyTransferLib.NATIVE_TOKEN), "ERC20QuestRewards: Invalid token address"); if(tokenAddress == CurrencyTransferLib.NATIVE_TOKEN){ nativeCoinsNeeded += numRewards; } } require(msg.value == nativeCoinsNeeded, "ERC20QuestRewards: Launch campaign fail, not enough coins"); require( _verify( _hashLaunchCampaign(_cid, _msgSender(), _startTime, _claimTime, _campaignRewards), _signature ), "ERC20QuestRewards: Invalid signature" ); campaignConfigs[_cid] = CampaignConfig( _msgSender(), _startTime, _claimTime ); uint96[] memory rewardIdArr = new uint96[](_campaignRewards.length); for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; uint96 rewardId = _campaignRewards[i].rewardId; if(tokenAddress != CurrencyTransferLib.NATIVE_TOKEN){ bool deposit = IERC20(tokenAddress).transferFrom(_msgSender(), address(this), numRewards); require(deposit, "ERC20QuestRewards: Launch campaign fail, not enough tokens"); } rewardConfigs[rewardId] = RewardConfig( _cid, tokenAddress, numRewards, 0, 0 ); rewardIdArr[i] = _campaignRewards[i].rewardId; } campaignToRewards[_cid] = rewardIdArr; emit ERC20LaunchCampaign(_cid, _msgSender(), _startTime, _claimTime, _campaignRewards); } function claim( uint96 _rewardId, uint96 _userId, uint256 _amountToClaim, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_rewardId > 0, "ERC20QuestRewards: Invalid rewardId"); require(_userId > 0, "ERC20QuestRewards: Invalid userId"); require(_amountToClaim > 0, "ERC20QuestRewards: Invalid amount"); require(!hasClaimed[_rewardId][_msgSender()], "ERC20QuestRewards: Already claimed"); require(!hasClaimedUserId[_rewardId][_userId], "ERC20QuestRewards: Already claimed"); require( _verify( _hashClaim(_rewardId, _userId, _msgSender(), _amountToClaim), _signature ), "ERC20QuestRewards: Invalid signature" ); RewardConfig storage rewardConfig = rewardConfigs[_rewardId]; CampaignConfig storage campaignConfig = campaignConfigs[rewardConfig.cid]; require(rewardConfig.tokensClaimed + _amountToClaim <= rewardConfig.numRewards, "ERC20QuestRewards: Insufficient rewards available"); require(campaignConfig.startTime < block.timestamp, "ERC20QuestRewards: Claim phase not started"); require(block.timestamp < campaignConfig.claimTime, "ERC20QuestRewards: Claim phase ended"); hasClaimed[_rewardId][_msgSender()] = true; hasClaimedUserId[_rewardId][_userId] = true; rewardConfig.tokensClaimed = rewardConfig.tokensClaimed + _amountToClaim; rewardConfig.usersClaimed = rewardConfig.usersClaimed + 1; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { (bool success, ) = payable(_msgSender()).call{value: _amountToClaim}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(_msgSender(), _amountToClaim); require(success, "ERC20QuestRewards: Transfer failed"); } emit ERC20Claim(_rewardId, _userId, _msgSender(), _amountToClaim); } function dummyClaim( uint96 _cid, uint96 _rewardId, uint96 _userId, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_userId > 0, "ERC20QuestRewards: Invalid userId"); bytes32 hash = _hashDummyClaim(_cid, _rewardId, _userId, _msgSender()); require(!usedDummyClaimHashes[hash], "ERC20QuestRewards: Already claimed"); require( _verify( hash, _signature ), "ERC20QuestRewards: Invalid signature" ); uint96 dummyRewardId = 1; uint256 _amountToClaim = 1; RewardConfig storage rewardConfig = rewardConfigs[dummyRewardId]; require(rewardConfig.tokensClaimed + _amountToClaim <= rewardConfig.numRewards, "ERC20QuestRewards: Insufficient rewards available"); usedDummyClaimHashes[hash] = true; rewardConfig.tokensClaimed = rewardConfig.tokensClaimed + _amountToClaim; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { (bool success, ) = payable(_msgSender()).call{value: _amountToClaim}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(_msgSender(), _amountToClaim); require(success, "ERC20QuestRewards: Transfer failed"); } emit ERC20DummyClaim(_cid, _rewardId, _userId, _msgSender()); } function withdraw(uint96 _cid) external virtual whenNotPaused nonReentrant { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); CampaignConfig storage campaignConfig = campaignConfigs[_cid]; require(campaignConfig.admin != address(0), "ERC20QuestRewards: Campaign not found"); require(campaignConfig.startTime < block.timestamp, "ERC20QuestRewards: Withdraw phase not started"); require(campaignConfig.claimTime < block.timestamp, "ERC20QuestRewards: Claim phase still active"); uint96[] memory rewardIds = campaignToRewards[_cid]; uint256 nativeCoinsNeeded = 0; for(uint256 i = 0; i < rewardIds.length; i++) { RewardConfig storage rewardConfig = rewardConfigs[rewardIds[i]]; if(rewardConfig.tokensClaimed >= rewardConfig.numRewards) { continue; } uint256 tokensLeft = rewardConfig.numRewards - rewardConfig.tokensClaimed; if (rewardConfig.tokenAddress == CurrencyTransferLib.NATIVE_TOKEN) { nativeCoinsNeeded = nativeCoinsNeeded + tokensLeft; } else { bool success = IERC20(rewardConfig.tokenAddress).transfer(campaignConfig.admin, tokensLeft); require(success, "ERC20QuestRewards: Transfer failed"); } rewardConfig.tokensClaimed = rewardConfig.numRewards; emit ERC20Withdraw(_cid, rewardIds[i], rewardConfig.tokenAddress, campaignConfig.admin, tokensLeft); } if(nativeCoinsNeeded > 0) { (bool success, ) = campaignConfig.admin.call{value: nativeCoinsNeeded}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } } /* ============ Owner Functions ============ */ function updateSigner(address _intractSigner) external onlyOwner { require(_intractSigner != address(0), "ERC20QuestRewards: Invalid address"); intractSigner = _intractSigner; emit ERC20SignerUpdate(intractSigner, _intractSigner); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function updateClaimTime(uint96 _cid, uint256 _newClaimTime) external onlyOwner { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); CampaignConfig storage campaignConfig = campaignConfigs[_cid]; require(campaignConfig.admin != address(0), "ERC20QuestRewards: Campaign not found"); uint256 oldClaimTime = campaignConfig.claimTime; campaignConfig.claimTime = _newClaimTime; emit ERC20ClaimTimeUpdate(_cid, oldClaimTime, _newClaimTime); } /* ============ Fallback Functions ============ */ receive() external payable { // anonymous transfer: to admin (bool success, ) = payable(owner()).call{value: msg.value}( new bytes(0) ); require(success, "ERC20QuestRewards: Transfer failed"); } fallback() external payable { if (msg.value > 0) { // call non exist function: send to admin (bool success, ) = payable(owner()).call{value: msg.value}(new bytes(0)); require(success, "ERC20QuestRewards: Transfer failed"); } } /* ============ Internal Functions ============ */ function _hashLaunchCampaign( uint96 _cid, address _admin, uint256 _startTime, uint256 _claimTime, CampaignReward[] calldata _campaignRewards ) internal view returns (bytes32) { bytes32[] memory encodedCamapignRewards = new bytes32[](_campaignRewards.length); for(uint256 i = 0; i < _campaignRewards.length; i++) { encodedCamapignRewards[i] = keccak256( abi.encode( ERC20_REWARD_CONFIG_TYPEHASH, _campaignRewards[i].rewardId, _campaignRewards[i].tokenAddress, _campaignRewards[i].numRewards ) ); } return _hashTypedDataV4( keccak256( abi.encode( ERC20_ACTIVATE_CAMPAIGN_TYPEHASH, _cid, _admin, _startTime, _claimTime, keccak256(abi.encodePacked(encodedCamapignRewards)) ) ) ); } function _hashClaim( uint96 _rewardId, uint96 _userId, address _userAddress, uint256 _amountToClaim ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC20_CLAIM_TYPEHASH, _rewardId, _userId, _userAddress, _amountToClaim ) ) ); } function _hashDummyClaim( uint96 _cid, uint96 _rewardId, uint96 _userId, address _userAddress ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC20_DUMMY_CLAIM_TYPEHASH, _cid, _rewardId, _userId, _userAddress ) ) ); } function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } function _verify(bytes32 hash, bytes calldata signature) internal view returns (bool) { return ECDSA.recover(hash, signature) == intractSigner; } } contract ERC20QuestRewardsV2 is ERC20QuestRewards_ { using Address for address; /* ============ Constructor ============ */ /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) ERC20QuestRewards_(_trustedForwarder) {} /* ============ External Functions ============ */ function launchCampaign( uint96 _cid, uint256 _startTime, uint256 _claimTime, CampaignReward[] calldata _campaignRewards, bytes calldata _signature ) external virtual override payable whenNotPaused nonReentrant { require(_cid > 0, "ERC20QuestRewards: Invalid cid"); require( _startTime > 0 && _startTime < _claimTime && block.timestamp < _claimTime, "ERC20QuestRewards: Invalid campaign time"); require(campaignConfigs[_cid].admin == address(0), "ERC20QuestRewards: Campaign has been activated"); uint256 nativeCoinsNeeded = 0; for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; require(numRewards > 0, "ERC20QuestRewards: Invalid number of reward tokens"); require(tokenAddress != address(0) && (tokenAddress.isContract() || tokenAddress == CurrencyTransferLib.NATIVE_TOKEN), "ERC20QuestRewards: Invalid token address"); if(tokenAddress == CurrencyTransferLib.NATIVE_TOKEN){ nativeCoinsNeeded += numRewards; } } require(msg.value == nativeCoinsNeeded, "ERC20QuestRewards: Launch campaign fail, not enough coins"); require( _verify( _hashLaunchCampaign(_cid, msg.sender, _startTime, _claimTime, _campaignRewards), _signature ), "ERC20QuestRewards: Invalid signature" ); campaignConfigs[_cid] = CampaignConfig( msg.sender, _startTime, _claimTime ); uint96[] memory rewardIdArr = new uint96[](_campaignRewards.length); for(uint256 i=0; i < _campaignRewards.length; i++) { address tokenAddress = _campaignRewards[i].tokenAddress; uint256 numRewards = _campaignRewards[i].numRewards; uint96 rewardId = _campaignRewards[i].rewardId; if(tokenAddress != CurrencyTransferLib.NATIVE_TOKEN){ bool deposit = IERC20(tokenAddress).transferFrom(msg.sender, address(this), numRewards); require(deposit, "ERC20QuestRewards: Launch campaign fail, not enough tokens"); } rewardConfigs[rewardId] = RewardConfig( _cid, tokenAddress, numRewards, 0, 0 ); rewardIdArr[i] = _campaignRewards[i].rewardId; } campaignToRewards[_cid] = rewardIdArr; emit ERC20LaunchCampaign(_cid, msg.sender, _startTime, _claimTime, _campaignRewards); } function version2() external pure returns (bool success) { return true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract DummyToken is ERC20 { uint256 public constant INITIAL_SUPPLY = type(uint256).max; constructor() ERC20("Intract Dummy Token", "IDT") { _mint(msg.sender, INITIAL_SUPPLY); } function decimals() public pure override returns (uint8) { return 1; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "hardhat/console.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; contract IntractopiaStorageV2 { /* ============ TypeHashes and Constants ============ */ bytes32 public constant ERC1155_CLAIM_TYPEHASH = keccak256( "ERC1155Claim(uint96 rewardId,uint96 userId,uint256 tokenId,address userAddress,uint256 amountToClaim)" ); bytes32 public constant ERC1155_DUMMY_CLAIM_TYPEHASH = keccak256( "ERC1155DummyClaim(uint96 rewardId,uint96 userId,address userAddress)" ); /* ============ Events ============ */ event ERC1155SignerUpdate(address oldSigner, address newSigner); event ERC1155AdminAdded(uint256 tokenId, address admin); event ERC1155CollectionLaunch( uint256 indexed tokenId, address indexed creator, uint256 initialSupply ); event ERC1155Claim( uint96 rewardId, uint96 indexed userId, uint256 indexed tokenId, address indexed userAddress, uint256 amountToClaim ); event ERC1155DummyClaim( uint96 indexed rewardId, uint96 indexed userId, address userAddress ); /* ============ Structs ============ */ /* ============ State Variables ============ */ // Intract Signer address public intractSigner; // TokenId uint256 public currentTokenId; // Mapping from tokenId to creator address mapping (uint256 => address) public creator; // Mapping from tokenId to admin addresses mapping (uint256 => mapping (address => bool)) public isAdmin; // Mapping from tokenId to current token supply mapping (uint256 => uint256) public tokenSupply; // rewardId => userAddress => if he has claimed mapping(uint96 => mapping(address => bool)) public hasClaimed; // rewardId => userId => if he has claimed mapping(uint96 => mapping(uint96 => bool)) public hasClaimedUserId; // signature => if it has been used mapping(bytes32 => bool) public usedDummyClaimHashes; mapping(uint256 => string) public uris; /** * @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[48] private __gap; } contract IntractopiaV1 is Initializable, OwnableUpgradeable, PausableUpgradeable, EIP712Upgradeable, ReentrancyGuardUpgradeable, ERC1155Upgradeable, ERC2771ContextUpgradeable, IntractopiaStorageV2 { /* ============ Modifiers ============ */ modifier tokenExists(uint256 _tokenId) { require(creator[_tokenId] != address(0), "Intractopia: TokenId does not exist"); _; } modifier onlyAdmin(uint256 _tokenId) { require(isAdmin[_tokenId][_msgSender()], "Intractopia: Only admin can call this function"); _; } /* ============ Initial setup ============ */ /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) ERC2771ContextUpgradeable(_trustedForwarder) {} function initialize(address _intractSigner, string calldata _uri) external initializer { require(_intractSigner != address(0), "Intractopia: Intract signer address must not be null address"); __Ownable_init(); __Pausable_init(); __EIP712_init("Intractopia", "1.0.0"); __ReentrancyGuard_init(); __ERC1155_init(_uri); intractSigner = _intractSigner; currentTokenId = 1; uint256 _id = currentTokenId; creator[_id] = _msgSender(); isAdmin[_id][_msgSender()] = true; _mint(_msgSender(), _id, 1, ""); tokenSupply[_id] = 1; emit ERC1155SignerUpdate(address(0), _intractSigner); } /* ============ External Functions ============ */ function createCollection( uint256 _initialSupply ) external virtual whenNotPaused nonReentrant returns (uint256) { currentTokenId += 1; uint256 _id = currentTokenId; creator[_id] = _msgSender(); isAdmin[_id][_msgSender()] = true; _mint(_msgSender(), _id, _initialSupply, ""); tokenSupply[_id] = _initialSupply; emit ERC1155CollectionLaunch(_id, _msgSender(), _initialSupply); return _id; } function claim( uint96 _rewardId, uint96 _userId, uint256 _tokenId, uint256 _amountToClaim, bytes calldata _signature ) external virtual whenNotPaused nonReentrant tokenExists(_tokenId) { require(_rewardId > 0, "Intractopia: Invalid rewardId"); require(_userId > 0, "Intractopia: Invalid userId"); require(_tokenId > 0, "Intractopia: Invalid tokenId"); require(_amountToClaim > 0, "Intractopia: Invalid amount"); require(!hasClaimed[_rewardId][_msgSender()], "Intractopia: Already claimed"); require(!hasClaimedUserId[_rewardId][_userId], "Intractopia: Already claimed"); require(_verify( _hashClaim(_rewardId, _userId, _tokenId, _msgSender(), _amountToClaim), _signature ), "Intractopia: Invalid signature"); hasClaimed[_rewardId][_msgSender()] = true; hasClaimedUserId[_rewardId][_userId] = true; emit ERC1155Claim(_rewardId, _userId, _tokenId, _msgSender(), _amountToClaim); _mint(_msgSender(), _tokenId, _amountToClaim, ""); } function dummyClaim( uint96 _rewardId, uint96 _userId, bytes calldata _signature ) external virtual whenNotPaused nonReentrant { require(_rewardId > 0, "Intractopia: Invalid rewardId"); require(_userId > 0, "Intractopia: Invalid userId"); bytes32 hash = _hashDummyClaim(_rewardId, _userId, _msgSender()); require(!usedDummyClaimHashes[hash], "Intractopia: Already claimed"); uint256 amountToClaim = 1; uint256 tokenId = 1; require(_verify( hash, _signature ), "Intractopia: Invalid signature"); usedDummyClaimHashes[hash] = true; emit ERC1155DummyClaim(_rewardId, _userId, _msgSender()); _mint(_msgSender(), tokenId, amountToClaim, ""); } function uri(uint256 _tokenId) public virtual override view returns (string memory) { return string(abi.encodePacked(super.uri(_tokenId), StringsUpgradeable.toString(_tokenId), ".json")); } /* ============ Owner Functions ============ */ function updateSigner(address _intractSigner) external onlyOwner { require(_intractSigner != address(0), "Intractopia: Invalid address"); emit ERC1155SignerUpdate(intractSigner, _intractSigner); intractSigner = _intractSigner; } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function setURI(string memory _uri) public onlyOwner { _setURI(_uri); } /* ============ Token Admin Functions ============ */ function mint( address _to, uint256 _tokenId, uint256 _amount, bytes memory _data ) external virtual nonReentrant onlyAdmin(_tokenId) { tokenSupply[_tokenId] += _amount; super._mint(_to, _tokenId, _amount, _data); } function mintBatch( address _to, uint256[] memory _tokenIds, uint256[] memory _amounts, bytes memory _data ) external virtual nonReentrant { for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 id = _tokenIds[i]; require(isAdmin[id][_msgSender()], "Intractopia: Only admin can call this function"); tokenSupply[id] += _amounts[i]; } super._mintBatch(_to, _tokenIds, _amounts, _data); } function addAdmin(uint256 _tokenId, address _admin) external virtual onlyAdmin(_tokenId) { require(_admin != address(0), "Intractopia: Invalid address"); isAdmin[_tokenId][_admin] = true; emit ERC1155AdminAdded(_tokenId, _admin); } /* ============ Fallback Functions ============ */ receive() external payable { // anonymous transfer: to admin (bool success, ) = payable(owner()).call{value: msg.value}( new bytes(0) ); require(success, "Intractopia: Transfer failed"); } fallback() external payable { if (msg.value > 0) { // call non exist function: send to admin (bool success, ) = payable(owner()).call{value: msg.value}(new bytes(0)); require(success, "Intractopia: Transfer failed"); } } /* ============ Internal Functions ============ */ function _hashClaim( uint96 _rewardId, uint96 _userId, uint256 _tokenId, address _userAddress, uint256 _amountToClaim ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC1155_CLAIM_TYPEHASH, _rewardId, _userId, _tokenId, _userAddress, _amountToClaim ) ) ); } function _hashDummyClaim( uint96 _rewardId, uint96 _userId, address _userAddress ) internal view returns (bytes32) { return _hashTypedDataV4( keccak256( abi.encode( ERC1155_DUMMY_CLAIM_TYPEHASH, _rewardId, _userId, _userAddress ) ) ); } function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } function _verify(bytes32 hash, bytes calldata signature) internal view returns (bool) { return ECDSA.recover(hash, signature) == intractSigner; } } contract IntractopiaV2 is IntractopiaV1 { /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _trustedForwarder) IntractopiaV1(_trustedForwarder) {} function createCollection( uint256 _initialSupply, string memory _uri ) external virtual whenNotPaused nonReentrant returns (uint256) { currentTokenId += 1; uint256 _id = currentTokenId; creator[_id] = _msgSender(); isAdmin[_id][_msgSender()] = true; tokenSupply[_id] = _initialSupply; uris[_id] = _uri; emit ERC1155CollectionLaunch(_id, _msgSender(), _initialSupply); _mint(_msgSender(), _id, _initialSupply, ""); return _id; } function uri(uint256 _tokenId) public virtual override view returns (string memory) { string memory tokenURI = uris[_tokenId]; if(bytes(tokenURI).length > 0) { return tokenURI; } return super.uri(_tokenId); } function setURI(uint256 _tokenId, string memory _uri) external virtual onlyAdmin(_tokenId) { uris[_tokenId] = _uri; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract USDC is ERC20 { constructor() ERC20("USD Coin", "USDC") {} function mint(address to, uint256 amount) external { _mint(to, amount); } function bulkMint(address[] calldata to, uint256 amount) external { for(uint256 i = 0; i < to.length; i++) { _mint(to[i], amount); } } // function decimals() public view virtual override returns (uint8) { // return 6; // } }
// SPDX-License-Identifier: MIT pragma solidity >= 0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_trustedForwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"ERC1155AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"rewardId","type":"uint96"},{"indexed":true,"internalType":"uint96","name":"userId","type":"uint96"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountToClaim","type":"uint256"}],"name":"ERC1155Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"initialSupply","type":"uint256"}],"name":"ERC1155CollectionLaunch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint96","name":"rewardId","type":"uint96"},{"indexed":true,"internalType":"uint96","name":"userId","type":"uint96"},{"indexed":false,"internalType":"address","name":"userAddress","type":"address"}],"name":"ERC1155DummyClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"ERC1155SignerUpdate","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ERC1155_CLAIM_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC1155_DUMMY_CLAIM_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"_rewardId","type":"uint96"},{"internalType":"uint96","name":"_userId","type":"uint96"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amountToClaim","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_initialSupply","type":"uint256"}],"name":"createCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"_rewardId","type":"uint96"},{"internalType":"uint96","name":"_userId","type":"uint96"},{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"dummyClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"address","name":"","type":"address"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"uint96","name":"","type":"uint96"}],"name":"hasClaimedUserId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_intractSigner","type":"address"},{"internalType":"string","name":"_uri","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"intractSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_intractSigner","type":"address"}],"name":"updateSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedDummyClaimHashes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162003e0138038062003e01833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b608051613d666200009b600039600081816105b401526126c50152613d666000f3fe6080604052600436106101fb5760003560e01c806359d162571161010d578063a7ecd37e116100a0578063dbdc814b1161006f578063dbdc814b14610795578063e985e9c5146107b5578063f242432a146107ff578063f2fde38b1461081f578063f399e22e1461083f576102d8565b8063a7ecd37e146106e5578063d0011d9d14610705578063d6a4222f14610725578063d6ea844914610759576102d8565b80638456cb59116100dc5780638456cb59146106725780638da5cb5b1461068757806394de1eac146106a5578063a22cb465146106c5576102d8565b806359d16257146106055780635c975abb14610625578063715018a61461063d578063731133e914610652576102d8565b80631f7fdffa116101905780633f4ba83a1161015f5780633f4ba83a146105065780634e1273f41461051b578063510b515814610548578063572b6c051461059757806357d1aeb5146105e4576102d8565b80631f7fdffa1461045c5780632693ebf21461047c5780632eb2c2d6146104aa57806339e83bea146104ca576102d8565b806304fdaa9a116101cc57806304fdaa9a1461038e57806305570dbc146103bf5780630e89341c146103f3578063146a291114610420576102d8565b80629a9b7b146102f4578062fdd58e1461031e57806301ffc9a71461033e57806302fe53051461036e576102d8565b366102d85760006102146033546001600160a01b031690565b604080516000815260208101918290526001600160a01b039290921691349161023d9190612f80565b60006040518083038185875af1925050503d806000811461027a576040519150601f19603f3d011682016040523d82523d6000602084013e61027f565b606091505b50509050806102d55760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a205472616e73666572206661696c65640000000060448201526064015b60405180910390fd5b50005b34156102f25760006102146033546001600160a01b031690565b005b34801561030057600080fd5b5061030b6101945481565b6040519081526020015b60405180910390f35b34801561032a57600080fd5b5061030b610339366004612fb8565b61085f565b34801561034a57600080fd5b5061035e610359366004612ff8565b6108f3565b6040519015158152602001610315565b34801561037a57600080fd5b506102f26103893660046130a5565b610945565b34801561039a57600080fd5b5061035e6103a93660046130ed565b61019a6020526000908152604090205460ff1681565b3480156103cb57600080fd5b5061030b7f9175b75f2204c4d4a610b1bbe17e5fa79fce7fbac7711cdf85d769cc3848bf4b81565b3480156103ff57600080fd5b5061041361040e3660046130ed565b610959565b6040516103159190613132565b34801561042c57600080fd5b5061035e61043b366004613145565b61019660209081526000928352604080842090915290825290205460ff1681565b34801561046857600080fd5b506102f2610477366004613225565b610994565b34801561048857600080fd5b5061030b6104973660046130ed565b6101976020526000908152604090205481565b3480156104b657600080fd5b506102f26104c53660046132bd565b610aac565b3480156104d657600080fd5b5061035e6104e536600461337d565b61019860209081526000928352604080842090915290825290205460ff1681565b34801561051257600080fd5b506102f2610b0a565b34801561052757600080fd5b5061053b6105363660046133a7565b610b1c565b60405161031591906134ac565b34801561055457600080fd5b5061057f6105633660046130ed565b610195602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610315565b3480156105a357600080fd5b5061035e6105b23660046134bf565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b3480156105f057600080fd5b506101935461057f906001600160a01b031681565b34801561061157600080fd5b506102f261062036600461351b565b610c45565b34801561063157600080fd5b5060655460ff1661035e565b34801561064957600080fd5b506102f2611074565b34801561065e57600080fd5b506102f261066d3660046135a3565b611086565b34801561067e57600080fd5b506102f261113d565b34801561069357600080fd5b506033546001600160a01b031661057f565b3480156106b157600080fd5b506102f26106c03660046135f7565b61114d565b3480156106d157600080fd5b506102f26106e036600461366c565b6113c4565b3480156106f157600080fd5b506102f26107003660046134bf565b6113da565b34801561071157600080fd5b5061030b6107203660046130ed565b6114a3565b34801561073157600080fd5b5061030b7f52fbdc3c74d741f91e89924e509efb37938f77dc0b874d0ae67a551cead3594881565b34801561076557600080fd5b5061035e6107743660046136a8565b61019960209081526000928352604080842090915290825290205460ff1681565b3480156107a157600080fd5b506102f26107b0366004613145565b6115f3565b3480156107c157600080fd5b5061035e6107d03660046136d2565b6001600160a01b0391821660009081526101306020908152604080832093909416825291909152205460ff1690565b34801561080b57600080fd5b506102f261081a3660046136ee565b611708565b34801561082b57600080fd5b506102f261083a3660046134bf565b61175f565b34801561084b57600080fd5b506102f261085a366004613752565b6117d5565b60006001600160a01b0383166108ca5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084016102cc565b50600090815261012f602090815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061092457506001600160e01b031982166303a24d0760e21b145b8061093f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61094d611b11565b61095681611b8a565b50565b606061096482611b9e565b61096d83611c33565b60405160200161097e9291906137a4565b6040516020818303038152906040529050919050565b600260cb5414156109b75760405162461bcd60e51b81526004016102cc906137e3565b600260cb5560005b8351811015610a945760008482815181106109dc576109dc61381a565b6020026020010151905061019660008281526020019081526020016000206000610a04611d38565b6001600160a01b0316815260208101919091526040016000205460ff16610a3d5760405162461bcd60e51b81526004016102cc90613830565b838281518110610a4f57610a4f61381a565b602002602001015161019760008381526020019081526020016000206000828254610a7a9190613894565b90915550829150610a8c9050816138ac565b9150506109bf565b50610aa184848484611d47565b5050600160cb555050565b610ab4611d38565b6001600160a01b0316856001600160a01b03161480610ada5750610ada856107d0611d38565b610af65760405162461bcd60e51b81526004016102cc906138c7565b610b038585858585611e9f565b5050505050565b610b12611b11565b610b1a61204b565b565b60608151835114610b815760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016102cc565b600083516001600160401b03811115610b9c57610b9c612f3e565b604051908082528060200260200182016040528015610bc5578160200160208202803683370190505b50905060005b8451811015610c3d57610c10858281518110610be957610be961381a565b6020026020010151858381518110610c0357610c0361381a565b602002602001015161085f565b828281518110610c2257610c2261381a565b6020908102919091010152610c36816138ac565b9050610bcb565b509392505050565b610c4d6120a3565b600260cb541415610c705760405162461bcd60e51b81526004016102cc906137e3565b600260cb556000858152610195602052604090205485906001600160a01b0316610ce85760405162461bcd60e51b815260206004820152602360248201527f496e74726163746f7069613a20546f6b656e496420646f6573206e6f742065786044820152621a5cdd60ea1b60648201526084016102cc565b6000886001600160601b031611610d415760405162461bcd60e51b815260206004820152601d60248201527f496e74726163746f7069613a20496e76616c696420726577617264496400000060448201526064016102cc565b6000876001600160601b031611610d9a5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420757365724964000000000060448201526064016102cc565b60008611610dea5760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420746f6b656e49640000000060448201526064016102cc565b60008511610e3a5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420616d6f756e74000000000060448201526064016102cc565b6001600160a01b038416610e905760405162461bcd60e51b815260206004820181905260248201527f496e74726163746f7069613a20496e76616c696420757365724164647265737360448201526064016102cc565b6001600160601b0388166000908152610198602090815260408083206001600160a01b038816845290915290205460ff1615610ede5760405162461bcd60e51b81526004016102cc90613916565b6001600160601b03808916600090815261019960209081526040808320938b168352929052205460ff1615610f255760405162461bcd60e51b81526004016102cc90613916565b610f3c610f35898989888a6120e9565b848461217a565b610f885760405162461bcd60e51b815260206004820152601e60248201527f496e74726163746f7069613a20496e76616c6964207369676e6174757265000060448201526064016102cc565b6001600160601b038881166000818152610198602090815260408083206001600160a01b038a168085529083528184208054600160ff1991821681179092558686526101998552838620978f168087529785529483902080549095161790935580519384529083018990529092899290917f55e45c439d1ff736812684adff4f5fc86d8db4de1374de90664ec17e7256f81e910160405180910390a46000868152610197602052604081208054879290611043908490613894565b92505081905550611065848787604051806020016040528060008152506121dc565b5050600160cb55505050505050565b61107c611b11565b610b1a60006122c4565b600260cb5414156110a95760405162461bcd60e51b81526004016102cc906137e3565b600260cb5560008381526101966020526040812084916110c7611d38565b6001600160a01b0316815260208101919091526040016000205460ff166111005760405162461bcd60e51b81526004016102cc90613830565b600084815261019760205260408120805485929061111f908490613894565b909155506111319050858585856121dc565b5050600160cb55505050565b611145611b11565b610b1a612316565b6111556120a3565b600260cb5414156111785760405162461bcd60e51b81526004016102cc906137e3565b600260cb556001600160601b0385166111d35760405162461bcd60e51b815260206004820152601d60248201527f496e74726163746f7069613a20496e76616c696420726577617264496400000060448201526064016102cc565b6000846001600160601b03161161122c5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420757365724964000000000060448201526064016102cc565b6001600160a01b0383166112825760405162461bcd60e51b815260206004820181905260248201527f496e74726163746f7069613a20496e76616c696420757365724164647265737360448201526064016102cc565b600061128f868686612354565b600081815261019a602052604090205490915060ff16156112c25760405162461bcd60e51b81526004016102cc90613916565b6001806112d083868661217a565b61131c5760405162461bcd60e51b815260206004820152601e60248201527f496e74726163746f7069613a20496e76616c6964207369676e6174757265000060448201526064016102cc565b600083815261019a6020908152604091829020805460ff1916600117905590516001600160a01b03881681526001600160601b0389811692908b16917faeedc887444f636ae962ff374f6709df2b420facc3749d5d6771d6bc4cdede5f910160405180910390a360008181526101976020526040812080548492906113a2908490613894565b92505081905550611065868284604051806020016040528060008152506121dc565b6113d66113cf611d38565b83836123b6565b5050565b6113e2611b11565b6001600160a01b0381166114385760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420616464726573730000000060448201526064016102cc565b61019354604080516001600160a01b03928316815291831660208301527f1bed810d070629e3c7f5073d5853d510358186fea41ee6b91e4c82b2ea38ed8f910160405180910390a161019380546001600160a01b0319166001600160a01b0392909216919091179055565b60006114ad6120a3565b600260cb5414156114d05760405162461bcd60e51b81526004016102cc906137e3565b600260cb81905550600161019460008282546114ec9190613894565b9091555050610194546114fd611d38565b60008281526101956020908152604080832080546001600160a01b0319166001600160a01b0395909516949094179093556101969052908120600191611541611d38565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905561158b611574611d38565b8285604051806020016040528060008152506121dc565b6000818152610197602052604090208390556115a5611d38565b6001600160a01b0316817febc11c13ed108c34e998bbf2874a52096c4fc5fea255aa86153110397d91f04a856040516115e091815260200190565b60405180910390a3600160cb5592915050565b600082815261019660205260408120839161160c611d38565b6001600160a01b0316815260208101919091526040016000205460ff166116455760405162461bcd60e51b81526004016102cc90613830565b6001600160a01b03821661169b5760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420616464726573730000000060448201526064016102cc565b6000838152610196602090815260408083206001600160a01b03861680855290835292819020805460ff191660011790558051868152918201929092527f74420b31ccd8bcac6b8a084da7b9253abd2ab85dd708b8c514b976c6b65d0d45910160405180910390a1505050565b611710611d38565b6001600160a01b0316856001600160a01b031614806117365750611736856107d0611d38565b6117525760405162461bcd60e51b81526004016102cc906138c7565b610b038585858585612498565b611767611b11565b6001600160a01b0381166117cc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102cc565b610956816122c4565b600054610100900460ff16158080156117f55750600054600160ff909116105b8061180f5750303b15801561180f575060005460ff166001145b6118725760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102cc565b6000805460ff191660011790558015611895576000805461ff0019166101001790555b6001600160a01b0384166119115760405162461bcd60e51b815260206004820152603c60248201527f496e74726163746f7069613a20496e7472616374207369676e6572206164647260448201527f657373206d757374206e6f74206265206e756c6c20616464726573730000000060648201526084016102cc565b6119196125d3565b611921612602565b61196b6040518060400160405280600b81526020016a496e74726163746f70696160a81b815250604051806040016040528060058152602001640312e302e360dc1b815250612631565b611973612662565b6119b283838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061269192505050565b61019380546001600160a01b0319166001600160a01b03861617905560016101948190556119de611d38565b60008281526101956020908152604080832080546001600160a01b0319166001600160a01b0395909516949094179093556101969052908120600191611a22611d38565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055611a6d611a55611d38565b826001604051806020016040528060008152506121dc565b6000818152610197602090815260408083206001905580519283526001600160a01b038816918301919091527f1bed810d070629e3c7f5073d5853d510358186fea41ee6b91e4c82b2ea38ed8f910160405180910390a1508015611b0b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b611b19611d38565b6001600160a01b0316611b346033546001600160a01b031690565b6001600160a01b031614610b1a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102cc565b80516113d690610131906020840190612ea5565b60606101318054611bae9061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611bda9061394d565b8015611c275780601f10611bfc57610100808354040283529160200191611c27565b820191906000526020600020905b815481529060010190602001808311611c0a57829003601f168201915b50505050509050919050565b606081611c575750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c815780611c6b816138ac565b9150611c7a9050600a8361399e565b9150611c5b565b6000816001600160401b03811115611c9b57611c9b612f3e565b6040519080825280601f01601f191660200182016040528015611cc5576020820181803683370190505b5090505b8415611d3057611cda6001836139b2565b9150611ce7600a866139c9565b611cf2906030613894565b60f81b818381518110611d0757611d0761381a565b60200101906001600160f81b031916908160001a905350611d29600a8661399e565b9450611cc9565b949350505050565b6000611d426126c1565b905090565b6001600160a01b038416611d6d5760405162461bcd60e51b81526004016102cc906139dd565b8151835114611d8e5760405162461bcd60e51b81526004016102cc90613a1e565b6000611d98611d38565b905060005b8451811015611e3757838181518110611db857611db861381a565b602002602001015161012f6000878481518110611dd757611dd761381a565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254611e1f9190613894565b90915550819050611e2f816138ac565b915050611d9d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611e88929190613a66565b60405180910390a4610b0381600087878787612709565b8151835114611ec05760405162461bcd60e51b81526004016102cc90613a1e565b6001600160a01b038416611ee65760405162461bcd60e51b81526004016102cc90613a94565b6000611ef0611d38565b905060005b8451811015611fdd576000858281518110611f1257611f1261381a565b602002602001015190506000858381518110611f3057611f3061381a565b602090810291909101810151600084815261012f835260408082206001600160a01b038e168352909352919091205490915081811015611f825760405162461bcd60e51b81526004016102cc90613ad9565b600083815261012f602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611fc2908490613894565b9250508190555050505080611fd6906138ac565b9050611ef5565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161202d929190613a66565b60405180910390a4612043818787878787612709565b505050505050565b612053612874565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612086611d38565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff1615610b1a5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016102cc565b604080517f52fbdc3c74d741f91e89924e509efb37938f77dc0b874d0ae67a551cead3594860208201526001600160601b03808816928201929092529085166060820152608081018490526001600160a01b03831660a082015260c081018290526000906121709060e0015b604051602081830303815290604052805190602001206128bd565b9695505050505050565b61019354604080516020601f85018190048102820181019092528381526000926001600160a01b0316916121ca918791879087908190840183828082843760009201919091525061290b92505050565b6001600160a01b031614949350505050565b6001600160a01b0384166122025760405162461bcd60e51b81526004016102cc906139dd565b600061220c611d38565b9050600061221985612927565b9050600061222685612927565b9050600086815261012f602090815260408083206001600160a01b038b1684529091528120805487929061225b908490613894565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46122bb83600089898989612972565b50505050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61231e6120a3565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612086611d38565b604080517f9175b75f2204c4d4a610b1bbe17e5fa79fce7fbac7711cdf85d769cc3848bf4b60208201526001600160601b038086169282019290925290831660608201526001600160a01b0382166080820152600090611d309060a001612155565b816001600160a01b0316836001600160a01b0316141561242a5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016102cc565b6001600160a01b0383811660008181526101306020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166124be5760405162461bcd60e51b81526004016102cc90613a94565b60006124c8611d38565b905060006124d585612927565b905060006124e285612927565b9050600086815261012f602090815260408083206001600160a01b038c168452909152902054858110156125285760405162461bcd60e51b81526004016102cc90613ad9565b600087815261012f602090815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612568908490613894565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46125c8848a8a8a8a8a612972565b505050505050505050565b600054610100900460ff166125fa5760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a3c565b600054610100900460ff166126295760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a73565b600054610100900460ff166126585760405162461bcd60e51b81526004016102cc90613b23565b6113d68282612aa6565b600054610100900460ff166126895760405162461bcd60e51b81526004016102cc90613b23565b610b1a612ae7565b600054610100900460ff166126b85760405162461bcd60e51b81526004016102cc90613b23565b61095681612b15565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316331415612701575060131936013560601c90565b503390565b90565b6001600160a01b0384163b156120435760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061274d9089908990889088908890600401613b6e565b602060405180830381600087803b15801561276757600080fd5b505af1925050508015612797575060408051601f3d908101601f1916820190925261279491810190613bcc565b60015b612844576127a3613be9565b806308c379a014156127dd57506127b8613c04565b806127c357506127df565b8060405162461bcd60e51b81526004016102cc9190613132565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016102cc565b6001600160e01b0319811663bc197c8160e01b146122bb5760405162461bcd60e51b81526004016102cc90613c8d565b60655460ff16610b1a5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016102cc565b600061093f6128ca612b3c565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061291a8585612bb7565b91509150610c3d81612bfd565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129615761296161381a565b602090810291909101015292915050565b6001600160a01b0384163b156120435760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906129b69089908990889088908890600401613cd5565b602060405180830381600087803b1580156129d057600080fd5b505af1925050508015612a00575060408051601f3d908101601f191682019092526129fd91810190613bcc565b60015b612a0c576127a3613be9565b6001600160e01b0319811663f23a6e6160e01b146122bb5760405162461bcd60e51b81526004016102cc90613c8d565b600054610100900460ff16612a635760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a6e611d38565b6122c4565b600054610100900460ff16612a9a5760405162461bcd60e51b81526004016102cc90613b23565b6065805460ff19169055565b600054610100900460ff16612acd5760405162461bcd60e51b81526004016102cc90613b23565b815160209283012081519190920120609791909155609855565b600054610100900460ff16612b0e5760405162461bcd60e51b81526004016102cc90613b23565b600160cb55565b600054610100900460ff1661094d5760405162461bcd60e51b81526004016102cc90613b23565b6000611d427f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612b6b60975490565b6098546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b600080825160411415612bee5760208301516040840151606085015160001a612be287828585612db8565b94509450505050612bf6565b506000905060025b9250929050565b6000816004811115612c1157612c11613d1a565b1415612c1a5750565b6001816004811115612c2e57612c2e613d1a565b1415612c7c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016102cc565b6002816004811115612c9057612c90613d1a565b1415612cde5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016102cc565b6003816004811115612cf257612cf2613d1a565b1415612d4b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016102cc565b6004816004811115612d5f57612d5f613d1a565b14156109565760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016102cc565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612def5750600090506003612e9c565b8460ff16601b14158015612e0757508460ff16601c14155b15612e185750600090506004612e9c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612e6c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612e9557600060019250925050612e9c565b9150600090505b94509492505050565b828054612eb19061394d565b90600052602060002090601f016020900481019282612ed35760008555612f19565b82601f10612eec57805160ff1916838001178555612f19565b82800160010185558215612f19579182015b82811115612f19578251825591602001919060010190612efe565b50612f25929150612f29565b5090565b5b80821115612f255760008155600101612f2a565b634e487b7160e01b600052604160045260246000fd5b60005b83811015612f6f578181015183820152602001612f57565b83811115611b0b5750506000910152565b60008251612f92818460208701612f54565b9190910192915050565b80356001600160a01b0381168114612fb357600080fd5b919050565b60008060408385031215612fcb57600080fd5b612fd483612f9c565b946020939093013593505050565b6001600160e01b03198116811461095657600080fd5b60006020828403121561300a57600080fd5b813561301581612fe2565b9392505050565b601f8201601f191681016001600160401b038111828210171561304157613041612f3e565b6040525050565b60006001600160401b0383111561306157613061612f3e565b604051613078601f8501601f19166020018261301c565b80915083815284848401111561308d57600080fd5b83836020830137600060208583010152509392505050565b6000602082840312156130b757600080fd5b81356001600160401b038111156130cd57600080fd5b8201601f810184136130de57600080fd5b611d3084823560208401613048565b6000602082840312156130ff57600080fd5b5035919050565b6000815180845261311e816020860160208601612f54565b601f01601f19169290920160200192915050565b6020815260006130156020830184613106565b6000806040838503121561315857600080fd5b8235915061316860208401612f9c565b90509250929050565b60006001600160401b0382111561318a5761318a612f3e565b5060051b60200190565b600082601f8301126131a557600080fd5b813560206131b282613171565b6040516131bf828261301c565b83815260059390931b85018201928281019150868411156131df57600080fd5b8286015b848110156131fa57803583529183019183016131e3565b509695505050505050565b600082601f83011261321657600080fd5b61301583833560208501613048565b6000806000806080858703121561323b57600080fd5b61324485612f9c565b935060208501356001600160401b038082111561326057600080fd5b61326c88838901613194565b9450604087013591508082111561328257600080fd5b61328e88838901613194565b935060608701359150808211156132a457600080fd5b506132b187828801613205565b91505092959194509250565b600080600080600060a086880312156132d557600080fd5b6132de86612f9c565b94506132ec60208701612f9c565b935060408601356001600160401b038082111561330857600080fd5b61331489838a01613194565b9450606088013591508082111561332a57600080fd5b61333689838a01613194565b9350608088013591508082111561334c57600080fd5b5061335988828901613205565b9150509295509295909350565b80356001600160601b0381168114612fb357600080fd5b6000806040838503121561339057600080fd5b61339983613366565b915061316860208401612f9c565b600080604083850312156133ba57600080fd5b82356001600160401b03808211156133d157600080fd5b818501915085601f8301126133e557600080fd5b813560206133f282613171565b6040516133ff828261301c565b83815260059390931b850182019282810191508984111561341f57600080fd5b948201945b838610156134445761343586612f9c565b82529482019490820190613424565b9650508601359250508082111561345a57600080fd5b5061346785828601613194565b9150509250929050565b600081518084526020808501945080840160005b838110156134a157815187529582019590820190600101613485565b509495945050505050565b6020815260006130156020830184613471565b6000602082840312156134d157600080fd5b61301582612f9c565b60008083601f8401126134ec57600080fd5b5081356001600160401b0381111561350357600080fd5b602083019150836020828501011115612bf657600080fd5b600080600080600080600060c0888a03121561353657600080fd5b61353f88613366565b965061354d60208901613366565b9550604088013594506060880135935061356960808901612f9c565b925060a08801356001600160401b0381111561358457600080fd5b6135908a828b016134da565b989b979a50959850939692959293505050565b600080600080608085870312156135b957600080fd5b6135c285612f9c565b9350602085013592506040850135915060608501356001600160401b038111156135eb57600080fd5b6132b187828801613205565b60008060008060006080868803121561360f57600080fd5b61361886613366565b945061362660208701613366565b935061363460408701612f9c565b925060608601356001600160401b0381111561364f57600080fd5b61365b888289016134da565b969995985093965092949392505050565b6000806040838503121561367f57600080fd5b61368883612f9c565b91506020830135801515811461369d57600080fd5b809150509250929050565b600080604083850312156136bb57600080fd5b6136c483613366565b915061316860208401613366565b600080604083850312156136e557600080fd5b61339983612f9c565b600080600080600060a0868803121561370657600080fd5b61370f86612f9c565b945061371d60208701612f9c565b9350604086013592506060860135915060808601356001600160401b0381111561374657600080fd5b61335988828901613205565b60008060006040848603121561376757600080fd5b61377084612f9c565b925060208401356001600160401b0381111561378b57600080fd5b613797868287016134da565b9497909650939450505050565b600083516137b6818460208801612f54565b8351908301906137ca818360208801612f54565b64173539b7b760d91b9101908152600501949350505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6020808252602e908201527f496e74726163746f7069613a204f6e6c792061646d696e2063616e2063616c6c60408201526d103a3434b990333ab731ba34b7b760911b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082198211156138a7576138a761387e565b500190565b60006000198214156138c0576138c061387e565b5060010190565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b6020808252601c908201527f496e74726163746f7069613a20416c726561647920636c61696d656400000000604082015260600190565b600181811c9082168061396157607f821691505b6020821081141561398257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b6000826139ad576139ad613988565b500490565b6000828210156139c4576139c461387e565b500390565b6000826139d8576139d8613988565b500690565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b604081526000613a796040830185613471565b8281036020840152613a8b8185613471565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b0386811682528516602082015260a060408201819052600090613b9a90830186613471565b8281036060840152613bac8186613471565b90508281036080840152613bc08185613106565b98975050505050505050565b600060208284031215613bde57600080fd5b815161301581612fe2565b600060033d11156127065760046000803e5060005160e01c90565b600060443d1015613c125790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613c4157505050505090565b8285019150815181811115613c595750505050505090565b843d8701016020828501011115613c735750505050505090565b613c826020828601018761301c565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090613d0f90830184613106565b979650505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220da2feff0257b5280c1fa25b0b334cebacd33e1db30d5b1a815a5de2a10c154a064736f6c63430008090033000000000000000000000000df1b0d8f4b45227e2750249d3e8598aca66521fa
Deployed Bytecode
0x6080604052600436106101fb5760003560e01c806359d162571161010d578063a7ecd37e116100a0578063dbdc814b1161006f578063dbdc814b14610795578063e985e9c5146107b5578063f242432a146107ff578063f2fde38b1461081f578063f399e22e1461083f576102d8565b8063a7ecd37e146106e5578063d0011d9d14610705578063d6a4222f14610725578063d6ea844914610759576102d8565b80638456cb59116100dc5780638456cb59146106725780638da5cb5b1461068757806394de1eac146106a5578063a22cb465146106c5576102d8565b806359d16257146106055780635c975abb14610625578063715018a61461063d578063731133e914610652576102d8565b80631f7fdffa116101905780633f4ba83a1161015f5780633f4ba83a146105065780634e1273f41461051b578063510b515814610548578063572b6c051461059757806357d1aeb5146105e4576102d8565b80631f7fdffa1461045c5780632693ebf21461047c5780632eb2c2d6146104aa57806339e83bea146104ca576102d8565b806304fdaa9a116101cc57806304fdaa9a1461038e57806305570dbc146103bf5780630e89341c146103f3578063146a291114610420576102d8565b80629a9b7b146102f4578062fdd58e1461031e57806301ffc9a71461033e57806302fe53051461036e576102d8565b366102d85760006102146033546001600160a01b031690565b604080516000815260208101918290526001600160a01b039290921691349161023d9190612f80565b60006040518083038185875af1925050503d806000811461027a576040519150601f19603f3d011682016040523d82523d6000602084013e61027f565b606091505b50509050806102d55760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a205472616e73666572206661696c65640000000060448201526064015b60405180910390fd5b50005b34156102f25760006102146033546001600160a01b031690565b005b34801561030057600080fd5b5061030b6101945481565b6040519081526020015b60405180910390f35b34801561032a57600080fd5b5061030b610339366004612fb8565b61085f565b34801561034a57600080fd5b5061035e610359366004612ff8565b6108f3565b6040519015158152602001610315565b34801561037a57600080fd5b506102f26103893660046130a5565b610945565b34801561039a57600080fd5b5061035e6103a93660046130ed565b61019a6020526000908152604090205460ff1681565b3480156103cb57600080fd5b5061030b7f9175b75f2204c4d4a610b1bbe17e5fa79fce7fbac7711cdf85d769cc3848bf4b81565b3480156103ff57600080fd5b5061041361040e3660046130ed565b610959565b6040516103159190613132565b34801561042c57600080fd5b5061035e61043b366004613145565b61019660209081526000928352604080842090915290825290205460ff1681565b34801561046857600080fd5b506102f2610477366004613225565b610994565b34801561048857600080fd5b5061030b6104973660046130ed565b6101976020526000908152604090205481565b3480156104b657600080fd5b506102f26104c53660046132bd565b610aac565b3480156104d657600080fd5b5061035e6104e536600461337d565b61019860209081526000928352604080842090915290825290205460ff1681565b34801561051257600080fd5b506102f2610b0a565b34801561052757600080fd5b5061053b6105363660046133a7565b610b1c565b60405161031591906134ac565b34801561055457600080fd5b5061057f6105633660046130ed565b610195602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610315565b3480156105a357600080fd5b5061035e6105b23660046134bf565b7f000000000000000000000000df1b0d8f4b45227e2750249d3e8598aca66521fa6001600160a01b0390811691161490565b3480156105f057600080fd5b506101935461057f906001600160a01b031681565b34801561061157600080fd5b506102f261062036600461351b565b610c45565b34801561063157600080fd5b5060655460ff1661035e565b34801561064957600080fd5b506102f2611074565b34801561065e57600080fd5b506102f261066d3660046135a3565b611086565b34801561067e57600080fd5b506102f261113d565b34801561069357600080fd5b506033546001600160a01b031661057f565b3480156106b157600080fd5b506102f26106c03660046135f7565b61114d565b3480156106d157600080fd5b506102f26106e036600461366c565b6113c4565b3480156106f157600080fd5b506102f26107003660046134bf565b6113da565b34801561071157600080fd5b5061030b6107203660046130ed565b6114a3565b34801561073157600080fd5b5061030b7f52fbdc3c74d741f91e89924e509efb37938f77dc0b874d0ae67a551cead3594881565b34801561076557600080fd5b5061035e6107743660046136a8565b61019960209081526000928352604080842090915290825290205460ff1681565b3480156107a157600080fd5b506102f26107b0366004613145565b6115f3565b3480156107c157600080fd5b5061035e6107d03660046136d2565b6001600160a01b0391821660009081526101306020908152604080832093909416825291909152205460ff1690565b34801561080b57600080fd5b506102f261081a3660046136ee565b611708565b34801561082b57600080fd5b506102f261083a3660046134bf565b61175f565b34801561084b57600080fd5b506102f261085a366004613752565b6117d5565b60006001600160a01b0383166108ca5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084016102cc565b50600090815261012f602090815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061092457506001600160e01b031982166303a24d0760e21b145b8061093f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61094d611b11565b61095681611b8a565b50565b606061096482611b9e565b61096d83611c33565b60405160200161097e9291906137a4565b6040516020818303038152906040529050919050565b600260cb5414156109b75760405162461bcd60e51b81526004016102cc906137e3565b600260cb5560005b8351811015610a945760008482815181106109dc576109dc61381a565b6020026020010151905061019660008281526020019081526020016000206000610a04611d38565b6001600160a01b0316815260208101919091526040016000205460ff16610a3d5760405162461bcd60e51b81526004016102cc90613830565b838281518110610a4f57610a4f61381a565b602002602001015161019760008381526020019081526020016000206000828254610a7a9190613894565b90915550829150610a8c9050816138ac565b9150506109bf565b50610aa184848484611d47565b5050600160cb555050565b610ab4611d38565b6001600160a01b0316856001600160a01b03161480610ada5750610ada856107d0611d38565b610af65760405162461bcd60e51b81526004016102cc906138c7565b610b038585858585611e9f565b5050505050565b610b12611b11565b610b1a61204b565b565b60608151835114610b815760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016102cc565b600083516001600160401b03811115610b9c57610b9c612f3e565b604051908082528060200260200182016040528015610bc5578160200160208202803683370190505b50905060005b8451811015610c3d57610c10858281518110610be957610be961381a565b6020026020010151858381518110610c0357610c0361381a565b602002602001015161085f565b828281518110610c2257610c2261381a565b6020908102919091010152610c36816138ac565b9050610bcb565b509392505050565b610c4d6120a3565b600260cb541415610c705760405162461bcd60e51b81526004016102cc906137e3565b600260cb556000858152610195602052604090205485906001600160a01b0316610ce85760405162461bcd60e51b815260206004820152602360248201527f496e74726163746f7069613a20546f6b656e496420646f6573206e6f742065786044820152621a5cdd60ea1b60648201526084016102cc565b6000886001600160601b031611610d415760405162461bcd60e51b815260206004820152601d60248201527f496e74726163746f7069613a20496e76616c696420726577617264496400000060448201526064016102cc565b6000876001600160601b031611610d9a5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420757365724964000000000060448201526064016102cc565b60008611610dea5760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420746f6b656e49640000000060448201526064016102cc565b60008511610e3a5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420616d6f756e74000000000060448201526064016102cc565b6001600160a01b038416610e905760405162461bcd60e51b815260206004820181905260248201527f496e74726163746f7069613a20496e76616c696420757365724164647265737360448201526064016102cc565b6001600160601b0388166000908152610198602090815260408083206001600160a01b038816845290915290205460ff1615610ede5760405162461bcd60e51b81526004016102cc90613916565b6001600160601b03808916600090815261019960209081526040808320938b168352929052205460ff1615610f255760405162461bcd60e51b81526004016102cc90613916565b610f3c610f35898989888a6120e9565b848461217a565b610f885760405162461bcd60e51b815260206004820152601e60248201527f496e74726163746f7069613a20496e76616c6964207369676e6174757265000060448201526064016102cc565b6001600160601b038881166000818152610198602090815260408083206001600160a01b038a168085529083528184208054600160ff1991821681179092558686526101998552838620978f168087529785529483902080549095161790935580519384529083018990529092899290917f55e45c439d1ff736812684adff4f5fc86d8db4de1374de90664ec17e7256f81e910160405180910390a46000868152610197602052604081208054879290611043908490613894565b92505081905550611065848787604051806020016040528060008152506121dc565b5050600160cb55505050505050565b61107c611b11565b610b1a60006122c4565b600260cb5414156110a95760405162461bcd60e51b81526004016102cc906137e3565b600260cb5560008381526101966020526040812084916110c7611d38565b6001600160a01b0316815260208101919091526040016000205460ff166111005760405162461bcd60e51b81526004016102cc90613830565b600084815261019760205260408120805485929061111f908490613894565b909155506111319050858585856121dc565b5050600160cb55505050565b611145611b11565b610b1a612316565b6111556120a3565b600260cb5414156111785760405162461bcd60e51b81526004016102cc906137e3565b600260cb556001600160601b0385166111d35760405162461bcd60e51b815260206004820152601d60248201527f496e74726163746f7069613a20496e76616c696420726577617264496400000060448201526064016102cc565b6000846001600160601b03161161122c5760405162461bcd60e51b815260206004820152601b60248201527f496e74726163746f7069613a20496e76616c696420757365724964000000000060448201526064016102cc565b6001600160a01b0383166112825760405162461bcd60e51b815260206004820181905260248201527f496e74726163746f7069613a20496e76616c696420757365724164647265737360448201526064016102cc565b600061128f868686612354565b600081815261019a602052604090205490915060ff16156112c25760405162461bcd60e51b81526004016102cc90613916565b6001806112d083868661217a565b61131c5760405162461bcd60e51b815260206004820152601e60248201527f496e74726163746f7069613a20496e76616c6964207369676e6174757265000060448201526064016102cc565b600083815261019a6020908152604091829020805460ff1916600117905590516001600160a01b03881681526001600160601b0389811692908b16917faeedc887444f636ae962ff374f6709df2b420facc3749d5d6771d6bc4cdede5f910160405180910390a360008181526101976020526040812080548492906113a2908490613894565b92505081905550611065868284604051806020016040528060008152506121dc565b6113d66113cf611d38565b83836123b6565b5050565b6113e2611b11565b6001600160a01b0381166114385760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420616464726573730000000060448201526064016102cc565b61019354604080516001600160a01b03928316815291831660208301527f1bed810d070629e3c7f5073d5853d510358186fea41ee6b91e4c82b2ea38ed8f910160405180910390a161019380546001600160a01b0319166001600160a01b0392909216919091179055565b60006114ad6120a3565b600260cb5414156114d05760405162461bcd60e51b81526004016102cc906137e3565b600260cb81905550600161019460008282546114ec9190613894565b9091555050610194546114fd611d38565b60008281526101956020908152604080832080546001600160a01b0319166001600160a01b0395909516949094179093556101969052908120600191611541611d38565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905561158b611574611d38565b8285604051806020016040528060008152506121dc565b6000818152610197602052604090208390556115a5611d38565b6001600160a01b0316817febc11c13ed108c34e998bbf2874a52096c4fc5fea255aa86153110397d91f04a856040516115e091815260200190565b60405180910390a3600160cb5592915050565b600082815261019660205260408120839161160c611d38565b6001600160a01b0316815260208101919091526040016000205460ff166116455760405162461bcd60e51b81526004016102cc90613830565b6001600160a01b03821661169b5760405162461bcd60e51b815260206004820152601c60248201527f496e74726163746f7069613a20496e76616c696420616464726573730000000060448201526064016102cc565b6000838152610196602090815260408083206001600160a01b03861680855290835292819020805460ff191660011790558051868152918201929092527f74420b31ccd8bcac6b8a084da7b9253abd2ab85dd708b8c514b976c6b65d0d45910160405180910390a1505050565b611710611d38565b6001600160a01b0316856001600160a01b031614806117365750611736856107d0611d38565b6117525760405162461bcd60e51b81526004016102cc906138c7565b610b038585858585612498565b611767611b11565b6001600160a01b0381166117cc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102cc565b610956816122c4565b600054610100900460ff16158080156117f55750600054600160ff909116105b8061180f5750303b15801561180f575060005460ff166001145b6118725760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102cc565b6000805460ff191660011790558015611895576000805461ff0019166101001790555b6001600160a01b0384166119115760405162461bcd60e51b815260206004820152603c60248201527f496e74726163746f7069613a20496e7472616374207369676e6572206164647260448201527f657373206d757374206e6f74206265206e756c6c20616464726573730000000060648201526084016102cc565b6119196125d3565b611921612602565b61196b6040518060400160405280600b81526020016a496e74726163746f70696160a81b815250604051806040016040528060058152602001640312e302e360dc1b815250612631565b611973612662565b6119b283838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061269192505050565b61019380546001600160a01b0319166001600160a01b03861617905560016101948190556119de611d38565b60008281526101956020908152604080832080546001600160a01b0319166001600160a01b0395909516949094179093556101969052908120600191611a22611d38565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055611a6d611a55611d38565b826001604051806020016040528060008152506121dc565b6000818152610197602090815260408083206001905580519283526001600160a01b038816918301919091527f1bed810d070629e3c7f5073d5853d510358186fea41ee6b91e4c82b2ea38ed8f910160405180910390a1508015611b0b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b611b19611d38565b6001600160a01b0316611b346033546001600160a01b031690565b6001600160a01b031614610b1a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102cc565b80516113d690610131906020840190612ea5565b60606101318054611bae9061394d565b80601f0160208091040260200160405190810160405280929190818152602001828054611bda9061394d565b8015611c275780601f10611bfc57610100808354040283529160200191611c27565b820191906000526020600020905b815481529060010190602001808311611c0a57829003601f168201915b50505050509050919050565b606081611c575750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c815780611c6b816138ac565b9150611c7a9050600a8361399e565b9150611c5b565b6000816001600160401b03811115611c9b57611c9b612f3e565b6040519080825280601f01601f191660200182016040528015611cc5576020820181803683370190505b5090505b8415611d3057611cda6001836139b2565b9150611ce7600a866139c9565b611cf2906030613894565b60f81b818381518110611d0757611d0761381a565b60200101906001600160f81b031916908160001a905350611d29600a8661399e565b9450611cc9565b949350505050565b6000611d426126c1565b905090565b6001600160a01b038416611d6d5760405162461bcd60e51b81526004016102cc906139dd565b8151835114611d8e5760405162461bcd60e51b81526004016102cc90613a1e565b6000611d98611d38565b905060005b8451811015611e3757838181518110611db857611db861381a565b602002602001015161012f6000878481518110611dd757611dd761381a565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254611e1f9190613894565b90915550819050611e2f816138ac565b915050611d9d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611e88929190613a66565b60405180910390a4610b0381600087878787612709565b8151835114611ec05760405162461bcd60e51b81526004016102cc90613a1e565b6001600160a01b038416611ee65760405162461bcd60e51b81526004016102cc90613a94565b6000611ef0611d38565b905060005b8451811015611fdd576000858281518110611f1257611f1261381a565b602002602001015190506000858381518110611f3057611f3061381a565b602090810291909101810151600084815261012f835260408082206001600160a01b038e168352909352919091205490915081811015611f825760405162461bcd60e51b81526004016102cc90613ad9565b600083815261012f602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611fc2908490613894565b9250508190555050505080611fd6906138ac565b9050611ef5565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161202d929190613a66565b60405180910390a4612043818787878787612709565b505050505050565b612053612874565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612086611d38565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff1615610b1a5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016102cc565b604080517f52fbdc3c74d741f91e89924e509efb37938f77dc0b874d0ae67a551cead3594860208201526001600160601b03808816928201929092529085166060820152608081018490526001600160a01b03831660a082015260c081018290526000906121709060e0015b604051602081830303815290604052805190602001206128bd565b9695505050505050565b61019354604080516020601f85018190048102820181019092528381526000926001600160a01b0316916121ca918791879087908190840183828082843760009201919091525061290b92505050565b6001600160a01b031614949350505050565b6001600160a01b0384166122025760405162461bcd60e51b81526004016102cc906139dd565b600061220c611d38565b9050600061221985612927565b9050600061222685612927565b9050600086815261012f602090815260408083206001600160a01b038b1684529091528120805487929061225b908490613894565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46122bb83600089898989612972565b50505050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61231e6120a3565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612086611d38565b604080517f9175b75f2204c4d4a610b1bbe17e5fa79fce7fbac7711cdf85d769cc3848bf4b60208201526001600160601b038086169282019290925290831660608201526001600160a01b0382166080820152600090611d309060a001612155565b816001600160a01b0316836001600160a01b0316141561242a5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016102cc565b6001600160a01b0383811660008181526101306020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166124be5760405162461bcd60e51b81526004016102cc90613a94565b60006124c8611d38565b905060006124d585612927565b905060006124e285612927565b9050600086815261012f602090815260408083206001600160a01b038c168452909152902054858110156125285760405162461bcd60e51b81526004016102cc90613ad9565b600087815261012f602090815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612568908490613894565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46125c8848a8a8a8a8a612972565b505050505050505050565b600054610100900460ff166125fa5760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a3c565b600054610100900460ff166126295760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a73565b600054610100900460ff166126585760405162461bcd60e51b81526004016102cc90613b23565b6113d68282612aa6565b600054610100900460ff166126895760405162461bcd60e51b81526004016102cc90613b23565b610b1a612ae7565b600054610100900460ff166126b85760405162461bcd60e51b81526004016102cc90613b23565b61095681612b15565b60007f000000000000000000000000df1b0d8f4b45227e2750249d3e8598aca66521fa6001600160a01b0316331415612701575060131936013560601c90565b503390565b90565b6001600160a01b0384163b156120435760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061274d9089908990889088908890600401613b6e565b602060405180830381600087803b15801561276757600080fd5b505af1925050508015612797575060408051601f3d908101601f1916820190925261279491810190613bcc565b60015b612844576127a3613be9565b806308c379a014156127dd57506127b8613c04565b806127c357506127df565b8060405162461bcd60e51b81526004016102cc9190613132565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016102cc565b6001600160e01b0319811663bc197c8160e01b146122bb5760405162461bcd60e51b81526004016102cc90613c8d565b60655460ff16610b1a5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016102cc565b600061093f6128ca612b3c565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061291a8585612bb7565b91509150610c3d81612bfd565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129615761296161381a565b602090810291909101015292915050565b6001600160a01b0384163b156120435760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906129b69089908990889088908890600401613cd5565b602060405180830381600087803b1580156129d057600080fd5b505af1925050508015612a00575060408051601f3d908101601f191682019092526129fd91810190613bcc565b60015b612a0c576127a3613be9565b6001600160e01b0319811663f23a6e6160e01b146122bb5760405162461bcd60e51b81526004016102cc90613c8d565b600054610100900460ff16612a635760405162461bcd60e51b81526004016102cc90613b23565b610b1a612a6e611d38565b6122c4565b600054610100900460ff16612a9a5760405162461bcd60e51b81526004016102cc90613b23565b6065805460ff19169055565b600054610100900460ff16612acd5760405162461bcd60e51b81526004016102cc90613b23565b815160209283012081519190920120609791909155609855565b600054610100900460ff16612b0e5760405162461bcd60e51b81526004016102cc90613b23565b600160cb55565b600054610100900460ff1661094d5760405162461bcd60e51b81526004016102cc90613b23565b6000611d427f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612b6b60975490565b6098546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b600080825160411415612bee5760208301516040840151606085015160001a612be287828585612db8565b94509450505050612bf6565b506000905060025b9250929050565b6000816004811115612c1157612c11613d1a565b1415612c1a5750565b6001816004811115612c2e57612c2e613d1a565b1415612c7c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016102cc565b6002816004811115612c9057612c90613d1a565b1415612cde5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016102cc565b6003816004811115612cf257612cf2613d1a565b1415612d4b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016102cc565b6004816004811115612d5f57612d5f613d1a565b14156109565760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016102cc565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612def5750600090506003612e9c565b8460ff16601b14158015612e0757508460ff16601c14155b15612e185750600090506004612e9c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612e6c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612e9557600060019250925050612e9c565b9150600090505b94509492505050565b828054612eb19061394d565b90600052602060002090601f016020900481019282612ed35760008555612f19565b82601f10612eec57805160ff1916838001178555612f19565b82800160010185558215612f19579182015b82811115612f19578251825591602001919060010190612efe565b50612f25929150612f29565b5090565b5b80821115612f255760008155600101612f2a565b634e487b7160e01b600052604160045260246000fd5b60005b83811015612f6f578181015183820152602001612f57565b83811115611b0b5750506000910152565b60008251612f92818460208701612f54565b9190910192915050565b80356001600160a01b0381168114612fb357600080fd5b919050565b60008060408385031215612fcb57600080fd5b612fd483612f9c565b946020939093013593505050565b6001600160e01b03198116811461095657600080fd5b60006020828403121561300a57600080fd5b813561301581612fe2565b9392505050565b601f8201601f191681016001600160401b038111828210171561304157613041612f3e565b6040525050565b60006001600160401b0383111561306157613061612f3e565b604051613078601f8501601f19166020018261301c565b80915083815284848401111561308d57600080fd5b83836020830137600060208583010152509392505050565b6000602082840312156130b757600080fd5b81356001600160401b038111156130cd57600080fd5b8201601f810184136130de57600080fd5b611d3084823560208401613048565b6000602082840312156130ff57600080fd5b5035919050565b6000815180845261311e816020860160208601612f54565b601f01601f19169290920160200192915050565b6020815260006130156020830184613106565b6000806040838503121561315857600080fd5b8235915061316860208401612f9c565b90509250929050565b60006001600160401b0382111561318a5761318a612f3e565b5060051b60200190565b600082601f8301126131a557600080fd5b813560206131b282613171565b6040516131bf828261301c565b83815260059390931b85018201928281019150868411156131df57600080fd5b8286015b848110156131fa57803583529183019183016131e3565b509695505050505050565b600082601f83011261321657600080fd5b61301583833560208501613048565b6000806000806080858703121561323b57600080fd5b61324485612f9c565b935060208501356001600160401b038082111561326057600080fd5b61326c88838901613194565b9450604087013591508082111561328257600080fd5b61328e88838901613194565b935060608701359150808211156132a457600080fd5b506132b187828801613205565b91505092959194509250565b600080600080600060a086880312156132d557600080fd5b6132de86612f9c565b94506132ec60208701612f9c565b935060408601356001600160401b038082111561330857600080fd5b61331489838a01613194565b9450606088013591508082111561332a57600080fd5b61333689838a01613194565b9350608088013591508082111561334c57600080fd5b5061335988828901613205565b9150509295509295909350565b80356001600160601b0381168114612fb357600080fd5b6000806040838503121561339057600080fd5b61339983613366565b915061316860208401612f9c565b600080604083850312156133ba57600080fd5b82356001600160401b03808211156133d157600080fd5b818501915085601f8301126133e557600080fd5b813560206133f282613171565b6040516133ff828261301c565b83815260059390931b850182019282810191508984111561341f57600080fd5b948201945b838610156134445761343586612f9c565b82529482019490820190613424565b9650508601359250508082111561345a57600080fd5b5061346785828601613194565b9150509250929050565b600081518084526020808501945080840160005b838110156134a157815187529582019590820190600101613485565b509495945050505050565b6020815260006130156020830184613471565b6000602082840312156134d157600080fd5b61301582612f9c565b60008083601f8401126134ec57600080fd5b5081356001600160401b0381111561350357600080fd5b602083019150836020828501011115612bf657600080fd5b600080600080600080600060c0888a03121561353657600080fd5b61353f88613366565b965061354d60208901613366565b9550604088013594506060880135935061356960808901612f9c565b925060a08801356001600160401b0381111561358457600080fd5b6135908a828b016134da565b989b979a50959850939692959293505050565b600080600080608085870312156135b957600080fd5b6135c285612f9c565b9350602085013592506040850135915060608501356001600160401b038111156135eb57600080fd5b6132b187828801613205565b60008060008060006080868803121561360f57600080fd5b61361886613366565b945061362660208701613366565b935061363460408701612f9c565b925060608601356001600160401b0381111561364f57600080fd5b61365b888289016134da565b969995985093965092949392505050565b6000806040838503121561367f57600080fd5b61368883612f9c565b91506020830135801515811461369d57600080fd5b809150509250929050565b600080604083850312156136bb57600080fd5b6136c483613366565b915061316860208401613366565b600080604083850312156136e557600080fd5b61339983612f9c565b600080600080600060a0868803121561370657600080fd5b61370f86612f9c565b945061371d60208701612f9c565b9350604086013592506060860135915060808601356001600160401b0381111561374657600080fd5b61335988828901613205565b60008060006040848603121561376757600080fd5b61377084612f9c565b925060208401356001600160401b0381111561378b57600080fd5b613797868287016134da565b9497909650939450505050565b600083516137b6818460208801612f54565b8351908301906137ca818360208801612f54565b64173539b7b760d91b9101908152600501949350505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6020808252602e908201527f496e74726163746f7069613a204f6e6c792061646d696e2063616e2063616c6c60408201526d103a3434b990333ab731ba34b7b760911b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082198211156138a7576138a761387e565b500190565b60006000198214156138c0576138c061387e565b5060010190565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b6020808252601c908201527f496e74726163746f7069613a20416c726561647920636c61696d656400000000604082015260600190565b600181811c9082168061396157607f821691505b6020821081141561398257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b6000826139ad576139ad613988565b500490565b6000828210156139c4576139c461387e565b500390565b6000826139d8576139d8613988565b500690565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b604081526000613a796040830185613471565b8281036020840152613a8b8185613471565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b0386811682528516602082015260a060408201819052600090613b9a90830186613471565b8281036060840152613bac8186613471565b90508281036080840152613bc08185613106565b98975050505050505050565b600060208284031215613bde57600080fd5b815161301581612fe2565b600060033d11156127065760046000803e5060005160e01c90565b600060443d1015613c125790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613c4157505050505090565b8285019150815181811115613c595750505050505090565b843d8701016020828501011115613c735750505050505090565b613c826020828601018761301c565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090613d0f90830184613106565b979650505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220da2feff0257b5280c1fa25b0b334cebacd33e1db30d5b1a815a5de2a10c154a064736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000df1b0d8f4b45227e2750249d3e8598aca66521fa
-----Decoded View---------------
Arg [0] : _trustedForwarder (address): 0xdf1b0d8f4B45227E2750249D3E8598acA66521Fa
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000df1b0d8f4b45227e2750249d3e8598aca66521fa
Deployed Bytecode Sourcemap
2915:8257:32:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9060:12;9086:7;1513:6:0;;-1:-1:-1;;;;;1513:6:0;;1441:85;9086:7:32;9131:12;;;9141:1;9131:12;;;;;;;;;-1:-1:-1;;;;;9078:21:32;;;;;9107:9;;9078:75;;9131:12;9078:75;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9059:94;;;9171:7;9163:48;;;;-1:-1:-1;;;9163:48:32;;890:2:48;9163:48:32;;;872:21:48;929:2;909:18;;;902:30;968;948:18;;;941:58;1016:18;;9163:48:32;;;;;;;;;9009:209;2915:8257;;9266:9;:13;9262:232;;9350:12;9376:7;1513:6:0;;-1:-1:-1;;;;;1513:6:0;;1441:85;9262:232:32;2915:8257;1939:29;;;;;;;;;;;;;;;;;;;1191:25:48;;;1179:2;1164:18;1939:29:32;;;;;;;;2593:227:5;;;;;;;;;;-1:-1:-1;2593:227:5;;;;;:::i;:::-;;:::i;1600:349::-;;;;;;;;;;-1:-1:-1;1600:349:5;;;;;:::i;:::-;;:::i;:::-;;;2215:14:48;;2208:22;2190:41;;2178:2;2163:18;1600:349:5;2050:187:48;7741:83:32;;;;;;;;;;-1:-1:-1;7741:83:32;;;;;:::i;:::-;;:::i;2567:52::-;;;;;;;;;;-1:-1:-1;2567:52:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;976:150;;;;;;;;;;;;1031:95;976:150;;7085:201;;;;;;;;;;-1:-1:-1;7085:201:32;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2116:61::-;;;;;;;;;;-1:-1:-1;2116:61:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;8166:489;;;;;;;;;;-1:-1:-1;8166:489:32;;;;;:::i;:::-;;:::i;2233:47::-;;;;;;;;;;-1:-1:-1;2233:47:32;;;;;:::i;:::-;;;;;;;;;;;;;;4473:427:5;;;;;;;;;;-1:-1:-1;4473:427:5;;;;;:::i;:::-;;:::i;2339:61:32:-;;;;;;;;;;-1:-1:-1;2339:61:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;7672:63;;;;;;;;;;;;;:::i;2977:508:5:-;;;;;;;;;;-1:-1:-1;2977:508:5;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2019:43:32:-;;;;;;;;;;-1:-1:-1;2019:43:32;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;2019:43:32;;;;;;-1:-1:-1;;;;;10219:32:48;;;10201:51;;10189:2;10174:18;2019:43:32;10055:203:48;627:136:1;;;;;;;;;;-1:-1:-1;627:136:1;;;;;:::i;:::-;739:17;-1:-1:-1;;;;;726:30:1;;;;;;;627:136;1888:28:32;;;;;;;;;;-1:-1:-1;1888:28:32;;;;-1:-1:-1;;;;;1888:28:32;;;4850:1270;;;;;;;;;;-1:-1:-1;4850:1270:32;;;;;:::i;:::-;;:::i;1858:84:3:-;;;;;;;;;;-1:-1:-1;1928:7:3;;;;1858:84;;2071:101:0;;;;;;;;;;;;;:::i;7889:271:32:-;;;;;;;;;;-1:-1:-1;7889:271:32;;;;;:::i;:::-;;:::i;7607:59::-;;;;;;;;;;;;;:::i;1441:85:0:-;;;;;;;;;;-1:-1:-1;1513:6:0;;-1:-1:-1;;;;;1513:6:0;1441:85;;6126:953:32;;;;;;;;;;-1:-1:-1;6126:953:32;;;;;:::i;:::-;;:::i;3553:153:5:-;;;;;;;;;;-1:-1:-1;3553:153:5;;;;;:::i;:::-;;:::i;7345:256:32:-;;;;;;;;;;-1:-1:-1;7345:256:32;;;;;:::i;:::-;;:::i;4410:434::-;;;;;;;;;;-1:-1:-1;4410:434:32;;;;;:::i;:::-;;:::i;792:177::-;;;;;;;;;;;;841:128;792:177;;2454:66;;;;;;;;;;-1:-1:-1;2454:66:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;8661:259;;;;;;;;;;-1:-1:-1;8661:259:32;;;;;:::i;:::-;;:::i;3773:166:5:-;;;;;;;;;;-1:-1:-1;3773:166:5;;;;;:::i;:::-;-1:-1:-1;;;;;3895:27:5;;;3872:4;3895:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;3773:166;4006:395;;;;;;;;;;-1:-1:-1;4006:395:5;;;;;:::i;:::-;;:::i;2321:198:0:-;;;;;;;;;;-1:-1:-1;2321:198:0;;;;;:::i;:::-;;:::i;3671:680:32:-;;;;;;;;;;-1:-1:-1;3671:680:32;;;;;:::i;:::-;;:::i;2593:227:5:-;2679:7;-1:-1:-1;;;;;2706:21:5;;2698:76;;;;-1:-1:-1;;;2698:76:5;;14926:2:48;2698:76:5;;;14908:21:48;14965:2;14945:18;;;14938:30;15004:34;14984:18;;;14977:62;-1:-1:-1;;;15055:18:48;;;15048:40;15105:19;;2698:76:5;14724:406:48;2698:76:5;-1:-1:-1;2791:13:5;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;2791:22:5;;;;;;;;;;;;2593:227::o;1600:349::-;1724:4;-1:-1:-1;;;;;;1759:52:5;;-1:-1:-1;;;1759:52:5;;:131;;-1:-1:-1;;;;;;;1827:63:5;;-1:-1:-1;;;1827:63:5;1759:131;:183;;;-1:-1:-1;;;;;;;;;;1168:51:14;;;1906:36:5;1740:202;1600:349;-1:-1:-1;;1600:349:5:o;7741:83:32:-;1334:13:0;:11;:13::i;:::-;7804::32::1;7812:4;7804:7;:13::i;:::-;7741:83:::0;:::o;7085:201::-;7154:13;7210:19;7220:8;7210:9;:19::i;:::-;7231:37;7259:8;7231:27;:37::i;:::-;7193:85;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7179:100;;7085:201;;;:::o;8166:489::-;1815:1:4;2569:7;;:19;;2561:63;;;;-1:-1:-1;;;2561:63:4;;;;;;;:::i;:::-;1815:1;2699:7;:18;8356:9:32::1;8351:239;8375:9;:16;8371:1;:20;8351:239;;;8412:10;8425:9;8435:1;8425:12;;;;;;;;:::i;:::-;;;;;;;8412:25;;8459:7;:11;8467:2;8459:11;;;;;;;;;;;:25;8471:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;8459:25:32::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;8459:25:32;;::::1;;8451:84;;;;-1:-1:-1::0;;;8451:84:32::1;;;;;;;:::i;:::-;8568:8;8577:1;8568:11;;;;;;;;:::i;:::-;;;;;;;8549;:15;8561:2;8549:15;;;;;;;;;;;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;8393:3:32;;-1:-1:-1;8393:3:32::1;::::0;-1:-1:-1;8393:3:32;::::1;:::i;:::-;;;;8351:239;;;;8599:49;8616:3;8621:9;8632:8;8642:5;8599:16;:49::i;:::-;-1:-1:-1::0;;1772:1:4;2872:7;:22;-1:-1:-1;;8166:489:32:o;4473:427:5:-;4706:12;:10;:12::i;:::-;-1:-1:-1;;;;;4698:20:5;:4;-1:-1:-1;;;;;4698:20:5;;:60;;;;4722:36;4739:4;4745:12;:10;:12::i;4722:36::-;4677:154;;;;-1:-1:-1;;;4677:154:5;;;;;;;:::i;:::-;4841:52;4864:4;4870:2;4874:3;4879:7;4888:4;4841:22;:52::i;:::-;4473:427;;;;;:::o;7672:63:32:-;1334:13:0;:11;:13::i;:::-;7718:10:32::1;:8;:10::i;:::-;7672:63::o:0;2977:508:5:-;3128:16;3187:3;:10;3168:8;:15;:29;3160:83;;;;-1:-1:-1;;;3160:83:5;;17707:2:48;3160:83:5;;;17689:21:48;17746:2;17726:18;;;17719:30;17785:34;17765:18;;;17758:62;-1:-1:-1;;;17836:18:48;;;17829:39;17885:19;;3160:83:5;17505:405:48;3160:83:5;3254:30;3301:8;:15;-1:-1:-1;;;;;3287:30:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3287:30:5;;3254:63;;3333:9;3328:120;3352:8;:15;3348:1;:19;3328:120;;;3407:30;3417:8;3426:1;3417:11;;;;;;;;:::i;:::-;;;;;;;3430:3;3434:1;3430:6;;;;;;;;:::i;:::-;;;;;;;3407:9;:30::i;:::-;3388:13;3402:1;3388:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;3369:3;;;:::i;:::-;;;3328:120;;;-1:-1:-1;3465:13:5;2977:508;-1:-1:-1;;;2977:508:5:o;4850:1270:32:-;1482:19:3;:17;:19::i;:::-;1815:1:4::1;2569:7;;:19;;2561:63;;;;-1:-1:-1::0;;;2561:63:4::1;;;;;;;:::i;:::-;1815:1;2699:7;:18:::0;3248:1:32::2;3219:17:::0;;;:7:::2;:17;::::0;;;;;5100:8;;-1:-1:-1;;;;;3219:17:32::2;3211:79;;;::::0;-1:-1:-1;;;3211:79:32;;18117:2:48;3211:79:32::2;::::0;::::2;18099:21:48::0;18156:2;18136:18;;;18129:30;18195:34;18175:18;;;18168:62;-1:-1:-1;;;18246:18:48;;;18239:33;18289:19;;3211:79:32::2;17915:399:48::0;3211:79:32::2;5140:1:::3;5128:9;-1:-1:-1::0;;;;;5128:13:32::3;;5120:55;;;::::0;-1:-1:-1;;;5120:55:32;;18521:2:48;5120:55:32::3;::::0;::::3;18503:21:48::0;18560:2;18540:18;;;18533:30;18599:31;18579:18;;;18572:59;18648:18;;5120:55:32::3;18319:353:48::0;5120:55:32::3;5203:1;5193:7;-1:-1:-1::0;;;;;5193:11:32::3;;5185:51;;;::::0;-1:-1:-1;;;5185:51:32;;18879:2:48;5185:51:32::3;::::0;::::3;18861:21:48::0;18918:2;18898:18;;;18891:30;18957:29;18937:18;;;18930:57;19004:18;;5185:51:32::3;18677:351:48::0;5185:51:32::3;5265:1;5254:8;:12;5246:53;;;::::0;-1:-1:-1;;;5246:53:32;;19235:2:48;5246:53:32::3;::::0;::::3;19217:21:48::0;19274:2;19254:18;;;19247:30;19313;19293:18;;;19286:58;19361:18;;5246:53:32::3;19033:352:48::0;5246:53:32::3;5334:1;5317:14;:18;5309:58;;;::::0;-1:-1:-1;;;5309:58:32;;19592:2:48;5309:58:32::3;::::0;::::3;19574:21:48::0;19631:2;19611:18;;;19604:30;19670:29;19650:18;;;19643:57;19717:18;;5309:58:32::3;19390:351:48::0;5309:58:32::3;-1:-1:-1::0;;;;;5385:26:32;::::3;5377:71;;;::::0;-1:-1:-1;;;5377:71:32;;19948:2:48;5377:71:32::3;::::0;::::3;19930:21:48::0;;;19967:18;;;19960:30;20026:34;20006:18;;;19999:62;20078:18;;5377:71:32::3;19746:356:48::0;5377:71:32::3;-1:-1:-1::0;;;;;5468:21:32;::::3;;::::0;;;:10:::3;:21;::::0;;;;;;;-1:-1:-1;;;;;5468:35:32;::::3;::::0;;;;;;;;::::3;;5467:36;5459:77;;;;-1:-1:-1::0;;;5459:77:32::3;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5555:27:32;;::::3;;::::0;;;:16:::3;:27;::::0;;;;;;;:36;;::::3;::::0;;;;;;;::::3;;5554:37;5546:78;;;;-1:-1:-1::0;;;5546:78:32::3;;;;;;;:::i;:::-;5651:125;5672:70;5683:9;5694:7;5703:8;5713:12;5727:14;5672:10;:70::i;:::-;5756:10;;5651:7;:125::i;:::-;5643:168;;;::::0;-1:-1:-1;;;5643:168:32;;20666:2:48;5643:168:32::3;::::0;::::3;20648:21:48::0;20705:2;20685:18;;;20678:30;20744:32;20724:18;;;20717:60;20794:18;;5643:168:32::3;20464:354:48::0;5643:168:32::3;-1:-1:-1::0;;;;;5822:21:32;;::::3;;::::0;;;:10:::3;:21;::::0;;;;;;;-1:-1:-1;;;;;5822:35:32;::::3;::::0;;;;;;;;;:42;;5860:4:::3;-1:-1:-1::0;;5822:42:32;;::::3;::::0;::::3;::::0;;;5874:27;;;:16:::3;:27:::0;;;;;:36;;::::3;::::0;;;;;;;;;;:43;;;;::::3;;::::0;;;5932:72;;20995:58:48;;;21069:18;;;21062:34;;;5822:35:32;;5965:8;;5874:36;;5932:72:::3;::::0;20968:18:48;5932:72:32::3;;;;;;;6015:21;::::0;;;:11:::3;:21;::::0;;;;:39;;6040:14;;6015:21;:39:::3;::::0;6040:14;;6015:39:::3;:::i;:::-;;;;;;;;6064:49;6070:12;6084:8;6094:14;6064:49;;;;;;;;;;;::::0;:5:::3;:49::i;:::-;-1:-1:-1::0;;1772:1:4::1;2872:7;:22:::0;-1:-1:-1;;;;;;4850:1270:32:o;2071:101:0:-;1334:13;:11;:13::i;:::-;2135:30:::1;2162:1;2135:18;:30::i;7889:271:32:-:0;1815:1:4;2569:7;;:19;;2561:63;;;;-1:-1:-1;;;2561:63:4;;;;;;;:::i;:::-;1815:1;2699:7;:18;3369:17:32::1;::::0;;;:7:::1;:17;::::0;;;;8049:8;;3387:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;3369:31:32::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;3369:31:32;;::::1;;3361:90;;;;-1:-1:-1::0;;;3361:90:32::1;;;;;;;:::i;:::-;8069:21:::2;::::0;;;:11:::2;:21;::::0;;;;:32;;8094:7;;8069:21;:32:::2;::::0;8094:7;;8069:32:::2;:::i;:::-;::::0;;;-1:-1:-1;8111:42:32::2;::::0;-1:-1:-1;8123:3:32;8128:8;8138:7;8147:5;8111:11:::2;:42::i;:::-;-1:-1:-1::0;;1772:1:4;2872:7;:22;-1:-1:-1;;;7889:271:32:o;7607:59::-;1334:13:0;:11;:13::i;:::-;7651:8:32::1;:6;:8::i;6126:953::-:0;1482:19:3;:17;:19::i;:::-;1815:1:4::1;2569:7;;:19;;2561:63;;;;-1:-1:-1::0;;;2561:63:4::1;;;;;;;:::i;:::-;1815:1;2699:7;:18:::0;-1:-1:-1;;;;;6329:13:32;::::2;6321:55;;;::::0;-1:-1:-1;;;6321:55:32;;18521:2:48;6321:55:32::2;::::0;::::2;18503:21:48::0;18560:2;18540:18;;;18533:30;18599:31;18579:18;;;18572:59;18648:18;;6321:55:32::2;18319:353:48::0;6321:55:32::2;6404:1;6394:7;-1:-1:-1::0;;;;;6394:11:32::2;;6386:51;;;::::0;-1:-1:-1;;;6386:51:32;;18879:2:48;6386:51:32::2;::::0;::::2;18861:21:48::0;18918:2;18898:18;;;18891:30;18957:29;18937:18;;;18930:57;19004:18;;6386:51:32::2;18677:351:48::0;6386:51:32::2;-1:-1:-1::0;;;;;6455:26:32;::::2;6447:71;;;::::0;-1:-1:-1;;;6447:71:32;;19948:2:48;6447:71:32::2;::::0;::::2;19930:21:48::0;;;19967:18;;;19960:30;20026:34;20006:18;;;19999:62;20078:18;;6447:71:32::2;19746:356:48::0;6447:71:32::2;6529:12;6544:49;6560:9;6571:7;6580:12;6544:15;:49::i;:::-;6612:26;::::0;;;:20:::2;:26;::::0;;;;;6529:64;;-1:-1:-1;6612:26:32::2;;6611:27;6603:68;;;;-1:-1:-1::0;;;6603:68:32::2;;;;;;;:::i;:::-;6706:1;::::0;6763:59:::2;6784:4:::0;6802:10;;6763:7:::2;:59::i;:::-;6755:102;;;::::0;-1:-1:-1;;;6755:102:32;;20666:2:48;6755:102:32::2;::::0;::::2;20648:21:48::0;20705:2;20685:18;;;20678:30;20744:32;20724:18;;;20717:60;20794:18;;6755:102:32::2;20464:354:48::0;6755:102:32::2;6868:26;::::0;;;:20:::2;:26;::::0;;;;;;;;:33;;-1:-1:-1;;6868:33:32::2;6897:4;6868:33;::::0;;6916:51;;-1:-1:-1;;;;;10219:32:48;;10201:51;;-1:-1:-1;;;;;6916:51:32;;::::2;::::0;;;::::2;::::0;::::2;::::0;10174:18:48;6916:51:32::2;;;;;;;6978:20;::::0;;;:11:::2;:20;::::0;;;;:37;;7002:13;;6978:20;:37:::2;::::0;7002:13;;6978:37:::2;:::i;:::-;;;;;;;;7025:47;7031:12;7045:7;7054:13;7025:47;;;;;;;;;;;::::0;:5:::2;:47::i;3553:153:5:-:0;3647:52;3666:12;:10;:12::i;:::-;3680:8;3690;3647:18;:52::i;:::-;3553:153;;:::o;7345:256:32:-;1334:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;7428:28:32;::::1;7420:69;;;::::0;-1:-1:-1;;;7420:69:32;;21309:2:48;7420:69:32::1;::::0;::::1;21291:21:48::0;21348:2;21328:18;;;21321:30;21387;21367:18;;;21360:58;21435:18;;7420:69:32::1;21107:352:48::0;7420:69:32::1;7524:13;::::0;7504:50:::1;::::0;;-1:-1:-1;;;;;7524:13:32;;::::1;21676:34:48::0;;21746:15;;;21741:2;21726:18;;21719:43;7504:50:32::1;::::0;21611:18:48;7504:50:32::1;;;;;;;7564:13;:30:::0;;-1:-1:-1;;;;;;7564:30:32::1;-1:-1:-1::0;;;;;7564:30:32;;;::::1;::::0;;;::::1;::::0;;7345:256::o;4410:434::-;4518:7;1482:19:3;:17;:19::i;:::-;1815:1:4::1;2569:7;;:19;;2561:63;;;;-1:-1:-1::0;;;2561:63:4::1;;;;;;;:::i;:::-;1815:1;2699:7;:18;;;;4555:1:32::2;4537:14;;:19;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;4580:14:32::2;::::0;4613:12:::2;:10;:12::i;:::-;4598;::::0;;;:7:::2;:12;::::0;;;;;;;:27;;-1:-1:-1;;;;;;4598:27:32::2;-1:-1:-1::0;;;;;4598:27:32;;;::::2;::::0;;;::::2;::::0;;;4635:7:::2;:12:::0;;;;;-1:-1:-1;;4648:12:32::2;:10;:12::i;:::-;-1:-1:-1::0;;;;;4635:26:32::2;::::0;;::::2;::::0;::::2;::::0;;;;;;-1:-1:-1;4635:26:32;:33;;-1:-1:-1;;4635:33:32::2;::::0;::::2;;::::0;;;::::2;::::0;;4672:44:::2;4678:12;:10;:12::i;:::-;4692:3;4697:14;4672:44;;;;;;;;;;;::::0;:5:::2;:44::i;:::-;4720:16;::::0;;;:11:::2;:16;::::0;;;;:33;;;4797:12:::2;:10;:12::i;:::-;-1:-1:-1::0;;;;;4768:58:32::2;4792:3;4768:58;4811:14;4768:58;;;;1191:25:48::0;;1179:2;1164:18;;1045:177;4768:58:32::2;;;;;;;;1772:1:4::1;2872:7;:22:::0;4837:3:32;4410:434;-1:-1:-1;;4410:434:32:o;8661:259::-;3369:17;;;;:7;:17;;;;;8740:8;;3387:12;:10;:12::i;:::-;-1:-1:-1;;;;;3369:31:32;;;;;;;;;;;;-1:-1:-1;3369:31:32;;;;3361:90;;;;-1:-1:-1;;;3361:90:32;;;;;;;:::i;:::-;-1:-1:-1;;;;;8768:20:32;::::1;8760:61;;;::::0;-1:-1:-1;;;8760:61:32;;21309:2:48;8760:61:32::1;::::0;::::1;21291:21:48::0;21348:2;21328:18;;;21321:30;21387;21367:18;;;21360:58;21435:18;;8760:61:32::1;21107:352:48::0;8760:61:32::1;8831:17;::::0;;;:7:::1;:17;::::0;;;;;;;-1:-1:-1;;;;;8831:25:32;::::1;::::0;;;;;;;;;;:32;;-1:-1:-1;;8831:32:32::1;8859:4;8831:32;::::0;;8878:35;;21947:25:48;;;21988:18;;;21981:60;;;;8878:35:32::1;::::0;21920:18:48;8878:35:32::1;;;;;;;8661:259:::0;;;:::o;4006:395:5:-;4214:12;:10;:12::i;:::-;-1:-1:-1;;;;;4206:20:5;:4;-1:-1:-1;;;;;4206:20:5;;:60;;;;4230:36;4247:4;4253:12;:10;:12::i;4230:36::-;4185:154;;;;-1:-1:-1;;;4185:154:5;;;;;;;:::i;:::-;4349:45;4367:4;4373:2;4377;4381:6;4389:4;4349:17;:45::i;2321:198:0:-;1334:13;:11;:13::i;:::-;-1:-1:-1;;;;;2409:22:0;::::1;2401:73;;;::::0;-1:-1:-1;;;2401:73:0;;22254:2:48;2401:73:0::1;::::0;::::1;22236:21:48::0;22293:2;22273:18;;;22266:30;22332:34;22312:18;;;22305:62;-1:-1:-1;;;22383:18:48;;;22376:36;22429:19;;2401:73:0::1;22052:402:48::0;2401:73:0::1;2484:28;2503:8;2484:18;:28::i;3671:680:32:-:0;3111:19:2;3134:13;;;;;;3133:14;;3179:34;;;;-1:-1:-1;3197:12:2;;3212:1;3197:12;;;;:16;3179:34;3178:108;;;-1:-1:-1;3258:4:2;1476:19:9;:23;;;3219:66:2;;-1:-1:-1;3268:12:2;;;;;:17;3219:66;3157:201;;;;-1:-1:-1;;;3157:201:2;;22661:2:48;3157:201:2;;;22643:21:48;22700:2;22680:18;;;22673:30;22739:34;22719:18;;;22712:62;-1:-1:-1;;;22790:18:48;;;22783:44;22844:19;;3157:201:2;22459:410:48;3157:201:2;3368:12;:16;;-1:-1:-1;;3368:16:2;3383:1;3368:16;;;3394:65;;;;3428:13;:20;;-1:-1:-1;;3428:20:2;;;;;3394:65;-1:-1:-1;;;;;3776:28:32;::::1;3768:101;;;::::0;-1:-1:-1;;;3768:101:32;;23076:2:48;3768:101:32::1;::::0;::::1;23058:21:48::0;23115:2;23095:18;;;23088:30;23154:34;23134:18;;;23127:62;23225:30;23205:18;;;23198:58;23273:19;;3768:101:32::1;22874:424:48::0;3768:101:32::1;3879:16;:14;:16::i;:::-;3905:17;:15;:17::i;:::-;3932:37;;;;;;;;;;;;;;-1:-1:-1::0;;;3932:37:32::1;;::::0;::::1;;;;;;;;;;;;;-1:-1:-1::0;;;3932:37:32::1;;::::0;:13:::1;:37::i;:::-;3979:24;:22;:24::i;:::-;4013:20;4028:4;;4013:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;4013:14:32::1;::::0;-1:-1:-1;;;4013:20:32:i:1;:::-;4043:13;:30:::0;;-1:-1:-1;;;;;;4043:30:32::1;-1:-1:-1::0;;;;;4043:30:32;::::1;;::::0;;-1:-1:-1;4092:14:32::1;:18:::0;;;4167:12:::1;:10;:12::i;:::-;4152;::::0;;;:7:::1;:12;::::0;;;;;;;:27;;-1:-1:-1;;;;;;4152:27:32::1;-1:-1:-1::0;;;;;4152:27:32;;;::::1;::::0;;;::::1;::::0;;;4189:7:::1;:12:::0;;;;;-1:-1:-1;;4202:12:32::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;4189:26:32::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;4189:26:32;:33;;-1:-1:-1;;4189:33:32::1;::::0;::::1;;::::0;;;::::1;::::0;;4226:31:::1;4232:12;:10;:12::i;:::-;4246:3;4251:1;4226:31;;;;;;;;;;;::::0;:5:::1;:31::i;:::-;4261:16;::::0;;;:11:::1;:16;::::0;;;;;;;4280:1:::1;4261:20:::0;;4297:47;;21676:34:48;;;-1:-1:-1;;;;;21746:15:48;;21726:18;;;21719:43;;;;4297:47:32::1;::::0;21611:18:48;4297:47:32::1;;;;;;;3758:593;3483:14:2::0;3479:99;;;3529:5;3513:21;;-1:-1:-1;;3513:21:2;;;3553:14;;-1:-1:-1;23455:36:48;;3553:14:2;;23443:2:48;23428:18;3553:14:2;;;;;;;3479:99;3101:483;3671:680:32;;;:::o;1599:130:0:-;1673:12;:10;:12::i;:::-;-1:-1:-1;;;;;1662:23:0;:7;1513:6;;-1:-1:-1;;;;;1513:6:0;;1441:85;1662:7;-1:-1:-1;;;;;1662:23:0;;1654:68;;;;-1:-1:-1;;;1654:68:0;;23704:2:48;1654:68:0;;;23686:21:48;;;23723:18;;;23716:30;23782:34;23762:18;;;23755:62;23834:18;;1654:68:0;23502:356:48;8581:86:5;8647:13;;;;:4;;:13;;;;;:::i;2348:103::-;2408:13;2440:4;2433:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2348:103;;;:::o;403:703:11:-;459:13;676:10;672:51;;-1:-1:-1;;702:10:11;;;;;;;;;;;;-1:-1:-1;;;702:10:11;;;;;403:703::o;672:51::-;747:5;732:12;786:75;793:9;;786:75;;818:8;;;;:::i;:::-;;-1:-1:-1;840:10:11;;-1:-1:-1;848:2:11;840:10;;:::i;:::-;;;786:75;;;870:19;902:6;-1:-1:-1;;;;;892:17:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;892:17:11;;870:39;;919:150;926:10;;919:150;;952:11;962:1;952:11;;:::i;:::-;;-1:-1:-1;1020:10:11;1028:2;1020:5;:10;:::i;:::-;1007:24;;:2;:24;:::i;:::-;994:39;;977:6;984;977:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;977:56:11;;;;;;;;-1:-1:-1;1047:11:11;1056:2;1047:11;;:::i;:::-;;;919:150;;;1092:6;403:703;-1:-1:-1;;;;403:703:11:o;10542:231:32:-;10691:14;10728:38;:36;:38::i;:::-;10721:45;;10542:231;:::o;10139:791:5:-;-1:-1:-1;;;;;10311:16:5;;10303:62;;;;-1:-1:-1;;;10303:62:5;;;;;;;:::i;:::-;10397:7;:14;10383:3;:10;:28;10375:81;;;;-1:-1:-1;;;10375:81:5;;;;;;;:::i;:::-;10467:16;10486:12;:10;:12::i;:::-;10467:31;;10591:9;10586:101;10610:3;:10;10606:1;:14;10586:101;;;10666:7;10674:1;10666:10;;;;;;;;:::i;:::-;;;;;;;10641:9;:17;10651:3;10655:1;10651:6;;;;;;;;:::i;:::-;;;;;;;10641:17;;;;;;;;;;;:21;10659:2;-1:-1:-1;;;;;10641:21:5;-1:-1:-1;;;;;10641:21:5;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;10622:3:5;;-1:-1:-1;10622:3:5;;;:::i;:::-;;;;10586:101;;;;10738:2;-1:-1:-1;;;;;10702:53:5;10734:1;-1:-1:-1;;;;;10702:53:5;10716:8;-1:-1:-1;;;;;10702:53:5;;10742:3;10747:7;10702:53;;;;;;;:::i;:::-;;;;;;;;10842:81;10878:8;10896:1;10900:2;10904:3;10909:7;10918:4;10842:35;:81::i;6643:1115::-;6863:7;:14;6849:3;:10;:28;6841:81;;;;-1:-1:-1;;;6841:81:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;6940:16:5;;6932:66;;;;-1:-1:-1;;;6932:66:5;;;;;;;:::i;:::-;7009:16;7028:12;:10;:12::i;:::-;7009:31;;7127:9;7122:411;7146:3;:10;7142:1;:14;7122:411;;;7177:10;7190:3;7194:1;7190:6;;;;;;;;:::i;:::-;;;;;;;7177:19;;7210:14;7227:7;7235:1;7227:10;;;;;;;;:::i;:::-;;;;;;;;;;;;7252:19;7274:13;;;:9;:13;;;;;;-1:-1:-1;;;;;7274:19:5;;;;;;;;;;;;7227:10;;-1:-1:-1;7315:21:5;;;;7307:76;;;;-1:-1:-1;;;7307:76:5;;;;;;;:::i;:::-;7425:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;7425:19:5;;;;;;;;;;7447:20;;;7425:42;;7495:17;;;;;;;:27;;7447:20;;7425:13;7495:27;;7447:20;;7495:27;:::i;:::-;;;;;;;;7163:370;;;7158:3;;;;:::i;:::-;;;7122:411;;;;7578:2;-1:-1:-1;;;;;7548:47:5;7572:4;-1:-1:-1;;;;;7548:47:5;7562:8;-1:-1:-1;;;;;7548:47:5;;7582:3;7587:7;7548:47;;;;;;;:::i;:::-;;;;;;;;7676:75;7712:8;7722:4;7728:2;7732:3;7737:7;7746:4;7676:35;:75::i;:::-;6831:927;6643:1115;;;;;:::o;2676:117:3:-;1729:16;:14;:16::i;:::-;2734:7:::1;:15:::0;;-1:-1:-1;;2734:15:3::1;::::0;;2764:22:::1;2773:12;:10;:12::i;:::-;2764:22;::::0;-1:-1:-1;;;;;10219:32:48;;;10201:51;;10189:2;10174:18;2764:22:3::1;;;;;;;2676:117::o:0;2010:106::-;1928:7;;;;2079:9;2071:38;;;;-1:-1:-1;;;2071:38:3;;27052:2:48;2071:38:3;;;27034:21:48;27091:2;27071:18;;;27064:30;-1:-1:-1;;;27110:18:48;;;27103:46;27166:18;;2071:38:3;26850:340:48;9561:541:32;9839:232;;;841:128;9839:232;;;27478:25:48;-1:-1:-1;;;;;27584:15:48;;;27564:18;;;27557:43;;;;27636:15;;;27616:18;;;27609:43;27668:18;;;27661:34;;;-1:-1:-1;;;;;27732:32:48;;27711:19;;;27704:61;27781:19;;;27774:35;;;9748:7:32;;9782:313;;27450:19:48;;9839:232:32;;;;;;;;;;;;;9812:273;;;;;;9782:16;:313::i;:::-;9767:328;9561:541;-1:-1:-1;;;;;;9561:541:32:o;11012:157::-;11149:13;;11115:30;;;;;;;;;;;;;;;;;;;;;;11092:4;;-1:-1:-1;;;;;11149:13:32;;11115:30;;11129:4;;11135:9;;;;;;11115:30;;11135:9;;;;11115:30;;;;;;;;;-1:-1:-1;11115:13:32;;-1:-1:-1;;;11115:30:32:i;:::-;-1:-1:-1;;;;;11115:47:32;;;11012:157;-1:-1:-1;;;;11012:157:32:o;9040:709:5:-;-1:-1:-1;;;;;9187:16:5;;9179:62;;;;-1:-1:-1;;;9179:62:5;;;;;;;:::i;:::-;9252:16;9271:12;:10;:12::i;:::-;9252:31;;9293:20;9316:21;9334:2;9316:17;:21::i;:::-;9293:44;;9347:24;9374:25;9392:6;9374:17;:25::i;:::-;9347:52;;9487:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;9487:17:5;;;;;;;;;:27;;9508:6;;9487:13;:27;;9508:6;;9487:27;:::i;:::-;;;;-1:-1:-1;;9529:52:5;;;27994:25:48;;;28050:2;28035:18;;28028:34;;;-1:-1:-1;;;;;9529:52:5;;;;9562:1;;9529:52;;;;;;27967:18:48;9529:52:5;;;;;;;9668:74;9699:8;9717:1;9721:2;9725;9729:6;9737:4;9668:30;:74::i;:::-;9169:580;;;9040:709;;;;:::o;2673:187:0:-;2765:6;;;-1:-1:-1;;;;;2781:17:0;;;-1:-1:-1;;;;;;2781:17:0;;;;;;;2813:40;;2765:6;;;2781:17;2765:6;;2813:40;;2746:16;;2813:40;2736:124;2673:187;:::o;2429:115:3:-;1482:19;:17;:19::i;:::-;2488:7:::1;:14:::0;;-1:-1:-1;;2488:14:3::1;2498:4;2488:14;::::0;;2517:20:::1;2524:12;:10;:12::i;10108:428:32:-:0;10333:172;;;1031:95;10333:172;;;28300:25:48;-1:-1:-1;;;;;28406:15:48;;;28386:18;;;28379:43;;;;28458:15;;;28438:18;;;28431:43;-1:-1:-1;;;;;28510:32:48;;28490:18;;;28483:60;10242:7:32;;10276:253;;28272:19:48;;10333:172:32;28073:476:48;13320:323:5;13470:8;-1:-1:-1;;;;;13461:17:5;:5;-1:-1:-1;;;;;13461:17:5;;;13453:71;;;;-1:-1:-1;;;13453:71:5;;28756:2:48;13453:71:5;;;28738:21:48;28795:2;28775:18;;;28768:30;28834:34;28814:18;;;28807:62;-1:-1:-1;;;28885:18:48;;;28878:39;28934:19;;13453:71:5;28554:405:48;13453:71:5;-1:-1:-1;;;;;13534:25:5;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13534:46:5;;;;;;;;;;13595:41;;2190::48;;;13595::5;;2163:18:48;13595:41:5;;;;;;;13320:323;;;:::o;5350:947::-;-1:-1:-1;;;;;5531:16:5;;5523:66;;;;-1:-1:-1;;;5523:66:5;;;;;;;:::i;:::-;5600:16;5619:12;:10;:12::i;:::-;5600:31;;5641:20;5664:21;5682:2;5664:17;:21::i;:::-;5641:44;;5695:24;5722:25;5740:6;5722:17;:25::i;:::-;5695:52;;5829:19;5851:13;;;:9;:13;;;;;;;;-1:-1:-1;;;;;5851:19:5;;;;;;;;;;5888:21;;;;5880:76;;;;-1:-1:-1;;;5880:76:5;;;;;;;:::i;:::-;5990:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;5990:19:5;;;;;;;;;;6012:20;;;5990:42;;6052:17;;;;;;;:27;;6012:20;;5990:13;6052:27;;6012:20;;6052:27;:::i;:::-;;;;-1:-1:-1;;6095:46:5;;;27994:25:48;;;28050:2;28035:18;;28028:34;;;-1:-1:-1;;;;;6095:46:5;;;;;;;;;;;;;;27967:18:48;6095:46:5;;;;;;;6222:68;6253:8;6263:4;6269:2;6273;6277:6;6285:4;6222:30;:68::i;:::-;5513:784;;;;5350:947;;;;;:::o;1003:95:0:-;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1065:26:0::1;:24;:26::i;1063:97:3:-:0;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1126:27:3::1;:25;:27::i;2306:147:13:-:0;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;2408:38:13::1;2432:4;2438:7;2408:23;:38::i;1853:111:4:-:0;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1923:34:4::1;:32;:34::i;1300:117:5:-:0;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1380:30:5::1;1405:4;1380:24;:30::i;769:448:1:-:0;831:14;739:17;-1:-1:-1;;;;;726:30:1;880:10;726:30;857:354;;;-1:-1:-1;;;1110:14:1;1106:23;1093:37;1089:2;1085:46;769:448;:::o;857:354::-;-1:-1:-1;929:10:10;;10542:231:32:o;857:354:1:-;769:448;:::o;16698:814:5:-;-1:-1:-1;;;;;16930:13:5;;1476:19:9;:23;16926:580:5;;16965:90;;-1:-1:-1;;;16965:90:5;;-1:-1:-1;;;;;16965:54:5;;;;;:90;;17020:8;;17030:4;;17036:3;;17041:7;;17050:4;;16965:90;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16965:90:5;;;;;;;;-1:-1:-1;;16965:90:5;;;;;;;;;;;;:::i;:::-;;;16961:535;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;17372:6;17365:14;;-1:-1:-1;;;17365:14:5;;;;;;;;:::i;16961:535::-;;;17419:62;;-1:-1:-1;;;17419:62:5;;31524:2:48;17419:62:5;;;31506:21:48;31563:2;31543:18;;;31536:30;31602:34;31582:18;;;31575:62;-1:-1:-1;;;31653:18:48;;;31646:50;31713:19;;17419:62:5;31322:416:48;16961:535:5;-1:-1:-1;;;;;;17134:71:5;;-1:-1:-1;;;17134:71:5;17130:168;;17229:50;;-1:-1:-1;;;17229:50:5;;;;;;;:::i;2188:106:3:-;1928:7;;;;2246:41;;;;-1:-1:-1;;;2246:41:3;;32354:2:48;2246:41:3;;;32336:21:48;32393:2;32373:18;;;32366:30;-1:-1:-1;;;32412:18:48;;;32405:50;32472:18;;2246:41:3;32152:344:48;3890:176:13;3967:7;3993:66;4026:20;:18;:20::i;:::-;4048:10;8710:57:12;;-1:-1:-1;;;8710:57:12;;;33325:27:48;33368:11;;;33361:27;;;33404:12;;;33397:28;;;8674:7:12;;33441:12:48;;8710:57:12;;;;;;;;;;;;8700:68;;;;;;8693:75;;8581:194;;;;;3759:227:29;3837:7;3857:17;3876:18;3898:27;3909:4;3915:9;3898:10;:27::i;:::-;3856:69;;;;3935:18;3947:5;3935:11;:18::i;17518:193:5:-;17637:16;;;17651:1;17637:16;;;;;;;;;17584;;17612:22;;17637:16;;;;;;;;;;;;-1:-1:-1;17637:16:5;17612:41;;17674:7;17663:5;17669:1;17663:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;17699:5;17518:193;-1:-1:-1;;17518:193:5:o;15945:747::-;-1:-1:-1;;;;;16152:13:5;;1476:19:9;:23;16148:538:5;;16187:83;;-1:-1:-1;;;16187:83:5;;-1:-1:-1;;;;;16187:49:5;;;;;:83;;16237:8;;16247:4;;16253:2;;16257:6;;16265:4;;16187:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16187:83:5;;;;;;;;-1:-1:-1;;16187:83:5;;;;;;;;;;;;:::i;:::-;;;16183:493;;;;:::i;:::-;-1:-1:-1;;;;;;16319:66:5;;-1:-1:-1;;;16319:66:5;16315:163;;16409:50;;-1:-1:-1;;;16409:50:5;;;;;;;:::i;1104:111:0:-;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1176:32:0::1;1195:12;:10;:12::i;:::-;1176:18;:32::i;1166:95:3:-:0;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1239:7:3::1;:15:::0;;-1:-1:-1;;1239:15:3::1;::::0;;1166:95::o;2459:297:13:-;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;2592:22:13;;::::1;::::0;;::::1;::::0;2648:25;;;;;::::1;::::0;2683:12:::1;:25:::0;;;;2718:15:::1;:31:::0;2459:297::o;1970:109:4:-;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;:::-;1772:1:4::1;2050:7;:22:::0;1970:109::o;1423:110:5:-;4910:13:2;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:2;;;;;;;:::i;2842:160:13:-;2895:7;2921:74;1595:95;2955:17;4386:12;;;4302:103;2955:17;4731:15;;3184:73;;;;;;35374:25:48;;;35415:18;;;35408:34;;;35458:18;;;35451:34;;;3228:13:13;35501:18:48;;;35494:34;3251:4:13;35544:19:48;;;35537:61;3148:7:13;;35346:19:48;;3184:73:13;;;;;;;;;;;;3174:84;;;;;;3167:91;;3008:257;;;;;;2243:730:29;2324:7;2333:12;2361:9;:16;2381:2;2361:22;2357:610;;;2697:4;2682:20;;2676:27;2746:4;2731:20;;2725:27;2803:4;2788:20;;2782:27;2399:9;2774:36;2844:25;2855:4;2774:36;2676:27;2725;2844:10;:25::i;:::-;2837:32;;;;;;;;;2357:610;-1:-1:-1;2916:1:29;;-1:-1:-1;2920:35:29;2357:610;2243:730;;;;;:::o;548:631::-;625:20;616:5;:29;;;;;;;;:::i;:::-;;612:561;;;548:631;:::o;612:561::-;721:29;712:5;:38;;;;;;;;:::i;:::-;;708:465;;;766:34;;-1:-1:-1;;;766:34:29;;33798:2:48;766:34:29;;;33780:21:48;33837:2;33817:18;;;33810:30;33876:26;33856:18;;;33849:54;33920:18;;766:34:29;33596:348:48;708:465:29;830:35;821:5;:44;;;;;;;;:::i;:::-;;817:356;;;881:41;;-1:-1:-1;;;881:41:29;;34151:2:48;881:41:29;;;34133:21:48;34190:2;34170:18;;;34163:30;34229:33;34209:18;;;34202:61;34280:18;;881:41:29;33949:355:48;817:356:29;952:30;943:5;:39;;;;;;;;:::i;:::-;;939:234;;;998:44;;-1:-1:-1;;;998:44:29;;34511:2:48;998:44:29;;;34493:21:48;34550:2;34530:18;;;34523:30;34589:34;34569:18;;;34562:62;-1:-1:-1;;;34640:18:48;;;34633:32;34682:19;;998:44:29;34309:398:48;939:234:29;1072:30;1063:5;:39;;;;;;;;:::i;:::-;;1059:114;;;1118:44;;-1:-1:-1;;;1118:44:29;;34914:2:48;1118:44:29;;;34896:21:48;34953:2;34933:18;;;34926:30;34992:34;34972:18;;;34965:62;-1:-1:-1;;;35043:18:48;;;35036:32;35085:19;;1118:44:29;34712:398:48;5167:1603:29;5293:7;;6217:66;6204:79;;6200:161;;;-1:-1:-1;6315:1:29;;-1:-1:-1;6319:30:29;6299:51;;6200:161;6374:1;:7;;6379:2;6374:7;;:18;;;;;6385:1;:7;;6390:2;6385:7;;6374:18;6370:100;;;-1:-1:-1;6424:1:29;;-1:-1:-1;6428:30:29;6408:51;;6370:100;6581:24;;;6564:14;6581:24;;;;;;;;;35836:25:48;;;35909:4;35897:17;;35877:18;;;35870:45;;;;35931:18;;;35924:34;;;35974:18;;;35967:34;;;6581:24:29;;35808:19:48;;6581:24:29;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6581:24:29;;-1:-1:-1;;6581:24:29;;;-1:-1:-1;;;;;;;6619:20:29;;6615:101;;6671:1;6675:29;6655:50;;;;;;;6615:101;6734:6;-1:-1:-1;6742:20:29;;-1:-1:-1;5167:1603:29;;;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:127:48;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:258;218:1;228:113;242:6;239:1;236:13;228:113;;;318:11;;;312:18;299:11;;;292:39;264:2;257:10;228:113;;;359:6;356:1;353:13;350:48;;;-1:-1:-1;;394:1:48;376:16;;369:27;146:258::o;409:274::-;538:3;576:6;570:13;592:53;638:6;633:3;626:4;618:6;614:17;592:53;:::i;:::-;661:16;;;;;409:274;-1:-1:-1;;409:274:48:o;1227:173::-;1295:20;;-1:-1:-1;;;;;1344:31:48;;1334:42;;1324:70;;1390:1;1387;1380:12;1324:70;1227:173;;;:::o;1405:254::-;1473:6;1481;1534:2;1522:9;1513:7;1509:23;1505:32;1502:52;;;1550:1;1547;1540:12;1502:52;1573:29;1592:9;1573:29;:::i;:::-;1563:39;1649:2;1634:18;;;;1621:32;;-1:-1:-1;;;1405:254:48:o;1664:131::-;-1:-1:-1;;;;;;1738:32:48;;1728:43;;1718:71;;1785:1;1782;1775:12;1800:245;1858:6;1911:2;1899:9;1890:7;1886:23;1882:32;1879:52;;;1927:1;1924;1917:12;1879:52;1966:9;1953:23;1985:30;2009:5;1985:30;:::i;:::-;2034:5;1800:245;-1:-1:-1;;;1800:245:48:o;2242:249::-;2352:2;2333:13;;-1:-1:-1;;2329:27:48;2317:40;;-1:-1:-1;;;;;2372:34:48;;2408:22;;;2369:62;2366:88;;;2434:18;;:::i;:::-;2470:2;2463:22;-1:-1:-1;;2242:249:48:o;2496:469::-;2561:5;-1:-1:-1;;;;;2587:6:48;2584:30;2581:56;;;2617:18;;:::i;:::-;2666:2;2660:9;2678:69;2735:2;2714:15;;-1:-1:-1;;2710:29:48;2741:4;2706:40;2660:9;2678:69;:::i;:::-;2765:6;2756:15;;2795:6;2787;2780:22;2835:3;2826:6;2821:3;2817:16;2814:25;2811:45;;;2852:1;2849;2842:12;2811:45;2902:6;2897:3;2890:4;2882:6;2878:17;2865:44;2957:1;2950:4;2941:6;2933;2929:19;2925:30;2918:41;;2496:469;;;;;:::o;2970:451::-;3039:6;3092:2;3080:9;3071:7;3067:23;3063:32;3060:52;;;3108:1;3105;3098:12;3060:52;3148:9;3135:23;-1:-1:-1;;;;;3173:6:48;3170:30;3167:50;;;3213:1;3210;3203:12;3167:50;3236:22;;3289:4;3281:13;;3277:27;-1:-1:-1;3267:55:48;;3318:1;3315;3308:12;3267:55;3341:74;3407:7;3402:2;3389:16;3384:2;3380;3376:11;3341:74;:::i;3426:180::-;3485:6;3538:2;3526:9;3517:7;3513:23;3509:32;3506:52;;;3554:1;3551;3544:12;3506:52;-1:-1:-1;3577:23:48;;3426:180;-1:-1:-1;3426:180:48:o;3978:258::-;4020:3;4058:5;4052:12;4085:6;4080:3;4073:19;4101:63;4157:6;4150:4;4145:3;4141:14;4134:4;4127:5;4123:16;4101:63;:::i;:::-;4218:2;4197:15;-1:-1:-1;;4193:29:48;4184:39;;;;4225:4;4180:50;;3978:258;-1:-1:-1;;3978:258:48:o;4241:220::-;4390:2;4379:9;4372:21;4353:4;4410:45;4451:2;4440:9;4436:18;4428:6;4410:45;:::i;4466:254::-;4534:6;4542;4595:2;4583:9;4574:7;4570:23;4566:32;4563:52;;;4611:1;4608;4601:12;4563:52;4647:9;4634:23;4624:33;;4676:38;4710:2;4699:9;4695:18;4676:38;:::i;:::-;4666:48;;4466:254;;;;;:::o;4725:183::-;4785:4;-1:-1:-1;;;;;4810:6:48;4807:30;4804:56;;;4840:18;;:::i;:::-;-1:-1:-1;4885:1:48;4881:14;4897:4;4877:25;;4725:183::o;4913:724::-;4967:5;5020:3;5013:4;5005:6;5001:17;4997:27;4987:55;;5038:1;5035;5028:12;4987:55;5074:6;5061:20;5100:4;5123:43;5163:2;5123:43;:::i;:::-;5195:2;5189:9;5207:31;5235:2;5227:6;5207:31;:::i;:::-;5273:18;;;5365:1;5361:10;;;;5349:23;;5345:32;;;5307:15;;;;-1:-1:-1;5389:15:48;;;5386:35;;;5417:1;5414;5407:12;5386:35;5453:2;5445:6;5441:15;5465:142;5481:6;5476:3;5473:15;5465:142;;;5547:17;;5535:30;;5585:12;;;;5498;;5465:142;;;-1:-1:-1;5625:6:48;4913:724;-1:-1:-1;;;;;;4913:724:48:o;5642:221::-;5684:5;5737:3;5730:4;5722:6;5718:17;5714:27;5704:55;;5755:1;5752;5745:12;5704:55;5777:80;5853:3;5844:6;5831:20;5824:4;5816:6;5812:17;5777:80;:::i;5868:868::-;6013:6;6021;6029;6037;6090:3;6078:9;6069:7;6065:23;6061:33;6058:53;;;6107:1;6104;6097:12;6058:53;6130:29;6149:9;6130:29;:::i;:::-;6120:39;;6210:2;6199:9;6195:18;6182:32;-1:-1:-1;;;;;6274:2:48;6266:6;6263:14;6260:34;;;6290:1;6287;6280:12;6260:34;6313:61;6366:7;6357:6;6346:9;6342:22;6313:61;:::i;:::-;6303:71;;6427:2;6416:9;6412:18;6399:32;6383:48;;6456:2;6446:8;6443:16;6440:36;;;6472:1;6469;6462:12;6440:36;6495:63;6550:7;6539:8;6528:9;6524:24;6495:63;:::i;:::-;6485:73;;6611:2;6600:9;6596:18;6583:32;6567:48;;6640:2;6630:8;6627:16;6624:36;;;6656:1;6653;6646:12;6624:36;;6679:51;6722:7;6711:8;6700:9;6696:24;6679:51;:::i;:::-;6669:61;;;5868:868;;;;;;;:::o;6741:943::-;6895:6;6903;6911;6919;6927;6980:3;6968:9;6959:7;6955:23;6951:33;6948:53;;;6997:1;6994;6987:12;6948:53;7020:29;7039:9;7020:29;:::i;:::-;7010:39;;7068:38;7102:2;7091:9;7087:18;7068:38;:::i;:::-;7058:48;;7157:2;7146:9;7142:18;7129:32;-1:-1:-1;;;;;7221:2:48;7213:6;7210:14;7207:34;;;7237:1;7234;7227:12;7207:34;7260:61;7313:7;7304:6;7293:9;7289:22;7260:61;:::i;:::-;7250:71;;7374:2;7363:9;7359:18;7346:32;7330:48;;7403:2;7393:8;7390:16;7387:36;;;7419:1;7416;7409:12;7387:36;7442:63;7497:7;7486:8;7475:9;7471:24;7442:63;:::i;:::-;7432:73;;7558:3;7547:9;7543:19;7530:33;7514:49;;7588:2;7578:8;7575:16;7572:36;;;7604:1;7601;7594:12;7572:36;;7627:51;7670:7;7659:8;7648:9;7644:24;7627:51;:::i;:::-;7617:61;;;6741:943;;;;;;;;:::o;7689:179::-;7756:20;;-1:-1:-1;;;;;7805:38:48;;7795:49;;7785:77;;7858:1;7855;7848:12;7873:258;7940:6;7948;8001:2;7989:9;7980:7;7976:23;7972:32;7969:52;;;8017:1;8014;8007:12;7969:52;8040:28;8058:9;8040:28;:::i;:::-;8030:38;;8087;8121:2;8110:9;8106:18;8087:38;:::i;8136:1208::-;8254:6;8262;8315:2;8303:9;8294:7;8290:23;8286:32;8283:52;;;8331:1;8328;8321:12;8283:52;8371:9;8358:23;-1:-1:-1;;;;;8441:2:48;8433:6;8430:14;8427:34;;;8457:1;8454;8447:12;8427:34;8495:6;8484:9;8480:22;8470:32;;8540:7;8533:4;8529:2;8525:13;8521:27;8511:55;;8562:1;8559;8552:12;8511:55;8598:2;8585:16;8620:4;8643:43;8683:2;8643:43;:::i;:::-;8715:2;8709:9;8727:31;8755:2;8747:6;8727:31;:::i;:::-;8793:18;;;8881:1;8877:10;;;;8869:19;;8865:28;;;8827:15;;;;-1:-1:-1;8905:19:48;;;8902:39;;;8937:1;8934;8927:12;8902:39;8961:11;;;;8981:148;8997:6;8992:3;8989:15;8981:148;;;9063:23;9082:3;9063:23;:::i;:::-;9051:36;;9014:12;;;;9107;;;;8981:148;;;9148:6;-1:-1:-1;;9192:18:48;;9179:32;;-1:-1:-1;;9223:16:48;;;9220:36;;;9252:1;9249;9242:12;9220:36;;9275:63;9330:7;9319:8;9308:9;9304:24;9275:63;:::i;:::-;9265:73;;;8136:1208;;;;;:::o;9349:435::-;9402:3;9440:5;9434:12;9467:6;9462:3;9455:19;9493:4;9522:2;9517:3;9513:12;9506:19;;9559:2;9552:5;9548:14;9580:1;9590:169;9604:6;9601:1;9598:13;9590:169;;;9665:13;;9653:26;;9699:12;;;;9734:15;;;;9626:1;9619:9;9590:169;;;-1:-1:-1;9775:3:48;;9349:435;-1:-1:-1;;;;;9349:435:48:o;9789:261::-;9968:2;9957:9;9950:21;9931:4;9988:56;10040:2;10029:9;10025:18;10017:6;9988:56;:::i;10263:186::-;10322:6;10375:2;10363:9;10354:7;10350:23;10346:32;10343:52;;;10391:1;10388;10381:12;10343:52;10414:29;10433:9;10414:29;:::i;10454:347::-;10505:8;10515:6;10569:3;10562:4;10554:6;10550:17;10546:27;10536:55;;10587:1;10584;10577:12;10536:55;-1:-1:-1;10610:20:48;;-1:-1:-1;;;;;10642:30:48;;10639:50;;;10685:1;10682;10675:12;10639:50;10722:4;10714:6;10710:17;10698:29;;10774:3;10767:4;10758:6;10750;10746:19;10742:30;10739:39;10736:59;;;10791:1;10788;10781:12;10806:766;10919:6;10927;10935;10943;10951;10959;10967;11020:3;11008:9;10999:7;10995:23;10991:33;10988:53;;;11037:1;11034;11027:12;10988:53;11060:28;11078:9;11060:28;:::i;:::-;11050:38;;11107:37;11140:2;11129:9;11125:18;11107:37;:::i;:::-;11097:47;;11191:2;11180:9;11176:18;11163:32;11153:42;;11242:2;11231:9;11227:18;11214:32;11204:42;;11265:39;11299:3;11288:9;11284:19;11265:39;:::i;:::-;11255:49;;11355:3;11344:9;11340:19;11327:33;-1:-1:-1;;;;;11375:6:48;11372:30;11369:50;;;11415:1;11412;11405:12;11369:50;11454:58;11504:7;11495:6;11484:9;11480:22;11454:58;:::i;:::-;10806:766;;;;-1:-1:-1;10806:766:48;;-1:-1:-1;10806:766:48;;;;11428:84;;-1:-1:-1;;;10806:766:48:o;11577:531::-;11672:6;11680;11688;11696;11749:3;11737:9;11728:7;11724:23;11720:33;11717:53;;;11766:1;11763;11756:12;11717:53;11789:29;11808:9;11789:29;:::i;:::-;11779:39;;11865:2;11854:9;11850:18;11837:32;11827:42;;11916:2;11905:9;11901:18;11888:32;11878:42;;11971:2;11960:9;11956:18;11943:32;-1:-1:-1;;;;;11990:6:48;11987:30;11984:50;;;12030:1;12027;12020:12;11984:50;12053:49;12094:7;12085:6;12074:9;12070:22;12053:49;:::i;12113:628::-;12208:6;12216;12224;12232;12240;12293:3;12281:9;12272:7;12268:23;12264:33;12261:53;;;12310:1;12307;12300:12;12261:53;12333:28;12351:9;12333:28;:::i;:::-;12323:38;;12380:37;12413:2;12402:9;12398:18;12380:37;:::i;:::-;12370:47;;12436:38;12470:2;12459:9;12455:18;12436:38;:::i;:::-;12426:48;;12525:2;12514:9;12510:18;12497:32;-1:-1:-1;;;;;12544:6:48;12541:30;12538:50;;;12584:1;12581;12574:12;12538:50;12623:58;12673:7;12664:6;12653:9;12649:22;12623:58;:::i;:::-;12113:628;;;;-1:-1:-1;12113:628:48;;-1:-1:-1;12700:8:48;;12597:84;12113:628;-1:-1:-1;;;12113:628:48:o;12746:347::-;12811:6;12819;12872:2;12860:9;12851:7;12847:23;12843:32;12840:52;;;12888:1;12885;12878:12;12840:52;12911:29;12930:9;12911:29;:::i;:::-;12901:39;;12990:2;12979:9;12975:18;12962:32;13037:5;13030:13;13023:21;13016:5;13013:32;13003:60;;13059:1;13056;13049:12;13003:60;13082:5;13072:15;;;12746:347;;;;;:::o;13098:256::-;13164:6;13172;13225:2;13213:9;13204:7;13200:23;13196:32;13193:52;;;13241:1;13238;13231:12;13193:52;13264:28;13282:9;13264:28;:::i;:::-;13254:38;;13311:37;13344:2;13333:9;13329:18;13311:37;:::i;13359:260::-;13427:6;13435;13488:2;13476:9;13467:7;13463:23;13459:32;13456:52;;;13504:1;13501;13494:12;13456:52;13527:29;13546:9;13527:29;:::i;13624:606::-;13728:6;13736;13744;13752;13760;13813:3;13801:9;13792:7;13788:23;13784:33;13781:53;;;13830:1;13827;13820:12;13781:53;13853:29;13872:9;13853:29;:::i;:::-;13843:39;;13901:38;13935:2;13924:9;13920:18;13901:38;:::i;:::-;13891:48;;13986:2;13975:9;13971:18;13958:32;13948:42;;14037:2;14026:9;14022:18;14009:32;13999:42;;14092:3;14081:9;14077:19;14064:33;-1:-1:-1;;;;;14112:6:48;14109:30;14106:50;;;14152:1;14149;14142:12;14106:50;14175:49;14216:7;14207:6;14196:9;14192:22;14175:49;:::i;14235:484::-;14315:6;14323;14331;14384:2;14372:9;14363:7;14359:23;14355:32;14352:52;;;14400:1;14397;14390:12;14352:52;14423:29;14442:9;14423:29;:::i;:::-;14413:39;;14503:2;14492:9;14488:18;14475:32;-1:-1:-1;;;;;14522:6:48;14519:30;14516:50;;;14562:1;14559;14552:12;14516:50;14601:58;14651:7;14642:6;14631:9;14627:22;14601:58;:::i;:::-;14235:484;;14678:8;;-1:-1:-1;14575:84:48;;-1:-1:-1;;;;14235:484:48:o;15135:637::-;15415:3;15453:6;15447:13;15469:53;15515:6;15510:3;15503:4;15495:6;15491:17;15469:53;:::i;:::-;15585:13;;15544:16;;;;15607:57;15585:13;15544:16;15641:4;15629:17;;15607:57;:::i;:::-;-1:-1:-1;;;15686:20:48;;15715:22;;;15764:1;15753:13;;15135:637;-1:-1:-1;;;;15135:637:48:o;15777:355::-;15979:2;15961:21;;;16018:2;15998:18;;;15991:30;16057:33;16052:2;16037:18;;16030:61;16123:2;16108:18;;15777:355::o;16137:127::-;16198:10;16193:3;16189:20;16186:1;16179:31;16229:4;16226:1;16219:15;16253:4;16250:1;16243:15;16269:410;16471:2;16453:21;;;16510:2;16490:18;;;16483:30;16549:34;16544:2;16529:18;;16522:62;-1:-1:-1;;;16615:2:48;16600:18;;16593:44;16669:3;16654:19;;16269:410::o;16684:127::-;16745:10;16740:3;16736:20;16733:1;16726:31;16776:4;16773:1;16766:15;16800:4;16797:1;16790:15;16816:128;16856:3;16887:1;16883:6;16880:1;16877:13;16874:39;;;16893:18;;:::i;:::-;-1:-1:-1;16929:9:48;;16816:128::o;16949:135::-;16988:3;-1:-1:-1;;17009:17:48;;17006:43;;;17029:18;;:::i;:::-;-1:-1:-1;17076:1:48;17065:13;;16949:135::o;17089:411::-;17291:2;17273:21;;;17330:2;17310:18;;;17303:30;17369:34;17364:2;17349:18;;17342:62;-1:-1:-1;;;17435:2:48;17420:18;;17413:45;17490:3;17475:19;;17089:411::o;20107:352::-;20309:2;20291:21;;;20348:2;20328:18;;;20321:30;20387;20382:2;20367:18;;20360:58;20450:2;20435:18;;20107:352::o;23863:380::-;23942:1;23938:12;;;;23985;;;24006:61;;24060:4;24052:6;24048:17;24038:27;;24006:61;24113:2;24105:6;24102:14;24082:18;24079:38;24076:161;;;24159:10;24154:3;24150:20;24147:1;24140:31;24194:4;24191:1;24184:15;24222:4;24219:1;24212:15;24076:161;;23863:380;;;:::o;24248:127::-;24309:10;24304:3;24300:20;24297:1;24290:31;24340:4;24337:1;24330:15;24364:4;24361:1;24354:15;24380:120;24420:1;24446;24436:35;;24451:18;;:::i;:::-;-1:-1:-1;24485:9:48;;24380:120::o;24505:125::-;24545:4;24573:1;24570;24567:8;24564:34;;;24578:18;;:::i;:::-;-1:-1:-1;24615:9:48;;24505:125::o;24635:112::-;24667:1;24693;24683:35;;24698:18;;:::i;:::-;-1:-1:-1;24732:9:48;;24635:112::o;24752:397::-;24954:2;24936:21;;;24993:2;24973:18;;;24966:30;25032:34;25027:2;25012:18;;25005:62;-1:-1:-1;;;25098:2:48;25083:18;;25076:31;25139:3;25124:19;;24752:397::o;25154:404::-;25356:2;25338:21;;;25395:2;25375:18;;;25368:30;25434:34;25429:2;25414:18;;25407:62;-1:-1:-1;;;25500:2:48;25485:18;;25478:38;25548:3;25533:19;;25154:404::o;25563:465::-;25820:2;25809:9;25802:21;25783:4;25846:56;25898:2;25887:9;25883:18;25875:6;25846:56;:::i;:::-;25950:9;25942:6;25938:22;25933:2;25922:9;25918:18;25911:50;25978:44;26015:6;26007;25978:44;:::i;:::-;25970:52;25563:465;-1:-1:-1;;;;;25563:465:48:o;26033:401::-;26235:2;26217:21;;;26274:2;26254:18;;;26247:30;26313:34;26308:2;26293:18;;26286:62;-1:-1:-1;;;26379:2:48;26364:18;;26357:35;26424:3;26409:19;;26033:401::o;26439:406::-;26641:2;26623:21;;;26680:2;26660:18;;;26653:30;26719:34;26714:2;26699:18;;26692:62;-1:-1:-1;;;26785:2:48;26770:18;;26763:40;26835:3;26820:19;;26439:406::o;28964:407::-;29166:2;29148:21;;;29205:2;29185:18;;;29178:30;29244:34;29239:2;29224:18;;29217:62;-1:-1:-1;;;29310:2:48;29295:18;;29288:41;29361:3;29346:19;;28964:407::o;29376:827::-;-1:-1:-1;;;;;29773:15:48;;;29755:34;;29825:15;;29820:2;29805:18;;29798:43;29735:3;29872:2;29857:18;;29850:31;;;29698:4;;29904:57;;29941:19;;29933:6;29904:57;:::i;:::-;30009:9;30001:6;29997:22;29992:2;29981:9;29977:18;29970:50;30043:44;30080:6;30072;30043:44;:::i;:::-;30029:58;;30136:9;30128:6;30124:22;30118:3;30107:9;30103:19;30096:51;30164:33;30190:6;30182;30164:33;:::i;:::-;30156:41;29376:827;-1:-1:-1;;;;;;;;29376:827:48:o;30208:249::-;30277:6;30330:2;30318:9;30309:7;30305:23;30301:32;30298:52;;;30346:1;30343;30336:12;30298:52;30378:9;30372:16;30397:30;30421:5;30397:30;:::i;30462:179::-;30497:3;30539:1;30521:16;30518:23;30515:120;;;30585:1;30582;30579;30564:23;-1:-1:-1;30622:1:48;30616:8;30611:3;30607:18;30462:179;:::o;30646:671::-;30685:3;30727:4;30709:16;30706:26;30703:39;;;30646:671;:::o;30703:39::-;30769:2;30763:9;-1:-1:-1;;30834:16:48;30830:25;;30827:1;30763:9;30806:50;30885:4;30879:11;30909:16;-1:-1:-1;;;;;31015:2:48;31008:4;31000:6;30996:17;30993:25;30988:2;30980:6;30977:14;30974:45;30971:58;;;31022:5;;;;;30646:671;:::o;30971:58::-;31059:6;31053:4;31049:17;31038:28;;31095:3;31089:10;31122:2;31114:6;31111:14;31108:27;;;31128:5;;;;;;30646:671;:::o;31108:27::-;31212:2;31193:16;31187:4;31183:27;31179:36;31172:4;31163:6;31158:3;31154:16;31150:27;31147:69;31144:82;;;31219:5;;;;;;30646:671;:::o;31144:82::-;31235:57;31286:4;31277:6;31269;31265:19;31261:30;31255:4;31235:57;:::i;:::-;-1:-1:-1;31308:3:48;;30646:671;-1:-1:-1;;;;;30646:671:48:o;31743:404::-;31945:2;31927:21;;;31984:2;31964:18;;;31957:30;32023:34;32018:2;32003:18;;31996:62;-1:-1:-1;;;32089:2:48;32074:18;;32067:38;32137:3;32122:19;;31743:404::o;32501:561::-;-1:-1:-1;;;;;32798:15:48;;;32780:34;;32850:15;;32845:2;32830:18;;32823:43;32897:2;32882:18;;32875:34;;;32940:2;32925:18;;32918:34;;;32760:3;32983;32968:19;;32961:32;;;32723:4;;33010:46;;33036:19;;33028:6;33010:46;:::i;:::-;33002:54;32501:561;-1:-1:-1;;;;;;;32501:561:48:o;33464:127::-;33525:10;33520:3;33516:20;33513:1;33506:31;33556:4;33553:1;33546:15;33580:4;33577:1;33570:15
Swarm Source
ipfs://da2feff0257b5280c1fa25b0b334cebacd33e1db30d5b1a815a5de2a10c154a0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.