Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

Emergency Withdrawal Breaks Fee Distribution

Summary

A critical vulnerability exists in the FeeCollector contract where using the emergency withdrawal feature breaks the contract's core functionality.

Vulnerability Details

When emergency withdrawal is used, it removes all tokens without updating the internal accounting (collectedFees). This creates a mismatch between what the contract thinks it has and its actual balance.

To reproduce:

1. Collect 200 RAAC fees
2. Emergency withdraw all funds
3. Collect 100 more RAAC
4. Try to distribute -> fails with InsufficientBalance

To run it place the following code in FeeCollector.test.js, in fee collection and distribution section:

it('will leave the contract in a broken state if some funds are drawn for an emergency', async () => {
const feeCollectorAddress = await feeCollector.getAddress();
console.log(feeCollectorAddress);
console.log(owner.address);
const feeAmount = ethers.parseEther("200");
await raacToken.mint(owner.address, feeAmount);
await raacToken.connect(owner).approve(feeCollectorAddress, feeAmount);
await feeCollector.connect(owner).collectFee(feeAmount, 7);
// Pause and withdraw emergency
await feeCollector.connect(emergencyAdmin).pause();
await feeCollector.connect(emergencyAdmin).emergencyWithdraw(await raacToken.getAddress());
await feeCollector.connect(emergencyAdmin).unpause();
// Collect more fees after emergency withdrawal
const newFeeAmount = ethers.parseEther("100");
await raacToken.mint(owner.address, newFeeAmount);
await raacToken.connect(owner).approve(feeCollectorAddress, newFeeAmount);
await feeCollector.connect(owner).collectFee(newFeeAmount, 7);
// Try to distribute fees - should fail
await expect(
feeCollector.connect(owner).distributeCollectedFees()
).to.be.revertedWithCustomError(feeCollector, "InsufficientBalance");
});

Impact

  • Contract becomes permanently unable to distribute fees

  • Core functionality is broken after emergency actions

Tools Used

Manual review, unit tests

Recommendations

On emergency withdraw, reset collectedFees variable.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.