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: 23/96
Findings: 2
Award: $192.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
180.6401 USDC - $180.64
Within the "_pledge" function. There is no check that the "endTimeStamp" variable provided by the user is not lower than block.timestamp (i.e. that the provided date is not in the past). If this is the case, the function will revert on line 237 due to the overflow protection of the EVM since the solidity version used is 0.8.X.
The Openzeppelin’s Ownable contract implements renounceOwnership. This can represent a certain risk if the ownership is renounced for any other reason than by design. Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
WardenPledge.sol#L18
Admin calls Ownable.transferOwnership function to transfers the ownership to the new address directly. As such, there is a risk that the ownership is transferred to an invalid address, thus causing the contract to be without a owner.
WardenPledge.sol#L18
Use (e.g. 1e6) rather than decimal literals (e.g. 1000000), for better code readability
WardenPledge.sol#L23
WardenPledge.sol#L24
Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.
WardenPledge.sol#L229 WardenPledge.sol#L237 WardenPledge.sol#L319 WardenPledge.sol#L380 WardenPledge.sol#L426 WardenPledge.sol#L430 WardenPledge.sol#L463 WardenPledge.sol#L496
WardenPledge.sol#L626
Different bug corrections have been released after version 0.8.10. For instance, version 0.8.13 Correctly encode literals used in abi.encodeCall in place of fixed bytes arguments. Version 0.8.15 avoids writing dirty bytes to storage when copying bytes arrays.
#0 - c4-judge
2022-11-12T00:17:54Z
kirk-baird marked the issue as grade-a
🌟 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
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
WardenPledge.sol#L41
Strict inequalities (> or <) are more expensive than non-strict ones (>= or <=). This is due to some supplementary checks (ISZERO, 3 gas). As a result, it is possible potentialy save 3 gas for various lines in the contract (at least where it has almost no impact on the logic) :
WardenPledge.sol#L234 WardenPledge.sol#L245 WardenPledge.sol#L386 WardenPledge.sol#L463
if a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address…). Explicitly initializing it with its default value is an anti-pattern and wastes gas.
File : WardenPledge.sol
WardenPledge.sol#L547 WardenPledge.sol#L613
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
File : WardenPledge.sol
WardenPledge.sol#L41
If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost.
WardenPledge.sol#L541 WardenPledge.sol#L560 WardenPledge.sol#L570 WardenPledge.sol#L585 WardenPledge.sol#L599 WardenPledge.sol#L612 WardenPledge.sol#L625 WardenPledge.sol#L636 WardenPledge.sol#L653
Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot. Finally, if both fields are accessed in the same function, can save ~42 gas per access due to not having to recalculate the key’s keccak256 hash (Gkeccak256 - 30 gas) and that calculation’s associated stack operations.
The pledgeOwner and the pledgeAvailableRewardAmounts mappings can be combined to a single struct.
WardenPledge.sol#L50 WardenPledge.sol#L56
Solidity versions higher than 0.8.10 have some benefits from a gas optimisation point of view. Version 0.8.12 will remove the mstore and sstore operations if the slot already contains the same value. version 0.8.15 improved Inlining heuristics in the optimizer and resulted in lower bytecode size and consequently lower deployment costs. Version 0.8.16 has a more efficient code for checked addition and subtraction.
Within the same function, calling multiple time the same "state variable" is inefficient from a gas point of view. SLOADs cost 100gas compared to MLOADs/MSTOREs ("gas). As a result, it is more efficient to first store with an sload the state variable into memory and then call this new variable.
minAmountRewardToken (2SLOADS) WardenPledge.sol#L312 WardenPledge.sol#L313
There are 4 instances of it :
WardenPledge.sol#L268 WardenPledge.sol#L340 WardenPledge.sol#L401 WardenPledge.sol#L445
The variable minDelegationTime is called within the contract but is never updated.
WardenPledge.sol#L79
Doing so will improve deployment cost and code readability.
The following set of conditions performed in three different functions (closePledge, retrievePledgeRewards, increasePledgeRewardPerVote) : WardenPledge.sol#L420:#L426 (excluding the close "check which is only performed in two of the three function).
if(token == address(0)) revert Errors.ZeroAddress() is called 3 times : WardenPledge.sol#L527 WardenPledge.sol#L571 WardenPledge.sol#L586
Revert()/require() that only perform checks on memory variables should come first. Then one could order the revert() based on the number of called state variables.
WardenPledge.sol#L224 should come before WardenPledge.sol#L223
WardenPledge.sol#L315:L316 should come before WardenPledge.sol#L311
WardenPledge.sol#L527:L528 should come before WardenPledge.sol#L526
WardenPledge.sol#L385
WardenPledge.sol#L94 WardenPledge.sol#L96 WardenPledge.sol#L98 WardenPledge.sol#L102 WardenPledge.sol#L105 WardenPledge.sol#L108 WardenPledge.sol#L110 WardenPledge.sol#L115 WardenPledge.sol#L116 WardenPledge.sol#L119
#0 - c4-judge
2022-11-12T00:17:18Z
kirk-baird marked the issue as grade-b