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
Rank: 61/189
Findings: 3
Award: $192.67
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Toshii
Also found by: 0x3b, 0xDING99YA, 0xmystery, Cosine, Jiamin, Juntao, Matin, Qeew, Topmark, catwhiskeys, circlelooper, crunch, deadrxsezzz, eeshenggoh, lsaudit, peakbolt, pep7siup, piyushshukla, qpzm, visualbits
96.3292 USDC - $96.33
If rDPX price is much lower than ETH price, PUT Option strike price can be much higher than 25% below the current price, this violates the invariant that PUT Option can only be created with strike price is 25% below the current price.
As stated in the code comment, PUT Option strike price should be 25% below the current price:
uint256 strike = roundUp(currentPrice - (currentPrice / 4)); // 25% below the current price
The currentPrice
is rDPX price in 8 dp denominated in ETH:
uint256 currentPrice = getUnderlyingPrice(); // price of underlying wrt collateralToken
Currently, rDPX price is 20u and ETH price is 1700u, then the current price is 0.011e8 and PUT Option strike price should be 0.00825e8. However, the strike price is rounded up by roundUp method:
function roundUp(uint256 _strike) public view returns (uint256 strike) { uint256 remainder = _strike % roundingPrecision; if (remainder == 0) { return _strike; } else { return _strike - remainder + roundingPrecision; } }
=> remainder = _strike % roundingPrecision = 0.00825e8 % 1e6 = 0.00825e8 != 0 => strike = _strike - remainder + roundingPrecision = 0.00825e8 - 0.00825e8 + 1e6 = 1e6 => PUT Option strike price is much higher than 25% below the current price
Manual Review
It is recommended to set roundingPrecision
to a much smaller value so that PUT Option strike price won't be rounded up to be much higher than 25% below the current price.
Other
#0 - c4-pre-sort
2023-09-09T05:27:40Z
bytes032 marked the issue as duplicate of #2083
#1 - c4-pre-sort
2023-09-12T04:43:42Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T14:18:06Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: klau5
Also found by: 0x3b, 0xCiphky, 0xDING99YA, 0xWaitress, 0xbranded, 0xc0ffEE, 0xklh, 0xsurena, 0xvj, ABA, AkshaySrivastav, Anirruth, Aymen0909, Baki, Blockian, BugzyVonBuggernaut, DanielArmstrong, Evo, GangsOfBrahmin, HChang26, Inspex, Jiamin, Juntao, Kow, Krace, KrisApostolov, LFGSecurity, LokiThe5th, Mike_Bello90, Norah, Nyx, QiuhaoLi, RED-LOTUS-REACH, SBSecurity, Snow24, SpicyMeatball, T1MOH, Tendency, Toshii, Udsen, Yanchuan, __141345__, ak1, asui, auditsea, ayden, bart1e, bin2chen, blutorque, carrotsmuggler, chaduke, chainsnake, circlelooper, clash, codegpt, crunch, degensec, dirk_y, ge6a, gjaldon, grearlake, jasonxiale, juancito, ke1caM, kodyvim, kutugu, ladboy233, lanrebayode77, mahdikarimi, max10afternoon, mert_eren, nirlin, nobody2018, oakcobalt, parsely, peakbolt, pks_, pontifex, ravikiranweb3, rokinot, rvierdiiev, said, savi0ur, sces60107, sh1v, sl1, spidy730, tapir, tnquanghuy0512, ubermensch, visualbits, volodya, wintermute
0.0098 USDC - $0.01
It is possible to grief attack on settling an PUT Option.
If an PUT Option is In-The-Money, it will be settled and collateral token will be transferred from perpetual vault LP to rdpx rdpxV2Core:
collateralToken.safeTransferFrom( addresses.perpetualAtlanticVaultLP, addresses.rdpxV2Core, ethAmount );
After that, it will update collateral token balance of perpetual vault LP:
IPerpetualAtlanticVaultLP(addresses.perpetualAtlanticVaultLP).subtractLoss( ethAmount );
It is worth noting that subtractLoss will check if enough collateral was sent out and it requires the collateral token balance of perpetual vault LP is equal to the _totalCollateral - loss
:
function subtractLoss(uint256 loss) public onlyPerpVault { require( collateral.balanceOf(address(this)) == _totalCollateral - loss, "Not enough collateral was sent out" ); _totalCollateral -= loss; }
It is possible that an attacker grief attack on settling by sending some amount of collateral token to perpetual vault LP, then the require statement above will fail and settling transaction will revert.
Manual Review
The culprit is that _totalCollateral
is not synced before settling, it is recommended to do so to ensure settling transaction cannot be grief attacked.
DoS
#0 - c4-pre-sort
2023-09-09T09:54:51Z
bytes032 marked the issue as duplicate of #619
#1 - c4-pre-sort
2023-09-11T16:14:24Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T19:31:08Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: LokiThe5th
Also found by: 0xPsuedoPandit, 0xTiwa, 0xnev, 0xvj, Evo, Jiamin, Juntao, QiuhaoLi, T1MOH, Udsen, circlelooper, crunch, eeshenggoh, gjaldon, hals, josephdara, kutugu, minhtrng, niki, umarkhatab_465
96.3292 USDC - $96.33
getRdpxPrice in RdpxV2Core.sol assumes IRdpxEthOracle returns RdpxPriceInEth in 8 dp which is not the case.
getRdpxPrice
is used to
uint256 rdpxRequiredInWeth = (_rdpxRequired * getRdpxPrice()) / 1e8;
uint256 rdpxAmountInWeth = (_rdpxAmount * getRdpxPrice()) / 1e8; uint256 discountReceivedInWeth = _bondAmount - _wethAmount - rdpxAmountInWeth; uint256 extraRdpxToWithdraw = (discountReceivedInWeth * 1e8) / getRdpxPrice();
uint256 rdpxPrice = getRdpxPrice();
In all of the above used case, the price is divided by 1e8 because getRdpxPrice incorrectly assumes the price is in 8 dp, while in fact the IRdpxEthOracle returns RdpxPriceInEth in 8 dp is in 18 dp:
/// @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"); }
Manual Review
function getRdpxPrice() public view returns (uint256) { return IRdpxEthOracle(pricingOracleAddresses.rdpxPriceOracle) .getRdpxPriceInEth() / 1e10; }
Decimal
#0 - c4-pre-sort
2023-09-09T05:13:52Z
bytes032 marked the issue as duplicate of #549
#1 - c4-pre-sort
2023-09-12T05:19:17Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T18:27:57Z
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)