StabilityPool is an upgradeable contract but doesn't initialize the contract correctly.
The constructor is misconfigured, allowing potential attackers to initialize the contract thenselves.
Attacker can take over the ownership of this contract.
- address private immutable _initialOwner;
.
.
.
constructor(address initialOwner) {
- _initialOwner = initialOwner;
+ _disableInitializers();
}
.
.
.
function initialize(
+ address _owner,
address _rToken,
address _deToken,
address _raacToken,
address _raacMinter,
address _crvUSDToken,
address _lendingPool
) public initializer {
if (_rToken == address(0) || _deToken == address(0) || _raacToken == address(0) || _raacMinter == address(0) || _crvUSDToken == address(0) || _lendingPool == address(0)) revert InvalidAddress();
- __Ownable_init(_initialOwner);
+ __Ownable_init(_owner);
__Pausable_init();
rToken = IRToken(_rToken);
deToken = IDEToken(_deToken);
raacToken = IRAACToken(_raacToken);
raacMinter = IRAACMinter(_raacMinter);
crvUSDToken = IERC20(_crvUSDToken);
lendingPool = ILendingPool(_lendingPool);
// Get and store the decimals
rTokenDecimals = IRToken(_rToken).decimals();
deTokenDecimals = IDEToken(_deToken).decimals();
}
Since the developer wants the owner of this contract to be immutable, the protocol team should consider using the Ownable2StepUpgradeable contract to prevent misconfiguration.