Liquid Staking

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

Lack of validation of inputs when initialising the `StakingPool` contract which can lead to many issues.

Relevant GitHub Links

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L65

Summary

Several inputs should be validated to avoid bad initialization of the StakingPool contract.

Vulnerability Details

When initialize the StakingPool contract, no check was made to validate the inputs provided by user. When initializing the StakingPool contract, no check was made to validate the inputs provided by the user. So the _token variable can be initialized with the value address(0) which is an invalid address; the strings _liquidTokenName and _liquidTokenSymbol can take the value empty string which will prevent the token from being identified; the variable _unusedDepositLimit which represents max number of tokens can be initialized to zerowhich is not logical and finally the array _fees can be initialized with a size equal to zero and null elements or an extremely large size, which causes unexpected behaviour:

function initialize(
address _token,
string memory _liquidTokenName,
string memory _liquidTokenSymbol,
Fee[] memory _fees,
uint256 _unusedDepositLimit
) public initializer {
// @audit Missing check of all privided inputs
__StakingRewardsPool_init(_token, _liquidTokenName, _liquidTokenSymbol);
for (uint256 i = 0; i < _fees.length; i++) {
fees.push(_fees[i]);
}
require(_totalFeesBasisPoints() <= 4000, "Total fees must be <= 40%");
unusedDepositLimit = _unusedDepositLimit;
}

Impact

This lack of verification can cause a number of problems:

- Loss of Functionality: If _token is set to address(0), any subsequent interactions with the token (such as transfers, approvals, or balance checks) will fail. This can effectively break the functionality of the contract since the staking and rewards logic would likely depend on a valid token contract.

- UI/UX Problems: If _liquidTokenName or _liquidTokenSymbol is an empty string, it could lead to Front-end interfaces and block explorers that rely on these values to display token information (name, symbol) might malfunction or show incorrect data. Users may not trust a token that doesn’t have a valid name or symbol.

- Incorrect Fee Calculations: If _fees contains invalid or malformed fee entries, the contract could miscalculate the total fees. This might result in users being charged incorrect fees, which could be higher or lower than intended.

- Excessive Gas Costs: If the _fees array is too large and there’s no validation, looping through it could cause the contract to hit the block gas limit during execution

Tools Used

Manual analysis.

Recommendations

function initialize(
address _token,
string memory _liquidTokenName,
string memory _liquidTokenSymbol,
Fee[] memory _fees,
uint256 _unusedDepositLimit
) public initializer {
+ require(_token != address(0), "Token address cannot be zero");
+ require(bytes(_liquidTokenName).length > 0, "Token name cannot be empty");
+ require(bytes(_liquidTokenSymbol).length > 0, "Token symbol cannot be empty");
+ require(_unusedDepositLimit > 0, "Deposit limit must be greater than zero");
+ require(_fees.length > 0, "Fees array cannot be empty");
+ require(_fees.length <= MAX_FEES, "Too many fee entries");
__StakingRewardsPool_init(_token, _liquidTokenName, _liquidTokenSymbol);
for (uint256 i = 0; i < _fees.length; i++) {
+ require(_fees[i]> 0, "fee amount cannot be null");
fees.push(_fees[i]);
}
require(_totalFeesBasisPoints() <= 4000, "Total fees must be <= 40%");
unusedDepositLimit = _unusedDepositLimit;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 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.