code-423n4 / 2023-08-dopex-findings

3 stars 3 forks source link

wrong calculation of `bondDiscount` and `weth/rdpx` required lead to incorrect amount needed to mint dpxETH #2211

Open code423n4 opened 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/core/RdpxV2Core.sol#L1162-L1177

Vulnerability details

impact

In the calculateBondCost function, there is an issue with the bondDiscount calculation, which affects the precision of the required weth and rdpx values. The formula should ensure that bondDiscount has 8 decimal places, but the current implementation returns a value without the proper precision. This results in incorrect calculations for both the required weth and rdpx amounts. More details are provided in the proof of concept (POC).

proof of concepts

in the calculateBondCost function we calculate the bond discount and weth required like the follow:

  uint256 bondDiscount = (bondDiscountFactor *
        Math.sqrt(IRdpxReserve(addresses.rdpxReserve).rdpxReserve()) *
        1e2) / (Math.sqrt(1e18)); // 1e8 precision

      _validate(bondDiscount < 100e8, 14);

      rdpxRequired =
        ((RDPX_RATIO_PERCENTAGE - (bondDiscount / 2)) *
          _amount *
          DEFAULT_PRECISION) /
        (DEFAULT_PRECISION * rdpxPrice * 1e2);

      wethRequired =
        ((ETH_RATIO_PERCENTAGE - (bondDiscount / 2)) * _amount) /
        (DEFAULT_PRECISION * 1e2);

However, when calculating bondDiscount, it returns a value like 300 without the proper 8 decimal places precision. For example:

bondDiscountFactor = 30e8 sqrt(IRdpxReserve(1e18)) = sqrt(1000000000000000000) (Math.sqrt(1e18)) = (1000000000000000000)

let say ((3000000000*sqrt(1000000000000000000) * 1e2) / (1000000000000000000)) == 300 not in 8 decimal

Then we get 300, which lacks the required precision of 300e8 or 3e10. Subsequently, this value is used to calculate the required weth and rdpx, following this formula:

(((2500000000 - (300/ 2)) 1 100000000) / (100000000 20 100))

when:

RDPX_RATIO_PERCENTAGE = 25e8 or 2500000000 bondDiscount / 2 = 300/ 2 _amount = 1 dpxETH we need to mint rdpxPrice = 20

This results in 1249999, which is equivalent to $31249975, and this value does not accurately represent the correct amount of rdpx required for 1 DPXETH.

It's worth noting that the weth and rdpx calculations will be incorrect even if the discount factor has 8 decimals.

Tools used

manual review

recommendation

To resolve this issue, ensure that the correct formula and decimal precision are used for both the discount factor and the weth and rdpx required calculations.

Assessed type

Math

c4-pre-sort commented 12 months ago

bytes032 marked the issue as primary issue

c4-pre-sort commented 12 months ago

bytes032 marked the issue as duplicate of #2086

c4-pre-sort commented 12 months ago

bytes032 marked the issue as not a duplicate

c4-pre-sort commented 12 months ago

bytes032 marked the issue as duplicate of #629

c4-pre-sort commented 11 months ago

bytes032 marked the issue as duplicate of #2086

c4-pre-sort commented 11 months ago

bytes032 marked the issue as duplicate of #481

c4-judge commented 10 months ago

GalloDaSballo changed the severity to QA (Quality Assurance)

c4-judge commented 10 months ago

GalloDaSballo marked the issue as grade-b