-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Funds locked due to missing transfer check #235
Comments
raymondfam marked the issue as sufficient quality report |
raymondfam marked the issue as duplicate of #331 |
The majority of the ERC20 tokens would revert if the transfer of assets failed. Nevertheless, the exact use of _latentAssets could indeed be an issue if the assets withdrawn from the yield vault are deficient even by a single unit. Keeping a minimum asset buffer in the contract would probably be a more guaranteed way of circumventing the issue. |
raymondfam marked the issue as high quality report |
raymondfam marked the issue as not a duplicate |
raymondfam marked the issue as primary issue |
trmid (sponsor) confirmed |
I would like to add that if a "compatible ERC4626 yield vault returns less assets than expected", then it is not actually ERC4626 compatible as these behaviors are required in the spec. That being said, there are likely to be some yield vaults that have errors like this and it is a good thing if we can protect against it without inhibiting the default experience! The |
mitigation: GenerationSoftware/pt-v5-vault#86 |
The impact is critical if But another impact is |
hansfriese changed the severity to 2 (Med Risk) |
hansfriese marked the issue as satisfactory |
hansfriese marked the issue as selected for report |
Lines of code
https://github.com/code-423n4/2024-03-pooltogether/blob/480d58b9e8611c13587f28811864aea138a0021a/pt-v5-vault/src/PrizeVault.sol#L933-L936
https://github.com/code-423n4/2024-03-pooltogether/blob/480d58b9e8611c13587f28811864aea138a0021a/pt-v5-vault/src/PrizeVault.sol#L939
Vulnerability details
Impact
Impact: All of the user's funds are unretrievably locked in the
PrizeVault
contract.A combination of issues allows for the following scenario:
_withdraw(receiver, assets)
(viaburn()
orwithdraw()
).previewWithdraw(assets)
.At this point, the contract holds fewer than
assets
tokens.transfer
assets to the receiver. This fails due to insufficient funds, but the ERC 20-compliant token does not revert (only returnsfalse
).PrizeVault
contract. They cannot be withdrawn at a later point, because the corresponding prize vault and yield vault shares have been burned.The exploit relies on insufficient handling of two corner cases of ERC-20 and ERC-4246:
transfer
must throw if the message sender holds insufficient balance. Instead, returningfalse
is compliant with ERC-20 and implemented by many tokens, including BAT, cUSDC, EURS, HuobiToken, ZRX and many more.redeem(previewWithdraw(assets))
transfers at leastassets
. In particular,redeem(shares, ...)
only guarantees that exactlyshares
are burned. The only guaranteed way to gain a certain amount of assets is by callingwithdraw(assets, ...)
.While this is the most standards-compliant scenario, a malicious vault could simply not transfer the required tokens on purpose, and still trigger the same effect as described above.
Proof of Concept
We provide a proof of concept that results in all of Alice's assets locked in the
PrizeVault
contract and all her shares burned.Place the file below in
test/unit/PrizeVault/PoCLockedFunds.t.sol
and run the test withTools Used
manual code review
Recommended Mitigation Steps
We recommend to fix both the ERC-20 transfer and ERC-4626 withdrawal.
For the first, it is easiest to rely on OpenZeppelin's SafeERC20
safeTransfer
function:This already mitigates the erroneous locking of assets.
In addition, we recommend to ensure that at least the necessary amount of shares is withdrawn from the yield vault.
In the simplest form, this can be ensured by invoking
withdraw
directly:If a tighter bound on redeemed shares is desired, the call to
previewWithdraw
/redeem
should be followed by awithdraw
of the outstanding assets:Assessed type
ERC20
The text was updated successfully, but these errors were encountered: