Core Contracts

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

Ambiguous Function Naming and Overlapping Logic in Voting Power Calculations

Description

The veRAACToken.sol contract contains two functions named getVotingPower:

  1. getVotingPower(address account): Returns the current voting power for an account.

  2. getVotingPower(address account, uint256 timestamp): Returns the voting power for an account at a specific timestamp.

Additionally, the internal functions calculatePowerAtTimestamp and getCurrentPower appear to perform similar calculations, but there is no clear distinction between their use cases. This creates confusion for developers and users, as it is unclear which function to use in a given scenario. Furthermore, the overlapping logic in these functions suggests potential redundancy or inconsistency in the implementation.

Affected Code

External Functions

/**
* @notice Gets the current voting power for an account
* @dev Calculates voting power based on lock amount and remaining time
* @param account The address to check voting power for
* @return The current voting power of the account
*/
function getVotingPower(address account) public view returns (uint256) {
return _votingState.getCurrentPower(account, block.timestamp);
}
/**
* @notice Gets the voting power for an account at a specific timestamp
* @dev Calculates time-weighted voting power at the given timestamp
* @param account The address to check
* @param timestamp The timestamp to calculate voting power at
* @return The voting power at the specified timestamp
*/
function getVotingPower(address account, uint256 timestamp) external view returns (uint256) {
return _votingState.calculatePowerAtTimestamp(account, timestamp);
}

Internal Functions

/**
* @notice Calculates voting power at a specific timestamp
* @dev Applies time-based decay to voting power
* @param state The voting power state
* @param account The account to check
* @param timestamp The timestamp to check power at
* @return The voting power at the specified timestamp
*/
function calculatePowerAtTimestamp(
VotingPowerState storage state,
address account,
uint256 timestamp
) internal view returns (uint256) {
RAACVoting.Point memory point = state.points[account];
if (point.timestamp == 0) return 0;
if (timestamp < point.timestamp) {
return 0;
}
uint256 timeDelta = timestamp - point.timestamp;
int128 adjustedBias = point.bias - (point.slope * int128(int256(timeDelta)));
return adjustedBias > 0 ? uint256(uint128(adjustedBias)) : 0;
}
/**
* @notice Gets the current voting power for an account
* @param state The voting power state
* @param account The account to check
* @param timestamp The timestamp to check power at
* @return The current voting power
*/
function getCurrentPower(
VotingPowerState storage state,
address account,
uint256 timestamp
) internal view returns (uint256) {
RAACVoting.Point memory point = state.points[account];
if (point.timestamp == 0) return 0;
if (timestamp < point.timestamp) {
return uint256(uint128(point.bias));
}
uint256 timeDelta = timestamp - point.timestamp;
// Calculate decay
int128 adjustedBias = point.bias;
if (timeDelta > 0) {
// Calculate decay per second and multiply by time delta
int128 decay = (point.slope * int128(int256(timeDelta))) / int128(int256(1));
adjustedBias = point.bias - decay;
}
// Return 0 if power has fully decayed
return adjustedBias > 0 ? uint256(uint128(adjustedBias)) : 0;
}

Vulnerability Details

  1. Ambiguous Function Naming:

    • The two external functions share the same name (getVotingPower), making it unclear which one to use in a given scenario.

    • The internal functions calculatePowerAtTimestamp and getCurrentPower also appear to perform similar calculations, but there is no clear distinction between their use cases.

  2. Overlapping Logic:

    • Both calculatePowerAtTimestamp and getCurrentPower calculate voting power by applying time-based decay to a user's voting power. However, the logic is not consistent:

      • calculatePowerAtTimestamp returns 0 if timestamp < point.timestamp.

      • getCurrentPower returns point.bias if timestamp < point.timestamp.

    • This inconsistency could lead to incorrect results depending on which function is used.

  3. Lack of Clarity:

    • There is no clear guidance on when to use calculatePowerAtTimestamp versus getCurrentPower. This could lead to developers using the wrong function, resulting in incorrect voting power calculations.

Tools Used

Manual Review

Recommended Mitigation Steps

  1. Rename External Functions:

    • Rename getVotingPower(address account) to getCurrentVotingPower(address account).

    • Rename getVotingPower(address account, uint256 timestamp) to getVotingPowerAtTimestamp(address account, uint256 timestamp).

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.