Closed sherlock-admin2 closed 3 months ago
Invalid, Yieldvault logic is OOS of this contest
This is a valid medium severity issue
Root cause: Frontrunning yield accrual by liquidating can lead to a loss of yield
Impact: Loss of yield to users
Potential Fix: This is a risk that should be communicated to users. Their deposits are not at risk but the yield is.
Note: In the POC section of my report I mention updating a mock, this is not necessary for this attack to work and the POC will run fine
The issue involves an attack path interacting with PoolTogether's contracts AND impacts depositors to the prizeVault therefore it must be in scope
Below is the POC with comments to show the attack path
Escalate
On behalf of @0xspearmint1
Escalate
On behalf of @0xspearmint1
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
In the escalation I meant to say high severity
There is a definite loss of yield to users, without any restrictive constrains.
To simplify the attack as much as possible, it's basically the first depositor attack and due to precision loss in yield vault, the attacker is able to get the shares of other users, correct? Hence, the root cause is how the yield vault implements deposits, correct?
@WangSecurity This is not a first depositor attack since it can occur at anytime not just in the beginning. The precision loss and YV deposit implementation is irrelevant for the attack to take place.
The root cause is that a large liquidation will result in YV shares owned by the PZ = 0.
The attacker does not get the shares of other users. The way liquidations happen in the protocol is that they redeem YV shares, if an attacker performs a large enough liquidation, they can redeem all the YV shares.
Since the PV now owns 0 YV shares it will not be attributed any yield.
The attack path involves frontrunning yield accrual by performing a large liquidation (clearly outlined in the POC) to enter the state of 0 YV shares.
Just to make it clear: The attack path will work REGARDLESS the implementation of the YV deposit function and REGARDLESS of precision loss in YV
This attack is invalid because the attacker loses the yield fee of that donation and there is a smoothing factor in the liquidation pair, which only allows liquidating a part of it, so the attacker would take a huge loss.
Also, I could not understand how the users lose their shares, or the shares of the yield owned by the prize vault go to 0, could you explain it with words and links?
The point you made does not make the attack invalid. Those are requirements for the attack to be very profitable, which I clearly abided by in my POC.
The coded POC is clear enough, go through the trace if you want more understanding.
No one will execute this if they lose upfront a hugh chunk of the donation.
if yield fee = 0 (which most live vaults do) the attacker loses nothing.
The smoothing factor does not prevent the attack it just makes it more complex and OOS of this issue.
Another point is that the attacker may be willing to spend $ in terms of yieldFee etc, if he can make back the profit in the yield that should have been attributed to the PV depositors.
It's not more complex, the smoothing factor only allows liquidating a % of the liquidatable balance, so the remaining % would be stuck in the vault.
Why would most live vaults pick a 0 liquidation fee?
Not necessarily stuck in the YV if the attacker is deposited in the YV directly and owns shares in it.
here you can see the live vaults. I checked a few and they all had yield fee = 0.
The balance of the attacker is capped at a 1:1 ratio, so he will not own all the exceeding donated yield
He will if he is the only one other than the PV deposited in that YV.
Not sure what you mean. Let's say he had 100 balance in the PV and donated 1000 to the PV. The yield will be 1000, so the liquidation happens with a smoothing factor that leaves 200 + the 100 deposit. The user can only withdraw 100, so he lost 200, in the PV.
Your example is confusing since you do not specify PV and YV etc.
You are not considering if the attacker owns YV shares, then he will be attributed all the yield if he is the only shareholder in the YV.
So the donation is to the yield vault, sorry thought it was a donation to the prize vault.
Agree it is OOS then.
It is not OOS the root cause is within the PV, and the huge impact is to PV depositors.
The smoothing factor still stops this because the PV would have YV shares after the liquidation that the attacker could not withdraw due to the PV having at most 1:1 ratio when withdrawing.
These funds would be there to be liquidated after the tpda price drops, some time after, and anyone could liquidate them in return of prize tokens, so the attacker would lose then.
The 1:1 withdrawal ratio guarantees this attack is never profitable. And, it is very expensive due to the yield fee and smoothing factor.
It is not OOS the root cause is within the PV, and the huge impact is to PV depositors.
What is the issue here? The prize vault depositors are supposed to get x amount of prizeTokens in exchange for the yield. Here they will still get it right because at the time of liquidation the attacker will have to pay x amount.
I believe it still depends on the YV logic that will lead to PV having 0 shares in YV, while there are depositors in PV. Additionally, the comment above. Hence, planning to reject the escalation and leave the issue as it is.
Result: Invalid Unique
0xSpearmint1
high
An attacker can frontrun a yieldVault accumulating yield with a large liquidation to lose/steal the yield of all the users
Summary
An attacker can frontrun a yieldVault accumulating yield with a large liquidation to lose the yield for all the users
Vulnerability Detail
The vulnerability is that the attacker can take some steps (described in POC) to enter a state where yieldVault shares held by the prizeVault = 0
In this state any yield accumulated will not be attributed to the prizeVault hence not credited to the user's that deposited
So if an attacker frontruns yield accrual with a large liquidation + withdraw to enter the defined state, they can cause yield loss to all the users whose funds actually generated the yield in the first place.
The attacker can take advantage of this by preemptively depositing in the yieldVault directly to own some yieldVault shares, in this case they will be attributed all the yield to themselves
The attack is best described as a set of steps so see the coded POC steps
Impact
Users lose their hard earned yield
Attacker can steal this yield
Proof of Concept
Replace the existing
BaseIntegration.t.sol
in /2024-05-pooltogether/pt-v5-vault/test/integration/BaseIntegration.t.sol with the followingUpdate the yieldVault MOCK so it is more realistic with the sanity check
Find it in /2024-05-pooltogether/pt-v5-vault/test/contracts/mock/YieldVault.sol
Now add the following FrontrunToLoseYield.sol to /2024-05-pooltogether/pt-v5-vault/test/integration/FrontrunToLoseYield.sol
The following foundry test test__FrontrunToLoseYield() illustrates the attack scenario.
Run it with the following command line input
Console Output
Code Snippet
https://github.com/sherlock-audit/2024-05-pooltogether/blob/1aa1b8c028b659585e4c7a6b9b652fb075f86db3/pt-v5-vault/src/PrizeVault.sol#L747
Tool used
Manual Review
Recommendation