Platform: Code4rena
Start Date: 25/01/2023
Pot Size: $36,500 USDC
Total HM: 11
Participants: 173
Period: 5 days
Judge: kirk-baird
Total Solo HM: 1
Id: 208
League: ETH
Rank: 160/173
Findings: 1
Award: $2.59
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0xMAKEOUTHILL, 0xMirce, 7siech, AkshaySrivastav, AlexCzm, Awesome, Aymen0909, Cryptor, Deivitto, DimitarDimitrov, ElKu, Garrett, Jayus, Josiah, Kenshin, KrisApostolov, RaymondFam, SovaSlava, Timenov, UdarTeam, amaechieth, btk, c3phas, codeislight, fellows, frankudoags, gzeon, hansfriese, luxartvinsec, millersplanet, mookimgo, navinavu, oberon, paspe, pavankv, petersspetrov, pfapostol, prestoncodes, rbserver, sakshamguruji, shark, thekmj, trustindistrust, tsvetanovv, usmannk, vagrant, vanko1, xAriextz, yosuke
2.5852 USDC - $2.59
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleReceipt.sol#L58-L61 https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleReceipt.sol#L98-L104 https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleTickets.sol#L47-L50 https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleTickets.sol#L83-L85
The onlyMinter
modifier is meant to act as access control, preventing unauthorised users from minting, however, the implementation of the modifier is missing a require/revert statement and is therefore implemented incorrectly. As this modifier is broken, it has full access to the mint function, which essentially breaks the functionality of this protocol.
This is the modifier in question.
modifier onlyMinter() { msg.sender == minterAddress; // @audit incorrect implementation _; }
This is a POC to show how it doesn't work, using the protocols existing tests & changing the caller of the function which is meant to be access restricted:
describe('mint', () => { it.only('mints a token with correct questId', async () => { await RHReceipt.connect(hackerAddress).mint(firstAddress.address, 'def456') expect(await RHReceipt.balanceOf(firstAddress.address)).to.eq(1) expect(await RHReceipt.questIdForTokenId(1)).to.eq('def456') }) })
This is the output from running that test:
RabbitholeReceipt Contract mint ✓ mints a token with correct questId
Manual Audit + Hardhat tests
Change modifier to:
modifier onlyMinter() { require(msg.sender == minterAddress); _; }
#0 - c4-judge
2023-02-05T04:48:15Z
kirk-baird marked the issue as duplicate of #9
#1 - c4-judge
2023-02-14T08:39:14Z
kirk-baird marked the issue as satisfactory