Core Contracts

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

Unsafe Typecasting in Voting Power Calculation

Overview

This report analyzes a vulnerability in the getCurrentPower function, where unsafe typecasting is employed during voting power calculations. The vulnerability primarily arises from a dual-type mismatch and lack of proper overflow checks, which can lead to critical miscalculations and potential exploits in governance mechanisms.

Key Issues

  1. Dual-Type Mismatch

    • Signed vs. Unsigned: The point.bias variable is declared as an int128 (signed), yet voting power inherently must be non-negative.

    • Unsafe Casting: Casting from int128 to uint128 (and subsequently to uint256) can lead to improper sign handling. For instance, a negative bias value, due to incorrect calculations, would convert to a large positive number when cast, thereby inflating a user’s voting power erroneously.

  2. Calculation Risks

    • Overflow During Initialization: In calculateAndUpdatePower, the bias is derived from an initialPower (a uint256) via:

      bias = int128(int256(initialPower)); // Unsafe downcast

      If initialPower exceeds 2^127 - 1, the downcast overflows, causing bias to become negative.

    • Incorrect Result Example: For instance, an initialPower of 2^127 results in bias being set to -2^127. When subsequently cast to uint128, this negative value converts to 2^127, drastically distorting the voting power calculation.

  3. Missing Safety Checks

    • Validation Gaps: There is no validation to ensure that bias remains non-negative or fits within the uint128 range.

    • Silent Truncation/Overflow: The lack of explicit checks can cause silent overflow or truncation, corrupting the intended voting power values without triggering any errors.

Impact

  • Incorrect Voting Power: Users might experience massively inflated or erroneously reduced voting power. Negative bias values, when misinterpreted as large positive numbers, can lead to incorrect token voting weights.

  • Governance Attacks: Malicious actors may exploit these miscalculations to manipulate voting outcomes, undermining the protocol’s integrity.

  • Fund Locking: The miscalculation may result in tokens being permanently locked or misallocated, disrupting the overall tokenomics and governance structure.

Fixes

  1. Use uint128 for Bias

    • Redesign the RAACVoting.Point structure to store bias as uint128 since voting power should always be non-negative:

      struct Point {
      uint128 bias; // Changed from int128
      int128 slope;
      uint256 timestamp;
      }
    • Update all related calculations to consistently use uint128.

  2. Add Overflow Checks

    • Incorporate explicit validations when setting bias:

      // In calculateAndUpdatePower
      require(initialPower <= type(uint128).max, "Overflow");
      bias = uint128(initialPower);
    • This ensures that values do not exceed the permissible range and prevents silent overflow.

  3. Adjust Return Logic

    • With bias stored as uint128, the return logic in getCurrentPower can be simplified:

      return adjustedBias > 0 ? uint256(adjustedBias) : 0;
    • This eliminates the need for unsafe casts and guarantees correct interpretation of the voting power.

  4. Fix calculateInitialPower

    • Remove redundant casts once the bias type is updated:

      return uint256(bias); // Directly return as uint256

Example Scenario

Consider a scenario where a user locks tokens resulting in:

  • Initial Condition: initialPower = 2^128

  • Current Code Behavior:

    • bias = int128(2^128) overflows, resulting in bias = -2^127.

    • When cast via uint256(uint128(point.bias)), the negative value -2^127 becomes 2^127, erroneously granting an excessively high voting power.

  • Fixed Code Behavior:

    • The check require(2^128 <= type(uint128).max) would fail, reverting the transaction and preventing invalid locks.

    • Alternatively, if properly bounded, the new design with uint128 would correctly handle the calculation without misinterpretation.

Conclusion

The unsafe typecast in the getCurrentPower function, combined with the use of a signed type for inherently unsigned voting power calculations, introduces a significant vulnerability. This mismanagement of data types can lead to either inflated or deflated voting power, posing risks of governance attacks and token misallocation. Addressing this issue requires restructuring the data types, adding robust overflow checks, and revising related calculations to ensure the integrity of the voting mechanism. Implementing these changes is critical to maintaining protocol security and preventing potential exploits.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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