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

1 stars 1 forks source link

Gas Optimizations #250

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Gas Optimizations

[G01] Use calldata instead of memory:

For external function's dynamic params, calldata is the cheapest location to use.

MerkleDropFactory.sol
  88,82:     function withdraw(uint treeIndex, address destination, uint value, bytes32[] memory proof) public {

MerkleEligibility.sol
  70,66:     function isEligible(uint index, address recipient, bytes32[] memory proof) public override view returns (bool eligible) {
  85,68:     function passThruGate(uint index, address recipient, bytes32[] memory proof) external override {

MerkleIdentity.sol
  116,62:     function withdraw(uint merkleIndex, uint tokenId, string memory uri, bytes32[] memory addressProof, bytes32[] memory metadataProof) external payable {
  116,84:     function withdraw(uint merkleIndex, uint tokenId, string memory uri, bytes32[] memory addressProof, bytes32[] memory metadataProof) external payable {
  116,115:     function withdraw(uint merkleIndex, uint tokenId, string memory uri, bytes32[] memory addressProof, bytes32[] memory metadataProof) external payable {
  152,72:     function isEligible(uint merkleIndex, address recipient, bytes32[] memory proof) public view returns (bool) {
  163,64:     function verifyMetadata(bytes32 root, uint tokenId, string memory uri, bytes32[] memory proof) public pure returns (bool) {
  163,86:     function verifyMetadata(bytes32 root, uint tokenId, string memory uri, bytes32[] memory proof) public pure returns (bool) {

MerkleLib.sol
  17,64:     function verifyProof(bytes32 root, bytes32 leaf, bytes32[] memory proof) public pure returns (bool) {

MerkleResistor.sol
  134,136:     function initialize(uint treeIndex, address destination, uint vestingTime, uint minTotalPayments, uint maxTotalPayments, bytes32[] memory proof) external {

MerkleVesting.sol
  104,143:     function initialize(uint treeIndex, address destination, uint totalCoins, uint startTime, uint endTime, uint lockPeriodEndTime, bytes32[] memory proof) external {

interfaces/IEligibility.sol
  17,50:     function isEligible(uint, address, bytes32[] memory) external view returns (bool eligible);
  21,52:     function passThruGate(uint, address, bytes32[] memory) external;

Recommended Mitigation Steps:

Change params memory to calldata

[G02] uint default value is 0 so we can remove = 0:

MerkleDropFactory.sol
  17,26:     uint public numTrees = 0;

MerkleEligibility.sol
  31,26:     uint public numGates = 0;

MerkleLib.sol
  22,21:         for (uint i = 0; i < proof.length; i += 1) {

MerkleResistor.sol
  24,26:     uint public numTrees = 0;
  176,32:         uint currentWithdrawal = 0;

MerkleVesting.sol
  16,26:     uint public numTrees = 0;
  150,32:         uint currentWithdrawal = 0;

PermissionlessBasicPoolFactory.sol
  115,21:         for (uint i = 0; i < rewardTokenAddresses.length; i++) {
  141,21:         for (uint i = 0; i < pool.rewardFunding.length; i++) {
  168,21:         for (uint i = 0; i < pool.rewardsWeiPerSecondPerToken.length; i++) {
  224,21:         for (uint i = 0; i < rewards.length; i++) {
  249,21:         for (uint i = 0; i < pool.rewardTokens.length; i++) {
  266,21:         for (uint i = 0; i < pool.rewardTokens.length; i++) {

VoterID.sol
  69,31:     uint public numIdentities = 0;

[G03] ++i use less gas than i++ or i += 1:

++i costs less gas compared to i++. about 5 gas per iteration.

PermissionlessBasicPoolFactory.sol
  115,59:         for (uint i = 0; i < rewardTokenAddresses.length; i++) {
  141,57:         for (uint i = 0; i < pool.rewardFunding.length; i++) {
  168,71:         for (uint i = 0; i < pool.rewardsWeiPerSecondPerToken.length; i++) {
  224,46:         for (uint i = 0; i < rewards.length; i++) {
  249,56:         for (uint i = 0; i < pool.rewardTokens.length; i++) {
  266,56:         for (uint i = 0; i < pool.rewardTokens.length; i++) {

MerkleLib.sol
  22,21:         for (uint i = 0; i < proof.length; i += 1) {

[G04] Use Custom Errors to save Gas:

Custom errors from Solidity 0.8.4 are cheaper than require messages. https://blog.soliditylang.org/2021/04/21/custom-errors/

illuzen commented 2 years ago

all duplicates