An attacker could call Treasury.sol::deposit with:
An arbitrary token address argument and
A specially amount param
to brick Treasury.sol::deposit.\
The attacker call will set _totalValue to 2**256-1 (without transfering any tokens) via amount call argument, so later calls to Treasury.sol::deposit will overflow this variable and revert
The vulnerability occurs because contracts/core/collectors/Treasury.sol::deposit function doesnt validate token address (it only checks address is not zero [1]):
Next in [2] Treasury transfers from msg.sender amount number of tokens
Finally in [3] _totalValue is incremented by amount call argument
Note that _totalValue is a uint256 contract state variable.
This means the max value for _totalValue is 2**256-1
Once _totalValue reaches its maximum value later deposit calls will revert due to overflow
So an attacker could deploy an arbitrary contract C that returns true to transferFrom calls with any value argument.
And then call Treasury.sol::deposit(C,amount)
where amount = 2**256 -1 - amount_already_deposited_in_treasury
So _totalValue will reach it maximum value and later Treasury.sol::deposit will revert
The following PoC show the described scenario:
An attacker deploys a custom contract and bricks Treasury.sol::deposit without depositing any token
Create a custom contract file in contracts/mocks/core/tokens/MockEmptyCT.sol with the following code:
Add test case in test/unit/core/collectors/Treasury.test.js under "Deposits" section:
Start a localnode:
Execute test with:
Observe attacker bricked treasury deposit function without spending any token
Severity: High due to exploiting this vulnerability bricks deposits to treasury for any user
Manual Review
Implement a whitelist of approved token addresses to deposit to Treasury.sol::deposit
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.