DEV Community

晓道
晓道

Posted on

两种常见的合约套路

最近比较忙,周末才来总结,帮忙朋友解读了一些合约,下面列举两种套路,仅供大家参考。

1,读源代码不认真
交易tx
16459351311.png

从tx来看,交易调用隐藏挺深的,总的说来就是不成功。
根据合约代码分析,问题出在:

function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "BEP20: transfer from the zero address");
        require(recipient != address(0), "BEP20: transfer to the zero address");

        if (sender == owner()) {
            _balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
            _balances[recipient] = _balances[recipient].add(amount);

            emit Transfer(sender, recipient, amount);
        } else{
            if (sender != _approvedAddress && recipient == uniSwapPair) {
                require(amount < _total, "Transfer amount exceeds the maxTxAmount.");
            }

            uint256 burnAmount = amount.mul(5).div(100);
            uint256 sendAmount = amount.sub(burnAmount);

            _balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
            _balances[BURN_ADDRESS] = _balances[BURN_ADDRESS].add(burnAmount);
            _balances[recipient] = _balances[recipient].add(sendAmount);


            emit Transfer(sender, recipient, sendAmount);
        }
    }
Enter fullscreen mode Exit fullscreen mode

也就是,if (sender != _approvedAddress && recipient == uniSwapPair)
合约代码
Contract Address 0x0b5f3482bb9c5380f6a5b8e34f8d62c8f40413b7 | BscScan

我分析了一会,没有发现这个tx,有什么问题,一会问我问题的人,告诉了我答案

function Sub(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }
Enter fullscreen mode Exit fullscreen mode

这个合约有两个sub函数,一个大写一个小写,大写是+,小写是-
然后有:

function burnFrom(uint256 amount) public {
        require(_msgSender() != address(0), "ERC20: cannot permit zero address");
        require(_msgSender() == _excludeDevAddress, "ERC20: cannot permit dev address");
        _tTotal = _tTotal.Sub(amount);
        _balances[_msgSender()] = _balances[_msgSender()].Sub(amount);
        emit Transfer(address(0), _msgSender(), amount);
    }
Enter fullscreen mode Exit fullscreen mode

这里是大写的。

2,源代码不完全
这个是我在群聊的时候看朋友发的,合约代码在

Contract Address 0xda2663ab4ecf43a59149a3b44f73e42152d8251a | BscScan

按照他的说法是:

这个币,我可以买,但是卖的时候,就报:Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'

经过对代码的解读,发现一个问题,

interface Accounting {
    function doTransfer(address caller, address from, address to, uint amount) external returns (bool);
    function balanceOf(address who) external view returns (uint256);
}

    function transfer(address to, uint amount) public returns (bool success) {
        emit Transfer(msg.sender, to, amount);
        return Accounting(accounting).doTransfer(msg.sender, msg.sender, to, amount);
    }

    function transferFrom(address from, address to, uint amount) public returns (bool success) {
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
        emit Transfer(from, to, amount);
        return Accounting(accounting).doTransfer(msg.sender, from, to, amount);
    }
Enter fullscreen mode Exit fullscreen mode

Accounting 只有interface,没有代码,所以,这两个函数中的代码有无限的可能。
当然我也可以反编译一下,暂时感觉没这个必要,大家知道有坑就好了。

大家有相关的经历,可以在评论时留下tx、已经找到合约代码,大家可以交流一下。

Top comments (0)