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
The yield buffer acts as a constant margin against a proportional lossy deposit error #337
Comments
raymondfam marked the issue as insufficient quality report |
raymondfam marked the issue as primary issue |
QA at best as that's the intended design per the readme: This buffer should never run dry during normal operating conditions and expected yield rates. |
Intended behavior. The yield buffer is just to cover the rounding errors during deposits/withdrawals. |
hansfriese marked the issue as unsatisfactory: |
This is what is stated, but errors may be more general than just due to rounding. It is also not only about errors, but about an actual price fluctuation. There are two problems leading to this issue. The second problem is that the yield buffer is constant and immutable, but the error is not necessarily so. The simplest example is that the |
hansfriese removed the grade |
hansfriese marked the issue as satisfactory |
hansfriese marked the issue as duplicate of #336 |
@hansfriese You are correct that both issues are related to Within PrizeVault the core reasons are different and need different fixes. In #336 it is that |
Is anything wrong if function totalAssets() public view returns (uint256) {
return yieldVault.previewRedeem(yieldVault.balanceOf(address(this))) + _asset.balanceOf(address(this));
} |
@hansfriese, yes it is. A constant buffer cannot take into account that the error might be proportional. |
I understand what you are saying. Originally, this report says two concerns.
1 can be mitigated if FYI, here is the sponsor's comment.
|
In #336 this fix is to prevent
It is mistake to use a constant buffer since the error might be proportional. It is impossible to predict the needed size of the yield buffer in advance, since we don't know how much the vaults will grow (even if we can put a reasonable bound on the proportion of the error), so the yield buffer would have to be set with a huge margin. This was clearly not anticipated by the sponsor, who intended the yield buffer only to account for small rounding errors (seemingly not even taking into account the other errors at all). They therefore risk running into this issue in the future and wouldn't be able to increase the tiny yield buffer. |
Thank you for your additional context. It's true that
Since As stated, the yield buffer is intended to mitigate rounding error loss, not other losses. |
@trmid Keep in mind that the latent assets are regularly redeposited, so any fluctuation downward will eat directly into the yield buffer. [Random] tiny fluctuations in |
The prize vault yield buffer strategy only aims to mitigate against rounding error loss. Any other errors or downward fluctuations in calculations no matter how big or small are not intended to be covered by the yield buffer and should be detected and evaluated prior to prize vault deployment. If any of the planned yield vault integrations have errors that fit this behaviour, it would help determine their compatibility with the prize vault. |
@trmid This means you cannot integrate general EIP-4626 compliant yield vaults. This error is permitted by EIP-4626, and you would have to carefully audit each yield vault's implementation of its I still fear there might be future unintended consequences if this issue is not fixed. |
I would like to clarify that the intended fix is to use |
That's exactly right @d3e4; we are vetting integrations because they need to be compatible with our prize vault in addition to having up only yield vs assets trend upward. The Prize Vault supports the general 4626 spec, but it prevents deposits when it detects loss. This means that vaults whose assets trend upward would prevent deposits during a dip. Not an ideal user experience! This was a design decision we made to keep the vault simple; but a more flexible vault could be built in the future that supports deposits during a "loss" and is able to recover. |
@trmid @asselstine You can of course audit the yield vaults for all these aspects to prevent this issue, but I would also like to ask whether I am missing some reason why it is important that the yield buffer be immutable? |
There are an infinite number of ways an 4626-compliant yield vault could be designed such that it won't be compatible with the prize vault in a way that results in normal prize generation. The 4626 standard is just that flexible. Although it is important to design the prize vault to gracefully deal with as many yield vault designs as possible, we can never guarantee compatibility with every single one. As a result, it is more effective to design it to work with 90% of existing vaults and then identify the breaking points that can be used to evaluate if a new vault is compatible or not. The wiggle room on As for the revert concerns, any reversions on |
Lines of code
https://github.com/code-423n4/2024-03-pooltogether/blob/480d58b9e8611c13587f28811864aea138a0021a/pt-v5-vault/src/PrizeVault.sol#L874
https://github.com/code-423n4/2024-03-pooltogether/blob/480d58b9e8611c13587f28811864aea138a0021a/pt-v5-vault/src/PrizeVault.sol#L337
Vulnerability details
Impact
DoS of deposits.
Proof of Concept
When depositing it is required that
totalAssets() >= totalDebt()
.totalAssets()
increases overtotalDebt()
when yield is generated, but this yield is constantly withdrawn, up to leaving the yield buffer. This yield buffer, which is intended to be very small, is the only margin in this inequality.However,
is only approximate since
yieldVault.convertToAssets()
is approximate, per EIP-4626. And the error oftotalAssets()
may be proportional to the value oftotalAssets()
, for example if a price oracle is used in the yield vault.As more and more is deposited into the PrizeVault,
totalAssets()
andtotalDebt()
will both increase equally, but since the yield buffer is constant their difference will stay the same. Eventually the error intotalAssets()
will exceed the yield buffer difference between them, and thus break the inequality condition. This DoS-es deposits.Recommended Mitigation Steps
The yield buffer can certainly be used to account for small drops in
totalAssets()
due to noise/errors. Allow theyieldBuffer
to be increased/decreased by the owner.(Another reason it should not be immutable is that the initial conditions used to decide its value may change further down the line, e.g. because the exchange rate increases.)
Assessed type
ERC4626
The text was updated successfully, but these errors were encountered: