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
Rank: 25/62
Findings: 2
Award: $40.13
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0x3b, 0xAadi, 0xDING99YA, 0xTheC0der, 0xWaitress, 0xdice91, 100su, 3docSec, BRONZEDISC, BoRonGod, Eurovickk, GKBG, HChang26, IceBear, JP_Courses, MatricksDeCoder, Mike_Bello90, SovaSlava, Topmark, albahaca, cookedcookee, gzeon, hunter_w3b, kutugu, lukejohn, marqymarq10, matrix_0wl, orion, pep7siup, radev_sw, sces60107, taner2344, tpiliposian, wahedtalash77, xAriextz, zpan
4.9369 USDC - $4.94
Low Risk & Non Critical Findings 5
Low-Risk Findings List
Number | Issue Detail | Severity |
---|---|---|
L-01 | Multiplication on the Result of Division | Low |
L-02 | Not Enough Coverage of Functions and Contracts In the Docs | Low |
Total ~ 3 Issues
Non Critical Issues List
Number | Issue Details | Instances |
---|---|---|
NC-01 | dt as a Local variable name causes confusion | Non-Critical |
NC-02 | There should be a Min and Max weekFrom/weekTo Limit to be set. | Non-Critical |
NC-03 | Missing Events for certain Critical functions. | Non-Critical |
Multiplication
on the Result of Division
Dividing an integer by another integer will often result in a loss of precision. When the result is multiplied by another number, the loss of precision is magnified, often to material magnitudes. (X / Z) * Y should be re-written as (X * Y) / Z. Note This wasn't found in the bot report.
you can see instances of these issues
File: LiquidityMining.sol 51: uint32 currWeek = uint32((time / WEEK) * WEEK); 52: uint32 nextWeek = uint32(((time + WEEK) / WEEK) * WEEK); ............... 96: uint32 currWeek = uint32((time / WEEK) * WEEK); 97: uint32 nextWeek = uint32(((time + WEEK) / WEEK) * WEEK); ................ 208: uint32 currWeek = uint32((time / WEEK) * WEEK); 209: uint32 nextWeek = uint32(((time + WEEK) / WEEK) * WEEK); ................ 238: uint32 currWeek = uint32((time / WEEK) * WEEK); 239: uint32 nextWeek = uint32(((time + WEEK) / WEEK) * WEEK);
multiply before division. An instance of such mitigation would be
File: LiquidityMining.sol - 51: uint32 currWeek = uint32((time / WEEK) * WEEK); + 51: uint32 currWeek = uint32((WEEK / WEEK) * time);
Enough
Coverage of Functions
and Contracts
In the Docs
There isn't enough coverage on the user flows and functions in canto liquidity mining, which can lead to confusion and incorrect assumptions made when auditing the specific codebases.
the only place where there is anything said about the protocol is on the contest page on the code4rena site Link here and you can see that it doesn't do a good job of explaining how the contract and the functions logic are supposed to interact and be interacted with.
Create good documentation of the contracts and the functions stating and explaining how they are meant to be performed. .
dt
as a Local
variable name causes confusion
The local variable named dt
doesn't give a complete and accurate context as to what it is meant for in LiquidityMining.sol
and can cause confusion.
Local variable dt is declared in the:
accrueConcentratedGlobalTimeWeightedLiquidity()
accrueConcentratedPositionTimeWeightedLiquidity()
accrueAmbientGlobalTimeWeightedLiquidity()
accrueAmbientPositionTimeWeightedLiquidity()
Functions respectively, however, the variable name gives little context as to what is stored and nothing is said about it in the read.md
choose a better name for the variable that entails what it is meant for.
Min
and Max
weekFrom
and weekTo
limit to be setThere should be a minimum and maximum amount of weeks that can be set to have weekly rewards in order to help protect governance against any input mistake made.
you can see the instance of this issue.
File: LiquidityMiningPath.sol function setConcRewards(bytes32 poolIdx, uint32 weekFrom, uint32 weekTo, uint64 weeklyReward) public payable { // require(msg.sender == governance_, "Only callable by governance"); require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks"); while (weekFrom <= weekTo) { concRewardPerWeek_[poolIdx][weekFrom] = weeklyReward; weekFrom += uint32(WEEK); } } function setAmbRewards(bytes32 poolIdx, uint32 weekFrom, uint32 weekTo, uint64 weeklyReward) public payable { // require(msg.sender == governance_, "Only callable by governance"); require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks"); while (weekFrom <= weekTo) { ambRewardPerWeek_[poolIdx][weekFrom] = weeklyReward; weekFrom += uint32(WEEK); } }
add a check to ensure against setting weekly rewards for too many weeks ahead.
Missing
Events for certain Critical
functions.certain critical functions lack events which are very useful for contracts deployed on the EVM Note This is not the same as the issue in the bot reports.
you can see the Instances of critical functions that do not emit events. when claiming rewards or when accruals are being made.
claimConcentratedRewards()
claimAmbientRewards()
accrueAmbientGlobalTimeWeightedLiquidity()
accrueAmbientPositionTimeWeightedLiquidity()
accrueConcentratedPositionTimeWeightedLiquidity()
accrueConcentratedGlobalTimeWeightedLiquidity()
emit events for the given functions.
#0 - c4-pre-sort
2023-10-09T17:21:14Z
141345 marked the issue as sufficient quality report
#1 - c4-judge
2023-10-18T23:07:20Z
dmvt marked the issue as grade-b
🌟 Selected for report: 0xweb3boy
Also found by: 0xdice91, Banditx0x, JP_Courses, ZanyBonzy, albahaca, cookedcookee, hunter_w3b, invitedtea, radev_sw, sandy
35.1935 USDC - $35.19
Canto Liquidity Mining is a novel feature introduced to the canto chain, mainly for incentivizing liquidity on Ambient Finance, it makes use of an Incentive mechanism and a nice liquidity mining scheme that incentivizes LPs to provide liquidity to the aimed protocol.
During This audit, I focused on getting a full understanding of the mechanisms in the protocol, the functions to be called by a user and the ones to be called by the governance, I focused on invariants that could be broken and security guidelines followed by the protocol.
The Overall Architecture of the protocol is well designed and user flows are properly implemented as the interactions between the contracts and the mechanisms implemented all align with Canto's aimed goals.
The Codebase was really short and all the more easier to understand, I would mark is as Good all though there wasns't a full coverage of test on the codebase and Natspecs for certain functions were missing.
Codebase Quality Categories | Comments |
---|---|
Unit Testing | The Codebase was actually well-teste, but the coverage being 75% wasn't enough, and Hardhat was use, I strongly recommend the use of Foundry |
Code Comments | Incomplete Comments and Natspecs on critical functions that were heuristic but due to the SLOC of the codebase I can see why the devs didn't put much time into that, but for a good and well audited codebase I recommend more and detailed comments and Natspecs be added to the 2 contracts |
Documentation | The codebase was well described in the contest page of the contest, however I recommend that a detailed documentation of the codebase should be made and more should be done explaining how the functions are supposed to work |
Organization | The Codebase was actually so easy and simple removing complexities that made it look mature and well organized with clear distinctions between the contracts, and how they interact with each other to help aid their functionalities |
Due to Canto's Governance I think the issue of centralization was well mitigated in the codebase
The audit cover a total of 2 contracts.
Mechanism where to set the rewards which is to be done by the Governance and claiming of rewards. i believe the mechanisms in the codebase were properly implemented and user flows go as planned.
The Systematic risk have already been admitted by the developers in the Ambient docs.
12 hours
#0 - c4-pre-sort
2023-10-09T17:24:20Z
141345 marked the issue as sufficient quality report
#1 - c4-judge
2023-10-19T16:33:56Z
dmvt marked the issue as grade-b