Core Contracts

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

In Treasury.sol all yields from rebasing tokens will be stuck in the contracts. RAAC cannot use it's own RToken in Treasury.

Summary

In Treasury.sol, the deposit() and withdraw() functions have internal accounting to record the balance of tokens.

The issue is that it will not work with rebasing tokens. The protocol will likely use its own RToken in the treasury so that it will have some yields (funds in the treasury are stagnant for a long time).

All excess yields will be stuck forever in the Treasury as retrieving them is impossible because of how the internal accounting is done.

Vulnerability Details

  1. When a deposit() is made, _balances[token] += amount is recorded. Let's say 100 RToken (or scrvUSD) is deposited

  2. Time pass, and now the Treasury holds 110 scrvUSD

  3. Because of the internal accounting, it will not be possible to withdraw() more than 100 scrvUSD -> if (_balances[token] < amount) revert InsufficientBalance();

  4. 10 scrvUSD will be locked forever in the contract

Impact

All yields earned by deposited yield tokens in Treasury will be lost forever. Treasury of RAAC cannot use its own RToken (rebasing token) in treasury.

Tools Used

Manual

Recommendation

Remove the accounting and use balanceOf instead :

function deposit(address token, uint256 amount) external override nonReentrant {
if (token == address(0)) revert InvalidAddress();
if (amount == 0) revert InvalidAmount();
IERC20(token).transferFrom(msg.sender, address(this), amount);
- _balances[token] += amount;
- _totalValue += amount;
emit Deposited(token, amount);
}
function withdraw(
address token,
uint256 amount,
address recipient
) external override nonReentrant onlyRole(MANAGER_ROLE) {
if (token == address(0)) revert InvalidAddress();
if (recipient == address(0)) revert InvalidRecipient();
- if (_balances[token] < amount) revert InsufficientBalance();
+ if (IERC20(token)balanceOf(address(this)) < amount) revert InsufficientBalance(); //the transfer will revert as well so this line is not even mandatory
- _balances[token] -= amount;
- _totalValue -= amount;
IERC20(token).transfer(recipient, amount);
emit Withdrawn(token, amount, recipient);
}
Updates

Lead Judging Commences

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

Treasury::deposit increments _balances[token] with amount, not taking FoT or rebasing into account

Support

FAQs

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

Give us feedback!