Core Contracts

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

Missing Slope Change Adjustment in `withdraw` and `emergencyWithdraw` Functions Leads to Stale Slope Data

Summary:

The withdraw and emergencyWithdraw functions in the veRAACToken contract are missing the crucial step of adjusting the slope changes recorded in the VotingPowerLib's state.slopeChanges mapping when a user withdraws their locked tokens. While the user's lock information and point data are deleted, the corresponding entry in state.slopeChanges, which tracks changes in voting power slope over time, is not updated. This omission can lead to stale slope data.

Vulnerability Details:

The lock, increase, and extend functions in veRAACToken, which modify a user's lock, correctly call the _updateSlopeChanges function in VotingPowerLib to adjust the state.slopeChanges mapping. This mapping is essential for accurate voting power calculations as it tracks how the slope of a all voting power changes over time.

However, the withdraw and emergencyWithdraw functions, which handle the removal of a user's lock, do not call _updateSlopeChanges.

// In veRAACToken.sol (withdraw and emergencyWithdraw)
function withdraw() external nonReentrant {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount;
uint256 unlockTime = userLock.end;
// ... other code ...
//@audit But _updateSlopeChanges is NOT called
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender]; // User points are deleted
}
function emergencyWithdraw() external nonReentrant {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount;
uint256 unlockTime = userLock.end;
// ... other code ...
//@audit But _updateSlopeChanges is NOT called
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender]; // User points are deleted
}

This means that after a user withdraws, the state.slopeChanges mapping might still contain an entry related before withdrawal of lock.

Impact:

The missing slope change adjustment can lead to the following problems:

  • Inconsistent State Changes: The state.slopeChanges mapping might contain stale data related to withdrawn locks, leading to inconsistent states.

  • Unexpected Behavior: The contract might exhibit unexpected behavior in scenarios where in future if time-dependent voting power calculations are involved.

Proof of Concept (PoC):

Scenario: Alice locks 100 tokens for 365 days. Her slope change is recorded in state.slopeChanges. Alice then withdraws her tokens.

  1. Alice calls lock(100, 365 days). An entry is added to state.slopeChanges reflecting the change in her voting power slope.

  2. Alice calls withdraw(). Her lock information and points are deleted, but the _updateSlopeChanges function is
    not called, and the corresponding entry in state.slopeChanges remains same

The state.slopeChanges mapping now contains stale data. If this data is used in future voting power calculations, the results might be incorrect.

Recommended Mitigation:

In both the withdraw and emergencyWithdraw functions, before deleting the user's lock information and points, call the _updateSlopeChanges function with the appropriate parameters to adjust the state.slopeChanges mapping.

function withdraw() external nonReentrant whenNotPaused {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount;
uint256 unlockTime = userLock.end;
// ... other code ...
+ _updateSlopeChanges(_votingState, userLock.end, _votingState.points[msg.sender].slope, 0); // Call _updateSlopeChanges
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
// ... rest of the code ...
}
function emergencyWithdraw() external nonReentrant {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
uint256 amount = userLock.amount;
uint256 unlockTime = userLock.end;
// ... other code ...
+ _updateSlopeChanges(_votingState, userLock.end, _votingState.points[msg.sender].slope, 0); // Call _updateSlopeChanges
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
// ... rest of the code ...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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.

Give us feedback!