capture the ether靶场题解(Math)

Token sale

分析

题目代码:

pragma solidity ^0.4.21;

contract TokenSaleChallenge {
   
    mapping(address => uint256) public balanceOf;
    uint256 constant PRICE_PER_TOKEN = 1 ether;

    function TokenSaleChallenge(address _player) public payable {
   
        require(msg.value == 1 ether);
    }

    function isComplete() public view returns (bool) {
   
        return address(this).balance < 1 ether;
    }

    function buy(uint256 numTokens) public payable {
   
        require(msg.value == numTokens * PRICE_PER_TOKEN);

        balanceOf[msg.sender] += numTokens;
    }

    function sell(uint256 numTokens) public {
   
        require(balanceOf[msg.sender] >= numTokens);

        balanceOf[msg.sender] -= numTokens;
        msg.sender.transfer(numTokens * PRICE_PER_TOKEN);
    }
}

目标依然是调用isComplete函数,此题中就是需要题目合约的余额小于1ether。
由于属于math系列,所以我看的时候对运算很敏锐,很容易就能发现require(msg.value == numTokens * PRICE_PER_TOKEN);会存在一个很明显的溢出,只要我们numTokens传的足够大,在乘以10**18次方后,我们的msg.value就能够超过这个溢出之后的值,我们的余额就会变得非常巨大。

攻击

攻击合约:

contract attack{
   
    uint256 max = 2**256-1;
    uint256 public num1;
    uint256 public num2;
    function att()public{
   
        num1 = max/10**18;
        num2 = (num1+1)*10**18;
    }
}

攻击合约没啥目的,只是为了算出多大的数可以溢出,以及我们需要付出多少的value。
在这里插入图片描述
我们在buy中传入num1+1,并给出比num2相等或更多的wei,就能够让我们的余额发生溢出。
在这里插入图片描述
如图所示,余额很大,所以我们提出1ether毫无问题,合约剩下的eth不足1eth,isComplete成功调用,完成攻击。
在这里插入图片描述

Token whale

分析

TokenWhale合约:

pragma solidity ^0.4.21;

contract TokenWhaleChallenge {
   
    address player;

    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    string public name = "Simple ERC20 Token";
    string public symbol = "SET";
    uint8 public decimals = 18;

    function TokenWhaleChallenge(address _player) public {
   
        player = _player;
        totalSupply = 1000;
        balanceOf[player] = 1000;
    }

    function isComplete() public view returns (bool) {
   
        return balanceOf[play
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值