Core Contracts

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

Incorrect Block Tracking in `RAACMinter::pause/unpause/_setLastUpdateBlock` Logic Causes Under-Minting to Stability Pool

Summary

The RAACMinter::pause RAACMinter::unpause and RAACMinter::_setLastUpdateBlock functions improperly update lastUpdateBlock, leading to skipped block intervals between last update period and paused period. For example:

  • Normal operation: Last update at Block 2

  • Paused at Block 4

  • unpaused and tick at Block 5

  • Expected minting: Block 3* emissionRate

  • Actual result: lastUpdateBlock is set to 5 during unpausing, causing zero minting for Block 3.

Vulnerability Details

function pause(bool updateLastBlock, uint256 newLastUpdateBlock) external onlyRole(PAUSER_ROLE) {
_pause();
if (updateLastBlock) {
_setLastUpdateBlock(newLastUpdateBlock); <==@found
}
}
function unpause(bool updateLastBlock, uint256 newLastUpdateBlock) external onlyRole(PAUSER_ROLE) {
_unpause();
if (updateLastBlock) {
_setLastUpdateBlock(newLastUpdateBlock); <==@found
}
}
function _setLastUpdateBlock(uint256 newLastUpdateBlock) internal {
if (newLastUpdateBlock > block.number) revert InvalidBlockNumber();
lastUpdateBlock = newLastUpdateBlock == 0 ? block.number : newLastUpdateBlock; <==@found
emit LastUpdateBlockSet(lastUpdateBlock);
}

Impact

  • Under-minting: Stability pool receives fewer RAAC tokens than expected

  • Incorrect block tracking: Skips valid minting periods

Tools Used

  • Manual Review

Recommendations

Refactor as follows:

+ uint256 pausedBlock;
+ uint256 unpausedBlock;
function pause(bool updateLastBlock, uint256 newLastUpdateBlock) external onlyRole(PAUSER_ROLE) {
_pause();
if (updateLastBlock) {
- _setLastUpdateBlock(newLastUpdateBlock);
+ _setLastUpdateBlock(newLastUpdateBlock,true);
}
}
function unpause(bool updateLastBlock, uint256 newLastUpdateBlock) external onlyRole(PAUSER_ROLE) {
_unpause();
if (updateLastBlock) {
- _setLastUpdateBlock(newLastUpdateBlock);
+ _setLastUpdateBlock(newLastUpdateBlock,false);
}
}
function _setLastUpdateBlock(uint256 newLastUpdateBlock,bool pause) internal {
if (newLastUpdateBlock > block.number) revert InvalidBlockNumber();
- lastUpdateBlock = newLastUpdateBlock == 0 ? block.number : newLastUpdateBlock;
+ if(pause){
+ pausedBlock = block.number;
+ }else{
+ unpausedBlock = block.number;
+ lastUpdateBlock += unpausedBlock - pausedBlock + 1;
+ }
emit LastUpdateBlockSet(lastUpdateBlock);
}
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!