29181 - [SC - High] Tautology in PoolVoterregisterGauge makes it im...
Submitted on Mar 9th 2024 at 20:29:08 UTC by @nethoxa for Boost | ZeroLend
Report ID: #29181
Report type: Smart Contract
Report severity: High
Target: https://github.com/zerolend/governance
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
Tautology in PoolVoter::registerGauge
makes it impossible to add pools to the _pools
array, as it checks for isPool[_asset]
to be true
, which is set in the same logical branch so it can't be triggered. That makes most of the distribute*
functions useless as they rely on either _pools.length
(which would be 0
so they become NOPs) or they access elements inside such array, triggering an OOB error and always reverting such a transaction.
Vulnerability Details
It is pretty visual, the only place where isPool
is set to true
for a given asset is in PoolVoter::registerGauge
:
function registerGauge(
address _asset,
address _gauge
) external onlyOwner returns (address) {
if (isPool[_asset]) {
_pools.push(_asset);
isPool[_asset] = true;
}
...
}
however, as mappings defaults to 0
or false
, it won't be triggered and the _pools
array will remain empty.
Impact Details
Calls to distribute
or distributeEx
will either revert or return without doing anything, as they rely on _pools.length
to iterate the array or they will access it, even if it is empty. That is, those functions remain useless, so it can be seen a self-griefing from the contract to any user who calls those functions.
Proof of Concept
I initialized a Foundry repo to test it, but I believe this is simple enough that it does not matter which framework you use to test it. I can provide the repo if you want:
pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import {PoolVoter} from "src/voter/PoolVoter.sol";
contract POC is Test {
function test_POC() external {
PoolVoter voter = new PoolVoter();
voter.init(address(0xabcd), address(0xabcd));
voter.registerGauge(address(0xabcd), address(0xabcd));
require(voter.pools().length == 0, "POC");
}
}
Last updated
Was this helpful?