mintAndAuction() can be broken easily, and the auction flow can be permanently disabled for a collection. #931
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-1613
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/smart-contracts/MinterContract.sol#L292
https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/smart-contracts/MinterContract.sol#L295
Vulnerability details
Impact
Some collection id can have a parallel auction as well as regular phased minting. And
mintAndAuction()
enforces a periodic minting check to limit one token that can be minted for auction at a given time period.This issue is that this check is enforced with a flawed logic that allows
mintAndAuction()
to be broken for a collection.Proof of Concept
In MinterContract.sol -
mintAndAuction()
, whenever a collection allows minting, the function admin can mint one token per period. This is ensured through trackinglastMintDate[_collectionId]
to calculated the time passed since the last minttDiff = (block.timestamp - timeOfLastMint) /collectionPhases[_collectionID].timePeriod
. And the firsttimeOfLastMint
value is based on the collectionallowListStarTime
. This means thatmintAndAuction()
start time is the same as the generalmint()
.However, the way
lastMintDate[_collectionId]
is updated is flawed. Currently,lastMintDate[_collectionId]
is not updated strictly based onblock.timestamp
, but rather updated based on the current circulation supply of a token. This means that if the collection circulation supply is increased, thelastMintDate[_collectionId]
will be increased as well.And the collection circulation supply can be increased through many other methods such as
airDropTokens()
,mint()
orburnToMint()
, etc. For example, if users are minting new tokens for the collection through the publicly accessiblemint()
function, they can mint many tokens depending on the sales model and mint model.This means that when a user can mint directly through
mint()
to cause the token circulation supply to increase such that inmintAndAuction()
- lastMintDate[_collectionId]will be set as an unrealistic future timestamp, this will cause
(block.timestamp - timeOfLastMint)` to underflow, effectively disable all auction for the collection.(https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/smart-contracts/MinterContract.sol#L295)
(https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/smart-contracts/NextGenCore.sol#L191)
As seen above, when any of other minting methods such as
mint()
from MinterContract.sol invokesmint()
on NextGenCore.sol,collectionCirculationSupply
will increase, which means back inmintAndAuction()
,lastTimeDate[_collectionId]
will directly be updated to a future timestamp when anyone minted more than one token within a given period. And this will cause the futuremintAndAuction()
to revert due toblock.timestamp - timeOfLastMint
underflow.This vulnerability can either be exploited by a user maliciously minting to cause the auction flow to revert, or by the normal operation of public minting of excessive amounts of tokens.
Tools Used
Manual review
Recommended Mitigation Steps
Consider changing how
lastMintDate[_collectionId]
is calculated, calculating the timestamp based onblock.timestamp
such that the value will always reflect a historic timestamp.Assessed type
Error
The text was updated successfully, but these errors were encountered: