<!-- canonical: https://0xsimao.com/findings/autonomint-deposit-withdraw-reinit-stuck -->

# Borrower deposit, withdraw, deposit will reinit `omniChainData.cdsPoolValue`, getting profit stuck for cds depositors

Crit/High · Sherlock · Hedged stablecoin · 4th December 2024

Finding H-27 of the Autonomint competition.

- Protocol: https://audits.sherlock.xyz/contests/569
- Report: /reports/autonomint
- Codebase: https://github.com/0xsimao/2024-11-autonomint/tree/0d324e04d4c0ca306e1ae4d4c65f0cb9d681751b
- Source: https://github.com/sherlock-audit/2024-11-autonomint-judging/issues/919

---

### Summary

[BorrowLib::calculateRatio()](https://github.com/sherlock-audit/2024-11-autonomint/blob/main/Blockchain/Blockchian/contracts/lib/BorrowLib.sol#L156) sets `omniChainData.cdsPoolValue` to `previousData.totalCDSPool + netPLCdsPool`, disregarding any past value of `omniChainData.cdsPoolValue`, when the `noOfDeposits` is null.
`noOfDeposits` is `omniChainData.totalNoOfDepositIndices`, which is increased and decrease on borrower deposit and withdraw, respectively. Hence, it's possible to make it null again while still having cds depositors and positive long contributions to `omniChainData.cdsPoolValue`.

### Root Cause

In `BorrowLib:199`, `omniChainData.cdsPoolValue` is overwritten.

### Internal pre-conditions

None.

### External pre-conditions

None.

### Attack Path

1. Consider a cds depositor of 1000 USDa and a ETH price of 1000 USD / ETH.
2. Borrower deposits 1 ETH and borrows 800 USDa (consider no option fees). Strike price is 1050 USD / ETH.
3. Price goes up to 1050 USD / ETH.
4. Consider that no interest on the debt accrued and the borrower withdraws. `omniChainData.cdsPoolValue` will increase to `1000 + 1 * (1050 - 1000) = 1050`. The cumulative value in cds is [updated](https://github.com/sherlock-audit/2024-11-autonomint/blob/main/Blockchain/Blockchian/contracts/lib/BorrowLib.sol#L930-L933), adding `1 * (1050 - 1000) / 1000 = 0.05`. 
5. Another borrower comes in, deposits 1 wei of ETH. Note that it will [calculate](https://github.com/sherlock-audit/2024-11-autonomint/blob/main/Blockchain/Blockchian/contracts/lib/BorrowLib.sol#L661) the ratio, and `omniChainData.totalNoOfDepositIndices` is 0 now. So, `previousData.cdsPoolValue = currentCDSPoolValue;` is set, and `currentCDSPoolValue = previousData.totalCDSPool + netPLCdsPool = 1000 + 0 = 1000`. `netPLCdsPool == 0` because the price is 1050 now and has not changed.
6. Cds depositor withdraws (ignore 1 wei borrow, it's irrelevant), with a profit of `1000 * 0.05 = 50` USD, but `previousData.cdsPoolValue` is 1000 USD, as the cds depositor tries to withdraw 1050 USD, it [underflows](https://github.com/sherlock-audit/2024-11-autonomint/blob/main/Blockchain/Blockchian/contracts/Core_logic/CDS.sol#L395).

### Impact

Cds depositor can not withdraw 50 USDa profit (and whole deposit, until someone else deposits cds and this user steals cds from the next depositor).

### PoC

See above explanation.

### Mitigation

Consider track if there is pending net cds pool.

---

Related findings:

- [Wrong reward distribution between early and late depositors because of the late `syncRewards()` call in the cycle, `syncReward()` logic should be executed in each withdraw or deposits (without reverting)](https://0xsimao.com/findings/gogopool-reward-rewards-withdraw-deposits): GoGoPool
- [A pool delegate should not be allowed to be a borrower](https://0xsimao.com/findings/maple-finance-iii-pool-delegate-borrower): Maple Finance
- [Stuck ETH in Curve exchanges due to sending msg.value to the exchange instead of amountIn](https://0xsimao.com/findings/singularity-stuck-eth-curve-exchanges): Singularity
- [`burnSharesToWithdrawEarnings` burns before math, causing the share value to increase](https://0xsimao.com/findings/teller-finance-burn-shares-withdraw-share): Teller Finance
