29122 - [SC - High] All reward tokens can be stolen by an attacker ...

Submitted on Mar 7th 2024 at 18:58:55 UTC by @Trust for Boost | ZeroLend

Report ID: #29122

Report type: Smart Contract

Report severity: High

Target: https://github.com/zerolend/governance

Impacts:

  • Theft of unclaimed yield

Description

Brief/Intro

Tokens can be distributed in the PoolVoter through distributeEx(). It will allocate tokens to different gauges based on their weights.

Vulnerability Details

The root issue is that when distributing it assumes all rewards were sent in the correct ratio, therefore it doesn't store how much was sent for each gauge. This could be exploited if notifyRewardAmount() returns false, in this case attacker can call distributeEx() again to re-dispatch the remaining balance of rewards. It could be repeated to claim a larger and large percentage of the reward balance, until there's diminishing returns. However, since distributeEx() can be called with any start,finish pair, we could exploit it regardly of any other token's notifyRewardAmount(). Just repeatedly call distributeEx() with the attacker's gauge to claim almost all rewards. We view this as a single root cause of not accounting for already sent portions for each gauge, so it is not submitted as two exploits.

Impact Details

All reward tokens can be stolen by an attacker with interest in a particular gauge.

Proof of Concept

The POC is implemented in a single file. Simply run steal_rewards() to see an example of one gauge getting more rewards than it should. The lines can also be uncommented to view the correct allocation when distributeEx() is called with all gauges.

Last updated

Was this helpful?