#42539 [SC-Low] Incorrect `maxWithdraw()` returns lead to user failed withdrawals of returned maximum amount
Was this helpful?
Was this helpful?
Submitted on Mar 24th 2025 at 15:17:25 UTC by @merlinboii for
Report ID: #42539
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/audit-comp-yeet/blob/main/src/contracts/MoneyBrinter.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
The MoneyBrinter.maxWithdraw()
function returns an overestimated value that doesn't account for withdrawal fees, causing withdrawals at the reported maximum to always revert due to insufficient shares balance to burn.
The ERC4626 implementation's maxWithdraw
calculates withdrawable assets as:
However, the previewWithdraw()
implementation adds a fee:
This creates a mathematical inconsistency where the maxWithdraw()
is returned the assets from the shares balance of owner
, but the previewWithdraw()
returns the shares amount from the assets + fee
.
Return the maximum amount of assets that could be transferred from owner through withdraw and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).
MUST factor in both global and user-specific limits, like if withdrawals are entirely disabled (even temporarily) it MUST return 0.
MUST NOT revert.
Low (Contract fails to deliver promised returns, but doesn't lose value)
While no funds are directly at risk, this issue:
Cause failed transactions and wasted gas when users attempt to withdraw their reported maximum
Breaks core EIP-4626 functionality and compliance
https://github.com/immunefi-team/audit-comp-yeet/blob/main/src/contracts/MoneyBrinter.sol
https://github.com/immunefi-team/audit-comp-yeet/blob/main/src/contracts/MoneyBrinter.sol#L24
Initial state:
Assume a user has 100 shares in the vault
Assume the exchange rate is 1:1 (1 share = 1 asset)
Assume exitFeeBasisPoints = 100 (1%)
User queries their maximum withdrawable amount
User attempts to withdraw this maximum amount
The withdraw()
function will revert because:
The transaction reverts because the user needs 101 shares to withdraw 100 assets (query from maxWithdraw()
), but they only have 100 shares.
Moreover, this is not compile with EIP-4626 as according to specifications, maxWithdraw
MUST: