Core Contracts

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

Unchecked Return Value in RAACReleaseOrchestrator

Summary

RAACReleaseOrchestrator.sol::release RAACReleaseOrchestrator.sol::emergencyRevoke
The RAACReleaseOrchestrator contract contains two instances where the return value of the transfer function is not checked. This could lead to silent failures, state inconsistencies, and potential loss of funds if the token transfer fails.

https://detectors.auditbase.com/unchecked-transfer-return-values-solidity

Vulnerability Details

The transfer function of ERC20 tokens returns a boolean value indicating whether the transfer was successful or not. In the RAACReleaseOrchestrator contract, the return value of transfer is not checked in the following functions:

raacToken.transfer(beneficiary, releasableAmount);

The transfer function is called to send tokens to the beneficiary, but its return value is not checked.

raacToken.transfer(address(this), unreleasedAmount);

The transfer function is called to send unreleased tokens back to the contract, but its return value is not checked.

POC

A beneficiary calls the release function to claim their vested tokens.

The transfer function is called, but it fails (e.g., due to insufficient balance or a non-standard ERC20 token).

The contract does not check the return value, so it proceeds as if the transfer was successful.

The state is updated (schedule.releasedAmount += releasableAmount), but the tokens were not actually transferred.

This results in an inconsistent state and potential loss of funds.

Similarly, in the emergencyRevoke function:

An admin calls the emergencyRevoke function to revoke a vesting schedule.

The transfer function is called to return unreleased tokens to the contract, but it fails.

The contract does not check the return value, so it proceeds as if the transfer was successful.

The state is updated (delete vestingSchedules[beneficiary]), but the tokens were not actually transferred.

This results in an inconsistent state and potential loss of funds.

Impact

Funds Loss: If the transfer function fails, tokens may not be transferred, but the contract will assume they were. This could result in loss of funds for beneficiaries or the contract itself.

State Corruption: The contract's state (e.g., releasedAmount) may become inconsistent with the actual token balances.

Exploitation: Malicious or non-standard ERC20 tokens could exploit this behavior to manipulate the contract's state or cause unexpected behavior.

Tools Used

Manual Review

Recommendations

To fix this issue, you should always check the return value of the transfer function. Here are the recommended fixes:

  1. Use SafeERC20 Library
    The contract already imports the SafeERC20 library, which provides a safeTransfer function that reverts if the transfer fails. Replace the transfer calls with safeTransfer:

raacToken.safeTransfer(beneficiary, releasableAmount);
  1. Manually Check the Return Value
    If you prefer not to use SafeERC20, you can manually check the return value of the transfer function

bool success = raacToken.transfer(beneficiary, releasableAmount);
if (!success) revert TransferFailed();
  1. Add a Custom Error
    Define a custom error for failed transfers:

error TransferFailed();
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[INVALID] SafeERC20 not used

LightChaser Low-60

Support

FAQs

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