Core Contracts

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

`StabilityPool` can be upgraded by anyone

Summary

The StabilityPool contract is meant to be upgradeable. In case it's going to use the UUPS pattern, it misses a function to authorize upgrades. This means upgrades can be done by anyone as the _authorizeUpgrade() function needs to be overridden with proper access control to only allow trusted accounts to perform an upgrade.

Vulnerability Details

According to the sponsor, the StabilityPool is meant to be an upgradeable contract. Generally, there are two options to make a contract upgradeable:

  1. Using transparent proxies

  2. Using the UUPS pattern

Both options are identical, in the sense that they require a proxy that users will talk to.
However, there's one crucial difference between the two:

When using transparent proxies, the upgrade logic lives in the proxy contract.
When using UUPS, the upgrade logic lives in the logic contract (allowing for upgrading the upgrade logic itself).

Looking at the code, it is unclear which options the implementers of the protocol will use. However, option 2 is more widely adopted these days due to the added flexibility of changing the upgrade logic when upgrading to a newer version.

For this case, the logic contract has to implement and override the necessary function to authorize the upgrades.
This function is missing in StabilityPool resulting in this contract being upgradeable by anyone, if it follows the UUPS pattern.

Impact

Due to the missing _authorizeUpgrade function in StabilityPool this contract will be upgradeable by anyone.

Tools Used

Manual review

Recommendations

First of all, add the UUPSUpgradeable to the inheritance chain, this makes it very explicit that this contract is making use of the UUPS pattern. Then, add the necessary _authorizeUpgrade function that this interface expects for its upgradeToAndCall() function.

Ensure that _authorizeUpgrade has proper access control so it can only be called by trusted accounts:

- contract StabilityPool is IStabilityPool, Initializable, ReentrancyGuard, OwnableUpgradeable, PausableUpgradeable {
+ contract StabilityPool is IStabilityPool, Initializable, ReentrancyGuard, OwnableUpgradeable, PausableUpgradeable, UUPSUpgradeable {
...
+. function _authorizeUpgrade(address newImplementation) internal view override onlyOwner {}
}

Relevant links

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!