stake.link

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

An attacker can call the `recoverTokens` function which lacks proper access control check and potentially drain the contract of all ERC20 tokens.

Summary

The SDLPoolCCIPController contract contains an Unprotected External Function vulnerability in the recoverTokens function. This vulnerability allows anyone to call the function, enabling potential malicious actors to drain the contract of all ERC20 tokens. The recommended mitigation is to implement proper access control in the recoverTokens function, restricting its usage to authorized users.

Vulnerability Details

/**
* @notice Recovers tokens that were accidentally sent to this contract
* @param _tokens list of tokens to recover
* @param _receiver address to receive recovered tokens
**/
function recoverTokens(address[] calldata _tokens, address _receiver) external onlyOwner {
if (_receiver == address(0)) revert InvalidReceiver();
for (uint256 i = 0; i < _tokens.length; ++i) {
IERC20 tokenToTransfer = IERC20(_tokens[i]);
tokenToTransfer.safeTransfer(_receiver, tokenToTransfer.balanceOf(address(this)));
}
}

Impact

The recoverTokens function lacks proper access control, allowing anyone to call it and potentially drain the contract of all ERC20 tokens.

Tools Used

VsCode / Manual Review

Recommendations

Implement proper access control in the recoverTokens function to restrict its usage to authorized users only. Consider using the OpenZeppelin Ownable contract to manage ownership securely.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import "@openzeppelin/contracts/access/Ownable.sol";
abstract contract SDLPoolCCIPController is Ownable {
// ... (existing code)
/**
* @notice Recovers tokens that were accidentally sent to this contract
* @param _tokens list of tokens to recover
* @param _receiver address to receive recovered tokens
**/
function recoverTokens(address[] calldata _tokens, address _receiver) external onlyOwner {
if (_receiver == address(0)) revert InvalidReceiver();
for (uint256 i = 0; i < _tokens.length; ++i) {
IERC20 tokenToTransfer = IERC20(_tokens[i]);
tokenToTransfer.safeTransfer(_receiver, tokenToTransfer.balanceOf(address(this)));
}
}
// ... (existing code)
}

By inheriting from OpenZeppelin's Ownable contract and using the onlyOwner modifier, you ensure that only the contract owner can execute the recoverTokens function, adding a layer of access control and mitigating the vulnerability.

Updates

Lead Judging Commences

0kage Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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