More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 5,247 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mines_Start | 65142771 | 2 days ago | IN | 0.14595174 POL | 0.01098045 | ||||
Mines_End | 65142760 | 2 days ago | IN | 0 POL | 0.00313028 | ||||
Mines_Start | 65142739 | 2 days ago | IN | 0.14563793 POL | 0.01076812 | ||||
Mines_End | 65142137 | 2 days ago | IN | 0 POL | 0.00250629 | ||||
Mines_Start | 65137229 | 2 days ago | IN | 0.14373285 POL | 0.00998755 | ||||
Mines_End | 65075110 | 3 days ago | IN | 0 POL | 0.00717341 | ||||
Mines_Reveal | 65075081 | 3 days ago | IN | 0.07289492 POL | 0.01683762 | ||||
Mines_Start | 65075061 | 3 days ago | IN | 0.08886432 POL | 0.02583221 | ||||
Mines_End | 65074879 | 3 days ago | IN | 0 POL | 0.00669567 | ||||
Mines_Reveal | 65074738 | 3 days ago | IN | 0.08284541 POL | 0.0202592 | ||||
Mines_Reveal | 65074721 | 3 days ago | IN | 0.08110045 POL | 0.01966611 | ||||
Mines_Start | 65074701 | 3 days ago | IN | 0.08570314 POL | 0.02446212 | ||||
Mines_Start | 65074449 | 3 days ago | IN | 0.19445529 POL | 0.03294652 | ||||
Mines_End | 65074364 | 3 days ago | IN | 0 POL | 0.0076144 | ||||
Mines_Reveal | 65074349 | 3 days ago | IN | 0.08773022 POL | 0.02382082 | ||||
Mines_Start | 65074305 | 3 days ago | IN | 0.10234368 POL | 0.03208402 | ||||
Mines_Reveal | 65074305 | 3 days ago | IN | 0.09700305 POL | 0.02469971 | ||||
Mines_Start | 65074285 | 3 days ago | IN | 0.1092412 POL | 0.03518688 | ||||
Mines_Start | 65074274 | 3 days ago | IN | 0.20774911 POL | 0.03891093 | ||||
Mines_Start | 65074265 | 3 days ago | IN | 0.11655573 POL | 0.03843299 | ||||
Mines_Reveal | 65074241 | 3 days ago | IN | 0.10214315 POL | 0.02702714 | ||||
Mines_Start | 65074217 | 3 days ago | IN | 0.12562109 POL | 0.04240827 | ||||
Mines_End | 64746686 | 12 days ago | IN | 0 POL | 0.00687803 | ||||
Mines_Reveal | 64746655 | 12 days ago | IN | 0.08001523 POL | 0.01973449 | ||||
Mines_Start | 64746625 | 12 days ago | IN | 0.17097373 POL | 0.02742193 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
65142779 | 2 days ago | 0.1 POL | ||||
65142771 | 2 days ago | 0.00919034 POL | ||||
65142760 | 2 days ago | 0.1 POL | ||||
65142739 | 2 days ago | 0.00912758 POL | ||||
65142137 | 2 days ago | 0.1 POL | ||||
65137229 | 2 days ago | 0.00874657 POL | ||||
65075110 | 3 days ago | 0.01 POL | ||||
65075081 | 3 days ago | 0.01457898 POL | ||||
65075061 | 3 days ago | 0.01577286 POL | ||||
65074879 | 3 days ago | 0.1 POL | ||||
65074744 | 3 days ago | 0.01 POL | ||||
65074738 | 3 days ago | 0.01656908 POL | ||||
65074721 | 3 days ago | 0.01622009 POL | ||||
65074701 | 3 days ago | 0.01514062 POL | ||||
65074449 | 3 days ago | 0.01889105 POL | ||||
65074364 | 3 days ago | 0.01 POL | ||||
65074357 | 3 days ago | 0.1 POL | ||||
65074349 | 3 days ago | 0.01754604 POL | ||||
65074305 | 3 days ago | 0.01846873 POL | ||||
65074305 | 3 days ago | 0.01940061 POL | ||||
65074293 | 3 days ago | 0.01 POL | ||||
65074285 | 3 days ago | 0.01984824 POL | ||||
65074274 | 3 days ago | 0.02154982 POL | ||||
65074272 | 3 days ago | 0.01 POL | ||||
65074265 | 3 days ago | 0.02131114 POL |
Loading...
Loading
Contract Name:
Mines
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"; //Bug on reveal event if player loses num mines is incorrect // End game , event must include num mines and tiles revealed /** * @title Mines game, player have 25 tiles where mines are hidden, players flip tiles until they cashout or reveal a mine in which case they lose */ contract Mines is Common { using SafeERC20 for IERC20; constructor( address _bankroll, address _vrf, address link_eth_feed, address _forwarder, uint8[24] memory maxReveal ) { Bankroll = IBankRoll(_bankroll); IChainLinkVRF = IVRFCoordinatorV2(_vrf); LINK_ETH_FEED = AggregatorV3Interface(link_eth_feed); ChainLinkVRF = _vrf; _setMaxReveal(maxReveal); _trustedForwarder = _forwarder; } struct MinesGame { address tokenAddress; uint256 wager; uint256 requestID; uint64 blockNumber; uint64 currentMultiplier; uint8 numMines; bool[25] revealedTiles; bool[25] tilesPicked; bool isCashout; } mapping(address => MinesGame) minesGames; mapping(uint256 => address) minesIDs; mapping(uint256 => mapping(uint256 => uint256)) minesMultipliers; mapping(uint256 => uint256) minesMaxReveal; /** * @dev event emitted at the start of the game * @param playerAddress address of the player that made the bet * @param wager wager amount * @param tokenAddress address of token the wager was made and payout, 0 address is considered the native coin * @param numMines number of mines * @param isCashout if player intends to cashout in case of victory */ event Mines_Play_Event( address indexed playerAddress, uint256 wager, address tokenAddress, uint8 numMines, bool isCashout, uint256 VRFFee ); event Mines_Fee_Event(address indexed playerAddress, uint256 VRFFee); /** * @dev event emitted by the VRF callback with the tile reveal results * @param playerAddress address of the player that made the bet * @param wager wager amount * @param payout payout if player were to end the game * @param tokenAddress address of token the wager was made and payout, 0 address is considered the native coin * @param numMines number of mines * @param minesTiles tiles in which mines were revealed, if any is true the game is over and the player lost * @param revealedTiles all tiles that have been revealed, true correspond to a revealed tile * @param multiplier current game multiplier if the game player chooses to end the game */ event Mines_Reveal_Event( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, uint256 numMines, bool[25] minesTiles, bool[25] revealedTiles, uint256 multiplier ); /** * @dev event emitted by the VRF callback with the tile reveal results and cashout * @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 numMines number of mines * @param minesTiles tiles in which mines were revealed, if any is true the game is over and the player lost * @param revealedTiles all tiles that have been revealed, true correspond to a revealed tile * @param multiplier current game multiplier */ event Mines_RevealCashout_Event( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, uint256 numMines, bool[25] minesTiles, bool[25] revealedTiles, uint256 multiplier ); /** * @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 multiplier final game multiplier */ event Mines_End_Event( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, uint256 numMines, bool[25] revealedTiles, uint256 multiplier ); /** * @dev event emitted when a refund is done in mines * @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 Mines_Refund_Event( address indexed player, uint256 wager, address tokenAddress ); error InvalidNumMines(); error AlreadyInGame(); error NotInGame(); error AwaitingVRF(uint256 requestID); error InvalidNumberToReveal(uint32 numberPicked, uint256 maxAllowed); error TileAlreadyRevealed(uint8 position); error WagerAboveLimit(uint256 wager, uint256 maxWager); error NoRequestPending(); error BlockNumberTooLow(uint256 have, uint256 want); error OnlyCoordinatorCanFulfill(address have, address want); /** * @dev function to view the current mines multipliers * @param numMines number of mines in the game * @param numRevealed tiles revealed * @return multiplier multiplier of selected numMines and numRevealed */ function Mines_GetMultipliers( uint256 numMines, uint256 numRevealed ) public view returns (uint256 multiplier) { multiplier = minesMultipliers[numMines][numRevealed]; return multiplier; } /** * @dev function to view the max number of tiles to reveal in mines * @return maxReveal array with max number of tiles to reveal for each number of mines */ function Mines_GetMaxReveal() external view returns (uint256[24] memory maxReveal) { for (uint256 i = 0; i < 24; i++) { maxReveal[i] = minesMaxReveal[i + 1]; } } /** * @dev get current game state of player * @param player address of the player that made the bet * @return minesState current state of player game */ function Mines_GetState( address player ) external view returns (MinesGame memory minesState) { minesState = minesGames[player]; return minesState; } /** * @dev function to start mines game, player cannot currently be in a game * @param wager wager amount * @param tokenAddress address of token the wager was made and payout, 0 address is considered the native coin * @param tiles arrays of tiles to initialy reveal, true equals that tile will be revealed * @param isCashout if true, game will give payout if player doesn't reveal mines * @param numMines number of mines present in game, range from 1-24 */ function Mines_Start( uint256 wager, address tokenAddress, uint8 numMines, bool[25] calldata tiles, bool isCashout ) external payable nonReentrant { address msgSender = _msgSender(); if (!(numMines >= 1 && numMines <= 24)) { revert InvalidNumMines(); } MinesGame storage game = minesGames[msgSender]; if (game.requestID != 0) { revert AwaitingVRF(game.requestID); } if (game.numMines != 0) { revert AlreadyInGame(); } uint32 numTilesToReveal; for (uint8 i = 0; i < tiles.length; i++) { if (tiles[i]) { numTilesToReveal++; } } uint256 _minesMaxReveal = minesMaxReveal[numMines]; if (numTilesToReveal == 0 || numTilesToReveal > _minesMaxReveal) { revert InvalidNumberToReveal(numTilesToReveal, _minesMaxReveal); } _kellyWager(wager, tokenAddress, _minesMaxReveal, numMines); uint256 fee = _transferWager(tokenAddress, wager, 500000, msgSender); uint256 id = _requestRandomWords(numTilesToReveal); minesIDs[id] = msgSender; game.numMines = numMines; game.wager = wager; game.tokenAddress = tokenAddress; game.isCashout = isCashout; game.tilesPicked = tiles; game.requestID = id; game.blockNumber = uint64(block.number); emit Mines_Play_Event( msgSender, wager, tokenAddress, numMines, isCashout, fee ); } /** * @dev function to reveal tiles in an ongoing game * @param tiles array of tiles that the player wishes to reveal, can't choose already revealed tiles, true equals that tile will be revealed * @param isCashout if true and player doesn't reveal mines, will cashout */ function Mines_Reveal( bool[25] calldata tiles, bool isCashout ) external payable nonReentrant { address msgSender = _msgSender(); MinesGame storage game = minesGames[msgSender]; if (game.numMines == 0) { revert NotInGame(); } if (game.requestID != 0) { revert AwaitingVRF(game.requestID); } uint32 numTilesRevealed; uint32 numTilesToReveal; for (uint8 i = 0; i < tiles.length; i++) { if (tiles[i]) { if (game.revealedTiles[i]) { revert TileAlreadyRevealed(i); } numTilesToReveal++; } if (game.revealedTiles[i]) { numTilesRevealed++; } } if ( numTilesToReveal == 0 || numTilesToReveal + numTilesRevealed > minesMaxReveal[game.numMines] ) { revert InvalidNumberToReveal( numTilesToReveal + numTilesRevealed, minesMaxReveal[game.numMines] ); } uint256 VRFFee = _payVRFFee(500000); uint256 id = _requestRandomWords(numTilesToReveal); minesIDs[id] = msgSender; game.tilesPicked = tiles; game.isCashout = isCashout; game.requestID = id; game.blockNumber = uint64(block.number); emit Mines_Fee_Event(msgSender, VRFFee); } /** * @dev function to end player current game and receive payout */ function Mines_End() external nonReentrant { address msgSender = _msgSender(); MinesGame storage game = minesGames[msgSender]; if (game.numMines == 0) { revert NotInGame(); } if (game.requestID != 0) { revert AwaitingVRF(game.requestID); } uint8 numMines = game.numMines; bool[25] memory revealedTiles = game.revealedTiles; uint256 multiplier = game.currentMultiplier; uint256 wager = game.wager; uint256 payout = (multiplier * wager) / 10000; address tokenAddress = game.tokenAddress; _transferToBankroll(tokenAddress, wager); delete (minesGames[msgSender]); _transferPayout(msgSender, payout, tokenAddress); emit Mines_End_Event( msgSender, wager, payout, tokenAddress, numMines, revealedTiles, multiplier ); } /** * @dev Function to get refund for game if VRF request fails */ function Mines_Refund() external nonReentrant { address msgSender = _msgSender(); if (minesGames[msgSender].numMines == 0) { revert NotInGame(); } if (minesGames[msgSender].requestID == 0) { revert NoRequestPending(); } if ( minesGames[msgSender].blockNumber + BLOCK_NUMBER_REFUND + 10 > block.number ) { revert BlockNumberTooLow( block.number, minesGames[msgSender].blockNumber + BLOCK_NUMBER_REFUND + 10 ); } uint256 wager = minesGames[msgSender].wager; address tokenAddress = minesGames[msgSender].tokenAddress; delete (minesGames[msgSender]); if (tokenAddress == address(0)) { (bool success, ) = payable(msgSender).call{value: wager}(""); if (!success) { revert TransferFailed(); } } else { IERC20(tokenAddress).safeTransfer(msgSender, wager); } emit Mines_Refund_Event(msgSender, wager, tokenAddress); } /** * @dev function to set game multipliers * @param numMines number of mines to set multipliers for */ function Mines_SetMultipliers(uint256 numMines) external { if (numMines == 0 || numMines >= 25) { revert(); } if (minesMultipliers[numMines][1] != 0) { revert(); } for (uint256 g = 1; g <= 25 - numMines; g++) { uint256 multiplier = 1; uint256 divisor = 1; for (uint256 f = 0; f < g; f++) { multiplier *= (25 - numMines - f); divisor *= (25 - f); } minesMultipliers[numMines][g] = (9900 * (10 ** 9)) / ((multiplier * (10 ** 9)) / divisor); } } /** * @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 player = minesIDs[requestId]; if (player == address(0)) revert(); delete (minesIDs[requestId]); MinesGame storage game = minesGames[player]; if (block.number > game.blockNumber + BLOCK_NUMBER_REFUND) revert(); uint8 numMines = game.numMines; uint256 numberOfRevealedTiles; for (uint256 i = 0; i < game.revealedTiles.length; i++) { if (game.revealedTiles[i] == true) { numberOfRevealedTiles += 1; } } bool[25] memory mines; bool won = true; uint256 randomCounter; for (uint256 i = 0; i < game.tilesPicked.length; i++) { if ( game.numMines == 0 || 25 - numberOfRevealedTiles == game.numMines ) { if (game.tilesPicked[i]) { game.revealedTiles[i] = true; } continue; } if (game.tilesPicked[i]) { bool gem = _pickTile( player, i, 25 - numberOfRevealedTiles, game.numMines, randomWords[randomCounter] ); if (gem == false) { game.numMines -= 1; mines[i] = true; won = false; } numberOfRevealedTiles += 1; randomCounter += 1; } } if (!won) { if (game.isCashout == false) { emit Mines_Reveal_Event( player, game.wager, 0, game.tokenAddress, numMines, mines, game.revealedTiles, 0 ); } else { emit Mines_RevealCashout_Event( player, game.wager, 0, game.tokenAddress, numMines, mines, game.revealedTiles, 0 ); } _transferToBankroll(game.tokenAddress, game.wager); delete (minesGames[player]); return; } uint256 multiplier = minesMultipliers[game.numMines][ numberOfRevealedTiles ]; if (game.isCashout == false) { game.currentMultiplier = uint64(multiplier); game.requestID = 0; emit Mines_Reveal_Event( player, game.wager, (multiplier * game.wager) / 10000, game.tokenAddress, game.numMines, mines, game.revealedTiles, multiplier ); } else { uint256 wager = game.wager; address tokenAddress = game.tokenAddress; emit Mines_RevealCashout_Event( player, wager, (multiplier * wager) / 10000, tokenAddress, game.numMines, mines, game.revealedTiles, multiplier ); _transferToBankroll(tokenAddress, game.wager); delete (minesGames[player]); _transferPayout(player, (multiplier * wager) / 10000, tokenAddress); } } function _pickTile( address player, uint256 tileNumber, uint256 numberTilesLeft, uint256 numberOfMinesLeft, uint256 rng ) internal returns (bool) { uint256 winChance = 10000 - (numberOfMinesLeft * 10000) / numberTilesLeft; bool won = false; if (rng % 10000 <= winChance) { won = true; } minesGames[player].revealedTiles[tileNumber] = true; return won; } /** * @dev function to set game max number of reveals only callable at deploy time * @param maxReveal max reveal for each num Mines */ function _setMaxReveal(uint8[24] memory maxReveal) internal { for (uint256 i = 0; i < maxReveal.length; i++) { minesMaxReveal[i + 1] = maxReveal[i]; } } /** * @dev calculates the maximum wager allowed based on the bankroll size */ function _kellyWager( uint256 wager, address tokenAddress, uint256 maxReveal, uint256 numMines ) internal view { uint256 balance; if (tokenAddress == address(0)) { balance = address(Bankroll).balance; } else { balance = IERC20(tokenAddress).balanceOf(address(Bankroll)); } uint256 maxWager = (balance * (11000 - 10890)) / (minesMultipliers[numMines][maxReveal] - 10000); 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 (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 (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); }
{ "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"},{"internalType":"uint8[24]","name":"maxReveal","type":"uint8[24]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInGame","type":"error"},{"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":[],"name":"InvalidNumMines","type":"error"},{"inputs":[{"internalType":"uint32","name":"numberPicked","type":"uint32"},{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"InvalidNumberToReveal","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"sent","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"NoRequestPending","type":"error"},{"inputs":[],"name":"NotApprovedBankroll","type":"error"},{"inputs":[],"name":"NotInGame","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":[{"internalType":"uint8","name":"position","type":"uint8"}],"name":"TileAlreadyRevealed","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":"uint256","name":"numMines","type":"uint256"},{"indexed":false,"internalType":"bool[25]","name":"revealedTiles","type":"bool[25]"},{"indexed":false,"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"Mines_End_Event","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"playerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"VRFFee","type":"uint256"}],"name":"Mines_Fee_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":"uint8","name":"numMines","type":"uint8"},{"indexed":false,"internalType":"bool","name":"isCashout","type":"bool"},{"indexed":false,"internalType":"uint256","name":"VRFFee","type":"uint256"}],"name":"Mines_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":"Mines_Refund_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":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"numMines","type":"uint256"},{"indexed":false,"internalType":"bool[25]","name":"minesTiles","type":"bool[25]"},{"indexed":false,"internalType":"bool[25]","name":"revealedTiles","type":"bool[25]"},{"indexed":false,"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"Mines_RevealCashout_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":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"numMines","type":"uint256"},{"indexed":false,"internalType":"bool[25]","name":"minesTiles","type":"bool[25]"},{"indexed":false,"internalType":"bool[25]","name":"revealedTiles","type":"bool[25]"},{"indexed":false,"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"Mines_Reveal_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":[],"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":"Mines_End","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"Mines_GetMaxReveal","outputs":[{"internalType":"uint256[24]","name":"maxReveal","type":"uint256[24]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numMines","type":"uint256"},{"internalType":"uint256","name":"numRevealed","type":"uint256"}],"name":"Mines_GetMultipliers","outputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"Mines_GetState","outputs":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"wager","type":"uint256"},{"internalType":"uint256","name":"requestID","type":"uint256"},{"internalType":"uint64","name":"blockNumber","type":"uint64"},{"internalType":"uint64","name":"currentMultiplier","type":"uint64"},{"internalType":"uint8","name":"numMines","type":"uint8"},{"internalType":"bool[25]","name":"revealedTiles","type":"bool[25]"},{"internalType":"bool[25]","name":"tilesPicked","type":"bool[25]"},{"internalType":"bool","name":"isCashout","type":"bool"}],"internalType":"struct Mines.MinesGame","name":"minesState","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Mines_Refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool[25]","name":"tiles","type":"bool[25]"},{"internalType":"bool","name":"isCashout","type":"bool"}],"name":"Mines_Reveal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numMines","type":"uint256"}],"name":"Mines_SetMultipliers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wager","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint8","name":"numMines","type":"uint8"},{"internalType":"bool[25]","name":"tiles","type":"bool[25]"},{"internalType":"bool","name":"isCashout","type":"bool"}],"name":"Mines_Start","outputs":[],"stateMutability":"payable","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
60806040523480156200001157600080fd5b50604051620033f5380380620033f5833981016040819052620000349162000164565b6001600055600680546001600160a01b038088166001600160a01b03199283161790925560058054878416908316811790915560048054938716938316939093179092556002805490911690911790556200008f81620000ba565b50600380546001600160a01b0319166001600160a01b039290921691909117905550620002a7915050565b60005b60188110156200011b57818160188110620000dc57620000dc62000242565b602002015160ff16600a6000620000f58460016200026e565b815260208101919091526040016000205580620001128162000289565b915050620000bd565b5050565b80516001600160a01b03811681146200013757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b805160ff811681146200013757600080fd5b60008060008060006103808087890312156200017f57600080fd5b6200018a876200011f565b955060206200019b8189016200011f565b9550620001ab604089016200011f565b9450620001bb606089016200011f565b935088609f890112620001cd57600080fd5b60405161030081016001600160401b0381118282101715620001f357620001f36200013c565b60405291880191808a8411156200020957600080fd5b60808a015b848110156200023057620002228162000152565b82529083019083016200020e565b50508093505050509295509295909350565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111562000284576200028462000258565b500190565b6000600019821415620002a057620002a062000258565b5060010190565b61313e80620002b76000396000f3fe6080604052600436106101295760003560e01c80638bd16114116100a5578063ad17836111610074578063c6318aad11610059578063c6318aad1461033e578063d0bcfc0c14610360578063eb5d80751461038057600080fd5b8063ad17836114610309578063b5f2da971461032957600080fd5b80638bd16114146102935780638d7c16d2146102b3578063953995ea146102c9578063a6d18c51146102e957600080fd5b80634dd189d5116100fc57806356c022bb116100e157806356c022bb14610214578063572b6c051461023457806363dc4ef51461027357600080fd5b80634dd189d5146101ae57806350ffd786146101e657600080fd5b80630f53b8261461012e5780631fe543e31461014557806320ade00314610165578063320a51351461019b575b600080fd5b34801561013a57600080fd5b50610143610393565b005b34801561015157600080fd5b5061014361016036600461279c565b610679565b34801561017157600080fd5b5061018561018036600461287b565b6106e0565b60405161019291906128c4565b60405180910390f35b6101436101a9366004612997565b610827565b3480156101ba57600080fd5b506005546101ce906001600160a01b031681565b6040516001600160a01b039091168152602001610192565b3480156101f257600080fd5b506102066102013660046129d1565b610b22565b604051908152602001610192565b34801561022057600080fd5b506003546101ce906001600160a01b031681565b34801561024057600080fd5b5061026361024f36600461287b565b6003546001600160a01b0391821691161490565b6040519015158152602001610192565b34801561027f57600080fd5b5061014361028e36600461287b565b610b43565b34801561029f57600080fd5b506102066102ae3660046129f3565b610d20565b3480156102bf57600080fd5b5061020660015481565b3480156102d557600080fd5b506002546101ce906001600160a01b031681565b3480156102f557600080fd5b506101436103043660046129f3565b610e81565b34801561031557600080fd5b506004546101ce906001600160a01b031681565b34801561033557600080fd5b50610143610f84565b34801561034a57600080fd5b50610353611194565b6040516101929190612a0c565b34801561036c57600080fd5b506006546101ce906001600160a01b031681565b61014361038e366004612a3e565b6111f3565b61039b6114f2565b60006103a561154c565b6001600160a01b038116600090815260076020526040902060030154909150600160801b900460ff166103eb5760405163218286cb60e11b815260040160405180910390fd5b6001600160a01b03811660009081526007602052604090206002015461043d576040517f90a7340b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600760205260409020600301544390610472906103e89067ffffffffffffffff16612ac3565b61047d90600a612ac3565b67ffffffffffffffff161115610517576001600160a01b03811660009081526007602052604090206003015443906104c2906103e89067ffffffffffffffff16612ac3565b6104cd90600a612ac3565b6040517fb4ae675a000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044015b60405180910390fd5b6001600160a01b03808216600090815260076020526040812060018101805482546001600160a01b031981168455918490556002830184905560038301805470ffffffffffffffffffffffffffffffffff19169055600483018490559316916000600583015550600601805460ff191690556001600160a01b038116610611576000836001600160a01b03168360405160006040518083038185875af1925050503d80600081146105e4576040519150601f19603f3d011682016040523d82523d6000602084013e6105e9565b606091505b505090508061060b576040516312171d8360e31b815260040160405180910390fd5b50610625565b6106256001600160a01b0382168484611580565b604080518381526001600160a01b0383811660208301528516917f47d03d5b779b98ffcf8d141c72233e07e1eefe64744ce9d5288aea98eaf6bc9c910160405180910390a25050506106776001600055565b565b6002546001600160a01b031633146106d2576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116602482015260440161050e565b6106dc828261162e565b5050565b6106e861262b565b6001600160a01b03828116600090815260076020908152604080832081516101208101835281549095168552600181015492850192909252600282015484820152600382015467ffffffffffffffff8082166060870152680100000000000000008204166080860152600160801b900460ff1660a08501528051610320810191829052919260c0850192916004850191601991908390855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116107805750505092845250506040805161032081019182905260209093019291506005840190601990826000855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116107d8575050509284525050506006919091015460ff16151560209091015292915050565b61082f6114f2565b600061083961154c565b6001600160a01b0381166000908152600760205260409020600381015491925090600160801b900460ff166108815760405163218286cb60e11b815260040160405180910390fd5b6002810154156108ac578060020154604051632206dcb760e11b815260040161050e91815260200190565b60008060005b60198160ff1610156109b657868160ff16601981106108d3576108d3612aef565b6020020160208101906108e69190612b05565b1561096357836004018160ff166019811061090357610903612aef565b602081049091015460ff601f9092166101000a90041615610955576040517f63926f5100000000000000000000000000000000000000000000000000000000815260ff8216600482015260240161050e565b8161095f81612b22565b9250505b836004018160ff166019811061097b5761097b612aef565b602081049091015460ff601f9092166101000a900416156109a457826109a081612b22565b9350505b806109ae81612b46565b9150506108b2565b5063ffffffff811615806109f557506003830154600160801b900460ff166000908152600a60205260409020546109ed8383612b66565b63ffffffff16115b15610a4a57610a048282612b66565b6003840154600160801b900460ff166000908152600a60205260409081902054905163377e537f60e11b815263ffffffff9092166004830152602482015260440161050e565b6000610a586207a120611c8c565b90506000610a6583611cf2565b600081815260086020526040902080546001600160a01b0319166001600160a01b0389161790559050610a9d600586018960196126a3565b5060068501805460ff19168815151790556002850181905560038501805467ffffffffffffffff19164367ffffffffffffffff161790556040518281526001600160a01b038716907f676c918f37fe2b3bf042543e3fdaf058ce52fd6fde49a5303cf971d7037f84ec9060200160405180910390a25050505050506106dc6001600055565b60008281526009602090815260408083208484529091529020545b92915050565b610b4b6114f2565b600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc29190612b85565b6001600160a01b0316336001600160a01b031614610c9557600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c519190612b85565b6040517f23295f0e0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015233602482015260440161050e565b600180546000918290556040519091906001600160a01b0384169083908381818185875af1925050503d8060008114610cea576040519150601f19603f3d011682016040523d82523d6000602084013e610cef565b606091505b5050905080610d11576040516312171d8360e31b815260040160405180910390fd5b5050610d1d6001600055565b50565b60048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009384936001600160a01b03169263feaf968c928183019260a0928290030181865afa158015610d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da69190612bc1565b5050509150506000600560009054906101000a90046001600160a01b03166001600160a01b0316635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610e02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e269190612c38565b50505050505050509050670de0b6b3a7640000828263ffffffff1664e8d4a51000610e519190612ce0565b610e5b9190612ce0565b610e659190612d15565b610e6f853a612ce0565b610e799190612d29565b949350505050565b801580610e8f575060198110155b15610e9957600080fd5b60008181526009602090815260408083206001845290915290205415610ebe57600080fd5b60015b610ecc826019612d41565b81116106dc5760018060005b83811015610f2b5780610eec866019612d41565b610ef69190612d41565b610f009084612ce0565b9250610f0d816019612d41565b610f179083612ce0565b915080610f2381612d58565b915050610ed8565b5080610f3b83633b9aca00612ce0565b610f459190612d15565b610f559065090105fbb800612d15565b600085815260096020908152604080832087845290915290205550819050610f7c81612d58565b915050610ec1565b610f8c6114f2565b6000610f9661154c565b6001600160a01b0381166000908152600760205260409020600381015491925090600160801b900460ff16610fde5760405163218286cb60e11b815260040160405180910390fd5b600281015415611009578060020154604051632206dcb760e11b815260040161050e91815260200190565b600381015460408051610320810191829052600160801b90920460ff169160009160048501906019908285855b825461010083900a900460ff16151581526020600192830181810494850194909303909202910180841161103657505050506003860154600187015493945068010000000000000000900467ffffffffffffffff169291506000905061271061109f8385612ce0565b6110a99190612d15565b86549091506001600160a01b03166110c18184611dbe565b6001600160a01b038816600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055611137888383611e5a565b876001600160a01b03167f1fe1dd196606ad2650d7969421fce1457a68ab5ef856f561b02c43d85e2b23058484848a8a8a60405161117a96959493929190612d73565b60405180910390a250505050505050506106776001600055565b61119c612733565b60005b60188110156111ef57600a60006111b7836001612d29565b8152602001908152602001600020548282601881106111d8576111d8612aef565b6020020152806111e781612d58565b91505061119f565b5090565b6111fb6114f2565b600061120561154c565b905060018460ff161015801561121f575060188460ff1611155b611255576040517f822cb1a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600760205260409020600281015415611298578060020154604051632206dcb760e11b815260040161050e91815260200190565b6003810154600160801b900460ff16156112de576040517fc56fb25300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b60198160ff16101561133b57858160ff166019811061130357611303612aef565b6020020160208101906113169190612b05565b15611329578161132581612b22565b9250505b8061133381612b46565b9150506112e2565b5060ff86166000908152600a602052604090205463ffffffff821615806113675750808263ffffffff16115b156113945760405163377e537f60e11b815263ffffffff831660048201526024810182905260440161050e565b6113a38989838a60ff16611ee6565b60006113b4898b6207a1208861201d565b905060006113c184611cf2565b600081815260086020526040902080546001600160a01b03199081166001600160a01b038a8116919091179092556003880180547fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff16600160801b60ff8f1602179055600188018e9055875416908c1617865560068601805460ff19168915151790559050611455600586018960196126a3565b506002850181905560038501805467ffffffffffffffff19164367ffffffffffffffff16179055604080518c81526001600160a01b038c8116602083015260ff8c16828401528915156060830152608082018590529151918816917f06b735e3b542c1e7f37c869cdc85e44e5653bb9d7df7669703552379dc5d89b59160a0908290030190a25050505050506114eb6001600055565b5050505050565b600260005414156115455760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161050e565b6002600055565b60006014361080159061156957506003546001600160a01b031633145b1561157b575060131936013560601c90565b503390565b6040516001600160a01b0383166024820152604481018290526116299084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122c2565b505050565b6000828152600860205260409020546001600160a01b03168061165057600080fd5b600083815260086020908152604080832080546001600160a01b03191690556001600160a01b038416835260079091529020600381015461169e906103e89067ffffffffffffffff16612ac3565b67ffffffffffffffff164311156116b457600080fd5b6003810154600160801b900460ff166000805b6019811015611727578360040181601981106116e5576116e5612aef565b602091828204019190069054906101000a900460ff16151560011515141561171557611712600183612d29565b91505b8061171f81612d58565b9150506116c7565b50611730612752565b60016000805b60198110156118e9576003870154600160801b900460ff16158061177157506003870154600160801b900460ff1661176f866019612d41565b145b156117e25786600501816019811061178b5761178b612aef565b602081049091015460ff601f9092166101000a900416156117dd5760018760040182601981106117bd576117bd612aef565b602091828204019190066101000a81548160ff0219169083151502179055505b6118d7565b8660050181601981106117f7576117f7612aef565b602081049091015460ff601f9092166101000a900416156118d75760006118588983611824896019612d41565b8b60030160109054906101000a900460ff1660ff168e888151811061184b5761184b612aef565b60200260200101516123a7565b9050806118bb5760018860030160108282829054906101000a900460ff166118809190612db9565b92506101000a81548160ff021916908360ff16021790555060018583601981106118ac576118ac612aef565b91151560209092020152600093505b6118c6600187612d29565b95506118d3600184612d29565b9250505b806118e181612d58565b915050611736565b5081611a4957600686015460ff1661195c57600186015486546040516001600160a01b03808b16937fa2c15df8b18610ebd81258461bf85a580874824addb5419f1a723080a1cbb9df9361194f9391926000929116908b908a9060048f01908590612fc0565b60405180910390a26119b9565b600186015486546040516001600160a01b03808b16937feac20db8d33062f61bf7dd8f8c6fb0ce14563dec2fa4726683f5bb14c01241b4936119b09391926000929116908b908a9060048f01908590612fc0565b60405180910390a25b855460018701546119d3916001600160a01b031690611dbe565b6001600160a01b038716600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055505050505050505050565b600386015460ff600160801b909104811660009081526009602090815260408083208884529091529020546006880154909116611b61576003870180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416021790556000600288015560018701546001600160a01b038916907fa2c15df8b18610ebd81258461bf85a580874824addb5419f1a723080a1cbb9df90612710611b078286612ce0565b611b119190612d15565b8a60000160009054906101000a90046001600160a01b03168b60030160109054906101000a900460ff16898d60040188604051611b549796959493929190612fc0565b60405180910390a2611c80565b600187015487546001600160a01b03908116908a167feac20db8d33062f61bf7dd8f8c6fb0ce14563dec2fa4726683f5bb14c01241b483612710611ba58288612ce0565b611baf9190612d15565b848d60030160109054906101000a900460ff168b8f6004018a604051611bdb9796959493929190612fc0565b60405180910390a2611bf1818a60010154611dbe565b6001600160a01b038a16600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055611c7d8a612710611c6d8587612ce0565b611c779190612d15565b83611e5a565b50505b50505050505050505050565b6000611c9782610d20565b905080341015611cc35760405163de9b74a160e01b81526004810182905234602482015260440161050e565b611cd5611cd08234612d41565b612443565b8060016000828254611ce79190612d29565b909155509092915050565b6002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a86004820152610240602482015260036044820152622625a0606482015263ffffffff831660848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af1158015611d9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613015565b6001600160a01b038216611e40576006546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611e19576040519150601f19603f3d011682016040523d82523d6000602084013e611e1e565b606091505b505090508061162957604051633c31275160e21b815260040160405180910390fd5b6006546106dc906001600160a01b03848116911683611580565b6006546040517f6c025ec20000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b158015611ec957600080fd5b505af1158015611edd573d6000803e3d6000fd5b50505050505050565b60006001600160a01b038416611f0957506006546001600160a01b031631611f93565b6006546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa158015611f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f909190613015565b90505b6000828152600960209081526040808320868452909152812054611fba9061271090612d41565b611fc583606e612ce0565b611fcf9190612d15565b905080861115612015576040517fd53662aa000000000000000000000000000000000000000000000000000000008152600481018790526024810182905260440161050e565b505050505050565b6006546040517fbfd7f9cc0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038681166024830152600092169063bfd7f9cc90604401602060405180830381865afa158015612087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ab919061302e565b6120e1576040517f51c3b94f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83612118576040517f07375c8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f0a5748a80000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526000928392911690630a5748a8906024016040805180830381865afa15801561217e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a2919061304b565b9150915081156121e1576040517f6c2775f50000000000000000000000000000000000000000000000000000000081526004810182905260240161050e565b6121ea85610d20565b92506001600160a01b038716612254576122048387612d29565b341015612238576122158387612d29565b60405163de9b74a160e01b8152600481019190915234602482015260440161050e565b61224f6122458785612d29565b611cd09034612d41565b6122a0565b8234101561227e5760405163de9b74a160e01b81526004810184905234602482015260440161050e565b6122936001600160a01b0388168530896124b4565b6122a0611cd08434612d41565b82600160008282546122b29190612d29565b9091555092979650505050505050565b6000612317826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661250b9092919063ffffffff16565b8051909150156116295780806020019051810190612335919061302e565b6116295760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161050e565b600080846123b785612710612ce0565b6123c19190612d15565b6123cd90612710612d41565b90506000816123de61271086613079565b116123e7575060015b6001600160a01b0388166000908152600760205260409020600190600401886019811061241657612416612aef565b602091828204019190066101000a81548160ff021916908315150217905550809250505095945050505050565b8061244b5750565b604051600090339083908381818185875af1925050503d806000811461248d576040519150601f19603f3d011682016040523d82523d6000602084013e612492565b606091505b50509050806106dc57604051633c31275160e21b815260040160405180910390fd5b6040516001600160a01b03808516602483015283166044820152606481018290526125059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016115c5565b50505050565b6060610e79848460008585600080866001600160a01b0316858760405161253291906130b9565b60006040518083038185875af1925050503d806000811461256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b509150915061258587838387612590565b979650505050505050565b606083156125fc5782516125f5576001600160a01b0385163b6125f55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161050e565b5081610e79565b610e7983838151156126115781518083602001fd5b8060405162461bcd60e51b815260040161050e91906130d5565b60405180610120016040528060006001600160a01b031681526020016000815260200160008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600060ff168152602001612689612752565b8152602001612696612752565b8152600060209091015290565b6001830191839082156127275791602002820160005b838211156126f8578335151583826101000a81548160ff02191690831515021790555092602001926001016020816000010492830192600103026126b9565b80156127255782816101000a81549060ff02191690556001016020816000010492830192600103026126f8565b505b506111ef929150612771565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b5b808211156111ef5760008155600101612772565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156127af57600080fd5b8235915060208084013567ffffffffffffffff808211156127cf57600080fd5b818601915086601f8301126127e357600080fd5b8135818111156127f5576127f5612786565b8060051b604051601f19603f8301168101818110858211171561281a5761281a612786565b60405291825284820192508381018501918983111561283857600080fd5b938501935b828510156128565784358452938501939285019261283d565b8096505050505050509250929050565b6001600160a01b0381168114610d1d57600080fd5b60006020828403121561288d57600080fd5b813561289881612866565b9392505050565b8060005b601981101561250557815115158452602093840193909101906001016128a3565b6000610720820190506001600160a01b03835116825260208301516020830152604083015160408301526060830151612909606084018267ffffffffffffffff169052565b506080830151612925608084018267ffffffffffffffff169052565b5060a083015161293a60a084018260ff169052565b5060c083015161294d60c084018261289f565b5060e08301516129616103e084018261289f565b5061010092909201511515610700919091015290565b806103208101831015610b3d57600080fd5b8015158114610d1d57600080fd5b60008061034083850312156129ab57600080fd5b6129b58484612977565b91506103208301356129c681612989565b809150509250929050565b600080604083850312156129e457600080fd5b50508035926020909101359150565b600060208284031215612a0557600080fd5b5035919050565b6103008101818360005b6018811015612a35578151835260209283019290910190600101612a16565b50505092915050565b60008060008060006103a08688031215612a5757600080fd5b853594506020860135612a6981612866565b9350604086013560ff81168114612a7f57600080fd5b9250612a8e8760608801612977565b9150610380860135612a9f81612989565b809150509295509295909350565b634e487b7160e01b600052601160045260246000fd5b600067ffffffffffffffff808316818516808303821115612ae657612ae6612aad565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612b1757600080fd5b813561289881612989565b600063ffffffff80831681811415612b3c57612b3c612aad565b6001019392505050565b600060ff821660ff811415612b5d57612b5d612aad565b60010192915050565b600063ffffffff808316818516808303821115612ae657612ae6612aad565b600060208284031215612b9757600080fd5b815161289881612866565b805169ffffffffffffffffffff81168114612bbc57600080fd5b919050565b600080600080600060a08688031215612bd957600080fd5b612be286612ba2565b9450602086015193506040860151925060608601519150612c0560808701612ba2565b90509295509295909350565b805163ffffffff81168114612bbc57600080fd5b805162ffffff81168114612bbc57600080fd5b60008060008060008060008060006101208a8c031215612c5757600080fd5b612c608a612c11565b9850612c6e60208b01612c11565b9750612c7c60408b01612c11565b9650612c8a60608b01612c11565b9550612c9860808b01612c11565b9450612ca660a08b01612c25565b9350612cb460c08b01612c25565b9250612cc260e08b01612c25565b9150612cd16101008b01612c25565b90509295985092959850929598565b6000816000190483118215151615612cfa57612cfa612aad565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612d2457612d24612cff565b500490565b60008219821115612d3c57612d3c612aad565b500190565b600082821015612d5357612d53612aad565b500390565b6000600019821415612d6c57612d6c612aad565b5060010190565b868152602081018690526001600160a01b038516604082015260ff841660608201526103c08101612da7608083018561289f565b826103a0830152979650505050505050565b600060ff821660ff841680821015612dd357612dd3612aad565b90039392505050565b805460ff80821615158452612dfa60208501828460081c1615159052565b612e0d60408501828460101c1615159052565b612e2060608501828460181c1615159052565b612e3360808501828460201c1615159052565b612e4660a08501828460281c1615159052565b612e5960c08501828460301c1615159052565b612e6c60e08501828460381c1615159052565b612e806101008501828460401c1615159052565b612e946101208501828460481c1615159052565b612ea86101408501828460501c1615159052565b612ebc6101608501828460581c1615159052565b612ed06101808501828460601c1615159052565b612ee46101a08501828460681c1615159052565b612ef86101c08501828460701c1615159052565b612f0c6101e08501828460781c1615159052565b612f206102008501828460801c1615159052565b612f346102208501828460881c1615159052565b612f486102408501828460901c1615159052565b612f5c6102608501828460981c1615159052565b612f706102808501828460a01c1615159052565b612f846102a08501828460a81c1615159052565b612f986102c08501828460b01c1615159052565b612fac6102e08501828460b81c1615159052565b6125056103008501828460c01c1615159052565b878152602081018790526001600160a01b038616604082015260ff851660608201526106e08101612ff4608083018661289f565b6130026103a0830185612ddc565b826106c083015298975050505050505050565b60006020828403121561302757600080fd5b5051919050565b60006020828403121561304057600080fd5b815161289881612989565b6000806040838503121561305e57600080fd5b825161306981612989565b6020939093015192949293505050565b60008261308857613088612cff565b500690565b60005b838110156130a8578181015183820152602001613090565b838111156125055750506000910152565b600082516130cb81846020870161308d565b9190910192915050565b60208152600082518060208401526130f481604085016020870161308d565b601f01601f1916919091016040019291505056fea26469706673582212203ce81215919bea7d6fa99fd9d77bcf19217c6d48ab97ac418b9fcfc3425cc00564736f6c634300080b003300000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959000000000000000000000000ae975071be8f8ee67addbc1a82488f1c248580670000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x6080604052600436106101295760003560e01c80638bd16114116100a5578063ad17836111610074578063c6318aad11610059578063c6318aad1461033e578063d0bcfc0c14610360578063eb5d80751461038057600080fd5b8063ad17836114610309578063b5f2da971461032957600080fd5b80638bd16114146102935780638d7c16d2146102b3578063953995ea146102c9578063a6d18c51146102e957600080fd5b80634dd189d5116100fc57806356c022bb116100e157806356c022bb14610214578063572b6c051461023457806363dc4ef51461027357600080fd5b80634dd189d5146101ae57806350ffd786146101e657600080fd5b80630f53b8261461012e5780631fe543e31461014557806320ade00314610165578063320a51351461019b575b600080fd5b34801561013a57600080fd5b50610143610393565b005b34801561015157600080fd5b5061014361016036600461279c565b610679565b34801561017157600080fd5b5061018561018036600461287b565b6106e0565b60405161019291906128c4565b60405180910390f35b6101436101a9366004612997565b610827565b3480156101ba57600080fd5b506005546101ce906001600160a01b031681565b6040516001600160a01b039091168152602001610192565b3480156101f257600080fd5b506102066102013660046129d1565b610b22565b604051908152602001610192565b34801561022057600080fd5b506003546101ce906001600160a01b031681565b34801561024057600080fd5b5061026361024f36600461287b565b6003546001600160a01b0391821691161490565b6040519015158152602001610192565b34801561027f57600080fd5b5061014361028e36600461287b565b610b43565b34801561029f57600080fd5b506102066102ae3660046129f3565b610d20565b3480156102bf57600080fd5b5061020660015481565b3480156102d557600080fd5b506002546101ce906001600160a01b031681565b3480156102f557600080fd5b506101436103043660046129f3565b610e81565b34801561031557600080fd5b506004546101ce906001600160a01b031681565b34801561033557600080fd5b50610143610f84565b34801561034a57600080fd5b50610353611194565b6040516101929190612a0c565b34801561036c57600080fd5b506006546101ce906001600160a01b031681565b61014361038e366004612a3e565b6111f3565b61039b6114f2565b60006103a561154c565b6001600160a01b038116600090815260076020526040902060030154909150600160801b900460ff166103eb5760405163218286cb60e11b815260040160405180910390fd5b6001600160a01b03811660009081526007602052604090206002015461043d576040517f90a7340b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600760205260409020600301544390610472906103e89067ffffffffffffffff16612ac3565b61047d90600a612ac3565b67ffffffffffffffff161115610517576001600160a01b03811660009081526007602052604090206003015443906104c2906103e89067ffffffffffffffff16612ac3565b6104cd90600a612ac3565b6040517fb4ae675a000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044015b60405180910390fd5b6001600160a01b03808216600090815260076020526040812060018101805482546001600160a01b031981168455918490556002830184905560038301805470ffffffffffffffffffffffffffffffffff19169055600483018490559316916000600583015550600601805460ff191690556001600160a01b038116610611576000836001600160a01b03168360405160006040518083038185875af1925050503d80600081146105e4576040519150601f19603f3d011682016040523d82523d6000602084013e6105e9565b606091505b505090508061060b576040516312171d8360e31b815260040160405180910390fd5b50610625565b6106256001600160a01b0382168484611580565b604080518381526001600160a01b0383811660208301528516917f47d03d5b779b98ffcf8d141c72233e07e1eefe64744ce9d5288aea98eaf6bc9c910160405180910390a25050506106776001600055565b565b6002546001600160a01b031633146106d2576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116602482015260440161050e565b6106dc828261162e565b5050565b6106e861262b565b6001600160a01b03828116600090815260076020908152604080832081516101208101835281549095168552600181015492850192909252600282015484820152600382015467ffffffffffffffff8082166060870152680100000000000000008204166080860152600160801b900460ff1660a08501528051610320810191829052919260c0850192916004850191601991908390855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116107805750505092845250506040805161032081019182905260209093019291506005840190601990826000855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116107d8575050509284525050506006919091015460ff16151560209091015292915050565b61082f6114f2565b600061083961154c565b6001600160a01b0381166000908152600760205260409020600381015491925090600160801b900460ff166108815760405163218286cb60e11b815260040160405180910390fd5b6002810154156108ac578060020154604051632206dcb760e11b815260040161050e91815260200190565b60008060005b60198160ff1610156109b657868160ff16601981106108d3576108d3612aef565b6020020160208101906108e69190612b05565b1561096357836004018160ff166019811061090357610903612aef565b602081049091015460ff601f9092166101000a90041615610955576040517f63926f5100000000000000000000000000000000000000000000000000000000815260ff8216600482015260240161050e565b8161095f81612b22565b9250505b836004018160ff166019811061097b5761097b612aef565b602081049091015460ff601f9092166101000a900416156109a457826109a081612b22565b9350505b806109ae81612b46565b9150506108b2565b5063ffffffff811615806109f557506003830154600160801b900460ff166000908152600a60205260409020546109ed8383612b66565b63ffffffff16115b15610a4a57610a048282612b66565b6003840154600160801b900460ff166000908152600a60205260409081902054905163377e537f60e11b815263ffffffff9092166004830152602482015260440161050e565b6000610a586207a120611c8c565b90506000610a6583611cf2565b600081815260086020526040902080546001600160a01b0319166001600160a01b0389161790559050610a9d600586018960196126a3565b5060068501805460ff19168815151790556002850181905560038501805467ffffffffffffffff19164367ffffffffffffffff161790556040518281526001600160a01b038716907f676c918f37fe2b3bf042543e3fdaf058ce52fd6fde49a5303cf971d7037f84ec9060200160405180910390a25050505050506106dc6001600055565b60008281526009602090815260408083208484529091529020545b92915050565b610b4b6114f2565b600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc29190612b85565b6001600160a01b0316336001600160a01b031614610c9557600660009054906101000a90046001600160a01b03166001600160a01b031663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c519190612b85565b6040517f23295f0e0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015233602482015260440161050e565b600180546000918290556040519091906001600160a01b0384169083908381818185875af1925050503d8060008114610cea576040519150601f19603f3d011682016040523d82523d6000602084013e610cef565b606091505b5050905080610d11576040516312171d8360e31b815260040160405180910390fd5b5050610d1d6001600055565b50565b60048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009384936001600160a01b03169263feaf968c928183019260a0928290030181865afa158015610d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da69190612bc1565b5050509150506000600560009054906101000a90046001600160a01b03166001600160a01b0316635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610e02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e269190612c38565b50505050505050509050670de0b6b3a7640000828263ffffffff1664e8d4a51000610e519190612ce0565b610e5b9190612ce0565b610e659190612d15565b610e6f853a612ce0565b610e799190612d29565b949350505050565b801580610e8f575060198110155b15610e9957600080fd5b60008181526009602090815260408083206001845290915290205415610ebe57600080fd5b60015b610ecc826019612d41565b81116106dc5760018060005b83811015610f2b5780610eec866019612d41565b610ef69190612d41565b610f009084612ce0565b9250610f0d816019612d41565b610f179083612ce0565b915080610f2381612d58565b915050610ed8565b5080610f3b83633b9aca00612ce0565b610f459190612d15565b610f559065090105fbb800612d15565b600085815260096020908152604080832087845290915290205550819050610f7c81612d58565b915050610ec1565b610f8c6114f2565b6000610f9661154c565b6001600160a01b0381166000908152600760205260409020600381015491925090600160801b900460ff16610fde5760405163218286cb60e11b815260040160405180910390fd5b600281015415611009578060020154604051632206dcb760e11b815260040161050e91815260200190565b600381015460408051610320810191829052600160801b90920460ff169160009160048501906019908285855b825461010083900a900460ff16151581526020600192830181810494850194909303909202910180841161103657505050506003860154600187015493945068010000000000000000900467ffffffffffffffff169291506000905061271061109f8385612ce0565b6110a99190612d15565b86549091506001600160a01b03166110c18184611dbe565b6001600160a01b038816600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055611137888383611e5a565b876001600160a01b03167f1fe1dd196606ad2650d7969421fce1457a68ab5ef856f561b02c43d85e2b23058484848a8a8a60405161117a96959493929190612d73565b60405180910390a250505050505050506106776001600055565b61119c612733565b60005b60188110156111ef57600a60006111b7836001612d29565b8152602001908152602001600020548282601881106111d8576111d8612aef565b6020020152806111e781612d58565b91505061119f565b5090565b6111fb6114f2565b600061120561154c565b905060018460ff161015801561121f575060188460ff1611155b611255576040517f822cb1a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600760205260409020600281015415611298578060020154604051632206dcb760e11b815260040161050e91815260200190565b6003810154600160801b900460ff16156112de576040517fc56fb25300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b60198160ff16101561133b57858160ff166019811061130357611303612aef565b6020020160208101906113169190612b05565b15611329578161132581612b22565b9250505b8061133381612b46565b9150506112e2565b5060ff86166000908152600a602052604090205463ffffffff821615806113675750808263ffffffff16115b156113945760405163377e537f60e11b815263ffffffff831660048201526024810182905260440161050e565b6113a38989838a60ff16611ee6565b60006113b4898b6207a1208861201d565b905060006113c184611cf2565b600081815260086020526040902080546001600160a01b03199081166001600160a01b038a8116919091179092556003880180547fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff16600160801b60ff8f1602179055600188018e9055875416908c1617865560068601805460ff19168915151790559050611455600586018960196126a3565b506002850181905560038501805467ffffffffffffffff19164367ffffffffffffffff16179055604080518c81526001600160a01b038c8116602083015260ff8c16828401528915156060830152608082018590529151918816917f06b735e3b542c1e7f37c869cdc85e44e5653bb9d7df7669703552379dc5d89b59160a0908290030190a25050505050506114eb6001600055565b5050505050565b600260005414156115455760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161050e565b6002600055565b60006014361080159061156957506003546001600160a01b031633145b1561157b575060131936013560601c90565b503390565b6040516001600160a01b0383166024820152604481018290526116299084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122c2565b505050565b6000828152600860205260409020546001600160a01b03168061165057600080fd5b600083815260086020908152604080832080546001600160a01b03191690556001600160a01b038416835260079091529020600381015461169e906103e89067ffffffffffffffff16612ac3565b67ffffffffffffffff164311156116b457600080fd5b6003810154600160801b900460ff166000805b6019811015611727578360040181601981106116e5576116e5612aef565b602091828204019190069054906101000a900460ff16151560011515141561171557611712600183612d29565b91505b8061171f81612d58565b9150506116c7565b50611730612752565b60016000805b60198110156118e9576003870154600160801b900460ff16158061177157506003870154600160801b900460ff1661176f866019612d41565b145b156117e25786600501816019811061178b5761178b612aef565b602081049091015460ff601f9092166101000a900416156117dd5760018760040182601981106117bd576117bd612aef565b602091828204019190066101000a81548160ff0219169083151502179055505b6118d7565b8660050181601981106117f7576117f7612aef565b602081049091015460ff601f9092166101000a900416156118d75760006118588983611824896019612d41565b8b60030160109054906101000a900460ff1660ff168e888151811061184b5761184b612aef565b60200260200101516123a7565b9050806118bb5760018860030160108282829054906101000a900460ff166118809190612db9565b92506101000a81548160ff021916908360ff16021790555060018583601981106118ac576118ac612aef565b91151560209092020152600093505b6118c6600187612d29565b95506118d3600184612d29565b9250505b806118e181612d58565b915050611736565b5081611a4957600686015460ff1661195c57600186015486546040516001600160a01b03808b16937fa2c15df8b18610ebd81258461bf85a580874824addb5419f1a723080a1cbb9df9361194f9391926000929116908b908a9060048f01908590612fc0565b60405180910390a26119b9565b600186015486546040516001600160a01b03808b16937feac20db8d33062f61bf7dd8f8c6fb0ce14563dec2fa4726683f5bb14c01241b4936119b09391926000929116908b908a9060048f01908590612fc0565b60405180910390a25b855460018701546119d3916001600160a01b031690611dbe565b6001600160a01b038716600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055505050505050505050565b600386015460ff600160801b909104811660009081526009602090815260408083208884529091529020546006880154909116611b61576003870180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416021790556000600288015560018701546001600160a01b038916907fa2c15df8b18610ebd81258461bf85a580874824addb5419f1a723080a1cbb9df90612710611b078286612ce0565b611b119190612d15565b8a60000160009054906101000a90046001600160a01b03168b60030160109054906101000a900460ff16898d60040188604051611b549796959493929190612fc0565b60405180910390a2611c80565b600187015487546001600160a01b03908116908a167feac20db8d33062f61bf7dd8f8c6fb0ce14563dec2fa4726683f5bb14c01241b483612710611ba58288612ce0565b611baf9190612d15565b848d60030160109054906101000a900460ff168b8f6004018a604051611bdb9796959493929190612fc0565b60405180910390a2611bf1818a60010154611dbe565b6001600160a01b038a16600090815260076020526040812080546001600160a01b0319168155600181018290556002810182905560038101805470ffffffffffffffffffffffffffffffffff1916905560048101829055906000600583015550600601805460ff19169055611c7d8a612710611c6d8587612ce0565b611c779190612d15565b83611e5a565b50505b50505050505050505050565b6000611c9782610d20565b905080341015611cc35760405163de9b74a160e01b81526004810182905234602482015260440161050e565b611cd5611cd08234612d41565b612443565b8060016000828254611ce79190612d29565b909155509092915050565b6002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a86004820152610240602482015260036044820152622625a0606482015263ffffffff831660848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af1158015611d9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613015565b6001600160a01b038216611e40576006546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611e19576040519150601f19603f3d011682016040523d82523d6000602084013e611e1e565b606091505b505090508061162957604051633c31275160e21b815260040160405180910390fd5b6006546106dc906001600160a01b03848116911683611580565b6006546040517f6c025ec20000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b158015611ec957600080fd5b505af1158015611edd573d6000803e3d6000fd5b50505050505050565b60006001600160a01b038416611f0957506006546001600160a01b031631611f93565b6006546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa158015611f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f909190613015565b90505b6000828152600960209081526040808320868452909152812054611fba9061271090612d41565b611fc583606e612ce0565b611fcf9190612d15565b905080861115612015576040517fd53662aa000000000000000000000000000000000000000000000000000000008152600481018790526024810182905260440161050e565b505050505050565b6006546040517fbfd7f9cc0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038681166024830152600092169063bfd7f9cc90604401602060405180830381865afa158015612087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ab919061302e565b6120e1576040517f51c3b94f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83612118576040517f07375c8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f0a5748a80000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526000928392911690630a5748a8906024016040805180830381865afa15801561217e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a2919061304b565b9150915081156121e1576040517f6c2775f50000000000000000000000000000000000000000000000000000000081526004810182905260240161050e565b6121ea85610d20565b92506001600160a01b038716612254576122048387612d29565b341015612238576122158387612d29565b60405163de9b74a160e01b8152600481019190915234602482015260440161050e565b61224f6122458785612d29565b611cd09034612d41565b6122a0565b8234101561227e5760405163de9b74a160e01b81526004810184905234602482015260440161050e565b6122936001600160a01b0388168530896124b4565b6122a0611cd08434612d41565b82600160008282546122b29190612d29565b9091555092979650505050505050565b6000612317826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661250b9092919063ffffffff16565b8051909150156116295780806020019051810190612335919061302e565b6116295760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161050e565b600080846123b785612710612ce0565b6123c19190612d15565b6123cd90612710612d41565b90506000816123de61271086613079565b116123e7575060015b6001600160a01b0388166000908152600760205260409020600190600401886019811061241657612416612aef565b602091828204019190066101000a81548160ff021916908315150217905550809250505095945050505050565b8061244b5750565b604051600090339083908381818185875af1925050503d806000811461248d576040519150601f19603f3d011682016040523d82523d6000602084013e612492565b606091505b50509050806106dc57604051633c31275160e21b815260040160405180910390fd5b6040516001600160a01b03808516602483015283166044820152606481018290526125059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016115c5565b50505050565b6060610e79848460008585600080866001600160a01b0316858760405161253291906130b9565b60006040518083038185875af1925050503d806000811461256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b509150915061258587838387612590565b979650505050505050565b606083156125fc5782516125f5576001600160a01b0385163b6125f55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161050e565b5081610e79565b610e7983838151156126115781518083602001fd5b8060405162461bcd60e51b815260040161050e91906130d5565b60405180610120016040528060006001600160a01b031681526020016000815260200160008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600060ff168152602001612689612752565b8152602001612696612752565b8152600060209091015290565b6001830191839082156127275791602002820160005b838211156126f8578335151583826101000a81548160ff02191690831515021790555092602001926001016020816000010492830192600103026126b9565b80156127255782816101000a81549060ff02191690556001016020816000010492830192600103026126f8565b505b506111ef929150612771565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b5b808211156111ef5760008155600101612772565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156127af57600080fd5b8235915060208084013567ffffffffffffffff808211156127cf57600080fd5b818601915086601f8301126127e357600080fd5b8135818111156127f5576127f5612786565b8060051b604051601f19603f8301168101818110858211171561281a5761281a612786565b60405291825284820192508381018501918983111561283857600080fd5b938501935b828510156128565784358452938501939285019261283d565b8096505050505050509250929050565b6001600160a01b0381168114610d1d57600080fd5b60006020828403121561288d57600080fd5b813561289881612866565b9392505050565b8060005b601981101561250557815115158452602093840193909101906001016128a3565b6000610720820190506001600160a01b03835116825260208301516020830152604083015160408301526060830151612909606084018267ffffffffffffffff169052565b506080830151612925608084018267ffffffffffffffff169052565b5060a083015161293a60a084018260ff169052565b5060c083015161294d60c084018261289f565b5060e08301516129616103e084018261289f565b5061010092909201511515610700919091015290565b806103208101831015610b3d57600080fd5b8015158114610d1d57600080fd5b60008061034083850312156129ab57600080fd5b6129b58484612977565b91506103208301356129c681612989565b809150509250929050565b600080604083850312156129e457600080fd5b50508035926020909101359150565b600060208284031215612a0557600080fd5b5035919050565b6103008101818360005b6018811015612a35578151835260209283019290910190600101612a16565b50505092915050565b60008060008060006103a08688031215612a5757600080fd5b853594506020860135612a6981612866565b9350604086013560ff81168114612a7f57600080fd5b9250612a8e8760608801612977565b9150610380860135612a9f81612989565b809150509295509295909350565b634e487b7160e01b600052601160045260246000fd5b600067ffffffffffffffff808316818516808303821115612ae657612ae6612aad565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612b1757600080fd5b813561289881612989565b600063ffffffff80831681811415612b3c57612b3c612aad565b6001019392505050565b600060ff821660ff811415612b5d57612b5d612aad565b60010192915050565b600063ffffffff808316818516808303821115612ae657612ae6612aad565b600060208284031215612b9757600080fd5b815161289881612866565b805169ffffffffffffffffffff81168114612bbc57600080fd5b919050565b600080600080600060a08688031215612bd957600080fd5b612be286612ba2565b9450602086015193506040860151925060608601519150612c0560808701612ba2565b90509295509295909350565b805163ffffffff81168114612bbc57600080fd5b805162ffffff81168114612bbc57600080fd5b60008060008060008060008060006101208a8c031215612c5757600080fd5b612c608a612c11565b9850612c6e60208b01612c11565b9750612c7c60408b01612c11565b9650612c8a60608b01612c11565b9550612c9860808b01612c11565b9450612ca660a08b01612c25565b9350612cb460c08b01612c25565b9250612cc260e08b01612c25565b9150612cd16101008b01612c25565b90509295985092959850929598565b6000816000190483118215151615612cfa57612cfa612aad565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612d2457612d24612cff565b500490565b60008219821115612d3c57612d3c612aad565b500190565b600082821015612d5357612d53612aad565b500390565b6000600019821415612d6c57612d6c612aad565b5060010190565b868152602081018690526001600160a01b038516604082015260ff841660608201526103c08101612da7608083018561289f565b826103a0830152979650505050505050565b600060ff821660ff841680821015612dd357612dd3612aad565b90039392505050565b805460ff80821615158452612dfa60208501828460081c1615159052565b612e0d60408501828460101c1615159052565b612e2060608501828460181c1615159052565b612e3360808501828460201c1615159052565b612e4660a08501828460281c1615159052565b612e5960c08501828460301c1615159052565b612e6c60e08501828460381c1615159052565b612e806101008501828460401c1615159052565b612e946101208501828460481c1615159052565b612ea86101408501828460501c1615159052565b612ebc6101608501828460581c1615159052565b612ed06101808501828460601c1615159052565b612ee46101a08501828460681c1615159052565b612ef86101c08501828460701c1615159052565b612f0c6101e08501828460781c1615159052565b612f206102008501828460801c1615159052565b612f346102208501828460881c1615159052565b612f486102408501828460901c1615159052565b612f5c6102608501828460981c1615159052565b612f706102808501828460a01c1615159052565b612f846102a08501828460a81c1615159052565b612f986102c08501828460b01c1615159052565b612fac6102e08501828460b81c1615159052565b6125056103008501828460c01c1615159052565b878152602081018790526001600160a01b038616604082015260ff851660608201526106e08101612ff4608083018661289f565b6130026103a0830185612ddc565b826106c083015298975050505050505050565b60006020828403121561302757600080fd5b5051919050565b60006020828403121561304057600080fd5b815161289881612989565b6000806040838503121561305e57600080fd5b825161306981612989565b6020939093015192949293505050565b60008261308857613088612cff565b500690565b60005b838110156130a8578181015183820152602001613090565b838111156125055750506000910152565b600082516130cb81846020870161308d565b9190910192915050565b60208152600082518060208401526130f481604085016020870161308d565b601f01601f1916919091016040019291505056fea26469706673582212203ce81215919bea7d6fa99fd9d77bcf19217c6d48ab97ac418b9fcfc3425cc00564736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959000000000000000000000000ae975071be8f8ee67addbc1a82488f1c248580670000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _bankroll (address): 0x51e99A0D09EeCa8d7EFEc3062AC024B6d0989959
Arg [1] : _vrf (address): 0xAE975071Be8F8eE67addBC1A82488F1C24858067
Arg [2] : link_eth_feed (address): 0x5787BefDc0ECd210Dfa948264631CD53E68F7802
Arg [3] : _forwarder (address): 0xF73ab2d782bf6BA97ac4405D2CD4F1135da8dbd9
Arg [4] : maxReveal (uint8[24]): 24,21,17,14,12,10,9,8,7,6,5,5,4,4,3,3,3,2,2,2,2,1,1,1
-----Encoded View---------------
28 Constructor Arguments found :
Arg [0] : 00000000000000000000000051e99a0d09eeca8d7efec3062ac024b6d0989959
Arg [1] : 000000000000000000000000ae975071be8f8ee67addbc1a82488f1c24858067
Arg [2] : 0000000000000000000000005787befdc0ecd210dfa948264631cd53e68f7802
Arg [3] : 000000000000000000000000f73ab2d782bf6ba97ac4405d2cd4f1135da8dbd9
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000018
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [7] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [24] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [26] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | Polygon (POL) | 100.00% | $0.684861 | 108.5596 | $74.35 |
[ 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.