Clearpool

Clearpool: CPOOL to CLEAR Token Swap

Cantina Security Report

Organization

@clearpool

Engagement Type

Cantina Reviews

Period

-


Findings

Low Risk

1 findings

1 fixed

0 acknowledged

Informational

2 findings

1 fixed

1 acknowledged


Low Risk1 finding

  1. owner and layerzero's delegate are not updated atomically

    Severity

    Severity: Low

    Submitted by

    Om Parikh


    Description

    the owner and lz's delegate is same address _admin. however transferOwnership and/or renounceOwnership doesn't change it when updating owner.

    In several cases, old delegate can change config before acceptOwnership transaction and may cause side effects, such as: `

    • clear.transferOwnership(...) -> endpoint.setConfig(CLEAR, ...) -> clear.acceptOwnership(...) -> clear.setDelegate(newOwner);

    same is also true for renounceOwnership.

    Recommendation

    • override acceptOwnership to handle it atomically
    +    /// @notice Accepts ownership and atomically transfers the LayerZero+    ///         Endpoint delegate to the new owner.+    function acceptOwnership() public override {+        super.acceptOwnership();+        setDelegate(owner());+    }
    • since renounceOwnership creates partial ownerless system, it can be mitigated by not allowing to renounce.
    +    error OwnershipRenouncementDisabled();++    /// @notice Ownership renouncement is disabled because CLEAR requires+    ///         an owner for minting, LayerZero configuration, and swapper control.+    function renounceOwnership() public pure override {+        revert OwnershipRenouncementDisabled();+    }

Informational2 findings

  1. Code Style

    State

    Acknowledged

    Severity

    Severity: Informational

    Submitted by

    Red Swan


    Description

    Across CLEAR.sol and CPoolToClearSwapper.sol, several stylistic inconsistencies and missing NatSpec documentation items were identified:

    1. Non-Standard Immutable Naming (UPPER_SNAKE_CASE):

      • According to the Solidity Style Guide, immutable variables and constants should follow UPPER_SNAKE_CASE.
      • In CLEAR.sol, swapper is declared in camelCase.
      • In CPoolToClearSwapper.sol, oldCpool and clear are declared in camelCase.
    2. Function Ordering Violations in CLEAR.sol:

      • The Solidity style convention recommends grouping functions by visibility: external, public, internal, and private, with view/pure functions placed at the end of each section.
      • In CLEAR.sol, the internal hook _update precedes the public functions nonces and transferOwnership.
    3. Incomplete NatSpec Documentation:

      • Constructors: Missing @param tags in CLEAR.sol (_lzEndpoint, _admin, _oldCpool) and CPoolToClearSwapper.sol (_oldCpool).
      • Internal / Helper Functions: _checkClearOwner in CPoolToClearSwapper.sol lacks NatSpec documentation entirely.
      • Overrides: Overridden methods in CLEAR.sol (_update, nonces, transferOwnership, _transferOwnership) omit @inheritdoc or explanatory @dev annotations detailing custom behavior (e.g., the recipient exclusion guard in _update).
    4. Shadowing and Header Formatting Nits:

      • Variable Shadowing: In CLEAR.sol, the owner parameter of nonces(address owner) shadows Ownable.owner().
      • Fragmented @dev Tags: The file header of CLEAR.sol contains six separate @dev tags rather than a consolidated documentation block or @custom: tags.
      • Wordy NatSpec: Functions repeatedly prefix @notice descriptions with "This function allows...", which can be streamlined.

    Recommendation

    If code style is important, consider making the changes described above.

  2. Upgrade to newer solc version

    Severity

    Severity: Informational

    Submitted by

    Om Parikh


    Description

    Consider upgrading from current 0.8.28 solc version to current or close to current version as there are multiple known bugs in older version.

    Recommendation

    - pragma solidity 0.8.28;+ pragma solidity 0.8.37;