Core Contracts

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

User's `balanceOf` does not decay over time leading to vote accounting errors

Summary

The lack of decay logic in veRAACToken.balanceOf() will cause voting power accounting errors as user's actual power decays but their balance does not decrease accordingly.

Root Cause

In veRAACToken.sol, the balanceOf function is inherited from ERC20 without overriding, causing it to remain static while voting power decays over time.

Vulnerability Details

The contract documentation explicitly states that voting power should decay linearly over time:

/**
* @title Vote Escrowed RAAC Token
* @notice A vote-escrowed token contract that allows users to lock RAAC tokens to receive voting power and boost capabilities
* @dev Implementation of vote-escrowed RAAC (veRAAC) with time-weighted voting power, emergency controls, governance integration and boost calculations
* Key features:
* - Users can lock RAAC tokens for voting power
-> * - Voting power decays linearly over time
*/

However, the balanceOf function, which represents user's power, does not implement this decay mechanism since it's using the basic ERC20 implementation.

This mismatch between intended and actual behavior leads to several issues:

  1. The increase() function can revert unexpectedly when the new calculated power is less than current balance

  2. GaugeController.vote() uses incorrect voting power by reading the non-decaying balance

  3. Total voting power becomes inaccurate over time

PoC

Consider this scenario:

  1. User locks 1e18 RAAC tokens for 365 days

    • Initial veRAACToken balance = 1e18 * 365/1460 = 0.25e18

  2. After 182.5 days (half year), user attempts to increase lock by 0.5e18 RAAC

    • New power calculation: 1.5e18 * (365/2)/1460 = 0.1875e18

    • Current balance = 0.25e18

    • _mint(msg.sender, newPower - balanceOf(msg.sender)) reverts as 0.1875e18 - 0.25e18 is negative

The transaction reverts even though this should be a valid increase operation.

Impact

  • Incorrect voting power accounting affecting governance

  • Failed token operations due to power/balance mismatch

  • Inaccurate total voting power calculations

Mitigation

  1. Override balanceOf() to return time-decayed voting power

  2. Override getTotalVotingPower() to return decayed total power

  3. Update voting power calculations to properly handle decay

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

veRAACToken::increase underflows on newPower - balanceOf(msg.sender)

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!