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: 185/189
Findings: 1
Award: $0.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
Every option that has been purchased has unique optionId. This id represent the current position of optionHolder includes strike price at which option bought and the amount purchased.
A person with DEFAULT_ADMIN_ROLE can directly settles these options via call to RdpxV2Core#settle()
, which can be DoS by an attacker by directly transfer funds to the LP Vault.
File: RdpxV2Core.sol
function settle( uint256[] memory optionIds ) external onlyRole(DEFAULT_ADMIN_ROLE) returns (uint256 amountOfWeth, uint256 rdpxAmount) { // ...SNIP... (amountOfWeth, rdpxAmount) = IPerpetualAtlanticVault( addresses.perpetualAtlanticVault ).settle(optionIds); // ...SNIP... }
File: PerpetualAtlanticVault.sol
function settle( uint256[] memory optionIds ) external nonReentrant onlyRole(RDPXV2CORE_ROLE) returns (uint256 ethAmount, uint256 rdpxAmount) { _whenNotPaused(); _isEligibleSender(); // ...SNIP... // Transfer collateral token from perpetual vault to rdpx rdpxV2Core collateralToken.safeTransferFrom( addresses.perpetualAtlanticVaultLP, addresses.rdpxV2Core, ethAmount ); // Transfer rdpx from rdpx rdpxV2Core to perpetual vault IERC20WithBurn(addresses.rdpx).safeTransferFrom( addresses.rdpxV2Core, addresses.perpetualAtlanticVaultLP, rdpxAmount ); IPerpetualAtlanticVaultLP(addresses.perpetualAtlanticVaultLP).subtractLoss(ethAmount); // update the totalCollateral state // ...SNIP... }
The above snippet shows IPerpetualAtlanticVault(address).settle()
function transfer the collateral(e.g. weth) from LpVault to the RdpxV2Core which decreases collateral balance of LpVault.
File: PerpetualAtlanticVaultLP.sol
function subtractLoss(uint256 loss) public onlyPerpVault { require( collateral.balanceOf(address(this)) == _totalCollateral - loss, "Not enough collateral was sent out" ); _totalCollateral -= loss; }
Following the change in collateral balance, the call to subtractLoss()
function reduces the _totalCollateral
by the amount that being transferred to RdpxV2Core. Its looks like here the developer pre-assumed that the collateral balance should be equal to _totalColllateral
before its call to subtractLoss()
. The assumption can be break easily by transferring the minimum 1 wei of colllateral directly to the LpVault contract.
Hence, the check will always failed and revert any txn that came to the option settlement.
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Manual review
I discussed some fixes with sponser, but it looks like there will always be risk because we can't control the collateral balance in contract. Therefore its in our best interest to remove the check. Modify the subtractLoss()
function to below.
function subtractLoss(uint256 loss) public onlyPerpVault { _totalCollateral -= loss; }
DoS
#0 - c4-pre-sort
2023-09-09T09:57:34Z
bytes032 marked the issue as duplicate of #619
#1 - c4-pre-sort
2023-09-11T16:14:32Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T19:34:17Z
GalloDaSballo marked the issue as satisfactory