第18节:安全事故8-可燃烧代币攻击

有些代币在转账时会销毁一部分转账费用,导致实际收到的代币余额偏少,如果开发者没考虑到这一点,以转账值计算,会导致出现偏差。

我们可以通过校验转账前后的token余额来进行校验,确保转账之后确实收到了预期数量的token,从而防止作恶行为。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

contract StakePool {

    function stake(address _token_addr, uint256 _amount) public {
          // 1. 检查转账之前的余额
        uint256 balance_before_transfer = IERC20(_token_addr).balanceOf(address(this));

          // 2. 转账
        IERC20(_token_addr).safeTransferFrom(msg.sender, address(this), _amount);

          // 3. 检查转账之后的余额
        uint256 balance_after_transfer = IERC20(_token_addr).balanceOf(address(this));

          // 4. 计算差值,得到实际收取到的金额,进行校验!
        uint256 received_amount = balance_after_transfer - balance_before_transfer;
        require(received_amount >= _amount, "received should gt _amount");
    }
}