Platform: Code4rena
Start Date: 07/08/2023
Pot Size: $36,500 USDC
Total HM: 11
Participants: 125
Period: 3 days
Judge: alcueca
Total Solo HM: 4
Id: 274
League: ETH
Rank: 59/125
Findings: 1
Award: $9.82
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: RED-LOTUS-REACH
Also found by: 0x3b, 0x4non, 0xCiphky, 0xDING99YA, 0xDetermination, 0xE1, 0xG0P1, 0xStalin, 0xWaitress, 0xbrett8571, 0xhacksmithh, 0xkazim, 0xmuxyz, 0xweb3boy, 14si2o_Flint, AlexCzm, Alhakista, Bube, Bughunter101, Deekshith99, Eeyore, Giorgio, HChang26, InAllHonesty, JP_Courses, KmanOfficial, MatricksDeCoder, Mike_Bello90, MrPotatoMagic, Naubit, QiuhaoLi, RHaO-sec, Raihan, Rolezn, SUPERMAN_I4G, Shubham, Silverskrrrt, Strausses, T1MOH, Topmark, Tripathi, Watermelon, _eperezok, aakansha, auditsea, audityourcontracts, ayden, carlos__alegre, castle_chain, cducrest, ch0bu, d23e, deadrxsezzz, deth, devival, erebus, fatherOfBlocks, halden, hassan-truscova, hpsb, hunter_w3b, imkapadia, immeas, jat, kaden, kaveyjoe, klau5, koxuan, kutugu, ladboy233, lanrebayode77, leasowillow, lsaudit, markus_ether, matrix_0wl, merlin, nemveer, ni8mare, nonseodion, oakcobalt, owadez, p_crypt0, pipidu83, piyushshukla, popular00, ppetrov, rjs, sandy, sl1, supervrijdag, tay054, thekmj, wahedtalash77, windhustler, zhaojie
9.8204 USDC - $9.82
LockAction.INCREASE_TIME
and LockAction.QUIT
are not used anywhere in the contract. They can be removed.
_checkpoint function consider splitting the whole function into checkpoint individual and checkpoint global functions. This makes the code more readable and since the global state is not used anywhere except for the view functions it makes sense to split it.
userOldPoint.slope and userNewPoint.slope calculations result in loss of precision. Consider multiplying the delegated amount with a multiplier(scaling before division) and using it as such through the codebase. And then dividing it back when needed to preserve accuracy. See Uniswap's approach.
Remove redundant code
Setting the userPointHistory[_addr][uEpoch + 1]
twice is redundant since there is no else
statement, the second assignment will always be executed.
lastPoint
can be written more concisely and save some gas as:
Point memory lastPoint; if (epoch > 0) { lastPoint = pointHistory[epoch]; } else { lastPoint = Point({bias: 0, slope: 0, ts: block.timestamp, blk: block.number}); }
Inconsistent styling through the codebase:
In some places +=
is used, in other places plain +
is used. Consider using the same style everywhere.
Remove unnecessary nonReentrant
function modifier from createLock, increaseAmount and delegate functions.
Redundant sum after checking if locked_.amount == 0
. Change to:
require(locked_.amount == 0, "Lock exists"); // Update lock and voting power (checkpoint) locked_.amount = int128(int256(_value));
VotedSlope
struct.struct VotedSlope { uint256 slope; uint240 end; // Max value is restricted by some time in the future so uint240 is enough. uint16 power; // Max value is 10000 so uint16 is enough. }
time_sum
assignment:time_sum = (block.timestamp / WEEK) * WEEK;
if (t > block.timestamp) { time_sum = t; break; }
if (t > block.timestamp) { time_weight[_gauge_addr] = t; break; }
msg.sender
.#0 - c4-judge
2023-08-22T13:59:17Z
alcueca marked the issue as grade-a