hats-finance / SeeR-PM-0x899bc13919880db76edf4ccd72bdfa5dfa666fb7

1 stars 0 forks source link

SavingsXDai Inflation Attack #28

Open hats-bug-reporter[bot] opened 1 month ago

hats-bug-reporter[bot] commented 1 month ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0xfcb06a10abcef38d141af4d0dabf5881aa4ff7cc4eee906dc7170dc41c7fa42e Severity: medium

Description: Description\ Malicious users can perform an inflation attack against the SavingsXDai to steal the assets of the victim.

Root casue : _decimalsOffset being 0 Reference :

Attack Scenario\ SavingsXDai has _decimalsOffset == 0, if _decimalsOffset is > 1, then issue can never occur

New vaults are at the greatest risk of inflation attacks. Let’s illustrate this with an example: Suppose a user is about to deposit 100 tokens into a new vault as the first depositor. If an attacker front-runs this initial deposit with even 1 wei, this minuscule deposit would still garner the attacker a 100% share of the pool.

Next, the attacker donates an amount greater than or equal to 100 tokens to the vault. This action increases the total balance of the pool, while maintaining the number of shares in circulation.

By the time the initial user’s deposit of 100 tokens makes it to the pool, the calculation for their share ends up being zero due to the way pool shares are calculated with the donated token balance (in this example, 100/101 rounds down to 0).

Finally, the attacker withdraws their share from the pool. Since they are the only one with any shares, this withdrawal equals the balance of the vault. This means the attacker also withdraws the 100 tokens deposited by the initial user, effectively stealing their deposit.

283:     function _decimalsOffset() internal view virtual returns (uint8) {
284:         return 0;
285:     }

229:     function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256) {
230:         return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);
231:     }

236:     function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256) {
237:         return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);
238:     }

Attachments

  1. Proof of Concept (PoC) File

  2. Revised Code File (Optional)

clesaege commented 1 month ago

This contract is a third party contract already deployed. It doesn't affect Seer. As per competition rules, are excluded: