NextGen - 0xblackskull's results

Advanced smart contracts for launching generative art projects on Ethereum.

General Information

Platform: Code4rena

Start Date: 30/10/2023

Pot Size: $49,250 USDC

Total HM: 14

Participants: 243

Period: 14 days

Judge: 0xsomeone

Id: 302

League: ETH

NextGen

Findings Distribution

Researcher Performance

Rank: 51/243

Findings: 1

Award: $137.89

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Labels

bug
2 (Med Risk)
downgraded by judge
partial-50
sufficient quality report
duplicate-741

Awards

137.8889 USDC - $137.89

External Links

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/NextGenCore.sol#L147

Vulnerability details

Impact

The bug enables an attacker to tamper with _collectionArtistAddress after triggering with _collectionTotalSupply = 0, If the artist has already signed the collection data, setCollectionData may display a different value than the actual _collectionArtistAddress, potentially leading to misattributed ownership of the smart contract system . Additionally, when _collectionTotalSupply = 0 is applied, it breaks protocol invariants related to viewTokensIndexMin and viewTokensIndexMax

Proof of Concept

function test_createCollectionSetCollectionData_withZero_collectionTotalSupply() public {
        string[] memory _collectionScript = new string[](2);
        _collectionScript[0] = "Script One";
        _collectionScript[1] = "Script Two";
        core.createCollection(
            "collectionName",
            "collectionArtist", 
            "collectionDescription", 
            "collectionWebsite",
            "_collectionLicense", 
            "_collectionBaseURI", 
            "_collectionLibrary", 
            _collectionScript);
            core.isCollectionCreated(1);
            
            uint256 _collectionID = 1;

            address _collectionArtistAddress1 = address(4);
            uint256 _maxCollectionPurchases2= 10000;
            uint _setFinalSupplyTimeAfterMint2 = 1000;
            
            uint256 _collectionTotalSupply1 = 0; 
            uint256 _collectionTotalSupply2 = 10; 
            core.setCollectionData(_collectionID, _collectionArtistAddress1, _maxCollectionPurchases2, _collectionTotalSupply1, _setFinalSupplyTimeAfterMint2); //NOTE setCollectionData 1

            (address collectionArtistAddress, uint256 maxCollectionPurchases, uint256 collectionCirculationSupply, uint256 collectionTotalSupply, uint setFinalSupplyTimeAfterMint, address randomizerContract) = core.retrieveCollectionAdditionalData(1);
            console.log("_collectionTotalSupply with 0 value");
            console.log("First setCollectionData collectionArtistAddress:",collectionArtistAddress);

            console.log("viewTokensIndexMin: ", core.viewTokensIndexMin(1));
            console.log("viewTokensIndexMax: ", core.viewTokensIndexMax(1));

            vm.label(address(4), "1st Artist");
            vm.startPrank(address(4));
            core.artistSignature(1,"0x");
            vm.stopPrank();
            core.artistSigned(1); //, "0x");
            
            // console.log(core.artistsSignatures(1));

            vm.label(address(5), "2nd Artist");
            address _collectionArtistAddress2 = address(5);
            core.setCollectionData(_collectionID, _collectionArtistAddress2, _maxCollectionPurchases2, _collectionTotalSupply2, _setFinalSupplyTimeAfterMint2);  //NOTE setCollectionData 2

            // core.retrieveCollectionAdditionalData(1);
            (address collectionArtistAddress2, uint256 maxCollectionPurchases2, uint256 collectionCirculationSupply2, uint256 collectionTotalSupply2, uint setFinalSupplyTimeAfterMint2, address randomizerContract2) = core.retrieveCollectionAdditionalData(1);
            
            console.log("---------------------------------");
            console.log("_collectionTotalSupply with arbitary value");
            console.log("Second setCollectionData collectionArtistAddress:",collectionArtistAddress2);

            console.log("viewTokensIndexMin: ", core.viewTokensIndexMin(1));
            console.log("viewTokensIndexMax: ", core.viewTokensIndexMax(1));
            
            
            // vm.startPrank(address(5));
            // // core.artistSignature(1, "0x");
            // vm.stopPrank();    
            // core.setCollectionData(_collectionID, _collectionArtistAddress2, _maxCollectionPurchases2, _collectionTotalSupply2, _setFinalSupplyTimeAfterMint2);  //NOTE setCollectionData 2

 }

Traces

[PASS] test_createCollectionSetCollectionData_withZero_collectionTotalSupply() (gas: 553337) Logs: _collectionTotalSupply with 0 value First setCollectionData collectionArtistAddress: 0x0000000000000000000000000000000000000004 viewTokensIndexMin: 10000000000 viewTokensIndexMax: 9999999999 --------------------------------- _collectionTotalSupply with arbitary value Second setCollectionData collectionArtistAddress: 0x0000000000000000000000000000000000000005 viewTokensIndexMin: 10000000000 viewTokensIndexMax: 10000000009

Tools Used

Foundry

require(_collectionTotalSupply != 0);

Assessed type

Context

#0 - c4-pre-sort

2023-11-20T13:45:50Z

141345 marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-11-22T12:23:24Z

141345 marked the issue as duplicate of #478

#2 - c4-judge

2023-12-01T21:29:30Z

alex-ppg marked the issue as not a duplicate

#3 - c4-judge

2023-12-01T21:29:44Z

alex-ppg marked the issue as duplicate of #1972

#4 - c4-judge

2023-12-01T21:40:22Z

alex-ppg marked the issue as duplicate of #478

#5 - c4-judge

2023-12-08T21:55:10Z

alex-ppg marked the issue as partial-50

#6 - c4-judge

2023-12-09T00:22:40Z

alex-ppg changed the severity to 2 (Med Risk)

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