Open hats-bug-reporter[bot] opened 1 month ago
Thank you for your report. We've confirmed this behavior is working as intended, preventing double minting between v1 and v2 tokens. While it allows 'unstopping' v2 tokens, this doesn't pose a significant security risk. We've categorized this as a low-priority issue. We appreciate your attention to detail.
Hi @benjaminbollen thank you for your comment !
I agree that I incorrectly classified this issue as a high-severity vulnerability, as it doesn't meet any of the criteria for high severity outlined in the Hats severity guidelines.
However, it does fall under the medium severity category according to the Hats documentation:
Issues that lead to an economic loss but do not lead to direct loss of on-chain assets. Examples are:
- Attacks that make essential functionality of the contracts temporarily unusable or inaccessible.
This issue allows users to mint when they shouldn't by resetting the INDEFINITE_FUTURE
, making the essential stop
functionality temporarily inaccessible. It's important to note that for an issue to be classified as medium severity, the term "temporarily" is key, meaning the disruption can occur for even a short period of time.
Secondly since the user is able to mint when he should not this effectively causes economic loss, whether it may be important to the protocol or not. This does not have to be a direct loss of funds as that would be classified as a HIGH vulnerability.
I want to reiterate that I agree this doesn't pose a significant security risk. However, it still qualifies as medium severity, as that classification doesn't require a significant security threat.
I hereby kindly ask you to reassess this issue.
This issue allows users to mint when they shouldn't by resetting the INDEFINITE_FUTURE, making the essential stop functionality temporarily inaccessible.
What does it even mean "to make the stop functionality temporarily inaccessible"?
At no point is the stop()
function unavailable, even temporarily.
Furthermore,
stop()
is a user's choice to indicate that they no longer want to mint; it is not essential because we could have equally opted for pause()
and unpause()
to indicate user preferences, which with the current bug it is a "one-time unpause". To be clear, it is called stop()
and the intended design is for it to irrevocably stop, not once-pause-unpause-stop().v1:stop()
to avoid double mint. So yes, the expectation is that for a Circles v3 in some future, v2:stop()
functions correctly to then build on it. But for the concern of v2, this is only a deviation of the intended design/common sense. If any financial loss could have come from it, can only occur in a Circles v3 wrongly building on a broken v2:stop(); but errors in unwritten future code are clearly out of scope of any/this security review.In conclusion, we stay with our judgment of (a very good!) low
issue.
Github username: -- Twitter username: -- Submission hash (on-chain): 0x656ba747c9cf205046fac382c4ea7acfdf437e1261a20107b208517353de9e74 Severity: high
Description: The
stop
function is designed to prevent any future mints by settinglastMintTime
toINDEFINITE_FUTURE
. This action is intended to be irreversible.The issue, however, is that a user can reset the
mintTime.lastMintTime
after it has been set toINDEFINITE_FUTURE
, which violates a key aspect of the protocol: once thestop
function is executed, it should be irreversible.The user can do so simply by calling
calculateIssuanceWithCheck
:This will invoke
_updateMintV1Status
if V1 Circles has not been stopped:In this case, if the
mintV1Status
changed,mintTime.lastMintTime
is reset toblock.timestamp
to prevent potential overlap between Hub v1 and Hub v2. However, it does not verify whethermintTime.lastMintTime
has already been set toINDEFINITE_FUTURE
.A change in
mintV1Status
can easily occur if the status is modified within the V1 contract.This ultimately will allow a user to reset the
stop
functionalityFix
Only allow updating the
mintTime.lastMintTime
if it is not set toINDEFINITE_FUTURE