據慢霧區情報,2020 年11 月22 日,以太坊DeFi 項目Pickle Finance 遭受攻擊,損失約2000萬DAI。慢霧安全團隊第一時間跟進相關事件並進行分析,以下為分析簡略過程1、項目的Controller 合約中的swapExactJarForJar 函數允許傳入兩個任意的jar 合約地址進行代幣的兌換,其中的_fromJar , _toJar, _fromJarAmount, _toJarMinAmount 都是用戶可以控制的變量,攻擊者利用這個特性,將_fromJar 和_toJar 都填上自己的地址,_fromJarAmount 是攻擊者設定的要抽取合約的DAI 的數量,約2000萬DAI 2、使用swapExactJarForJar 函數進行兌換過程中,合約會通過傳入的_fromJar 合約和_toJar 合約的token() 函數獲取對應的token 是什麼,用於指定兌換的資產。而由於_fromJar 合約和_toJar 合約都是攻擊者傳入的,導致使用token() 函數獲取的值也是可控的,這裡從_fromJar 合約和_toJar 合約獲取到的token 是DAI,。 3. 此時發生兌換,Controller 合約使用transferFrom 函數從_fromJar 合約轉入一定量的的ptoken,但是由於fromJar 合約是攻擊者控制的地址,所以這裡轉入的ptoken 是攻擊者的假幣。同時,因為合約從_fromJar 合約中獲取的token 是DAI,然後合約會判斷合約裡的資金是否足夠用於兌換,如果不夠,會從策略池中贖回一定量的代幣然後轉到Controller 合約中。在本次的攻擊中,合約中的DAI 不足以用於兌換,此時合約會從策略池中提出不足的份額,湊夠攻擊者設定的2000萬DAI 4. 兌換繼續,Controller 合約在從策略池裡提出DAI 湊夠攻擊者設定的2000萬DAI後,會調用_fromJar 的withdraw 函數,將攻擊者在第三步轉入的假ptoken burn 掉,然後合約判斷當前合約中_toJar 合約指定的token 的餘額是多少,由於_toJar 合約指定的token 是DAI,Controller 合約會判斷合約中剩餘DAI 的數量,此時由於第三步Controller 合約已湊齊2000萬DAI,所以DAI 的餘額是2000萬。這時Controller 合約調用_toJar 合約的deposit 函數將2000萬DAI轉入攻擊者控制的_toJar 合約中。到此,攻擊者完成獲利總結:此次攻擊中,攻擊者通過調用Controller 合約中的swapExactJarForJar 函數時,偽造_fromJar 和_toJar 的合約地址,通過轉入假幣而換取合約中的真DAI,完成了一次攻擊的過程。