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.