Contract 0xD1CEeee3ecFff60d9532C37c9d24f68cA0E96453

 

Overview

Balance:
0.01 Ether

EtherValue:
$29.19 (@ $2,918.84/ETH)

Token:
Txn Hash Method
Block
From
To
Value
0x0a2dc5436777b238fea396c59d211ec3977455ae9684ca19e0a0e1727481098dSettle Bet59952732018-07-20 1:22:011166 days 10 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.000024047521.02
0x2da78addc5e3a778fd8f7f009e337d5348ba8529caa5ea81f408d5342cffea32Place Bet59952622018-07-20 1:18:501166 days 10 hrs ago0x0d508968c96d6436f8097513a182992d621fa877 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.01 Ether0.0000285041
0xe10dd7932178e302c12c0cc8a1c239e7bec86dbc55cb609c32ab27e06acdc8d4Kill59741382018-07-16 10:08:341170 days 1 hr ago0xd1ceeee271fd5a8b0e2bfc12ea5b5b2e5cedec95 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.000109448
0x545c43d6c84d3e172a1ad3b21dcafe60c26f26132ebbad5b841af0abf363f0afWithdraw Funds59471102018-07-11 21:58:381174 days 13 hrs ago0xd1ceeee271fd5a8b0e2bfc12ea5b5b2e5cedec95 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00086162525
0xb77d4c8dcf286806db26aeedb3c9ddffb0f5ad2e706ea18f691d6ff37118d3edSet Max Profit59470992018-07-11 21:56:411174 days 13 hrs ago0xd1ceeee271fd5a8b0e2bfc12ea5b5b2e5cedec95 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00033987525
0xb6b00149c98c68619791f81360e59fc45b14e584ced077e487cf53c9d2175b3eSettle Bet59461392018-07-11 18:08:591174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069995222
0xf42b689e9abc926d0197aca4c18e7277c75b95d1b5a334377b51a997157ca476Settle Bet59461392018-07-11 18:08:591174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069328622
0x861da5caafe520f67f65975102550e1f8b1b38a8e4a7207058cefc42decbd0e1Settle Bet59461352018-07-11 18:07:581174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069995222
0x13584d57a76c0ccc0465dfb843e538b506cc6d5a40cc4d011c39e6512bd261a1Settle Bet59461332018-07-11 18:07:381174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069194422
0x2712deb2c3651aabd9fa1d9e631eb4e8fca75a9909f6dc47821cee8d6b589c6fSettle Bet59461332018-07-11 18:07:381174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069624034322.09375
0x95bf7fca9504ea5528033236a2fb2d83c1761e6d7c31cc5bbe79d137e2dfb0a4Place Bet59461322018-07-11 18:07:321174 days 17 hrs ago0x145b34e0278aa7fa0deeeee6154a4a5efcfc623b IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.15 Ether0.00178246222
0x0c5ddf0373c59a02ef0aabc2f25812539247fd246579f19edfc6c3d315498c0bPlace Bet59461322018-07-11 18:07:321174 days 17 hrs ago0x915d631d71efb2b20ad1773728f12f76eeeeee23 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.1 Ether0.00179056587522.09375
0x00da4d9870ed3e506b8acc760e9c6ab280dfc4a5cbda2daff00b34a42cd69bf1Settle Bet59461322018-07-11 18:07:321174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069624034322.09375
0x865b908be5832db774b42b7028edd8fe1f1a36775ae8d6a14f6b510bff7249deSettle Bet59461302018-07-11 18:07:131174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00070300103122.09375
0x26a75e3c1a6203cb25c48b504df5718ff0276584db7782589f8b5a3ac7a89f9bPlace Bet59461242018-07-11 18:05:431174 days 17 hrs ago0x145b34e0278aa7fa0deeeee6154a4a5efcfc623b IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.15 Ether0.0017838722
0x763e85b84177abb4b42e925360ce44de6499bf90c87c8d63d6aac16c78cc341ePlace Bet59461172018-07-11 18:03:491174 days 17 hrs ago0x915d631d71efb2b20ad1773728f12f76eeeeee23 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.1 Ether0.00179197987522.09375
0xe4eadad68a6fc7ba5c1a54eadf42954763bf43cd2fecc55b965b4c3960b93477Settle Bet59461162018-07-11 18:03:201174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069891822
0xf807218718dd6c4cc90c95ffdbee1d8974394e335c45677ebd9659b46f5c27cdPlace Bet59461132018-07-11 18:02:541174 days 17 hrs ago0x669fa9e30916e0c244849d4266560fdd6feeeee2 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.15 Ether0.00178437622
0xe35f2ae0e4c1c03b8892972e42d2f5f70e8217d1e06b39d9f9a9c74d35562ff8Settle Bet59461132018-07-11 18:02:541174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00070001822
0x4ea2741e77c99318bc6e4b44aa77b8b99e67faa26dd292351f1e8e55259f5dacPlace Bet59461082018-07-11 18:02:211174 days 17 hrs ago0x669fa9e30916e0c244849d4266560fdd6feeeee2 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.15 Ether0.00178437622
0x6b1539c84a94af622ebdf8cdf5f3ec36097c36dc400c92c9ac22ef6cb4c16dbcPlace Bet59461082018-07-11 18:02:211174 days 17 hrs ago0x145b34e0278aa7fa0deeeee6154a4a5efcfc623b IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.1 Ether0.0017838722
0xc2c71048bda138fb34b5cda457e4830b635633ea50813a22a774cb47fc8c902fSettle Bet59461082018-07-11 18:02:211174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00069995222
0x40ad81086de492821b93c768b1833ce4b9c60cf8c58a3fc65c7a2dfa16326483Place Bet59460982018-07-11 18:00:141174 days 17 hrs ago0xc9c0d3a96b07b9894b904fe57c0480b553aa6ba9 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.1 Ether0.00170278521
0x1b11dd355a3a3c0075d4f5c4536445470a42f392831e1f24b2db38c80804c4b5Place Bet59460982018-07-11 18:00:141174 days 17 hrs ago0x6e5151c00394bacf6caff6e418e36356eeeee901 IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530.1 Ether0.00178809422
0x05e8b8e68854f77617130da9026dec1346843a7e463b3f9f898c9197d656c077Settle Bet59460982018-07-11 18:00:141174 days 17 hrs ago0x00000000c0293c8ca34dac9bcc0f953532d34e4d IN  0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530 Ether0.00070001822
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe10dd7932178e302c12c0cc8a1c239e7bec86dbc55cb609c32ab27e06acdc8d459741382018-07-16 10:08:341170 days 1 hr ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530xd1ceeee271fd5a8b0e2bfc12ea5b5b2e5cedec952.723 Ether
0x545c43d6c84d3e172a1ad3b21dcafe60c26f26132ebbad5b841af0abf363f0af59471102018-07-11 21:58:381174 days 13 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e96453 0xd1ceeee6b94de402e14f24de0871580917ede8a765.780499599064603112 Ether
0xb6b00149c98c68619791f81360e59fc45b14e584ced077e487cf53c9d2175b3e59461392018-07-11 18:08:591174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x145b34e0278aa7fa0deeeee6154a4a5efcfc623b1 wei
0xf42b689e9abc926d0197aca4c18e7277c75b95d1b5a334377b51a997157ca47659461392018-07-11 18:08:591174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x915d631d71efb2b20ad1773728f12f76eeeeee231 wei
0x861da5caafe520f67f65975102550e1f8b1b38a8e4a7207058cefc42decbd0e159461352018-07-11 18:07:581174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x145b34e0278aa7fa0deeeee6154a4a5efcfc623b1 wei
0x13584d57a76c0ccc0465dfb843e538b506cc6d5a40cc4d011c39e6512bd261a159461332018-07-11 18:07:381174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x915d631d71efb2b20ad1773728f12f76eeeeee230.213043478260869564 Ether
0x2712deb2c3651aabd9fa1d9e631eb4e8fca75a9909f6dc47821cee8d6b589c6f59461332018-07-11 18:07:381174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x669fa9e30916e0c244849d4266560fdd6feeeee21 wei
0x00da4d9870ed3e506b8acc760e9c6ab280dfc4a5cbda2daff00b34a42cd69bf159461322018-07-11 18:07:321174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x669fa9e30916e0c244849d4266560fdd6feeeee21 wei
0x865b908be5832db774b42b7028edd8fe1f1a36775ae8d6a14f6b510bff7249de59461302018-07-11 18:07:131174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x145b34e0278aa7fa0deeeee6154a4a5efcfc623b0.196 Ether
0xe4eadad68a6fc7ba5c1a54eadf42954763bf43cd2fecc55b965b4c3960b9347759461162018-07-11 18:03:201174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530xc9c0d3a96b07b9894b904fe57c0480b553aa6ba90.196 Ether
0xe35f2ae0e4c1c03b8892972e42d2f5f70e8217d1e06b39d9f9a9c74d35562ff859461132018-07-11 18:02:541174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x6e5151c00394bacf6caff6e418e36356eeeee9010.160363636363636363 Ether
0xc2c71048bda138fb34b5cda457e4830b635633ea50813a22a774cb47fc8c902f59461082018-07-11 18:02:211174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x6e5151c00394bacf6caff6e418e36356eeeee9011 wei
0x05e8b8e68854f77617130da9026dec1346843a7e463b3f9f898c9197d656c07759460982018-07-11 18:00:141174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530xeab955e8aa1aede4caa9a09e01611022fad898f31.96 Ether
0x6138ea73a56179b868ed55eb9e42fe74a8199ea6f214c3f9615d3ca583cd54a759460942018-07-11 17:58:471174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x6e5151c00394bacf6caff6e418e36356eeeee9011 wei
0xc32271da1ce0b86459f85a4e66916044ea29f706d3453adef659b4cde1e499b859460892018-07-11 17:57:201174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x8d708903efc42eeeee45cba89e9c0b81871ff63a1 wei
0xc0207043a16ffea573b156c9bd168d94ff8abb7b499a935b2d47174f79e7b07a59460862018-07-11 17:56:361174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x8d708903efc42eeeee45cba89e9c0b81871ff63a0.213043478260869564 Ether
0x8ab976a677d8259cf97dffad5ce66dc66132daf9a6e9acafa442a0adcbed248659460772018-07-11 17:54:561174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x9393deeeeef4a3b8fd10b196ce159a8a7b93d3750.080181818181818181 Ether
0x5e27db65b90975f3c802391b97bfbbd860de78681bf8a232c7c1868df26502a459460742018-07-11 17:54:121174 days 17 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x9393deeeeef4a3b8fd10b196ce159a8a7b93d3750.160363636363636363 Ether
0x6aabae76ed6afda402aa3cef8feba0f3d9c02561100bca16e82ee8a3020b9d3059459772018-07-11 17:30:591174 days 18 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x1aecd20831901840169eeeee9ac1b54c7a197aa61 wei
0x3f7dfa94427ab9fa3db926ac4ea466bb399dff1cbaea544520fc0b22f826a86a59459692018-07-11 17:29:201174 days 18 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x1aecd20831901840169eeeee9ac1b54c7a197aa60.282692307692307691 Ether
0x4e4baa221ff98b119f40ac20deadf49f6a62d486d55b04abc50733c7fb4f16ee59458372018-07-11 16:56:051174 days 18 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530xcecf50c281c29c55dee38beeeeecff378f7bcab61 wei
0x7d0e149169ef687c632677f7b6428189f3818712ce3280f380a61009ac87b88659455492018-07-11 15:53:101174 days 19 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x4b7fcf77dceeeeeeb21e5a2283986979e23477ec1 wei
0xcef11f6c2e536340c50bfc263ca0a85bd0e884347e4cfb74a91b082ab0a8ebc559454532018-07-11 15:31:121174 days 20 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x4fed3116eeeeebc81a9f697f5b2b06bc8ed230890.392 Ether
0x1e1ba81639553a7f224c38b86e56ef214ccc15ad98f9a3e41abb28bb4b63ecc259453722018-07-11 15:08:511174 days 20 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x5d9ddb66eeeee088da0a66c17e7054ecd06f47d81 wei
0x5dde14252c8870b235ab93bac40efb73a1bee3cb8c434381499676dfe6f51bdd59453602018-07-11 15:05:431174 days 20 hrs ago 0xd1ceeee3ecfff60d9532c37c9d24f68ca0e964530x5d9ddb66eeeee088da0a66c17e7054ecd06f47d80.294 Ether
[ Download CSV Export 
Loading
Contract Self Destruct called at Txn Hash 0xe10dd7932178e302c12c0cc8a1c239e7bec86dbc55cb609c32ab27e06acdc8d4


Contract Source Code Verified (Exact Match)

Contract Name:
Dice2Win

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2018-07-07
*/

pragma solidity ^0.4.23;

// * dice2.win - fair games that pay Ether.
// * Ethereum smart contract, deployed at 0xD1CEeee3ecFff60d9532C37c9d24f68cA0E96453
// * Uses hybrid commit-reveal + block hash random number generation that is immune
//   to tampering by players, house and miners. Apart from being fully transparent,
//   this also allows arbitrarily high bets.
// * Refer to https://dice2.win/whitepaper.pdf for detailed description and proofs.

contract Dice2Win {
    /// *** Constants section

    // Chance to win jackpot - currently 0.1%
    uint constant JACKPOT_MODULO = 1000;

    // Each bet is deducted 2% amount - 1% is house edge, 1% goes to jackpot fund.
    uint constant HOUSE_EDGE_PERCENT = 2;
    uint constant JACKPOT_FEE_PERCENT = 50;

    // There is a minimum and maximum bets. Minimum is dictated by the gas usage
    // of settlement transactions, and maximum is just some safe & sane number.
    uint constant MIN_BET = 0.01 ether;
    uint constant MAX_AMOUNT = 300000 ether;

    // Bets lower than this amount do not participate in jackpot rolls.
    uint constant MIN_JACKPOT_BET = 0.1 ether;

    // Modulo is a number of equiprobable outcomes in a game:
    //  - 2 for coin flip
    //  - 6 for dice
    //  - 6*6 = 36 for double dice
    //  - 100 for etheroll
    //  - 37 for roulette
    //  etc.
    // It's called so because 256-bit entropy is treated like a huge integer and
    // the remainder of its division by modulo is considered bet outcome.
    uint constant MAX_MODULO = 100;

    // For modulos below this threshold rolls are checked against a bit mask,
    // thus allowing betting on any combination of outcomes. For example, given
    // modulo 6 for dice, 101000 mask (base-2, big endian) means betting on
    // 4 and 6; for games with modulos higher than threshold (Etheroll), a simple
    // limit is used, allowing betting on any outcome in [0, N) range.
    //
    // The specific value is dictated by the fact that 256-bit intermediate
    // multiplication result allows implementing population count efficiently
    // for numbers that are up to 42 bits, and 40 is the highest multiple of
    // eight below 42.
    uint constant MAX_MASK_MODULO = 40;

    // This is a check on bet mask overflow.
    uint constant MAX_BET_MASK = 2 ** MAX_MASK_MODULO;

    // EVM BLOCKHASH opcode can query no further than 256 blocks into the
    // past. Given that settleBet uses block hash of placeBet as one of
    // complementary entropy sources, we cannot process bets older than this
    // threshold. On rare occasions dice2.win croupier may fail to invoke
    // settleBet in this timespan due to technical issues or extreme Ethereum
    // congestion; such bets can be refunded via invoking refundBet.
    uint constant BET_EXPIRATION_BLOCKS = 250;

    // Some deliberately invalid address to initialize the secret signer with.
    // Forces maintainers to invoke setSecretSigner before processing any bets.
    address constant DUMMY_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    // Standard contract ownership transfer.
    address public owner;
    address private nextOwner;

    // Adjustable max bet profit. Used to cap bets against dynamic odds.
    uint public maxProfit;

    // The address corresponding to a private key used to sign placeBet commits.
    address public secretSigner;

    // Accumulated jackpot fund.
    uint128 public jackpotSize;

    // Funds that are locked in potentially winning bets. Prevents contract from
    // committing to bets it cannot pay out.
    uint128 public lockedInBets;

    // A structure representing a single bet.
    struct Bet {
        // Wager amount in wei.
        uint amount;
        // Modulo of a game.
        uint8 modulo;
        // Number of winning outcomes, used to compute winning payment (* modulo/rollUnder),
        // and used instead of mask for games with modulo > MAX_MASK_MODULO.
        uint8 rollUnder;
        // Block number of placeBet tx.
        uint40 placeBlockNumber;
        // Bit mask representing winning bet outcomes (see MAX_MASK_MODULO comment).
        uint40 mask;
        // Address of a gambler, used to pay out winning bets.
        address gambler;
    }

    // Mapping from commits to all currently active & processed bets.
    mapping (uint => Bet) bets;

    // Events that are issued to make statistic recovery easier.
    event FailedPayment(address indexed _beneficiary, uint amount);
    event Payment(address indexed _beneficiary, uint amount);
    event JackpotPayment(address indexed _beneficiary, uint amount);

    // Constructor. Deliberately does not take any parameters.
    constructor () public {
        owner = msg.sender;
        secretSigner = DUMMY_ADDRESS;
    }

    // Standard modifier on methods invokable only by contract owner.
    modifier onlyOwner {
        require (msg.sender == owner);
        _;
    }

    // Standard contract ownership transfer implementation,
    function approveNextOwner(address _nextOwner) external onlyOwner {
        require (_nextOwner != owner);
        nextOwner = _nextOwner;
    }

    function acceptNextOwner() external {
        require (msg.sender == nextOwner);
        owner = nextOwner;
    }

    // Fallback function deliberately left empty. It's primary use case
    // is to top up the bank roll.
    function () public payable {
    }

    // See comment for "secretSigner" variable.
    function setSecretSigner(address newSecretSigner) external onlyOwner {
        secretSigner = newSecretSigner;
    }

    // Change max bet reward. Setting this to zero effectively disables betting.
    function setMaxProfit(uint newMaxProfit) public onlyOwner {
        require (newMaxProfit < MAX_AMOUNT);
        maxProfit = newMaxProfit;
    }

    // This function is used to bump up the jackpot fund. Cannot be used to lower it.
    function increaseJackpot(uint increaseAmount) external onlyOwner {
        require (increaseAmount <= address(this).balance);
        require (jackpotSize + lockedInBets + increaseAmount <= address(this).balance);
        jackpotSize += uint128(increaseAmount);
    }

    // Funds withdrawal to cover costs of dice2.win operation.
    function withdrawFunds(address beneficiary, uint withdrawAmount) external onlyOwner {
        require (withdrawAmount <= address(this).balance);
        require (jackpotSize + lockedInBets + withdrawAmount <= address(this).balance);
        sendFunds(beneficiary, withdrawAmount, withdrawAmount);
    }

    // Contract may be destroyed only when there are no ongoing bets,
    // either settled or refunded. All funds are transferred to contract owner.
    function kill() external onlyOwner {
        require (lockedInBets == 0);
        selfdestruct(owner);
    }

    /// *** Betting logic

    // Bet states:
    //  amount == 0 && gambler == 0 - 'clean' (can place a bet)
    //  amount != 0 && gambler != 0 - 'active' (can be settled or refunded)
    //  amount == 0 && gambler != 0 - 'processed' (can clean storage)

    // Bet placing transaction - issued by the player.
    //  betMask         - bet outcomes bit mask for modulo <= MAX_MASK_MODULO,
    //                    [0, betMask) for larger modulos.
    //  modulo          - game modulo.
    //  commitLastBlock - number of the maximum block where "commit" is still considered valid.
    //  commit          - Keccak256 hash of some secret "reveal" random number, to be supplied
    //                    by the dice2.win croupier bot in the settleBet transaction. Supplying
    //                    "commit" ensures that "reveal" cannot be changed behind the scenes
    //                    after placeBet have been mined.
    //  r, s            - components of ECDSA signature of (commitLastBlock, commit). v is
    //                    guaranteed to always equal 27.
    //
    // Commit, being essentially random 256-bit number, is used as a unique bet identifier in
    // the 'bets' mapping.
    //
    // Commits are signed with a block limit to ensure that they are used at most once - otherwise
    // it would be possible for a miner to place a bet with a known commit/reveal pair and tamper
    // with the blockhash. Croupier guarantees that commitLastBlock will always be not greater than
    // placeBet block number plus BET_EXPIRATION_BLOCKS. See whitepaper for details.
    function placeBet(uint betMask, uint modulo,
                      uint commitLastBlock, uint commit, bytes32 r, bytes32 s) external payable {
        // Check that the bet is in 'clean' state.
        Bet storage bet = bets[commit];
        require (bet.gambler == address(0));

        // Validate input data ranges.
        uint amount = msg.value;
        require (modulo > 1 && modulo <= MAX_MODULO);
        require (amount >= MIN_BET && amount <= MAX_AMOUNT);
        require (betMask > 0 && betMask < MAX_BET_MASK);

        // Check that commit is valid - it has not expired and its signature is valid.
        require (block.number <= commitLastBlock);
        bytes32 signatureHash = keccak256(abi.encodePacked(uint40(commitLastBlock), commit));
        require (secretSigner == ecrecover(signatureHash, 27, r, s));

        uint rollUnder;
        uint mask;

        if (modulo <= MAX_MASK_MODULO) {
            // Small modulo games specify bet outcomes via bit mask.
            // rollUnder is a number of 1 bits in this mask (population count).
            // This magic looking formula is an efficient way to compute population
            // count on EVM for numbers below 2**40. For detailed proof consult
            // the dice2.win whitepaper.
            rollUnder = ((betMask * POPCNT_MULT) & POPCNT_MASK) % POPCNT_MODULO;
            mask = betMask;
        } else {
            // Larger modulos specify the right edge of half-open interval of
            // winning bet outcomes.
            require (betMask > 0 && betMask <= modulo);
            rollUnder = betMask;
        }

        // Winning amount and jackpot increase.
        uint possibleWinAmount = getDiceWinAmount(amount, modulo, rollUnder);
        uint jackpotFee = getJackpotFee(amount);

        // Enforce max profit limit.
        require (possibleWinAmount <= amount + maxProfit);

        // Lock funds.
        lockedInBets += uint128(possibleWinAmount);
        jackpotSize += uint128(jackpotFee);

        // Check whether contract has enough funds to process this bet.
        require (jackpotSize + lockedInBets <= address(this).balance);

        // Store bet parameters on blockchain.
        bet.amount = amount;
        bet.modulo = uint8(modulo);
        bet.rollUnder = uint8(rollUnder);
        bet.placeBlockNumber = uint40(block.number);
        bet.mask = uint40(mask);
        bet.gambler = msg.sender;
    }

    // Settlement transaction - can in theory be issued by anyone, but is designed to be
    // handled by the dice2.win croupier bot. To settle a bet with a specific "commit",
    // settleBet should supply a "reveal" number that would Keccak256-hash to
    // "commit". clean_commit is some previously 'processed' bet, that will be moved into
    // 'clean' state to prevent blockchain bloat and refund some gas.
    function settleBet(uint reveal, uint clean_commit) external {
        // "commit" for bet settlement can only be obtained by hashing a "reveal".
        uint commit = uint(keccak256(abi.encodePacked(reveal)));

        // Fetch bet parameters into local variables (to save gas).
        Bet storage bet = bets[commit];
        uint amount = bet.amount;
        uint modulo = bet.modulo;
        uint rollUnder = bet.rollUnder;
        uint placeBlockNumber = bet.placeBlockNumber;
        address gambler = bet.gambler;

        // Check that bet is in 'active' state.
        require (amount != 0);

        // Check that bet has not expired yet (see comment to BET_EXPIRATION_BLOCKS).
        require (block.number > placeBlockNumber);
        require (block.number <= placeBlockNumber + BET_EXPIRATION_BLOCKS);

        // Move bet into 'processed' state already.
        bet.amount = 0;

        // The RNG - combine "reveal" and blockhash of placeBet using Keccak256. Miners
        // are not aware of "reveal" and cannot deduce it from "commit" (as Keccak256
        // preimage is intractable), and house is unable to alter the "reveal" after
        // placeBet have been mined (as Keccak256 collision finding is also intractable).
        bytes32 entropy = keccak256(abi.encodePacked(reveal, blockhash(placeBlockNumber)));

        // Do a roll by taking a modulo of entropy. Compute winning amount.
        uint dice = uint(entropy) % modulo;
        uint diceWinAmount = getDiceWinAmount(amount, modulo, rollUnder);

        uint diceWin = 0;
        uint jackpotWin = 0;

        // Determine dice outcome.
        if (modulo <= MAX_MASK_MODULO) {
            // For small modulo games, check the outcome against a bit mask.
            if ((2 ** dice) & bet.mask != 0) {
                diceWin = diceWinAmount;
            }

        } else {
            // For larger modulos, check inclusion into half-open interval.
            if (dice < rollUnder) {
                diceWin = diceWinAmount;
            }

        }

        // Unlock the bet amount, regardless of the outcome.
        lockedInBets -= uint128(diceWinAmount);

        // Roll for a jackpot (if eligible).
        if (amount >= MIN_JACKPOT_BET) {
            // The second modulo, statistically independent from the "main" dice roll.
            // Effectively you are playing two games at once!
            uint jackpotRng = (uint(entropy) / modulo) % JACKPOT_MODULO;

            // Bingo!
            if (jackpotRng == 0) {
                jackpotWin = jackpotSize;
                jackpotSize = 0;
            }
        }

        // Tally up the win.
        uint totalWin = diceWin + jackpotWin;

        if (totalWin == 0) {
            totalWin = 1 wei;
        }

        // Log jackpot win.
        if (jackpotWin > 0) {
            emit JackpotPayment(gambler, jackpotWin);
        }

        // Send the funds to gambler.
        sendFunds(gambler, totalWin, diceWin);

        // Clear storage of some previous bet.
        if (clean_commit == 0) {
            return;
        }

        clearProcessedBet(clean_commit);
    }

    // Refund transaction - return the bet amount of a roll that was not processed in a
    // due timeframe. Processing such blocks is not possible due to EVM limitations (see
    // BET_EXPIRATION_BLOCKS comment above for details). In case you ever find yourself
    // in a situation like this, just contact the dice2.win support, however nothing
    // precludes you from invoking this method yourself.
    function refundBet(uint commit) external {
        // Check that bet is in 'active' state.
        Bet storage bet = bets[commit];
        uint amount = bet.amount;

        require (amount != 0);

        // Check that bet has already expired.
        require (block.number > bet.placeBlockNumber + BET_EXPIRATION_BLOCKS);

        // Move bet into 'processed' state, release funds.
        bet.amount = 0;
        lockedInBets -= uint128(getDiceWinAmount(amount, bet.modulo, bet.rollUnder));

        // Send the refund.
        sendFunds(bet.gambler, amount, amount);
    }

    // A helper routine to bulk clean the storage.
    function clearStorage(uint[] clean_commits) external {
        uint length = clean_commits.length;

        for (uint i = 0; i < length; i++) {
            clearProcessedBet(clean_commits[i]);
        }
    }

    // Helper routine to move 'processed' bets into 'clean' state.
    function clearProcessedBet(uint commit) private {
        Bet storage bet = bets[commit];

        // Do not overwrite active bets with zeros; additionally prevent cleanup of bets
        // for which commit signatures may have not expired yet (see whitepaper for details).
        if (bet.amount != 0 || block.number <= bet.placeBlockNumber + BET_EXPIRATION_BLOCKS) {
            return;
        }

        // Zero out the remaining storage (amount was zeroed before, delete would consume 5k
        // more gas).
        bet.modulo = 0;
        bet.rollUnder = 0;
        bet.placeBlockNumber = 0;
        bet.mask = 0;
        bet.gambler = address(0);
    }

    // Get the expected win amount after house edge is subtracted.
    function getDiceWinAmount(uint amount, uint modulo, uint rollUnder) pure private returns (uint) {
        require (0 < rollUnder && rollUnder <= modulo);
        return amount * modulo / rollUnder * (100 - HOUSE_EDGE_PERCENT) / 100;
    }

    // Get the portion of bet amount that is to be accumulated in the jackpot.
    function getJackpotFee(uint amount) pure private returns (uint) {
        return amount * HOUSE_EDGE_PERCENT / 100 * JACKPOT_FEE_PERCENT / 100;
    }

    // Helper routine to process the payment.
    function sendFunds(address beneficiary, uint amount, uint successLogAmount) private {
        if (beneficiary.send(amount)) {
            emit Payment(beneficiary, successLogAmount);
        } else {
            emit FailedPayment(beneficiary, amount);
        }
    }

    // This are some constants making O(1) population count in placeBet possible.
    // See whitepaper for intuition and proofs behind it.
    uint constant POPCNT_MULT = 1 + 2**41 + 2**(41*2) + 2**(41*3) + 2**(41*4) + 2**(41*5);
    uint constant POPCNT_MASK = 1 + 2**(6*1) + 2**(6*2) + 2**(6*3) + 2**(6*4) + 2**(6*5)
        + 2**(6*6) + 2**(6*7) + 2**(6*8) + 2**(6*9) + 2**(6*10) + 2**(6*11) + 2**(6*12)
        + 2**(6*13) + 2**(6*14) + 2**(6*15) + 2**(6*16) + 2**(6*17) + 2**(6*18) + 2**(6*19)
        + 2**(6*20) + 2**(6*21) + 2**(6*22) + 2**(6*23) + 2**(6*24) + 2**(6*25) + 2**(6*26)
        + 2**(6*27) + 2**(6*28) + 2**(6*29) + 2**(6*30) + 2**(6*31) + 2**(6*32) + 2**(6*33)
        + 2**(6*34) + 2**(6*35) + 2**(6*36) + 2**(6*37) + 2**(6*38) + 2**(6*39) + 2**(6*40);

    uint constant POPCNT_MODULO = 2**6 - 1;

}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"reveal","type":"uint256"},{"name":"clean_commit","type":"uint256"}],"name":"settleBet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secretSigner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"jackpotSize","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"betMask","type":"uint256"},{"name":"modulo","type":"uint256"},{"name":"commitLastBlock","type":"uint256"},{"name":"commit","type":"uint256"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"placeBet","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxProfit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"withdrawAmount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"acceptNextOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nextOwner","type":"address"}],"name":"approveNextOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"increaseAmount","type":"uint256"}],"name":"increaseJackpot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newSecretSigner","type":"address"}],"name":"setSecretSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lockedInBets","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"commit","type":"uint256"}],"name":"refundBet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"clean_commits","type":"uint256[]"}],"name":"clearStorage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newMaxProfit","type":"uint256"}],"name":"setMaxProfit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"FailedPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Payment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"JackpotPayment","type":"event"}]

