Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken modifier implementation allows anyone to call mint* functions #152

Closed
code423n4 opened this issue Jan 27, 2023 · 2 comments
Closed
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-608 satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleReceipt.sol#L58-L61
https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleTickets.sol#L47-L50

Vulnerability details

https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleReceipt.sol#L58-L61

https://github.com/rabbitholegg/quest-protocol/blob/8c4c1f71221570b14a0479c216583342bd652d8d/contracts/RabbitHoleTickets.sol#L47-L50

Description

A mis-implementation of a modifier allows anyone to call the mint* functions of the RabbitHoleReceipt and RabbitHoleTickets contracts.

In the case of RabbitHoleReceipt.mint(), this allows an attacker to create valid Receipts for a Quest via its id, and then redeem the receipts for rewards via Erc20Quest.claim() and Erc1155Quest.claim(), draining all rewards to themselves.

In the case of RabbitHoleTickets, whatever benefit/value is applied to that token would be freely available to the minter.

PoC

Modify the existing RabbitHoleReceipt.spec.ts test 'mint' like so:

describe('mint', () => {
  it('mints a token with correct questId', async () => {
    await RHReceipt.connect(minterAddress).mint(firstAddress.address, 'def456')

    expect(await RHReceipt.balanceOf(firstAddress.address)).to.eq(1)
    expect(await RHReceipt.questIdForTokenId(1)).to.eq('def456')

    // connect to the Receipt with non-privileged user, call mint
    await RHReceipt.connect(firstAddress).mint(firstAddress.address, 'def456')
    // since there's no revert, we want their token balance to remain 1
    expect(await RHReceipt.balanceOf(firstAddress.address)).to.eq(1)
  })
})

The test will fail:

mints a token with correct questId:

AssertionError: expected 2 to equal 1. The numerical values of the given "ethers.BigNumber" and "number" inputs were compared, and they differed.
  + expected - actual

  -2
  +1

Mitigation

Fix the modifier as follows:

modifier onlyMinter() {
    require(msg.sender == minterAddress);
    _;
}

Note that this breaks other tests in the suite because of the use of owner.address instead of the QuestFactory contract in the initializer used to deploy the RabbitHoleReceipt.

Tools used

Provided test suite, manual review

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Jan 27, 2023
code423n4 added a commit that referenced this issue Jan 27, 2023
@c4-judge c4-judge closed this as completed Feb 5, 2023
@c4-judge
Copy link
Contributor

c4-judge commented Feb 5, 2023

kirk-baird marked the issue as duplicate of #9

@c4-judge
Copy link
Contributor

kirk-baird marked the issue as satisfactory

@c4-judge c4-judge added satisfactory satisfies C4 submission criteria; eligible for awards duplicate-608 and removed duplicate-9 labels Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-608 satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

2 participants