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: 135/189
Findings: 2
Award: $17.32
🌟 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
The PerpetualAtlanticVaultLP.subtractLoss
function contains this validation statement
function subtractLoss(uint256 loss) public onlyPerpVault { require( collateral.balanceOf(address(this)) == _totalCollateral - loss, "Not enough collateral was sent out" ); _totalCollateral -= loss; }
The function has a strict equality check for collateral token balance. Anyone can donate 1 wei to collateral token to the VaultLp contract and force this function to always revert.
Due to this the PerpetualAtlanticVault.settle
function will also always revert. Hence no bond can be settled ever.
_totalCollateral
is 100.settle
call, the balance of VaultLp is reduced by 10 and subtractLoss
is invoked. But now the token balance of contract is 91 (100 + 1 - 10) and _totalCollateral
is 100.91 != 100 - 10
.PerpetualAtlanticVaultLP.subtractLoss
reverts.PerpetualAtlanticVault.settle
reverts.Manual review
Use >=
operator instead of ==
.
Context
#0 - c4-pre-sort
2023-09-09T09:54:38Z
bytes032 marked the issue as duplicate of #619
#1 - c4-pre-sort
2023-09-11T16:14:22Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T19:30:45Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: said
Also found by: 0Kage, 0xCiphky, 0xkazim, 836541, AkshaySrivastav, Evo, HChang26, HHK, KrisApostolov, Neon2835, QiuhaoLi, Tendency, Toshii, bart1e, bin2chen, carrotsmuggler, chaduke, etherhood, gjaldon, glcanvas, josephdara, lanrebayode77, mahdikarimi, max10afternoon, nobody2018, peakbolt, qpzm, rvierdiiev, sces60107, tapir, ubermensch, volodya
17.313 USDC - $17.31
Anyone can gain disproportionate amount of PerpetualAtlanticVaultLP shares instantly and can use them to drain almost all rDPX tokens from the contract.
The deposit
function of PerpetualAtlanticVaultLP contract can be called by anyone. So anyone can deposit WETH and can collect vault shares. During redemption, the output WETH and rDPX amounts are calculated based upon the ratio of caller's shares balance and shares total supply.
function _convertToAssets( uint256 shares ) internal view virtual returns (uint256 assets, uint256 rdpxAmount) { uint256 supply = totalSupply; return (supply == 0) ? (shares, 0) : ( shares.mulDivDown(totalCollateral(), supply), shares.mulDivDown(_rdpxCollateral, supply) ); }
So anyone with huge shares balance can withdraw almost all rDPX tokens from the contract instantly.
A flash loan can be used to perform the above steps atomically and without any upfront capital.
Manual review
Consider restricting the deposit
function to Core contract only. Otherwise the economics of contracts will remain misaligned, in current state any depositor can withdraw more than the deposited amount instantly.
Context
#0 - c4-pre-sort
2023-09-10T07:42:07Z
bytes032 marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-09-10T07:42:14Z
bytes032 marked the issue as primary issue
#2 - c4-pre-sort
2023-09-11T15:56:24Z
bytes032 marked the issue as duplicate of #867
#3 - c4-judge
2023-10-20T19:25:57Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: said
Also found by: 0Kage, 0xCiphky, 0xkazim, 836541, AkshaySrivastav, Evo, HChang26, HHK, KrisApostolov, Neon2835, QiuhaoLi, Tendency, Toshii, bart1e, bin2chen, carrotsmuggler, chaduke, etherhood, gjaldon, glcanvas, josephdara, lanrebayode77, mahdikarimi, max10afternoon, nobody2018, peakbolt, qpzm, rvierdiiev, sces60107, tapir, ubermensch, volodya
17.313 USDC - $17.31
The PerpetualAtlanticVaultLP.deposit
function looks like this:
function deposit( uint256 assets, address receiver ) public virtual returns (uint256 shares) { require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); perpetualAtlanticVault.updateFunding(); ... }
It can be seen that the shares amount for the deposit is calculated before performing the perpetualAtlanticVault.updateFunding
, which is incorrect.
The perpetualAtlanticVault.updateFunding
function sends collateral tokens to the vaultLp contract and hence updates _totalCollateral
value.
The incorrect execution order of the above mentioned statements causes loss of funds for the contract.
updateFunding
call will send 10 tokens to vaultLp.deposit
function with 100 as input. His shares is calculated as 100. After that updateFunding
is executed and 10 collateral tokens get transferred to vaultLp.redeem
and receives back 105 collateral tokens.The attack caused instant profit of 5 tokens to the attacker, profit can be increased by increasing the attacker deposit amount. If attacker deposits 10k tokens he can capture all the additional 10 tokens.
This bug also leads to a scenario in which two depositors receive different ratio of shares even when they deposit in the same block.
Manual review
Calculate the shares after performing the updateFunding
.
Context
#0 - c4-pre-sort
2023-09-09T05:42:09Z
bytes032 marked the issue as duplicate of #867
#1 - c4-pre-sort
2023-09-11T09:08:12Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-20T19:23:46Z
GalloDaSballo marked the issue as satisfactory