More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 7,973 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
End | 17030860 | 4 days ago | IN | 0 ETH | 0.00000008 | ||||
Play | 17030847 | 4 days ago | IN | 0.00000085 ETH | 0.00000037 | ||||
End | 17030790 | 4 days ago | IN | 0 ETH | 0.00000008 | ||||
Play | 17030774 | 4 days ago | IN | 0.00000085 ETH | 0.00000037 | ||||
End | 17005571 | 5 days ago | IN | 0 ETH | 0.00000008 | ||||
Play | 17005564 | 5 days ago | IN | 0.00000178 ETH | 0.00000037 | ||||
Play | 16853645 | 9 days ago | IN | 0.00000084 ETH | 0.00000038 | ||||
Play | 16853074 | 9 days ago | IN | 0.00000084 ETH | 0.00000038 | ||||
Play | 16710756 | 12 days ago | IN | 0.00000136 ETH | 0.00000036 | ||||
Play | 16682207 | 12 days ago | IN | 0.00000112 ETH | 0.00000039 | ||||
Play | 16682196 | 12 days ago | IN | 0.00000114 ETH | 0.00000039 | ||||
Play | 16679609 | 13 days ago | IN | 0.00000115 ETH | 0.00000039 | ||||
Play | 16679565 | 13 days ago | IN | 0.00000115 ETH | 0.00000039 | ||||
End | 16618475 | 14 days ago | IN | 0 ETH | 0.0000001 | ||||
Play | 16618467 | 14 days ago | IN | 0.00000164 ETH | 0.00000044 | ||||
Play | 16595749 | 14 days ago | IN | 0.00000167 ETH | 0.00000039 | ||||
Play | 16595733 | 14 days ago | IN | 0.00000164 ETH | 0.00000039 | ||||
End | 16576842 | 15 days ago | IN | 0 ETH | 0.00000009 | ||||
Play | 16576833 | 15 days ago | IN | 0.00000096 ETH | 0.00000041 | ||||
Play | 16519968 | 16 days ago | IN | 0.00000108 ETH | 0.00000036 | ||||
End | 16469759 | 17 days ago | IN | 0 ETH | 0.00000008 | ||||
Play | 16469747 | 17 days ago | IN | 0.00000135 ETH | 0.00000037 | ||||
Play | 16467760 | 17 days ago | IN | 0.00000103 ETH | 0.00000039 | ||||
Play | 16465828 | 17 days ago | IN | 0.00000111 ETH | 0.00000039 | ||||
Play | 16387694 | 19 days ago | IN | 0.00000085 ETH | 0.00000039 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17030847 | 4 days ago | 0.00000011 ETH | ||||
17030774 | 4 days ago | 0.00000012 ETH | ||||
17005564 | 5 days ago | 0.00000031 ETH | ||||
16853645 | 9 days ago | 0.00000015 ETH | ||||
16853074 | 9 days ago | 0.00000015 ETH | ||||
16710756 | 12 days ago | 0.00000024 ETH | ||||
16682207 | 12 days ago | 0.00000019 ETH | ||||
16682196 | 12 days ago | 0.0000002 ETH | ||||
16679609 | 13 days ago | 0.00000019 ETH | ||||
16679565 | 13 days ago | 0.00000019 ETH | ||||
16618467 | 14 days ago | 0.00000025 ETH | ||||
16595749 | 14 days ago | 0.00000026 ETH | ||||
16595733 | 14 days ago | 0.00000029 ETH | ||||
16576833 | 15 days ago | 0.00000014 ETH | ||||
16519968 | 16 days ago | 0.0000001 ETH | ||||
16469747 | 17 days ago | 0.00000018 ETH | ||||
16467760 | 17 days ago | 0.00000017 ETH | ||||
16465828 | 17 days ago | 0.0000002 ETH | ||||
16387694 | 19 days ago | 0.00000014 ETH | ||||
16387669 | 19 days ago | 0.00000014 ETH | ||||
16302196 | 21 days ago | 0.00000015 ETH | ||||
16302181 | 21 days ago | 0.00000015 ETH | ||||
16203352 | 24 days ago | 0.0000001 ETH | ||||
16203339 | 24 days ago | 0.0000001 ETH | ||||
16202918 | 24 days ago | 0.00000011 ETH |
Loading...
Loading
Contract Name:
ZapankiMinesKroma
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./common/ZapankiGamesKroma.sol"; contract ZapankiMinesKroma is ZapankiGamesKroma { using SafeERC20 for IERC20; 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) vrfPendingPlayer; mapping(uint256 => mapping(uint256 => uint256)) minesMultipliers; mapping(uint256 => uint256) minesMaxReveal; event MinesReveal( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, bool[25] minesTiles, bool[25] revealedTiles, uint256 multiplier, uint256 l2eAmount ); event MinesRevealCashout( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, bool[25] minesTiles, bool[25] revealedTiles, uint256 multiplier, uint256 l2eAmount ); event MinesEnd( address indexed playerAddress, uint256 wager, uint256 payout, address tokenAddress, uint256 multiplier ); event MinesRefund(address indexed player, uint256 wager, address tokenAddress); constructor( address _vrfCoordinator, IBankroll _bankroll, address _trustedForwarder, address _vrfDepositor ) ZapankiGamesKroma(_vrfCoordinator, _bankroll, _trustedForwarder, _vrfDepositor) { _setMaxReveal([24, 21, 17, 14, 12, 10, 9, 8, 7, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1]); for (uint256 i = 1; i <= 24; i++) { _setMinesMultipliers(i); } } function getMultipliers(uint256 numMines, uint256 numRevealed) public view returns (uint256 multiplier) { multiplier = minesMultipliers[numMines][numRevealed]; return multiplier; } function getMaxReveal() external view returns (uint256[24] memory maxReveal) { for (uint256 i = 0; i < 24; i++) { maxReveal[i] = minesMaxReveal[i + 1]; } } function getCurrentUserState(address player) external view returns (MinesGame memory minesState) { minesState = minesGames[player]; return minesState; } function play( uint256 wager, address tokenAddress, uint8 numMines, bool[25] calldata tiles, bool isCashout ) external payable nonReentrant { address msgSender = _msgSender(); require(1 <= numMines && numMines <= 24, "numMines must be between 8 and 16"); require(minesGames[msgSender].requestID == 0, "Waiting VRF request"); require(minesGames[msgSender].numMines == 0, "Already playing"); uint32 revealedTiles; for (uint8 i = 0; i < tiles.length; i++) { if (tiles[i]) { revealedTiles++; } } uint256 _minesMaxReveal = minesMaxReveal[numMines]; require(!(revealedTiles == 0 || revealedTiles > _minesMaxReveal), "Invalid to reveal"); _checkMaxWager(wager, tokenAddress, _minesMaxReveal, numMines); _processWager(tokenAddress, wager, 500000, msgSender); uint256 id = _requestRandomWords(revealedTiles); vrfPendingPlayer[id] = msgSender; MinesGame storage game = minesGames[msgSender]; game.numMines = numMines; game.wager = wager; game.tokenAddress = tokenAddress; game.isCashout = isCashout; game.tilesPicked = tiles; game.requestID = id; game.blockNumber = uint64(block.number); callback.onPlay(1, msgSender, tokenAddress, wager, 1); } function reveal(bool[25] calldata tiles, bool isCashout) external payable nonReentrant { MinesGame storage game = minesGames[msg.sender]; require(game.numMines != 0, "Not playing"); require(game.requestID == 0, "Waiting VRF request"); uint32 numTilesRevealed; uint32 numTilesToReveal; bool isTileAlreadyRevealed = false; for (uint8 i = 0; i < tiles.length; i++) { if (tiles[i]) { if (game.revealedTiles[i]) { isTileAlreadyRevealed = true; break; } numTilesToReveal++; } if (game.revealedTiles[i]) { numTilesRevealed++; } } require(!isTileAlreadyRevealed, "Tile already revealed"); require( !(numTilesToReveal == 0 || numTilesToReveal + numTilesRevealed > minesMaxReveal[game.numMines]), "Invalid to reveal" ); _chargeVRFFee(msg.value, 500000); uint256 id = _requestRandomWords(numTilesToReveal); vrfPendingPlayer[id] = msg.sender; game.tilesPicked = tiles; game.isCashout = isCashout; game.requestID = id; game.blockNumber = uint64(block.number); } function end() external nonReentrant { MinesGame storage game = minesGames[msg.sender]; require(game.numMines != 0, "Not playing"); require(game.requestID == 0, "Waiting VRF request"); uint256 multiplier = game.currentMultiplier; uint256 wager = game.wager; uint256 payout = (multiplier * wager) / 10000; address tokenAddress = game.tokenAddress; _transferToBankroll(tokenAddress, wager); delete (minesGames[msg.sender]); _payoutBankrollToPlayer(msg.sender, payout, tokenAddress); emit MinesEnd(msg.sender, wager, payout, tokenAddress, multiplier); } function refund() external nonReentrant { address msgSender = _msgSender(); MinesGame storage game = minesGames[msgSender]; require(game.numMines != 0, "Not playing"); require(game.requestID != 0, "Not waiting VRF request"); require(game.blockNumber + BLOCK_REFUND_COOLDOWN + 10 <= block.number, "Too early"); uint256 wager = game.wager; address tokenAddress = minesGames[msg.sender].tokenAddress; if (tokenAddress == address(0)) { (bool success, ) = payable(msg.sender).call{value: wager}(""); require(success, "Transfer failed"); } else { IERC20(tokenAddress).safeTransfer(msg.sender, wager); } emit MinesRefund(msg.sender, wager, tokenAddress); delete (minesGames[msg.sender]); } function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { address player = vrfPendingPlayer[_requestId]; if (player == address(0)) revert(); delete (vrfPendingPlayer[_requestId]); MinesGame storage game = minesGames[player]; uint256 numberOfRevealedTiles; for (uint32 tile = 0; tile < game.revealedTiles.length; tile++) { if (game.revealedTiles[tile]) { numberOfRevealedTiles += 1; } } uint256 numberOfMinesLeft = game.numMines; bool[25] memory mines; bool won = true; uint8 randomCounter; for (uint32 tileIdx = 0; tileIdx < game.tilesPicked.length; tileIdx++) { if (numberOfMinesLeft == 0 || 25 - numberOfRevealedTiles == numberOfMinesLeft) { if (game.tilesPicked[tileIdx]) { game.revealedTiles[tileIdx] = true; } continue; } if (game.tilesPicked[tileIdx]) { minesGames[player].revealedTiles[tileIdx] = true; bool isBomb = _isBomb(25 - numberOfRevealedTiles, numberOfMinesLeft, _randomWords[randomCounter]); if (isBomb) { numberOfMinesLeft -= 1; mines[tileIdx] = true; won = false; } numberOfRevealedTiles += 1; randomCounter += 1; } } if (!won) { _transferToBankroll(game.tokenAddress, game.wager); uint256 l2eAmount = bankroll.payoutL2E(player, game.tokenAddress, game.wager, 0); if (game.isCashout == false) { emit MinesReveal(player, game.wager, 0, game.tokenAddress, mines, game.revealedTiles, 0, l2eAmount); } else { emit MinesRevealCashout( player, game.wager, 0, game.tokenAddress, mines, game.revealedTiles, 0, l2eAmount ); } callback.onEnd(1, player, game.tokenAddress, game.wager, 1, 0); delete (minesGames[player]); return; } uint256 multiplier = minesMultipliers[numberOfMinesLeft][numberOfRevealedTiles]; if (game.isCashout == false) { game.currentMultiplier = uint64(multiplier); game.requestID = 0; emit MinesReveal( player, game.wager, (multiplier * game.wager) / 10000, game.tokenAddress, mines, game.revealedTiles, multiplier, 0 ); } else { uint256 wager = game.wager; address tokenAddress = game.tokenAddress; uint256 payout = (multiplier * wager) / 10000; emit MinesRevealCashout(player, wager, payout, tokenAddress, mines, game.revealedTiles, multiplier, 0); _transferToBankroll(tokenAddress, game.wager); _payoutBankrollToPlayer(player, payout, tokenAddress); callback.onEnd(1, player, game.tokenAddress, game.wager, 1, payout); delete (minesGames[player]); } } function _isBomb(uint256 numberTilesLeft, uint256 numberOfMinesLeft, uint256 rng) internal pure returns (bool) { uint256 winThreshold = 10000 - (numberOfMinesLeft * 10000) / numberTilesLeft; return rng % 10000 > winThreshold; } function _setMaxReveal(uint8[24] memory maxReveal) internal { for (uint256 i = 0; i < maxReveal.length; i++) { minesMaxReveal[i + 1] = maxReveal[i]; } } function _setMinesMultipliers(uint256 numMines) internal { 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); } } function _checkMaxWager(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); require(wager <= maxWager, "Too many wager"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @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. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ 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]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../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; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @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); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) 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 FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../../../interfaces/ISupraRouter.sol"; import "../../../interfaces/IBankroll.sol"; import "../../../interfaces/ICallback.sol"; import "../../../interfaces/IKromaGasPriceOracle.sol"; abstract contract ZapankiGamesKroma is ReentrancyGuard { using SafeERC20 for IERC20; IKromaGasPriceOracle private constant KROMA_GAS_ORACLE = IKromaGasPriceOracle(0x420000000000000000000000000000000000000F); uint256 public constant ECOTONE_GAS_CALC_CONSTANT = 16; ISupraRouter public vrfCoordinator; address public vrfDepositor; IBankroll public bankroll; ICallback public callback; address public trustedForwarder; bytes32 vrfKeyHash; uint256 public claimableVRFFee; uint64 constant BLOCK_REFUND_COOLDOWN = 1000; uint64 vrfSubId; uint32 vrfCallbackGasLimit; modifier onlyOwner() { require(msg.sender == bankroll.owner(), "Not Owner"); _; } constructor(address _vrfCoordinator, IBankroll _bankroll, address _trustedForwarder, address _vrfDepositor) { vrfCoordinator = ISupraRouter(_vrfCoordinator); bankroll = _bankroll; callback = ICallback(address(_bankroll)); trustedForwarder = _trustedForwarder; vrfDepositor = _vrfDepositor; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == trustedForwarder; } function _msgSender() internal view returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return msg.sender; } } function _shouldStop(int256 value, uint256 stopGain, uint256 stopLoss) internal pure returns (bool) { return value >= int256(stopGain) || value <= -int256(stopLoss); } function _processWager(address tokenAddress, uint256 wager, uint256 gasAmount, address msgSender) internal { require(bankroll.getIsValidWager(address(this), tokenAddress), "Token not approved"); require(wager != 0, "Wager must be greater than 0"); if (tokenAddress == address(0)) { _chargeVRFFee(msg.value - wager, gasAmount); } else { _chargeVRFFee(msg.value, gasAmount); IERC20(tokenAddress).safeTransferFrom(msgSender, address(this), wager); } } function _transferToBankroll(address tokenAddress, uint256 amount) internal { if (tokenAddress == address(0)) { (bool success, ) = payable(address(bankroll)).call{value: amount}(""); require(success, "refund failed"); } else { IERC20(tokenAddress).safeTransfer(address(bankroll), amount); } } function getVRFFee(uint256 gasAmount) public view returns (uint256 fee) { uint256 scaledBaseFee = KROMA_GAS_ORACLE.baseFeeScalar() * ECOTONE_GAS_CALC_CONSTANT * KROMA_GAS_ORACLE.l1BaseFee(); uint256 scaledBlobBaseFee = KROMA_GAS_ORACLE.blobBaseFeeScalar() * KROMA_GAS_ORACLE.blobBaseFee(); uint256 _l1GasFee = (6700 * (scaledBaseFee + scaledBlobBaseFee)) / (ECOTONE_GAS_CALC_CONSTANT * 10 ** KROMA_GAS_ORACLE.decimals()); fee = (1000252 * gasAmount) + _l1GasFee; } function _refundVRFFee(uint256 refundableAmount) internal { if (refundableAmount > 0) { (bool success, ) = payable(msg.sender).call{value: refundableAmount}(""); require(success, "refund failed"); } } function _chargeVRFFee(uint256 vrfFeeProvided, uint256 gasAmount) internal { uint256 _vrfFee = getVRFFee(gasAmount); require(vrfFeeProvided >= _vrfFee, "Insufficient vrf fee"); _refundVRFFee(vrfFeeProvided - _vrfFee); claimableVRFFee += _vrfFee; } function collectVrfFee() external nonReentrant onlyOwner { uint256 fee = claimableVRFFee; claimableVRFFee = 0; (bool success, ) = payable(address(msg.sender)).call{value: fee}(""); require(success, "transfer failed"); } function _payoutBankrollToPlayer(address player, uint256 payout, address tokenAddress) internal { bankroll.transferPayout(player, payout, tokenAddress); } function _requestRandomWords(uint32 numWords) internal returns (uint256 s_requestId) { s_requestId = vrfCoordinator.generateRequest( "rawFulfillRandomWords(uint256,uint256[])", uint8(numWords), 1, vrfDepositor ); } function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { require(msg.sender == address(vrfCoordinator)); fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; 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 owner() external view returns (address); function payoutL2E( address player, address wagerToken, uint256 wager, uint256 payout ) external returns (uint256 l2eAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ICallback { function onPlay(uint32 game, address playerAddress, address tokenAddress, uint256 wager, uint256 numGames) external; function onEnd( uint32 game, address playerAddress, address tokenAddress, uint256 wager, uint256 numGames, uint totalPayout ) external; }
interface IKromaGasPriceOracle { //returns the gas price for the network function l1BaseFee() external view returns (uint256); //returns which fork (Ecotone or Bedrock) is used by OP Stack L2 for the network function isEcotone() external view returns (bool); //returns the overhead for the network function overhead() external view returns (uint256); //returns the scalar value for the network function scalar() external view returns (uint256); //returns the decimal value for the network function decimals() external view returns (uint256); //returns the decimal value for the network function DECIMALS() external view returns (uint256); /// @notice Retrieves the current blob base fee. /// @return Current blob base fee. function blobBaseFee() external view returns (uint256); /// @notice Retrieves the current base fee scalar. /// @return Current base fee scalar. function baseFeeScalar() external view returns (uint32); /// @notice Retrieves the current blob base fee scalar. /// @return Current blob base fee scalar. function blobBaseFeeScalar() external view returns (uint32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ISupraRouter { function generateRequest( string memory _functionSig, uint8 _rngCount, uint256 _numConfirmations, address _clientWalletAddress ) external returns (uint256); }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"contract IBankroll","name":"_bankroll","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"address","name":"_vrfDepositor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","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":"multiplier","type":"uint256"}],"name":"MinesEnd","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":"MinesRefund","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":"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"},{"indexed":false,"internalType":"uint256","name":"l2eAmount","type":"uint256"}],"name":"MinesReveal","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":"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"},{"indexed":false,"internalType":"uint256","name":"l2eAmount","type":"uint256"}],"name":"MinesRevealCashout","type":"event"},{"inputs":[],"name":"ECOTONE_GAS_CALC_CONSTANT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bankroll","outputs":[{"internalType":"contract IBankroll","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callback","outputs":[{"internalType":"contract ICallback","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimableVRFFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectVrfFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"end","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"getCurrentUserState","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 ZapankiMinesKroma.MinesGame","name":"minesState","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"getMultipliers","outputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"}],"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":"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":"play","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool[25]","name":"tiles","type":"bool[25]"},{"internalType":"bool","name":"isCashout","type":"bool"}],"name":"reveal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"trustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfCoordinator","outputs":[{"internalType":"contract ISupraRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfDepositor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200319b3803806200319b8339810160408190526200003491620002ef565b6001600081905580546001600160a01b038087166001600160a01b03199283161783556003805482881690841681178255600480548516909117815560058054848916908616178155600280549488169490951693909317845560408051610300810182526018815260156020820152601191810191909152600e6060820152600c6080820152600a60a0820152600960c0820152600860e082015260076101008201526006610120820152610140810184905261016081019390935261018083018190526101a08301526101c082018190526101e082018190526102008201526102208101829052610240810182905261026081018290526102808101919091526102a081018290526102c081018290526102e08101919091526200015a9062000191565b60015b6018811162000186576200017181620001f6565b806200017d816200036d565b9150506200015d565b50505050506200040e565b60005b6018811015620001f257818160188110620001b357620001b362000389565b602002015160ff16600c6000620001cc8460016200039f565b815260208101919091526040016000205580620001e9816200036d565b91505062000194565b5050565b60015b62000206826019620003bb565b8111620001f25760018060005b838110156200027457806200022a866019620003bb565b620002369190620003bb565b620002429084620003d1565b925062000251816019620003bb565b6200025d9083620003d1565b9150806200026b816200036d565b91505062000213565b50806200028683633b9aca00620003d1565b620002929190620003eb565b620002a49065090105fbb800620003eb565b6000858152600b6020908152604080832087845290915290205550819050620002cd816200036d565b915050620001f9565b6001600160a01b0381168114620002ec57600080fd5b50565b600080600080608085870312156200030657600080fd5b84516200031381620002d6565b60208601519094506200032681620002d6565b60408601519093506200033981620002d6565b60608601519092506200034c81620002d6565b939692955090935050565b634e487b7160e01b600052601160045260246000fd5b60006001820162000382576200038262000357565b5060010190565b634e487b7160e01b600052603260045260246000fd5b80820180821115620003b557620003b562000357565b92915050565b81810381811115620003b557620003b562000357565b8082028115828204841417620003b557620003b562000357565b6000826200040957634e487b7160e01b600052601260045260246000fd5b500490565b612d7d806200041e6000396000f3fe6080604052600436106101095760003560e01c806376fca03d11610095578063a3e56fa811610064578063a3e56fa8146102cf578063a50ce2f7146102ef578063a5ef362a1461030f578063efbe1c1c14610331578063fea52f101461034657600080fd5b806376fca03d1461024c5780637da0a8771461027957806380cfa527146102995780638bd16114146102af57600080fd5b806336e51f72116100dc57806336e51f72146101b0578063572b6c05146101d0578063590e1ae31461020f57806359cd33271461022457806374b0a7891461023757600080fd5b8063083b27321461010e5780630c657eb01461014b5780631fe543e31461016b578063337161941461018d575b600080fd5b34801561011a57600080fd5b5060045461012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561015757600080fd5b5060035461012e906001600160a01b031681565b34801561017757600080fd5b5061018b610186366004612472565b610359565b005b34801561019957600080fd5b506101a2601081565b604051908152602001610142565b3480156101bc57600080fd5b506101a26101cb36600461253b565b61037e565b3480156101dc57600080fd5b506101ff6101eb366004612572565b6005546001600160a01b0391821691161490565b6040519015158152602001610142565b34801561021b57600080fd5b5061018b61039f565b61018b6102323660046125af565b610634565b34801561024357600080fd5b5061018b61098b565b34801561025857600080fd5b5061026c610267366004612572565b610af6565b6040516101429190612643565b34801561028557600080fd5b5060055461012e906001600160a01b031681565b3480156102a557600080fd5b506101a260075481565b3480156102bb57600080fd5b506101a26102ca3660046126f3565b610c37565b3480156102db57600080fd5b5060015461012e906001600160a01b031681565b3480156102fb57600080fd5b5060025461012e906001600160a01b031681565b34801561031b57600080fd5b50610324610ed4565b604051610142919061270c565b34801561033d57600080fd5b5061018b610f33565b61018b61035436600461273e565b6110ad565b6001546001600160a01b0316331461037057600080fd5b61037a828261133f565b5050565b6000828152600b602090815260408083208484529091529020545b92915050565b6103a7611af2565b60006103b1611b1c565b6001600160a01b0381166000908152600960205260408120600381015492935091600160801b900460ff1690036104035760405162461bcd60e51b81526004016103fa90612778565b60405180910390fd5b80600201546000036104575760405162461bcd60e51b815260206004820152601760248201527f4e6f742077616974696e6720565246207265717565737400000000000000000060448201526064016103fa565b60038101544390610474906103e8906001600160401b03166127b3565b61047f90600a6127b3565b6001600160401b031611156104c25760405162461bcd60e51b8152602060048201526009602482015268546f6f206561726c7960b81b60448201526064016103fa565b6001810154336000908152600960205260409020546001600160a01b03168061057557604051600090339084908381818185875af1925050503d8060008114610527576040519150601f19603f3d011682016040523d82523d6000602084013e61052c565b606091505b505090508061056f5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016103fa565b50610589565b6105896001600160a01b0382163384611b43565b604080518381526001600160a01b038316602082015233917f9177b7a6097b17a0f6566e1246faed203766b45045bc76865977cd251c658cf0910160405180910390a2505033600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b0319169055600481018290556005810191909155600601805460ff191690555061063290506001600055565b565b61063c611af2565b6000610646611b1c565b90508360ff16600111158015610660575060188460ff1611155b6106b65760405162461bcd60e51b815260206004820152602160248201527f6e756d4d696e6573206d757374206265206265747765656e203820616e6420316044820152601b60f91b60648201526084016103fa565b6001600160a01b038116600090815260096020526040902060020154156106ef5760405162461bcd60e51b81526004016103fa906127d3565b6001600160a01b038116600090815260096020526040902060030154600160801b900460ff16156107545760405162461bcd60e51b815260206004820152600f60248201526e416c726561647920706c6179696e6760881b60448201526064016103fa565b6000805b60198160ff1610156107b157848160ff166019811061077957610779612800565b60200201602081019061078c9190612816565b1561079f578161079b81612833565b9250505b806107a981612856565b915050610758565b5060ff85166000908152600c602052604090205463ffffffff821615806107dd5750808263ffffffff16115b1561081e5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1bc81c995d99585b607a1b60448201526064016103fa565b61082d8888838960ff16611ba7565b61083c87896207a12086611cc2565b600061084783611e12565b6000818152600a6020908152604080832080546001600160a01b03199081166001600160a01b038b811691821790935585526009909352922060038101805460ff60801b1916600160801b60ff8e1602179055600181018d90558054909116918b1691909117815560068101805460ff19168815151790559091506108d160058201886019612303565b506002810182905560038101805467ffffffffffffffff1916436001600160401b0316179055600480546040516327ffe84360e01b815260019281018390526001600160a01b0388811660248301528c81166044830152606482018e905260848201939093529116906327ffe8439060a401600060405180830381600087803b15801561095d57600080fd5b505af1158015610971573d6000803e3d6000fd5b5050505050505050506109846001600055565b5050505050565b610993611af2565b600360009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0a9190612875565b6001600160a01b0316336001600160a01b031614610a565760405162461bcd60e51b81526020600482015260096024820152682737ba1027bbb732b960b91b60448201526064016103fa565b60078054600091829055604051909190339083908381818185875af1925050503d8060008114610aa2576040519150601f19603f3d011682016040523d82523d6000602084013e610aa7565b606091505b5050905080610aea5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064016103fa565b50506106326001600055565b610afe612393565b6001600160a01b0382811660009081526009602090815260408083208151610120810183528154909516855260018101549285019290925260028201548482015260038201546001600160401b038082166060870152600160401b8204166080860152600160801b900460ff1660a08501528051610320810191829052919260c0850192916004850191601991908390855b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610b905750505092845250506040805161032081019182905260209093019291506005840190601990826000855b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610be8575050509284525050506006919091015460ff16151560209091015292915050565b600080600f602160991b016001600160a01b031663519b4bd36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca39190612892565b6010600f602160991b016001600160a01b031663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e91906128ab565b63ffffffff16610d1e91906128d1565b610d2891906128d1565b90506000600f602160991b016001600160a01b031663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190612892565b600f602160991b016001600160a01b03166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfe91906128ab565b63ffffffff16610e0e91906128d1565b90506000600f602160991b016001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7b9190612892565b610e8690600a6129cc565b610e919060106128d1565b610e9b83856129d8565b610ea790611a2c6128d1565b610eb19190612a01565b905080610ec186620f433c6128d1565b610ecb91906129d8565b95945050505050565b610edc612409565b60005b6018811015610f2f57600c6000610ef78360016129d8565b815260200190815260200160002054828260188110610f1857610f18612800565b602002015280610f2781612a15565b915050610edf565b5090565b610f3b611af2565b33600090815260096020526040812060038101549091600160801b90910460ff169003610f7a5760405162461bcd60e51b81526004016103fa90612778565b600281015415610f9c5760405162461bcd60e51b81526004016103fa906127d3565b60038101546001820154600160401b9091046001600160401b0316906000612710610fc783856128d1565b610fd19190612a01565b84549091506001600160a01b0316610fe98184611ede565b33600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b031916905560048101829055906000600583015550600601805460ff1916905561104c338383611f99565b60408051848152602081018490526001600160a01b0383168183015260608101869052905133917f57317678548d469552350099a23c37dc29501a40c2705d61262dd7e2f4f7a454919081900360800190a250505050506106326001600055565b6110b5611af2565b33600090815260096020526040812060038101549091600160801b90910460ff1690036110f45760405162461bcd60e51b81526004016103fa90612778565b6002810154156111165760405162461bcd60e51b81526004016103fa906127d3565b6000806000805b60198160ff1610156111f357868160ff166019811061113e5761113e612800565b6020020160208101906111519190612816565b156111a057846004018160ff166019811061116e5761116e612800565b602081049091015460ff601f9092166101000a9004161561119257600191506111f3565b8261119c81612833565b9350505b846004018160ff16601981106111b8576111b8612800565b602081049091015460ff601f9092166101000a900416156111e157836111dd81612833565b9450505b806111eb81612856565b91505061111d565b50801561123a5760405162461bcd60e51b8152602060048201526015602482015274151a5b1948185b1c9958591e481c995d99585b1959605a1b60448201526064016103fa565b63ffffffff8216158061127857506003840154600160801b900460ff166000908152600c60205260409020546112708484612a2e565b63ffffffff16115b156112b95760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1bc81c995d99585b607a1b60448201526064016103fa565b6112c6346207a12061200c565b60006112d183611e12565b6000818152600a6020526040902080546001600160a01b03191633179055905061130060058601886019612303565b5060068501805460ff19168715151790556002850155505050600301805467ffffffffffffffff1916436001600160401b031617905560016000555050565b6000828152600a60205260409020546001600160a01b03168061136157600080fd5b6000838152600a6020908152604080832080546001600160a01b03191690556001600160a01b03841683526009909152812090805b60198163ffffffff1610156113fb57826004018163ffffffff16601981106113c0576113c0612800565b602081049091015460ff601f9092166101000a900416156113e9576113e66001836129d8565b91505b806113f381612833565b915050611396565b506003820154600160801b900460ff16611413612428565b60016000805b60198163ffffffff1610156115e65784158061143e57508461143c876019612a4b565b145b156114bb57866005018163ffffffff166019811061145e5761145e612800565b602081049091015460ff601f9092166101000a900416156114b6576001876004018263ffffffff166019811061149657611496612800565b602091828204019190066101000a81548160ff0219169083151502179055505b6115d4565b866005018163ffffffff16601981106114d6576114d6612800565b602081049091015460ff601f9092166101000a900416156115d4576001600160a01b038816600090815260096020526040902060019060040163ffffffff83166019811061152657611526612800565b602091828204019190066101000a81548160ff021916908315150217905550600061157a8760196115579190612a4b565b878c8660ff168151811061156d5761156d612800565b602002602001015161208e565b905080156115b85761158d600187612a4b565b95506001858363ffffffff16601981106115a9576115a9612800565b91151560209092020152600093505b6115c36001886129d8565b96506115d0600184612a5e565b9250505b806115de81612833565b915050611419565b50816118755785546001870154611606916001600160a01b031690611ede565b6003548654600188015460405160016292610160e01b031981526001600160a01b038b811660048301529283166024820152604481019190915260006064820181905292919091169063ff6d9eff906084016020604051808303816000875af1158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190612892565b600688015490915060ff16151560000361171057600187015487546040516001600160a01b03808c16937f452848572a392f59c79a54a328cf0b86e82eae605cb9ab28a3e5e5368f7ce2dd936117039391926000929116908a9060048f019084908a90612c5b565b60405180910390a261176d565b600187015487546040516001600160a01b03808c16937f2c4b3bfad3ec9e6453de286795f790bd6bbfc4001caa3102c98862298fcc8daf936117649391926000929116908a9060048f019084908a90612c5b565b60405180910390a25b600460009054906101000a90046001600160a01b03166001600160a01b031663e2382aa160018a8a60000160009054906101000a90046001600160a01b03168b60010154600160006040518763ffffffff1660e01b81526004016117d696959493929190612cab565b600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050506001600160a01b038916600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b03191690556004810182905591506000600583015550600601805460ff1916905550505050505050505050565b6000848152600b602090815260408083208884529091528120546006880154909160ff90911615159003611952576003870180546fffffffffffffffff00000000000000001916600160401b6001600160401b038416021790556000600288015560018701546001600160a01b038916907f452848572a392f59c79a54a328cf0b86e82eae605cb9ab28a3e5e5368f7ce2dd9061271061191582866128d1565b61191f9190612a01565b8a546040516119459392916001600160a01b0316908a9060048f01908990600090612c5b565b60405180910390a2611ae6565b600187015487546001600160a01b0316600061271061197184866128d1565b61197b9190612a01565b90508a6001600160a01b03167f2c4b3bfad3ec9e6453de286795f790bd6bbfc4001caa3102c98862298fcc8daf8483858b8f6004018a60006040516119c69796959493929190612c5b565b60405180910390a26119dc828b60010154611ede565b6119e78b8284611f99565b600460009054906101000a90046001600160a01b03166001600160a01b031663e2382aa160018d8d60000160009054906101000a90046001600160a01b03168e600101546001876040518763ffffffff1660e01b8152600401611a4f96959493929190612cab565b600060405180830381600087803b158015611a6957600080fd5b505af1158015611a7d573d6000803e3d6000fd5b5050506001600160a01b038c16600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b03191690556004810182905591506000600583015550600601805460ff191690555050505b50505050505050505050565b600260005403611b1557604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6005546000906001600160a01b03163303611b3e575060131936013560601c90565b503390565b6040516001600160a01b03838116602483015260448201839052611ba291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506120cf565b505050565b60006001600160a01b038416611bca57506003546001600160a01b031631611c3b565b6003546040516370a0823160e01b81526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa158015611c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c389190612892565b90505b6000828152600b60209081526040808320868452909152812054611c629061271090612a4b565b611c6d83606e6128d1565b611c779190612a01565b905080861115611cba5760405162461bcd60e51b815260206004820152600e60248201526d2a37b79036b0b73c903bb0b3b2b960911b60448201526064016103fa565b505050505050565b600354604051632ff5fe7360e21b81523060048201526001600160a01b0386811660248301529091169063bfd7f9cc90604401602060405180830381865afa158015611d12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d369190612ce7565b611d775760405162461bcd60e51b8152602060048201526012602482015271151bdad95b881b9bdd08185c1c1c9bdd995960721b60448201526064016103fa565b82600003611dc75760405162461bcd60e51b815260206004820152601c60248201527f5761676572206d7573742062652067726561746572207468616e20300000000060448201526064016103fa565b6001600160a01b038416611ded57611de8611de28434612a4b565b8361200c565b611e0c565b611df7348361200c565b611e0c6001600160a01b038516823086612132565b50505050565b6001805460025460405163d291ba0960e01b815260806004820152602860848201527f72617746756c66696c6c52616e646f6d576f7264732875696e743235362c756960a4820152676e743235365b5d2960c01b60c482015260ff8516602482015260448101939093526001600160a01b03908116606484015260009291169063d291ba099060e4016020604051808303816000875af1158015611eba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103999190612892565b6001600160a01b038216611f7f576003546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611f39576040519150601f19603f3d011682016040523d82523d6000602084013e611f3e565b606091505b5050905080611ba25760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b60448201526064016103fa565b60035461037a906001600160a01b03848116911683611b43565b6003546040516336012f6160e11b81526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b50505050505050565b600061201782610c37565b9050808310156120605760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e74207672662066656560601b60448201526064016103fa565b61207261206d8285612a4b565b61216b565b806007600082825461208491906129d8565b9091555050505050565b6000808461209e856127106128d1565b6120a89190612a01565b6120b490612710612a4b565b9050806120c361271085612d04565b119150505b9392505050565b60006120e46001600160a01b038416836121fc565b905080516000141580156121095750808060200190518101906121079190612ce7565b155b15611ba257604051635274afe760e01b81526001600160a01b03841660048201526024016103fa565b6040516001600160a01b038481166024830152838116604483015260648201839052611e0c9186918216906323b872dd90608401611b70565b80156121f957604051600090339083908381818185875af1925050503d80600081146121b3576040519150601f19603f3d011682016040523d82523d6000602084013e6121b8565b606091505b505090508061037a5760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b60448201526064016103fa565b50565b60606120c88383600084600080856001600160a01b031684866040516122229190612d18565b60006040518083038185875af1925050503d806000811461225f576040519150601f19603f3d011682016040523d82523d6000602084013e612264565b606091505b509150915061227486838361227e565b9695505050505050565b6060826122935761228e826122da565b6120c8565b81511580156122aa57506001600160a01b0384163b155b156122d357604051639996b31560e01b81526001600160a01b03851660048201526024016103fa565b50806120c8565b8051156122ea5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001830191839082156123875791602002820160005b83821115612358578335151583826101000a81548160ff0219169083151502179055509260200192600101602081600001049283019260010302612319565b80156123855782816101000a81549060ff0219169055600101602081600001049283019260010302612358565b505b50610f2f929150612447565b60405180610120016040528060006001600160a01b03168152602001600081526020016000815260200160006001600160401b0316815260200160006001600160401b03168152602001600060ff1681526020016123ef612428565b81526020016123fc612428565b8152600060209091015290565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b5b80821115610f2f5760008155600101612448565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561248557600080fd5b823591506020808401356001600160401b03808211156124a457600080fd5b818601915086601f8301126124b857600080fd5b8135818111156124ca576124ca61245c565b8060051b604051601f19603f830116810181811085821117156124ef576124ef61245c565b60405291825284820192508381018501918983111561250d57600080fd5b938501935b8285101561252b57843584529385019392850192612512565b8096505050505050509250929050565b6000806040838503121561254e57600080fd5b50508035926020909101359150565b6001600160a01b03811681146121f957600080fd5b60006020828403121561258457600080fd5b81356120c88161255d565b80610320810183101561039957600080fd5b80151581146121f957600080fd5b60008060008060006103a086880312156125c857600080fd5b8535945060208601356125da8161255d565b9350604086013560ff811681146125f057600080fd5b92506125ff876060880161258f565b9150610380860135612610816125a1565b809150509295509295909350565b8060005b6019811015611e0c5781511515845260209384019390910190600101612622565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151610720830191612684908401826001600160401b03169052565b50608083015161269f60808401826001600160401b03169052565b5060a08301516126b460a084018260ff169052565b5060c08301516126c760c084018261261e565b5060e08301516126db6103e084018261261e565b506101008301518015156107008401525b5092915050565b60006020828403121561270557600080fd5b5035919050565b6103008101818360005b6018811015612735578151835260209283019290910190600101612716565b50505092915050565b600080610340838503121561275257600080fd5b61275c848461258f565b915061032083013561276d816125a1565b809150509250929050565b6020808252600b908201526a4e6f7420706c6179696e6760a81b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6001600160401b038181168382160190808211156126ec576126ec61279d565b60208082526013908201527215d85a5d1a5b99c8159491881c995c5d595cdd606a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561282857600080fd5b81356120c8816125a1565b600063ffffffff80831681810361284c5761284c61279d565b6001019392505050565b600060ff821660ff810361286c5761286c61279d565b60010192915050565b60006020828403121561288757600080fd5b81516120c88161255d565b6000602082840312156128a457600080fd5b5051919050565b6000602082840312156128bd57600080fd5b815163ffffffff811681146120c857600080fd5b80820281158282048414176103995761039961279d565b600181815b808511156129235781600019048211156129095761290961279d565b8085161561291657918102915b93841c93908002906128ed565b509250929050565b60008261293a57506001610399565b8161294757506000610399565b816001811461295d576002811461296757612983565b6001915050610399565b60ff8411156129785761297861279d565b50506001821b610399565b5060208310610133831016604e8410600b84101617156129a6575081810a610399565b6129b083836128e8565b80600019048211156129c4576129c461279d565b029392505050565b60006120c8838361292b565b808201808211156103995761039961279d565b634e487b7160e01b600052601260045260246000fd5b600082612a1057612a106129eb565b500490565b600060018201612a2757612a2761279d565b5060010190565b63ffffffff8181168382160190808211156126ec576126ec61279d565b818103818111156103995761039961279d565b60ff81811683821601908111156103995761039961279d565b805460ff80821615158452612a9560208501828460081c1615159052565b612aa860408501828460101c1615159052565b612abb60608501828460181c1615159052565b612ace60808501828460201c1615159052565b612ae160a08501828460281c1615159052565b612af460c08501828460301c1615159052565b612b0760e08501828460381c1615159052565b612b1b6101008501828460401c1615159052565b612b2f6101208501828460481c1615159052565b612b436101408501828460501c1615159052565b612b576101608501828460581c1615159052565b612b6b6101808501828460601c1615159052565b612b7f6101a08501828460681c1615159052565b612b936101c08501828460701c1615159052565b612ba76101e08501828460781c1615159052565b612bbb6102008501828460801c1615159052565b612bcf6102208501828460881c1615159052565b612be36102408501828460901c1615159052565b612bf76102608501828460981c1615159052565b612c0b6102808501828460a01c1615159052565b612c1f6102a08501828460a81c1615159052565b612c336102c08501828460b01c1615159052565b612c476102e08501828460b81c1615159052565b611e0c6103008501828460c01c1615159052565b878152602081018790526001600160a01b03861660408201526106e08101612c86606083018761261e565b612c94610380830186612a77565b6106a08201939093526106c0015295945050505050565b63ffffffff9690961686526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b600060208284031215612cf957600080fd5b81516120c8816125a1565b600082612d1357612d136129eb565b500690565b6000825160005b81811015612d395760208186018101518583015201612d1f565b50600092019182525091905056fea2646970667358221220699e3e8d3950edaf4536a1a149d0bfbe3986929b4bb2e79e288c484cb9112f9364736f6c63430008140033000000000000000000000000589b45f2c65796fc60b1b61802b10d7c7de86cc70000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c2120000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c21200000000000000000000000027280e40b343995210ce79ca04000e753fa6d031
Deployed Bytecode
0x6080604052600436106101095760003560e01c806376fca03d11610095578063a3e56fa811610064578063a3e56fa8146102cf578063a50ce2f7146102ef578063a5ef362a1461030f578063efbe1c1c14610331578063fea52f101461034657600080fd5b806376fca03d1461024c5780637da0a8771461027957806380cfa527146102995780638bd16114146102af57600080fd5b806336e51f72116100dc57806336e51f72146101b0578063572b6c05146101d0578063590e1ae31461020f57806359cd33271461022457806374b0a7891461023757600080fd5b8063083b27321461010e5780630c657eb01461014b5780631fe543e31461016b578063337161941461018d575b600080fd5b34801561011a57600080fd5b5060045461012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561015757600080fd5b5060035461012e906001600160a01b031681565b34801561017757600080fd5b5061018b610186366004612472565b610359565b005b34801561019957600080fd5b506101a2601081565b604051908152602001610142565b3480156101bc57600080fd5b506101a26101cb36600461253b565b61037e565b3480156101dc57600080fd5b506101ff6101eb366004612572565b6005546001600160a01b0391821691161490565b6040519015158152602001610142565b34801561021b57600080fd5b5061018b61039f565b61018b6102323660046125af565b610634565b34801561024357600080fd5b5061018b61098b565b34801561025857600080fd5b5061026c610267366004612572565b610af6565b6040516101429190612643565b34801561028557600080fd5b5060055461012e906001600160a01b031681565b3480156102a557600080fd5b506101a260075481565b3480156102bb57600080fd5b506101a26102ca3660046126f3565b610c37565b3480156102db57600080fd5b5060015461012e906001600160a01b031681565b3480156102fb57600080fd5b5060025461012e906001600160a01b031681565b34801561031b57600080fd5b50610324610ed4565b604051610142919061270c565b34801561033d57600080fd5b5061018b610f33565b61018b61035436600461273e565b6110ad565b6001546001600160a01b0316331461037057600080fd5b61037a828261133f565b5050565b6000828152600b602090815260408083208484529091529020545b92915050565b6103a7611af2565b60006103b1611b1c565b6001600160a01b0381166000908152600960205260408120600381015492935091600160801b900460ff1690036104035760405162461bcd60e51b81526004016103fa90612778565b60405180910390fd5b80600201546000036104575760405162461bcd60e51b815260206004820152601760248201527f4e6f742077616974696e6720565246207265717565737400000000000000000060448201526064016103fa565b60038101544390610474906103e8906001600160401b03166127b3565b61047f90600a6127b3565b6001600160401b031611156104c25760405162461bcd60e51b8152602060048201526009602482015268546f6f206561726c7960b81b60448201526064016103fa565b6001810154336000908152600960205260409020546001600160a01b03168061057557604051600090339084908381818185875af1925050503d8060008114610527576040519150601f19603f3d011682016040523d82523d6000602084013e61052c565b606091505b505090508061056f5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016103fa565b50610589565b6105896001600160a01b0382163384611b43565b604080518381526001600160a01b038316602082015233917f9177b7a6097b17a0f6566e1246faed203766b45045bc76865977cd251c658cf0910160405180910390a2505033600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b0319169055600481018290556005810191909155600601805460ff191690555061063290506001600055565b565b61063c611af2565b6000610646611b1c565b90508360ff16600111158015610660575060188460ff1611155b6106b65760405162461bcd60e51b815260206004820152602160248201527f6e756d4d696e6573206d757374206265206265747765656e203820616e6420316044820152601b60f91b60648201526084016103fa565b6001600160a01b038116600090815260096020526040902060020154156106ef5760405162461bcd60e51b81526004016103fa906127d3565b6001600160a01b038116600090815260096020526040902060030154600160801b900460ff16156107545760405162461bcd60e51b815260206004820152600f60248201526e416c726561647920706c6179696e6760881b60448201526064016103fa565b6000805b60198160ff1610156107b157848160ff166019811061077957610779612800565b60200201602081019061078c9190612816565b1561079f578161079b81612833565b9250505b806107a981612856565b915050610758565b5060ff85166000908152600c602052604090205463ffffffff821615806107dd5750808263ffffffff16115b1561081e5760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1bc81c995d99585b607a1b60448201526064016103fa565b61082d8888838960ff16611ba7565b61083c87896207a12086611cc2565b600061084783611e12565b6000818152600a6020908152604080832080546001600160a01b03199081166001600160a01b038b811691821790935585526009909352922060038101805460ff60801b1916600160801b60ff8e1602179055600181018d90558054909116918b1691909117815560068101805460ff19168815151790559091506108d160058201886019612303565b506002810182905560038101805467ffffffffffffffff1916436001600160401b0316179055600480546040516327ffe84360e01b815260019281018390526001600160a01b0388811660248301528c81166044830152606482018e905260848201939093529116906327ffe8439060a401600060405180830381600087803b15801561095d57600080fd5b505af1158015610971573d6000803e3d6000fd5b5050505050505050506109846001600055565b5050505050565b610993611af2565b600360009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0a9190612875565b6001600160a01b0316336001600160a01b031614610a565760405162461bcd60e51b81526020600482015260096024820152682737ba1027bbb732b960b91b60448201526064016103fa565b60078054600091829055604051909190339083908381818185875af1925050503d8060008114610aa2576040519150601f19603f3d011682016040523d82523d6000602084013e610aa7565b606091505b5050905080610aea5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064016103fa565b50506106326001600055565b610afe612393565b6001600160a01b0382811660009081526009602090815260408083208151610120810183528154909516855260018101549285019290925260028201548482015260038201546001600160401b038082166060870152600160401b8204166080860152600160801b900460ff1660a08501528051610320810191829052919260c0850192916004850191601991908390855b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610b905750505092845250506040805161032081019182905260209093019291506005840190601990826000855b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411610be8575050509284525050506006919091015460ff16151560209091015292915050565b600080600f602160991b016001600160a01b031663519b4bd36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca39190612892565b6010600f602160991b016001600160a01b031663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e91906128ab565b63ffffffff16610d1e91906128d1565b610d2891906128d1565b90506000600f602160991b016001600160a01b031663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d959190612892565b600f602160991b016001600160a01b03166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfe91906128ab565b63ffffffff16610e0e91906128d1565b90506000600f602160991b016001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7b9190612892565b610e8690600a6129cc565b610e919060106128d1565b610e9b83856129d8565b610ea790611a2c6128d1565b610eb19190612a01565b905080610ec186620f433c6128d1565b610ecb91906129d8565b95945050505050565b610edc612409565b60005b6018811015610f2f57600c6000610ef78360016129d8565b815260200190815260200160002054828260188110610f1857610f18612800565b602002015280610f2781612a15565b915050610edf565b5090565b610f3b611af2565b33600090815260096020526040812060038101549091600160801b90910460ff169003610f7a5760405162461bcd60e51b81526004016103fa90612778565b600281015415610f9c5760405162461bcd60e51b81526004016103fa906127d3565b60038101546001820154600160401b9091046001600160401b0316906000612710610fc783856128d1565b610fd19190612a01565b84549091506001600160a01b0316610fe98184611ede565b33600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b031916905560048101829055906000600583015550600601805460ff1916905561104c338383611f99565b60408051848152602081018490526001600160a01b0383168183015260608101869052905133917f57317678548d469552350099a23c37dc29501a40c2705d61262dd7e2f4f7a454919081900360800190a250505050506106326001600055565b6110b5611af2565b33600090815260096020526040812060038101549091600160801b90910460ff1690036110f45760405162461bcd60e51b81526004016103fa90612778565b6002810154156111165760405162461bcd60e51b81526004016103fa906127d3565b6000806000805b60198160ff1610156111f357868160ff166019811061113e5761113e612800565b6020020160208101906111519190612816565b156111a057846004018160ff166019811061116e5761116e612800565b602081049091015460ff601f9092166101000a9004161561119257600191506111f3565b8261119c81612833565b9350505b846004018160ff16601981106111b8576111b8612800565b602081049091015460ff601f9092166101000a900416156111e157836111dd81612833565b9450505b806111eb81612856565b91505061111d565b50801561123a5760405162461bcd60e51b8152602060048201526015602482015274151a5b1948185b1c9958591e481c995d99585b1959605a1b60448201526064016103fa565b63ffffffff8216158061127857506003840154600160801b900460ff166000908152600c60205260409020546112708484612a2e565b63ffffffff16115b156112b95760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d1bc81c995d99585b607a1b60448201526064016103fa565b6112c6346207a12061200c565b60006112d183611e12565b6000818152600a6020526040902080546001600160a01b03191633179055905061130060058601886019612303565b5060068501805460ff19168715151790556002850155505050600301805467ffffffffffffffff1916436001600160401b031617905560016000555050565b6000828152600a60205260409020546001600160a01b03168061136157600080fd5b6000838152600a6020908152604080832080546001600160a01b03191690556001600160a01b03841683526009909152812090805b60198163ffffffff1610156113fb57826004018163ffffffff16601981106113c0576113c0612800565b602081049091015460ff601f9092166101000a900416156113e9576113e66001836129d8565b91505b806113f381612833565b915050611396565b506003820154600160801b900460ff16611413612428565b60016000805b60198163ffffffff1610156115e65784158061143e57508461143c876019612a4b565b145b156114bb57866005018163ffffffff166019811061145e5761145e612800565b602081049091015460ff601f9092166101000a900416156114b6576001876004018263ffffffff166019811061149657611496612800565b602091828204019190066101000a81548160ff0219169083151502179055505b6115d4565b866005018163ffffffff16601981106114d6576114d6612800565b602081049091015460ff601f9092166101000a900416156115d4576001600160a01b038816600090815260096020526040902060019060040163ffffffff83166019811061152657611526612800565b602091828204019190066101000a81548160ff021916908315150217905550600061157a8760196115579190612a4b565b878c8660ff168151811061156d5761156d612800565b602002602001015161208e565b905080156115b85761158d600187612a4b565b95506001858363ffffffff16601981106115a9576115a9612800565b91151560209092020152600093505b6115c36001886129d8565b96506115d0600184612a5e565b9250505b806115de81612833565b915050611419565b50816118755785546001870154611606916001600160a01b031690611ede565b6003548654600188015460405160016292610160e01b031981526001600160a01b038b811660048301529283166024820152604481019190915260006064820181905292919091169063ff6d9eff906084016020604051808303816000875af1158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190612892565b600688015490915060ff16151560000361171057600187015487546040516001600160a01b03808c16937f452848572a392f59c79a54a328cf0b86e82eae605cb9ab28a3e5e5368f7ce2dd936117039391926000929116908a9060048f019084908a90612c5b565b60405180910390a261176d565b600187015487546040516001600160a01b03808c16937f2c4b3bfad3ec9e6453de286795f790bd6bbfc4001caa3102c98862298fcc8daf936117649391926000929116908a9060048f019084908a90612c5b565b60405180910390a25b600460009054906101000a90046001600160a01b03166001600160a01b031663e2382aa160018a8a60000160009054906101000a90046001600160a01b03168b60010154600160006040518763ffffffff1660e01b81526004016117d696959493929190612cab565b600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050506001600160a01b038916600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b03191690556004810182905591506000600583015550600601805460ff1916905550505050505050505050565b6000848152600b602090815260408083208884529091528120546006880154909160ff90911615159003611952576003870180546fffffffffffffffff00000000000000001916600160401b6001600160401b038416021790556000600288015560018701546001600160a01b038916907f452848572a392f59c79a54a328cf0b86e82eae605cb9ab28a3e5e5368f7ce2dd9061271061191582866128d1565b61191f9190612a01565b8a546040516119459392916001600160a01b0316908a9060048f01908990600090612c5b565b60405180910390a2611ae6565b600187015487546001600160a01b0316600061271061197184866128d1565b61197b9190612a01565b90508a6001600160a01b03167f2c4b3bfad3ec9e6453de286795f790bd6bbfc4001caa3102c98862298fcc8daf8483858b8f6004018a60006040516119c69796959493929190612c5b565b60405180910390a26119dc828b60010154611ede565b6119e78b8284611f99565b600460009054906101000a90046001600160a01b03166001600160a01b031663e2382aa160018d8d60000160009054906101000a90046001600160a01b03168e600101546001876040518763ffffffff1660e01b8152600401611a4f96959493929190612cab565b600060405180830381600087803b158015611a6957600080fd5b505af1158015611a7d573d6000803e3d6000fd5b5050506001600160a01b038c16600090815260096020526040812080546001600160a01b031916815560018101829055600281018290556003810180546001600160881b03191690556004810182905591506000600583015550600601805460ff191690555050505b50505050505050505050565b600260005403611b1557604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6005546000906001600160a01b03163303611b3e575060131936013560601c90565b503390565b6040516001600160a01b03838116602483015260448201839052611ba291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506120cf565b505050565b60006001600160a01b038416611bca57506003546001600160a01b031631611c3b565b6003546040516370a0823160e01b81526001600160a01b039182166004820152908516906370a0823190602401602060405180830381865afa158015611c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c389190612892565b90505b6000828152600b60209081526040808320868452909152812054611c629061271090612a4b565b611c6d83606e6128d1565b611c779190612a01565b905080861115611cba5760405162461bcd60e51b815260206004820152600e60248201526d2a37b79036b0b73c903bb0b3b2b960911b60448201526064016103fa565b505050505050565b600354604051632ff5fe7360e21b81523060048201526001600160a01b0386811660248301529091169063bfd7f9cc90604401602060405180830381865afa158015611d12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d369190612ce7565b611d775760405162461bcd60e51b8152602060048201526012602482015271151bdad95b881b9bdd08185c1c1c9bdd995960721b60448201526064016103fa565b82600003611dc75760405162461bcd60e51b815260206004820152601c60248201527f5761676572206d7573742062652067726561746572207468616e20300000000060448201526064016103fa565b6001600160a01b038416611ded57611de8611de28434612a4b565b8361200c565b611e0c565b611df7348361200c565b611e0c6001600160a01b038516823086612132565b50505050565b6001805460025460405163d291ba0960e01b815260806004820152602860848201527f72617746756c66696c6c52616e646f6d576f7264732875696e743235362c756960a4820152676e743235365b5d2960c01b60c482015260ff8516602482015260448101939093526001600160a01b03908116606484015260009291169063d291ba099060e4016020604051808303816000875af1158015611eba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103999190612892565b6001600160a01b038216611f7f576003546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611f39576040519150601f19603f3d011682016040523d82523d6000602084013e611f3e565b606091505b5050905080611ba25760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b60448201526064016103fa565b60035461037a906001600160a01b03848116911683611b43565b6003546040516336012f6160e11b81526001600160a01b03858116600483015260248201859052838116604483015290911690636c025ec290606401600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b50505050505050565b600061201782610c37565b9050808310156120605760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e74207672662066656560601b60448201526064016103fa565b61207261206d8285612a4b565b61216b565b806007600082825461208491906129d8565b9091555050505050565b6000808461209e856127106128d1565b6120a89190612a01565b6120b490612710612a4b565b9050806120c361271085612d04565b119150505b9392505050565b60006120e46001600160a01b038416836121fc565b905080516000141580156121095750808060200190518101906121079190612ce7565b155b15611ba257604051635274afe760e01b81526001600160a01b03841660048201526024016103fa565b6040516001600160a01b038481166024830152838116604483015260648201839052611e0c9186918216906323b872dd90608401611b70565b80156121f957604051600090339083908381818185875af1925050503d80600081146121b3576040519150601f19603f3d011682016040523d82523d6000602084013e6121b8565b606091505b505090508061037a5760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b60448201526064016103fa565b50565b60606120c88383600084600080856001600160a01b031684866040516122229190612d18565b60006040518083038185875af1925050503d806000811461225f576040519150601f19603f3d011682016040523d82523d6000602084013e612264565b606091505b509150915061227486838361227e565b9695505050505050565b6060826122935761228e826122da565b6120c8565b81511580156122aa57506001600160a01b0384163b155b156122d357604051639996b31560e01b81526001600160a01b03851660048201526024016103fa565b50806120c8565b8051156122ea5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001830191839082156123875791602002820160005b83821115612358578335151583826101000a81548160ff0219169083151502179055509260200192600101602081600001049283019260010302612319565b80156123855782816101000a81549060ff0219169055600101602081600001049283019260010302612358565b505b50610f2f929150612447565b60405180610120016040528060006001600160a01b03168152602001600081526020016000815260200160006001600160401b0316815260200160006001600160401b03168152602001600060ff1681526020016123ef612428565b81526020016123fc612428565b8152600060209091015290565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b5b80821115610f2f5760008155600101612448565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561248557600080fd5b823591506020808401356001600160401b03808211156124a457600080fd5b818601915086601f8301126124b857600080fd5b8135818111156124ca576124ca61245c565b8060051b604051601f19603f830116810181811085821117156124ef576124ef61245c565b60405291825284820192508381018501918983111561250d57600080fd5b938501935b8285101561252b57843584529385019392850192612512565b8096505050505050509250929050565b6000806040838503121561254e57600080fd5b50508035926020909101359150565b6001600160a01b03811681146121f957600080fd5b60006020828403121561258457600080fd5b81356120c88161255d565b80610320810183101561039957600080fd5b80151581146121f957600080fd5b60008060008060006103a086880312156125c857600080fd5b8535945060208601356125da8161255d565b9350604086013560ff811681146125f057600080fd5b92506125ff876060880161258f565b9150610380860135612610816125a1565b809150509295509295909350565b8060005b6019811015611e0c5781511515845260209384019390910190600101612622565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151610720830191612684908401826001600160401b03169052565b50608083015161269f60808401826001600160401b03169052565b5060a08301516126b460a084018260ff169052565b5060c08301516126c760c084018261261e565b5060e08301516126db6103e084018261261e565b506101008301518015156107008401525b5092915050565b60006020828403121561270557600080fd5b5035919050565b6103008101818360005b6018811015612735578151835260209283019290910190600101612716565b50505092915050565b600080610340838503121561275257600080fd5b61275c848461258f565b915061032083013561276d816125a1565b809150509250929050565b6020808252600b908201526a4e6f7420706c6179696e6760a81b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6001600160401b038181168382160190808211156126ec576126ec61279d565b60208082526013908201527215d85a5d1a5b99c8159491881c995c5d595cdd606a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561282857600080fd5b81356120c8816125a1565b600063ffffffff80831681810361284c5761284c61279d565b6001019392505050565b600060ff821660ff810361286c5761286c61279d565b60010192915050565b60006020828403121561288757600080fd5b81516120c88161255d565b6000602082840312156128a457600080fd5b5051919050565b6000602082840312156128bd57600080fd5b815163ffffffff811681146120c857600080fd5b80820281158282048414176103995761039961279d565b600181815b808511156129235781600019048211156129095761290961279d565b8085161561291657918102915b93841c93908002906128ed565b509250929050565b60008261293a57506001610399565b8161294757506000610399565b816001811461295d576002811461296757612983565b6001915050610399565b60ff8411156129785761297861279d565b50506001821b610399565b5060208310610133831016604e8410600b84101617156129a6575081810a610399565b6129b083836128e8565b80600019048211156129c4576129c461279d565b029392505050565b60006120c8838361292b565b808201808211156103995761039961279d565b634e487b7160e01b600052601260045260246000fd5b600082612a1057612a106129eb565b500490565b600060018201612a2757612a2761279d565b5060010190565b63ffffffff8181168382160190808211156126ec576126ec61279d565b818103818111156103995761039961279d565b60ff81811683821601908111156103995761039961279d565b805460ff80821615158452612a9560208501828460081c1615159052565b612aa860408501828460101c1615159052565b612abb60608501828460181c1615159052565b612ace60808501828460201c1615159052565b612ae160a08501828460281c1615159052565b612af460c08501828460301c1615159052565b612b0760e08501828460381c1615159052565b612b1b6101008501828460401c1615159052565b612b2f6101208501828460481c1615159052565b612b436101408501828460501c1615159052565b612b576101608501828460581c1615159052565b612b6b6101808501828460601c1615159052565b612b7f6101a08501828460681c1615159052565b612b936101c08501828460701c1615159052565b612ba76101e08501828460781c1615159052565b612bbb6102008501828460801c1615159052565b612bcf6102208501828460881c1615159052565b612be36102408501828460901c1615159052565b612bf76102608501828460981c1615159052565b612c0b6102808501828460a01c1615159052565b612c1f6102a08501828460a81c1615159052565b612c336102c08501828460b01c1615159052565b612c476102e08501828460b81c1615159052565b611e0c6103008501828460c01c1615159052565b878152602081018790526001600160a01b03861660408201526106e08101612c86606083018761261e565b612c94610380830186612a77565b6106a08201939093526106c0015295945050505050565b63ffffffff9690961686526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b600060208284031215612cf957600080fd5b81516120c8816125a1565b600082612d1357612d136129eb565b500690565b6000825160005b81811015612d395760208186018101518583015201612d1f565b50600092019182525091905056fea2646970667358221220699e3e8d3950edaf4536a1a149d0bfbe3986929b4bb2e79e288c484cb9112f9364736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000589b45f2c65796fc60b1b61802b10d7c7de86cc70000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c2120000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c21200000000000000000000000027280e40b343995210ce79ca04000e753fa6d031
-----Decoded View---------------
Arg [0] : _vrfCoordinator (address): 0x589b45F2c65796fc60b1b61802B10d7C7de86cc7
Arg [1] : _bankroll (address): 0x4334b45B8eb99b68c37d75ccad4a1559B865c212
Arg [2] : _trustedForwarder (address): 0x4334b45B8eb99b68c37d75ccad4a1559B865c212
Arg [3] : _vrfDepositor (address): 0x27280E40b343995210cE79CA04000e753Fa6d031
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000589b45f2c65796fc60b1b61802b10d7c7de86cc7
Arg [1] : 0000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c212
Arg [2] : 0000000000000000000000004334b45b8eb99b68c37d75ccad4a1559b865c212
Arg [3] : 00000000000000000000000027280e40b343995210ce79ca04000e753fa6d031
Loading...
Loading
OVERVIEW
Mines contract of ZapankiSwap gamesLoading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.