又發現一個ERC20 超級大的漏洞app
這個漏洞嚴重到什麼狀況呢?ui
你的錢再也不是你的錢,任何人均可以把你的錢轉走,你也能夠轉走任何人的錢spa
那筆操做記錄是 0x9a6a0ba68214db82ec6fd12ee3a6b4cf1143ec963974d7a5edf97e08b6c482cacode
下面我來帶你們看看,黑客是如何實現的!blog
咱們能夠看到執行的方法是 transferFrom
rem
那這個方法是幹嗎的呢?(從某我的 轉錢到 另一我的 )get
這個方法有一個配套的方法approve
,你受權某我的用多少你的錢。。。it
因此,這兩個方法的使用場景是,io
舉個例子:function
我受權我兒子使用個人100塊錢,那我先調用approve
而後 我兒子要用錢的時候,調用transferFrom
來用個人錢,固然用一次少一次(並且每次用的錢不能超過我受權的錢)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { /// same as above require(_to != 0x0); require(balances[_from] >= _value); require(balances[_to] + _value > balances[_to]); uint previousBalances = balances[_from] + balances[_to]; balances[_from] -= _value; balances[_to] += _value; allowed[_from][msg.sender] -= _value; Transfer(_from, _to, _value); assert(balances[_from] + balances[_to] == previousBalances); return true; }
這個方法會傳入三個參數
require(_to != 0x0); require(balances[_from] >= _value); require(balances[_to] + _value > balances[_to]);
這三行是一些強制要求
uint previousBalances = balances[_from] + balances[_to]; balances[_from] -= _value; balances[_to] += _value;
這三行
allowed[_from][msg.sender] -= _value;
這一行咱們分解下allowed[_from][msg.sender]
是 當前方法調用的人(msg.sender)可使用(_from) 多少錢
也就是假如 我受權了我兒子100塊,那麼
allowed個人地址 = 100(這邊的msg.sender 須要是我兒子的地址,若是是別人的話,我沒有受權給他,則是0
因此這一行本來的意思是 (我兒子用了多少受權的金額,那麼總受權金額須要 減掉 被用掉的)
可是呢。。。由於沒用用safemath...致使任何人都能經過這一行(也就是 0- value)
0-value是不會報錯的(固然若是用safemath的話,是會報錯的。。。)
因此呢,只要你找到一個有錢人的地址,,,而後就能夠吧他的錢所有轉給任何帳戶。。。
下面的代碼就沒有意義了,不須要解釋了。。。
並且他這個合約 沒有暫停的方法。。。
致使如今任何人均可以調用這個合約。。。
正常來講,應該須要加一個 判斷,被受權的金額 不能大於 要發送的金額。。。
require(allowed[_from][msg.sender] >= _value);
這樣的話 後面也就不會有這些事情了。。。
我發現了 攻擊這個合約的人 已經攻擊了不少合約了!!!
這一些幣你們就別抄底了!