Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: low
Likelihood: low

Single-step ownership transfer in StrataxOracle can permanently lock admin control

Author Revealed upon completion

Description

  • StrataxOracle allows the current owner to transfer ownership by calling transferOwnership, which immediately sets the new owner. Only the owner can call setPriceFeed and setPriceFeeds to manage Chainlink price feeds.

  • The transfer happens in a single step with no confirmation from the receiving address. If an incorrect address is provided, ownership is irreversibly transferred and there is no way to recover it.

function transferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0), "Invalid address");
address previousOwner = owner;
// @> owner = _newOwner;
emit OwnershipTransferred(previousOwner, _newOwner);
}

Risk

Likelihood:

  • The owner makes a typo or copies the wrong address when calling transferOwnership.

  • The owner transfers to a contract address that has no capability to call owner-restricted functions.

Impact:

  • setPriceFeed and setPriceFeeds become permanently uncallable, making price feed management impossible.

  • The oracle cannot be updated or extended, which over time leads to stale or missing price data for new tokens in Stratax.sol.

Proof of Concept

  1. Owner calls transferOwnership(wrongAddress).

  2. owner is immediately set to wrongAddress.

  3. The deployer tries to call transferOwnership again — reverts with "Not owner".

  4. No one can call setPriceFeed or setPriceFeeds anymore.

  5. Protocol cannot add or update Chainlink price feeds.

Recommended Mitigation

+ address public pendingOwner;
function transferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0), "Invalid address");
- address previousOwner = owner;
- owner = _newOwner;
- emit OwnershipTransferred(previousOwner, _newOwner);
+ pendingOwner = _newOwner;
}
+ function acceptOwnership() external {
+ require(msg.sender == pendingOwner, "Not pending owner");
+ address previousOwner = owner;
+ owner = pendingOwner;
+ pendingOwner = address(0);
+ emit OwnershipTransferred(previousOwner, owner);
+ }

Support

FAQs

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

Give us feedback!