The SwanManager contract inherits from OpenZeppelin’s OwnableUpgradeable contract to restrict certain functions to the contract’s owner. However, because this contract is designed for upgradeable deployment, the ownership is not set in the constructor. Instead, it must be set in an initialization function (initialize) since the constructor is disabled in upgradeable contracts by calling _disableInitializers(). Currently, SwanManager lacks an initialize function or equivalent to set the owner. Without this function, no account will have ownership rights, rendering all onlyOwner functions inaccessible and blocking essential administrative actions.
The SwanManager contract uses OpenZeppelin’s OwnableUpgradeable for access control, which provides the onlyOwner modifier to restrict access to functions like setMarketParameters, setOracleParameters, setFactories, addOperator, and removeOperator. In upgradeable contracts, constructors are disabled since the contract’s logic is deployed only once, while the storage and ownership are handled separately in proxy deployments. Therefore, an initialization function (initialize) is required to set the owner upon deployment.
Here is the current constructor in SwanManager:
By calling _disableInitializers, this constructor prevents the contract from being reinitialized, as is standard practice for OpenZeppelin’s upgradeable contract pattern. However, without an initialization function, the contract never calls __Ownable_init, the function that would set the contract owner in an upgradeable context.
Due to the lack of an initialize function, the ownership of SwanManager is never set. Functions guarded by the onlyOwner modifier cannot be called, including setMarketParameters, setOracleParameters, setFactories, addOperator, and removeOperator. This prevents essential contract configuration and administrative tasks from being performed, which are required to operate the contract as intended. The owner should have control over key contract parameters, such as market settings, oracle parameters, and authorized operators. Without ownership set, no account has administrative control over the contract, limiting its functionality and impeding its adaptability to evolving needs or scenarios.
Manual Review
To resolve this issue, implement an initialize function in the SwanManager contract that sets the owner upon deployment. This function should call __Ownable_init to assign the deployer as the owner, or it can accept an address parameter to assign a specified account as the owner.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.