Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: low
Invalid

Missing Initializer Modifiers in SystemConfig.sol and TokenManager.sol

Summary

The initialize functions in both SystemConfig.sol and TokenManager.sol lack modifiers to ensure they can only be called once. This absence allows the initialize functions to be called multiple times, leading to potential issues with contract state predictability and security. Adding the initializer modifier ensures these functions can only be invoked once during the contract's lifecycle.

Vulnerability Details

  1. Location: contracts/SystemConfig.sol, Lines 25-31

    • Code Snippet:

      function initialize(uint256 _basePlatformFeeRate, uint256 _baseReferralRate) external onlyOwner {
      basePlatformFeeRate = _basePlatformFeeRate;
      baseReferralRate = _baseReferralRate;
      }
  2. Location: contracts/TokenManager.sol, Lines 43-45

    • Code Snippet:

      function initialize(address _wrappedNativeToken) external onlyOwner {
      wrappedNativeToken = _wrappedNativeToken;
      }

The initialize functions can currently be called multiple times because there is no mechanism in place to prevent them from being re-invoked after the first successful call. This can lead to undesirable changes in state variables and potential security vulnerabilities.

Impact

  • Unpredictable State Changes: Repeated calls to initialize can overwrite critical initialization parameters, leading to unpredictable behavior.

  • Security Risks: The ability to reinitialize contracts can introduce significant security risks, particularly if rogue actors gain control over the call.

Tools Used

To mitigate this issue, the initialize functions should use the initializer modifier from the OpenZeppelin Initializable contract. This ensures that the initialize functions can only be executed once.

Recommendations

  1. Import and Extend OpenZeppelin's Initializable Contract: Import OpenZeppelin's Initializable contract and extend it in both SystemConfig.sol and TokenManager.sol.

  2. Use the initializer Modifier: Apply the initializer modifier to the initialize functions to ensure they can only be called once.

Example Implementation:

  1. SystemConfig.sol:

    // Import Initializable at the top
    import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
    contract SystemConfig is Initializable {
    uint256 public basePlatformFeeRate;
    uint256 public baseReferralRate;
    function initialize(uint256 _basePlatformFeeRate, uint256 _baseReferralRate) external initializer onlyOwner {
    basePlatformFeeRate = _basePlatformFeeRate;
    baseReferralRate = _baseReferralRate;
    }
    }
  2. TokenManager.sol:

    // Import Initializable at the top
    import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
    contract TokenManager is Initializable {
    address public wrappedNativeToken;
    function initialize(address _wrappedNativeToken) external initializer onlyOwner {
    wrappedNativeToken = _wrappedNativeToken;
    }
    }
Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[invalid] finding-Rescuable-initialize-owner

Invalid, can only be initialized by admin, which are trusted per contest READ.ME. So this would take a malicious admin to reinitialize contracts.

Support

FAQs

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