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: 111/189
Findings: 1
Award: $46.25
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xWagmi
Also found by: 836541, Bauchibred, GangsOfBrahmin, Hama, IceBear, Inspecktor, Matin, MohammedRizwan, catellatech, erebus, lsaudit, niki, okolicodes, ravikiranweb3, tapir, vangrim, zaevlad
46.2486 USDC - $46.25
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L224 https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L265 https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L159
First depositor can deposit a single wei as shares then donate to the vault as the supply gets so big to greatly inflate the ratio so that their returned assets and rdpxAmount values would be minimal. Due to truncation when calling reddem and converting to shares this will be used to steal funds from later depositors.
the bug is presented in _convertToAssets
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) ); }
_convertToAssets is called in redeemPreview
function redeemPreview( uint256 shares ) public view returns (uint256, uint256) { return _convertToAssets(shares); }
_convertToAssets is called in redeem
function redeem( uint256 shares, address receiver, address owner ) public returns (uint256 assets, uint256 rdpxAmount) { .. (assets, rdpxAmount) = redeemPreview(shares); // Check for rounding error since we round down in previewRedeem. require(assets != 0, "ZERO_ASSETS"); _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); }
Manual review
Either during creation of the vault or for first depositor, lock a small amount of the deposit to avoid this.
Token-Transfer
#0 - c4-pre-sort
2023-09-07T13:25:45Z
bytes032 marked the issue as duplicate of #863
#1 - c4-pre-sort
2023-09-11T09:09:58Z
bytes032 marked the issue as sufficient quality report
#2 - c4-judge
2023-10-18T12:41:49Z
GalloDaSballo changed the severity to 2 (Med Risk)
#3 - c4-judge
2023-10-18T12:49:49Z
GalloDaSballo marked the issue as satisfactory