-
Notifications
You must be signed in to change notification settings - Fork 0
zzykxx - A round can be canceled after a random number has been drawn in a specific edge case #47
Comments
|
Escalate I agree that this is circumstantial but I also think the impact is critical for the protocol given that the whole system is built on the principle of being a fair lottery. Because of low likelihood but high impact I believe this should be considered as a valid. Adding 10 minutes of delay on mainnet means an attacker that funded the chainlink subscription contract has to hope the transaction stays pending for more than 10 minutes to be able to execute the attack. The fix is straightforward and just requires increasing the time after which |
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. |
@zzykxx Anyone can top up the Chainlink subscription within the 24 hours, not just Alice. |
Invalid, anybody can top up LINK (even admin) at anytime to prevent this from happening, so this is a non-issue. Adding a buffer also do not mitigate the issue. |
Escalate I would kindly like to escalate As a default we cannot rely on users of the protocol to top up LINK in order to keep protocol functioning. Additionally users seek profit, the chance that a user will willingly buy LINK then send that LINK for top up is extremely unlikely. This is akin to a lottery buyer sending money to the organizer, it just isn't feasible or even likely. Furthermore, the readme state that YOLO will be deployed on
If we include EVM compatible L2 the amount of yolo instances will be over 8. The likeliness that a Subscription stays under funded for 24 hours is likely now. Even more we are assuming that the admin/owner is responsible for LINK top up, this was never stated in the readme, here are all the listed action of the admin
Therefor we cannot assume that the person who is responsible for top up is trusted. As a default if an actor is not named, we assume him to not be trusted. This is the case here. @nevillehuang Adding a 10 min buffer does help to mitigate the issue. I kindly ask for you to read the Chainlink documentation. Pending chainlink orders expire after 24 hours, if we add 10 minutes to the 24 hour delay, we can now be sure the pending request would have expired by that time.
https://docs.chain.link/vrf/v2/subscription The argument against this issue is that it can be prevented. This is not enough reason to disqualify and issue especially since there is a scenario where a loss of funds is possible and this issue allows gaming a user odds, which is complete breaking of the contracts core functionality. We are also disqualifying this issue on the basis that the user will do the right thing and top up the LINK, using this same logic again, we must assume that issue 18 must also be invalid if we assume that the user will always do the right thing and not deposit with Value 0. Now according to sherlock docs, what makes a valid high issue?
here we do have a definite loss of funds without extensive limitations of external conditions. There is only 1 external condition that needs to be met, and that is that LINK is not topped up. This is NOT extensive so therefore this issue fits the high severity criteria without a doubt. I have proven why this issue is a valid high according to sherlocks own documentation. I ask kindly that we can judge this issue correctly, thanks. |
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. |
|
Just like historical decisions cannot influence a current finding, it is also true that YOLO v1 past historical performance cannot be used to refute this issue. This is stated in the sherlock docs, and just because this exploit has not yet happened does not mean it will never happen
@0xhiroshi I am not trying to be arrogant or come off in the wrong way. We must follow procedures and rules. I have again through sherlocks own docs described why this issue is valid. I ask the judge does not judge this issue based on bias but rather logic and what is considered a valid issue according to the sherlock documentation. Strict adherence to rules is what is fair for everyone involved. |
We use the bot to monitor our balances but we top up manually, but even if do have a bot that automatically tops up our subscriptions, your argument that it can run out of balance is a stretch. I can then say we will always have someone to top up the bot, and then you can say something like "what if the person responsible for topping up the bot is sick, or what if the computer with LINK has no battery"? This can go on and on and deviates from the protocol itself. And since it's no longer about the smart contract but whether someone can top it up in 24 hours, is this really in scope? Also, 24 hours is a very long time. We are not talking about the round can be manipulated if we don't top up the subscription within a block, but a full day. |
The fact is that in scope contracts have an edge case which can cause loss of funds for users and breaks key functionality given a certain condition. This is to say, given a certain condition, the issue is valid. From sherlock docs we can observe that a issue is a valid high if it causes loss of funds in certain condition, these conditions cannot be extensive.
The external condition is not extensive, the external condition of this issue is that LINK is not topped up for 24 hours. Ability to avoid an external condition is not sufficient to refute the issue. Because sherlock allows highs to be submitted even if it includes an external condition(as long as this external condition is not extensive) which this issue does, the issue is valid given that the external condition is met and is not extensive which is the case here. This is my final comment :) |
I also add my final observations about the discussion:
|
To make this even more circumstantial, let's say we follow your suggestion and add 10 minutes to the 24 hours deadline before the round can be cancelled, and because the network is so congested, the Chainlink randomness fulfillment that was sent by the 24 hours mark (attacker topped up the subscription around that time and the transaction was confirmed) stays in the mempool for 10+ minutes, and the current block timestamp is passed the round's drawn at + 24 hours + 10 minutes. So now the round can be cancelled with a Chainlink VRF response in the mempool and we are in the exact same frontrun situation. What do you suggest? |
@0xhiroshi chainlink nodes bump the gas on tx in the mempool after a predefined number of blocks, the example used in documentation was 3 blocks or around 36 seconds. The gas bump is used to ensure that a chain link tx does not stay in the mempool for long. So the buffer should be sufficient in most cases to mitigate the risk. Unless we expect gas prices to rise every block for 30 minutes straight. Which is 100x more unlikely to happen than someone forgetting to top up LINK. Once again when doing security we plan for the worst case scenario, because we are human and are therefore not perfect. We can be expected to slip up from time to time. Forgetting to top up LINK is a likely scenario. We cannot always assume that everything goes as planned everyday all day for the rest of YOLOV2 life cycle. It is best for us to take in worst case scenarios and implement fixes to mitigate these risks if they ever were to happen. |
If we have to be purely hypothetical, there is still no guarantee for the transaction to be confirmed on time even if Chainlink bumps the gas price. The gas price can spike to a level higher than our gas lane after the fulfilment is submitted to the network, correct me if I am wrong but I don't think Chainlink can bump the gas price even further as it has already reached the upper limit of the gas lane? imo having the gas price to rise above 200 gwei on mainnet (we are not going for more than 200 gwei because we will lose money if we go for 500 or 1000 gwei) for more than 10 minutes can happen easily if let's say there is a price crash and a bunch of people are getting liquidated on-chain. I can say it's even more likely than someone forgetting to top up our Chainlink subscription. It's all subjective here and we can't really say what's "100x" more likely or not. |
Yeah that's true. But at the end of the day I have described why according to Sherlock documentation that this is a valid issue. You have tried to refute finding with what ifs and no clear reference to documentation to support your dispute. If you really think that everything will be perfect and the team will never forget to top up link. Then what is the point of having the |
I would accept this issue as invalid if it is disputed using/referencing either the readme or Sherlock documentation. It is expected of watsons to use logic/ documentation to support our finding. It should therefore be the same way for the protocol team. Please use logic and the documentation/rules of Sherlock to dispute the finding. Not personal beliefs and what ifs. |
I don't see how this issue itself isn't also based on a lot of "what ifs" lining up together and even with the proposed fix it can still break in theory. You are getting personal here, saying it's based on my personal belief. |
It's not my intent to be personal, but if Sherlock allows a valid issue if they contain an external condition, I don't see why you think the issue is invalid. Here is a snippet from Sherlock documentation
This is criteria for medium, which this issue fits perfectly. I now see your argument is correct to disqualify this issue as high. But it is definitely a medium. Sorry if I came off the wrong way, I am just very passionate about this space. |
Let's have a constructive conversation starting from here. If we really want to make sure it's absolute airtight, just adding 10 minutes isn't going to fix the problem, just a smaller chance of having it. Is there a better solution than adding more and more buffer? We can't lock user funds for too long. |
@0xhiroshi yes I think making the function cancelAfterRandomnessRequest a privileged function will solve this issue. The admin can check the chainlink dashboard to ensure there is no pending/ sent tx in mempool and then he can then call cancelAfterRandomnessRequest himself. This should mitigate this issue 100%. |
On the other hand I am worried it can be said that there is a possibility of us holding up users' fund for a round that should be cancelled for not executing |
Maybe a 1 hour buffer added to cancelAfterRandomnessRequest is sufficient. This will only hold up funds for an extra hour. At this point the chance that a chainlink tx has been in mempool is extremely low. Also adding comments to the function explaining that after 24 hours, chainlink values should not be considered. |
In this way if we cancel a round after 25 hours and there is a randomness request in mempool, we can assure the users that this was expected behavior. |
@ArnieGod @zzykxx In my personal opinion, since admins are trusted, if they want the game to stop by not fuifilling the following precondition, it is a valid centralization risk consideration. This is not even considering any users can just continue the game anyways.
More importantly, even if you increase it to 25 hours, there is always the argument for the same scenario that can happen if chainlink response doesn't return by 25 hours, than the front-running issue can happen again and so on and so forth, where the possibility is endless. Additionally, for cancelled rounds, users can simply withdraw their deposits for cancelled deposits via Hence, I believe this issue should be low severity. Also the difference between this and #43 is the likelihood and edge case scenarios for this to occur. |
This is just not true, respectfully your comment shows clearly you don't have full context or understanding of the issue at hand, because what your stating is not even true, front running will be impossible if the chainlink vrf didn't return a value by 25 hours because there will be no tx to frontrun. I kindly ask the head judge to read the duplicate of this report for better understanding #102 that duplicate highlights impact and issue more thoroughly. The impact is breaking core functionality and also a loss of funds. And I know historical decisions do not matter but the exact same report was deemed high severity when reported by trust in the forgeries contest on c4. I can further explain the issue in detail if necessary, if I were asked to be 100% unbiased I would without a doubt count this issue a valid medium at the very least, if not there is also some argument for a high. |
@ArnieGod Can you point me to the c4 issue? I will have a look and rereview my comments. Could you correct me about why there will be no tx to front-run if you increase expiry to 25 hours before allowing cancellation? |
@ArnieGod Ok I got the issue, but wouldn’t this still be dependent on looksrare ensuring a high enough LINK balance? Is there any scenario where this is out of their control (Chainlink fees get unreasonably high)? Also this issue also doesn’t allow a redraw like forgeries but simply a cancellation after which deposits can be withdrawn. So we have to take it into account before deciding severity, though if all things line up, the winner would indeed lose his winnings. |
@nevillehuang if anything I think the chance of this edge case happening here is exponentially higher than trusts report. From what I know the forgeries contract was deployed on 1 chain. This contract will potentially be deployed on 8+ chains as stated in the read me
So the issue is at most around 8-10x more likely in this report than in trusts. Given that the team will have to track multiple chainlink balances, the chance this edge case happens is likely. Given that the Impact is severe, loss of funds for users, and breaking core invariants and functionality of the protocol. This was my reasoning for thinking this issue was high severity |
@ArnieGod As far as I know, there will be automated bots assigned to ensure sufficient LINK balance in place. This would fall under out of scope admin configurations/conditions that admins are trusted to maintain. I understand you mentioned a point about the need to not consider this configurations that are out of scope, but based on my understanding of how sherlock will judge this, if an issue is dependent on such out of scope mechanisms, this will likely be invalid. I believe no further discussions is required, I will leave it to @Czar102 to decide |
@nevillehuang i admire your ability to see both sides of the argument. I think we just leave it up to the head judge now. My final point
Since there was no mention of the bots in readme, according to Sherlock rules we must judge this issue with the assumption that there is no bots that are in charge with the link funding. Therefore if we judge this issue fairly and in accordance with Sherlock documentation. I strongly believe this issue is a valid high. |
It is a part of protocol maintenance to top the LINK balance up. Even in an out-of-scope scenario where admins/developers don't top up, any user can top up LINK (essentially like a gas cost) to have randomness fulfilled to their bet. Planning to reject the escalations and leave the issue as is. |
you can calculate the cost of a request on this chainlink link inputting 500k as the callback gas which is what is used by the team
we get this from the calculator
Link price is currently 18$ thinking its logical that a user will pay 36$ just to fulfill his randomness is actually insane (this is not simply just gas cost, this is a substantial amount of money that i think virtually no one will ever pay). when hes not even guaranteed to win anything. Also the maximum cost per request can be up to 15 LINK, or 270.
Assuming a random user will pay 36$ to fulfill a function that guarantees him 0$ in this greed filled space is actually absurd to me, especially when many games on YOLO currently end in the winner profiting 24$ or .01 eth. Its almost certain no user will top up LINK in this scenario... If you actually think a user will pay up to 270 USD to fulfill his request then I guess this issue is invalid. |
Result: |
zzykxx
medium
A round can be canceled after a random number has been drawn in a specific edge case
Summary
There's an edge case in which the protocol fairness can be undermined by canceling a round after a random number has been drawn.
Vulnerability Detail
The
cancelAfterRandomnessRequest()
function allows anybody to cancel the current round if the round status isDrawn
and at least 1 day (24 hours) passed since the randomness request.To understand the root cause of this issue there's two things to keep in mind:
This might look fine in theory but in practice there's a small time window in which an user can cancel a round if the random number sent by chainlink is not in their favor.
POC
Here's how it works:
_drawWinner()
cancelAfterRandomnessRequest()
Important to note is that the delay between
4.
and.6
can happen because:Impact
Although this requires some preconditions and is unlikely to happen, there's a possibility of undermining the fairness of the protocol which is one of his main selling points:
Code Snippet
cancelAfterRandomnessRequest()
Tool used
Manual Review
Recommendation
Increase the time window after which
cancelAfterRandomnessRequest()
can be called by at least 10 minutes on mainnet and potentially more on cheaper chains:The text was updated successfully, but these errors were encountered: