manifoldfinance / defi-threat

a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations on decentralized finance
Mozilla Public License 2.0
487 stars 53 forks source link

Lending: Depositors unfairly harmed by sandwich when debt is distributed #22

Open sambacha opened 1 year ago

sambacha commented 1 year ago

Attackers can profit by sandwiching calls that result in bad debt being distributed among depositors, such as liquidate and handleBadDebt. As a consequence, protocols floating assets depositors decrease their assets in a higher than fair proportion.

By redeeming their deposits before, and depositing again right after spreadBadDebt takes place, attackers avoid being distributed bad debt, and also profit by obtaining cheaper market shares. The amount of profit depends on how much debt is being distributed. Also, if the network transaction fees are low enough the malicious holder can trigger this sandwich attack to every single liquidate call and take profits in the event of debt being distributed. The ratio between the shares used by the malicious holder to perform this attack and the current pool liquidity determines how much do bystanders lose.

The malicious holder (Alice) simply needs to redeem the shares just before a liquidate call and deposit again in order to repurchase them at a discounted price. It can be seen how the value of the shares held by Annie (bystander) changes depending on the case (usual liquidation and sandwich liquidation).

1.Before Liquidation (NO SANDWICH)
Assets that Alice gets if withdraws = 30000000000000000000000
Alice Shares = 30000000000000000000000
Alice DAI Balance = 20000000000000000000000
Assets that ANNIE (Bystander) gets if withdraws = 100000000000000000000
Floating Assets = 64100000000000000000000
After Liquidation (NO SANDWICH)
Assets that Alice gets if withdraws = 29610480782867678343497
Alice Shares = 30000000000000000000000
Alice DAI Balance = 20000000000000000000000
Assets that ANNIE (Bystander) gets if withdraws = 98701602609558927811
Floating Assets = 63267727272727272727273
2.Before Liquidate (WITH SANDWICH)
Assets that Alice gets if withdraws = 30000000000000000000000
Alice Shares = 30000000000000000000000
Alice DAI Balance = 20000000000000000000000
Assets that ANNIE (Bystander) gets if withdraws = 100000000000000000000
Floating Assets = 64100000000000000000000
After Liquidation (WITH SANDWICH)
Assets that Alice gets if withdraws = 29999999999999999999999
Alice Shares = 30750522619519326674773
Alice DAI Balance = 20000000000000000000000
Assets that ANNIE (Bystander) gets if withdraws = 97559317515329245534
Floating Assets = 63267727272727272727273

Recommendation

Fixed by clearing the bad debt by subtracting from the earningsAccumulator instead of distributing the bad debt over the users. The clearBadDebt function allows partial debt clearing. When the earningsAccumulator does not suffice to clear all the debt, the call will not revert and the bad debt can be cleared when more earnings are available. This effectively addresses the sandwich attack reported in this issue.

sambacha commented 1 year ago

src: https://www.coinspect.com/doc/Coinspect%20-%20Smart%20Contract%20Audit%20-%20Exactly%20Protocol%204th%20Audit%20V221028.pdf