Liquid Staking

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

test/linkStaking/vault.test.ts

The provided Solidity test suite for a smart contract related to a vault has several aspects worth analyzing for vulnerabilities and potential improvements. Below, I'll highlight some of the vulnerabilities and suggest improvements with detailed explanations.

Vulnerabilities and Improvements

  1. Use of assert for critical checks:

    • Issue: The assert function is used for checks that should not fail under normal circumstances. If they do fail, it indicates a bug, and the transaction is reverted without providing useful feedback.

    • Improvement: Replace assert with expect for better error messages in the case of test failures. For example, expect(actual).to.equal(expected) provides clearer context on what went wrong.

    expect(fromEther(await token.balanceOf(adrs.stakingController))).to.equal(100);
  2. Magic Numbers:

    • Issue: The unbonding and claim periods are defined as magic numbers in the code, which may lead to confusion about their meanings.

    • Improvement: Define constants with descriptive names for better readability and maintainability.

    const UNBONDING_PERIOD = 28 * 86400; // 28 days
    const CLAIM_PERIOD = 7 * 86400; // 7 days
  3. Insufficient Validation of Input Values:

    • Issue: There is no validation for deposit amounts or any checks for non-zero deposits, which could lead to unexpected behavior.

    • Improvement: Implement checks to ensure that the deposit amount is greater than zero.

    require(amount > 0, "Deposit amount must be greater than zero");
  4. Lack of Access Control:

    • Issue: The tests assume that any account can call the deposit, unbond, and withdraw functions. This could lead to unauthorized access and misuse of the vault.

    • Improvement: Implement role-based access control to restrict who can perform certain actions, especially for functions that change state.

    modifier onlyOwner() {
    require(msg.sender == owner, "Not the owner");
    _;
    }
  5. Potential Reentrancy Issues:

    • Issue: The withdraw function could be susceptible to reentrancy attacks, especially if external calls are made (e.g., transferring tokens).

    • Improvement: Use the Checks-Effects-Interactions pattern and implement a reentrancy guard.

    bool private locked;
    modifier nonReentrant() {
    require(!locked, "Reentrancy detected");
    locked = true;
    _;
    locked = false;
    }
  6. Testing Edge Cases:

    • Issue: The test cases focus primarily on happy paths. There are no tests for edge cases, such as what happens when the user tries to withdraw without having deposited any funds.

    • Improvement: Add more test cases that cover various edge cases, including scenarios where users attempt to withdraw more than their balance, deposit negative amounts, etc.

    await expect(vault.withdraw(toEther(1000))).to.be.revertedWith("Insufficient balance");
  7. Gas Optimization:

    • Issue: The use of multiple state variable reads can be optimized. Each read from the blockchain is expensive in terms of gas.

    • Improvement: Store the values of frequently accessed state variables in local variables if used multiple times.

    const principalDeposits = await vault.getPrincipalDeposits();
    expect(fromEther(principalDeposits)).to.equal(70);
  8. Event Emissions:

    • Issue: There are no events emitted during critical actions like deposits, withdrawals, or unbonding, which can hinder off-chain tracking of contract activities.

    • Improvement: Emit events for state-changing operations to allow better tracking and monitoring of actions.

    event Deposited(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    function deposit(uint256 amount) external {
    // Logic
    emit Deposited(msg.sender, amount);
    }
  9. Lack of Descriptive Error Messages:

    • Issue: When using revertedWithCustomError, there are no clear messages about why the error occurred.

    • Improvement: Use require statements with clear error messages for better debugging.

    require(claimPeriodActive(), "Claim period is not active");
  10. Testing for Admin Functions:

    • Issue: If there are administrative functions (not visible in the test), they should also be tested.

    • Improvement: Add test cases for admin functions, ensuring only the admin can call them and that they work as intended.

Conclusion

Implementing the suggested improvements would enhance the code's robustness, maintainability, and security. Additionally, expanding the test suite to cover edge cases and potential vulnerabilities will ensure that the smart contract behaves as expected in various scenarios.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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