Closed sherlock-admin2 closed 11 months ago
Based on the following reasons, I believe this issue is invalid:
Merkle tree and proofs are generated off-chain assigned by the admin, as long as proofs are correctly assigned to the owner of the NFT, once the user gains back his NFT he can still claim prizes
If user provide NFT as collateral, then he is not participating in the game, so he shouldn't be assigned any rewards.
Escalate
I would like to answer these reasonings.
As far as I understand from the conversations with the sponsor, Merkle trees are generated automatically based on the NFT ownership. Prize earners are the club NFT owners at that moment. Therefore the prize earner will be assigned as the third party smart contract (vault etc) (Proofs are correctly assigned to the owner of the NFT as the judge says, but the owner at that moment is the third party contract). Getting back your NFT will not work and actually this is the exact thing I submitted in this issue. Prizes are not tied to NFTs, they are tied to accounts that holds NFT at that specific moment.
Leagues take around 1 month in this protocol and first 9 places earn prizes. A user playing 25-27 days and then depositing their NFT as a collateral just for a few days doesn't mean "they didn't play the game and they don't deserve". If that club finishes in top 9 places with user's accomplishments in the first 25 days, that club's earned prize will be assigned but no one will be able to claim it.
I also would like to point out that there is no scenario where blockchain gaming and this protocol is successful but the gaming NFTs are only used in-game. They will be used for lending, borrowing, investing and even renting and many more. It is not a user mistake, it is the nature of the blockchain space. Players are not warned about they must hold their NFTs in their wallets all the time.
The impact is not only a player losing a prize, it is also the protocol losing:
With these reasoning, I strongly believe this is a valid issue due to loss of funds, viable scenario (which is not unlikely) and conditions have a reasonable chance of becoming true in the future.
There is a viable scenario (even if unlikely) that could cause the protocol to enter a state where a material amount of funds can be lost. The attack path is possible with assumptions that either mimic on-chain conditions or reflect conditions having a reasonable chance of becoming true in the future.
Kind regards,
Escalate
I would like to answer these reasonings.
As far as I understand from the conversations with the sponsor, Merkle trees are generated automatically based on the NFT ownership. Prize earners are the club NFT owners at that moment. Therefore the prize earner will be assigned as the third party smart contract (vault etc) (Proofs are correctly assigned to the owner of the NFT as the judge says, but the owner at that moment is the third party contract). Getting back your NFT will not work and actually this is the exact thing I submitted in this issue. Prizes are not tied to NFTs, they are tied to accounts that holds NFT at that specific moment.
Leagues take around 1 month in this protocol and first 9 places earn prizes. A user playing 25-27 days and then depositing their NFT as a collateral just for a few days doesn't mean "they didn't play the game and they don't deserve". If that club finishes in top 9 places with user's accomplishments in the first 25 days, that club's earned prize will be assigned but no one will be able to claim it.
I also would like to point out that there is no scenario where blockchain gaming and this protocol is successful but the gaming NFTs are only used in-game. They will be used for lending, borrowing, investing and even renting and many more. It is not a user mistake, it is the nature of the blockchain space. Players are not warned about they must hold their NFTs in their wallets all the time.
The impact is not only a player losing a prize, it is also the protocol losing:
- That deposited prize funds, since the contract does not have a withdraw method for stuck/unclaimable prizes.
- Users trust and engagement with the game.
With these reasoning, I strongly believe this is a valid issue due to loss of funds, viable scenario (which is not unlikely) and conditions have a reasonable chance of becoming true in the future.
There is a viable scenario (even if unlikely) that could cause the protocol to enter a state where a material amount of funds can be lost. The attack path is possible with assumptions that either mimic on-chain conditions or reflect conditions having a reasonable chance of becoming true in the future.
Kind regards,
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.
@osmanozdemir1
TLDR, you are highlighting a potential timing issue about the merkle-proof generation that is an off-chain design opinion out of scope for this contest.
@nevillehuang
Long story short: The issue is not about incorrect Merkle tree generation or timing of it. We already know it is generated every time when a league ends. There is loss of funds regardless of the off-chain design opinion. Solutions are either changing both on-chain claimed prize tracking logic and off-chain tree generation, or implementing an on-chain withdraw method.
@osmanozdemir1
To me, what you are describing requires out of scope understanding of the off-chain merkle proof generation not known to any watson.
We already know it is generated every time when a league ends
Is this publicly available info? If not it is fair for watsons to assume the admin is trusted to generate correct merkle proofs. Since the solution can be implemented off-chain, then I still think this should be invalid, given it is out of scope. I will loop in sponsor @JDansercoer @logiclogue and head of judging @Czar102 to verify my claims.
@nevillehuang Thanks for the reply.
We already know it is generated every time when a league ends
Just to clarify, the reason I'm saying that is this logic. For this to happen, Merkle tree must be updated every time a league ends by adding latest prizes. Maybe I should've said "we must assume" instead of "we already know".
Thanks again and I'll wait your responses. Kind regards,
@osmanozdemir1 Based on your initial comment, I still maintain my stance as invalid and will wait for sponsor and head of judging to comment
Merkle trees are generated automatically based on the NFT ownership
From my understanding, "will not make mistakes [in merkle proofs]" means that the admins will choose an address that is able to claim the reward.
I fully agree with the Lead Judge @nevillehuang. I have nothing more to add to his argument. Also, this is an opportunity loss or an integration issue. Hence, the report is out of scope on this basis, too.
Planning to reject the escalation and leave the issue as is.
Result: Invalid Unique
osmanozdemir1
high
Some prizes can not be claimable and will be locked forever due to prizes being tied to accounts, not NFTs.
Summary
When the prize Merkle tree is generated, the club NFTs might be held in a contract that lacks a method for claiming prizes, leading to the prizes being locked in the
FootiumPrizeDistributor
Vulnerability Detail
This protocol is a blockchain gaming protocol where the users own their in-game assets, play, and earn prizes with their assets. This is the most important argument of the blockchain gaming industry: ownership of assets, and the ability to use your assets however you like.
Users play a football manager game in this protocol, the first 9 spots in a league earn prizes, and a Merkle tree is generated at the end of every season to prove who earned how much. This Merkle tree is generated based on who owns the NFT at that time and holds the lifetime value earned by the user(Club NFT owner at that time).
Here is the crucial part: Prizes are tied to accounts, not NFTs themselves.
Merkle Tree stores the total earned prizes by an account, and the smart contract tracks the total claimed prizes by an account.
Everything is okay so far. Where is the issue?
Let's go back to the ownership argument. Players can do whatever they want with their NFTs. They can play the game, they can store it in a cold wallet, transfer to someone etc.
Now imagine this scenario:
The year 2024-2025, and the bull market comes. This time it is not DeFi summer, it is GameFi summer. Blockchain gaming is very popular, and Footium Club NFTs gained a lot of value.
Bob is a long-time holder of the Club NFT and also plays the game.
In this game, every season is around 1 month in real life.
Bob plays the current season for 25 days. The season is about to finish and his team is in a good position. He will certainly win some prizes.
Bob needs some money but he doesn't want to sell his Footium NFT because the Footium is quite popular and will probably be worth much more in the future.
He decides to take a loan by providing his Footium NFT as collateral.
He may use NFTfi, Arcade, or many others.
NFT is transferred to an escrow contract or a vault depending on the protocol.
League finishes.
Bob pays his debt 1 week later and gets his NFT back. He thinks he can claim his earned prizes.
He doesn't have the prize. What?
Because the prizes are tied to accounts and not the NFTs themselves, that season's prize earner is appointed as the NFT lending platform's vault/escrow.
This is because the owner of the NFT is the vault/escrow at the moment when the Merkle tree is generated.
That vault/escrow contract of course does not have a way to call the
FootiumPrizeDistributor::claimETHPrize
.The prize is locked in the
FootiumPrizeDistributor
contract since no one can claim it (The contract also does not have a withdrawal method to save locked funds).I also would like to point out that this can not be considered a user mistake since there is no warning regarding how the players should use their club NFTs, and there is no warning that explains users must hold their NFTs in their wallet when the league ends.
Impact
Code Snippet
https://github.com/sherlock-audit/2023-12-footium/blob/main/footium-eth-shareable/contracts/FootiumPrizeDistributor.sol#L29C1-L31C57
https://github.com/sherlock-audit/2023-12-footium/blob/main/footium-eth-shareable/contracts/FootiumPrizeDistributor.sol#L109C2-L194C6
Tool used
Manual Review
Recommendation
It is hard to recommend a solution blindly and it depends on how the protocol wants to approach this.
If the protocol wants to give flexibility to its users in terms of asset ownership, then the protocol should track prizes with NFTs themselves not with the accounts. NFTs should have an internal value of earned prizes and claimed prizes. This will probably require much more work, but it also matches the main idea of asset ownership behind blockchain gaming.
The other option is restricting users' actions. The protocol should warn users regularly to hold their tokens in their wallet, especially during the time at the end of the season when the Merkle tree is generated. The protocol should tell its users they may lose their prizes if they transfer their tokens to other vaults. In the meantime, the protocol might need to add a withdraw function to save locked tokens in case of non-compliant users.
The second option is much easier to implement but unfortunately, it contradicts the asset ownership idea which is the starting point of blockchain gaming in the first place.