Platform: Code4rena
Start Date: 27/10/2022
Pot Size: $33,500 USDC
Total HM: 8
Participants: 96
Period: 3 days
Judge: kirk-baird
Total Solo HM: 1
Id: 176
League: ETH
Rank: 48/96
Findings: 2
Award: $31.16
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: robee
Also found by: 0x007, 0x1f8b, 0x52, 0xDjango, 0xNazgul, 0xSmartContract, 8olidity, Awesome, B2, Bnke0x0, Chom, Diana, Dravee, JTJabba, Jeiwan, Josiah, Lambda, Mathieu, Picodes, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Ruhum, Sm4rty, Tricko, Trust, Waze, __141345__, a12jmx, adriro, ajtra, brgltd, c3phas, carlitox477, cccz, ch0bu, chaduke, chrisdior4, corerouter, cryptonue, csanuragjain, ctf_sec, cylzxje, delfin454000, dic0de, djxploit, horsefacts, imare, jayphbee, jwood, ktg, ladboy233, leosathya, lukris02, minhtrng, neko_nyaa, oyc_109, pashov, peritoflores, rbserver, rvierdiiev, shark, tnevler, yixxas
19.6449 USDC - $19.64
Title | Instances | |
---|---|---|
[L-01] | Typo/grammar mistakes | 14 |
[L-02] | Redundant return value | 1 |
[L-03] | Incomplete documentation | 13 |
[L-04] | Wrong usage of NatSpec format comments | 24 |
[L-05] | Missing zero address checks in constructor | 1 |
[N-01] | A constant should be used instead of a magic value | 1 |
[N-02] | Documentation on obvious functions may be redundant | 2 |
[N-03] | Use native time unit rather than defining constants | 1 |
[N-04] | Events can use indexed fields for easier querying | 1 |
[N-05] | The nonReentrant modifier should occur before all other modifiers | 7 |
protocalFeeRatio
should be protocolFeeRatio
InequalArraySizes
should be UnequalArraySizes
canceled
should be cancelled
taget of votes
should be target of votes
balacne
should be balance
Address tof the EC2O token
should be Address of the ERC2O token
(two mistakes: tof
and EC20
)https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L295 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L296 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L365 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L366 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L413
ot be pulled
should be to be pulled
https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L453 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L485
fo
should be of
reards
should be rewards
Platform
should not be uppercase when referring to self.
Function recoverERC20()
uses OpenZeppelin's safeTransfer()
, which is guaranteed to revert if the transfer fails. Hence, this function will either revert, or return true, making the return value redundant.
All of the events (13 in total) have incomplete documentation
In general, @notice
is meant to be a brief description of the function (i.e. what it's supposed to do, in one line), while @dev
is meant to provide devs with clarifications, or some notes on function behavior that one might not expect, or anything noteworthy in general.
The report below points out all found instances of tags misusage, along with recommended mitigation. There are four distinct issues in total listed:
@dev
-tagged line and the @notice
-tagged line are completely the same. Recommendation: remove the @dev
line.https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L288-L289 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L149-L150 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L158-L159 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L168-L169 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L189-L190 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L200-L201 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L536-L537 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L555-L556 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L565-L566 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L581-L582 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L595-L596 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L608-L609 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L621-L622 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L648-L649
@dev
-tagged line is just the @notice
line with extra details. Recommendation: Remove the current @notice
and replace @dev
with @notice
.https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L361-L362 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L407-L408 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L451-L452 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L483-L484
@dev
tag is used where @notice
should be. Recommendation: Replace @dev
with @notice
.https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L126 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L177 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L216 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L521
@notice
tag, or be its own @dev
tag. Recommendation: Either combine them with the preceeding @notice
tag, or tag it with @dev
.https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L55 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L66
Specifically, updateChest()
has a zero-address sanity check for chestAddress
, however there is no such check in the constructor.
This is also in line with how the contract defines constants for e.g. MAX_PCT
.
I think pause()
functions are completely clear and do not need documentation. Furthermore they are admin functions.
However this is an opinion-based non-risk finding, the decision should be ultimately up to the sponsors' preference.
https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L634 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L641
The line below can be changed to 7 weeks
This is also for consistency with how minDelegationTime
is defined, as shown below
indexed
fields for easier queryingGenerally it is a good idea to place indexed
fields for database-like data, where it is expected that such data will be queried.
Specifically, the event NewPledge
would be extremely helpful to contain indexed
fields for creator
and receiver
, where such values can be expected to be queried by user when needed (e.g. when a receiver wants to query who has pledged them or otherwise).
nonReentrant
modifier should occur before all other modifiersThis is a best-practice to protect against reentrancy in other modifiers. Applies to all functions with this modifier.
https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L195 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L206 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L307 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L373 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L419 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L456 https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L488
#0 - c4-judge
2022-11-11T23:40:58Z
kirk-baird marked the issue as grade-b
🌟 Selected for report: c3phas
Also found by: 0x1f8b, 0xNazgul, 0xRoxas, 0xSmartContract, 0xbepresent, Amithuddar, Awesome, B2, Bnke0x0, Dravee, KoKo, Mathieu, Picodes, RaymondFam, RedOneN, ReyAdmirado, RockingMiles, Ruhum, SadBase, SooYa, Waze, __141345__, adriro, ajtra, ballx, carlitox477, ch0bu, cylzxje, djxploit, durianSausage, emrekocak, erictee, gogo, halden, horsefacts, imare, indijanc, karanctf, leosathya, lukris02, neko_nyaa, oyc_109, peiw, sakman, shark, skyle, tnevler
11.5153 USDC - $11.52
Overall, the codebase was quite well-written, with clear intentions for gas optimizations found in e.g. unchecked for loops. The C4udit tool also points out a lot of impactful gas optimizations. This report points out some other possible gas savings for the contract.
Title | Instances | Gas saved | |
---|---|---|---|
[G-01] | Several variables can be made constant and immutable | 3 | 17090 deployment, 2000 per operations |
[G-02] | unchecked applicable for arithmetic operations that cannot overflow/underflow | 2 | approx. 150 per operations |
[G-03] | protocalFeeRatio can be better packed | 1 | -18698 deployment, 2000 per operations |
constant
and immutable
The following value can be made constant
:
uint256 public minDelegationTime = 1 weeks;
The following two values can be made immutable
:
IVotingEscrow public votingEscrow; IBoostV2 public delegationBoost;
Applying all the aforementioned reduces deployment gas from 2695825
down to 2678735
(for 17090
gas in total).
Furthermore, since constants and immutables are stored in the contract bytecode rather than storage, this also saves around 2000
storage-reading gas for every operations that require these values.
unchecked
applicable for arithmetic operations that cannot overflow/underflowTwo instances are found:
unchecked {return (timestamp / WEEK) * WEEK;}
unchecked{pledgeAvailableRewardAmounts[pledgeId] -= rewardAmount;}
Saves approx. 150 operational gas on re-running tests with these modifications applied, also saves minor deployment gas.
protocalFeeRatio
can be better packed(For the sake of reporting, we ignore the typo)
The storage variable protocalFeeRatio
can be changed to type uint96
, since the fee ratio cannot exceed 500. Then the storage slot looks like follow:
// this is one slot uint96 public protocalFeeRatio = 250; address public chestAddress;
updatePlatformFee()
can be easily modified accordingly.
Re-running tests with this optimization increases deployment gas by 18698
(up to 2714523
). However, all pledging operations (except for closePledge()
) saves approx. 2000
gas, for having reduced one storage slot to look at. Hence this optimization is impactful in the long run.
#0 - c4-judge
2022-11-12T00:35:10Z
kirk-baird marked the issue as grade-b