Dopex - 0xklh'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: 179/189

Findings: 1

Award: $0.01

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

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

Vulnerability details

Impact

Option writers can anticipate calls to PerpetualAtlanticVault.settle() to prevent any in-the-money option from being exercised, potentially allowing the backing of $dpxETH to fall down to its 75%ETH value under adverse market conditions.

Proof of Concept

Whenever an option is settled, the Atlantic Vault will transfer collateral (that is, WETH) from the VaultLP contract to the Core contract to make up for the reduced rDPX value; subsequently, a call is made to the VaultLP to update its state, substracting the loss incurred from its _totalCollateral variable.

In the process however, a check is made that the current WETH balance of the contract strictly matches _totalCollateral minus the loss calculated by the Vault: https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L199-L203

Hence sending 1 wei in advance is enough to trigger a revert of the settle() call.

The following addition to the existing test-perp/Unit.testSettle() unit test demonstrates how an otherwise successful call can be blocked :

diff --git a/Unit.t.sol.orig b/Unit.t.sol index c8016e0..60ee447 100644 --- a/Unit.t.sol.orig +++ b/Unit.t.sol @@ -158,6 +158,7 @@ contract Unit is ERC721Holder, Setup { priceOracle.updateRdpxPrice(0.010 gwei); // ITM uint256 wethBalanceBefore = weth.balanceOf(address(this)); uint256 rdpxBalanceBefore = rdpx.balanceOf(address(this)); + weth.transfer(address(vaultLp), 1 wei); vault.settle(ids); uint256 wethBalanceAfter = weth.balanceOf(address(this)); uint256 rdpxBalanceAfter = rdpx.balanceOf(address(this));

As the WETH value sent to the contract can arbitrarily low, the only cost incurred to an attacker would be the gas costs.

Tools Used

Manual review

Consider removing or losening the check.

Assessed type

DoS

#0 - c4-pre-sort

2023-09-12T12:50:19Z

bytes032 marked the issue as low quality report

#1 - bytes032

2023-09-12T12:50:20Z

LQ because of front-running on Arb

#3 - c4-judge

2023-10-15T12:50:45Z

GalloDaSballo marked the issue as duplicate of #619

#4 - GalloDaSballo

2023-10-15T12:50:52Z

Valid high quality, bad formatting

#5 - c4-judge

2023-10-20T19:34:08Z

GalloDaSballo marked the issue as satisfactory

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