One of the invariants of the protocol is that users can only claim HealthToken
if they own three different MartenisaToken
s, but due to the lack of access control in MartenitsaToken::updateCountMartenitsaTokensOwner
any user can call the function to increase their token counter, without actually owning any token, and then execute MartenitsaMarketplace::collectReward
to get free rewards.
Rewards can be minted for free by following the next steps:
User calls three time MartenitsaToken::updateCountMartenitsaTokensOwner
Now that the user's token counter is equal to 3, he calls MartenitsaMarketplace::collectReward
Now the user owns 1 HealthToken
To verify the exploit, paste the following test in MartenitsaToken.t.sol
:
Invariant of the protocol broken, HealthToken
s can be minted for free
Manual review, Foundry
I recommend refactoring the external updateCountMartenitsaTokensOwner
function into two new functions as such:
an external
updateCountMartenitsaTokensOwner
function to act as an exclusive entry point for MartenitsaMarketplace
, because this is the only external contract that needs access to MartenitsaToken::countMartenitsaTokensOwner
an internal
_updateCountMartenitsaTokensOwner
function to be called in the context of MartenitsaToken
when a new token is minted in MartenitsaToken::createMartenitsa
Check the following example on how to update MartenitsaToken
:
Update MartenitsaToken::createMartenitsa
:
Create MartenitsaToken::updateCountMartenitsaTokensOwner
:
Update MartenitsaToken::updateCountMartenitsaTokensOwner
:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.