code-423n4 / 2023-03-polynomial-findings

2 stars 1 forks source link

`LiquidityPool.getTokenPrice` can revert and it can cause a DOS #222

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-03-polynomial/blob/aeecafc8aaceab1ebeb94117459946032ccdff1e/src/LiquidityPool.sol#L340-L365

Vulnerability details

Impact

getTokenPrice can revert and the pool's deposit and withdraw will not work.

Proof of Concept

getTokenPrice returns 1e18 when totalFunds = 0, but the correct condition is totalSupply = 0.

getTokenPrice reverts when totalSupply = 0 at the following line.

    return totalValue.divWadDown(totalSupply);

If totalFunds is always 0 when totalSupply = 0, getTokenPrice will return the correct value of 1e18.

        if (totalFunds == 0) {
            return 1e18;
        }

But totalFunds can be a dust value when totalSupply = 0. This situation can be happen in several conditions, and the correct token price is 1e18 instead of reversion. If getTokenPrice reverts, there is no way to deposit and it can result a DOS.

One of the possible senarios is for the first depositor. The first depositor can deposit and withdraw in the same transaction. He will send totalFunds for the first deposit, and the token price will be totalFunds.divWadDown(totalSupply) after that. If he withdraws all liquidity tokens (= total supply), susdToReturn = tokens.mulWadDown(tokenPrice) in withdraw method.

So if totalSupply > 1e18, susdToReturn can be slightly less than totalFunds, and totalFunds can be a non-zero dust value. After this, there is no way to deposit/withdraw and this will result DOS.

Similar thing can be happen in KangarooVault because implementation of getTokenPrice is very similar.

Tools Used

Manual Review

Recommended Mitigation Steps

getTokenPrice should return 1e18 when totalSupply = 0.

c4-judge commented 1 year ago

JustDravee marked the issue as duplicate of #157

c4-judge commented 1 year ago

JustDravee marked the issue as satisfactory