背景
北京時間2022年9月10日,DPC代幣合約遭到黑客攻擊,損失超73,614 BUSD, 零時科技安全團隊及時對此安全事件進行分析,詳情可移步至分析文章“零時科技 || DPC攻擊事件分析”。
DPC合約簡介
DPC合約是一個ERC20代幣合約,合約提供兌換、轉(zhuǎn)移代幣等功能。用戶可以使用USDT兌換獲得DPC代幣,將DPC代幣與USDT進行質(zhì)押來獲得DPC代幣獎勵。
漏洞核心
由于DPC合約中計算獎勵算法存在漏洞,攻擊者通過質(zhì)押流動性代幣獲得獎勵,通過調(diào)用函數(shù)取出代幣時進行獎勵累加,在合約中取出任意數(shù)量代幣都會進行獎勵累加操作且對于操作沒有頻率的限制,并且在獎勵累加時會進行兩次累加操作,使得計算獎勵時會翻倍增加。
1.通過質(zhì)押代幣將oldClaimQuota[] 與 dpcLp[]賦值
2.調(diào)用claimStakeLp()函數(shù)計算獎勵
3. getClaimQuota()函數(shù)中可以看到再次執(zhí)行了ClaimQuota的加法操作,調(diào)用一次計算獎勵函數(shù)時會給獎勵進行翻倍。
漏洞測試
攻擊合約核心代碼
測試結(jié)果
攻擊合約初始資金為204代幣,向被攻擊合約質(zhì)押200代幣后調(diào)用攻擊函數(shù),每調(diào)用一次攻擊函數(shù)向被攻擊合約轉(zhuǎn)移1個代幣實現(xiàn)獎勵累加,調(diào)用四次攻擊函數(shù)后獲得的獎勵為321代幣,將獎勵提取至被攻擊合約。
漏洞預(yù)防
在計算獎勵的函數(shù)中設(shè)置獎勵計算的頻率,并且設(shè)置每次調(diào)用函數(shù)時傳入?yún)?shù)的最小值,避免攻擊者可以通過轉(zhuǎn)移小額代幣就可以實現(xiàn)獎勵的累加。
將計算獎勵函數(shù)中累加計算改為只進行函數(shù)調(diào)用,避免一次調(diào)用函數(shù)實際進行了兩次獎勵累加。
修改之后用同樣的攻擊方法獲利只有38代幣,為正常應(yīng)獲得的獎勵數(shù)額。