Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Randomizer RNG return value 0 will revert #1606

Closed
c4-submissions opened this issue Nov 13, 2023 · 6 comments
Closed

Randomizer RNG return value 0 will revert #1606

c4-submissions opened this issue Nov 13, 2023 · 6 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-1627 partial-50 Incomplete articulation of vulnerability; eligible for partial credit only (50%) sufficient quality report This report is of sufficient quality

Comments

@c4-submissions
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/58090c9fbc036c06bbaa9600ec326034f2181a17/hardhat/smart-contracts/RandomizerRNG.sol#L48-L50
https://github.com/code-423n4/2023-10-nextgen/blob/58090c9fbc036c06bbaa9600ec326034f2181a17/hardhat/smart-contracts/NextGenCore.sol#L299-L303

Vulnerability details

Impact

The fulfillRandomWords call will revert and the NFT random hash cannot be set. The NFT will be corrupted.

Proof of Concept

When generating the random hash using Arrng, after getting the numbers, it packs the numbers with tokenID and cast to bytes32 to get the random hash. This casting truncates the packed data to its first 256 bits.

    bytes32(abi.encodePacked(numbers,requestToToken[id]))
File: smart-contracts/RandomizerRNG.sol
48:     function fulfillRandomWords(uint256 id, uint256[] memory numbers) internal override {
49:         gencoreContract.setTokenHash(tokenIdToCollection[requestToToken[id]], requestToToken[id], bytes32(abi.encodePacked(numbers,requestToToken[id])));
50:     }

https://github.com/code-423n4/2023-10-nextgen/blob/58090c9fbc036c06bbaa9600ec326034f2181a17/hardhat/smart-contracts/RandomizerRNG.sol#L48-L50

If the returned random number is 0, it means that the packed bytes will be 0x0000000000000000000000000000000000000000000000000000000000000000 despite of the token id.

Chisel output

    chisel
    Welcome to Chisel! Type `!help` to show available commands.
    ➜ uint256[] memory numbers = new uint256[](1);
    ➜ numbers[0] = 0;
    ➜ uint256 id = 10000000000;
    ➜ bytes32 c = bytes32(abi.encodePacked(numbers, id));
    ➜ c
    Type: bytes32
    └ Data: 0x0000000000000000000000000000000000000000000000000000000000000000
    ➜

However, if the _hash is 0x0000000000000000000000000000000000000000000000000000000000000000 then the gencoreContract.setTokenHash call will revert. The tokenToHash is not set.

File: smart-contracts/NextGenCore.sol
299:     function setTokenHash(uint256 _collectionID, uint256 _mintIndex, bytes32 _hash) external {
300:         require(msg.sender == collectionAdditionalData[_collectionID].randomizerContract);
301:         require(tokenToHash[_mintIndex] == 0x0000000000000000000000000000000000000000000000000000000000000000);
302:         tokenToHash[_mintIndex] = _hash;
303:     }

https://github.com/code-423n4/2023-10-nextgen/blob/58090c9fbc036c06bbaa9600ec326034f2181a17/hardhat/smart-contracts/NextGenCore.sol#L299-L303

The same issue can happen to RandomizerVRF despite the probability of returning 0 is very low.

Tools Used

Manual

Recommended Mitigation Steps

To prevent the potential for a zero hash, modify the hash generation in RandomizerRNG to use keccak256 instead of abi.encodePacked

    function fulfillRandomWords(uint256 id, uint256[] memory numbers) internal override {
-        gencoreContract.setTokenHash(tokenIdToCollection[requestToToken[id]], requestToToken[id], bytes32(abi.encodePacked(numbers,requestToToken[id])));
+        gencoreContract.setTokenHash(tokenIdToCollection[requestToToken[id]], requestToToken[id], keccak256(abi.encodePacked(numbers,requestToToken[id])));
    }

Assessed type

en/de-code

@c4-submissions c4-submissions added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Nov 13, 2023
c4-submissions added a commit that referenced this issue Nov 13, 2023
@c4-pre-sort c4-pre-sort added the sufficient quality report This report is of sufficient quality label Nov 20, 2023
@c4-pre-sort
Copy link

141345 marked the issue as sufficient quality report

@c4-pre-sort
Copy link

141345 marked the issue as duplicate of #852

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Dec 6, 2023
@c4-judge
Copy link

c4-judge commented Dec 6, 2023

alex-ppg changed the severity to QA (Quality Assurance)

@c4-judge c4-judge reopened this Dec 10, 2023
@c4-judge
Copy link

This previously downgraded issue has been upgraded by alex-ppg

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value and removed downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax labels Dec 10, 2023
@c4-judge
Copy link

alex-ppg marked the issue as duplicate of #1688

@c4-judge
Copy link

alex-ppg marked the issue as partial-50

@c4-judge c4-judge added partial-50 Incomplete articulation of vulnerability; eligible for partial credit only (50%) duplicate-1627 and removed duplicate-1688 labels Dec 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-1627 partial-50 Incomplete articulation of vulnerability; eligible for partial credit only (50%) sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

3 participants