Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 209,139 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Coin Flip_Play | 65199482 | 13 hrs ago | IN | 2.06329841 POL | 0.00900847 | ||||
Coin Flip_Play | 65199459 | 13 hrs ago | IN | 1.06329841 POL | 0.00900847 | ||||
Coin Flip_Play | 65199437 | 13 hrs ago | IN | 1.06329841 POL | 0.00966795 | ||||
Coin Flip_Play | 65199421 | 13 hrs ago | IN | 1.06329841 POL | 0.00966795 | ||||
Coin Flip_Play | 65199400 | 13 hrs ago | IN | 1.06329841 POL | 0.00966795 | ||||
Coin Flip_Play | 65189280 | 19 hrs ago | IN | 50.06376776 POL | 0.00966835 | ||||
Coin Flip_Play | 65189148 | 19 hrs ago | IN | 100.06376776 POL | 0.00966835 | ||||
Coin Flip_Play | 65188836 | 19 hrs ago | IN | 83.85302745 POL | 0.00884777 | ||||
Coin Flip_Play | 65188757 | 19 hrs ago | IN | 37.06302745 POL | 0.00884777 | ||||
Coin Flip_Play | 65186940 | 20 hrs ago | IN | 34.9857242 POL | 0.0100712 | ||||
Coin Flip_Play | 65186855 | 20 hrs ago | IN | 54.32572419 POL | 0.0100712 | ||||
Coin Flip_Play | 65186684 | 21 hrs ago | IN | 58.6957242 POL | 0.0100712 | ||||
Coin Flip_Play | 65185234 | 21 hrs ago | IN | 106.06595495 POL | 0.0100712 | ||||
Coin Flip_Play | 65185127 | 21 hrs ago | IN | 108.06595495 POL | 0.0100712 | ||||
Coin Flip_Play | 65184794 | 22 hrs ago | IN | 53.06595495 POL | 0.0100712 | ||||
Coin Flip_Play | 65184413 | 22 hrs ago | IN | 33.06595495 POL | 0.0100712 | ||||
Coin Flip_Play | 65184065 | 22 hrs ago | IN | 33.06619162 POL | 0.0100712 | ||||
Coin Flip_Play | 65183920 | 22 hrs ago | IN | 33.06619162 POL | 0.0100712 | ||||
Coin Flip_Play | 65183730 | 22 hrs ago | IN | 22.06619162 POL | 0.0100712 | ||||
Coin Flip_Play | 65159947 | 37 hrs ago | IN | 0.11151272 POL | 0.02248716 | ||||
Coin Flip_Play | 65159919 | 37 hrs ago | IN | 0.11529507 POL | 0.02343214 | ||||
Coin Flip_Play | 65159892 | 37 hrs ago | IN | 0.11349408 POL | 0.02298218 | ||||
Coin Flip_Play | 65159875 | 37 hrs ago | IN | 0.11916672 POL | 0.02439944 | ||||
Coin Flip_Play | 65159860 | 37 hrs ago | IN | 0.11395442 POL | 0.02309719 | ||||
Coin Flip_Play | 65159839 | 37 hrs ago | IN | 0.11411856 POL | 0.02313731 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
65199488 | 13 hrs ago | 2 POL | ||||
65199482 | 13 hrs ago | 0.01265968 POL | ||||
65199467 | 13 hrs ago | 1 POL | ||||
65199459 | 13 hrs ago | 0.01265968 POL | ||||
65199445 | 13 hrs ago | 1 POL | ||||
65199437 | 13 hrs ago | 0.01265968 POL | ||||
65199429 | 13 hrs ago | 1 POL | ||||
65199421 | 13 hrs ago | 0.01265968 POL | ||||
65199408 | 13 hrs ago | 1 POL | ||||
65199400 | 13 hrs ago | 0.01265968 POL | ||||
65189288 | 19 hrs ago | 50 POL | ||||
65189280 | 19 hrs ago | 0.01275355 POL | ||||
65189153 | 19 hrs ago | 100 POL | ||||
65189148 | 19 hrs ago | 0.01275355 POL | ||||
65188844 | 19 hrs ago | 83.79 POL | ||||
65188836 | 19 hrs ago | 0.01260549 POL | ||||
65188764 | 19 hrs ago | 37 POL | ||||
65188757 | 19 hrs ago | 0.01260549 POL | ||||
65186947 | 20 hrs ago | 34.92 POL | ||||
65186940 | 20 hrs ago | 0.01314484 POL | ||||
65186863 | 20 hrs ago | 54.26 POL | ||||
65186855 | 20 hrs ago | 0.01314483 POL | ||||
65186690 | 21 hrs ago | 58.63 POL | ||||
65186684 | 21 hrs ago | 0.01314484 POL | ||||
65185241 | 21 hrs ago | 106 POL |
Loading...
Loading
Contract Name:
CoinFlip
Compiler Version
v0.8.11+commit.d7f03943
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "./Common.sol"; /** * @title Coin Flip game, players predict if outcome will be heads or tails */ contract CoinFlip is Common { using SafeERC20 for IERC20; constructor( address _bankroll, address _vrf, address link_eth_feed, address _forwarder ) { Bankroll = IBankRoll(_bankroll); IChainLinkVRF = IVRFCoordinatorV2(_vrf); LINK_ETH_FEED = AggregatorV3Interface(link_eth_feed); ChainLinkVRF = _vrf; _trustedForwarder = _forwarder; } struct CoinFlipGame { uint256 wager; uint256 stopGain; uint256 stopLoss; uint256 requestID; address tokenAddress; uint64 blockNumber; uint32 numBets; bool isHeads; } mapping(address => CoinFlipGame) coinFlipGames; mapping(uint256 => address) coinIDs; /** * @dev event emitted at the start of the game * @param playerAddress address of the player that made the bet * @param wager wagered amount * @param tokenAddress address of token the wager was made, 0 address is considered the native coin * @param isHeads player bet on which side the coin will land 1-> Heads, 0 ->Tails * @param numBets number of bets the player intends to make * @param stopGain gain value at which the betting stop if a gain is reached * @param stopLoss loss value at which the betting stop if a loss is reached */ event CoinFlip_Play_Event( address indexed playerAddress, uint256 wager, address tokenAddress, bool isHeads, uint32 numBets, uint256 stopGain, uint256 stopLoss, uint256 VRFFee ); /** * @dev event emitted by the VRF callback with the bet results * @param playerAddress address of the player that made the bet * @param wager wager amount * @param payout total payout transfered to the player * @param tokenAddress address of token the wager was made and payout, 0 address is considered the native coin * @param coinOutcomes results of coinFlip, 1-> Heads, 0 ->Tails * @param payouts individual payouts for each bet * @param numGames number of games performed */ event CoinFlip_Outcome_Event( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, uint8[] coinOutcomes, uint256[] payouts, uint32 numGames ); /** * @dev event emitted when a refund is done in coin flip * @param player address of the player reciving the refund * @param wager amount of wager that was refunded * @param tokenAddress address of token the refund was made in */ event CoinFlip_Refund_Event( address indexed player, uint256 wager, address tokenAddress ); error WagerAboveLimit(uint256 wager, uint256 maxWager); error AwaitingVRF(uint256 requestID); error InvalidNumBets(uint256 maxNumBets); error NotAwaitingVRF(); error BlockNumberTooLow(uint256 have, uint256 want); error OnlyCoordinatorCanFulfill(address have, address want); /** * @dev function to get current request player is await from VRF, returns 0 if none * @param player address of the player to get the state */ function CoinFlip_GetState( address player ) external view returns (CoinFlipGame memory) { return (coinFlipGames[player]); } /** * @dev Function to play Coin Flip, takes the user wager saves bet parameters and makes a request to the VRF * @param wager wager amount * @param tokenAddress address of token to bet, 0 address is considered the native coin * @param numBets number of bets to make, and amount of random numbers to request * @param stopGain treshold value at which the bets stop if a certain profit is obtained * @param stopLoss treshold value at which the bets stop if a certain loss is obtained * @param isHeads if bet selected heads or Tails */ function CoinFlip_Play( uint256 wager, address tokenAddress, bool isHeads, uint32 numBets, uint256 stopGain, uint256 stopLoss ) external payable nonReentrant { address msgSender = _msgSender(); if (coinFlipGames[msgSender].requestID != 0) { revert AwaitingVRF(coinFlipGames[msgSender].requestID); } if (!(numBets > 0 && numBets <= 100)) { revert InvalidNumBets(100); } _kellyWager(wager, tokenAddress); uint256 fee = _transferWager( tokenAddress, wager * numBets, 1000000, msgSender ); uint256 id = _requestRandomWords(numBets); coinFlipGames[msgSender] = CoinFlipGame( wager, stopGain, stopLoss, id, tokenAddress, uint64(block.number), numBets, isHeads ); coinIDs[id] = msgSender; emit CoinFlip_Play_Event( msgSender, wager, tokenAddress, isHeads, numBets, stopGain, stopLoss, fee ); } /** * @dev Function to refund user in case of VRF request failling */ function CoinFlip_Refund() external nonReentrant { address msgSender = _msgSender(); CoinFlipGame storage game = coinFlipGames[msgSender]; if (game.requestID == 0) { revert NotAwaitingVRF(); } if (game.blockNumber + BLOCK_NUMBER_REFUND + 10 > block.number) { revert BlockNumberTooLow( block.number, game.blockNumber + BLOCK_NUMBER_REFUND + 10 ); } uint256 wager = game.wager * game.numBets; address tokenAddress = game.tokenAddress; delete (coinIDs[game.requestID]); delete (coinFlipGames[msgSender]); if (tokenAddress == address(0)) { (bool success, ) = payable(msgSender).call{value: wager}(""); if (!success) { revert TransferFailed(); } } else { IERC20(tokenAddress).safeTransfer(msgSender, wager); } emit CoinFlip_Refund_Event(msgSender, wager, tokenAddress); } /** * @dev function called by Chainlink VRF with random numbers * @param requestId id provided when the request was made * @param randomWords array of random numbers */ function rawFulfillRandomWords( uint256 requestId, uint256[] memory randomWords ) external { if (msg.sender != ChainLinkVRF) { revert OnlyCoordinatorCanFulfill(msg.sender, ChainLinkVRF); } fulfillRandomWords(requestId, randomWords); } function fulfillRandomWords( uint256 requestId, uint256[] memory randomWords ) internal { address playerAddress = coinIDs[requestId]; if (playerAddress == address(0)) revert(); CoinFlipGame storage game = coinFlipGames[playerAddress]; if (block.number > game.blockNumber + BLOCK_NUMBER_REFUND) revert(); int256 totalValue; uint256 payout; uint32 i; uint8[] memory coinFlip = new uint8[](game.numBets); uint256[] memory payouts = new uint256[](game.numBets); address tokenAddress = game.tokenAddress; for (i = 0; i < game.numBets; i++) { if (totalValue >= int256(game.stopGain)) { break; } if (totalValue <= -int256(game.stopLoss)) { break; } coinFlip[i] = uint8(randomWords[i] % 2); if (coinFlip[i] == 1 && game.isHeads == true) { totalValue += int256((game.wager * 9800) / 10000); payout += (game.wager * 19800) / 10000; payouts[i] = (game.wager * 19800) / 10000; continue; } if (coinFlip[i] == 0 && game.isHeads == false) { totalValue += int256((game.wager * 9800) / 10000); payout += (game.wager * 19800) / 10000; payouts[i] = (game.wager * 19800) / 10000; continue; } totalValue -= int256(game.wager); } payout += (game.numBets - i) * game.wager; emit CoinFlip_Outcome_Event( playerAddress, game.wager, payout, tokenAddress, coinFlip, payouts, i ); _transferToBankroll(tokenAddress, game.wager * game.numBets); delete (coinIDs[requestId]); delete (coinFlipGames[playerAddress]); if (payout != 0) { _transferPayout(playerAddress, payout, tokenAddress); } } /** * @dev calculates the maximum wager allowed based on the bankroll size */ function _kellyWager(uint256 wager, address tokenAddress) internal view { uint256 balance; if (tokenAddress == address(0)) { balance = address(Bankroll).balance; } else { balance = IERC20(tokenAddress).balanceOf(address(Bankroll)); } uint256 maxWager = (balance * 1122448) / 100000000; if (wager > maxWager) { revert WagerAboveLimit(wager, maxWager); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; //import "hardhat/console.sol"; interface IBankRoll { function getIsGame(address game) external view returns (bool); function getIsValidWager( address game, address tokenAddress ) external view returns (bool); function transferPayout( address player, uint256 payout, address token ) external; function getOwner() external view returns (address); function isPlayerSuspended( address player ) external view returns (bool, uint256); } interface IVRFCoordinatorV2 is VRFCoordinatorV2Interface { function getFeeConfig() external view returns ( uint32, uint32, uint32, uint32, uint32, uint24, uint24, uint24, uint24 ); } contract Common is ReentrancyGuard { using SafeERC20 for IERC20; uint256 public VRFFees; address public ChainLinkVRF; address public _trustedForwarder; uint64 constant BLOCK_NUMBER_REFUND = 1000; AggregatorV3Interface public LINK_ETH_FEED; IVRFCoordinatorV2 public IChainLinkVRF; IBankRoll public Bankroll; error NotApprovedBankroll(); error InvalidValue(uint256 required, uint256 sent); error TransferFailed(); error RefundFailed(); error NotOwner(address want, address have); error ZeroWager(); error PlayerSuspended(uint256 suspensionTime); /** * @dev function to transfer the player wager to bankroll, and charge for VRF fee * , reverts if bankroll doesn't approve game or token * @param tokenAddress address of the token the wager is made on * @param wager total amount wagered */ function _transferWager( address tokenAddress, uint256 wager, uint256 gasAmount, address msgSender ) internal returns (uint256 VRFfee) { if (!Bankroll.getIsValidWager(address(this), tokenAddress)) { revert NotApprovedBankroll(); } if (wager == 0) { revert ZeroWager(); } (bool suspended, uint256 suspendedTime) = Bankroll.isPlayerSuspended( msgSender ); if (suspended) { revert PlayerSuspended(suspendedTime); } VRFfee = getVRFFee(gasAmount); if (tokenAddress == address(0)) { if (msg.value < wager + VRFfee) { revert InvalidValue(wager + VRFfee, msg.value); } _refundExcessValue(msg.value - (VRFfee + wager)); } else { if (msg.value < VRFfee) { revert InvalidValue(VRFfee, msg.value); } IERC20(tokenAddress).safeTransferFrom( msgSender, address(this), wager ); _refundExcessValue(msg.value - VRFfee); } VRFFees += VRFfee; } /** * @dev function to transfer the wager held by the game contract to the bankroll * @param tokenAddress address of the token to transfer * @param amount token amount to transfer */ function _transferToBankroll( address tokenAddress, uint256 amount ) internal { if (tokenAddress == address(0)) { (bool success, ) = payable(address(Bankroll)).call{value: amount}( "" ); if (!success) { revert RefundFailed(); } } else { IERC20(tokenAddress).safeTransfer(address(Bankroll), amount); } } /** * @dev calculates in form of native token the fee charged by chainlink VRF * @return fee amount of fee user has to pay */ function getVRFFee(uint256 gasAmount) public view returns (uint256 fee) { (, int256 answer, , , ) = LINK_ETH_FEED.latestRoundData(); (uint32 fulfillmentFlatFeeLinkPPMTier1, , , , , , , , ) = IChainLinkVRF .getFeeConfig(); fee = tx.gasprice * (gasAmount) + ((1e12 * uint256(fulfillmentFlatFeeLinkPPMTier1) * uint256(answer)) / 1e18); } /** * @dev returns to user the excess fee sent to pay for the VRF * @param refund amount to send back to user */ function _refundExcessValue(uint256 refund) internal { if (refund == 0) { return; } (bool success, ) = payable(msg.sender).call{value: refund}(""); if (!success) { revert RefundFailed(); } } /** * @dev function to charge user for VRF */ function _payVRFFee(uint256 gasAmount) internal returns (uint256 VRFfee) { VRFfee = getVRFFee(gasAmount); if (msg.value < VRFfee) { revert InvalidValue(VRFfee, msg.value); } _refundExcessValue(msg.value - VRFfee); VRFFees += VRFfee; } /** * @dev function to transfer VRF fees acumulated in the contract to the Bankroll * Can only be called by owner */ function transferFees(address to) external nonReentrant { if (msg.sender != Bankroll.getOwner()) { revert NotOwner(Bankroll.getOwner(), msg.sender); } uint256 fee = VRFFees; VRFFees = 0; (bool success, ) = payable(address(to)).call{value: fee}(""); if (!success) { revert TransferFailed(); } } /** * @dev function to transfer wager to game contract, without charging for VRF * @param tokenAddress tokenAddress the wager is made on * @param wager wager amount */ function _transferWagerPvPNoVRF( address tokenAddress, uint256 wager ) internal { if (!Bankroll.getIsValidWager(address(this), tokenAddress)) { revert NotApprovedBankroll(); } if (tokenAddress == address(0)) { if (!(msg.value == wager)) { revert InvalidValue(wager, msg.value); } } else { IERC20(tokenAddress).safeTransferFrom( msg.sender, address(this), wager ); } } /** * @dev function to transfer wager to game contract, including charge for VRF * @param tokenAddress tokenAddress the wager is made on * @param wager wager amount */ function _transferWagerPvP( address tokenAddress, uint256 wager, uint256 gasAmount ) internal { if (!Bankroll.getIsValidWager(address(this), tokenAddress)) { revert NotApprovedBankroll(); } uint256 VRFfee = getVRFFee(gasAmount); if (tokenAddress == address(0)) { if (msg.value < wager + VRFfee) { revert InvalidValue(wager, msg.value); } _refundExcessValue(msg.value - (VRFfee + wager)); } else { if (msg.value < VRFfee) { revert InvalidValue(VRFfee, msg.value); } IERC20(tokenAddress).safeTransferFrom( msg.sender, address(this), wager ); _refundExcessValue(msg.value - VRFfee); } VRFFees += VRFfee; } /** * @dev transfers payout from the game contract to the players * @param player address of the player to transfer the payout to * @param payout amount of payout to transfer * @param tokenAddress address of the token that payout will be transfered */ function _transferPayoutPvP( address player, uint256 payout, address tokenAddress ) internal { if (tokenAddress == address(0)) { (bool success, ) = payable(player).call{value: payout}(""); if (!success) { revert TransferFailed(); } } else { IERC20(tokenAddress).safeTransfer(player, payout); } } /** * @dev transfers house edge from game contract to bankroll * @param amount amount to transfer * @param tokenAddress address of token to transfer */ function _transferHouseEdgePvP( uint256 amount, address tokenAddress ) internal { if (tokenAddress == address(0)) { (bool success, ) = payable(address(Bankroll)).call{value: amount}( "" ); if (!success) { revert TransferFailed(); } } else { IERC20(tokenAddress).safeTransfer(address(Bankroll), amount); } } /** * @dev function to request bankroll to give payout to player * @param player address of the player * @param payout amount of payout to give * @param tokenAddress address of the token in which to give the payout */ function _transferPayout( address player, uint256 payout, address tokenAddress ) internal { Bankroll.transferPayout(player, payout, tokenAddress); } /** * @dev function to send the request for randomness to chainlink * @param numWords number of random numbers required */ function _requestRandomWords( uint32 numWords ) internal returns (uint256 s_requestId) { s_requestId = VRFCoordinatorV2Interface(ChainLinkVRF) .requestRandomWords( 0xd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8, 576, 3, 2500000, numWords ); } function isTrustedForwarder(address forwarder) public view returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view returns (address ret) { if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { // At this point we know that the sender is a trusted forwarder, // so we trust that the last bytes of msg.data are the verified sender address. // extract sender address from the end of msg.data assembly { ret := shr(96, calldataload(sub(calldatasize(), 20))) } } else { ret = msg.sender; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// 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.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 // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (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); } } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_bankroll","type":"address"},{"internalType":"address","name":"_vrf","type":"address"},{"internalType":"address","name":"link_eth_feed","type":"address"},{"internalType":"address","name":"_forwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"requestID","type":"uint256"}],"name":"AwaitingVRF","type":"error"},{"inputs":[{"internalType":"uint256","name":"have","type":"uint256"},{"internalType":"uint256","name":"want","type":"uint256"}],"name":"BlockNumberTooLow","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxNumBets","type":"uint256"}],"name":"InvalidNumBets","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"sent","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"NotApprovedBankroll","type":"error"},{"inputs":[],"name":"NotAwaitingVRF","type":"error"},{"inputs":[{"internalType":"address","name":"want","type":"address"},{"internalType":"address","name":"have","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"inputs":[{"internalType":"uint256","name":"suspensionTime","type":"uint256"}],"name":"PlayerSuspended","type":"error"},{"inputs":[],"name":"RefundFailed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"wager","type":"uint256"},{"internalType":"uint256","name":"maxWager","type":"uint256"}],"name":"WagerAboveLimit","type":"error"},{"inputs":[],"name":"ZeroWager","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"playerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"wager","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint8[]","name":"coinOutcomes","type":"uint8[]"},{"indexed":false,"internalType":"uint256[]","name":"payouts","type":"uint256[]"},{"indexed":false,"internalType":"uint32","name":"numGames","type":"uint32"}],"name":"CoinFlip_Outcome_Event","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"playerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"wager","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"isHeads","type":"bool"},{"indexed":false,"internalType":"uint32","name":"numBets","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"stopGain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stopLoss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"VRFFee","type":"uint256"}],"name":"CoinFlip_Play_Event","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"wager","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"CoinFlip_Refund_Event","type":"event"},{"inputs":[],"name":"Bankroll","outputs":[{"internalType":"contract IBankRoll","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ChainLinkVRF","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"CoinFlip_GetState","outputs":[{"components":[{"internalType":"uint256","name":"wager","type":"uint256"},{"internalType":"uint256","name":"stopGain","type":"uint256"},{"internalType":"uint256","name":"stopLoss","type":"uint256"},{"internalType":"uint256","name":"requestID","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint64","name":"blockNumber","type":"uint64"},{"internalType":"uint32","name":"numBets","type":"uint32"},{"internalType":"bool","name":"isHeads","type":"bool"}],"internalType":"struct CoinFlip.CoinFlipGame","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wager","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isHeads","type":"bool"},{"internalType":"uint32","name":"numBets","type":"uint32"},{"internalType":"uint256","name":"stopGain","type":"uint256"},{"internalType":"uint256","name":"stopLoss","type":"uint256"}],"name":"CoinFlip_Play","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"CoinFlip_Refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"IChainLinkVRF","outputs":[{"internalType":"contract IVRFCoordinatorV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LINK_ETH_FEED","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VRFFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_trustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasAmount","type":"uint256"}],"name":"getVRFFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200236d3803806200236d8339810160408190526200003491620000b3565b6001600055600680546001600160a01b039586166001600160a01b031991821617909155600580549486169482168517905560048054938616938216939093179092556002805483169093179092556003805492909316911617905562000110565b80516001600160a01b0381168114620000ae57600080fd5b919050565b60008060008060808587031215620000ca57600080fd5b620000d58562000096565b9350620000e56020860162000096565b9250620000f56040860162000096565b9150620001056060860162000096565b905092959194509250565b61224d80620001206000396000f3fe6080604052600436106100d25760003560e01c80636d9747731161007f5780638d7c16d2116100595780638d7c16d214610377578063953995ea1461038d578063ad178361146103ad578063d0bcfc0c146103cd57600080fd5b80636d974773146101ca5780637df31284146101dd5780638bd161141461034957600080fd5b806356c022bb116100b057806356c022bb1461014b578063572b6c051461016b57806363dc4ef5146101aa57600080fd5b80631fe543e3146100d75780634dd189d5146100f9578063522d2c2414610136575b600080fd5b3480156100e357600080fd5b506100f76100f2366004611b9b565b6103ed565b005b34801561010557600080fd5b50600554610119906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561014257600080fd5b506100f7610459565b34801561015757600080fd5b50600354610119906001600160a01b031681565b34801561017757600080fd5b5061019a610186366004611c7a565b6003546001600160a01b0391821691161490565b604051901515815260200161012d565b3480156101b657600080fd5b506100f76101c5366004611c7a565b6106f7565b6100f76101d8366004611cbe565b6108d4565b3480156101e957600080fd5b506102cd6101f8366004611c7a565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152506001600160a01b03908116600090815260076020908152604091829020825161010081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201549283166080820152600160a01b830467ffffffffffffffff1660a0820152600160e01b90920463ffffffff1660c08301526005015460ff16151560e082015290565b60405161012d9190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526001600160a01b03608084015116608083015267ffffffffffffffff60a08401511660a083015263ffffffff60c08401511660c083015260e0830151151560e083015292915050565b34801561035557600080fd5b50610369610364366004611d23565b610c08565b60405190815260200161012d565b34801561038357600080fd5b5061036960015481565b34801561039957600080fd5b50600254610119906001600160a01b031681565b3480156103b957600080fd5b50600454610119906001600160a01b031681565b3480156103d957600080fd5b50600654610119906001600160a01b031681565b6002546001600160a01b0316331461044b576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6104558282610d69565b5050565b6104616111c7565b600061046b611221565b6001600160a01b03811660009081526007602052604090206003810154919250906104c2576040517f49050b3000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600481015443906104e7906103e890600160a01b900467ffffffffffffffff16611d52565b6104f290600a611d52565b67ffffffffffffffff1611156105775760048101544390610527906103e890600160a01b900467ffffffffffffffff16611d52565b61053290600a611d52565b6040517fb4ae675a000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff166024820152604401610442565b6004810154815460009161059991600160e01b90910463ffffffff1690611d7e565b6004808401546003808601546000908152600860209081526040808320805473ffffffffffffffffffffffffffffffffffffffff191690556001600160a01b038a8116845260079092528220828155600181018390556002810183905592830182905593820155600501805460ff19169055919250168061068e576000846001600160a01b03168360405160006040518083038185875af1925050503d8060008114610661576040519150601f19603f3d011682016040523d82523d6000602084013e610666565b606091505b5050905080610688576040516312171d8360e31b815260040160405180910390fd5b506106a2565b6106a26001600160a01b0382168584611255565b604080518381526001600160a01b0383811660208301528616917f60f5ec2f86c0cf8ae72815b61b05473a9382c1c34a74749680302b342c04138a910160405180910390a2505050506106f56001600055565b565b6106ff6111c7565b600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107769190611d9d565b6001600160a01b0316336001600160a01b03161461084957600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108059190611d9d565b6040517f23295f0e0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610442565b600180546000918290556040519091906001600160a01b0384169083908381818185875af1925050503d806000811461089e576040519150601f19603f3d011682016040523d82523d6000602084013e6108a3565b606091505b50509050806108c5576040516312171d8360e31b815260040160405180910390fd5b50506108d16001600055565b50565b6108dc6111c7565b60006108e6611221565b6001600160a01b0381166000908152600760205260409020600301549091501561095d576001600160a01b038116600090815260076020526040908190206003015490517f440db96e0000000000000000000000000000000000000000000000000000000081526004810191909152602401610442565b60008463ffffffff1611801561097a575060648463ffffffff1611155b6109b3576040517f9310749100000000000000000000000000000000000000000000000000000000815260646004820152602401610442565b6109bd8787611303565b60006109dd876109d363ffffffff88168b611d7e565b620f42408561141a565b905060006109ea866116c4565b90506040518061010001604052808a8152602001868152602001858152602001828152602001896001600160a01b031681526020014367ffffffffffffffff1681526020018763ffffffff16815260200188151581525060076000856001600160a01b03166001600160a01b031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160040160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060c082015181600401601c6101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160050160006101000a81548160ff021916908315150217905550905050826008600083815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03167f9802308245dc39ec39c453355c93a84c961f728db54b5adeaad1cd29aa6f3f738a8a8a8a8a8a89604051610beb97969594939291909687526001600160a01b03959095166020870152921515604086015263ffffffff919091166060850152608084015260a083015260c082015260e00190565b60405180910390a2505050610c006001600055565b505050505050565b60048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009384936001600160a01b03169263feaf968c928183019260a0928290030181865afa158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8e9190611dd9565b5050509150506000600560009054906101000a90046001600160a01b03166001600160a01b0316635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190611e3c565b50505050505050509050670de0b6b3a7640000828263ffffffff1664e8d4a51000610d399190611d7e565b610d439190611d7e565b610d4d9190611f08565b610d57853a611d7e565b610d619190611f1c565b949350505050565b6000828152600860205260409020546001600160a01b031680610d8b57600080fd5b6001600160a01b03811660009081526007602052604090206004810154610dc6906103e890600160a01b900467ffffffffffffffff16611d52565b67ffffffffffffffff16431115610ddc57600080fd5b6004810154600090819081908190600160e01b900463ffffffff1667ffffffffffffffff811115610e0f57610e0f611b85565b604051908082528060200260200182016040528015610e38578160200160208202803683370190505b506004860154909150600090600160e01b900463ffffffff1667ffffffffffffffff811115610e6957610e69611b85565b604051908082528060200260200182016040528015610e92578160200160208202803683370190505b506004870154600094509091506001600160a01b03165b600487015463ffffffff600160e01b9091048116908516101561108d5786600101548612610ed65761108d565b8660020154610ee490611f34565b8613610eef5761108d565b6002898563ffffffff1681518110610f0957610f09611f51565b6020026020010151610f1b9190611f67565b838563ffffffff1681518110610f3357610f33611f51565b602002602001019060ff16908160ff1681525050828463ffffffff1681518110610f5f57610f5f611f51565b602002602001015160ff166001148015610f825750600587015460ff1615156001145b1561101e57865461271090610f9990612648611d7e565b610fa39190611f08565b610fad9087611f7b565b875490965061271090610fc290614d58611d7e565b610fcc9190611f08565b610fd69086611f1c565b875490955061271090610feb90614d58611d7e565b610ff59190611f08565b828563ffffffff168151811061100d5761100d611f51565b60200260200101818152505061107b565b828463ffffffff168151811061103657611036611f51565b602002602001015160ff1660001480156110555750600587015460ff16155b1561106c57865461271090610f9990612648611d7e565b86546110789087611fd3565b95505b836110858161202b565b945050610ea9565b865460048801546110ac908690600160e01b900463ffffffff1661204f565b63ffffffff166110bc9190611d7e565b6110c69086611f1c565b9450876001600160a01b03167f063ba2c91a70f945b84c24531b0de813d66f430987169cb7d878431c04cb00048860000154878487878a60405161110f96959493929190612074565b60405180910390a26004870154875461114091839161113b91600160e01b900463ffffffff1690611d7e565b611796565b60008a8152600860209081526040808320805473ffffffffffffffffffffffffffffffffffffffff191690556001600160a01b038b168352600790915281208181556001810182905560028101829055600381018290556004810191909155600501805460ff1916905584156111bb576111bb888683611832565b50505050505050505050565b6002600054141561121a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610442565b6002600055565b60006014361080159061123e57506003546001600160a01b031633145b15611250575060131936013560601c90565b503390565b6040516001600160a01b0383166024820152604481018290526112fe9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526118be565b505050565b60006001600160a01b03821661132657506006546001600160a01b0316316113b0565b6006546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152908316906370a0823190602401602060405180830381865afa158015611389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ad9190612121565b90505b60006305f5e1006113c48362112090611d7e565b6113ce9190611f08565b905080841115611414576040517fd53662aa0000000000000000000000000000000000000000000000000000000081526004810185905260248101829052604401610442565b50505050565b6006546040517fbfd7f9cc0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038681166024830152600092169063bfd7f9cc90604401602060405180830381865afa158015611484573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a8919061213a565b6114de576040517f51c3b94f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83611515576040517f07375c8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f0a5748a80000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526000928392911690630a5748a8906024016040805180830381865afa15801561157b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159f9190612157565b9150915081156115de576040517f6c2775f500000000000000000000000000000000000000000000000000000000815260048101829052602401610442565b6115e785610c08565b92506001600160a01b038716611656576116018387611f1c565b341015611635576116128387611f1c565b60405163de9b74a160e01b81526004810191909152346024820152604401610442565b6116516116428785611f1c565b61164c9034612185565b6119a3565b6116a2565b823410156116805760405163de9b74a160e01b815260048101849052346024820152604401610442565b6116956001600160a01b038816853089611a14565b6116a261164c8434612185565b82600160008282546116b49190611f1c565b9091555092979650505050505050565b6002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a86004820152610240602482015260036044820152622625a0606482015263ffffffff831660848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af115801561176c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117909190612121565b92915050565b6001600160a01b038216611818576006546040516000916001600160a01b03169083908381818185875af1925050503d80600081146117f1576040519150601f19603f3d011682016040523d82523d6000602084013e6117f6565b606091505b50509050806112fe57604051633c31275160e21b815260040160405180910390fd5b600654610455906001600160a01b03848116911683611255565b6006546040517f6c025ec20000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b1580156118a157600080fd5b505af11580156118b5573d6000803e3d6000fd5b50505050505050565b6000611913826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a659092919063ffffffff16565b8051909150156112fe5780806020019051810190611931919061213a565b6112fe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610442565b806119ab5750565b604051600090339083908381818185875af1925050503d80600081146119ed576040519150601f19603f3d011682016040523d82523d6000602084013e6119f2565b606091505b505090508061045557604051633c31275160e21b815260040160405180910390fd5b6040516001600160a01b03808516602483015283166044820152606481018290526114149085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161129a565b6060610d61848460008585600080866001600160a01b03168587604051611a8c91906121c8565b60006040518083038185875af1925050503d8060008114611ac9576040519150601f19603f3d011682016040523d82523d6000602084013e611ace565b606091505b5091509150611adf87838387611aea565b979650505050505050565b60608315611b56578251611b4f576001600160a01b0385163b611b4f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610442565b5081610d61565b610d618383815115611b6b5781518083602001fd5b8060405162461bcd60e51b815260040161044291906121e4565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215611bae57600080fd5b8235915060208084013567ffffffffffffffff80821115611bce57600080fd5b818601915086601f830112611be257600080fd5b813581811115611bf457611bf4611b85565b8060051b604051601f19603f83011681018181108582111715611c1957611c19611b85565b604052918252848201925083810185019189831115611c3757600080fd5b938501935b82851015611c5557843584529385019392850192611c3c565b8096505050505050509250929050565b6001600160a01b03811681146108d157600080fd5b600060208284031215611c8c57600080fd5b8135611c9781611c65565b9392505050565b80151581146108d157600080fd5b63ffffffff811681146108d157600080fd5b60008060008060008060c08789031215611cd757600080fd5b863595506020870135611ce981611c65565b94506040870135611cf981611c9e565b93506060870135611d0981611cac565b9598949750929560808101359460a0909101359350915050565b600060208284031215611d3557600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b600067ffffffffffffffff808316818516808303821115611d7557611d75611d3c565b01949350505050565b6000816000190483118215151615611d9857611d98611d3c565b500290565b600060208284031215611daf57600080fd5b8151611c9781611c65565b805169ffffffffffffffffffff81168114611dd457600080fd5b919050565b600080600080600060a08688031215611df157600080fd5b611dfa86611dba565b9450602086015193506040860151925060608601519150611e1d60808701611dba565b90509295509295909350565b805162ffffff81168114611dd457600080fd5b60008060008060008060008060006101208a8c031215611e5b57600080fd5b8951611e6681611cac565b60208b0151909950611e7781611cac565b60408b0151909850611e8881611cac565b60608b0151909750611e9981611cac565b60808b0151909650611eaa81611cac565b9450611eb860a08b01611e29565b9350611ec660c08b01611e29565b9250611ed460e08b01611e29565b9150611ee36101008b01611e29565b90509295985092959850929598565b634e487b7160e01b600052601260045260246000fd5b600082611f1757611f17611ef2565b500490565b60008219821115611f2f57611f2f611d3c565b500190565b6000600160ff1b821415611f4a57611f4a611d3c565b5060000390565b634e487b7160e01b600052603260045260246000fd5b600082611f7657611f76611ef2565b500690565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615611fb557611fb5611d3c565b82600160ff1b038412811615611fcd57611fcd611d3c565b50500190565b600080831283600160ff1b01831281151615611ff157611ff1611d3c565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561202557612025611d3c565b50500390565b600063ffffffff8083168181141561204557612045611d3c565b6001019392505050565b600063ffffffff8381169083168181101561206c5761206c611d3c565b039392505050565b600060c08201888352602088818501526001600160a01b038816604085015260c0606085015281875180845260e086019150828901935060005b818110156120cd57845160ff16835293830193918301916001016120ae565b50508481036080860152865180825290820192508187019060005b81811015612104578251855293830193918301916001016120e8565b50505063ffffffff851660a0850152509050979650505050505050565b60006020828403121561213357600080fd5b5051919050565b60006020828403121561214c57600080fd5b8151611c9781611c9e565b6000806040838503121561216a57600080fd5b825161217581611c9e565b6020939093015192949293505050565b60008282101561219757612197611d3c565b500390565b60005b838110156121b757818101518382015260200161219f565b838111156114145750506000910152565b600082516121da81846020870161219c565b9190910192915050565b602081526000825180602084015261220381604085016020870161219c565b601f01601f1916919091016040019291505056fea2646970667358221220c05c34f2d96b8504319645a30325c483223c6edf38d0d25c6d42e4d95edff72c64736f6c634300080b003300000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959000000000000000000000000ae975071be8f8ee67addbc1a82488f1c248580670000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9
Deployed Bytecode
0x6080604052600436106100d25760003560e01c80636d9747731161007f5780638d7c16d2116100595780638d7c16d214610377578063953995ea1461038d578063ad178361146103ad578063d0bcfc0c146103cd57600080fd5b80636d974773146101ca5780637df31284146101dd5780638bd161141461034957600080fd5b806356c022bb116100b057806356c022bb1461014b578063572b6c051461016b57806363dc4ef5146101aa57600080fd5b80631fe543e3146100d75780634dd189d5146100f9578063522d2c2414610136575b600080fd5b3480156100e357600080fd5b506100f76100f2366004611b9b565b6103ed565b005b34801561010557600080fd5b50600554610119906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561014257600080fd5b506100f7610459565b34801561015757600080fd5b50600354610119906001600160a01b031681565b34801561017757600080fd5b5061019a610186366004611c7a565b6003546001600160a01b0391821691161490565b604051901515815260200161012d565b3480156101b657600080fd5b506100f76101c5366004611c7a565b6106f7565b6100f76101d8366004611cbe565b6108d4565b3480156101e957600080fd5b506102cd6101f8366004611c7a565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152506001600160a01b03908116600090815260076020908152604091829020825161010081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201549283166080820152600160a01b830467ffffffffffffffff1660a0820152600160e01b90920463ffffffff1660c08301526005015460ff16151560e082015290565b60405161012d9190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526001600160a01b03608084015116608083015267ffffffffffffffff60a08401511660a083015263ffffffff60c08401511660c083015260e0830151151560e083015292915050565b34801561035557600080fd5b50610369610364366004611d23565b610c08565b60405190815260200161012d565b34801561038357600080fd5b5061036960015481565b34801561039957600080fd5b50600254610119906001600160a01b031681565b3480156103b957600080fd5b50600454610119906001600160a01b031681565b3480156103d957600080fd5b50600654610119906001600160a01b031681565b6002546001600160a01b0316331461044b576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6104558282610d69565b5050565b6104616111c7565b600061046b611221565b6001600160a01b03811660009081526007602052604090206003810154919250906104c2576040517f49050b3000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600481015443906104e7906103e890600160a01b900467ffffffffffffffff16611d52565b6104f290600a611d52565b67ffffffffffffffff1611156105775760048101544390610527906103e890600160a01b900467ffffffffffffffff16611d52565b61053290600a611d52565b6040517fb4ae675a000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff166024820152604401610442565b6004810154815460009161059991600160e01b90910463ffffffff1690611d7e565b6004808401546003808601546000908152600860209081526040808320805473ffffffffffffffffffffffffffffffffffffffff191690556001600160a01b038a8116845260079092528220828155600181018390556002810183905592830182905593820155600501805460ff19169055919250168061068e576000846001600160a01b03168360405160006040518083038185875af1925050503d8060008114610661576040519150601f19603f3d011682016040523d82523d6000602084013e610666565b606091505b5050905080610688576040516312171d8360e31b815260040160405180910390fd5b506106a2565b6106a26001600160a01b0382168584611255565b604080518381526001600160a01b0383811660208301528616917f60f5ec2f86c0cf8ae72815b61b05473a9382c1c34a74749680302b342c04138a910160405180910390a2505050506106f56001600055565b565b6106ff6111c7565b600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107769190611d9d565b6001600160a01b0316336001600160a01b03161461084957600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108059190611d9d565b6040517f23295f0e0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610442565b600180546000918290556040519091906001600160a01b0384169083908381818185875af1925050503d806000811461089e576040519150601f19603f3d011682016040523d82523d6000602084013e6108a3565b606091505b50509050806108c5576040516312171d8360e31b815260040160405180910390fd5b50506108d16001600055565b50565b6108dc6111c7565b60006108e6611221565b6001600160a01b0381166000908152600760205260409020600301549091501561095d576001600160a01b038116600090815260076020526040908190206003015490517f440db96e0000000000000000000000000000000000000000000000000000000081526004810191909152602401610442565b60008463ffffffff1611801561097a575060648463ffffffff1611155b6109b3576040517f9310749100000000000000000000000000000000000000000000000000000000815260646004820152602401610442565b6109bd8787611303565b60006109dd876109d363ffffffff88168b611d7e565b620f42408561141a565b905060006109ea866116c4565b90506040518061010001604052808a8152602001868152602001858152602001828152602001896001600160a01b031681526020014367ffffffffffffffff1681526020018763ffffffff16815260200188151581525060076000856001600160a01b03166001600160a01b031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160040160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060c082015181600401601c6101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160050160006101000a81548160ff021916908315150217905550905050826008600083815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03167f9802308245dc39ec39c453355c93a84c961f728db54b5adeaad1cd29aa6f3f738a8a8a8a8a8a89604051610beb97969594939291909687526001600160a01b03959095166020870152921515604086015263ffffffff919091166060850152608084015260a083015260c082015260e00190565b60405180910390a2505050610c006001600055565b505050505050565b60048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009384936001600160a01b03169263feaf968c928183019260a0928290030181865afa158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8e9190611dd9565b5050509150506000600560009054906101000a90046001600160a01b03166001600160a01b0316635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190611e3c565b50505050505050509050670de0b6b3a7640000828263ffffffff1664e8d4a51000610d399190611d7e565b610d439190611d7e565b610d4d9190611f08565b610d57853a611d7e565b610d619190611f1c565b949350505050565b6000828152600860205260409020546001600160a01b031680610d8b57600080fd5b6001600160a01b03811660009081526007602052604090206004810154610dc6906103e890600160a01b900467ffffffffffffffff16611d52565b67ffffffffffffffff16431115610ddc57600080fd5b6004810154600090819081908190600160e01b900463ffffffff1667ffffffffffffffff811115610e0f57610e0f611b85565b604051908082528060200260200182016040528015610e38578160200160208202803683370190505b506004860154909150600090600160e01b900463ffffffff1667ffffffffffffffff811115610e6957610e69611b85565b604051908082528060200260200182016040528015610e92578160200160208202803683370190505b506004870154600094509091506001600160a01b03165b600487015463ffffffff600160e01b9091048116908516101561108d5786600101548612610ed65761108d565b8660020154610ee490611f34565b8613610eef5761108d565b6002898563ffffffff1681518110610f0957610f09611f51565b6020026020010151610f1b9190611f67565b838563ffffffff1681518110610f3357610f33611f51565b602002602001019060ff16908160ff1681525050828463ffffffff1681518110610f5f57610f5f611f51565b602002602001015160ff166001148015610f825750600587015460ff1615156001145b1561101e57865461271090610f9990612648611d7e565b610fa39190611f08565b610fad9087611f7b565b875490965061271090610fc290614d58611d7e565b610fcc9190611f08565b610fd69086611f1c565b875490955061271090610feb90614d58611d7e565b610ff59190611f08565b828563ffffffff168151811061100d5761100d611f51565b60200260200101818152505061107b565b828463ffffffff168151811061103657611036611f51565b602002602001015160ff1660001480156110555750600587015460ff16155b1561106c57865461271090610f9990612648611d7e565b86546110789087611fd3565b95505b836110858161202b565b945050610ea9565b865460048801546110ac908690600160e01b900463ffffffff1661204f565b63ffffffff166110bc9190611d7e565b6110c69086611f1c565b9450876001600160a01b03167f063ba2c91a70f945b84c24531b0de813d66f430987169cb7d878431c04cb00048860000154878487878a60405161110f96959493929190612074565b60405180910390a26004870154875461114091839161113b91600160e01b900463ffffffff1690611d7e565b611796565b60008a8152600860209081526040808320805473ffffffffffffffffffffffffffffffffffffffff191690556001600160a01b038b168352600790915281208181556001810182905560028101829055600381018290556004810191909155600501805460ff1916905584156111bb576111bb888683611832565b50505050505050505050565b6002600054141561121a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610442565b6002600055565b60006014361080159061123e57506003546001600160a01b031633145b15611250575060131936013560601c90565b503390565b6040516001600160a01b0383166024820152604481018290526112fe9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526118be565b505050565b60006001600160a01b03821661132657506006546001600160a01b0316316113b0565b6006546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152908316906370a0823190602401602060405180830381865afa158015611389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ad9190612121565b90505b60006305f5e1006113c48362112090611d7e565b6113ce9190611f08565b905080841115611414576040517fd53662aa0000000000000000000000000000000000000000000000000000000081526004810185905260248101829052604401610442565b50505050565b6006546040517fbfd7f9cc0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038681166024830152600092169063bfd7f9cc90604401602060405180830381865afa158015611484573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a8919061213a565b6114de576040517f51c3b94f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83611515576040517f07375c8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f0a5748a80000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526000928392911690630a5748a8906024016040805180830381865afa15801561157b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159f9190612157565b9150915081156115de576040517f6c2775f500000000000000000000000000000000000000000000000000000000815260048101829052602401610442565b6115e785610c08565b92506001600160a01b038716611656576116018387611f1c565b341015611635576116128387611f1c565b60405163de9b74a160e01b81526004810191909152346024820152604401610442565b6116516116428785611f1c565b61164c9034612185565b6119a3565b6116a2565b823410156116805760405163de9b74a160e01b815260048101849052346024820152604401610442565b6116956001600160a01b038816853089611a14565b6116a261164c8434612185565b82600160008282546116b49190611f1c565b9091555092979650505050505050565b6002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a86004820152610240602482015260036044820152622625a0606482015263ffffffff831660848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af115801561176c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117909190612121565b92915050565b6001600160a01b038216611818576006546040516000916001600160a01b03169083908381818185875af1925050503d80600081146117f1576040519150601f19603f3d011682016040523d82523d6000602084013e6117f6565b606091505b50509050806112fe57604051633c31275160e21b815260040160405180910390fd5b600654610455906001600160a01b03848116911683611255565b6006546040517f6c025ec20000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b1580156118a157600080fd5b505af11580156118b5573d6000803e3d6000fd5b50505050505050565b6000611913826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611a659092919063ffffffff16565b8051909150156112fe5780806020019051810190611931919061213a565b6112fe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610442565b806119ab5750565b604051600090339083908381818185875af1925050503d80600081146119ed576040519150601f19603f3d011682016040523d82523d6000602084013e6119f2565b606091505b505090508061045557604051633c31275160e21b815260040160405180910390fd5b6040516001600160a01b03808516602483015283166044820152606481018290526114149085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161129a565b6060610d61848460008585600080866001600160a01b03168587604051611a8c91906121c8565b60006040518083038185875af1925050503d8060008114611ac9576040519150601f19603f3d011682016040523d82523d6000602084013e611ace565b606091505b5091509150611adf87838387611aea565b979650505050505050565b60608315611b56578251611b4f576001600160a01b0385163b611b4f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610442565b5081610d61565b610d618383815115611b6b5781518083602001fd5b8060405162461bcd60e51b815260040161044291906121e4565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215611bae57600080fd5b8235915060208084013567ffffffffffffffff80821115611bce57600080fd5b818601915086601f830112611be257600080fd5b813581811115611bf457611bf4611b85565b8060051b604051601f19603f83011681018181108582111715611c1957611c19611b85565b604052918252848201925083810185019189831115611c3757600080fd5b938501935b82851015611c5557843584529385019392850192611c3c565b8096505050505050509250929050565b6001600160a01b03811681146108d157600080fd5b600060208284031215611c8c57600080fd5b8135611c9781611c65565b9392505050565b80151581146108d157600080fd5b63ffffffff811681146108d157600080fd5b60008060008060008060c08789031215611cd757600080fd5b863595506020870135611ce981611c65565b94506040870135611cf981611c9e565b93506060870135611d0981611cac565b9598949750929560808101359460a0909101359350915050565b600060208284031215611d3557600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b600067ffffffffffffffff808316818516808303821115611d7557611d75611d3c565b01949350505050565b6000816000190483118215151615611d9857611d98611d3c565b500290565b600060208284031215611daf57600080fd5b8151611c9781611c65565b805169ffffffffffffffffffff81168114611dd457600080fd5b919050565b600080600080600060a08688031215611df157600080fd5b611dfa86611dba565b9450602086015193506040860151925060608601519150611e1d60808701611dba565b90509295509295909350565b805162ffffff81168114611dd457600080fd5b60008060008060008060008060006101208a8c031215611e5b57600080fd5b8951611e6681611cac565b60208b0151909950611e7781611cac565b60408b0151909850611e8881611cac565b60608b0151909750611e9981611cac565b60808b0151909650611eaa81611cac565b9450611eb860a08b01611e29565b9350611ec660c08b01611e29565b9250611ed460e08b01611e29565b9150611ee36101008b01611e29565b90509295985092959850929598565b634e487b7160e01b600052601260045260246000fd5b600082611f1757611f17611ef2565b500490565b60008219821115611f2f57611f2f611d3c565b500190565b6000600160ff1b821415611f4a57611f4a611d3c565b5060000390565b634e487b7160e01b600052603260045260246000fd5b600082611f7657611f76611ef2565b500690565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615611fb557611fb5611d3c565b82600160ff1b038412811615611fcd57611fcd611d3c565b50500190565b600080831283600160ff1b01831281151615611ff157611ff1611d3c565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561202557612025611d3c565b50500390565b600063ffffffff8083168181141561204557612045611d3c565b6001019392505050565b600063ffffffff8381169083168181101561206c5761206c611d3c565b039392505050565b600060c08201888352602088818501526001600160a01b038816604085015260c0606085015281875180845260e086019150828901935060005b818110156120cd57845160ff16835293830193918301916001016120ae565b50508481036080860152865180825290820192508187019060005b81811015612104578251855293830193918301916001016120e8565b50505063ffffffff851660a0850152509050979650505050505050565b60006020828403121561213357600080fd5b5051919050565b60006020828403121561214c57600080fd5b8151611c9781611c9e565b6000806040838503121561216a57600080fd5b825161217581611c9e565b6020939093015192949293505050565b60008282101561219757612197611d3c565b500390565b60005b838110156121b757818101518382015260200161219f565b838111156114145750506000910152565b600082516121da81846020870161219c565b9190910192915050565b602081526000825180602084015261220381604085016020870161219c565b601f01601f1916919091016040019291505056fea2646970667358221220c05c34f2d96b8504319645a30325c483223c6edf38d0d25c6d42e4d95edff72c64736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959000000000000000000000000ae975071be8f8ee67addbc1a82488f1c248580670000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9
-----Decoded View---------------
Arg [0] : _bankroll (address): 0x51e99A0D09EeCa8d7EFEc3062AC024B6d0989959
Arg [1] : _vrf (address): 0xAE975071Be8F8eE67addBC1A82488F1C24858067
Arg [2] : link_eth_feed (address): 0x5787BefDc0ECd210Dfa948264631CD53E68F7802
Arg [3] : _forwarder (address): 0xF73ab2d782bf6BA97ac4405D2CD4F1135da8dbd9
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959
Arg [1] : 000000000000000000000000ae975071be8f8ee67addbc1a82488f1c24858067
Arg [2] : 0000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802
Arg [3] : 000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9
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.