Liquid Staking

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

test/core/lst-rewards-splitter.test.ts

This code implements a test suite for a rewards-splitting system using smart contracts. Let's break it down into several sections, including general observations, potential improvements, and areas for security, performance, and readability considerations.


Summary of the Code:

The code tests a rewards-splitting mechanism via the LSTRewardsSplitter and LSTRewardsSplitterController contracts. These contracts:

  1. Accept deposits via token transfers.

  2. Split rewards among multiple recipients according to predefined ratios (in basis points).

  3. Include a mechanism to check and perform upkeep to ensure that reward distributions remain correct.


Key Areas Reviewed:

  1. Imports and Setup

  2. Deploy Fixture Logic

  3. Individual Test Cases Review

  4. Potential Issues and Suggestions for Improvement


Imports and Setup:

import { toEther, deploy, getAccounts, setupToken, fromEther } from '../utils/helpers'
import { LSTMock, LSTRewardsSplitterController } from '../../typechain-types'
import { assert, expect } from 'chai'
import { loadFixture } from '@nomicfoundation/hardhat-toolbox/network-helpers'
import { ethers } from 'hardhat'
  • Good Practice: Using loadFixture() ensures that deployments are reused between tests, making test runs more efficient.

  • Typechain Usage: The use of LSTMock and LSTRewardsSplitterController types helps catch type errors early.

  • Chai Assertions: The use of chai for assertion testing aligns with standard best practices for Hardhat tests.

  • Helper Functions: Utilities like toEther and fromEther improve code readability by abstracting the conversion of token units.


Deploy Fixture Logic:

The deployFixture function handles the deployment of the contracts and sets up initial conditions, including:

  1. Deploying the LSTMock token with a supply of 100 million tokens.

  2. Setting up the LSTRewardsSplitterController to manage reward splitting.

  3. Adding two splitters for different accounts with recipients and basis points.

Code Review:

  • Accounts Separation: Good use of multiple splitters with various recipients.

  • Structure: Separation between controller and individual splitters improves modularity.

  • Potential Edge Cases to Consider:

    • What happens if two splitters for the same account are added?

    • Should basis points exceed 10,000 (100%)?


Test Cases Review:

Below, I evaluate each test case for clarity, completeness, and possible improvements.

1. onTokenTransfer Functionality:

This test checks the onTokenTransfer function for handling both reverts and successful transfers.
Key assertions:

  • Revert on unauthorized transfers (InvalidToken, SenderNotAuthorized).

  • Valid transfers increase principal deposits and balance of splitters.

Suggestions:

  • Consider testing edge cases:

    • Transfer with 0 tokens.

    • Double calls to onTokenTransfer—does it handle duplicate transfers gracefully?


2. Withdraw Functionality:

This test ensures that withdrawals only occur under authorized conditions.

  • Unauthorized Access: Reverts if an unauthorized user attempts to withdraw.

  • Overdraw Protection: Reverts if withdrawal exceeds available balance.

Suggestions:

  • Include a partial withdrawal edge case where only part of the splitter’s deposit is withdrawn.

  • Consider burn scenarios—what happens to the state if tokens are accidentally burned from the splitter's balance?


3. checkUpkeep Functionality:

This test verifies the behavior of checkUpkeep, which indicates whether the upkeep process needs to be performed based on token balances.

  • Encoded Return Values: The test uses ethers.AbiCoder to encode results as expected by the upkeep logic.

Suggestions:

  • Add more complex scenarios:

    • Check if upkeep returns correct states when multiple splitters are inactive or require upkeep.

    • Explore what happens if token balances are altered mid-upkeep.


4. performUpkeep Functionality:

This test checks if upkeep is correctly performed by distributing rewards to recipients.

  • Successful Upkeep: Updates token balances for recipients according to basis points.

  • Reverts on invalid data: Ensures the upkeep process is robust.

Potential Improvement:

  • Add events assertion to confirm that upkeep emits expected logs.

  • Explore whether front-running attacks are possible by manipulating token transfers before calling upkeep.


5. splitRewards Functionality:

This test ensures rewards are correctly split between recipients based on basis points.

  • Insufficient Rewards Check: Reverts if there are not enough rewards to split.

  • Multiplier Basis Points: Tests with multiplier logic to verify that it scales correctly.

Potential Improvement:

  • Test with additional recipients to confirm the splitter handles arbitrary reward distributions.

  • Add edge case tests for multiplier values like 0% or 1000%.


6. Adding Splitters:

Tests whether new splitters can be added.

  • Reverts if splitter already exists for an account.

Suggestions:

  • Consider a test where the splitter is replaced for an existing account.

  • Verify event emissions when new splitters are added.


7. Removing Splitters:

This test verifies that splitters can be removed and ensures appropriate reverts if they do not exist.

Potential Improvements:

  • Include a re-add test to confirm that an account can be safely re-assigned a new splitter after removal.

  • Check if the state cleanup is sufficient when a splitter is removed.


Code Quality Review:

  1. Readability: The code is well-organized and readable, with clear variable names (splitter0, splitter1).

  2. Reusability: Using fixtures and helper functions increases code reuse.

  3. Event Handling: The code does not assert events. Adding event assertions would make the tests more thorough.

  4. Error Handling: The to.be.revertedWithCustomError checks are precise and ensure expected behavior.

  5. Security: Tests cover key scenarios like unauthorized access and over-withdrawal, but edge cases (e.g., front-running) could be explored further.


Suggestions for Improvement:

  1. Edge Case Coverage: Add tests for unusual scenarios such as 0-value transfers, double calls, and token burns.

  2. Event Assertions: Verify emitted events to ensure the contracts behave as expected.

  3. Gas Optimization Tests: Consider testing the gas costs of large transfers or complex upkeep operations.

  4. More Assertions for Clean State: When removing splitters, ensure all associated state variables are reset.


Conclusion:

This test suite provides comprehensive coverage for the LSTRewardsSplitter and LSTRewardsSplitterController contracts, ensuring core functionality works as intended. With a few additional edge cases, event checks, and front-running scenarios, the suite would become even more robust. The use of Hardhat, Chai, and Typechain is well-aligned with best practices for blockchain development.

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.