Core Contracts

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

veRAACToken is missing an admin `pause` function

Summary

veRAACToken is pausable in that it has a public paused variable and uses the standard whenNotPaused modifiers. However there is no way to set paused = true.

Finding Description

veRAACToken.sol includes a public state variable for paused and a standard modifier using it:

/**
* @notice Whether the contract is paused
*/
bool public paused;
/**
* @notice Modifier to check if the contract is not paused
*/
modifier whenNotPaused() {
if (paused) revert ContractPaused();
_;
}

Source: veRAACToken.sol#L100-L103 and veRAACToken.sol#L150-L156

The whenNotPaused modifier is used by the functions lock, increase, and extend. e.g.

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {

Source: veRAACToken.sol#L212

However there is no function to assign a value to paused!

We expect an implementation such as this one from LendingPool.sol:

/**
* @notice Pauses the contract functions under `whenNotPaused`
* @dev Only callable by the contract owner
*/
function pause() external onlyOwner {
_pause();
}
/**
* @notice Unpauses the contract functions under `whenNotPaused`
* @dev Only callable by the contract owner
*/
function unpause() external onlyOwner {
_unpause();
}

Source: LendingPool.sol#L659-L673

Impact Explanation

In the event of an emergency, pausing the contract is NOT an option for the team. Given the partial implementation of the feature in this token's contract and then fact other contracts in this protocol do implement pause correctly suggests that the team believes this emergency action would be available to them.

Likelihood Explanation

Ideally pause is never needed. However contracts often includes it just in case, hoping that it never needs to be called.

Proof of Concept

It's difficult to prove that a needed capability is missing, but we can search for "paused =" to confirm veRAACToken doesn't include any functions for this purpose. Additionally we can cast interface veRAACToken which helps ensure we consider inherited contracts as well, after removing the view only functions we get the following interface. A quick scan also confirms ("emergency" functions here do not use the paused variable).

interface veRAACToken {
function approve(address spender, uint256 value) external returns (bool);
function cancelEmergencyAction(bytes32 actionId) external;
function emergencyWithdraw() external;
function enableEmergencyWithdraw() external;
function executeEmergencyUnlock() external;
function extend(uint256 newDuration) external;
function increase(uint256 amount) external;
function lock(uint256 amount, uint256 duration) external;
function recordVote(address voter, uint256 proposalId) external;
function renounceOwnership() external;
function scheduleEmergencyAction(bytes32 actionId) external;
function scheduleEmergencyUnlock() external;
function setMinter(address _minter) external;
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function transferOwnership(address newOwner) external;
function withdraw() external;
}

Recommendation

Add functions to pause/unpause like other contracts such as the LendingPool currently do. This git patch adds simple functions for this purpose:

diff --git a/contracts/core/tokens/veRAACToken.sol b/contracts/core/tokens/veRAACToken.sol
index 71c040c..22a571d 100644
--- a/contracts/core/tokens/veRAACToken.sol
+++ b/contracts/core/tokens/veRAACToken.sol
@@ -203,6 +203,14 @@ contract veRAACToken is ERC20, Ownable, ReentrancyGuard, IveRAACToken {
_lockState.maxTotalLocked = MAX_TOTAL_LOCKED_AMOUNT; // 1B
}
+ function pause() external onlyOwner {
+ paused = true;
+ }
+
+ function unpause() external onlyOwner {
+ paused = false;
+ }
+
/**
* @notice Creates a new lock position for RAAC tokens
* @dev Locks RAAC tokens for a specified duration and mints veRAAC tokens representing voting power
Updates

Lead Judging Commences

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

veRAACToken lacks the ability to configure `paused` variable

Support

FAQs

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