In the tick function, tokens are minted directly to the StabilityPool but the minted amount is also added to the excessTokens variable. Later, in the mintRewards function, excessTokens is used to determine if additional tokens need to be minted to this contract in order to transfer rewards. Since the tokens minted in tick are sent to the StabilityPool and not held by the RAACMinter contract, the contract’s internal accounting of excessTokens overestimates the tokens available. This discrepancy can cause the mintRewards function to attempt a transfer that reverts because the contract lacks sufficient tokens.
Token Minting in tick:
In the tick function, when amountToMint is calculated, the following operations occur:
Here, amountToMint is added to excessTokens, implying these tokens are available for reward transfers. However, the tokens are minted to the stabilityPool rather than to the RAACMinter contract.
Reward Distribution in mintRewards:
In the mintRewards function, the contract uses excessTokens to determine if additional minting is needed:
This logic assumes that excessTokens reflects tokens held by the contract. In reality, tokens minted in tick were sent to the StabilityPool, so the RAACMinter contract's balance might be insufficient to satisfy the safeTransfer.
Consequences:
False Availability:
The contract erroneously believes it holds extra tokens (tracked by excessTokens), even though those tokens are located at the StabilityPool address.
Transfer Revert:
When mintRewards calls raacToken.safeTransfer(to, amount), it may revert because the RAACMinter contract doesn’t actually hold the tokens it expects based on excessTokens.
Assume:
The tick function calculates amountToMint = 100 tokens.
These 100 tokens are minted to the StabilityPool.
The contract then sets excessTokens += 100.
Later, when mintRewards is called with amount = 50:
The contract computes:
Since excessTokens (100) >= amount (50), it sets:
toMint = 0
excessTokens = excessTokens - amount = 100 - 50 = 50
The function then attempts:
However, the RAACMinter contract’s own balance does not include these 100 tokens (they reside in the StabilityPool), so the transfer fails due to insufficient balance.
Reversion of Reward Transfers:*
The mismatch causes the mintRewards function to revert because it attempts to transfer tokens that aren’t actually held by the RAACMinter contract.
Inaccurate Accounting:
The internal accounting (excessTokens) does not accurately reflect the contract's token balance, leading to potential inconsistencies in token distribution.
Potential Denial-of-Service:
Repeated failures in reward transfers may disrupt the normal operation of the reward distribution mechanism, affecting users relying on timely rewards.
Manual review
Align Minting Destination with Accounting:
Either mint tokens directly to the RAACMinter contract in the tick function (so that excessTokens accurately reflects tokens available for transfer), or adjust the accounting to exclude tokens minted to the StabilityPool.
Separate Accounting:
Maintain separate accounting for tokens minted to the StabilityPool and tokens held by the RAACMinter contract, ensuring that mintRewards only considers tokens actually available for transfer.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.