code-423n4 / 2022-07-fractional-findings

0 stars 0 forks source link

Small scalar may make `buyoutPrice` calculation incorrectly #642

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/modules/Buyout.sol#L86 https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/modules/Migration.sol#L527

Vulnerability details

Impact

In Buyout.start() function, buyoutPrice is calculated using a scalar = 100. This small scalar and division rouding will reduce the precision of the formula significantly.

Proof of Concept

  1. Alice call start() with msg.value = 1e18 and depositAmount = 4567. Assume totalSupply = 1e4. Then 1e18 wei should be equal to 10000 - 4567 = 5433 fractions. So 1 fractions will equal to 1.840603e14 wei

  2. But actually

    
    buyoutPrice 
    = (msg.value * 100) / (100 - ((depositAmount * 100) / totalSupply))
    = (1e18 * 100) / (100 - ((4567 * 100) / 1e4))
    = 1e20 / (100 - 55) 
    = 2.2222222e18

fractionPrice = buyoutPrice / totalSupply = 2.2222222e18 / 1e4 = 2.2222222e14



Which is significantly bigger than `1.840603e14`

3. Now if Bob want to sell a large amount of fractions, there will not have enough ETH balance to do that. 

## Tools Used

Manual Review

## Recommended Mitigation Steps

Rewrite the formula to only do division in the last and increase the scalar for more precision
stevennevins commented 2 years ago

Duplicate of #647

HardlyDifficult commented 2 years ago

Duping to https://github.com/code-423n4/2022-07-fractional-findings/issues/310