Dopex - lanrebayode77'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: 134/189

Findings: 3

Award: $17.39

🌟 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#L200-L203

Vulnerability details

Impact

PerpetualAtlanticVault.settle() is susceptible to frontrunning which could cause the function to revert due to a call made to PerpetualAtlanticVaultLP.subtractLoss().

Proof of Concept

After transferring WETH from PerpetualAtlanticVaultLP to the RdpxV2Core, and RDPX is transferred from RdpxV2Core to the PerpetualAtlanticVaultLP, PerpetualAtlanticVaultLP.subtractLoss() is triggered to deduct the transferred WETH from _totalCollateral.

The problem with PerpetualAtlanticVaultLP.subtractLoss() function is the check that requires collateral.balanceOf(address(this)) == _totalCollateral - loss, this check can be easily made to fail by sending dust(little) amount of WETH to the PerpetualAtlanticVaultLP contract address directly which will not be accounted for in _totalCollateral.

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

Tools Used

Manual review.

Consider changing the equality sign to less or equal.

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

Assessed type

DoS

#0 - c4-pre-sort

2023-09-09T06:49:42Z

bytes032 marked the issue as duplicate of #619

#1 - c4-pre-sort

2023-09-11T16:14:11Z

bytes032 marked the issue as sufficient quality report

#2 - c4-judge

2023-10-20T20:02:06Z

GalloDaSballo marked the issue as satisfactory

#3 - c4-judge

2023-10-21T07:26:28Z

GalloDaSballo changed the severity to 3 (High Risk)

#4 - c4-judge

2023-10-21T07:26:28Z

GalloDaSballo changed the severity to 3 (High Risk)

#5 - c4-judge

2023-10-21T07:26:28Z

GalloDaSballo changed the severity to 3 (High Risk)

#6 - c4-judge

2023-10-21T07:26:28Z

GalloDaSballo changed the severity to 3 (High Risk)

#7 - c4-judge

2023-10-21T07:26:29Z

GalloDaSballo changed the severity to 3 (High Risk)

Awards

17.313 USDC - $17.31

Labels

bug
3 (High Risk)
satisfactory
duplicate-867

External Links

Lines of code

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

Vulnerability details

Impact

Whenever shares are redeemed in PerpetualAtlanticVaultLP, there's an accounting deficit that causes a revert in PerpetualAtlanticVaultLP.addProceeds(), leading to a denial of service in multiple functions that makes calls to PerpetualAtlanticVaultLP.addProceeds() through PerpetualAtlanticVault.updateFunding() like; PerpetualAtlanticVault.purchase(), PerpetualAtlanticVault.settle(), PerpetualAtlanticVaultLP.deposit(), and PerpetualAtlanticVaultLP.redeem()

Proof of Concept

  1. A user makes deposit to mint shares through PerpetualAtlanticVaultLP.deposit() where funds is transferred from user to the contract and _totalCollatera is updated(increamented). https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L128-L132
// Need to transfer before minting or ERC777s could reenter. collateral.transferFrom(msg.sender, address(this), assets); _mint(receiver, shares); _totalCollateral += assets;
  1. When shares are redeemed, funds(collateral and rpdx) are transferred to user, _rdpxCollateral is updated(decremented) but _totalCollateral is not. https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L162-L175
_rdpxCollateral -= rdpxAmount; beforeWithdraw(assets, shares); _burn(owner, shares); collateral.transfer(receiver, assets); IERC20WithBurn(rdpx).safeTransfer(receiver, rdpxAmount); emit Withdraw(msg.sender, receiver, owner, assets, shares);
  1. The problem here is, in PerpetualAtlanticVaultLP.addProceeds() a check is done to assert that balanceOf Collateral is equal or greater than _totalCollateral + proceeds, this will NEVER hold if shares have been redeemed. https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L191-L194
require( collateral.balanceOf(address(this)) >= _totalCollateral + proceeds, "Not enough collateral token was sent" );

Instance:

--Alice makes a deposit of 100 collateral token to get equivalent shares, this increases _totalCollateral by 100. --Alice redeems 50% of her shares to get 50 collateral token transferred back to her by the contract, reducing the contract balance by 50 but no corresponding decrease in _totalCollateral. --So whenever collateral.balanceOf(address(this)) >= _totalCollateral + proceeds is checked, _totalCollateral will still hold 100+, so the check always fails. --The ripple effect is that all function that relies on the check fails.

Tools Used

Manual review.

Update _totalCollateral after transferring collateral to the redeemer.

_totalCollateral -= assets;

Assessed type

Token-Transfer

#0 - c4-pre-sort

2023-09-13T12:44:03Z

bytes032 marked the issue as duplicate of #867

#1 - c4-judge

2023-10-20T19:26:19Z

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

RdpxV2Core.sync() will fail if a whale delegate withdraws a large amount of WETH or WETH reserve balance gets updated with a wrong value when a smaller withdrawal is made due to un-updated totalWethDelegated in the withdraw() function.

Another problem this will cause is that RdpxV2Core.bond() and RdpxV2Core.bondWithDelegate() will revert because they both make a call to ReLPContrac.reLp() function which calls the RdpxV2Core.sync(), this will also cause both functions to fail if isReLPActive is true.

Proof of Concept

  1. When a user calls addDelegate() and deposits WETH, totalWethDelegated is incremented with the deposited amount. https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/core/RdpxV2Core.sol#L963-L964
// add amount to total weth delegated totalWethDelegated += _amount;
  1. When another user calls bondWithDelegate(), a call is made to _bondWithDelegate() that decrements the totalWethDelegated by the amount of WETH required for the bonding. https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/core/RdpxV2Core.sol#L719-L720
// update total weth delegated totalWethDelegated -= wethRequired;
  1. However, when a delegate calls withdraw(), available WETH is sent to the delegate without updating(decrement) the totalWethDelegated by the withdrawn amount.

The problem is that, when syn() is called, it checks for WETH and decrements the balance by totalWethDelegated. If a withdrawal was made, the contract WETH balance will reduce by the withdrawn amount and the calculated balance will give wrong value, in a case where a whale delegate makes a huge withdrawal the function will fail due to an overflow exception error.

Instance:

--Alice calls addDelegate() to deposit 1000WETH, totalWethDelegated increased by 1000 --10WETH was used for bonding so totalWethDelegated reduces to 990WETH --She withdrew 990WETH but totalWethDelegated remains the same --syn() is called and WETH balance was 300WETH, but balance = balance - totalWethDelegated is 300 - 990(instead of 300 - 0 = 300) which will cause the entire function to revert due to solidity prevention of overflow. -- If the withdrawn amount is lower(let's say 200), WETH balance will be updated with a wrong value of 1100 - 200 = 900 instead of 1100 - 0 = 1100 https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/core/RdpxV2Core.sol#L1001-L1004

if (weth == reserveAsset[i].tokenAddress) { balance = balance - totalWethDelegated; } reserveAsset[i].tokenBalance = balance; }

Tools Used

Manual review.

Update totalWethDelegated during withdrawals

totalWethDelegated -= wethRequired;

Assessed type

Math

#0 - c4-pre-sort

2023-09-08T13:28:03Z

bytes032 marked the issue as duplicate of #2186

#1 - c4-judge

2023-10-20T17:55:50Z

GalloDaSballo marked the issue as satisfactory

#2 - c4-judge

2023-10-21T07:38:54Z

GalloDaSballo changed the severity to 3 (High Risk)

#3 - c4-judge

2023-10-21T07:45:55Z

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