6月29日北京時間凌晨2點03分,CertiK天網系統 (Skynet) 檢查到在區塊10355807處Balancer DeFi合約異常,安全研究員迅速介入調查,攻擊過程浮出水面。
6月29日凌晨2點03分,攻擊者利用從dYdX閃電貸中借到的WETH,大量買進STA代幣,使得STA與其他代幣的兌換價格急劇上升。然後使用最小量的STA(數值為1e-18)不斷回購WETH,並在每次回購後,利用Balancer的合約漏洞重置其內部STA的數量(數值為1e-18),以此穩住STA的高價位。
攻擊者不斷利用漏洞,用高價的STA將某一種代幣完全買空(WETH,WBTC, LINK和SNX),最終用WETH償還閃電貸,並剩餘大量STA,WETH,WBTC, LINK和SNX,並透過uniswap將非法所得轉移到自己賬戶中。此次攻擊約獲利90萬人民幣。
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