Core Contracts

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

`veRAACToken.lock` mechanism can lead to a permanent lock of RAAC funds

Relevant Links

Summary

veRAACToken.sol::lock mechanism can lead to a permannet lock of RAAC funds

Vulnerability Details

veRAACToken.sol::lock when creating a lock, calls this line which creates a lock on the lockState

_lockState.createLock(msg.sender, amount, duration);

The createLock method is implemented as follows.

function createLock(
LockState storage state,
address user,
uint256 amount,
uint256 duration
) internal returns (uint256 end) {
// ... input sanitation ...
end = block.timestamp + duration;
// @audit : notice, we destructively override the previous lock value
state.locks[user] = Lock({
amount: amount,
end: end,
exists: true
});
state.totalLocked += amount;
emit LockCreated(user, amount, end);
return end;
}

When we create a lock, a certain amount of RAAC token is sent to the veRAACToken and we get an equivalent amount of veRAACToken minted to us and then a Lock is created indicating the amount locked and the endtime of the lock. All the other methods that permit to go the reverse route, that is, from veRAACToken to RAAC token only convert the amount of the lock and not a user defined value. In other words, the user can't determine which amount to unlock or convert other than the whole of the amount in the Lock to be withdrawn. These methods are:

The issue here is that, if I lock amounts X and an hour after I like amount Y. Given that, my lock state for amount X has now been overriden by that of amount Y, I can no longer recover my X amount of RAAC tokens I created the first lock with. This is because, that lock is nowhere to be found in the system to be unlcoked.

One might ask, why would the user create 2 locks? 2 answers come to my head quickly.

  • Said user lost track of the fact that, he had already created a lock

  • User thought that, creating a lock for the second time will update the existing lock with the additional amount and or new end time of the incoming lock. Given the impact and how trivial the fix is, I think this warrants fixing.

Impact

Permanent lock of user funds

Tools Used

Manual review

Recommendations

File: LockManager.sol

function createLock(
LockState storage state,
address user,
uint256 amount,
uint256 duration
) internal returns (uint256 end) {
// Validation logic remains the same
if (state.minLockDuration != 0 && state.maxLockDuration != 0) {
if (duration < state.minLockDuration || duration > state.maxLockDuration)
revert InvalidLockDuration();
}
if (amount == 0) revert InvalidLockAmount();
end = block.timestamp + duration;
+ require(!state.locks[user].exists, "Lock already exist, rather `increaseLock` or `extendLock`");
state.locks[user] = Lock({
amount: amount,
end: end,
exists: true
});
state.totalLocked += amount;
emit LockCreated(user, amount, end);
return end;
}
Updates

Lead Judging Commences

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

Give us feedback!