-
Notifications
You must be signed in to change notification settings - Fork 8
elhaj - Claimers Cannot Claim Prizes When Last Tier Liquidity is 0, Preventing Winners from Receiving Their Prizes #84
Comments
|
The escalation could not be created because you are not exceeding the escalation threshold. You can view the required number of additional valid issues/judging contest payouts in your Profile page, |
Escalate On behalf of @elhajin |
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. |
To clarify, the users indeed can receive rewards, the problem is that they have to do that by themselves and without claimers? But claimers are DOSed? |
Yes .. and the argument here is this is not the expected behaviour
|
This is a design choice. They cap the fee to the the prize pool of the last non canary tier. If this is 0, then fine, new draws have to be awarded so there is enough fee (if users still want to claim, they can call it). If prizes are not claimed, the number of tiers will decrease, which will increase the fee for the next draw, as the number of tiers will be less, so each tier has more liquidity and the number of prizes for the fee tier (number - 3) decreases, so the fee increases. So basically the transaction reverting or not does not matter because the max fee is 0, so if they want it to go through, they need to set the fee to 0. Think about it this way, if there are no contributions, or small contributions in the last draw (which is the requirement for this), the fee should also be 0 or small. |
Good point .. but i disagree that this is a designe choice
Here a quote from the docs :
|
Claimers can not be incentivized if there was no liquidity provided, which was the design choice made by picking the last non canary tier prize size. The docs still match the code because the incentive is a % of something, if that something is 0, than the incentive is also 0. What I meant by it's fine, is that users can claim prizes themselves, sure the protocol prefers that bots claim it, but this does not mean users can not claim them, even more so when there was no liquidity contributed. Bots will have incentives in the next draw. Also, the fact that the transaction reverts when the prize is 0 has nothing to do with this, the issue itself is in how the protocol We can see that it is a design choice because the fix would be a different design of the fee, such as adding a fixed component, which is not a valid issue. |
I understand your POV.
To summarize that for the judge:
|
It is a design choice and another proof is that the issue will never happen due to
Starting state, draw 5 Final state, draw 6 Example2, tiers stay at 4 Starting state, draw 5 Final state, draw 6 So utilization ratio + requirement to claim all prizes + not having contributions in the whole draw + last non canary tier having much more shares than canary tiers make this issue impossible to happen |
Will never happen???
|
It decreases the likelihood a lot as it needs to outperform the expected claim counts by a big margin (double) on both canary tiers and the last non canary tier in some cases (tier 4 to tier 4 and tier 5 to tier 4). Assume 2 users, each 0.5 contribution to prize, probably of claiming both canaries twice is
This doesnt matter, liquidity ratio just decreases 50% here, and the prize count does not get big enough to send to 0, even if we are in tier 11 (highly unlikely), 4^8 == 65536. The prize token is WETH, which has 18 decimals, 65536 / 1e18 / 0.5 == 1.31072e-13 WETH, which is a dust contribution, enough for this to not happen.
It would require all vaults to not contribute in a day, which is highly unlikely. So if we multiply all these chances, as they all need to happen simultaneously (and the fact that the last non canary tier has more shares, so it will absorve most liquidity), this will never happen. And it is a design choice regardless, but wanted to get this straight. |
Firstly, I can confirm that it's not a design decision. Secondly, I agree that it's not a duplicate of #112. Thirdly, based on the discussion above, this scenario indeed has significant requirements and constraints (based on this and this comments), moreover, it only DOSes the claimers, but the prizes can still be received. I understand that the goal is to claimers to claim prizes, still the prizes are not locked completely and can be claimed. Planning to accept the escalation and de-dup the report. |
It's highly likely. We're talking about two vaults in production at the current time (even with 10 vaults, it's highly likely this will happen). Whether a design choice or not, let's let the judge decide. |
@elhajin as the utilization ratio is 50%, the odds of claiming all canary tiers twice are close to If we think there is a 1% chance no contributions happen in a day (this number seems too big, I think the chance is even smaller, in normal operating conditions, as bots are incentivized to liquidate daily, if they don't, this is irregular), the chance would be And even if this happens (highly unlikely), users can still claim prizes for themselves, or even the protocol may choose to sponsor it. |
|
It's not the expected, regular behaviour. The protocol incentivizes liquidating daily, so anything other than this is unlikely. In this case, there are multiple vaults, even more unlikely. It would require having unexpected behaviour (not liquidating daily) for all vaults, which is very unlikely. About the odds, here is the calculation. |
|
@elhajin, the sponsor said it's possible to claim all prizes, which I agree with, but very unlikely, given the utilization ratio. But the fact that the vaults have to not contribute in the next day, further reduces the likelihood. The 2 chances multiplied are very low for this to be high, estimated at 0.0625% or less. |
I think we made our points clear .. let's let the judge decide that ser🤝 |
And the expected behaviour part is true. Ok they only have 2 deployed vaults right now. But still the expected behaviour is them contributing daily. So the chances go from very low to non existent, considering winning all prizes by double the amount (0.0625) and not contributing in a single day. The actual chance is closer to 0.0625% or lower due to the 2 conditions, not just 6.25% as you mentioned. |
Also, they have a lot of vaults deployed, 19, 12 and 11, respectively. |
To clarify, the chances of this happening is ~0.0625% and not 6.25%, so when @0x73696d616f wrote just 0.0625 it meant 0.0625%, correct? |
Yes 0.0625%, after seeing that there are so many deployed vaults, it's even lower than this. |
@WangSecurity how so 😐? it's 6%.. |
@elhajin you are not multiplying by the chance of not liquidating in a whole day, which is very low as explained before. There are at least 12 vaults, so all vaults would have to behave unexpectedly and not liquidate in a day for this to happen. I attributed a chance of 1% to this scenario, which is very reasonable, in reality it will be lower. @WangSecurity to be clear, for this issue to happen all the canary prizes have to be claimed, which is a |
|
This is false, we need to multiply by the chance of all vaults not contributing in a day, @WangSecurity if u need any further explanation let me know but this is factual.
The chance of all vaults behaving in a way they are not incentivized to is extremely unlikely. We can use 1%, but it is likely lower than this. If we say each vault has 10% chance of not contributing in a day, the chance would be 0.1^12=1e-12, with 12 vaults. With 2 vaults, it's 0.1^2 = 0.01 = 1%. So the chance goes from very low to impossible. Also, if we have less vaults, the likelihood of not contributing in a day will decrease for each because there is way more liquidity to liquidate, so the incentive is huge.
With regular user operation it can be expected a decent number of vaults will be active, anything other than this is extremely unlikely and it's not what the protocol expects.
We need to talk about regular conditions, not some bootstrap phase. If you want to consider weird activity, than we need to consider the prize may be very small, this phase has a low likelihood of happening, bots may choose not claim all prizes due to low liquidity, so on and so forth. In phases like this bots may not even be setup so this issue will not happen anyway. This issue is an extremely edge case which will never happen, even medium is questionable. The stars would have to align for this to happen under normal operations. |
H/M severity don't take likelihood, only impact and constraints. |
Firstly, I believe the constraints for this scenario to happen are extremely high (all the canary prizes have to be claimed, which is a 6.25% chance AND no contributions from all vaults can happen in a whole day). Secondly, the prizes are not lost per se, it's just the claimers who are DOSed. I understand that's an important part of the protocol, but still the funds are not locked, and winners can claim the prizes themselves. I believe based on these two points together, low severity is indeed more appropriate. The decision remains the same, planning to accept the escalation and de-dup this issue as invalid. |
Wrapping around my head on how this is not breakage of core functionality.
|
I agree this breaks the core contract functionality, but it has to have impact besides just breaking the core contract functionality:
As I've said there are no funds lost, since the users can still claim the prizes. But, on the other hand, the idea that just came to my mind is that, claimers have their own contract |
@WangSecurity That's the idea . And claimer contract also in scope. |
With that, I still believe there is no loss of funds per se, because the prizes still can be claimed by the winners themselves. But, the core contract Planning to accept the escalation and make a new family of medium severity. Are there any duplicates? |
There are no dupes of this issue its unique finding. |
Result: |
Escalations have been resolved successfully! Escalation status:
|
The protocol team fixed this issue in the following PRs/commits: |
Fixed in GenerationSoftware/pt-v5-claimer#33 and GenerationSoftware/pt-v5-claimer#34 |
The Lead Senior Watson signed off on the fix. |
elhaj
high
Claimers Cannot Claim Prizes When Last Tier Liquidity is 0, Preventing Winners from Receiving Their Prizes
Summary
Claimer
contract'sclaimPrizes
function can revert when the prize for the tier(numberOfTiers - 3)
is 0. This prevents all winners in this draw from receiving their prizes (through claimer) and stops honest claimers from claiming rewards due to the transaction reverting.Vulnerability Detail
PrizePool
have the chance to win prizes proportional to their contribution and twab balance in every draw. On the other hand, the Claimer contract facilitates the claiming of prizes on behalf of winners so that winners automatically receive their prizes. An honest claimer should always have the ability to claim prizes for correct winners in every draw._computeFeePerClaim()
to compute the fee the claimer bot will receive based on the auction condition at this time. In_computeFeePerClaim()
, another internal function_computeDecayConstant
is called to compute the decay constant for theVariable Rate Gradual Dutch Auction
:_computeDecayConstant
, themaximumFee
is obtained as the prize of thetier(_numberOfTiers - 3)
, which is the last tier before canary tiers. This value is then fed into theLinearVRGDALib.getMaximumPriceDeltaScale()
function.maximumFee
is zero, which can happen if there is no liquidity in this tier. WithmaximumFee = 0
, the internal call toLinearVRGDALib.getMaximumPriceDeltaScale()
will revert specifically inwadLn
function when input is0
, causing the transaction to revert:This means that even if a winner wins, the claimer won't be able to claim the prize for them if
tier(_numberOfTiers - 3).prize = 0
, unless they set fees to 0. However, no claimer will do this since they would be paying gas for another user's prize. This will lead to winners not receiving their prizes even when they have won, and it prevents the honest claimer from performing its expected job due to external conditions.The winner in this case may win prizes from tiers less than
_numberOfTiers - 3
, which are rarer and higher prizes (they can't win prizes from tier(_numberOfTiers - 3)
since it has 0 liquidity).The
tier(_numberOfTiers - 3).prize
can be 0 in different scenarios (less liquidity that round to zero when devid by prize count,hightierLiquidityUtilizationRate
..ect). Here is a detailed example explain one of the scenarios that can lead totier(_numberOfTiers - 3).prize= 0
:Example Scenario
Initial Setup:
[0, 1, 2, 3]
.rewardPerToken = 2
.rewardPerToken
becomes 3.rewardPerToken
remains 3.claimPrizes
with the winners.uint256 maximumFee = prizePool.getTierPrizeSize(_numberOfTiers - 3);
(tier2) will be 0 since there was no liquidity .wadLn(0)
to revert when trying to compute the claimer fees thus tx revert and claimer can't claim any prize.Impact
Code Snippet
Tool used
Manual Review , Foundry Testing
Recommendation
getTierPrizeSize(numberOfTiers - 3)
prize is0
, to make sure that the prize for winner still can be claimed by claimers.The text was updated successfully, but these errors were encountered: