Yield Witch v2 contest - joestakey's results

Fixed-rate borrowing and lending on Ethereum

General Information

Platform: Code4rena

Start Date: 14/07/2022

Pot Size: $25,000 USDC

Total HM: 2

Participants: 63

Period: 3 days

Judge: PierrickGT

Total Solo HM: 1

Id: 147

League: ETH

Yield

Findings Distribution

Researcher Performance

Rank: 38/63

Findings: 1

Award: $39.86

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

Gas Report

Table of Contents

Constants can be private

IMPACT

Marking constants as private save gas upon deployment, as the compiler does not have to create getter functions for these variables. It is worth noting that a private variable can still be read using either the verified contract source code or the bytecode.

PROOF OF CONCEPT

Instances:

Witch.sol

ICauldron private immutable cauldron

TOOLS USED

Manual Analysis

MITIGATION

Make ICauldron private instead of public:

  • deployment gas cost in original contract:

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3076398 ┆ 15658 ┆ ┆ ┆ ┆ │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

  • deployment gas cost after the change made:

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3066367 ┆ 15601 ┆ ┆ ┆ ┆ │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

This saves 10,031 gas upon deployment.

Constructor parameters should be avoided when possible

IMPACT

Constructor parameters are expensive. The contract deployment will be cheaper in gas if they are hard coded instead of using constructor parameters.

PROOF OF CONCEPT

Instances:

Witch.sol

cauldron = cauldron_
ladle = ladle_

TOOLS USED

Manual Analysis

MITIGATION

Hardcode cauldron and ladle with their initial value instead of writing them during contract deployment with constructor parameters.

Custom Errors

IMPACT

Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met) while providing the same amount of information, as explained here

Custom errors are defined using the error statement

PROOF OF CONCEPT

17 instances:

Witch.sol

require(param == "ladle", "Unrecognized")
require(initialOffer <= 1e18, "InitialOffer above 100%")
require(proportion <= 1e18, "Proportion above 100%")
require(initialOffer == 0 || initialOffer >= 0.01e18,"InitialOffer below 1%")
require(proportion >= 0.01e18, "Proportion below 1%")
require(cauldron.level(vaultId) < 0, "Not undercollateralized")
require(limits_.sum <= limits_.max, "Collateral limit reached")
require(auction_.start > 0, "Vault not under auction")
require(cauldron.level(vaultId) >= 0, "Undercollateralized")
require(auction_.start > 0, "Vault not under auction")
require(liquidatorCut >= minInkOut, "Not enough bought")
require(baseJoin != IJoin(address(0)), "Join not found")
require(auction_.start > 0, "Vault not under auction")
require(liquidatorCut >= minInkOut, "Not enough bought")
require(baseJoin != IJoin(address(0)), "Join not found")
require(auction_.start > 0, "Vault not under auction")
require(auction_.art - artIn >= debt.min * (10**debt.dec),"Leaves dust")

TOOLS USED

Manual Analysis

MITIGATION

Replace require and revert statements with custom errors.

For instance:

Replace

require(param == "ladle", "Unrecognized")

with

if (param != "ladle") { revert Unrecognized(); }

and define the custom error in the contract

error Unrecognized();
  • gas costs before amendment

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3076398 ┆ 15658 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ point ┆ 2934 ┆ 5098 ┆ 2942 ┆ 9420 ┆ 3 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

  • gas costs after amendment

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3070390 ┆ 15628 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ point ┆ 2870 ┆ 5074 ┆ 2934 ┆ 9420 ┆ 3 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

Changing this one require statement into a custom error saves 6,008 gas upon deployment, and an average of 24 gas per function call.

Event fields are redundant

PROBLEM

block.timestamp and block.number are added to event information by default, explicitly adding them is a waste of gas.

PROOF OF CONCEPT

Witch.sol

emit Auctioned(vaultId, uint32(block.timestamp))

TOOLS USED

Manual Analysis

MITIGATION

Remove the start event field of Auctioned.

Functions with access control cheaper if payable

PROBLEM

A function with access control marked as payable will lbe cheaper for legitimate callers: the compiler removes checks for msg.value, saving approximately 20 gas per function call.

PROOF OF CONCEPT

6 instances:

Witch.sol

function point(bytes32 param, address value) external auth
function setLine(bytes6 ilkId,bytes6 baseId,uint32 duration,uint64 proportion,uint64 initialOffer) external auth
function setLimit() bytes6 ilkId,bytes6 baseId,uint128 max) external auth
function setAnotherWitch(address value, bool isWitch) external aut
function setIgnoredPair(bytes6 ilkId,bytes6 baseId,bool ignore) external auth
function setAuctioneerReward(uint128 auctioneerReward_) external auth

TOOLS USED

Manual Analysis

MITIGATION

add the payable modifier to these functions.

Mathematical optimizations

