Core Contracts

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

Potential Reward Distribution Inconsistencies Due to L2 Block Number Behavior

Summary

The RAAC protocol is expected to be compatible with all EVM-compatible. Problem is the RAACMinter contract uses block.number with a fixed 12-second block time assumption, which is incompatible with L2 networks that use L1 block numbers and have different block timing. This could result in inaccurate reward distributions on L2 deployments.

Vulnerability Details

The core issue lies in the RAACMinter's assumptions about block timing:

uint256 public constant BLOCKS_PER_DAY = 7200; // Assuming 12-second block time
uint256 public constant INITIAL_RATE = 1000 * 1e18; // 1000 RAAC per day
uint256 public constant MAX_BENCHMARK_RATE = 2000 * 1e18 / BLOCKS_PER_DAY; // 2000 RAAC per day maximum
uint256 public minEmissionRate = 100 * 1e18 / BLOCKS_PER_DAY; // 100 RAAC per day minimum
uint256 public maxEmissionRate = 2000 * 1e18 / BLOCKS_PER_DAY; // 2000 RAAC per day maximum
// Used in tick() function
uint256 public lastUpdateBlock;
uint256 blocksSinceLastUpdate = currentBlock - lastUpdateBlock;
uint256 amountToMint = emissionRate * blocksSinceLastUpdate;

The contract calculates rewards based on block differences, but this calculation is problematic in some L2s. Let's take a look on Arbitrum for instance:

  1. block.number on Arbitrum returns the L1 block number "ish" (approximately), not the actual L2 block number

  2. L2 blocks are created based on usage, not at fixed intervals

  3. The assumption of 7200 blocks per day (12-second blocks) doesn't hold true on L2s

For example:

Wall Clock time 12:00 am 12:00:15 am 12:00:30 am 12:00:45 am 12:01 am 12:01:15 am
L1 block.number 1000 1001 1002 1003 1004 1005
L2 block.number 1000 1000 1000 1000 1004 1004

This means the reward calculation emissionRate * blocksSinceLastUpdate could be incorrect in two ways:

  1. Underestimating rewards during periods of high L2 activity (many L2 blocks per L1 block)

  2. Overestimating rewards during periods of low L2 activity (few L2 blocks per L1 block)

Impact

  1. The reward distribution will significantly deviate from the intended token emissions over time.

  2. Users might receive different amounts of rewards for the same time period.

Tools Used

Manual Review

Recommendations

  1. Avoid using block.number directly.

  2. On Arbitrum for instance, the reliable way to get the block.number is using ArbSys, i.e: arbSys.arbBlockNumber()

  3. Pass a variable for the blocks per day in the constructor so it can be adjusted during deployment based on the chain protocol being deployed.

Updates

Lead Judging Commences

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

RAACMinter hardcoded BLOCKS_PER_DAY breaks cross-chain compatibility with variable token emission rates

Known issue LightChaser M12

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

RAACMinter hardcoded BLOCKS_PER_DAY breaks cross-chain compatibility with variable token emission rates

Known issue LightChaser M12

Appeal created

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

RAACMinter hardcoded BLOCKS_PER_DAY breaks cross-chain compatibility with variable token emission rates

Known issue LightChaser M12

Support

FAQs

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