Dopex - Jiamin's results

A rebate system for option writers in the Dopex Protocol.

General Information

Platform: Code4rena

Start Date: 21/08/2023

Pot Size: $125,000 USDC

Total HM: 26

Participants: 189

Period: 16 days

Judge: GalloDaSballo

Total Solo HM: 3

Id: 278

League: ETH

Dopex

Findings Distribution

Researcher Performance

Rank: 58/189

Findings: 3

Award: $192.67

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

96.3292 USDC - $96.33

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
duplicate-2083

External Links

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVault.sol#L270

Vulnerability details

Impact

Option strike price is incorrectly rounded up and option will be created with incorrect strike price.

Proof of Concept

When creating an put option, the option strike price is supposed to be 25% below the current price.

uint256 strike = roundUp(currentPrice - (currentPrice / 4)); // 25% below the current price

If currentPrice - (currentPrice / 4) is less than roundingPrecision, then it will be rounded up:

function roundUp(uint256 _strike) public view returns (uint256 strike) { uint256 remainder = _strike % roundingPrecision; if (remainder == 0) { return _strike; } else { return _strike - remainder + roundingPrecision; } }

If currentPrice (denominated in ETH) is 0.01e8, then the strike price is expected to be 0.0075e8, however, as the price is in 8 decimals and the roundingPrecision is 1e6, so the minimum price will be (1e6 / 1e8) * ETH price, which is 0.01e8, as an result the option is created with strike price 0.01e8, not 25% below the current price.

Tools Used

Manual Review

Please consider to set roundingPrecision to an much smaller value so that it's less likely option strike price will be rounded up to be higher than 25% below the current price.

Assessed type

Math

#0 - c4-pre-sort

2023-09-09T05:29:36Z

bytes032 marked the issue as duplicate of #2083

#1 - c4-pre-sort

2023-09-12T04:43:44Z

bytes032 marked the issue as sufficient quality report

#2 - c4-judge

2023-10-20T14:17:48Z

GalloDaSballo marked the issue as satisfactory

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L201

Vulnerability details

Impact

Attacker can prevent options from being settled by transferring collateral tokens.

Proof of Concept

subtractLoss(uint256 loss) function is called when an option is settled, in this function, protocol will check if the collateral tokens balance of PerpetualAtlanticVaultLP is the same as _totalCollateral - loss.

require( collateral.balanceOf(address(this)) == _totalCollateral - loss, "Not enough collateral was sent out" );

Because _totalCollateral is not updated when options are settled, so an attacker can DOS attack by transferring small amount of collateral tokens to PerpetualAtlanticVaultLP, then the require statement will revert due to collateral.balanceOf(address(this)) != _totalCollateral - loss, thus preventing the option from being settled.

Tools Used

Manual Review

Update _totalCollateral when an options is settled.

Assessed type

DoS

#0 - c4-pre-sort

2023-09-09T09:57:51Z

bytes032 marked the issue as duplicate of #619

#1 - c4-pre-sort

2023-09-11T16:15:05Z

bytes032 marked the issue as sufficient quality report

#2 - c4-judge

2023-10-20T19:34:30Z

GalloDaSballo marked the issue as satisfactory

Findings Information

Awards

96.3292 USDC - $96.33

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
sufficient quality report
edited-by-warden
duplicate-549

External Links

Lines of code

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

Vulnerability details

Impact

Protocol wrongly assumes oracle returns price data in 8 decimals, results in price data being wrongly used.

Proof of Concept

getRdpxPrice() returns the price of rDPX against ETH, and the price data is directly fetched from oracle.

function getRdpxPrice() public view returns (uint256) { return IRdpxEthOracle(pricingOracleAddresses.rdpxPriceOracle) .getRdpxPriceInEth(); }

Protocol assumes the price data is in 8 decimals, and uses the prices in multiple functions. For example, When calculates the delegate amounts, the price data is divided by 1e8:

uint256 rdpxRequiredInWeth = (_rdpxRequired * getRdpxPrice()) / 1e8;

However, when we check the implementation of IRdpxEthOracle, we can find oracle returns the price data in 18 decimals:

/// @notice Returns the price of rDPX in ETH /// @return price price of rDPX in ETH in 1e18 decimals function getRdpxPriceInEth() external view override returns (uint price) { require( blockTimestampLast + timePeriod + nonUpdateTolerance > block.timestamp, "RdpxEthOracle: UPDATE_TOLERANCE_EXCEEDED" ); price = consult(token0, 1e18); require(price > 0, "RdpxEthOracle: PRICE_ZERO"); }

Tools Used

Manual Review

Please consider to convert oracle price data to 8 decimals before use.

Assessed type

Decimal

#0 - c4-pre-sort

2023-09-09T05:16:20Z

bytes032 marked the issue as duplicate of #549

#1 - c4-pre-sort

2023-09-12T05:19:46Z

bytes032 marked the issue as sufficient quality report

#2 - c4-judge

2023-10-20T18:27:55Z

GalloDaSballo marked the issue as satisfactory

#3 - c4-judge

2023-10-20T18:28:12Z

GalloDaSballo changed the severity to 2 (Med Risk)

#4 - c4-judge

2023-10-20T18:28:21Z

GalloDaSballo changed the severity to 3 (High Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter