Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 28 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Send Ether | 19563327 | 720 days ago | IN | 0 ETH | 0.00086658 | ||||
| Send Ether | 19563326 | 720 days ago | IN | 0 ETH | 0.00132282 | ||||
| Enter Raffle | 17478688 | 1012 days ago | IN | 0.025 ETH | 0.00199167 | ||||
| Send Ether | 17416562 | 1021 days ago | IN | 0 ETH | 0.00148394 | ||||
| Enter Raffle | 17123889 | 1062 days ago | IN | 0.025 ETH | 0.0040022 | ||||
| Enter Raffle | 17087017 | 1067 days ago | IN | 0.025 ETH | 0.00548394 | ||||
| Set Entrance Fee | 17045325 | 1073 days ago | IN | 0 ETH | 0.00082568 | ||||
| Enter Raffle | 17044711 | 1073 days ago | IN | 0.037 ETH | 0.00244766 | ||||
| Pay | 17040273 | 1074 days ago | IN | 0 ETH | 0.00227331 | ||||
| Enter Raffle | 17040251 | 1074 days ago | IN | 0.037 ETH | 0.00365934 | ||||
| Enter Raffle | 17039617 | 1074 days ago | IN | 0.037 ETH | 0.00343961 | ||||
| Send Ether | 17031892 | 1075 days ago | IN | 0 ETH | 0.00066525 | ||||
| Enter Raffle | 17019790 | 1077 days ago | IN | 0.037 ETH | 0.00292991 | ||||
| Pay | 17006157 | 1079 days ago | IN | 0 ETH | 0.00152562 | ||||
| Enter Raffle | 17005855 | 1079 days ago | IN | 0.037 ETH | 0.00233296 | ||||
| Enter Raffle | 16988500 | 1081 days ago | IN | 0.037 ETH | 0.00268357 | ||||
| Enter Raffle | 16988476 | 1081 days ago | IN | 0.037 ETH | 0.00273421 | ||||
| Pay | 16956502 | 1086 days ago | IN | 0 ETH | 0.00119603 | ||||
| Enter Raffle | 16956378 | 1086 days ago | IN | 0.037 ETH | 0.00216019 | ||||
| Enter Raffle | 16956368 | 1086 days ago | IN | 0.037 ETH | 0.0022462 | ||||
| Set Entrance Fee | 16956332 | 1086 days ago | IN | 0 ETH | 0.00059838 | ||||
| Enter Raffle | 16956039 | 1086 days ago | IN | 0.033 ETH | 0.0021541 | ||||
| Send Ether | 16954817 | 1086 days ago | IN | 0 ETH | 0.0007622 | ||||
| Enter Raffle | 16954658 | 1086 days ago | IN | 0.033 ETH | 0.00240002 | ||||
| Enter Raffle | 16954658 | 1086 days ago | IN | 0.033 ETH | 0.00240002 |
Latest 7 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 19563326 | 720 days ago | 0.025 ETH | ||||
| Transfer | 17416562 | 1021 days ago | 0.11115104 ETH | ||||
| Transfer | 17040273 | 1074 days ago | 0.04984895 ETH | ||||
| Transfer | 17031892 | 1075 days ago | 0.14602252 ETH | ||||
| Transfer | 17006157 | 1079 days ago | 0.05389806 ETH | ||||
| Transfer | 16956502 | 1086 days ago | 0.0550794 ETH | ||||
| Transfer | 16954817 | 1086 days ago | 0.066 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RaffleImpl
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./interfaces/Raffle.sol";
import "./Ticket.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract RaffleImpl is Ownable, Raffle, VRFConsumerBaseV2 {
/* Raffle Variables */
Ticket public immutable ticketNft;
uint256 public entranceFee = 0.033 ether;
uint256 public ticketsLeft;
uint256 private ticketsLeftToFulfill;
uint256[] private amounts;
uint256[] public sums;
bool public isOpen;
mapping (address => address) refferalToRefferer;
uint256 constant private FLOOR = 1_000;
uint256 public reffererShare = 100;
/* Chainlink Variables */
AggregatorV3Interface private priceFeed;
VRFCoordinatorV2Interface private vrfCoordinator;
uint32 public constant numWords = 1;
uint16 public immutable requestConfirmations;
uint32 public constant callbackGasLimit = 400000;
bytes32 public keyHash;
uint64 public subscriptionId;
mapping (uint256 => address) public playerByRequestId;
modifier opened() {
require(isOpen, "RaffleImpl: raffle is closed");
_;
}
constructor(
uint256[] memory _amounts,
uint256[] memory _sums,
address _priceFeed,
address _ticketNft,
address _vffCoordinatorV2,
uint16 _requestConfirmations,
bytes32 _keyHash,
uint64 _subscriptionId
) VRFConsumerBaseV2(_vffCoordinatorV2) {
require(
_amounts.length == _sums.length && _amounts.length != 0,
"RaffleImpl: invalid arguments"
);
require(_priceFeed != address(0), "RaffleImpl: invalid arguments");
require(_ticketNft != address(0), "RaffleImpl: invalid arguments");
require(_vffCoordinatorV2 != address(0), "RaffleImpl: invalid arguments");
require(_keyHash != bytes32(0), "RaffleImpl: invalid arguments");
require(_requestConfirmations != 0, "RaffleImpl: invalid arguments");
require(_subscriptionId != 0, "RaffleImpl: invalid arguments");
priceFeed = AggregatorV3Interface(_priceFeed);
vrfCoordinator = VRFCoordinatorV2Interface(_vffCoordinatorV2);
requestConfirmations = _requestConfirmations;
keyHash = _keyHash;
subscriptionId = _subscriptionId;
sums = _sums;
amounts = _amounts;
ticketsLeft = 11999;
ticketsLeftToFulfill = 11999;
ticketNft = Ticket(_ticketNft);
}
function setSubscriptionId(uint64 newId) external onlyOwner {
require(newId != 0, "RaffleImpl: invalid arguments");
subscriptionId = newId;
}
function setKeyHash(bytes32 newKeyHash) external onlyOwner {
require(newKeyHash != bytes32(0), "RaffleImpl: invalid arguments");
keyHash = newKeyHash;
}
function openRaffle() external override onlyOwner {
isOpen = true;
}
function stopRaffle() external override onlyOwner {
isOpen = false;
}
function setEntranceFee(uint256 newEntranceFee) external onlyOwner {
require(newEntranceFee != 0, "RaffleImpl: invalid arguments");
entranceFee = newEntranceFee;
}
function setPriceFeed(address newPriceFeed) external onlyOwner {
require(newPriceFeed != address(0), "RaffleImpl: invalid arguments");
priceFeed = AggregatorV3Interface(newPriceFeed);
}
function setReffererShare(uint256 newShare) external onlyOwner {
require (newShare < FLOOR, "RaffleImpl: too big share");
reffererShare = newShare;
}
function finalGame() external view returns (address[20] memory) {
require(isOpen == false, "RaffleImpl: raffle not stopped");
return getTopPlayers();
}
function pay(
address target,
uint256 amountInUsdt
) external override onlyOwner {
(, int256 answer, , , ) = priceFeed.latestRoundData();
uint256 amount = amountInUsdt * uint256(answer);
(bool success, ) = payable(target).call{value: amount}("");
require(success, "RaffleImpl: Transfer failed");
}
function sendEther(address target, uint256 amount) external override onlyOwner {
(bool success,) = payable(target).call{value: amount}("");
require(success, "RaffleImpl: Transfer failed");
}
function enterRaffle(address refferer) external payable override opened {
require(msg.value >= entranceFee, "RaffleImpl: not enough ether sent");
require(ticketsLeft > 0, "RaffleImpl: All positions are closed");
require(refferer != msg.sender, "RaffleImpl: Refferer is msg.sender");
if (refferalToRefferer[msg.sender] == address(0) && refferer != address(0)) {
refferalToRefferer[msg.sender] = refferer;
}
if (refferalToRefferer[msg.sender] != address(0)) {
// don't check return value because we should not revert on failure
(bool success,) = refferalToRefferer[msg.sender].call{value: entranceFee * reffererShare / FLOOR}("");
if (success) {
emit ReffererPaid(block.timestamp, refferalToRefferer[msg.sender], msg.sender, entranceFee, entranceFee * reffererShare / FLOOR);
}
}
--ticketsLeft;
uint256 requestId = vrfCoordinator.requestRandomWords(keyHash, subscriptionId, requestConfirmations, callbackGasLimit, numWords);
playerByRequestId[requestId] = msg.sender;
if (msg.value > entranceFee) {
(bool success,) = payable(msg.sender).call{value: msg.value - entranceFee}("");
require(success, "RaffleImpl: Transfer failed");
}
emit Requested(msg.sender, requestId);
}
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
uint256 randomNumber = randomWords[0] % ticketsLeftToFulfill;
--ticketsLeftToFulfill;
address player = playerByRequestId[requestId];
uint256 winningIndex = _chooseWinTicket(randomNumber);
uint256 sumOfTicket = sums[winningIndex];
uint256 tokenId = ticketNft.mint(player, sumOfTicket);
emit WinnerChosen(player, sumOfTicket, tokenId);
}
function _chooseWinTicket(uint256 randomNumber) internal returns (uint256) {
uint256 length = amounts.length;
uint256 winningIndex = length - 1;
for (uint256 i = 0; i < length; i++) {
if (amounts[i] == 0) {
continue;
}
if (amounts[i] < randomNumber) {
randomNumber -= amounts[i];
} else {
winningIndex = i;
amounts[i]--;
break;
}
}
return winningIndex;
}
function getTicketsLeftBySum(uint256 sum) external view returns (uint256) {
for (uint256 i = 0; i < sums.length; i++) {
if (sums[i] == sum) {
return amounts[i];
}
}
return 0;
}
function getTicketsLeft() external view returns (uint256[] memory) {
return amounts;
}
function getTopPlayers() public view returns (address[20] memory) {
return ticketNft.getTopPlayers();
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}// 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 v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner or approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_safeTransfer(from, to, tokenId, data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _ownerOf(tokenId) != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId, 1);
// Check that tokenId was not minted by `_beforeTokenTransfer` hook
require(!_exists(tokenId), "ERC721: token already minted");
unchecked {
// Will not overflow unless all 2**256 token ids are minted to the same owner.
// Given that tokens are minted one by one, it is impossible in practice that
// this ever happens. Might change if we allow batch minting.
// The ERC fails to describe this case.
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId, 1);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId, 1);
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
owner = ERC721.ownerOf(tokenId);
// Clear approvals
delete _tokenApprovals[tokenId];
unchecked {
// Cannot overflow, as that would require more tokens to be burned/transferred
// out than the owner initially received through minting and transferring in.
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId, 1);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId, 1);
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
// Clear approvals from the previous owner
delete _tokenApprovals[tokenId];
unchecked {
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
// `from`'s balance is the number of token held, which is at least one before the current
// transfer.
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
// all 2**256 token ids to be minted, which in practice is impossible.
_balances[from] -= 1;
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId, 1);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
* - When `from` is zero, the tokens will be minted for `to`.
* - When `to` is zero, ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256, /* firstTokenId */
uint256 batchSize
) internal virtual {
if (batchSize > 1) {
if (from != address(0)) {
_balances[from] -= batchSize;
}
if (to != address(0)) {
_balances[to] += batchSize;
}
}
}
/**
* @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
* - When `from` is zero, the tokens were minted for `to`.
* - When `to` is zero, ``from``'s tokens were burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
if (batchSize > 1) {
// Will only trigger during construction. Batch transferring (minting) is not available afterwards.
revert("ERC721Enumerable: consecutive transfers not supported");
}
uint256 tokenId = firstTokenId;
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
interface Raffle {
event WinnerChosen(address indexed player, uint256 indexed sum, uint256 indexed tokenId);
event Requested(address indexed player, uint256 requestId);
event ReffererPaid(uint256 timestamp, address indexed refferer, address refferal, uint256 price, uint256 reward);
function openRaffle() external;
function stopRaffle() external;
function pay(address target, uint256 amountInUsdt) external;
function sendEther(address target, uint256 amount) external;
function enterRaffle(address refferer) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract Ticket is ERC721, Ownable {
using Counters for Counters.Counter;
mapping(uint256 => uint256) public sums;
mapping(uint256 => uint256) private tokenIds;
mapping(address => uint256) private amountOfTickets;
address[20] private topPlayers;
string private baseUri = "https://veritty-backend-app.herokuapp.com/metadata/";
constructor(uint256[] memory _tokenIds, uint256[] memory _sums) ERC721("VERITTY Ticket", "VRT") {
require(_tokenIds.length == _sums.length, "Ticket: invalid arguments");
uint256 length = _tokenIds.length;
for (uint256 i = 0; i < length; i++) {
tokenIds[_sums[i]] = _tokenIds[i];
}
}
function mint(address _to, uint256 _sum) public onlyOwner returns (uint256) {
uint256 tokenId = tokenIds[_sum]++;
_mint(_to, tokenId);
sums[tokenId] = _sum;
return tokenId;
}
function setBaseUri(string memory _baseUri) external onlyOwner {
baseUri = _baseUri;
}
function getTopPlayer(uint256 index) external view returns (address) {
return topPlayers[index];
}
function getTopPlayers() external view returns (address[20] memory) {
return topPlayers;
}
function win(uint256 _tokenId) external view returns (bool) {
return sums[_tokenId] != 0;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireMinted(tokenId);
return string(abi.encodePacked(baseUri, Strings.toString(tokenId)));
}
function _updateStatistics(address from, address winner) internal {
amountOfTickets[winner]++;
if (from != address(0)) {
amountOfTickets[from]--;
}
_updateTop20(winner);
}
function _updateTop20(address player) internal {
uint256 balance = amountOfTickets[player];
uint256 lastPlayerBalance = amountOfTickets[topPlayers[19]];
bool inArray;
for (uint256 i = 0; i < 20; i++) {
if (topPlayers[i] == player) {
inArray = true;
break;
}
}
if (!inArray) {
if (balance == lastPlayerBalance + 1) {
topPlayers[19] = player;
}
}
_sortTopPlayers();
}
function _sortTopPlayers() internal {
address[20] memory tp = topPlayers;
for (uint i = 1; i < 20; i++) {
uint j = i;
while (j > 0 && (amountOfTickets[tp[j - 1]] < amountOfTickets[tp[j]])) {
address tmp = tp[j];
tp[j] = tp[j - 1];
tp[j - 1] = tmp;
j--;
}
}
topPlayers = tp;
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId,
uint256 batchSize
) internal override(ERC721) {
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}
function _afterTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal override(ERC721) {
_updateStatistics(from, to);
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721) returns (bool) {
return super.supportsInterface(interfaceId);
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_sums","type":"uint256[]"},{"internalType":"address","name":"_priceFeed","type":"address"},{"internalType":"address","name":"_ticketNft","type":"address"},{"internalType":"address","name":"_vffCoordinatorV2","type":"address"},{"internalType":"uint16","name":"_requestConfirmations","type":"uint16"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint64","name":"_subscriptionId","type":"uint64"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"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":"timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"refferer","type":"address"},{"indexed":false,"internalType":"address","name":"refferal","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"ReffererPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"Requested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":true,"internalType":"uint256","name":"sum","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"WinnerChosen","type":"event"},{"inputs":[],"name":"callbackGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"refferer","type":"address"}],"name":"enterRaffle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"entranceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalGame","outputs":[{"internalType":"address[20]","name":"","type":"address[20]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTicketsLeft","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sum","type":"uint256"}],"name":"getTicketsLeftBySum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTopPlayers","outputs":[{"internalType":"address[20]","name":"","type":"address[20]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numWords","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amountInUsdt","type":"uint256"}],"name":"pay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"playerByRequestId","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"reffererShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestConfirmations","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEntranceFee","type":"uint256"}],"name":"setEntranceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newKeyHash","type":"bytes32"}],"name":"setKeyHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPriceFeed","type":"address"}],"name":"setPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newShare","type":"uint256"}],"name":"setReffererShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newId","type":"uint64"}],"name":"setSubscriptionId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sums","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketNft","outputs":[{"internalType":"contract Ticket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketsLeft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60e060405266753d533d96800060015560646008553480156200002157600080fd5b50604051620036f4380380620036f4833981810160405281019062000047919062000898565b83620000686200005c6200047360201b60201c565b6200047b60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505086518851148015620000b157506000885114155b620000f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000ea9062000a00565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160362000165576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200015c9062000a00565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603620001d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001ce9062000a00565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160362000249576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002409062000a00565b60405180910390fd5b6000801b820362000291576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002889062000a00565b60405180910390fd5b60008361ffff1603620002db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002d29062000a00565b60405180910390fd5b60008167ffffffffffffffff16036200032b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003229062000a00565b60405180910390fd5b85600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508261ffff1660c08161ffff168152505081600b8190555080600c60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508660059080519060200190620004059291906200053f565b5087600490805190602001906200041e9291906200053f565b50612edf600281905550612edf6003819055508473ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1681525050505050505050505062000a22565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8280548282559060005260206000209081019282156200057e579160200282015b828111156200057d57825182559160200191906001019062000560565b5b5090506200058d919062000591565b5090565b5b80821115620005ac57600081600090555060010162000592565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200061482620005c9565b810181811067ffffffffffffffff82111715620006365762000635620005da565b5b80604052505050565b60006200064b620005b0565b905062000659828262000609565b919050565b600067ffffffffffffffff8211156200067c576200067b620005da565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b620006a78162000692565b8114620006b357600080fd5b50565b600081519050620006c7816200069c565b92915050565b6000620006e4620006de846200065e565b6200063f565b905080838252602082019050602084028301858111156200070a57620007096200068d565b5b835b81811015620007375780620007228882620006b6565b8452602084019350506020810190506200070c565b5050509392505050565b600082601f830112620007595762000758620005c4565b5b81516200076b848260208601620006cd565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007a18262000774565b9050919050565b620007b38162000794565b8114620007bf57600080fd5b50565b600081519050620007d381620007a8565b92915050565b600061ffff82169050919050565b620007f281620007d9565b8114620007fe57600080fd5b50565b6000815190506200081281620007e7565b92915050565b6000819050919050565b6200082d8162000818565b81146200083957600080fd5b50565b6000815190506200084d8162000822565b92915050565b600067ffffffffffffffff82169050919050565b620008728162000853565b81146200087e57600080fd5b50565b600081519050620008928162000867565b92915050565b600080600080600080600080610100898b031215620008bc57620008bb620005ba565b5b600089015167ffffffffffffffff811115620008dd57620008dc620005bf565b5b620008eb8b828c0162000741565b985050602089015167ffffffffffffffff8111156200090f576200090e620005bf565b5b6200091d8b828c0162000741565b9750506040620009308b828c01620007c2565b9650506060620009438b828c01620007c2565b9550506080620009568b828c01620007c2565b94505060a0620009698b828c0162000801565b93505060c06200097c8b828c016200083c565b92505060e06200098f8b828c0162000881565b9150509295985092959890939650565b600082825260208201905092915050565b7f526166666c65496d706c3a20696e76616c696420617267756d656e7473000000600082015250565b6000620009e8601d836200099f565b9150620009f582620009b0565b602082019050919050565b6000602082019050818103600083015262000a1b81620009d9565b9050919050565b60805160a05160c051612c8662000a6e60003960008181610df2015261131f01526000818161120a01528181611585015261182d01526000818161075601526107aa0152612c866000f3fe6080604052600436106101d15760003560e01c8063724e78da116100f7578063b0fb162f11610095578063e09b2a6211610064578063e09b2a621461061a578063ea7b4f7714610645578063f2fde38b1461066e578063fe56f5a014610697576101d8565b8063b0fb162f14610586578063b4ba7d36146105b1578063c1756a2c146105c8578063c4076876146105f1576101d8565b806381326c4e116100d157806381326c4e146104ca57806388e814e6146105075780638da5cb5b14610532578063985447101461055d576101d8565b8063724e78da1461045f5780637ccfd7fc146104885780637dae059a146104b3576101d8565b80634d827e081161016f578063649677e11161013e578063649677e1146103b5578063694c49be146103e05780636cab5e5b1461041d578063715018a614610448576101d8565b80634d827e0814610318578063536b24c91461033457806361728f391461035f578063646f22c51461038a576101d8565b80631fe543e3116101ab5780631fe543e31461026e57806324f7469714610297578063328169ad146102c257806347535d7b146102ed576101d8565b806309c1ba2e146101dd5780631bb43646146102085780631f564a4514610231576101d8565b366101d857005b600080fd5b3480156101e957600080fd5b506101f26106c0565b6040516101ff9190611b2b565b60405180910390f35b34801561021457600080fd5b5061022f600480360381019061022a9190611b90565b6106da565b005b34801561023d57600080fd5b5061025860048036038101906102539190611b90565b610730565b6040516102659190611bcc565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190611d40565b610754565b005b3480156102a357600080fd5b506102ac610814565b6040516102b99190611dbb565b60405180910390f35b3480156102ce57600080fd5b506102d761081b565b6040516102e49190611eb3565b60405180910390f35b3480156102f957600080fd5b50610302610886565b60405161030f9190611eea565b60405180910390f35b610332600480360381019061032d9190611f31565b610899565b005b34801561034057600080fd5b50610349610fe5565b6040516103569190611bcc565b60405180910390f35b34801561036b57600080fd5b50610374610feb565b6040516103819190611f77565b60405180910390f35b34801561039657600080fd5b5061039f610ff1565b6040516103ac9190612050565b60405180910390f35b3480156103c157600080fd5b506103ca611049565b6040516103d79190611bcc565b60405180910390f35b3480156103ec57600080fd5b5061040760048036038101906104029190611b90565b61104f565b6040516104149190611bcc565b60405180910390f35b34801561042957600080fd5b506104326110ce565b60405161043f9190611bcc565b60405180910390f35b34801561045457600080fd5b5061045d6110d4565b005b34801561046b57600080fd5b5061048660048036038101906104819190611f31565b6110e8565b005b34801561049457600080fd5b5061049d6111a3565b6040516104aa9190611dbb565b60405180910390f35b3480156104bf57600080fd5b506104c86111a8565b005b3480156104d657600080fd5b506104f160048036038101906104ec9190611b90565b6111cd565b6040516104fe9190612081565b60405180910390f35b34801561051357600080fd5b5061051c611200565b6040516105299190611eb3565b60405180910390f35b34801561053e57600080fd5b5061054761129d565b6040516105549190612081565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906120c8565b6112c6565b005b34801561059257600080fd5b5061059b61131d565b6040516105a89190612112565b60405180910390f35b3480156105bd57600080fd5b506105c6611341565b005b3480156105d457600080fd5b506105ef60048036038101906105ea919061212d565b611366565b005b3480156105fd57600080fd5b506106186004803603810190610613919061212d565b61141f565b005b34801561062657600080fd5b5061062f611583565b60405161063c91906121cc565b60405180910390f35b34801561065157600080fd5b5061066c60048036038101906106679190612213565b6115a7565b005b34801561067a57600080fd5b5061069560048036038101906106909190611f31565b611628565b005b3480156106a357600080fd5b506106be60048036038101906106b99190611b90565b6116ab565b005b600c60009054906101000a900467ffffffffffffffff1681565b6106e2611700565b6103e88110610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071d9061229d565b60405180910390fd5b8060088190555050565b6005818154811061074057600080fd5b906000526020600020016000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080657337f00000000000000000000000000000000000000000000000000000000000000006040517f1cf993f40000000000000000000000000000000000000000000000000000000081526004016107fd9291906122bd565b60405180910390fd5b610810828261177e565b5050565b62061a8081565b610823611ae5565b60001515600660009054906101000a900460ff16151514610879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087090612332565b60405180910390fd5b610881611200565b905090565b600660009054906101000a900460ff1681565b600660009054906101000a900460ff166108e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108df9061239e565b60405180910390fd5b60015434101561092d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092490612430565b60405180910390fd5b600060025411610972576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610969906124c2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d790612554565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015610aa85750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15610b2c5780600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b600073ffffffffffffffffffffffffffffffffffffffff16600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610d80576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e8600854600154610c4a91906125a3565b610c549190612614565b604051610c6090612676565b60006040518083038185875af1925050503d8060008114610c9d576040519150601f19603f3d011682016040523d82523d6000602084013e610ca2565b606091505b505090508015610d7e57600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fc7dde075d320ffe9e9ba5748acbfa47ebbbb1a54ca5486ce0cc1ef006ddf9d2a42336001546103e8600854600154610d5b91906125a3565b610d659190612614565b604051610d75949392919061268b565b60405180910390a25b505b600260008154610d8f906126d0565b919050819055506000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30600b54600c60009054906101000a900467ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000062061a8060016040518663ffffffff1660e01b8152600401610e379594939291906126f9565b6020604051808303816000875af1158015610e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7a9190612761565b905033600d600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600154341115610f935760003373ffffffffffffffffffffffffffffffffffffffff1660015434610eff919061278e565b604051610f0b90612676565b60006040518083038185875af1925050503d8060008114610f48576040519150601f19603f3d011682016040523d82523d6000602084013e610f4d565b606091505b5050905080610f91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f889061280e565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff167f189155e729161d41c9756b8f023ae2bcb16166eb447c05edd79b57f5c29f19e382604051610fd99190611bcc565b60405180910390a25050565b60085481565b600b5481565b6060600480548060200260200160405190810160405280929190818152602001828054801561103f57602002820191906000526020600020905b81548152602001906001019080831161102b575b5050505050905090565b60015481565b600080600090505b6005805490508110156110c35782600582815481106110795761107861282e565b5b9060005260206000200154036110b0576004818154811061109d5761109c61282e565b5b90600052602060002001549150506110c9565b80806110bb9061285d565b915050611057565b50600090505b919050565b60025481565b6110dc611700565b6110e66000611919565b565b6110f0611700565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361115f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611156906128f1565b60405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600181565b6111b0611700565b6000600660006101000a81548160ff021916908315150217905550565b600d6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611208611ae5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166388e814e66040518163ffffffff1660e01b815260040161028060405180830381865afa158015611274573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129891906129d7565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112ce611700565b6000801b8103611313576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130a906128f1565b60405180910390fd5b80600b8190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611349611700565b6001600660006101000a81548160ff021916908315150217905550565b61136e611700565b60008273ffffffffffffffffffffffffffffffffffffffff168260405161139490612676565b60006040518083038185875af1925050503d80600081146113d1576040519150601f19603f3d011682016040523d82523d6000602084013e6113d6565b606091505b505090508061141a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114119061280e565b60405180910390fd5b505050565b611427611700565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ba9190612a7d565b505050915050600081836114ce91906125a3565b905060008473ffffffffffffffffffffffffffffffffffffffff16826040516114f690612676565b60006040518083038185875af1925050503d8060008114611533576040519150601f19603f3d011682016040523d82523d6000602084013e611538565b606091505b505090508061157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061280e565b60405180910390fd5b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6115af611700565b60008167ffffffffffffffff16036115fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f3906128f1565b60405180910390fd5b80600c60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b611630611700565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169690612b6a565b60405180910390fd5b6116a881611919565b50565b6116b3611700565b600081036116f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ed906128f1565b60405180910390fd5b8060018190555050565b6117086119dd565b73ffffffffffffffffffffffffffffffffffffffff1661172661129d565b73ffffffffffffffffffffffffffffffffffffffff161461177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177390612bd6565b60405180910390fd5b565b6000600354826000815181106117975761179661282e565b5b60200260200101516117a99190612bf6565b90506003600081546117ba906126d0565b919050819055506000600d600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000611804836119e5565b905060006005828154811061181c5761181b61282e565b5b9060005260206000200154905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1985846040518363ffffffff1660e01b8152600401611886929190612c27565b6020604051808303816000875af11580156118a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c99190612761565b905080828573ffffffffffffffffffffffffffffffffffffffff167f583f2b104ddadb04015734001b634e73a2cd12f3beccb23ad14d2df0ab279dcf60405160405180910390a450505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080600480549050905060006001826119ff919061278e565b905060005b82811015611ada57600060048281548110611a2257611a2161282e565b5b90600052602060002001540315611ac7578460048281548110611a4857611a4761282e565b5b90600052602060002001541015611a8a5760048181548110611a6d57611a6c61282e565b5b906000526020600020015485611a83919061278e565b9450611ac6565b80915060048181548110611aa157611aa061282e565b5b906000526020600020016000815480929190611abc906126d0565b9190505550611ada565b5b8080611ad29061285d565b915050611a04565b508092505050919050565b604051806102800160405280601490602082028036833780820191505090505090565b600067ffffffffffffffff82169050919050565b611b2581611b08565b82525050565b6000602082019050611b406000830184611b1c565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b611b6d81611b5a565b8114611b7857600080fd5b50565b600081359050611b8a81611b64565b92915050565b600060208284031215611ba657611ba5611b50565b5b6000611bb484828501611b7b565b91505092915050565b611bc681611b5a565b82525050565b6000602082019050611be16000830184611bbd565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c3582611bec565b810181811067ffffffffffffffff82111715611c5457611c53611bfd565b5b80604052505050565b6000611c67611b46565b9050611c738282611c2c565b919050565b600067ffffffffffffffff821115611c9357611c92611bfd565b5b602082029050602081019050919050565b600080fd5b6000611cbc611cb784611c78565b611c5d565b90508083825260208201905060208402830185811115611cdf57611cde611ca4565b5b835b81811015611d085780611cf48882611b7b565b845260208401935050602081019050611ce1565b5050509392505050565b600082601f830112611d2757611d26611be7565b5b8135611d37848260208601611ca9565b91505092915050565b60008060408385031215611d5757611d56611b50565b5b6000611d6585828601611b7b565b925050602083013567ffffffffffffffff811115611d8657611d85611b55565b5b611d9285828601611d12565b9150509250929050565b600063ffffffff82169050919050565b611db581611d9c565b82525050565b6000602082019050611dd06000830184611dac565b92915050565b600060149050919050565b600081905092915050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611e2182611df6565b9050919050565b611e3181611e16565b82525050565b6000611e438383611e28565b60208301905092915050565b6000602082019050919050565b611e6581611dd6565b611e6f8184611de1565b9250611e7a82611dec565b8060005b83811015611eab578151611e928782611e37565b9650611e9d83611e4f565b925050600181019050611e7e565b505050505050565b600061028082019050611ec96000830184611e5c565b92915050565b60008115159050919050565b611ee481611ecf565b82525050565b6000602082019050611eff6000830184611edb565b92915050565b611f0e81611e16565b8114611f1957600080fd5b50565b600081359050611f2b81611f05565b92915050565b600060208284031215611f4757611f46611b50565b5b6000611f5584828501611f1c565b91505092915050565b6000819050919050565b611f7181611f5e565b82525050565b6000602082019050611f8c6000830184611f68565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611fc781611b5a565b82525050565b6000611fd98383611fbe565b60208301905092915050565b6000602082019050919050565b6000611ffd82611f92565b6120078185611f9d565b935061201283611fae565b8060005b8381101561204357815161202a8882611fcd565b975061203583611fe5565b925050600181019050612016565b5085935050505092915050565b6000602082019050818103600083015261206a8184611ff2565b905092915050565b61207b81611e16565b82525050565b60006020820190506120966000830184612072565b92915050565b6120a581611f5e565b81146120b057600080fd5b50565b6000813590506120c28161209c565b92915050565b6000602082840312156120de576120dd611b50565b5b60006120ec848285016120b3565b91505092915050565b600061ffff82169050919050565b61210c816120f5565b82525050565b60006020820190506121276000830184612103565b92915050565b6000806040838503121561214457612143611b50565b5b600061215285828601611f1c565b925050602061216385828601611b7b565b9150509250929050565b6000819050919050565b600061219261218d61218884611df6565b61216d565b611df6565b9050919050565b60006121a482612177565b9050919050565b60006121b682612199565b9050919050565b6121c6816121ab565b82525050565b60006020820190506121e160008301846121bd565b92915050565b6121f081611b08565b81146121fb57600080fd5b50565b60008135905061220d816121e7565b92915050565b60006020828403121561222957612228611b50565b5b6000612237848285016121fe565b91505092915050565b600082825260208201905092915050565b7f526166666c65496d706c3a20746f6f2062696720736861726500000000000000600082015250565b6000612287601983612240565b915061229282612251565b602082019050919050565b600060208201905081810360008301526122b68161227a565b9050919050565b60006040820190506122d26000830185612072565b6122df6020830184612072565b9392505050565b7f526166666c65496d706c3a20726166666c65206e6f742073746f707065640000600082015250565b600061231c601e83612240565b9150612327826122e6565b602082019050919050565b6000602082019050818103600083015261234b8161230f565b9050919050565b7f526166666c65496d706c3a20726166666c6520697320636c6f73656400000000600082015250565b6000612388601c83612240565b915061239382612352565b602082019050919050565b600060208201905081810360008301526123b78161237b565b9050919050565b7f526166666c65496d706c3a206e6f7420656e6f7567682065746865722073656e60008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b600061241a602183612240565b9150612425826123be565b604082019050919050565b600060208201905081810360008301526124498161240d565b9050919050565b7f526166666c65496d706c3a20416c6c20706f736974696f6e732061726520636c60008201527f6f73656400000000000000000000000000000000000000000000000000000000602082015250565b60006124ac602483612240565b91506124b782612450565b604082019050919050565b600060208201905081810360008301526124db8161249f565b9050919050565b7f526166666c65496d706c3a205265666665726572206973206d73672e73656e6460008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061253e602283612240565b9150612549826124e2565b604082019050919050565b6000602082019050818103600083015261256d81612531565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006125ae82611b5a565b91506125b983611b5a565b92508282026125c781611b5a565b915082820484148315176125de576125dd612574565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061261f82611b5a565b915061262a83611b5a565b92508261263a576126396125e5565b5b828204905092915050565b600081905092915050565b50565b6000612660600083612645565b915061266b82612650565b600082019050919050565b600061268182612653565b9150819050919050565b60006080820190506126a06000830187611bbd565b6126ad6020830186612072565b6126ba6040830185611bbd565b6126c76060830184611bbd565b95945050505050565b60006126db82611b5a565b9150600082036126ee576126ed612574565b5b600182039050919050565b600060a08201905061270e6000830188611f68565b61271b6020830187611b1c565b6127286040830186612103565b6127356060830185611dac565b6127426080830184611dac565b9695505050505050565b60008151905061275b81611b64565b92915050565b60006020828403121561277757612776611b50565b5b60006127858482850161274c565b91505092915050565b600061279982611b5a565b91506127a483611b5a565b92508282039050818111156127bc576127bb612574565b5b92915050565b7f526166666c65496d706c3a205472616e73666572206661696c65640000000000600082015250565b60006127f8601b83612240565b9150612803826127c2565b602082019050919050565b60006020820190508181036000830152612827816127eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061286882611b5a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361289a57612899612574565b5b600182019050919050565b7f526166666c65496d706c3a20696e76616c696420617267756d656e7473000000600082015250565b60006128db601d83612240565b91506128e6826128a5565b602082019050919050565b6000602082019050818103600083015261290a816128ce565b9050919050565b600067ffffffffffffffff82111561292c5761292b611bfd565b5b602082029050919050565b60008151905061294681611f05565b92915050565b600061295f61295a84612911565b611c5d565b9050806020840283018581111561297957612978611ca4565b5b835b818110156129a2578061298e8882612937565b84526020840193505060208101905061297b565b5050509392505050565b600082601f8301126129c1576129c0611be7565b5b60146129ce84828561294c565b91505092915050565b600061028082840312156129ee576129ed611b50565b5b60006129fc848285016129ac565b91505092915050565b600069ffffffffffffffffffff82169050919050565b612a2481612a05565b8114612a2f57600080fd5b50565b600081519050612a4181612a1b565b92915050565b6000819050919050565b612a5a81612a47565b8114612a6557600080fd5b50565b600081519050612a7781612a51565b92915050565b600080600080600060a08688031215612a9957612a98611b50565b5b6000612aa788828901612a32565b9550506020612ab888828901612a68565b9450506040612ac98882890161274c565b9350506060612ada8882890161274c565b9250506080612aeb88828901612a32565b9150509295509295909350565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612b54602683612240565b9150612b5f82612af8565b604082019050919050565b60006020820190508181036000830152612b8381612b47565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612bc0602083612240565b9150612bcb82612b8a565b602082019050919050565b60006020820190508181036000830152612bef81612bb3565b9050919050565b6000612c0182611b5a565b9150612c0c83611b5a565b925082612c1c57612c1b6125e5565b5b828206905092915050565b6000604082019050612c3c6000830185612072565b612c496020830184611bbd565b939250505056fea26469706673582212202d3c3bf70511180ef4912225b95dfded620a33a9306f64c9eed98e61c1f1c04664736f6c6343000813003300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000ee9f2375b4bdf6387aa8265dd4fb8f16512a1d46000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000000000000000000000000000000000000000000038af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000002c1000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000076b0000000000000000000000000000000000000000000000000000000000002724000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000075300000000000000000000000000000000000000000000000000000000000003a980000000000000000000000000000000000000000000000000000000000001b580000000000000000000000000000000000000000000000000000000000000dac00000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101d15760003560e01c8063724e78da116100f7578063b0fb162f11610095578063e09b2a6211610064578063e09b2a621461061a578063ea7b4f7714610645578063f2fde38b1461066e578063fe56f5a014610697576101d8565b8063b0fb162f14610586578063b4ba7d36146105b1578063c1756a2c146105c8578063c4076876146105f1576101d8565b806381326c4e116100d157806381326c4e146104ca57806388e814e6146105075780638da5cb5b14610532578063985447101461055d576101d8565b8063724e78da1461045f5780637ccfd7fc146104885780637dae059a146104b3576101d8565b80634d827e081161016f578063649677e11161013e578063649677e1146103b5578063694c49be146103e05780636cab5e5b1461041d578063715018a614610448576101d8565b80634d827e0814610318578063536b24c91461033457806361728f391461035f578063646f22c51461038a576101d8565b80631fe543e3116101ab5780631fe543e31461026e57806324f7469714610297578063328169ad146102c257806347535d7b146102ed576101d8565b806309c1ba2e146101dd5780631bb43646146102085780631f564a4514610231576101d8565b366101d857005b600080fd5b3480156101e957600080fd5b506101f26106c0565b6040516101ff9190611b2b565b60405180910390f35b34801561021457600080fd5b5061022f600480360381019061022a9190611b90565b6106da565b005b34801561023d57600080fd5b5061025860048036038101906102539190611b90565b610730565b6040516102659190611bcc565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190611d40565b610754565b005b3480156102a357600080fd5b506102ac610814565b6040516102b99190611dbb565b60405180910390f35b3480156102ce57600080fd5b506102d761081b565b6040516102e49190611eb3565b60405180910390f35b3480156102f957600080fd5b50610302610886565b60405161030f9190611eea565b60405180910390f35b610332600480360381019061032d9190611f31565b610899565b005b34801561034057600080fd5b50610349610fe5565b6040516103569190611bcc565b60405180910390f35b34801561036b57600080fd5b50610374610feb565b6040516103819190611f77565b60405180910390f35b34801561039657600080fd5b5061039f610ff1565b6040516103ac9190612050565b60405180910390f35b3480156103c157600080fd5b506103ca611049565b6040516103d79190611bcc565b60405180910390f35b3480156103ec57600080fd5b5061040760048036038101906104029190611b90565b61104f565b6040516104149190611bcc565b60405180910390f35b34801561042957600080fd5b506104326110ce565b60405161043f9190611bcc565b60405180910390f35b34801561045457600080fd5b5061045d6110d4565b005b34801561046b57600080fd5b5061048660048036038101906104819190611f31565b6110e8565b005b34801561049457600080fd5b5061049d6111a3565b6040516104aa9190611dbb565b60405180910390f35b3480156104bf57600080fd5b506104c86111a8565b005b3480156104d657600080fd5b506104f160048036038101906104ec9190611b90565b6111cd565b6040516104fe9190612081565b60405180910390f35b34801561051357600080fd5b5061051c611200565b6040516105299190611eb3565b60405180910390f35b34801561053e57600080fd5b5061054761129d565b6040516105549190612081565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906120c8565b6112c6565b005b34801561059257600080fd5b5061059b61131d565b6040516105a89190612112565b60405180910390f35b3480156105bd57600080fd5b506105c6611341565b005b3480156105d457600080fd5b506105ef60048036038101906105ea919061212d565b611366565b005b3480156105fd57600080fd5b506106186004803603810190610613919061212d565b61141f565b005b34801561062657600080fd5b5061062f611583565b60405161063c91906121cc565b60405180910390f35b34801561065157600080fd5b5061066c60048036038101906106679190612213565b6115a7565b005b34801561067a57600080fd5b5061069560048036038101906106909190611f31565b611628565b005b3480156106a357600080fd5b506106be60048036038101906106b99190611b90565b6116ab565b005b600c60009054906101000a900467ffffffffffffffff1681565b6106e2611700565b6103e88110610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071d9061229d565b60405180910390fd5b8060088190555050565b6005818154811061074057600080fd5b906000526020600020016000915090505481565b7f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080657337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096040517f1cf993f40000000000000000000000000000000000000000000000000000000081526004016107fd9291906122bd565b60405180910390fd5b610810828261177e565b5050565b62061a8081565b610823611ae5565b60001515600660009054906101000a900460ff16151514610879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087090612332565b60405180910390fd5b610881611200565b905090565b600660009054906101000a900460ff1681565b600660009054906101000a900460ff166108e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108df9061239e565b60405180910390fd5b60015434101561092d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092490612430565b60405180910390fd5b600060025411610972576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610969906124c2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d790612554565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015610aa85750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15610b2c5780600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b600073ffffffffffffffffffffffffffffffffffffffff16600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610d80576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e8600854600154610c4a91906125a3565b610c549190612614565b604051610c6090612676565b60006040518083038185875af1925050503d8060008114610c9d576040519150601f19603f3d011682016040523d82523d6000602084013e610ca2565b606091505b505090508015610d7e57600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fc7dde075d320ffe9e9ba5748acbfa47ebbbb1a54ca5486ce0cc1ef006ddf9d2a42336001546103e8600854600154610d5b91906125a3565b610d659190612614565b604051610d75949392919061268b565b60405180910390a25b505b600260008154610d8f906126d0565b919050819055506000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30600b54600c60009054906101000a900467ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000362061a8060016040518663ffffffff1660e01b8152600401610e379594939291906126f9565b6020604051808303816000875af1158015610e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7a9190612761565b905033600d600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600154341115610f935760003373ffffffffffffffffffffffffffffffffffffffff1660015434610eff919061278e565b604051610f0b90612676565b60006040518083038185875af1925050503d8060008114610f48576040519150601f19603f3d011682016040523d82523d6000602084013e610f4d565b606091505b5050905080610f91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f889061280e565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff167f189155e729161d41c9756b8f023ae2bcb16166eb447c05edd79b57f5c29f19e382604051610fd99190611bcc565b60405180910390a25050565b60085481565b600b5481565b6060600480548060200260200160405190810160405280929190818152602001828054801561103f57602002820191906000526020600020905b81548152602001906001019080831161102b575b5050505050905090565b60015481565b600080600090505b6005805490508110156110c35782600582815481106110795761107861282e565b5b9060005260206000200154036110b0576004818154811061109d5761109c61282e565b5b90600052602060002001549150506110c9565b80806110bb9061285d565b915050611057565b50600090505b919050565b60025481565b6110dc611700565b6110e66000611919565b565b6110f0611700565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361115f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611156906128f1565b60405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600181565b6111b0611700565b6000600660006101000a81548160ff021916908315150217905550565b600d6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611208611ae5565b7f000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb73ffffffffffffffffffffffffffffffffffffffff166388e814e66040518163ffffffff1660e01b815260040161028060405180830381865afa158015611274573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129891906129d7565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112ce611700565b6000801b8103611313576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130a906128f1565b60405180910390fd5b80600b8190555050565b7f000000000000000000000000000000000000000000000000000000000000000381565b611349611700565b6001600660006101000a81548160ff021916908315150217905550565b61136e611700565b60008273ffffffffffffffffffffffffffffffffffffffff168260405161139490612676565b60006040518083038185875af1925050503d80600081146113d1576040519150601f19603f3d011682016040523d82523d6000602084013e6113d6565b606091505b505090508061141a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114119061280e565b60405180910390fd5b505050565b611427611700565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ba9190612a7d565b505050915050600081836114ce91906125a3565b905060008473ffffffffffffffffffffffffffffffffffffffff16826040516114f690612676565b60006040518083038185875af1925050503d8060008114611533576040519150601f19603f3d011682016040523d82523d6000602084013e611538565b606091505b505090508061157c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115739061280e565b60405180910390fd5b5050505050565b7f000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb81565b6115af611700565b60008167ffffffffffffffff16036115fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f3906128f1565b60405180910390fd5b80600c60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b611630611700565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169690612b6a565b60405180910390fd5b6116a881611919565b50565b6116b3611700565b600081036116f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ed906128f1565b60405180910390fd5b8060018190555050565b6117086119dd565b73ffffffffffffffffffffffffffffffffffffffff1661172661129d565b73ffffffffffffffffffffffffffffffffffffffff161461177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177390612bd6565b60405180910390fd5b565b6000600354826000815181106117975761179661282e565b5b60200260200101516117a99190612bf6565b90506003600081546117ba906126d0565b919050819055506000600d600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000611804836119e5565b905060006005828154811061181c5761181b61282e565b5b9060005260206000200154905060007f000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb73ffffffffffffffffffffffffffffffffffffffff166340c10f1985846040518363ffffffff1660e01b8152600401611886929190612c27565b6020604051808303816000875af11580156118a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c99190612761565b905080828573ffffffffffffffffffffffffffffffffffffffff167f583f2b104ddadb04015734001b634e73a2cd12f3beccb23ad14d2df0ab279dcf60405160405180910390a450505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080600480549050905060006001826119ff919061278e565b905060005b82811015611ada57600060048281548110611a2257611a2161282e565b5b90600052602060002001540315611ac7578460048281548110611a4857611a4761282e565b5b90600052602060002001541015611a8a5760048181548110611a6d57611a6c61282e565b5b906000526020600020015485611a83919061278e565b9450611ac6565b80915060048181548110611aa157611aa061282e565b5b906000526020600020016000815480929190611abc906126d0565b9190505550611ada565b5b8080611ad29061285d565b915050611a04565b508092505050919050565b604051806102800160405280601490602082028036833780820191505090505090565b600067ffffffffffffffff82169050919050565b611b2581611b08565b82525050565b6000602082019050611b406000830184611b1c565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b611b6d81611b5a565b8114611b7857600080fd5b50565b600081359050611b8a81611b64565b92915050565b600060208284031215611ba657611ba5611b50565b5b6000611bb484828501611b7b565b91505092915050565b611bc681611b5a565b82525050565b6000602082019050611be16000830184611bbd565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c3582611bec565b810181811067ffffffffffffffff82111715611c5457611c53611bfd565b5b80604052505050565b6000611c67611b46565b9050611c738282611c2c565b919050565b600067ffffffffffffffff821115611c9357611c92611bfd565b5b602082029050602081019050919050565b600080fd5b6000611cbc611cb784611c78565b611c5d565b90508083825260208201905060208402830185811115611cdf57611cde611ca4565b5b835b81811015611d085780611cf48882611b7b565b845260208401935050602081019050611ce1565b5050509392505050565b600082601f830112611d2757611d26611be7565b5b8135611d37848260208601611ca9565b91505092915050565b60008060408385031215611d5757611d56611b50565b5b6000611d6585828601611b7b565b925050602083013567ffffffffffffffff811115611d8657611d85611b55565b5b611d9285828601611d12565b9150509250929050565b600063ffffffff82169050919050565b611db581611d9c565b82525050565b6000602082019050611dd06000830184611dac565b92915050565b600060149050919050565b600081905092915050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611e2182611df6565b9050919050565b611e3181611e16565b82525050565b6000611e438383611e28565b60208301905092915050565b6000602082019050919050565b611e6581611dd6565b611e6f8184611de1565b9250611e7a82611dec565b8060005b83811015611eab578151611e928782611e37565b9650611e9d83611e4f565b925050600181019050611e7e565b505050505050565b600061028082019050611ec96000830184611e5c565b92915050565b60008115159050919050565b611ee481611ecf565b82525050565b6000602082019050611eff6000830184611edb565b92915050565b611f0e81611e16565b8114611f1957600080fd5b50565b600081359050611f2b81611f05565b92915050565b600060208284031215611f4757611f46611b50565b5b6000611f5584828501611f1c565b91505092915050565b6000819050919050565b611f7181611f5e565b82525050565b6000602082019050611f8c6000830184611f68565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611fc781611b5a565b82525050565b6000611fd98383611fbe565b60208301905092915050565b6000602082019050919050565b6000611ffd82611f92565b6120078185611f9d565b935061201283611fae565b8060005b8381101561204357815161202a8882611fcd565b975061203583611fe5565b925050600181019050612016565b5085935050505092915050565b6000602082019050818103600083015261206a8184611ff2565b905092915050565b61207b81611e16565b82525050565b60006020820190506120966000830184612072565b92915050565b6120a581611f5e565b81146120b057600080fd5b50565b6000813590506120c28161209c565b92915050565b6000602082840312156120de576120dd611b50565b5b60006120ec848285016120b3565b91505092915050565b600061ffff82169050919050565b61210c816120f5565b82525050565b60006020820190506121276000830184612103565b92915050565b6000806040838503121561214457612143611b50565b5b600061215285828601611f1c565b925050602061216385828601611b7b565b9150509250929050565b6000819050919050565b600061219261218d61218884611df6565b61216d565b611df6565b9050919050565b60006121a482612177565b9050919050565b60006121b682612199565b9050919050565b6121c6816121ab565b82525050565b60006020820190506121e160008301846121bd565b92915050565b6121f081611b08565b81146121fb57600080fd5b50565b60008135905061220d816121e7565b92915050565b60006020828403121561222957612228611b50565b5b6000612237848285016121fe565b91505092915050565b600082825260208201905092915050565b7f526166666c65496d706c3a20746f6f2062696720736861726500000000000000600082015250565b6000612287601983612240565b915061229282612251565b602082019050919050565b600060208201905081810360008301526122b68161227a565b9050919050565b60006040820190506122d26000830185612072565b6122df6020830184612072565b9392505050565b7f526166666c65496d706c3a20726166666c65206e6f742073746f707065640000600082015250565b600061231c601e83612240565b9150612327826122e6565b602082019050919050565b6000602082019050818103600083015261234b8161230f565b9050919050565b7f526166666c65496d706c3a20726166666c6520697320636c6f73656400000000600082015250565b6000612388601c83612240565b915061239382612352565b602082019050919050565b600060208201905081810360008301526123b78161237b565b9050919050565b7f526166666c65496d706c3a206e6f7420656e6f7567682065746865722073656e60008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b600061241a602183612240565b9150612425826123be565b604082019050919050565b600060208201905081810360008301526124498161240d565b9050919050565b7f526166666c65496d706c3a20416c6c20706f736974696f6e732061726520636c60008201527f6f73656400000000000000000000000000000000000000000000000000000000602082015250565b60006124ac602483612240565b91506124b782612450565b604082019050919050565b600060208201905081810360008301526124db8161249f565b9050919050565b7f526166666c65496d706c3a205265666665726572206973206d73672e73656e6460008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061253e602283612240565b9150612549826124e2565b604082019050919050565b6000602082019050818103600083015261256d81612531565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006125ae82611b5a565b91506125b983611b5a565b92508282026125c781611b5a565b915082820484148315176125de576125dd612574565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061261f82611b5a565b915061262a83611b5a565b92508261263a576126396125e5565b5b828204905092915050565b600081905092915050565b50565b6000612660600083612645565b915061266b82612650565b600082019050919050565b600061268182612653565b9150819050919050565b60006080820190506126a06000830187611bbd565b6126ad6020830186612072565b6126ba6040830185611bbd565b6126c76060830184611bbd565b95945050505050565b60006126db82611b5a565b9150600082036126ee576126ed612574565b5b600182039050919050565b600060a08201905061270e6000830188611f68565b61271b6020830187611b1c565b6127286040830186612103565b6127356060830185611dac565b6127426080830184611dac565b9695505050505050565b60008151905061275b81611b64565b92915050565b60006020828403121561277757612776611b50565b5b60006127858482850161274c565b91505092915050565b600061279982611b5a565b91506127a483611b5a565b92508282039050818111156127bc576127bb612574565b5b92915050565b7f526166666c65496d706c3a205472616e73666572206661696c65640000000000600082015250565b60006127f8601b83612240565b9150612803826127c2565b602082019050919050565b60006020820190508181036000830152612827816127eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061286882611b5a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361289a57612899612574565b5b600182019050919050565b7f526166666c65496d706c3a20696e76616c696420617267756d656e7473000000600082015250565b60006128db601d83612240565b91506128e6826128a5565b602082019050919050565b6000602082019050818103600083015261290a816128ce565b9050919050565b600067ffffffffffffffff82111561292c5761292b611bfd565b5b602082029050919050565b60008151905061294681611f05565b92915050565b600061295f61295a84612911565b611c5d565b9050806020840283018581111561297957612978611ca4565b5b835b818110156129a2578061298e8882612937565b84526020840193505060208101905061297b565b5050509392505050565b600082601f8301126129c1576129c0611be7565b5b60146129ce84828561294c565b91505092915050565b600061028082840312156129ee576129ed611b50565b5b60006129fc848285016129ac565b91505092915050565b600069ffffffffffffffffffff82169050919050565b612a2481612a05565b8114612a2f57600080fd5b50565b600081519050612a4181612a1b565b92915050565b6000819050919050565b612a5a81612a47565b8114612a6557600080fd5b50565b600081519050612a7781612a51565b92915050565b600080600080600060a08688031215612a9957612a98611b50565b5b6000612aa788828901612a32565b9550506020612ab888828901612a68565b9450506040612ac98882890161274c565b9350506060612ada8882890161274c565b9250506080612aeb88828901612a32565b9150509295509295909350565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612b54602683612240565b9150612b5f82612af8565b604082019050919050565b60006020820190508181036000830152612b8381612b47565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612bc0602083612240565b9150612bcb82612b8a565b602082019050919050565b60006020820190508181036000830152612bef81612bb3565b9050919050565b6000612c0182611b5a565b9150612c0c83611b5a565b925082612c1c57612c1b6125e5565b5b828206905092915050565b6000604082019050612c3c6000830185612072565b612c496020830184611bbd565b939250505056fea26469706673582212202d3c3bf70511180ef4912225b95dfded620a33a9306f64c9eed98e61c1f1c04664736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000ee9f2375b4bdf6387aa8265dd4fb8f16512a1d46000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000000000000000000000000000000000000000000038af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000002c1000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000076b0000000000000000000000000000000000000000000000000000000000002724000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000075300000000000000000000000000000000000000000000000000000000000003a980000000000000000000000000000000000000000000000000000000000001b580000000000000000000000000000000000000000000000000000000000000dac00000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _amounts (uint256[]): 1,2,3,4,5,10,15,40,1899,10020
Arg [1] : _sums (uint256[]): 30000,15000,7000,3500,1500,700,300,150,100,0
Arg [2] : _priceFeed (address): 0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46
Arg [3] : _ticketNft (address): 0xd08E83e2d6DB068e2a0A9cfE39E5001a790cbacB
Arg [4] : _vffCoordinatorV2 (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [5] : _requestConfirmations (uint16): 3
Arg [6] : _keyHash (bytes32): 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [7] : _subscriptionId (uint64): 705
-----Encoded View---------------
30 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [2] : 000000000000000000000000ee9f2375b4bdf6387aa8265dd4fb8f16512a1d46
Arg [3] : 000000000000000000000000d08e83e2d6db068e2a0a9cfe39e5001a790cbacb
Arg [4] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [7] : 00000000000000000000000000000000000000000000000000000000000002c1
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [14] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [15] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000028
Arg [17] : 000000000000000000000000000000000000000000000000000000000000076b
Arg [18] : 0000000000000000000000000000000000000000000000000000000000002724
Arg [19] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [20] : 0000000000000000000000000000000000000000000000000000000000007530
Arg [21] : 0000000000000000000000000000000000000000000000000000000000003a98
Arg [22] : 0000000000000000000000000000000000000000000000000000000000001b58
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000dac
Arg [24] : 00000000000000000000000000000000000000000000000000000000000005dc
Arg [25] : 00000000000000000000000000000000000000000000000000000000000002bc
Arg [26] : 000000000000000000000000000000000000000000000000000000000000012c
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000096
Arg [28] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [29] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.