code-423n4 / 2022-05-velodrome-findings

0 stars 0 forks source link

Gas Optimizations #223

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Here are Gas reports


[GAS-1] Use custom errors

Using custom errors can reduce the gas cost.

There are more than 100 callsites of require check with inline error message. Using the custom errors instead of the inline error messages can reduce the gas cost.


[GAS-2] Use != 0 instead of > 0 on uint variables

uint variables will never be lower than 0. Therefore, > 0 and != 0 have same meanings. Using != 0 can reduce the gas deployment cost, so it is worth using != 0 wherever possible.

If the codebase uses > 0 on uint variables like this:

require(_amount > 0, "...");

it can rewrite like this:

require(_amount != 0, "...");

The above change can be applied to the following codes.

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Bribe.sol#L42 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Bribe.sol#L86 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Bribe.sol#L93 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Bribe.sol#L100

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L140 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L144 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L151 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L182 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L306 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L318 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L330 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L359 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L407 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L512 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L592 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L613 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L665 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L672 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L679

​​https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L140 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L154 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L164 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L174 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L183 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L187 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L207 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L303 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L322 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L522

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/PairFees.sol#L20 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/PairFees.sol#L29-L30

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Router.sol#L58-L59

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L111 (This if statement seems not necessary since it checks _votes != 0)

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L167 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L227 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L239 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L259 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L289 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L294 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L322 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L352

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L614 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L772 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L785 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L819 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1214 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1217 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1237 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1269 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1287 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1307


[Gas-3] No need to set 0 on uint variables

The default value of uint varibles are 0. Therefore, there is no need to set 0 on uint variables. Not setting 0 on uint variables can reduce the gas cost.

If 0 is set on uint variable like this uint256 amount = 0;, it can rewrite to uint256 amount;. In for loop, if uint is used like this for (uint256 i = 0; i < length; i++), it can omit setting = 0 and will be for (uint256 i; i < length; i++).

The above change can be applied to the following codes.

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L179 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L353 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L481 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L551

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Minter.sol#L57

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L20 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L257 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L273-L274 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L389

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L73 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L75 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L103 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L105 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L119 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L121 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L148 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L170-L171 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L195 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L227-L228 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L301

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Router.sol#L90 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Router.sol#L316

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Velo.sol#L9

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L76 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L101 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L103 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L128 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L139-L141 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L143 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L147 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L266 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L304 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L310

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L622 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L632 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L884 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L886 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L942
https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L960-L961 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L996 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1017 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1145 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1146 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1168 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1192 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1193 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1225 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1249 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1295 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1320 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1325


[Gas-4] Potential usage of unchecked

Following variables or operations can be wrapped by unchecked.

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L426

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L389

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L75

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L105

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L121

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L148

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/RewardsDistributor.sol#L195

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L272

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Voter.sol#L340

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L632

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L886 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L942 https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1017

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Gauge.sol#L615

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L144


[Gas-5] Avoid defining DOMAIN_SEPARATOR every time the functions are called

At folowing functions, they define DOMAIN_SEPARATOR every time the functions are called. DOMAIN_SEPARATOR can be set beforehand, and it can avoid defining DOMAIN_SEPARATOR every time.

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Pair.sol#L468-L476

https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/VotingEscrow.sol#L1362-L1370

GalloDaSballo commented 2 years ago

[Gas-5] Avoid defining DOMAIN_SEPARATOR every time the functions are called

Would save 120 gas and 90 gas per function call respectively

GalloDaSballo commented 2 years ago

[Gas-3] No need to set 0 on uint variables

51 entries per instance

[Gas-4] Potential usage of unchecked

[GAS-2] Use != 0 instead of > 0 on uint variables

Is no longer valid

Overall a neat report with an interesting find (5) Would save 20 gas (at least) per instance 20 * 20 = 400

GalloDaSballo commented 2 years ago

Total Gas Saved 661