Core Contracts

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

in `veRAACToken::lock` function rewrite user preview lock

Summary

The lock function is used to create new locks, issue is that the contract doesn't check if there's an existing lock for the user. That means if Alice locks 100 tokens for a year and then later locks another 50 tokens for two years, the second call overwrites her first lock. She loses her initial 100 tokens because the contract replaces the old lock with the new one. The RAAC tokens from the first lock are still in the contract, but her lock structure now points to the new amount and duration. She can't withdraw the original 100 tokens anymore because the contract thinks she only locked 50.

I am aware that increase function is used to increase the lock amount, but if a user blindly uses lock after already locking, there should be a check that prevents them from overwriting their lock.

Vulnerability Details

// Missing check for existing lock
function lock(...) {
// No require(locks[msg.sender].amount == 0)
_lockState.createLock(...) // Overwrites existing entry
}

The lock creation mechanism lacks state validation checks. The lock function accepts new lock positions without verifying existing commitments:

poc

function test__lockOverridesUserPreviousLock() public {
address alice = makeAddr("alice");
uint256 someAmount = 200e18;
deal(alice, someAmount);
vm.prank(owner);
mockraac.mintTo(alice, someAmount);
vm.startPrank(alice);
mockraac.approve(address(raacToken), 100e18);
raacToken.lock(100e18, 365 days);
mockraac.approve(address(raacToken), 50e18);
raacToken.lock(50e18, 745 days);
IveRAACToken.LockPosition memory lp = raacToken.getLockPosition(alice);
assertEq(lp.amount, 50e18); // instead of 100e18 + 50e18
}

Impact

Previous locked amounts become permanently inaccessible as contract state gets overwritten.

Tools Used

manual review, foundry

Recommendations

check if user has existing lock before creating a new one
require(locks[msg.sender].amount == 0)

Updates

Lead Judging Commences

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