Assessment reports>Staking>Discussion>Testing coverage assessment

Testing coverage assessment

In our assessment of GammaSwap's test suite, we observed that while it provides adequate coverage for many aspects of the codebase, there are specific branches and code paths that appear to be under-tested or not covered at all.

Invariant Testing:

Invariant conditions are conditions that should always hold true, regardless of the state of the system. For example, the total supply of a token should always be equal to the sum of all token balances.

Invariant testing is a useful testing procedure to ensure that the system is functioning as expected. We recommend extending invariant tests for the StakingRouter, so that the invariant conditions of the system are always verified. Examples of invariant conditions here could be:

// fail if there's any difference between the ratio of what two users staked (assume they are random values) and the rewards they are entitled to

uint256 lpBalanceBeforeUser1 = GammaPoolERC20(pool).balanceOf(user1);
uint256 lpBalanceBeforeUser2 = GammaPoolERC20(pool).balanceOf(user2);

// deposit random amounts for user1 and user2
vm.prank(user1);
stakingRouter.stakeLp(address(pool), lpAmount1);
vm.prank(user2);
stakingRouter.stakeLp(address(pool), lpAmount2);

uint256 lpBalanceAfterUser1 = GammaPoolERC20(pool).balanceOf(user1);
uint256 lpBalanceAfterUser2 = GammaPoolERC20(pool).balanceOf(user2);

vm.warp(block.timestamp + 1 days);

uint256 claimableRewardsUser1 = IRewardTracker(poolRewardTracker).claimable(user1);
uint256 claimableRewardsUser2 = IRewardTracker(poolRewardTracker).claimable(user2);

// ensure that the ratio of rewards is the same as the ratio of deposits

assertEq(
    (lpBalanceBeforeUser1 - lpBalanceAfterUser1) / claimableRewardsUser1,
    (lpBalanceBeforeUser2 - lpBalanceAfterUser2) / claimableRewardsUser2
);

// ...

Integration Testing:

While unit tests are present and comprehensive, there is room for improvement in integration testing.

The interaction between various smart contract components and their combined behavior under various scenarios should be thoroughly examined. Integration tests can help identify unforeseen issues arising from the interplay of different modules.

We recommend specifically improving testing around the StakingAdmin to ensure that all setters and initializers are called in the correct order. This is especially important for the StakingAdmin as it is the "deployer" of most other contracts in the system.

In our assessment, we found that enhancing test coverage for these specific areas would further bolster the reliability and resilience of the project. We recommend expanding the test suite to include test cases addressing the above points.

Zellic © 2024Back to top ↑