PROBLEM

X += Y costs more gas than X = X + Y. This can mean a lot of gas wasted in a function call when the computation is repeated n times (loops)

PROOF OF CONCEPT

6 instances include:

Witch.sol

limits_.sum += auction_.ink
limits_.sum -= auction_.ink
auction_.ink -= inkOut.u128()
auction_.art -= artIn.u128()
limits_.sum -= inkOut.u128()
liquidatorCut -= auctioneerCut

TOOLS USED

Manual Analysis

MITIGATION

use X = X + Y instead of X += Y (same with -)

For instance, just by changing limits_.sum += auction_.ink into limits_.sum = limits_.sum + auction_.ink:

  • gas costs before amendment

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3076398 ┆ 15658 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ auction ┆ 4219 ┆ 70111 ┆ 81848 ┆ 91148 ┆ 30 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

  • gas costs before amendment

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3074398 ┆ 15648 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ auction ┆ 4219 ┆ 70086 ┆ 81819 ┆ 91119 ┆ 30 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

It saves 2,000 gas upon deployment, and an average of 25 gas per function call.

Modifier instead of duplicate require

PROBLEM

When a require statement is used multiple times, it is cheaper in deployment costs to use a modifier instead.

PROOF OF CONCEPT

3 instances:

Witch.sol

require(auction_.start > 0, "Vault not under auction")
require(auction_.start > 0, "Vault not under auction")
require(auction_.start > 0, "Vault not under auction")
require(auction_.start > 0, "Vault not under auction")

require(baseJoin != IJoin(address(0)), "Join not found")
require(baseJoin != IJoin(address(0)), "Join not found")

require(liquidatorCut >= minInkOut, "Not enough bought")
require(liquidatorCut >= minInkOut, "Not enough bought")

TOOLS USED

Manual Analysis

MITIGATION

Use modifiers for these repeated statements

Require should be at the top

IMPACT

require statements checking function arguments should be at the top of the function, to prevent unnecessary extra computation when they revert

PROOF OF CONCEPT

2 instances:

Witch.sol

require(cauldron.level(vaultId) < 0, "Not undercollateralized")
require(cauldron.level(vaultId) >= 0, "Undercollateralized")

TOOLS USED

Manual Analysis

MITIGATION

Place these statements at the top of their respective functions.

Uint256 instead of Uint128

PROBLEM

Each storage slot has 256 bits. Whenever a uint smaller than 256 (or even a bool) is pulled from storage, the EVM casts it to a uint256. Calculations are also unexceptionally performed in uint256 by the EVM.

PROOF OF CONCEPT

Witch.sol

uint128 public auctioneerReward = 0.01e18

TOOLS USED

Manual Analysis

MITIGATION

Replace uint128 with uint256. Downcast when required.

Unchecked arithmetic

IMPACT

The default "checked" behavior costs more gas when adding/diving/multiplying, because under-the-hood those checks are implemented as a series of opcodes that, prior to performing the actual arithmetic, check for under/overflow and revert if it is detected.

if it can statically be determined there is no possible way for your arithmetic to under/overflow (such as a condition in an if statement), surrounding the arithmetic in an unchecked block will save gas

PROOF OF CONCEPT

Witch.sol

auction_.art -= artIn.u128() cannot underflow because of the check line 438

TOOLS USED

Manual Analysis

MITIGATION

Place this operation in an unchecked block

use Assembly for simple setters

IMPACT

Where it does not affect readability, using assembly allows to save gas not only on deployment, but also on function calls. This is the case for instance for simple admin setters.

PROOF OF CONCEPT

Instances:

Witch.sol

auctioneerReward = auctioneerReward_

MITIGATION

-  auctioneerReward = auctioneerReward_;
+  assembly {
+    sstore(auctioneerReward.slot, auctioneerReward_)
+  }
  • gas cost before amendment:

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3076398 ┆ 15658 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ setAuctioneerReward ┆ 2859 ┆ 4874 ┆ 2885 ┆ 8879 ┆ 3 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

  • gas cost after amendment:

╭─────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮ │ Witch contract ┆ ┆ ┆ ┆ ┆ │ ā•žā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•Ŗā•ā•ā•ā•ā•ā•ā•ā•ā•ā•” │ Deployment Cost ┆ Deployment Size ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ 3071390 ┆ 15633 ┆ ┆ ┆ ┆ │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ Function Name ┆ min ┆ avg ┆ median ┆ max ┆ # calls │ ā”œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¼ā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā•Œā”¤ │ setAuctioneerReward ┆ 2859 ┆ 4866 ┆ 2885 ┆ 8855 ┆ 3 │ ╰─────────────────────┓─────────────────┓───────┓────────┓───────┓─────────╯

It saves 5,008 gas upon deployment, and an average of 8 gas per function call.

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Ā© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter