Forgotten Runiverse - Versus contest - cccz's results

Create-to-earn in the most Magical Metaverse on Web3. An interactive fantasy MMO based on the @forgottenrunes .

General Information

Platform: Code4rena

Start Date: 20/12/2022

Pot Size: $24,500 USDC

Total HM: 7

Participants: 4

Period: 2 days

Judge: GalloDaSballo

Total Solo HM: 4

Id: 198

League: ETH

Forgotten Runiverse

Findings Distribution

Researcher Performance

Rank: 2/4

Findings: 2

Award: $0.00

QA:
grade-a

🌟 Selected for report: 2

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: cccz

Also found by: hansfriese

Labels

bug
2 (Med Risk)
primary issue
selected for report
sponsor confirmed
M-04

Awards

Data not available

External Links

Lines of code

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLandMinter.sol#L362-L393

Vulnerability details

Impact

The first eight digits of the RuniverseLand TokenID indicate the corresponding plotSize of the NFT owner can call RuniverseLandMinter.ownerMintUsingTokenId directly to mint the NFT for a specific TokenID In RuniverseLandMinter._mintTokensUsingTokenId, there is no verification that the first eight bits of the tokenId match the plotSize parameter, which allows the owner to bypass the plotsAvailablePerSize limit.

    function _mintTokensUsingTokenId(
        IRuniverseLand.PlotSize plotSize,
        uint256 tokenId,
        address recipient
    ) private {
        uint256 numPlots = 1;
        require(
            plotsMinted[uint256(plotSize)] <
                plotsAvailablePerSize[uint256(plotSize)],
            "All plots of that size minted"
        );
        require(
            plotsMinted[uint256(plotSize)] + numPlots <=
                plotsAvailablePerSize[uint256(plotSize)],
            "Trying to mint too many plots"
        );

        plotsMinted[uint256(plotSize)] += 1;


        runiverseLand.mintTokenId(recipient, tokenId, plotSize);
    }

For example, the plotSize parameter provided by the owner when calling ownerMintUsingTokenId is 8 * 8, while the plotSize contained in the tokenId is 128 * 128, thus bypassing the plotsAvailablePerSize limit

Also, once RuniverseLands with mismatched tokenId and plotSize are minted, the supply of RuniverseLands with different plotSize will no longer be correct because the plotsMinted variable is incorrectly calculated

Proof of Concept

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLandMinter.sol#L362-L393

Tools Used

None

Consider verifying in RuniverseLandMinter._mintTokensUsingTokenId that the first eight bits of the tokenId match the plotSize parameter

#0 - GalloDaSballo

2022-12-23T19:58:46Z

Additional possibly broken invariant due to Admin Privilege

#1 - msclecram

2023-01-04T02:15:36Z

Duplicated from #6 .

#2 - c4-sponsor

2023-01-04T02:15:40Z

msclecram marked the issue as sponsor confirmed

#3 - GalloDaSballo

2023-01-05T10:54:17Z

Similarly to #11 the Warden has shown a way to bypass specific checks which offer an invariant, in this case the invariant is the fact that plotSizes are capped, which can be broken by using ownerMintUsingTokenId in an unintended way.

Because the lack of checks allows that, whereas the rest of the codebase offers checks to prevent that, I agree with Medium Severity

#4 - c4-judge

2023-01-06T12:30:55Z

GalloDaSballo marked the issue as primary issue

#5 - c4-judge

2023-01-06T14:27:53Z

GalloDaSballo marked the issue as selected for report

#6 - msclecram

2023-01-11T04:34:03Z

We updated the code with the next changes: -We removed _mintTokensUsingTokenId

https://github.com/bisonic-official/plot-contract/commit/ea8abd7faffde4218232e22ba5d8402e37d96878

Findings Information

🌟 Selected for report: cccz

Labels

bug
2 (Med Risk)
selected for report
sponsor acknowledged
M-05

Awards

Data not available

External Links

Lines of code

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLand.sol#L88-L102

Vulnerability details

Impact

RuniverseLand allows primaryMinter and secondaryMinter to mint NFT.

