There is a contract with a betting function that calculates a random number and send you back a reward if winning. The betting function looks like:
function bet() public payable
{
if ((random()%2==1) && (msg.value == 1 ether))
{
if (!msg.sender.call.value(2 ether)())
throw;
}
}
function random() view returns (uint8) {
return uint8(uint256(keccak256(block.timestamp, block.difficulty))%256);
}
So if you send 1 ether and hit an odd number (50% chance) you will get back 2 ether. Now I want to precalculate the random number and bet if the number is odd. I am trying that with a contract like this:
BadRandomBetContract private bet_;
function win() public payable onlyOwner {
uint8 rnd = bet_.random(); // retrieve "random" number
require(rnd % 2 == 1); // odd number
require(msg.value == 1 ether);
bet_.bet.value(msg.value)(); // send 1 ether
require(getBalance() == 2 ether); // make sure we got 2 ether back, else revert
}
function getBalance() public view returns(uint256) {
return address(this).balance;
}
When the winning contract sends 1 ether, transaction fails afterwards. Sending 1 ether at least means the requirement require(rnd % 2 == 1);
passed. May it fail at this point require(getBalance() == 2 ether);
because the balance does not get updated immediately? Shall I check msg.value
in contracts fallback function?
The fail tx is from mainnet and the working one is from ropsten
getBalance()
before and after, and make sure that the difference is 2 ether.