Liquid Staking

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

contracts/core/test/StrategyMock.sol

This Solidity code defines a mock strategy contract, StrategyMock, for testing purposes. Here are some potential vulnerabilities and areas for improvement:

1. Reentrancy Vulnerability

  • Description: The withdraw function calls safeTransfer, which transfers tokens to msg.sender. If the recipient is a contract and it has a fallback function that calls back into the withdraw function, it could potentially drain funds.

  • Recommendation: Consider using a reentrancy guard, such as nonReentrant from OpenZeppelin, to prevent reentrancy attacks.

import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
contract StrategyMock is Strategy, ReentrancyGuardUpgradeable {
...
function withdraw(uint256 _amount, bytes calldata) external onlyStakingPool nonReentrant {
...
}
}

2. Lack of Input Validation

  • Description: The deposit and withdraw functions do not validate that _amount is greater than zero. This can lead to unexpected behaviors, like transferring zero tokens.

  • Recommendation: Add checks to ensure that _amount is greater than zero.

function deposit(uint256 _amount, bytes calldata) external onlyStakingPool {
require(_amount > 0, "Amount must be greater than zero");
...
}
function withdraw(uint256 _amount, bytes calldata) external onlyStakingPool {
require(_amount > 0, "Amount must be greater than zero");
...
}

3. Arithmetic Issues

  • Description: In the updateDeposits function, there are arithmetic operations that may result in underflows or overflows, especially when calculating totalDeposits. Although Solidity 0.8.x includes built-in overflow checks, it's good practice to ensure that calculations make sense.

  • Recommendation: Use SafeMath or ensure that conditions are checked before performing operations.

function updateDeposits(
bytes calldata
)
external
onlyStakingPool
returns (int256 depositChange, address[] memory receivers, uint256[] memory amounts)
{
depositChange = getDepositChange();
require(depositChange >= 0 || totalDeposits >= uint256(-depositChange), "Invalid totalDeposits after update");
...
}

4. Fees Without Validation

  • Description: The setFeeBasisPoints function allows anyone to set the fee basis points, which could be manipulated to set a very high fee.

  • Recommendation: Restrict access to this function to only the owner or a specific role.

function setFeeBasisPoints(uint256 _feeBasisPoints) external onlyOwner {
require(_feeBasisPoints <= 10000, "Fee basis points too high"); // Maximum fee of 100%
feeBasisPoints = _feeBasisPoints;
}

5. Potentially Unsafe Transfer in simulateSlash

  • Description: The simulateSlash function transfers tokens to msg.sender without checks, which could result in unexpected behavior or loss of funds if not handled correctly.

  • Recommendation: Ensure the contract has enough balance before attempting a transfer and clarify the intent of this function.

function simulateSlash(uint256 _amount) external {
require(token.balanceOf(address(this)) >= _amount, "Insufficient balance for slash");
token.safeTransfer(msg.sender, _amount);
}

6. No Access Control on Critical Functions

  • Description: The createRewardsPool function can be called by anyone, which could lead to unauthorized pools being created.

  • Recommendation: Implement access control to restrict who can create reward pools.

function createRewardsPool(address _token) public onlyOwner {
...
}

7. Potential Unused Parameters

  • Description: The bytes calldata parameters in the deposit, withdraw, and updateDeposits functions are not utilized. If they are not needed, consider removing them.

  • Recommendation: Remove unused parameters if they don’t serve a purpose.

Conclusion

While the code provides a basic structure for a mock strategy, addressing these vulnerabilities and incorporating best practices will significantly enhance the security and robustness of the contract. Always consider thorough testing and auditing before deploying any contracts to production environments.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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