608060405234801561001057600080fd5b5060008054600160a060020a031990811633179091556003805490911673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee179055610e95806100546000396000f3006080604052600436106100e55763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630d2cbe1381146100e757806341c0e1b5146101025780634d61537f1461011757806357246d23146101485780635e83b463146101795780638da5cb5b14610193578063b539cd55146101a8578063c1075329146101cf578063d06c54fb146101f3578063d579fd4414610208578063d6d30a5114610229578063d702087f14610241578063df88126f14610262578063e1fdb4b414610277578063ef1155421461028f578063fbd668a9146102af575b005b3480156100f357600080fd5b506100e56004356024356102c7565b34801561010e57600080fd5b506100e561060c565b34801561012357600080fd5b5061012c61064e565b60408051600160a060020a039092168252519081900360200190f35b34801561015457600080fd5b5061015d61065d565b604080516001608060020a039092168252519081900360200190f35b6100e560043560243560443560643560843560a43561066c565b34801561019f57600080fd5b5061012c610a02565b3480156101b457600080fd5b506101bd610a11565b60408051918252519081900360200190f35b3480156101db57600080fd5b506100e5600160a060020a0360043516602435610a17565b3480156101ff57600080fd5b506100e5610a79565b34801561021457600080fd5b506100e5600160a060020a0360043516610ac1565b34801561023557600080fd5b506100e5600435610b22565b34801561024d57600080fd5b506100e5600160a060020a0360043516610ba5565b34801561026e57600080fd5b5061015d610beb565b34801561028357600080fd5b506100e5600435610c01565b34801561029b57600080fd5b506100e56004803560248101910135610cb2565b3480156102bb57600080fd5b506100e5600435610ce7565b6000806000806000806000806000806000806000808f604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061032b5780518252601f19909201916020918201910161030c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600190049d50600560008f81526020019081526020016000209c508c600001549b508c60010160009054906101000a900460ff1660ff169a508c60010160019054906101000a900460ff1660ff1699508c60010160029054906101000a900464ffffffffff1664ffffffffff1698508c600101600c9054906101000a9004600160a060020a031697508b6000141515156103f157600080fd5b4389106103fd57600080fd5b60fa890143111561040d57600080fd5b60008d600001819055508f8940604051602001808381526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b602083106104775780518252601f199092019160209182019101610458565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912099508d9250899150508115156104b257fe5b0695506104c08c8c8c610d19565b94506000935083925060288b116104fd5760018d0154600287900a6701000000000000009091041664ffffffffff16156104f8578493505b610509565b89861015610509578493505b600480546001608060020a03608060020a8083048216899003821602911617905567016345785d8a00008c10610582576103e88b8881151561054757fe5b0481151561055157fe5b06915081151561058257600480546fffffffffffffffffffffffffffffffff1981169091556001608060020a031692505b50828201801515610591575060015b60008311156105da57604080518481529051600160a060020a038a16917fc388db0e8aa560a59633c094a0d0aa21322cd6234836fd5bac00fc5ae63b5783919081900360200190a25b6105e5888286610d5b565b8e15156105f1576105fa565b6105fa8f610e0d565b50505050505050505050505050505050565b600054600160a060020a0316331461062357600080fd5b600454608060020a90046001608060020a03161561064057600080fd5b600054600160a060020a0316ff5b600354600160a060020a031681565b6004546001608060020a031681565b60008381526005602052604081206001810154909190819081908190819081906c010000000000000000000000009004600160a060020a0316156106af57600080fd5b34955060018c1180156106c3575060648c11155b15156106ce57600080fd5b662386f26fc1000086101580156106ef5750693f870857a3e0e38000008611155b15156106fa57600080fd5b60008d11801561070f5750650100000000008d105b151561071a57600080fd5b438b101561072757600080fd5b8a8a604051602001808364ffffffffff1664ffffffffff167b01000000000000000000000000000000000000000000000000000000028152600501828152602001925050506040516020818303038152906040526040518082805190602001908083835b602083106107aa5780518252601f19909201916020918201910161078b565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450600185601b8b8b604051600081526020016040526040518085600019166000191681526020018460ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000865af115801561084e573d6000803e3d6000fd5b5050604051601f190151600354600160a060020a03908116911614905061087457600080fd5b60288c116108c757603f7920000000001000000000080000000004000000000200000000018e027e01041041041041041041041041041041041041041041041041041041041041160693508c92506108e6565b60008d1180156108d757508b8d11155b15156108e257600080fd5b8c93505b6108f1868d86610d19565b91506108fc86610e54565b600254909150860182111561091057600080fd5b600480546001608060020a03608060020a808304821686018216810292821692909217808216850182166fffffffffffffffffffffffffffffffff1991909116179283905530318382169290930481169190910116111561097057600080fd5b50509284556001909301805460ff191660ff998a161761ff00191661010099909416989098029290921766ffffffffff00001916620100004364ffffffffff90811691909102919091176bffffffffff0000000000000019166701000000000000009190921602176bffffffffffffffffffffffff16336c010000000000000000000000000217909555505050505050565b600054600160a060020a031681565b60025481565b600054600160a060020a03163314610a2e57600080fd5b3031811115610a3c57600080fd5b60045430316001608060020a03808316608060020a90930481169290920190911682011115610a6a57600080fd5b610a75828283610d5b565b5050565b600154600160a060020a03163314610a9057600080fd5b6001546000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b600054600160a060020a03163314610ad857600080fd5b600054600160a060020a0382811691161415610af357600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a03163314610b3957600080fd5b3031811115610b4757600080fd5b60045430316001608060020a03808316608060020a90930481169290920190911682011115610b7557600080fd5b600480546fffffffffffffffffffffffffffffffff1981166001608060020a039182169390930116919091179055565b600054600160a060020a03163314610bbc57600080fd5b6003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454608060020a90046001608060020a031681565b60008181526005602052604090208054801515610c1d57600080fd5b600182015464ffffffffff620100009091041660fa014311610c3e57600080fd5b600082556001820154610c5e90829060ff80821691610100900416610d19565b600480546001608060020a03808216608060020a9283900482169490940316029190911790556001820154610cad906c010000000000000000000000009004600160a060020a03168280610d5b565b505050565b8060005b81811015610ce157610cd9848483818110610ccd57fe5b90506020020135610e0d565b600101610cb6565b50505050565b600054600160a060020a03163314610cfe57600080fd5b693f870857a3e0e38000008110610d1457600080fd5b600255565b6000816000108015610d2b5750828211155b1515610d3657600080fd5b6064606283868602811515610d4757fe5b0402811515610d5257fe5b04949350505050565b604051600160a060020a0384169083156108fc029084906000818181858888f1935050505015610dc957604080518281529051600160a060020a038516917fd4f43975feb89f48dd30cabbb32011045be187d1e11c8ea9faa43efc35282519919081900360200190a2610cad565b604080518381529051600160a060020a038516917fac464fe4d3a86b9121261ac0a01dd981bfe0777c7c9d9c8f4473d31a9c0f9d2d919081900360200190a2505050565b60008181526005602052604090208054151580610e3f5750600181015464ffffffffff620100009091041660fa014311155b15610e4957610a75565b600060018201555050565b600060646002830281900460320204929150505600a165627a7a7230582000c2ed2604650f52891f7c4760d2f0b35d666799b57347cafb826dc35d6da08f0029

Swarm Source

bzzr://00c2ed2604650f52891f7c4760d2f0b35d666799b57347cafb826dc35d6da08f
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.