Canto Liquidity Mining Protocol - 100su's results

Execution layer for original work.

General Information

Platform: Code4rena

Start Date: 03/10/2023

Pot Size: $24,500 USDC

Total HM: 6

Participants: 62

Period: 3 days

Judge: LSDan

Total Solo HM: 3

Id: 288

League: ETH

Canto

Findings Distribution

Researcher Performance

Rank: 59/62

Findings: 1

Award: $4.94

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

4.9369 USDC - $4.94

Labels

bug
grade-b
QA (Quality Assurance)
sufficient quality report
edited-by-warden
Q-26

External Links

Check invalid weeks

In LiquidityMiningPath.sol,

  • L33 and L42, it is suggested that the following check
require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks");

is updated to

require(weekFrom % WEEK == 0 && weekTo % WEEK == 0 && weekFrom <= weekTo, "Invalid weeks");

in order to let users know that those are invalid weeks.

Avoid division-by-zero

In LiquidityMining.sol,

  • L175, division-by-zero can happen when overallInRangeLiquidity is zero.
  • The following check point can be added: if (overallInRangeLiquidity == 0) continue;
  • Then, we can modify L169 to L173 as
uint256 overallInRangeLiquidity = timeWeightedWeeklyGlobalConcLiquidity_[poolIdx][week];
if (overallInRangeLiquidity == 0) {
    continue;
}
uint256 inRangeLiquidityOfPosition;
for (int24 j = lowerTick + 10; j <= upperTick - 10; ++j) {
    inRangeLiquidityOfPosition += timeWeightedWeeklyPositionInRangeConcLiquidity_[poolIdx][posKey][week][j];
}
  • In the above, overallInRangeLiquidity can be checked first before calculation of inRangeLiquidityOfPosition.

In main branch, it seems to be resolved, but a line can be also fixed as above or the following.

uint256 overallInRangeLiquidity = timeWeightedWeeklyGlobalConcLiquidity_[poolIdx][week]; if (overallInRangeLiquidity > 0) { uint256 inRangeLiquidityOfPosition; for (int24 j = lowerTick + 10; j <= upperTick - 10; ++j) { inRangeLiquidityOfPosition += timeWeightedWeeklyPositionInRangeConcLiquidity_[poolIdx][posKey][week][j]; } // Percentage of this weeks overall in range liquidity that was provided by the user times the overall weekly rewards rewardsToSend += inRangeLiquidityOfPosition * concRewardPerWeek_[poolIdx][week] / overallInRangeLiquidity; concLiquidityRewardsClaimed_[poolIdx][posKey][week] = true; }
  • In above, concLiquidityRewardsClaimed_[poolIdx][posKey][week] = true; is moved into if-loop in order to save gas.

Check non-zero liquidity

In LiquidityMining.sol,

  • L48, if liquidity == 0, there is no meaning the codes below the line. So, the following revision is recommended to change from
// Only set time on first call
if (lastAccrued != 0) {
    uint256 liquidity = curve.concLiq_;

to

// Only set time on first call
uint256 liquidity = curve.concLiq_;
if (lastAccrued != 0 && liquidity != 0) {
  • The same revision can be done in L87, L191, and L221.

Suggestion: Generalization of Rewards Tokens

Currently, the liquidity mining mechanism considers the rewards only with native canto. Canto already deployed wcanto ERC20 contracts and it has been used. In this regards, if the rewards of the liquidity mining mechanism is distributed by wcanto (ERC20), the mechanism can be easily generalized with other rewards of other ERC20 tokens in the future. Of course, for this generalization, some more functions need to be developed, e.g., registration of rewards with amount and contracts, support of multiple tokens for rewards, and so on.

#0 - c4-pre-sort

2023-10-09T17:22:45Z

141345 marked the issue as sufficient quality report

#1 - c4-judge

2023-10-18T22:45:31Z

dmvt marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter