How Was Radiant Capital Exploited?

5 min read

Learn the Radiant Capital exploit due to a smart contract vulnerability, resulting in a $4.5M loss.

TL;DR#

On January 3, 2024, Radiant Capital was exploited on the Arbitrum Chain due to a smart contract vulnerability, which resulted in a loss of 1902 ETH, worth approximately $4.5 million.

Introduction to Radiant#

Radiant is a lending and borrowing protocol.

Vulnerability Assessment#

The root cause of the exploit is the loss of precision during smart contract operations.

Steps#

Step 1:

We attempt to analyze one of the attack transactions executed by the exploiter.

Step 2:

The attacker is able to exploit a time window when a new market is activated in a lending market, forked from AAVE or Compound.

The issue was vested in the newly created USDC market on the Arbitrum chain, which was exploited 6 seconds after its deployment.

Step 3:

For the newly deployed token, the totalSupply parameter was uninitialized or set to 0, which allowed the hacker to perform price manipulation of the underlying assets through a flash loan attack.

Step 4:

The attacker was the first individual to supply in this new USDC market, and he then used that opportunity to manipulate the liquidityIndex, a key factor in determining the AToken user balances, to borrow all the ETH.

Step 5:

The liquidityIndex was shifted to a very larger value than what it should have been, and a flaw in the rayDiv function, a known rounding issue, was taken advantage of to siphon funds from the pool.

/**
 * @dev Divides two ray, rounding half up to the nearest ray
 * @param a Ray
 * @param b Ray
 * @return The result of a/b, in ray
 **/
function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
  require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
  uint256 halfB = b / 2;

  require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);

  return (a * RAY + halfB) / b;
}

Step 6:

As a result of this inflation, the cumulative precision loss was magnified, allowing the attacker to take away their share of profit through repeated deposit and withdrawal operations.

/**
 * @dev Mints `amount` aTokens to `user`
 * - Only callable by the LendingPool, as extra state updates there need to be managed
 * @param user The address receiving the minted tokens
 * @param amount The amount of tokens getting minted
 * @param index The new liquidity index of the reserve
 * @return `true` if the the previous balance of the user was 0
 */
function mint(address user, uint256 amount, uint256 index) external override onlyLendingPool returns (bool) {
  uint256 previousBalance = super.balanceOf(user);

  uint256 amountScaled = amount.rayDiv(index);
  require(amountScaled != 0, Errors.CT_INVALID_MINT_AMOUNT);
  _mint(user, amountScaled);

  emit Transfer(address(0), user, amount);
  emit Mint(user, amount, index);

  return previousBalance == 0;
}
/**
 * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
 * - Only callable by the LendingPool, as extra state updates there need to be managed
 * @param user The owner of the aTokens, getting them burned
 * @param receiverOfUnderlying The address that will receive the underlying
 * @param amount The amount being burned
 * @param index The new liquidity index of the reserve
 **/
function burn(address user, address receiverOfUnderlying, uint256 amount, uint256 index) external override onlyLendingPool {
  uint256 amountScaled = amount.rayDiv(index);
  require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT);
  _burn(user, amountScaled);

  IERC20(_underlyingAsset).safeTransfer(receiverOfUnderlying, amount);

  emit Transfer(user, address(0), amount);
  emit Burn(user, receiverOfUnderlying, amount, index);
}

Aftermath#

The team acknowledged the occurrence of the exploit and stated that the Radiant DAO council has temporarily paused lending and borrowing operations on the Arbitrum chain while they investigate the issue.

The team has also sent an on-chain message to the exploiter with hopes of recovering the stolen assets.

Solution#

To address the Radiant Capital exploit, it is imperative to swiftly and comprehensively enhance security protocols. This process should commence with a thorough examination of the smart contracts, with particular attention given to lending, flash loans, and the management of critical variables. This scrutiny is essential not only for safeguarding the accuracy of calculations but also for deterring any potential manipulative actions that might trigger similar breaches in the future.

Simultaneously, the platform should introduce advanced precision protection protocols. These measures involve imposing strict limitations on numerical operations to prevent loss of precision and establishing rigorous controls over pivotal variables that influence lending algorithms. Such robust measures are indispensable for intercepting any suspicious transactions or activities, thereby safeguarding users' assets against intricate threats.

The significance of precision in numerical operations cannot be overstated, especially when dealing with calculations involving ratios, rates, or percentages. This necessitates allowing for larger numerators in fractions. Additionally, careful consideration should be given to the sequence of operations, with a preference for prioritizing multiplication over division to maintain precision. A recommended practice involves temporarily elevating variables to a higher precision for all calculations and then reverting to the required precision.

Solidity's absence of support for floating-point numbers compels developers to resort to fixed-point arithmetic for decimal numbers. This method involves scaling values, such as multiplying by 10^18 for Ether, executing operations in this scaled integer form, and subsequently scaling down as necessary. While effective in preserving precision, this approach demands meticulous management of scaling factors, underscoring the pivotal role of fixed-point arithmetic in retaining precision without introducing risks.

Nevertheless, it is crucial to acknowledge that even with the most stringent security measures in place, vulnerabilities may still be exploited. This is where Neptune Mutual plays a pivotal role. In the event of security incidents, establishing a dedicated cover pool with Neptune Mutual could have substantially mitigated the aftermath of the attack on Radiant Capital. Neptune Mutual offers coverage to users who incur losses of funds or digital assets due to smart contract vulnerabilities, courtesy of their parametric policies.

Collaborating with Neptune Mutual eliminates the need for users to navigate the often intricate process of providing detailed proof of loss. Once an incident has been verified and resolved through Neptune Mutual's incident resolution framework, the protocol prioritizes the swift disbursement of compensations, providing immediate financial relief to those affected.

Neptune Mutual operates across various prominent blockchain networks, including EthereumArbitrum, and the BNB chain. This extensive presence enables us to cater to a diverse spectrum of DeFi users, delivering protection against potential vulnerabilities and reinforcing their trust in the ecosystem.

Reference Source PeckSheild

By

Tags