stake.link

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

Lack of Input Validation for Constructor Parameters

Summary:

The constructor of the RewardsInitiator contract accepts two addresses as parameters: _stakingPool and _sdlPoolCCIPController. These addresses are critical as they link the contract to external contracts that manage staking pools and cross-chain reward distribution. However, there is no validation to ensure that the provided addresses are non-zero and point to valid contract addresses. If either address is incorrect, the contract may be deployed in a broken state, leading to potential loss of funds or failure of the intended functionality.

Code Snippet:

constructor(address _stakingPool, address _sdlPoolCCIPController) {
stakingPool = IStakingPool(_stakingPool);
sdlPoolCCIPController = ISDLPoolCCIPControllerPrimary(_sdlPoolCCIPController);
}

Impact:

If the constructor is called with an invalid _stakingPool or _sdlPoolCCIPController address (e.g., an EOA, a non-contract address, or a zero address), the contract will not function as intended. This could lead to several issues:

Inability to update rewards or distribute them correctly.
Loss of funds if the contract interacts with an incorrect address.
Increased attack surface if the address provided is malicious.

Steps To Reproduce:

Deploy the RewardsInitiator contract with an invalid _stakingPool or _sdlPoolCCIPController address (e.g., 0x0, EOA, or non-contract address).

Recommendation:

Implement input validation in the constructor to ensure that both _stakingPool and _sdlPoolCCIPController are non-zero addresses and point to deployed contracts. This can be achieved by using the Address utility library from OpenZeppelin, which provides functions like isContract to check if an address is a deployed contract.

Suggested Fix:

import "@openzeppelin/contracts/utils/Address.sol";

constructor(address _stakingPool, address _sdlPoolCCIPController) {
require(Address.isContract(_stakingPool), "_stakingPool must be a contract");
require(Address.isContract(_sdlPoolCCIPController), "_sdlPoolCCIPController must be a contract");

stakingPool = IStakingPool(_stakingPool);
sdlPoolCCIPController = ISDLPoolCCIPControllerPrimary(_sdlPoolCCIPController);

}

Tools Used:

Manual code review.

References:

OpenZeppelin Address Library: https://docs.openzeppelin.com/contracts/4.x/api/utils#Address

Notes:

Ensure that the contracts at _stakingPool and _sdlPoolCCIPController addresses implement the expected interfaces (IStakingPool and ISDLPoolCCIPControllerPrimary, respectively) before deployment.
Consider adding unit tests to cover the scenario where the constructor is called with invalid addresses.

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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