God.Game漏洞学习

合约代码地址:https://ropsten.etherscan.io/address/0x92cbCBc31f6bb209f2C4F6cbd0596ba22D71979d#code
pwn合约代码地址:https://ropsten.etherscan.io/address/0x88DF1483Db9d3720378d2CB6859c8487e4412ac7#code

function dividendsOf(address _customerAddress)
    view
    public
    returns (uint256)
    {
        return (uint256) ((int256)(profitPerShare_ * tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude;
    }

在计算分红时如果tokenBalanceLedger_[customerAddress])为0同时payoutsTo[customerAddress]为一个很小.则分红计算的结果会变得很大。
在函数transferFromInternal中合约到人的交易中没有对合约地址payoutsTo
[from] 进行操作。导致如果合约调用

if (fromLength > 0 && toLength <= 0) {
            // contract to human
            contractAddresses[_from] = true;
            contractPayout -= (int) (_amountOfTokens);
            tokenSupply_ = SafeMath.add(tokenSupply_, _amountOfTokens);
            payoutsTo_[_toAddress] += (int256) (profitPerShare_ * _amountOfTokens);

        } else if (fromLength <= 0 && toLength > 0) {
            // human to contract
            contractAddresses[_toAddress] = true;
            contractPayout += (int) (_amountOfTokens);
            tokenSupply_ = SafeMath.sub(tokenSupply_, _amountOfTokens);
            payoutsTo_[_from] -= (int256) (profitPerShare_ * _amountOfTokens);

        } else if (fromLength > 0 && toLength > 0) {
            // contract to contract
            contractAddresses[_from] = true;
            contractAddresses[_toAddress] = true;
        } else {
            // human to human
            payoutsTo_[_from] -= (int256) (profitPerShare_ * _amountOfTokens);
            payoutsTo_[_toAddress] += (int256) (profitPerShare_ * _amountOfTokens);
        }

withdraw()函数增加了payoutsTo_[]的值

 payoutsTo_[_customerAddress] += (int256) (_dividends * magnitude);

同时将token清零。dividendsOf会得到(uint256(-1)-(dividends * magnitude))/magnitude为一个很大的值。通过withdraw无法提取。但通过reinvest()函数再次购买大量token影响profitPerShare 的值。再根据god合约内eth的总量计算需要卖出的token数量(myDividends-ether/Profitpershare)=tokens ,用来减小自己withdraw)的数量(因为当前withdraw数量太多合约无法提供)。最后withdraw清空合约内的eth。


合约内payoutsTo_可以轻松溢出,可能是作者故意也解释了在加减payoutsTo_时没有用safemath。主要漏洞点应该就是transferFromInternal合约与人的交易上没有修改payoutsTo_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值