Open code423n4 opened 1 year ago
0xA5DF marked the issue as duplicate of #370
hansfriese changed the severity to QA (Quality Assurance)
hansfriese marked the issue as grade-a
This previously downgraded issue has been upgraded by hansfriese
hansfriese changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Frankencoin.sol#L290-L295 https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Frankencoin.sol#L148-L157
Vulnerability details
Bug Description
The
Frankencoin
contract determines if users are valid minters using theisMinter()
function:Frankencoin.sol#L290-L295
A user is a valid minter if
block.timestamp
is greater than or equal tominters[user]
.This is inconsistent with the
denyMinter()
function, which can be called by vetoers to prevent suggested users from becoming minters:Frankencoin.sol#L148-L157
As seen from above,
denyMinter()
can be called as long asblock.timestamp
is less than or equal tominters[user]
.Therefore, when
minters[user] == block.timestamp
,denyMinter()
still works althoughisMinter()
returns true.Impact
If a suggested user is vetoed at literally the last second (
block.timestamp == minters[user]
), the user might still be able to call minter functions, such asmint()
orburnFrom()
.Proof of Concept
Consider the following scenario:
suggestMinter()
with_applicationPeriod = 10 days
to suggest herself as minter.minters[alice] == block.timestamp
. During this period, no one has calleddenyMinter()
to veto Alice's suggestion.denyMinter()
at the last second to prevent Alice from becoming a minter.mint()
to mint Frankencoin for herself.mint()
will succeed.The following Foundry test demonstrates the scenario above:
Recommendation
Change
denyMinter()
to also revert whenblock.timestamp == minters[_minter]
:Frankencoin.sol#L152-L153
Alternatively, make suggested users become minters only after
minters[_minter]
has passed:Frankencoin.sol#L293-L295