CertiK分析的此次事件攻擊者心理畫像:
攻擊者在調取STA餘額後,快速呼叫swapExactAmountIn函式購買STA,並在第24次交易使用了另一個函式swapExactAmountOut精準的將STA的數目買到了最小值(1e-18),從而最大化後續攻擊的效率。最開始的6筆交易,在沒有必要的情況下,3次買入後賣出,損失了4個WETH,故布疑雲。並且能夠做到隱匿自己的閃電貸階段痕跡來看,有駭客特性。
CertiK判斷攻擊者是有經驗的駭客團隊在充分準備後的一次攻擊嘗試,有很大可能還會繼續攻擊其他DeFi合約。
攻擊重現
階段0:攻擊者從dYdX閃電貸處借款,獲得初始WETH資金。
階段1:攻擊者使用WETH將Balancer中的STA儘可能買空,最大程度提高STA價格。
階段2:攻擊者用獲得的STA多次買回WETH。每一次都用最小量的STA(數值為1e-18)進行購買,並利用Balancer內部漏洞函式gulp(),鎖定STA的數目,控制STA對WETH的價格。重複多次該種買回操作,直到將Balancer中的WETH取空。
階段3:換一種代幣,用STA重複階段2直到取空該種代幣。階段三重複了三次,一共有4種代幣受到了損失WETH,WBTC, LINK和SNX。
階段4:償還dYdX閃電貸,離場。
攻擊者獲利
攻擊者攻擊地址:
0x81D73c55458f024CDC82BbF27468A2dEAA631407
攻擊者最終收款地址:
0xbf675c80540111a310b06e1482f9127ef4e7469a
攻擊者最終獲利:565.5326240837032 ETH, 約合90萬人民幣(北京時間20200630早9點30分價格)
漏洞分析
Balancer合約的gulp()函式作用為將某一種代幣的內部記錄數值覆蓋到當前該種代幣的真實數目,但是錯誤的把他設定成沒有限制的external函式。gulp()函式不應該為external,或者應該加入對於特定使用者或者智慧合約擁有者的驗證或者防護限制條件。
參考資料:
1. Balancer Github:
https://github.com/balancer-labs/balancer-core/blob/140df49361a58e6c79b395964be98387702a7c0d/contracts/BPool.sol#L334
https://github.com/balancer-labs/balancer-core/blob/140df49361a58e6c79b395964be98387702a7c0d/contracts/BMath.sol#L28
https://github.com/balancer-labs/balancer-core/blob/140df49361a58e6c79b395964be98387702a7c0d/contracts/BPool.sol#L423
2. 攻擊交易歷史記錄:
https://ethtx.info/mainnet/0x013be97768b702fe8eccef1a40544d5ecb3c1961ad5f87fee4d16fdc08c78106
3. 官方攻擊報告:
https://medium.com/balancer-protocol/incident-with-non-standard-erc20-deflationary-tokens-95a0f6d46dea