Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 71 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy Tokens | 19229029 | 347 days ago | IN | 0.1 ETH | 0.00307592 | ||||
Buy Tokens | 19205145 | 351 days ago | IN | 0.1 ETH | 0.00248871 | ||||
Buy Tokens | 19200705 | 351 days ago | IN | 0.1 ETH | 0.00281727 | ||||
Buy Tokens | 19199991 | 351 days ago | IN | 0.1 ETH | 0.00329207 | ||||
Buy Tokens | 19178706 | 354 days ago | IN | 0.1 ETH | 0.00968171 | ||||
Buy Tokens | 19176176 | 355 days ago | IN | 0.1 ETH | 0.00301522 | ||||
Buy Tokens | 19169929 | 356 days ago | IN | 0.1 ETH | 0.00395897 | ||||
Buy Tokens | 19143149 | 359 days ago | IN | 0.1 ETH | 0.00197267 | ||||
Buy Tokens | 19142643 | 360 days ago | IN | 0.1 ETH | 0.00201896 | ||||
Buy Tokens | 19137037 | 360 days ago | IN | 0.1 ETH | 0.00229555 | ||||
Buy Tokens | 19123688 | 362 days ago | IN | 0.1 ETH | 0.00191787 | ||||
Buy Tokens | 19121795 | 362 days ago | IN | 0.1 ETH | 0.00236808 | ||||
Buy Tokens | 19114996 | 363 days ago | IN | 0.1 ETH | 0.00191387 | ||||
Buy Tokens | 19109469 | 364 days ago | IN | 0.1 ETH | 0.00111829 | ||||
Enter | 19087867 | 367 days ago | IN | 0.05 ETH | 0.00173836 | ||||
Enter | 19081486 | 368 days ago | IN | 0.05 ETH | 0.0008225 | ||||
Buy Tokens | 19079303 | 368 days ago | IN | 0.1 ETH | 0.00105173 | ||||
Buy Tokens | 19077333 | 369 days ago | IN | 0.1 ETH | 0.0019078 | ||||
Buy Tokens | 19074007 | 369 days ago | IN | 0.1 ETH | 0.00076936 | ||||
Buy Tokens | 19070437 | 370 days ago | IN | 0.1 ETH | 0.00233851 | ||||
Buy Tokens | 19070388 | 370 days ago | IN | 0.1 ETH | 0.00239111 | ||||
Buy Tokens | 19069817 | 370 days ago | IN | 0.1 ETH | 0.00170217 | ||||
Transfer Ownersh... | 19068421 | 370 days ago | IN | 0 ETH | 0.00055128 | ||||
Buy Tokens | 19065527 | 370 days ago | IN | 0.1 ETH | 0.00136169 | ||||
Buy Tokens | 19065418 | 370 days ago | IN | 0.1 ETH | 0.0012054 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19432962 | 319 days ago | 0.2 ETH | ||||
19229029 | 347 days ago | 0.1 ETH | ||||
19205145 | 351 days ago | 0.1 ETH | ||||
19200705 | 351 days ago | 0.1 ETH | ||||
19199991 | 351 days ago | 0.1 ETH | ||||
19178706 | 354 days ago | 0.1 ETH | ||||
19176176 | 355 days ago | 0.1 ETH | ||||
19169929 | 356 days ago | 0.1 ETH | ||||
19143149 | 359 days ago | 0.1 ETH | ||||
19142643 | 360 days ago | 0.1 ETH | ||||
19137037 | 360 days ago | 0.1 ETH | ||||
19123688 | 362 days ago | 0.1 ETH | ||||
19121795 | 362 days ago | 0.1 ETH | ||||
19114996 | 363 days ago | 0.1 ETH | ||||
19109469 | 364 days ago | 0.1 ETH | ||||
19079303 | 368 days ago | 0.1 ETH | ||||
19077333 | 369 days ago | 0.1 ETH | ||||
19074007 | 369 days ago | 0.1 ETH | ||||
19070437 | 370 days ago | 0.1 ETH | ||||
19070388 | 370 days ago | 0.1 ETH | ||||
19069817 | 370 days ago | 0.1 ETH | ||||
19069749 | 370 days ago | 0.05 ETH | ||||
19065527 | 370 days ago | 0.1 ETH | ||||
19065418 | 370 days ago | 0.1 ETH | ||||
19065195 | 370 days ago | 0.1 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Fatboi
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "./ThinChrisChan.sol"; import "./ThinRaffle.sol"; import "./ThinCrowdsale.sol"; contract Fatboi is ThinChrisChan, ThinCrowdsale { uint256 public constant MAX_SUPPLY = 1000000000000 * 1e18; constructor( address payable _multisig, uint64 _subscriptionId, address _vrfCoordinator, bytes32 _keyHash, uint256 _entryPrice, uint16 _requestConfirmations, uint32 _callbackGasLimit, bytes32 _lpRoot, uint256 _entryPriceLP, uint256 _maxTokenAlloc ) ERC20v1("ChrisChan", "CHCH") ThinChrisChan(_subscriptionId, _vrfCoordinator, _keyHash, _entryPrice, _requestConfirmations, _callbackGasLimit, _multisig) ThinCrowdsale(_multisig, _lpRoot, _entryPriceLP, _maxTokenAlloc) { _mint(_multisig, MAX_SUPPLY); } function decimals() public pure override returns (uint8) { return 18; } function _update(address from, address to, uint256 value) internal override(ThinChrisChan, ERC20v1) { ThinChrisChan._update(from, to, value); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; /* * @notice Check to see if there exists a request commitment consumers * for all consumers and keyhashes for a given sub. * @param subId - ID of the subscription * @return true if there exists at least one unfulfilled request for the subscription, false * otherwise. */ function pendingRequestExists(uint64 subId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); address private immutable vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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 (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ 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 v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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 v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @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; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); 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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {OwnableV1} from "./Ownable.sol"; import "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/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}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * 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. */ abstract contract ERC20v1 is Context, IERC20, IERC20Metadata, IERC20Errors, OwnableV1 { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) OwnableV1(msg.sender) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 default value returned by this function, unless * it's 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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 `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` 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 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); 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 `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` 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. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import "@openzeppelin/contracts/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. * * The initial owner is set to the address provided by the deployer. 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 OwnableV1 is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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: UNLICENSED pragma solidity ^0.8.0; import "./ERC20.sol"; import "./ThinRaffle.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; abstract contract ThinChrisChan is ERC20v1, ReentrancyGuard, ThinRaffle { //Whitelisted addresses can buy until certain timestamp uint256 public wlCanBuyUntil; bool public wlCanBuyUntilSet = false; //multisig address private multisig; constructor( uint64 _subscriptionId, address _vrfCoordinator, bytes32 _keyHash, uint256 _entryPrice, uint16 _requestConfirmations, uint32 _callbackGasLimit, address _multisig ) ThinRaffle( _subscriptionId, _vrfCoordinator, _keyHash, _entryPrice, _requestConfirmations, _callbackGasLimit ) {multisig = _multisig;} function burn(uint amount) public { _burn(msg.sender, amount); } function setwlCanBuyUntil(uint256 time) public { require(!wlCanBuyUntilSet, "wlCanBuyUntil already set"); wlCanBuyUntil = time; wlCanBuyUntilSet = true; } function withdrawCHCH() external onlyOwner { _transfer(address(this), msg.sender, balanceOf(address(this))); } function _update( address from, address to, uint256 amount // Overrides the _transfer() function to use an optional transfer condition. ) internal virtual override( ERC20v1 // Specifies only the ERC20 contract for the override. ) nonReentrant // Prevents re-entrancy attacks. { if (block.timestamp > wlCanBuyUntil || msg.sender == multisig ) { super._update(from, to, amount); // Transfers 100% of amount to recipient. } else { require( balanceOf(from) >= amount, "ERC20: transfer amount exceeds balance" ); // Makes sure sender has the required token amount for the total. require( hasWonRaffle[from] == true, "This user doesnt have WL and WL buy window is not passed yet. Check WLtimeover for timestamp." ); super._update(from, to, amount); // Perform transfer } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC20v1} from "./ERC20.sol"; import "./Ownable.sol"; abstract contract ThinCrowdsale is ERC20v1, ReentrancyGuard { mapping(address => uint256) public userBalances; mapping(address => bool) public claimed; mapping(address => bool) public entered; enum WITHDRAWALS { OPEN, CLOSED } WITHDRAWALS public withdrawals_state; bytes32 public immutable lpRoot; uint256 private rate; uint256 public entryPriceLP; uint256 public maxTokenAlloc; uint8 public participants; address payable private multisig; address public token; event TokensPurchased( address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount, bytes data ); constructor( address payable _multisig, bytes32 _lproot, uint _entryPriceLP, uint256 _maxTokenAlloc ) { lpRoot = _lproot; multisig = _multisig; entryPriceLP = _entryPriceLP; maxTokenAlloc = _maxTokenAlloc; token = address(this); withdrawals_state = WITHDRAWALS.CLOSED; } function buyTokens(bytes32[] memory proof) public payable nonReentrant { require( msg.value == entryPriceLP, "Not the right amount of eth!, check entryPriceLP" ); require( entered[msg.sender] != true, "Already has entered, cant allocate any more tokens" ); uint256 weiAmount = msg.value; validateTree(msg.sender, proof); userBalances[msg.sender] += maxTokenAlloc; (bool sent, bytes memory data) = payable(multisig).call{value: msg.value}(""); require(sent, "Failed to send Ether to multisig"); entered[msg.sender] = true; participants++; emit TokensPurchased( _msgSender(), msg.sender, weiAmount, maxTokenAlloc, data ); } function validateTree( address _beneficiary, bytes32[] memory proof ) internal view { bytes32 leaf = keccak256( bytes.concat(keccak256(abi.encode(msg.sender))) ); require(MerkleProof.verify(proof, lpRoot, leaf), "Invalid proof"); require( _beneficiary != address(0), "Crowdsale: beneficiary is the zero address" ); } function _deliverTokens(address beneficiary, uint256 tokenAmount) internal { IERC20(token).transfer(beneficiary, tokenAmount); claimed[msg.sender] = true; } function withdrawTokens() public { require(withdrawals_state == WITHDRAWALS.OPEN, "withdrawals closed"); require(claimed[msg.sender] != true, "already claimed"); uint256 amount = userBalances[msg.sender]; require(amount > 0); userBalances[msg.sender] = 0; _deliverTokens(msg.sender, amount); } function OpenWithdrawals() public onlyOwner { withdrawals_state = WITHDRAWALS.OPEN; } function CloseWithdrawals() public onlyOwner { withdrawals_state = WITHDRAWALS.CLOSED; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol"; import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./Ownable.sol"; abstract contract ThinRaffle is VRFConsumerBaseV2, OwnableV1 { uint256 public seed;//where seed is stored. bool public winnersSelected; //boolean for if SelectWinners() has been ran, can only be ran once so it doesnt overwrite existing WLs. uint256 public entryPrice; //ticket entry price. uint64 public subscriptionId; //subscriptionId for VRF. this is the subscription we will fill with LINK to have it spend from. address public vrfCoordinator; //vrf coordinator. uint16 public ticketsSubmitted; //keep track of how many tickets we have entered. uint8 public maxWinners = 100; //max amount of WLs we can pull in selectwinners. condition in for loop uint16 public maxTickets = 1000; //max amount of tickets allowed mapping(uint16 => bool) indexChoosen; //mapping to keep track of which indexes we have already chosen in selectwinners. mapping(uint16 => address) public tickets; //mapping of tickets, with index as key. mapping(address => bool) public hasEnteredRaffle; //mapping of addresses that have entered the raffle. event WonRaffle(address winner, uint16 ticketIndex); //event for when someone wins the raffle. mapping(address => bool) public hasWonRaffle; //mapping of addresses that have won the raffle. //VRF stuff, storage of needed parameters. uint64 s_subscriptionId; bytes32 keyHash; uint16 requestConfirmations; uint32 callbackGasLimit; uint256[] public requestIds; uint256 public lastRequestId; uint256 public timeStampSinceLastRequest; mapping(uint256 => RequestStatus) public s_requests; /* requestId --> requestStatus */ struct RequestStatus { bool fulfilled; // whether the request has been successfully fulfilled bool exists; // whether a requestId exists uint256[] randomWords; //contains randomNumbers when they are returned from VRF } //events are neat to have for the frontend. event RequestedRandomness(uint256 requestId); event RequestSent(uint256 requestId, uint32 numWords); event RequestFulfilled(uint256 requestId, uint256[] randomWords); event NewEntrance(uint16, address); VRFCoordinatorV2Interface COORDINATOR; //define VRF Coordinator uint8 numWords = 1; //number of numbers we ask VRF for. constructor( uint64 _subscriptionId, address _vrfCoordinator, bytes32 _keyHash, uint256 _entryPrice, uint16 _requestConfirmations, uint32 _callbackGasLimit ) VRFConsumerBaseV2(_vrfCoordinator) { COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator); subscriptionId = _subscriptionId; s_subscriptionId = _subscriptionId; vrfCoordinator = _vrfCoordinator; keyHash = _keyHash; entryPrice = _entryPrice; requestConfirmations = _requestConfirmations; callbackGasLimit = _callbackGasLimit; } function selectWinners() public onlyOwner { require(!winnersSelected, "winners already selected"); require(ticketsSubmitted == maxTickets, "not there yet"); require(seed != 0, "seed is missing, use getseed()"); uint256 j = 0; for (uint256 i = 0; i < maxWinners; i++) { uint16 randomIndex = getRandom(i, j); if (!indexChoosen[randomIndex]) { address winner = tickets[randomIndex]; indexChoosen[randomIndex] = true; hasWonRaffle[winner] = true; } else { j++; i--; } } winnersSelected = true; } function getRandom(uint i, uint j) private view returns (uint16) { return uint16(uint256(keccak256(abi.encodePacked(seed, blockhash(block.number - 1), i, j))) % ticketsSubmitted); } function enter() public payable { require(!hasEnteredRaffle[msg.sender], "Seems to already be entered, try a different wallet. 1 ticket per address"); require(msg.value == entryPrice, "Not the correct amount of ETH!, check entryPrice"); require(ticketsSubmitted < maxTickets, "Raffle is already full, sorry"); //set tickets with sender´s address. //put it inside a ticket, then inside tickets array mapping. tickets[ticketsSubmitted] = msg.sender; hasEnteredRaffle[msg.sender] = true; ticketsSubmitted++; emit NewEntrance(ticketsSubmitted, msg.sender); } function setEntranceFee( uint256 newCostToEnter ) public onlyOwner returns (uint256) { entryPrice = newCostToEnter; return entryPrice; } function getSeed() public onlyOwner { require(seed == 0, "Seed exists, so cant get a new one"); (uint96 balance, , ,) = COORDINATOR.getSubscription(subscriptionId); require( balance >= 0, "Need enough LINK in VRF Subscription to request random numbers upon raffle end!" ); uint256 requestId = requestRandomWords(); emit RequestedRandomness(requestId); } // Assumes the subscription is funded sufficiently. function requestRandomWords() internal onlyOwner returns (uint256 requestId) { // Will revert if subscription is not set and funded. requestId = COORDINATOR.requestRandomWords( keyHash, s_subscriptionId, requestConfirmations, callbackGasLimit, numWords ); s_requests[requestId] = RequestStatus({ randomWords: new uint256[](0), exists: true, fulfilled: false }); requestIds.push(requestId); lastRequestId = requestId; timeStampSinceLastRequest = block.timestamp; emit RequestSent(requestId, numWords); return requestId; } function fulfillRandomWords( uint256 _requestId, uint256[] memory _randomWords ) internal override { require(s_requests[_requestId].exists, "request not found"); s_requests[_requestId].fulfilled = true; s_requests[_requestId].randomWords = _randomWords; seed = _randomWords[0]; emit RequestFulfilled(_requestId, _randomWords); } function getRequestStatus( uint256 _requestId ) public view returns (bool fulfilled, uint256[] memory randomWords) { require(s_requests[_requestId].exists, "request not found"); RequestStatus memory request = s_requests[_requestId]; return (request.fulfilled, request.randomWords); } function withdrawETH(uint256 amount) external onlyOwner { require(amount > 0, "Withdrawal amount must be greater than 0"); require(address(this).balance >= amount, "Insufficient balance in the contract"); payable(owner()).transfer(amount); } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "viaIR": true, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address payable","name":"_multisig","type":"address"},{"internalType":"uint64","name":"_subscriptionId","type":"uint64"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint256","name":"_entryPrice","type":"uint256"},{"internalType":"uint16","name":"_requestConfirmations","type":"uint16"},{"internalType":"uint32","name":"_callbackGasLimit","type":"uint32"},{"internalType":"bytes32","name":"_lpRoot","type":"bytes32"},{"internalType":"uint256","name":"_entryPriceLP","type":"uint256"},{"internalType":"uint256","name":"_maxTokenAlloc","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"","type":"uint16"},{"indexed":false,"internalType":"address","name":"","type":"address"}],"name":"NewEntrance","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":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"RequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"numWords","type":"uint32"}],"name":"RequestSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"RequestedRandomness","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"purchaser","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TokensPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint16","name":"ticketIndex","type":"uint16"}],"name":"WonRaffle","type":"event"},{"inputs":[],"name":"CloseWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OpenWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"buyTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"enter","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"entered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entryPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entryPriceLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"getRequestStatus","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasEnteredRaffle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasWonRaffle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTickets","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenAlloc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWinners","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"participants","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"s_requests","outputs":[{"internalType":"bool","name":"fulfilled","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"seed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"selectWinners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCostToEnter","type":"uint256"}],"name":"setEntranceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setwlCanBuyUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"tickets","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketsSubmitted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeStampSinceLastRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"winnersSelected","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawCHCH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawals_state","outputs":[{"internalType":"enum ThinCrowdsale.WITHDRAWALS","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlCanBuyUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlCanBuyUntilSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c034620007ae57601f6200313d38819003918201601f19168301916001600160401b03831184841017620006655780849261014094604052833981010312620007ae578051906001600160a01b0382168203620007ae576020810151906001600160401b0382168203620007ae576040810151906001600160a01b0382168203620007ae57606081015192608082015160a08301519061ffff82168203620007ae5760c08401519063ffffffff82168203620007ae5760e08501519661012061010087015196015196620000d3620007b3565b600981526821b43934b9a1b430b760b91b6020820152620000f3620007b3565b9060048252630869086960e31b6020830152826080523315620007955760008054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a38051906001600160401b038211620006655760045490600182811c921680156200078a575b6020831014620006445781601f84931162000716575b50602090601f831160011462000687576000926200067b575b50508160011b916000199060031b1c1916176004555b8051906001600160401b038211620006655760055490600182811c921680156200065a575b6020831014620006445781601f849311620005ee575b50602090601f83116001146200055f5760009262000553575b50508160011b916000199060031b1c1916176005555b600a8054600b805461ffff19166103e8179055601780546001600160a81b03199081166001600160a01b0386811691909117600160a01b17909255601080546001600160401b0319166001600160401b03909b169a8b1781557fff00ffff0000000000000000000000000000000000000000000000000000000090931690991760409490941b600160401b600160e01b031693909317601960f21b179091556011929092556009929092556012805465ffffffffffff191661ffff959095169490941792901b65ffffffff0000169190911790915560198054909216600887901b610100600160a81b03169081179283905560a09590955260218054610100600160a81b031916909517909455601f91909155602091909155602280546001600160a01b03191630179055601d805460ff19166001179055908216156200053a576002600655601854421190811562000520575b5015620003c65762000398906001600160a01b0316620007d3565b60016006556040516128c190816200087c823960805181611c08015260a051818181610ae201526120750152f35b6000805260016020527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49546c0c9f2c9cd04674edea4000000011620004cc5760008052600f602052600160ff604060002054161515036200043b5762000435906001600160a01b0316620007d3565b62000398565b60405162461bcd60e51b815260206004820152605d60248201527f54686973207573657220646f65736e74206861766520574c20616e6420574c2060448201527f6275792077696e646f77206973206e6f7420706173736564207965742e20436860648201527f65636b20574c74696d656f76657220666f722074696d657374616d702e000000608482015260a490fd5b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b3360089190911c6001600160a01b0316149050386200037d565b60405163ec442f0560e01b815260006004820152602490fd5b01519050388062000213565b6005600090815293507f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db091905b601f1984168510620005d2576001945083601f19811610620005b8575b505050811b0160055562000229565b015160001960f88460031b161c19169055388080620005a9565b818101518355602094850194600190930192909101906200058c565b90915060056000526020600020601f840160051c8101602085106200063c575b90849392915b601f830160051c820181106200062c575050620001fa565b6000815585945060010162000614565b50806200060e565b634e487b7160e01b600052602260045260246000fd5b91607f1691620001e4565b634e487b7160e01b600052604160045260246000fd5b015190503880620001a9565b6004600090815293507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b91905b601f1984168510620006fa576001945083601f19811610620006e0575b505050811b01600455620001bf565b015160001960f88460031b161c19169055388080620006d1565b81810151835560209485019460019093019290910190620006b4565b60046000529091507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b6005601f8501811c82016020861062000782575b9085949392915b601f8401821c83018110620007725750505062000190565b600081558695506001016200075a565b508162000753565b91607f16916200017a565b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b60408051919082016001600160401b038111838210176200066557604052565b6003546c0c9f2c9cd04674edea400000009182820180921162000865576003919091556001600160a01b0316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090846200084e576c0c9f2c9cd04674edea3fffffff19600354016003555b604051908152a3565b848452600182526040842081815401905562000845565b634e487b7160e01b600052601160045260246000fdfe60806040818152600480361015610021575b505050361561001f57600080fd5b005b60009260e08435811c91826306fdde031461216a57508163095ea7b3146120c257816309c1ba2e146120985781630f8336f31461205c57816317b299aa1461201f57816318160ddd14611fff5781631a0de74c14611d9a5781631ea4b92814611d7b5781631fe543e314611b8157816323b872dd14611a7557816326224c6414611a3d5781632916983214611a1d578163313ce56714611a0057816332cb6b0c146119d7578163339b0735146119b757816339e7357c146115945781633f936e071461157457816342966c68146113e25781634c87d5f6146113bd5781636c4470fb1461139a57816370a0823114611362578163715018a6146112fc5781637d94792a146112dc5781638796ba8c146112a35781638bc532851461127e5781638d8f2adb146110ea5781638da5cb5b146110c357816395d89b4114610fab5781639b89470314610f87578163a168fa8914610f4e578163a337916314610f0e578163a3e56fa814610ee4578163a9059cbb14610eb2578163aafcc04814610e3e578163ab98089f14610a01578163ad8b280d146109c4578163b2c84bca14610990578163bd9766f414610953578163bffc945614610916578163c884ef83146108d9578163cde8e5d3146108b3578163d8a4676f146107f1578163dd62ed3e146107a7578163de9c5cd514610782578163e97dcb621461052957508063f10fdc9014610500578063f14210a6146103df578063f2fde38b14610333578063f745adfc14610314578063f8ad0449146102eb578063fc0c546a146102c3578063fc2a88c3146102a05763fe56f5a003610011573461029c57602036600319011261029c5760209250359061029261259a565b8160095551908152f35b8280fd5b5050346102bf57816003193601126102bf576020906014549051908152f35b5080fd5b5050346102bf57816003193601126102bf576020906001600160a01b03602254169051908152f35b833461031157806003193601126103115761030461259a565b60ff19601d5416601d5580f35b80fd5b5050346102bf57816003193601126102bf576020906009549051908152f35b503461029c57602036600319011261029c5761034d61229e565b9061035661259a565b6001600160a01b038092169283156103b057505082548273ffffffffffffffffffffffffffffffffffffffff198216178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b908460249251917f1e4fbdf7000000000000000000000000000000000000000000000000000000008352820152fd5b503461029c57602036600319011261029c578035906103fc61259a565b81156104975781471061042f575082808080936001600160a01b0382541682f115610425575080f35b51903d90823e3d90fd5b608490602084519162461bcd60e51b83528201526024808201527f496e73756666696369656e742062616c616e636520696e2074686520636f6e7460448201527f72616374000000000000000000000000000000000000000000000000000000006064820152fd5b608490602084519162461bcd60e51b8352820152602860248201527f5769746864726177616c20616d6f756e74206d7573742062652067726561746560448201527f72207468616e20300000000000000000000000000000000000000000000000006064820152fd5b833461031157806003193601126103115761051961259a565b600160ff19601d541617601d5580f35b848484928260031936011261029c573383526020600e815260ff83852054166106f457600954340361068c5761ffff80600a54841c1681600b541681101561064a578552600d82528385203373ffffffffffffffffffffffffffffffffffffffff19825416179055338552600e8252838520600160ff19825416179055600a548181851c16828114610637577fa3931daace9c6100d481842ddf7c64d8bb426c52fbb579c2055bdaf8cdbd7fb59697507dffff0000000000000000000000000000000000000000000000000000000060017fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9201861b1691161780600a558451931c1682523390820152a180f35b60248760118a634e487b7160e01b835252fd5b6064878487519162461bcd60e51b8352820152601d60248201527f526166666c6520697320616c72656164792066756c6c2c20736f7272790000006044820152fd5b8460849184519162461bcd60e51b8352820152603060248201527f4e6f742074686520636f727265637420616d6f756e74206f6620455448212c2060448201527f636865636b20656e7472795072696365000000000000000000000000000000006064820152fd5b8460a49184519162461bcd60e51b8352820152604960248201527f5365656d7320746f20616c726561647920626520656e74657265642c2074727960448201527f206120646966666572656e742077616c6c65742e2031207469636b657420706560648201527f72206164647265737300000000000000000000000000000000000000000000006084820152fd5b505050346102bf57816003193601126102bf5760209060ff6019541690519015158152f35b505050346102bf57806003193601126102bf57806020926107c661229e565b6107ce6122b9565b6001600160a01b0391821683526002865283832091168252845220549051908152f35b5050913461031157602092836003193601126102bf57358082526016845261082160ff8484205460081c16612840565b81526016835281812090825190610837826122cf565b60ff83548181161515845260081c16151585830152600180930190845193848784549182815201938352878320925b888282106108a0578861089c8989610880828b038361231d565b81848201525115159280805195869586528501528301906123a4565b0390f35b8454865290940193928201928201610866565b505050346102bf57816003193601126102bf5760209060ff600a5460f01c169051908152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361090361229e565b168152601b855220541690519015158152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361094061229e565b168152600e855220541690519015158152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361097d61229e565b168152600f855220541690519015158152f35b505050346102bf57816003193601126102bf576109c1906109af61259a565b308352600160205282205433306123d8565b80f35b50503461029c57602036600319011261029c573561ffff811680910361029c5781836001600160a01b039260209552600d85522054169051908152f35b50509060209081600319360112610e3a5767ffffffffffffffff908335828111610e365736602382011215610e36578085013594610a3e8661233f565b95610a4b8451978861231d565b8087528587019260249384600593841b83010191368311610e325785899101915b838310610e225750505050610a7f6125de565b601f543403610dbb57338852601c86526001968760ff868b205416151514610d54578790818651898101903382528a8152610ab981612301565b51902087518a81019182528a8152610ad081612301565b519020938b935b610d03575b505050507f000000000000000000000000000000000000000000000000000000000000000003610cc3573315610c5d578454338852601a8652610b23848920918254612619565b905586808080346001600160a01b0360215460081c165af13d15610c54573d948511610c4257835194610b5f601f8201601f191688018761231d565b85523d888787013e5b15610c0357338752601c85528287209060ff199187838254161790556021549260ff84169160ff8314610bf25750509060ff876060959493011691161760215583548151943486528501528301527fbf06671c7d1d4ba67c1030bfdc6f8355fb1b0490b8dc59dc4e1b3fb7802f9b4b339280610be93394606083019061225e565b0390a360065580f35b60118a91634e487b7160e01b835252fd5b846064928185519362461bcd60e51b85528401528201527f4661696c656420746f2073656e6420457468657220746f206d756c74697369676044820152fd5b5060418791634e487b7160e01b835252fd5b60609450610b68565b602a6084928685519362461bcd60e51b85528401528201527f43726f776473616c653a2062656e656669636961727920697320746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152fd5b600d6064928685519362461bcd60e51b85528401528201527f496e76616c69642070726f6f66000000000000000000000000000000000000006044820152fd5b909192938351851015610d4b5784821b84018a01519081811015610d3b578c528952610d32878c205b9461281d565b92919081610ad7565b908c528952610d32878c20610d2c565b93829150610adc565b6084836032868a89519362461bcd60e51b85528401528201527f416c72656164792068617320656e74657265642c2063616e7420616c6c6f636160448201527f746520616e79206d6f726520746f6b656e7300000000000000000000000000006064820152fd5b5060306084928685519362461bcd60e51b85528401528201527f4e6f742074686520726967687420616d6f756e74206f6620657468212c20636860448201527f65636b20656e74727950726963654c50000000000000000000000000000000006064820152fd5b8235815291810191899101610a6c565b8a80fd5b8580fd5b8380fd5b838584346102bf5760203660031901126102bf576019549060ff8216610e6f573560185560ff191660011760195580f35b606490602085519162461bcd60e51b8352820152601960248201527f776c43616e427579556e74696c20616c726561647920736574000000000000006044820152fd5b505050346102bf57806003193601126102bf57602090610edd610ed361229e565b60243590336123d8565b5160018152f35b505050346102bf57816003193601126102bf57600a548151911c6001600160a01b03168152602090f35b828585346102bf57816003193601126102bf5760ff601d54169051916002821015610f3b57602083838152f35b80602185634e487b7160e01b6024945252fd5b50503461029c57602036600319011261029c579181923581526016602052205460ff8251918181161515835260081c1615156020820152f35b505050346102bf57816003193601126102bf5760209061ffff600b54169051908152f35b505091346103115780600319360112610311578151918160055492600184811c918186169586156110b9575b60209687851081146110a6578899509688969785829a52918260001461107f575050600114611023575b50505061089c929161101491038561231d565b5192828493845283019061225e565b9190869350600583527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b828410611067575050508201018161101461089c611001565b8054848a01860152889550879490930192810161104e565b60ff19168782015293151560051b86019093019350849250611014915061089c9050611001565b60248360228c634e487b7160e01b835252fd5b92607f1692610fd7565b505050346102bf57816003193601126102bf576001600160a01b0360209254169051908152f35b50503461029c578260031936011261029c5760ff601d5416600281101561126b5761122957338352602090601b8252600160ff84862054161515146111e857338452601a825282842080548581156103115784925560446001600160a01b03602254169387875195869485937fa9059cbb000000000000000000000000000000000000000000000000000000008552339085015260248401525af180156111db576111a8575b50338352601b90528120805460ff1916600117905580f35b8181813d83116111d4575b6111bd818361231d565b81010312610e3a57518015150361029c5738611190565b503d6111b3565b50505051903d90823e3d90fd5b90606492519162461bcd60e51b8352820152600f60248201527f616c726561647920636c61696d656400000000000000000000000000000000006044820152fd5b6020606492519162461bcd60e51b8352820152601260248201527f7769746864726177616c7320636c6f73656400000000000000000000000000006044820152fd5b602484602184634e487b7160e01b835252fd5b505050346102bf57816003193601126102bf5760209060ff6008541690519015158152f35b50503461029c57602036600319011261029c57359160135483101561031157506112ce602092612357565b91905490519160031b1c8152f35b505050346102bf57816003193601126102bf576020906007549051908152f35b843461031157806003193601126103115761131561259a565b806001600160a01b03815473ffffffffffffffffffffffffffffffffffffffff1981168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b505050346102bf5760203660031901126102bf57806020926001600160a01b0361138a61229e565b1681526001845220549051908152f35b505050346102bf57816003193601126102bf5760209060ff602154169051908152f35b83853461031157806003193601126103115750600a549051911c61ffff168152602090f35b50503461029c57602036600319011261029c57803591331561155e576114066125de565b60185442118015611547575b1561142b575050611423903361263c565b600160065580f35b33845260016020528281852054106114f557338452600f602052600160ff8286205416151503611466575050611461903361263c565b611423565b90602060a492519162461bcd60e51b8352820152605d60248201527f54686973207573657220646f65736e74206861766520574c20616e6420574c2060448201527f6275792077696e646f77206973206e6f7420706173736564207965742e20436860648201527f65636b20574c74696d656f76657220666f722074696d657374616d702e0000006084820152fd5b906020608492519162461bcd60e51b8352820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152fd5b506001600160a01b0360195460081c163314611412565b90836024925191634b637e8f60e11b8352820152fd5b505050346102bf57816003193601126102bf576020906018549051908152f35b505082346103115780600319360112610311576115af61259a565b60075461194e57601754600a5484517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821685820152949060246001600160a01b03841685888381845afa80156119445761187d575b8596975061161d61259a565b60ff6011549563ffffffff8560105416601254908851997f5d3b1d30000000000000000000000000000000000000000000000000000000008b528d8b0152868a015261ffff811660448a015260101c16606488015260a01c1660848601528460a48160209889945af1938415611873578694611844575b5082519685880188811084821117610c425784528688528351926116b7846122cf565b87845286840160019481868093528782019b8c52888b5260168a52878b20915115159060ff61ff0084549251151560081b1692169061ffff1916171781550198519889519182116118325768010000000000000000998a831161182057889082548484558085106117f6575b5001908952878920858a5b8481106117e4575050505050601354978810156117d357505085611778917f5d7d0431c4991fcc9f63f03ad0ead4128b866a8ed115a818b6d87a3afedb7264969701601355612357565b81549060031b9084821b91600019901b191617905581601455426015557fcc58b13ad3eab50626c6a6300b1d139cd6ebb1688a7cced9461c2f7e762665ee8160ff60175460a01c1681519085825286820152a151908152a180f35b60418791634e487b7160e01b835252fd5b8a84519401938184015501869061172e565b8785848e8781522092830192015b828110611812575050611723565b8d81558c9450899101611804565b848a604186634e487b7160e01b835252fd5b8389604185634e487b7160e01b835252fd5b9093508481813d831161186c575b61185c818361231d565b81010312610e3657519287611694565b503d611852565b83513d88823e3d90fd5b3d80878a3e61188c818a61231d565b88016080898203126119405788516bffffffffffffffffffffffff81160361194057602098898101518581160361193c576118c886820161282c565b50606081015190858211611938570181601f8201121561193c578051908a806118f08461233f565b6118fc8a51918261231d565b848152019260051b820101928311611938578a01905b82821061192157505050611611565b8a809161192d8461282c565b815201910190611912565b8880fd5b8780fd5b8680fd5b84513d88823e3d90fd5b506020608492519162461bcd60e51b8352820152602260248201527f53656564206578697374732c20736f2063616e74206765742061206e6577206f60448201527f6e650000000000000000000000000000000000000000000000000000000000006064820152fd5b505050346102bf57816003193601126102bf57602090601f549051908152f35b505050346102bf57816003193601126102bf57602090516c0c9f2c9cd04674edea400000008152f35b505050346102bf57816003193601126102bf576020905160128152f35b505050346102bf57816003193601126102bf576020906015549051908152f35b505050346102bf5760203660031901126102bf57806020926001600160a01b03611a6561229e565b168152601a845220549051908152f35b5050823461031157606036600319011261031157611a9161229e565b611a996122b9565b91604435936001600160a01b038316808352600260205286832033845260205286832054916000198303611ad6575b602088610edd8989896123d8565b868310611b3c578115611b26573315611b1057508252600260209081528683203384528152918690209085900390558290610edd87611ac8565b60249084895191634a1406b160e11b8352820152fd5b6024908489519163e602df0560e01b8352820152fd5b87517ffb8f41b2000000000000000000000000000000000000000000000000000000008152339181019182526020820193909352604081018790528291506060010390fd5b838584346102bf57826003193601126102bf57803560249384359267ffffffffffffffff95868511610e365736602386011215610e36578482013591611bc68361233f565b97611bd38551998a61231d565b838952602096878a0184819660051b83010191368311610e3257858a9101915b838310611d6b57505050506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803303611d36575085885260168752611c4960ff868a205460081c16612840565b8588526016875284882090600180928160ff19825416178155018a5191821161182057680100000000000000008211611820578054828255808310611d0f575b5085908a52888a208a5b838110611cfe575050505050875115611ced57505094611ce7917ffe2e2d779dba245964d4e3ef9b994be63856fd568bf7d3ca9e224755cb1bd54d95965160075580805195869586528501528301906123a4565b0390a180f35b60328791634e487b7160e01b835252fd5b825182820155918a01918401611c93565b818b5283838b8d2092830192015b828110611d2b575050611c89565b8c8155018490611d1d565b90506044928551927f1cf993f40000000000000000000000000000000000000000000000000000000084523390840152820152fd5b82358152918101918a9101611bf3565b505050346102bf57816003193601126102bf5760209081549051908152f35b849150833461029c578260031936011261029c57611db661259a565b60ff908160085416611fbd5761ffff93600a93858554821c1686600b541603611f7a576007805415611f375782969596958392600019928343014381119040995b8b548a8160f01c16821015611f2657835483611f1357908c918b516020938482019283528d82015284606082015260808b81830152815260a0810181811067ffffffffffffffff821117611efd578d5251902090861c8716908115611ee957068616808a52600c8083528b8b20549091908d16611eb75790611eb29392918b52600d82526001600160a01b038c8c205416908252600f8c8c209260019260ff199484868254161790558d52528b8b209182541617905561281d565b611df7565b50505095611ec49061281d565b958015611ed65785611eb2910161281d565b60248860118f634e487b7160e01b835252fd5b8f8b6012602492634e487b7160e01b835252fd5b50508f8b6041602492634e487b7160e01b835252fd5b634e487b7160e01b8a5260118f5260248afd5b88600160ff19600854161760085580f35b606488602086519162461bcd60e51b8352820152601e60248201527f73656564206973206d697373696e672c207573652067657473656564282900006044820152fd5b606487602085519162461bcd60e51b8352820152600d60248201527f6e6f7420746865726520796574000000000000000000000000000000000000006044820152fd5b5162461bcd60e51b8152602081860152601860248201527f77696e6e65727320616c72656164792073656c656374656400000000000000006044820152606490fd5b505050346102bf57816003193601126102bf576020906003549051908152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361204961229e565b168152601c855220541690519015158152f35b505050346102bf57816003193601126102bf57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b505050346102bf57816003193601126102bf5760209067ffffffffffffffff600a54169051908152f35b50503461029c578160031936011261029c576120dc61229e565b602435903315612154576001600160a01b031691821561213e57508083602095338152600287528181208582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b60249085855191634a1406b160e11b8352820152fd5b6024838686519163e602df0560e01b8352820152fd5b83908686346102bf57816003193601126102bf5781845492600184811c91818616958615612254575b60209687851081146110a6579087899a92868b999a9b52918260001461222a5750506001146121cf575b858861089c89611014848a038561231d565b815286935091907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410612212575050508201018161101461089c886121bd565b8054848a0186015288955087949093019281016121f8565b60ff19168882015294151560051b87019094019450859350611014925061089c91508990506121bd565b92607f1692612193565b919082519283825260005b84811061228a575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201612269565b600435906001600160a01b03821682036122b457565b600080fd5b602435906001600160a01b03821682036122b457565b6060810190811067ffffffffffffffff8211176122eb57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176122eb57604052565b90601f8019910116810190811067ffffffffffffffff8211176122eb57604052565b67ffffffffffffffff81116122eb5760051b60200190565b60135481101561238e5760136000527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900190600090565b634e487b7160e01b600052603260045260246000fd5b90815180825260208080930193019160005b8281106123c4575050505090565b8351855293810193928101926001016123b6565b91906001600160a01b038084169081156125825780831615612551576123fc6125de565b6018544211908115612540575b501561242057506124199261271e565b6001600655565b80600052600160205282604060002054106124ed57600052600f602052600160ff6040600020541615150361245d576124589261271e565b612419565b60a460405162461bcd60e51b815260206004820152605d60248201527f54686973207573657220646f65736e74206861766520574c20616e6420574c2060448201527f6275792077696e646f77206973206e6f7420706173736564207965742e20436860648201527f65636b20574c74696d656f76657220666f722074696d657374616d702e0000006084820152fd5b608460405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152fd5b905060195460081c16331438612409565b60246040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152fd5b6024604051634b637e8f60e11b815260006004820152fd5b6001600160a01b036000541633036125ae57565b60246040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152fd5b6002600654146125ef576002600655565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b9190820180921161262657565b634e487b7160e01b600052601160045260246000fd5b9091906001600160a01b038116908161269857507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60208461268360009596600354612619565b6003555b8060035403600355604051908152a3565b92816000526001602052604060002054938185106126ec57506020817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926000959685875260018452036040862055612687565b60405163391434e360e21b81526001600160a01b03919091166004820152602481018590526044810191909152606490fd5b6001600160a01b038082169290918361279857507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160209161276386600354612619565b6003555b1693846127805780600354036003555b604051908152a3565b84600052600182526040600020818154019055612777565b836000526001602052604060002054908582106127eb575091602091857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef94866000526001855203604060002055612767565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101859052606490fd5b60001981146126265760010190565b51906001600160a01b03821682036122b457565b1561284757565b606460405162461bcd60e51b815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152fdfea2646970667358221220a5fdd10e1230904c88024d740d08a4f031f3b9cff17d23ce0c083c5081b9ae4a64736f6c634300081400330000000000000000000000006d2d146fa21e574e8b4789a88488617c1b44f28b000000000000000000000000000000000000000000000000000000000000038d000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699098af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a12028e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c119000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000019d971e4fe8401e74000000
Deployed Bytecode
0x60806040818152600480361015610021575b505050361561001f57600080fd5b005b60009260e08435811c91826306fdde031461216a57508163095ea7b3146120c257816309c1ba2e146120985781630f8336f31461205c57816317b299aa1461201f57816318160ddd14611fff5781631a0de74c14611d9a5781631ea4b92814611d7b5781631fe543e314611b8157816323b872dd14611a7557816326224c6414611a3d5781632916983214611a1d578163313ce56714611a0057816332cb6b0c146119d7578163339b0735146119b757816339e7357c146115945781633f936e071461157457816342966c68146113e25781634c87d5f6146113bd5781636c4470fb1461139a57816370a0823114611362578163715018a6146112fc5781637d94792a146112dc5781638796ba8c146112a35781638bc532851461127e5781638d8f2adb146110ea5781638da5cb5b146110c357816395d89b4114610fab5781639b89470314610f87578163a168fa8914610f4e578163a337916314610f0e578163a3e56fa814610ee4578163a9059cbb14610eb2578163aafcc04814610e3e578163ab98089f14610a01578163ad8b280d146109c4578163b2c84bca14610990578163bd9766f414610953578163bffc945614610916578163c884ef83146108d9578163cde8e5d3146108b3578163d8a4676f146107f1578163dd62ed3e146107a7578163de9c5cd514610782578163e97dcb621461052957508063f10fdc9014610500578063f14210a6146103df578063f2fde38b14610333578063f745adfc14610314578063f8ad0449146102eb578063fc0c546a146102c3578063fc2a88c3146102a05763fe56f5a003610011573461029c57602036600319011261029c5760209250359061029261259a565b8160095551908152f35b8280fd5b5050346102bf57816003193601126102bf576020906014549051908152f35b5080fd5b5050346102bf57816003193601126102bf576020906001600160a01b03602254169051908152f35b833461031157806003193601126103115761030461259a565b60ff19601d5416601d5580f35b80fd5b5050346102bf57816003193601126102bf576020906009549051908152f35b503461029c57602036600319011261029c5761034d61229e565b9061035661259a565b6001600160a01b038092169283156103b057505082548273ffffffffffffffffffffffffffffffffffffffff198216178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b908460249251917f1e4fbdf7000000000000000000000000000000000000000000000000000000008352820152fd5b503461029c57602036600319011261029c578035906103fc61259a565b81156104975781471061042f575082808080936001600160a01b0382541682f115610425575080f35b51903d90823e3d90fd5b608490602084519162461bcd60e51b83528201526024808201527f496e73756666696369656e742062616c616e636520696e2074686520636f6e7460448201527f72616374000000000000000000000000000000000000000000000000000000006064820152fd5b608490602084519162461bcd60e51b8352820152602860248201527f5769746864726177616c20616d6f756e74206d7573742062652067726561746560448201527f72207468616e20300000000000000000000000000000000000000000000000006064820152fd5b833461031157806003193601126103115761051961259a565b600160ff19601d541617601d5580f35b848484928260031936011261029c573383526020600e815260ff83852054166106f457600954340361068c5761ffff80600a54841c1681600b541681101561064a578552600d82528385203373ffffffffffffffffffffffffffffffffffffffff19825416179055338552600e8252838520600160ff19825416179055600a548181851c16828114610637577fa3931daace9c6100d481842ddf7c64d8bb426c52fbb579c2055bdaf8cdbd7fb59697507dffff0000000000000000000000000000000000000000000000000000000060017fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9201861b1691161780600a558451931c1682523390820152a180f35b60248760118a634e487b7160e01b835252fd5b6064878487519162461bcd60e51b8352820152601d60248201527f526166666c6520697320616c72656164792066756c6c2c20736f7272790000006044820152fd5b8460849184519162461bcd60e51b8352820152603060248201527f4e6f742074686520636f727265637420616d6f756e74206f6620455448212c2060448201527f636865636b20656e7472795072696365000000000000000000000000000000006064820152fd5b8460a49184519162461bcd60e51b8352820152604960248201527f5365656d7320746f20616c726561647920626520656e74657265642c2074727960448201527f206120646966666572656e742077616c6c65742e2031207469636b657420706560648201527f72206164647265737300000000000000000000000000000000000000000000006084820152fd5b505050346102bf57816003193601126102bf5760209060ff6019541690519015158152f35b505050346102bf57806003193601126102bf57806020926107c661229e565b6107ce6122b9565b6001600160a01b0391821683526002865283832091168252845220549051908152f35b5050913461031157602092836003193601126102bf57358082526016845261082160ff8484205460081c16612840565b81526016835281812090825190610837826122cf565b60ff83548181161515845260081c16151585830152600180930190845193848784549182815201938352878320925b888282106108a0578861089c8989610880828b038361231d565b81848201525115159280805195869586528501528301906123a4565b0390f35b8454865290940193928201928201610866565b505050346102bf57816003193601126102bf5760209060ff600a5460f01c169051908152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361090361229e565b168152601b855220541690519015158152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361094061229e565b168152600e855220541690519015158152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361097d61229e565b168152600f855220541690519015158152f35b505050346102bf57816003193601126102bf576109c1906109af61259a565b308352600160205282205433306123d8565b80f35b50503461029c57602036600319011261029c573561ffff811680910361029c5781836001600160a01b039260209552600d85522054169051908152f35b50509060209081600319360112610e3a5767ffffffffffffffff908335828111610e365736602382011215610e36578085013594610a3e8661233f565b95610a4b8451978861231d565b8087528587019260249384600593841b83010191368311610e325785899101915b838310610e225750505050610a7f6125de565b601f543403610dbb57338852601c86526001968760ff868b205416151514610d54578790818651898101903382528a8152610ab981612301565b51902087518a81019182528a8152610ad081612301565b519020938b935b610d03575b505050507f28e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c11903610cc3573315610c5d578454338852601a8652610b23848920918254612619565b905586808080346001600160a01b0360215460081c165af13d15610c54573d948511610c4257835194610b5f601f8201601f191688018761231d565b85523d888787013e5b15610c0357338752601c85528287209060ff199187838254161790556021549260ff84169160ff8314610bf25750509060ff876060959493011691161760215583548151943486528501528301527fbf06671c7d1d4ba67c1030bfdc6f8355fb1b0490b8dc59dc4e1b3fb7802f9b4b339280610be93394606083019061225e565b0390a360065580f35b60118a91634e487b7160e01b835252fd5b846064928185519362461bcd60e51b85528401528201527f4661696c656420746f2073656e6420457468657220746f206d756c74697369676044820152fd5b5060418791634e487b7160e01b835252fd5b60609450610b68565b602a6084928685519362461bcd60e51b85528401528201527f43726f776473616c653a2062656e656669636961727920697320746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152fd5b600d6064928685519362461bcd60e51b85528401528201527f496e76616c69642070726f6f66000000000000000000000000000000000000006044820152fd5b909192938351851015610d4b5784821b84018a01519081811015610d3b578c528952610d32878c205b9461281d565b92919081610ad7565b908c528952610d32878c20610d2c565b93829150610adc565b6084836032868a89519362461bcd60e51b85528401528201527f416c72656164792068617320656e74657265642c2063616e7420616c6c6f636160448201527f746520616e79206d6f726520746f6b656e7300000000000000000000000000006064820152fd5b5060306084928685519362461bcd60e51b85528401528201527f4e6f742074686520726967687420616d6f756e74206f6620657468212c20636860448201527f65636b20656e74727950726963654c50000000000000000000000000000000006064820152fd5b8235815291810191899101610a6c565b8a80fd5b8580fd5b8380fd5b838584346102bf5760203660031901126102bf576019549060ff8216610e6f573560185560ff191660011760195580f35b606490602085519162461bcd60e51b8352820152601960248201527f776c43616e427579556e74696c20616c726561647920736574000000000000006044820152fd5b505050346102bf57806003193601126102bf57602090610edd610ed361229e565b60243590336123d8565b5160018152f35b505050346102bf57816003193601126102bf57600a548151911c6001600160a01b03168152602090f35b828585346102bf57816003193601126102bf5760ff601d54169051916002821015610f3b57602083838152f35b80602185634e487b7160e01b6024945252fd5b50503461029c57602036600319011261029c579181923581526016602052205460ff8251918181161515835260081c1615156020820152f35b505050346102bf57816003193601126102bf5760209061ffff600b54169051908152f35b505091346103115780600319360112610311578151918160055492600184811c918186169586156110b9575b60209687851081146110a6578899509688969785829a52918260001461107f575050600114611023575b50505061089c929161101491038561231d565b5192828493845283019061225e565b9190869350600583527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b828410611067575050508201018161101461089c611001565b8054848a01860152889550879490930192810161104e565b60ff19168782015293151560051b86019093019350849250611014915061089c9050611001565b60248360228c634e487b7160e01b835252fd5b92607f1692610fd7565b505050346102bf57816003193601126102bf576001600160a01b0360209254169051908152f35b50503461029c578260031936011261029c5760ff601d5416600281101561126b5761122957338352602090601b8252600160ff84862054161515146111e857338452601a825282842080548581156103115784925560446001600160a01b03602254169387875195869485937fa9059cbb000000000000000000000000000000000000000000000000000000008552339085015260248401525af180156111db576111a8575b50338352601b90528120805460ff1916600117905580f35b8181813d83116111d4575b6111bd818361231d565b81010312610e3a57518015150361029c5738611190565b503d6111b3565b50505051903d90823e3d90fd5b90606492519162461bcd60e51b8352820152600f60248201527f616c726561647920636c61696d656400000000000000000000000000000000006044820152fd5b6020606492519162461bcd60e51b8352820152601260248201527f7769746864726177616c7320636c6f73656400000000000000000000000000006044820152fd5b602484602184634e487b7160e01b835252fd5b505050346102bf57816003193601126102bf5760209060ff6008541690519015158152f35b50503461029c57602036600319011261029c57359160135483101561031157506112ce602092612357565b91905490519160031b1c8152f35b505050346102bf57816003193601126102bf576020906007549051908152f35b843461031157806003193601126103115761131561259a565b806001600160a01b03815473ffffffffffffffffffffffffffffffffffffffff1981168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b505050346102bf5760203660031901126102bf57806020926001600160a01b0361138a61229e565b1681526001845220549051908152f35b505050346102bf57816003193601126102bf5760209060ff602154169051908152f35b83853461031157806003193601126103115750600a549051911c61ffff168152602090f35b50503461029c57602036600319011261029c57803591331561155e576114066125de565b60185442118015611547575b1561142b575050611423903361263c565b600160065580f35b33845260016020528281852054106114f557338452600f602052600160ff8286205416151503611466575050611461903361263c565b611423565b90602060a492519162461bcd60e51b8352820152605d60248201527f54686973207573657220646f65736e74206861766520574c20616e6420574c2060448201527f6275792077696e646f77206973206e6f7420706173736564207965742e20436860648201527f65636b20574c74696d656f76657220666f722074696d657374616d702e0000006084820152fd5b906020608492519162461bcd60e51b8352820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152fd5b506001600160a01b0360195460081c163314611412565b90836024925191634b637e8f60e11b8352820152fd5b505050346102bf57816003193601126102bf576020906018549051908152f35b505082346103115780600319360112610311576115af61259a565b60075461194e57601754600a5484517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821685820152949060246001600160a01b03841685888381845afa80156119445761187d575b8596975061161d61259a565b60ff6011549563ffffffff8560105416601254908851997f5d3b1d30000000000000000000000000000000000000000000000000000000008b528d8b0152868a015261ffff811660448a015260101c16606488015260a01c1660848601528460a48160209889945af1938415611873578694611844575b5082519685880188811084821117610c425784528688528351926116b7846122cf565b87845286840160019481868093528782019b8c52888b5260168a52878b20915115159060ff61ff0084549251151560081b1692169061ffff1916171781550198519889519182116118325768010000000000000000998a831161182057889082548484558085106117f6575b5001908952878920858a5b8481106117e4575050505050601354978810156117d357505085611778917f5d7d0431c4991fcc9f63f03ad0ead4128b866a8ed115a818b6d87a3afedb7264969701601355612357565b81549060031b9084821b91600019901b191617905581601455426015557fcc58b13ad3eab50626c6a6300b1d139cd6ebb1688a7cced9461c2f7e762665ee8160ff60175460a01c1681519085825286820152a151908152a180f35b60418791634e487b7160e01b835252fd5b8a84519401938184015501869061172e565b8785848e8781522092830192015b828110611812575050611723565b8d81558c9450899101611804565b848a604186634e487b7160e01b835252fd5b8389604185634e487b7160e01b835252fd5b9093508481813d831161186c575b61185c818361231d565b81010312610e3657519287611694565b503d611852565b83513d88823e3d90fd5b3d80878a3e61188c818a61231d565b88016080898203126119405788516bffffffffffffffffffffffff81160361194057602098898101518581160361193c576118c886820161282c565b50606081015190858211611938570181601f8201121561193c578051908a806118f08461233f565b6118fc8a51918261231d565b848152019260051b820101928311611938578a01905b82821061192157505050611611565b8a809161192d8461282c565b815201910190611912565b8880fd5b8780fd5b8680fd5b84513d88823e3d90fd5b506020608492519162461bcd60e51b8352820152602260248201527f53656564206578697374732c20736f2063616e74206765742061206e6577206f60448201527f6e650000000000000000000000000000000000000000000000000000000000006064820152fd5b505050346102bf57816003193601126102bf57602090601f549051908152f35b505050346102bf57816003193601126102bf57602090516c0c9f2c9cd04674edea400000008152f35b505050346102bf57816003193601126102bf576020905160128152f35b505050346102bf57816003193601126102bf576020906015549051908152f35b505050346102bf5760203660031901126102bf57806020926001600160a01b03611a6561229e565b168152601a845220549051908152f35b5050823461031157606036600319011261031157611a9161229e565b611a996122b9565b91604435936001600160a01b038316808352600260205286832033845260205286832054916000198303611ad6575b602088610edd8989896123d8565b868310611b3c578115611b26573315611b1057508252600260209081528683203384528152918690209085900390558290610edd87611ac8565b60249084895191634a1406b160e11b8352820152fd5b6024908489519163e602df0560e01b8352820152fd5b87517ffb8f41b2000000000000000000000000000000000000000000000000000000008152339181019182526020820193909352604081018790528291506060010390fd5b838584346102bf57826003193601126102bf57803560249384359267ffffffffffffffff95868511610e365736602386011215610e36578482013591611bc68361233f565b97611bd38551998a61231d565b838952602096878a0184819660051b83010191368311610e3257858a9101915b838310611d6b57505050506001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990916803303611d36575085885260168752611c4960ff868a205460081c16612840565b8588526016875284882090600180928160ff19825416178155018a5191821161182057680100000000000000008211611820578054828255808310611d0f575b5085908a52888a208a5b838110611cfe575050505050875115611ced57505094611ce7917ffe2e2d779dba245964d4e3ef9b994be63856fd568bf7d3ca9e224755cb1bd54d95965160075580805195869586528501528301906123a4565b0390a180f35b60328791634e487b7160e01b835252fd5b825182820155918a01918401611c93565b818b5283838b8d2092830192015b828110611d2b575050611c89565b8c8155018490611d1d565b90506044928551927f1cf993f40000000000000000000000000000000000000000000000000000000084523390840152820152fd5b82358152918101918a9101611bf3565b505050346102bf57816003193601126102bf5760209081549051908152f35b849150833461029c578260031936011261029c57611db661259a565b60ff908160085416611fbd5761ffff93600a93858554821c1686600b541603611f7a576007805415611f375782969596958392600019928343014381119040995b8b548a8160f01c16821015611f2657835483611f1357908c918b516020938482019283528d82015284606082015260808b81830152815260a0810181811067ffffffffffffffff821117611efd578d5251902090861c8716908115611ee957068616808a52600c8083528b8b20549091908d16611eb75790611eb29392918b52600d82526001600160a01b038c8c205416908252600f8c8c209260019260ff199484868254161790558d52528b8b209182541617905561281d565b611df7565b50505095611ec49061281d565b958015611ed65785611eb2910161281d565b60248860118f634e487b7160e01b835252fd5b8f8b6012602492634e487b7160e01b835252fd5b50508f8b6041602492634e487b7160e01b835252fd5b634e487b7160e01b8a5260118f5260248afd5b88600160ff19600854161760085580f35b606488602086519162461bcd60e51b8352820152601e60248201527f73656564206973206d697373696e672c207573652067657473656564282900006044820152fd5b606487602085519162461bcd60e51b8352820152600d60248201527f6e6f7420746865726520796574000000000000000000000000000000000000006044820152fd5b5162461bcd60e51b8152602081860152601860248201527f77696e6e65727320616c72656164792073656c656374656400000000000000006044820152606490fd5b505050346102bf57816003193601126102bf576020906003549051908152f35b505050346102bf5760203660031901126102bf5760ff816020936001600160a01b0361204961229e565b168152601c855220541690519015158152f35b505050346102bf57816003193601126102bf57602090517f28e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c1198152f35b505050346102bf57816003193601126102bf5760209067ffffffffffffffff600a54169051908152f35b50503461029c578160031936011261029c576120dc61229e565b602435903315612154576001600160a01b031691821561213e57508083602095338152600287528181208582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b60249085855191634a1406b160e11b8352820152fd5b6024838686519163e602df0560e01b8352820152fd5b83908686346102bf57816003193601126102bf5781845492600184811c91818616958615612254575b60209687851081146110a6579087899a92868b999a9b52918260001461222a5750506001146121cf575b858861089c89611014848a038561231d565b815286935091907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410612212575050508201018161101461089c886121bd565b8054848a0186015288955087949093019281016121f8565b60ff19168882015294151560051b87019094019450859350611014925061089c91508990506121bd565b92607f1692612193565b919082519283825260005b84811061228a575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201612269565b600435906001600160a01b03821682036122b457565b600080fd5b602435906001600160a01b03821682036122b457565b6060810190811067ffffffffffffffff8211176122eb57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176122eb57604052565b90601f8019910116810190811067ffffffffffffffff8211176122eb57604052565b67ffffffffffffffff81116122eb5760051b60200190565b60135481101561238e5760136000527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900190600090565b634e487b7160e01b600052603260045260246000fd5b90815180825260208080930193019160005b8281106123c4575050505090565b8351855293810193928101926001016123b6565b91906001600160a01b038084169081156125825780831615612551576123fc6125de565b6018544211908115612540575b501561242057506124199261271e565b6001600655565b80600052600160205282604060002054106124ed57600052600f602052600160ff6040600020541615150361245d576124589261271e565b612419565b60a460405162461bcd60e51b815260206004820152605d60248201527f54686973207573657220646f65736e74206861766520574c20616e6420574c2060448201527f6275792077696e646f77206973206e6f7420706173736564207965742e20436860648201527f65636b20574c74696d656f76657220666f722074696d657374616d702e0000006084820152fd5b608460405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152fd5b905060195460081c16331438612409565b60246040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152fd5b6024604051634b637e8f60e11b815260006004820152fd5b6001600160a01b036000541633036125ae57565b60246040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152fd5b6002600654146125ef576002600655565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b9190820180921161262657565b634e487b7160e01b600052601160045260246000fd5b9091906001600160a01b038116908161269857507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60208461268360009596600354612619565b6003555b8060035403600355604051908152a3565b92816000526001602052604060002054938185106126ec57506020817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926000959685875260018452036040862055612687565b60405163391434e360e21b81526001600160a01b03919091166004820152602481018590526044810191909152606490fd5b6001600160a01b038082169290918361279857507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160209161276386600354612619565b6003555b1693846127805780600354036003555b604051908152a3565b84600052600182526040600020818154019055612777565b836000526001602052604060002054908582106127eb575091602091857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef94866000526001855203604060002055612767565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101859052606490fd5b60001981146126265760010190565b51906001600160a01b03821682036122b457565b1561284757565b606460405162461bcd60e51b815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152fdfea2646970667358221220a5fdd10e1230904c88024d740d08a4f031f3b9cff17d23ce0c083c5081b9ae4a64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006d2d146fa21e574e8b4789a88488617c1b44f28b000000000000000000000000000000000000000000000000000000000000038d000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699098af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a12028e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c119000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000019d971e4fe8401e74000000
-----Decoded View---------------
Arg [0] : _multisig (address): 0x6D2D146fA21e574E8B4789A88488617C1B44F28b
Arg [1] : _subscriptionId (uint64): 909
Arg [2] : _vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [3] : _keyHash (bytes32): 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [4] : _entryPrice (uint256): 50000000000000000
Arg [5] : _requestConfirmations (uint16): 3
Arg [6] : _callbackGasLimit (uint32): 500000
Arg [7] : _lpRoot (bytes32): 0x28e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c119
Arg [8] : _entryPriceLP (uint256): 100000000000000000
Arg [9] : _maxTokenAlloc (uint256): 500000000000000000000000000
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000006d2d146fa21e574e8b4789a88488617c1b44f28b
Arg [1] : 000000000000000000000000000000000000000000000000000000000000038d
Arg [2] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [3] : 8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [4] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 000000000000000000000000000000000000000000000000000000000007a120
Arg [7] : 28e3ef3462f52b244d23a2ff294bc1e7edbb278a52313a8569596a39e4c0c119
Arg [8] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [9] : 0000000000000000000000000000000000000000019d971e4fe8401e74000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.