The CollateralTracker.previewDeposit function is used by the CollateralTracker.deposit function and the amount of shares to mint is calculated as follows:
unchecked {
shares = Math.mulDiv( //@audit-info - commissions are only paid when a new position is minted
assets * (DECIMALS - COMMISSION_FEE), //@audit-info - COMMISSION_FEE -> single payment of the commissionRate on the FINAL (post mev-tax) assets paid
totalSupply,
totalAssets() * DECIMALS
);
But the issue here is for the first depositor the totalSupply == 0 (no shares are minted yet). As a result the calculated number of shares for the provided asset amount will be 0. The CollateralTracker.deposit function will transfer the assets amount to the respective PanopticPool but the shares minted to the receiver will be 0. As a result the msg.sender or the receiver has lost his funds.
If another user mints shares by calling the CollateralTracker.mint function as the first depositor by supplying the required number of assets, then he can withdraw the funds of the previous depositor (who lost the funds) as well by redeeming his shares thus profiting as a result.
s_underlyingToken,
msg.sender,
address(s_panopticPool),
assets
);
// mint collateral shares of the Panoptic Pool funds (this ERC20 token)
_mint(receiver, shares);
Hence it is recommended to assign assets amount to the shares variable in the CollateralTracker.previewDeposit function, such that the first depositor calling the deposit function will not lose his funds.
Lines of code
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L401-L407 https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L425-L432
Vulnerability details
Impact
The
CollateralTracker.previewDeposit
function is used by theCollateralTracker.deposit
function and the amount ofshares
to mint is calculated as follows:But the issue here is for the first depositor the
totalSupply == 0
(no shares are minted yet). As a result the calculated number of shares for the provided asset amount will be0
. TheCollateralTracker.deposit
function will transfer theassets
amount to the respectivePanopticPool
but theshares minted to the receiver will be 0
. As a result themsg.sender or the receiver
has lost his funds.If another user
mints
shares by calling theCollateralTracker.mint
function as the first depositor by supplying the required number of assets, then he can withdraw the funds of the previous depositor (who lost the funds) as well by redeeming his shares thus profiting as a result.Proof of Concept
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L401-L407
https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/CollateralTracker.sol#L425-L432
Tools Used
Manual Review and VSCode
Recommended Mitigation Steps
Hence it is recommended to assign
assets
amount to theshares
variable in theCollateralTracker.previewDeposit
function, such that the first depositor calling thedeposit
function will not lose his funds.Assessed type
ERC4626