stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: medium
Invalid

Contract fail when the `handleOutgoingRESDL` and `handleIncomingRESDL` directly interact with `reSDLTokenBridge` without checking if it is set.

Summary

The handleOutgoingRESDL and handleIncomingRESDL functions in the SDLPoolCCIPController contract do not check if reSDLTokenBridge is set before interacting with it. If reSDLTokenBridge is not set, leaving these functions to fail.

Vulnerability Details

The functions handleOutgoingRESDL and handleIncomingRESDL directly interact with reSDLTokenBridge without checking if it is set, leaving the contract vulnerable to unexpected behavior when the bridge address is not initialized.

In the contract, the handleOutgoingRESDL and handleIncomingRESDL functions make direct calls to ccipSend and ccipReceive on reSDLTokenBridge without checking whether reSDLTokenBridge has been initialized. This lack of validation can lead to unexpected behavior and potential issues when attempting to interact with an uninitialized bridge address.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
abstract contract SDLPoolCCIPController is Ownable {
// ...
/**
* @notice Handles the outgoing transfer of an reSDL token to another chain
* @param _destinationChainSelector id of the destination chain
* @param _sender sender of the transfer
* @param _tokenId id of token
* @return the destination address
* @return the token being transferred
**/
function handleOutgoingRESDL(
uint64 _destinationChainSelector,
address _sender,
uint256 _tokenId
) external virtual returns (address, ISDLPool.RESDLToken memory) {
// ...
// Interact with reSDLTokenBridge without checking if it is set
IRESDLTokenBridge(reSDLTokenBridge).ccipSend(_destinationChainSelector, _evmToAnyMessage);
// ...
}
/**
* @notice Handles the incoming transfer of an reSDL token from another chain
* @param _sourceChainSelector id of the source chain
* @param _receiver receiver of the transfer
* @param _tokenId id of reSDL token
* @param _reSDLToken reSDL token
**/
function handleIncomingRESDL(
uint64 _sourceChainSelector,
address _receiver,
uint256 _tokenId,
ISDLPool.RESDLToken calldata _reSDLToken
) external virtual {
// ...
// Interact with reSDLTokenBridge without checking if it is set
IRESDLTokenBridge(reSDLTokenBridge).ccipReceive(_message);
// ...
}
// ...
}

Impact

If reSDLTokenBridge is not set, the functions relying on it will or may fail, leading to potential disruptions in the token transfer process or unintended behavior.

Tools Used

Manual Code Review

Recommendations

Ensure that reSDLTokenBridge is set before executing functions that rely on it. Add a check at the beginning of handleOutgoingRESDL and handleIncomingRESDL functions to prevent unexpected behavior.

Adding the require statement to check if reSDLTokenBridge is set, the contract can prevent unexpected behavior and potential failures due to uninitialized bridge addresses. This mitigation step ensures that the contract functions relying on the bridge can only proceed when the bridge address is properly initialized.

Implementation

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
abstract contract SDLPoolCCIPController is Ownable {
// ... (existing code)
/**
* @notice Handles the outgoing transfer of an reSDL token to another chain
* @param _destinationChainSelector id of the destination chain
* @param _sender sender of the transfer
* @param _tokenId id of token
* @return the destination address
* @return the token being transferred
**/
function handleOutgoingRESDL(
uint64 _destinationChainSelector,
address _sender,
uint256 _tokenId
) external virtual returns (address, ISDLPool.RESDLToken memory) {
// Ensure reSDLTokenBridge is set before proceeding
require(reSDLTokenBridge != address(0), "reSDLTokenBridge not set");
// ...
}
/**
* @notice Handles the incoming transfer of an reSDL token from another chain
* @param _sourceChainSelector id of the source chain
* @param _receiver receiver of the transfer
* @param _tokenId id of reSDL token
* @param _reSDLToken reSDL token
**/
function handleIncomingRESDL(
uint64 _sourceChainSelector,
address _receiver,
uint256 _tokenId,
ISDLPool.RESDLToken calldata _reSDLToken
) external virtual {
// Ensure reSDLTokenBridge is set before proceeding
require(reSDLTokenBridge != address(0), "reSDLTokenBridge not set");
// ...
}
// ...
}
Updates

Lead Judging Commences

0kage Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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