Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

contracts/core/ccip/base/CCIPReceiver.sol

Potential Vulnerabilities & Suggestions

  1. Reentrancy Risk in ccipReceive()

    • Observation: Although this contract deals with receiving messages (and potentially funds), there’s no nonReentrant modifier to protect against reentrancy attacks. This may not seem immediately risky, but if overridden functions perform external calls (e.g., calling other contracts), a reentrancy attack could happen.

    Mitigation:

    • If _ccipReceive() interacts with external systems or sends tokens, consider using the nonReentrant modifier from OpenZeppelin's ReentrancyGuard.

    • Alternatively, ensure _ccipReceive() does not invoke untrusted external contracts that could re-enter.

    Example:

    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    abstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165, Ownable, ReentrancyGuard {
    ...
    function ccipReceive(Client.Any2EVMMessage calldata _message)
    external override onlyRouter nonReentrant {
    _ccipReceive(_message);
    }
    }
  2. Centralization Risk in setRouter()

    • Observation: Only the contract owner (using Ownable) can update the router. This could introduce centralization risks if the owner address is compromised. Additionally, since setRouter() changes critical infrastructure (the message router), it could be exploited if called maliciously or accidentally with the wrong address.

    Mitigation:

    • Implement two-step governance for critical configuration updates like changing the router.

    • Alternatively, use multisig wallets or time locks for added security.

    Example:

    address private pendingRouter;
    event RouterUpdateProposed(address indexed newRouter);
    event RouterUpdated(address indexed oldRouter, address indexed newRouter);
    function proposeRouter(address _router) external onlyOwner {
    if (_router == address(0)) revert InvalidRouter(address(0));
    pendingRouter = _router;
    emit RouterUpdateProposed(_router);
    }
    function confirmRouter() external onlyOwner {
    emit RouterUpdated(i_router, pendingRouter);
    i_router = pendingRouter;
    pendingRouter = address(0);
    }
  3. Missing Event Emission on State-Changing Function

    • Observation: The setRouter() function changes a critical part of the contract, but no event is emitted. This could make it harder to track changes on-chain and audit the contract behavior over time.

    Mitigation:

    • Emit events whenever the router is changed.

    Example:

    event RouterChanged(address indexed oldRouter, address indexed newRouter);
    function setRouter(address _router) external onlyOwner {
    if (_router == address(0)) revert InvalidRouter(address(0));
    emit RouterChanged(i_router, _router);
    i_router = _router;
    }
  4. Unchecked Message Data in _ccipReceive()

    • Observation: The _ccipReceive() function is left to be implemented by inheriting contracts. If these implementations fail to validate message data properly (e.g., checking message sender, payload size, etc.), it could introduce unexpected vulnerabilities.

    Mitigation:

    • Consider adding a message validation framework or helper functions to make it easier for inheriting contracts to implement secure _ccipReceive() logic.

    • At a minimum, document the security expectations for this function.

  5. No Rate Limiting or Throttling Mechanism

    • Observation: There’s no mechanism to throttle the frequency of calls from the router. While the router is assumed to be trusted, a misconfigured or malicious router might spam calls to ccipReceive(), causing excessive gas usage and potentially DoS-ing the contract.

    Mitigation:

    • Add rate limiting by tracking timestamps of the last received message.

    • Use a circuit breaker to pause message processing if necessary.

  6. Open-Ended Access to Router Functions

    • Observation: The router can call ccipReceive() for any message. If the router behavior changes or is updated to a new address by mistake, unintended consequences could arise.

    Mitigation:

    • Add filters or access control to validate that only expected messages are processed by ccipReceive(). For instance, verifying that the message origin or payload meets certain criteria before processing.


Summary of Recommendations

  1. Add reentrancy protection to ccipReceive() if the _ccipReceive() logic involves external calls.

  2. Implement event emission in setRouter() to track state changes.

  3. Use a two-step router update mechanism to mitigate centralization risks.

  4. Document security expectations for inheriting contracts to correctly implement _ccipReceive().

  5. Consider rate-limiting or circuit-breakers to prevent spam from the router.

Updates

Lead Judging Commences

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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