Core Contracts

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

StabilityPool contract and its inheritance patterns

Summary

Looking at the StabilityPool contract and its inheritance patterns, I notice an architectural inconsistency. The contract uses OwnableUpgradeable and PausableUpgradeable base contracts but doesn't appear to implement the full upgradeability pattern since it's missing UUPSUpgradeable.

Vulnerability Details

Here's my analysis of why this could be problematic:

  1. The Upgradeable Pattern Mismatch The contract uses upgradeable versions of Ownable and Pausable, which are designed to work with proxy patterns, but doesn't implement the actual proxy upgrade mechanism through UUPSUpgradeable. This creates a partial implementation of the upgradeability pattern.

  2. Initialization vs Construction The contract uses an initialize() function instead of a constructor, which is a pattern typically used with proxy contracts. However, without the full proxy implementation, this initialization pattern doesn't provide its intended benefits.

Impact

The vulnerability exists in the initialize function which is part of the upgradeable contract pattern (using OpenZeppelin's Initializable). Here are the key issues:

  1. Unprotected Initialization: While the contract has an initializer modifier, there's no protection ensuring that the initialization happens in the same transaction as the deployment. This means anyone could potentially front-run the initialization or call it if it wasn't properly initialized by the deployer.

  2. Critical State Setting: The initialize function sets critical contract addresses and state:

    • rToken

    • deToken

    • raacToken

    • raacMinter

    • crvUSDToken

    • lendingPool

  3. Basic Address Validation: While there is a zero-address check:

`if (_rToken == address(0) || _deToken == address(0) || _raacToken == address(0) || _raacMinter == address(0) || _crvUSDToken == address(0) || _lendingPool == address(0)) revert InvalidAddress();`

This only prevents zero addresses but doesn't validate that the addresses actually implement the expected interfaces.

The potential exploit scenario:

  1. The contract is deployed but not initialized immediately in the same transaction

  2. An attacker could front-run and call initialize with malicious contract addresses

  3. This would give the attacker control over critical protocol components since they could deploy fake tokens and minter contracts

Tools Used

Manual review

Recommendations

Either use or don't use upgradable contracts.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!