function mintTokenId( address recipient, uint256 tokenId, PlotSize size ) public override nonReentrant { require(numMinted < MAX_SUPPLY, "All land has been minted"); require( _msgSender() == primaryMinter || _msgSender() == secondaryMinter, "Not a minter" ); numMinted += 1; emit LandMinted(recipient, tokenId, size); _mint(recipient, tokenId); }

RuniverseLandMinter, as one of them, will have a limit on the number of NFTs with different PlotSize

    uint256[] public plotsAvailablePerSize = [
        52500, // 8x8
        16828, // 16x16
        560, // 32x32
        105, // 64x64
        7 // 128x128
    ];

This will be checked in _mintTokens

    function _mintTokens(
        IRuniverseLand.PlotSize plotSize,
        uint256 numPlots,
        address recipient
    ) private {        
        require(
            plotsMinted[uint256(plotSize)] <
                plotsAvailablePerSize[uint256(plotSize)],
            "All plots of that size minted"
        );        
        require(
            plotsMinted[uint256(plotSize)] + numPlots <=
                plotsAvailablePerSize[uint256(plotSize)],
            "Trying to mint too many plots"
        );        
        for (uint256 i = 0; i < numPlots; i++) {

            uint256 tokenId = ownerGetNextTokenId(plotSize);            
            plotsMinted[uint256(plotSize)] += 1; 

But the other minter is not limited and can mint RuniverseLand with any tokenID, thus breaking the plotsAvailablePerSize limit

Proof of Concept

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLand.sol#L88-L102 https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLandMinter.sol#L323-L341

Tools Used

None

Consider making RuniverseLandMinter the only minter for RuniverseLand

#0 - GalloDaSballo

2022-12-23T19:57:27Z

Risk of broken invariant, will flag, unsure about severity

#1 - c4-sponsor

2023-01-04T02:12:02Z

msclecram marked the issue as sponsor acknowledged

#2 - GalloDaSballo

2023-01-05T10:52:14Z

The warden has shown a way to bypass specific checks, while the function is privileged, the lack of checks is inconsistent with the checks applied in other parts of the codebase.

For this reason, I agree with Medium Severity

#3 - c4-judge

2023-01-06T14:28:05Z

GalloDaSballo marked the issue as selected for report

Findings Information

🌟 Selected for report: Lambda

Also found by: Dravee, cccz, hansfriese

Labels

bug
downgraded by judge
grade-a
QA (Quality Assurance)
sponsor acknowledged
Q-02

Awards

Data not available

External Links

Lines of code

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLand.sol#L88-L102

Vulnerability details

Impact

In RuniverseLand.mintTokenId, _mint takes in two parameters, recipient and tokenId

_mint(recipient, tokenId);

However, if the recipient is a contract address that does not support ERC721, the NFT can be frozen in the contract.

As per the documentation of EIP-721:

A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.

https://eips.ethereum.org/EIPS/eip-721

As per the documentation of ERC721.sol by OpenZeppelin:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol#L274-L285

Proof of Concept

https://github.com/code-423n4/2022-12-forgotten-runiverse/blob/dcad1802bf258bf294900a08a03ca0d26d2304f4/contracts/RuniverseLand.sol#L88-L102

Tools Used

None

use safeMint instead of mint to check received address support for ERC721 implementation

#0 - GalloDaSballo

2022-12-23T19:49:17Z

Not sold on Med, but is valid

#1 - c4-sponsor

2023-01-04T02:06:28Z

msclecram marked the issue as sponsor acknowledged

#2 - GalloDaSballo

2023-01-05T08:55:54Z

Downgrading to QA per this reasoning: https://github.com/code-423n4/2022-09-artgobblers-findings/issues/321#issuecomment-1275317394

Both mint and safeMint have downsides, these are worth flagging, but by themselves, in a fairly open-ended codebase, they are not sufficient to demonstrate a Med Severity

L

#3 - c4-judge

2023-01-05T08:56:00Z

GalloDaSballo changed the severity to QA (Quality Assurance)

#4 - GalloDaSballo

2023-01-06T14:27:22Z

2L 1R

A

#5 - c4-judge

2023-01-06T14:27:28Z

GalloDaSballo marked the issue as grade-b

#6 - c4-judge

2023-01-06T14:27:37Z

GalloDaSballo marked the issue as grade-a

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