Forgeries contest - Ruhum's results

A protocol for on-chain games with NFT prizes on Ethereum.

General Information

Platform: Code4rena

Start Date: 13/12/2022

Pot Size: $36,500 USDC

Total HM: 5

Participants: 77

Period: 3 days

Judge: gzeon

Total Solo HM: 1

Id: 191

League: ETH

Forgeries

Findings Distribution

Researcher Performance

Rank: 38/77

Findings: 1

Award: $45.71

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

45.7078 USDC - $45.71

Labels

bug
downgraded by judge
grade-b
QA (Quality Assurance)
satisfactory
sponsor disputed
edited-by-warden
Q-08

External Links

Lines of code

https://github.com/code-423n4/2022-12-forgeries/blob/main/src/VRFNFTRandomDraw.sol#L271

Vulnerability details

Impact

Legacy NFTs like CryptoPunks don't follow the ERC721 standard. Those tokens won't be usable as either drawing or raffled tokens. Because the contest documentation explicitly stated the usage of CryptoPunks as drawing tokens, I thought it's worth bringing up here.

We want to raffle away a single NFT (token) based off of another NFT collection (or drawingToken) in a fair and trustless manner. For instance, we could raffle off a single high value NFT to any cryptopunk holder, the punk that wins can choose to claim the NFT. If they do not claim, a re-roll or redraw can be done to select a new holder that would be able to claim the NFT.

This does not result in any loss of funds. It only impacts the functionality of the contract.

Proof of Concept

The VRFNFTRandomDraw expects the drawingToken to have an ownerOf() function. Calls to that function will revert resulting in nobody being able to claim their NFT.

    function hasUserWon(address user) public view returns (bool) {
        if (!request.hasChosenRandomNumber) {
            revert NEEDS_TO_HAVE_CHOSEN_A_NUMBER();
        }

        return
            user ==
            IERC721EnumerableUpgradeable(settings.drawingToken).ownerOf(
                request.currentChosenTokenId
            );
    }

As seen here, the CryptoPunks contract doesn't have an ownerOf() function. Instead, you have to use punkIndexToAddress().

Tools Used

none

You can write a custom adapter that acts as an in-between for the VRFNFTRandomDraw and legacy NFT contracts.

#0 - c4-judge

2022-12-17T16:25:23Z

gzeon-c4 marked the issue as primary issue

#1 - c4-judge

2022-12-17T16:25:37Z

gzeon-c4 marked the issue as satisfactory

#2 - trust1995

2022-12-17T17:50:27Z

Cryptopunk compatibility is submitted often in ERC721-centric protocols. From what I've seen, they are considered QA, such as in PartyDAO , Cally and recently by Alex in Blur. They can always be externally wrapped which is what mostly happens in these types of protocols, without the requirement of the project to do it. It's worth standardizing this type of submission, maybe alongside other popular non-ERC20s. Will open a DAO discussion.

#3 - iainnash

2022-12-19T20:30:58Z

Would argue that this is not an issue. It's an example of a known contract that isn't an NFT and we require a valid NFT to support this protocol. Additionally, this is not mentioned anywhere in the code and in my opinion should fail which is the correct behavior in this case.

#4 - iainnash

2022-12-20T12:09:26Z

I would say most people use wrapped punks in situations such as this — as @trust1995 has written

#5 - c4-sponsor

2023-01-01T18:37:44Z

iainnash marked the issue as sponsor disputed

#6 - c4-judge

2023-01-07T17:08:45Z

gzeon-c4 changed the severity to QA (Quality Assurance)

#7 - c4-judge

2023-01-07T17:09:11Z

gzeon-c4 marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter