Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #249

Open
code423n4 opened this issue Sep 1, 2022 · 0 comments
Open

Gas Optimizations #249

code423n4 opened this issue Sep 1, 2022 · 0 comments

Comments

@code423n4
Copy link
Contributor

code423n4 commented Sep 1, 2022

Gas Optimizations List

Number Optimization Details Per gas saved Context
1 Sort Solidity operations using short-circuit mode 2111 2
2 Update on repayLoan function for gas earnings ~1000 1
3 Gas improvement on returning instructionsId value. ~200 1
4 Shifting cheaper than division 146 2
5 Using uint256 instead of bool in mappings is more gas efficient 146 6
6 Converting toggleBeat architecture from bool to uint256 saves gas 130 2
7 Gas can be saved by changing the way the constructor defines its arguments. 94 6
8 Unchecked decrement can be used in -= received [85 gas per use + ~15000 gas saved during deployment cost ] 85 1
9 Use assembly to write address storage values 33 5
10 Functions guaranteed to revert when called by normal users can be marked payable 24 9
11 Function ordering via method ID 22 All contracts
12 <x> += <y> costs more gas than <x> = <x> + <y> for state variables 16 9
13 Setting the constructor to payable 13 14
14 Catching the array length prior to loop [13 gas per 6 arrays instance] 13 1
15 Direct definition of boolean literals consumes more gas When we use if 9 2
16 Using private rather than public for constans, saves gas 7 8
17 Use assembly to check for address(0) 6 1
18 Using > instead of >= is more gas efficient 3 1

1- Sort Solidity operations using short-circuit mode [2111 gas saved]

Context:
RANGE.sol#L221
Operator.sol#L739-L741

Description:
Short-circuiting is a solidity contract development model that uses OR/AND logic to sequence different cost operations. It puts low gas cost operations in the front and high gas cost operations in the back, so that if the front is low If the cost operation is feasible, you can skip (short-circuit) the subsequent high-cost Ethereum virtual machine operation.

//f(x) is a low gas cost operation 
//g(y) is a high gas cost operation 

//Sort operations with different gas costs as follows 
f(x) || g(y) 
f(x) && g(y)

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

Operator.sol#L739-L741 : [ Min 2000 Gas Saved ]
RANGE.sol#L221 : [ 2111 Gas Saved (Poc is given below) ]

contract GasTest is DSTest {
    
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0.updateMarket();
        c1.updateMarket();
    }
}

contract Contract0 {
    uint256 marketCapacity_ = 0;
    uint256 market_ = type(uint256).max;
    error RANGE_InvalidParams();
    
    function updateMarket() public {
        if (market_ == type(uint256).max && marketCapacity_ != 0) revert RANGE_InvalidParams();
    }
}

contract Contract1 {
    uint256 marketCapacity_ = 0;
    uint256 market_ = type(uint256).max;
    error RANGE_InvalidParams();
    
    function updateMarket() public {
        if (marketCapacity_ != 0 && market_ == type(uint256).max) revert RANGE_InvalidParams();
    }
}

Gas Report:

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 66808                                      253                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 updateMarket                               4379             4379  4379    4379  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 66808                                      253                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 updateMarket                               2268             2268  2268    2268  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

2- Update on repayLoan function for gas earnings [~1000 gas]

Context:
TRSRY.sol#L105-L119

Description:
In the repayLoan function, gas is saved if transactions that consume gas but are not necessary are removed safeTransferFrom. Since the safeTransferFrom function does all balance and return success checks, there is no need for an additional check. So if we removed to balanceOf and other math. totaly ~1000 gas saved (Get the balance of the account it will cost 400 units of gas)

Current Code

TRSRY.sol#L105-L119
function repayLoan(ERC20 token_, uint256 amount_) external nonReentrant {
        if (reserveDebt[token_][msg.sender] == 0) revert TRSRY_NoDebtOutstanding();
        uint256 prevBalance = token_.balanceOf(address(this));
        token_.safeTransferFrom(msg.sender, address(this), amount_);
        uint256 received = token_.balanceOf(address(this)) - prevBalance;
       reserveDebt[token_][msg.sender] -= received;
        totalDebt[token_] -= received;
        emit DebtRepaid(token_, msg.sender, received);
    }

Recomendation code:

function repayLoan(ERC20 token_, uint256 amount_) external nonReentrant {
        if (reserveDebt[token_][msg.sender] == 0) revert TRSRY_NoDebtOutstanding();
        // uint256 prevBalance = token_.balanceOf(address(this));  (This line not necessary)
        token_.safeTransferFrom(msg.sender, address(this), amount_);
        // uint256 received = token_.balanceOf(address(this)) - prevBalance; (This line not necessary)
        reserveDebt[token_][msg.sender] -= amount;  // (directly read to ‘amount’ )
        totalDebt[token_] -= amount; // (directly read to ‘amount’ )
        emit DebtRepaid(token_, msg.sender, amount); // (directly read to ‘amount’ )
    }

3 – Gas improvement on returning instructionsId value [~200 gas saved]

Context:
INSTR.sol#L42

Recommendation:
instructionsId in function returns and delete INSTR.sol#L78 can save gas

Proof Of Concept:
The optimizer was turned on and set to 10000 runs
INSTR.sol#L78

function store(Instruction[] calldata instructions_) external permissioned returns (uint256) {
    //codes…..
    return instructionsId;

Recomendation code:

function store(Instruction[] calldata instructions_) external permissioned returns (uint256  instructionsId) {
    //codes…..

4 - Shifting cheaper than division [146 gas per instance]

Context:
Operator.sol#L372
Operator.sol#L427

Description:
A division by 2 can be calculated by shifting one to the right. While the DIV opcode uses 5 gas, the SHR opcode only uses 3 gas Furthermore, Solidity's division operation also includes a division-by-0 prevention which is bypassed using shifting.

Recommendation:
Change the functions visibility to external to save gas.

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    
    Contract1 c1;
    Contract2 c2;
    
    function setUp() public {
        c1 = new Contract1();
        c2 = new Contract2();
    }
    
    function testGas() public {
        c1.checkPoint();
        c2.checkPoint();
    }
}
contract Contract1 {
    uint32 a = 10;
    uint32 b = 2;
    
    function checkPoint() public view returns (uint32) {
        uint32 center = a/b;
        return(center);
    }
}
contract Contract2 { 
    uint32 a = 10;
    uint32 b = 2;
    
    function checkPoint() public view returns (uint32) {
        uint32 center = a >> 1;
        return(center);
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 70035                                      293                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 checkPoint                                 2413             2413  2413    2413  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract2 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 49417                                      189                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 checkPoint                                 2267             2267  2267    2267  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

5 - Using uint256 instead of bool in mappings is more gas efficient [146 gas per instance]

Context:
Kernel.sol#L181
Kernel.sol#L194
Kernel.sol#L197
BondCallback.sol#L24
Governance.sol#L105
Governance.sol#L117

Description:
OpenZeppelin uint256 and bool comparison :
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.The values being non-zero value makes deployment a bit more expensive.

Recommendation:
Use uint256(1) and uint256(2) instead of bool

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
     
        c0._setPolicyPermissions(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 79, true);
        c1._setPolicyPermissions(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 79, 2);
    }
}

contract Contract0 {
    mapping(address => mapping(uint256  => bool)) public modulePermissions;
    error boolcheck();

    function _setPolicyPermissions(address addr_, uint256 id, bool log) external {
       modulePermissions[addr_][id] = log; 
       if(modulePermissions[addr_][id] = false) revert boolcheck();
    }
}
contract Contract1 {
    mapping(address => mapping(uint256  => uint256)) public modulePermissions;
    error boolcheck();

    // Use uint256 instead of bool    (1 = false , 2 = true) 
    function _setPolicyPermissions(address addr_, uint256 id, uint256 log) external {
       modulePermissions[addr_][id] == log; 
       if(modulePermissions[addr_][id] == 1) revert boolcheck();
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 88335                                      473                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 _setPolicyPermissions                      2750             2750  2750    2750  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 87135                                      467                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 _setPolicyPermissions                      2604             2604  2604    2604  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

6- Converting toggleBeat architecture from bool to uint256 saves gas [130 gas per instance]

Context:
Heart.sol#L135-L137
Operator.sol#L624-L627

Current Code

Heart.sol#L135-L137

bool public active;

 function toggleBeat() external onlyRole("heart_admin") {
        active = !active;
    }

Recomendation code:

 uint256 check; // 1= active, 2= inactive

 function use() external  {
        check = 2;
    }

Proof Of Concept:

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;

    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();

    }

        function testGas() public {
            c0.set();
            c1.set();
            c0.use();
            c1.use();
        }
}

contract Contract0 {
    uint256 check; // 1= active, 2= inactive
    error Heart_BeatStopped();
   function use() external  {
        check = 2;
    }

    function set() external {
        if(check == 1) revert Heart_BeatStopped();
    }
}

contract Contract1 {
    bool active;
    error Heart_BeatStopped();
   function use() external  {
        active = !active;
    }

    function set() external  {
        if (active) revert Heart_BeatStopped();
    }

}

Proof of Concept Gas Report

╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 36687                                      214                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 set                                        2255             2255   2255    2255   1       
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 use                                        20116            20116  20116   20116  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 45499                                      258                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 set                                        2258             2258   2258    2258   1       
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 use                                        20246            20246  20246   20246  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯

7 – Gas can be saved by changing the way the constructor defines its arguments. [94 gas per use]

Context:
TRSRY.sol#L17
MINTR.sol#L8
RANGE.sol#L16
PRICE.sol#L22
VOTES.sol#L11
INSTR.sol#L10

Description:
When the constructor is inherited, the constructor arguments in the contract we inherit can be updated in two ways.

1 - Either specify directly in the inheritance list. (New use with Gas Optimization)
2- Or via a "modifier" of the derived constructor. (standard use)

In the contexts mentioned above, we get gas saved with this usage

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;

    function setUp() public {
        c0 = new Contract0(7);
        c1 = new Contract1();
    }

        function testGas() public {
            c0.set();
            c1.set();            
        }
}

contract Base {   
    uint public x; 
    constructor(uint _x) { x = _x; }
}

contract Contract0 is Base {
    constructor(uint _y) Base(7) {}

    function set() public {
    }
}

contract Contract1 is Base(7) {
    constructor() {}

    function set() public {
    }
}

Gas Report

Deployment cost difference can be checked

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 49723                                      266                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 set                                        120              120  120     120  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 49587                                      172                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 set                                        120              120  120     120  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯

8 - Unchecked decrement can be used in -= received [85 gas per use + ~15000 gas saved during deployment cost]

Context:
TRSRY.sol#L116

Description:
Newer versions of the Solidity compiler will check for integer overflows and underflows automatically. This provides safety but increases gas costs. When an unsigned integer is guaranteed to never overflow, the unchecked feature of Solidity can be used to save gas costs. There is no need for -= received safemath check in this function, there is no possibility of underflow, the first operations of the function do these checks

You can see exactly this example in transmission11 in solmate ERC20 contract:
https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol#L99-L105

Current Code

TRSRY.sol#L105-L119

function repayLoan(ERC20 token_, uint256 amount_) external nonReentrant {
        if (reserveDebt[token_][msg.sender] == 0) revert TRSRY_NoDebtOutstanding();

        uint256 prevBalance = token_.balanceOf(address(this));
        token_.safeTransferFrom(msg.sender, address(this), amount_);

        uint256 received = token_.balanceOf(address(this)) - prevBalance;

       reserveDebt[token_][msg.sender] -= received;
        totalDebt[token_] -= received;

        emit DebtRepaid(token_, msg.sender, received);
    }

Recomendation code:

function repayLoan(ERC20 token_, uint256 amount_) external nonReentrant {
        if (reserveDebt[token_][msg.sender] == 0) revert TRSRY_NoDebtOutstanding();

        uint256 prevBalance = token_.balanceOf(address(this));
        token_.safeTransferFrom(msg.sender, address(this), amount_);

        uint256 received = token_.balanceOf(address(this)) - prevBalance;

       reserveDebt[token_][msg.sender] -= received;
        unchecked {
            totalDebt[token_] -= received;
        }
        emit DebtRepaid(token_, msg.sender, received);
    }

Proof Of Concept:

contract GasTest is DSTest {
    
    Contract0 c0;
    Contract1 c1;

    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }

        function testGas() public {
            c0.repay(5);
            c1.repay(5);
        }
}

contract Contract0 {
           uint256 balanceOfme = 100;

       function repay( uint256 amount ) public  {
           balanceOfme -= amount;
       }
}

contract Contract1 {
          uint256 balanceOfme = 100;

       function repay( uint256 amount ) public  {
           unchecked {
               balanceOfme -= amount;
           }
       }
}

Proof of Concept Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 66999                                      260                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 repay                                      5293             5293  5293    5293  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 51787                                      183                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 repay                                      5208             5208  5208    5208  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

9 - Use assembly to write address storage values [33 gas per instance]

Context:
Heart.sol#L144-L145
Kernel.sol#L76-L77
Operator.sol#L119-L120
Operator.sol#L593-L594
BondCallback.sol#L43-L44

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTestFoundry is DSTest {
    Contract1 c1;
    Contract2 c2;
    
    function setUp() public {
        c1 = new Contract1();
        c2 = new Contract2();
    }
    
    function testGas() public {
        c1.setRewardTokenAndAmount(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 356);
        c2.setRewardTokenAndAmount(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 356);
    }
}

contract Contract1  {
    address rewardToken ;
    uint256 reward;

    function setRewardTokenAndAmount(address token_, uint256 reward_) external {
        rewardToken = token_;
        reward = reward_;
    }
}

contract Contract2  {
    address rewardToken ;
    uint256 reward;

    function setRewardTokenAndAmount(address token_, uint256 reward_) external {
        assembly {
            sstore(rewardToken.slot, token_)
            sstore(reward.slot, reward_)           
        }
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 50899                                      285                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 setRewardTokenAndAmount                    44490            44490  44490   44490  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract2 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 38087                                      221                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 setRewardTokenAndAmount                    44457            44457  44457   44457  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯

10 - Functions Guaranteed to Revert When Callled By Normal Users Can Be Marked Payable [24 gas per instance]

Context:
Kernel.sol#L235
Kernel.sol#L439
Kernel.sol#L451
BondCallback.sol#L190
BondCallback.sol#L152
Heart.sol#L130
Heart.sol#L135
Heart.sol#L140
Heart.sol#L150

Description:
If a function modifier or require such as onlyOwner-admin 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 24 gas per call to the function, in addition to the extra deployment cost

Recommendation:
Functions guaranteed to revert when called by normal users can be marked payable (for only onlyowner or admin functions)

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0.resetBeat();
        c1.resetBeat();
    }
}

contract Contract0 {
    uint256 versionNFTDropCollection;
    
    function resetBeat() external {
        versionNFTDropCollection++;
    }
}

contract Contract1 {
    uint256 versionNFTDropCollection;
    
    function resetBeat() external payable {
        versionNFTDropCollection++;
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 44293                                      252                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 resetBeat                                  22308            22308  22308   22308  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬───────┬────────┬───────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                                 
╞═══════════════════════════════════════════╪═════════════════╪═══════╪════════╪═══════╪═════════╡
 Deployment Cost                            Deployment Size                                
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 41893                                      240                                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg    median  max    # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 resetBeat                                  22284            22284  22284   22284  1       
╰───────────────────────────────────────────┴─────────────────┴───────┴────────┴───────┴─────────╯

11 - Function Ordering via Method ID [per gas 22 instance]

Context:
All Contracts

Description:
Contracts most called functions could simply save gas by function ordering via Method ID. Calling a function at runtime will be cheaper if the function is positioned earlier in the order (has a relatively lower Method ID) because 22 gas are added to the cost of a function for every position that came before it. The caller can save on gas if you prioritize most called functions.

Recommendation:
Find a lower method ID name for the most called functions for example Call() vs. Call1() is cheaper by 22 gas
For example, the function IDs in the Operator.sol contract will be the most used; A lower method ID may be given

Proof of Consept:
https://coinsbench.com/advanced-gas-optimizations-tips-for-solidity-85c47f413dc5

Operator.sol function names can be named and sorted according to METHOD ID

Sighash | Function Signature
========================
9459b875 => configureDependencies()
5924be70 => requestPermissions()
7159a618 => operate()
dc7fd16c => swap(ERC20,uint256,uint256)
ab104771 => bondPurchase(uint256,uint256)
b75a14c8 => _activate(bool)
d3170ab7 => _deactivate(bool)
ae159e98 => _getPriceDecimals(uint256)
41f19a46 => setSpreads(uint256,uint256)
33bd33b4 => setThresholdFactor(uint256)
aa9760a1 => setCushionFactor(uint32)
f2fa4737 => setCushionParams(uint32,uint32,uint32)
01de9ba8 => setReserveFactor(uint32)
3a3f54bc => setRegenParams(uint32,uint32,uint32)
945beb0a => setBondContracts(IBondAuctioneer,IBondCallback)
8129fc1c => initialize()
2ecd1f20 => regenerate(bool)
29c68dc1 => toggleActive()
d5711035 => _updateCapacity(bool,uint256)
1d952c94 => _updateRangePrices()
4c3a66d4 => _addObservation()
68c42258 => _regenerate(bool)
6d96c12c => _checkCushion(bool)
770a996e => getAmountOut(ERC20,uint256)
9e897711 => fullCapacity(bool)
200d2ed2 => status()
79502c55 => config()

12 - x += y costs more gas than x = x + y for state variables [16 gas per instance]

Context:
PRICE.sol#L136
PRICE.sol#L138
TRSRY.sol#L96-L97
TRSRY.sol#L131
VOTES.sol#L58
BondCallback.sol#L143-L144
Governance.sol#L198
Governance.sol#L252-L254
Heart.sol#L103

Description:
x += y costs more gas than x = x + y for state variables

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0.foo(33);
        c1.foo(33);
    }
}

contract Contract0 {
    uint256 _totalBorrow = 60;
    
    function foo(uint256 _interestEarned) public {
        _totalBorrow += interestEarned;
    }
}

contract Contract1 {
    uint256 _totalBorrow = 60;
    function foo(uint256 _interestEarned) public {
        _totalBorrow = _totalBorrow + interestEarned;
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 70805                                      279                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 foo                                        5302             5302  5302    5302  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 69805                                      274                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 foo                                        5286             5286  5286    5286  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

13 - Setting The Constructor To Payable [13 gas per instance]

Context:
Kernel.sol#L217, TRSRY.sol#L45, MINTR.sol#L15
RANGE.sol#L77, PRICE.sol#L22, VOTES.sol#L16
INSTR.sol#L20, TreasuryCustodian.sol#L24
Operator.sol#L92, BondCallback.sol#L38, Heart.sol#L54
PriceConfig.sol#L15, Governance.sol#L59, VoterRegistration.sol#L16

Description:
You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable. Making the constructor payable eliminates the need for an initial check of msg.value == 0 and saves 13 gas on deployment with no security risks.

Recommendation:
Set the constructor to payable

Proof Of Concept:
https://forum.openzeppelin.com/t/a-collection-of-gas-optimisation-tricks/19966/5?u=pcaversaccio

The optimizer was turned on and set to 10000 runs

contract GasTestFoundry is DSTest {
    
    Contract1 c1;
    Contract2 c2;
    
    function setUp() public {
        c1 = new Contract1();
        c2 = new Contract2();
    }
    
    function testGas() public {
        c1.x();
        c2.x();
    }
}

contract Contract1 {
    
    uint256 public dummy;
    constructor() payable {
        dummy = 1;
    }
    
    function x() public {

    }
}

contract Contract2 {
    
    uint256 public dummy;
    constructor() {
        dummy = 1;
    }
    
    function x() public {
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 49563                                      159                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract2 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 49587                                      172                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤

14 - Catching The Array Length Prior To Loop [ 13 gas per 6 arrays instance]

Context:
Governance.sol#L278

Description:
One can save gas by caching the array length (in stack) and using that set variable in the loop. Replace state variable reads and writes within loops with local variable reads and writes. This is done by assigning state variable values to new local variables, reading and/or writing the local variables in a loop, then after the loop assigning any changed local variables to their equivalent state variables.

Recommendation:
Simply do something like so before the for loop: uint length = variable.length Then add length in place of variable.length in the for loop.

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract1 c1;
    Contract2 c2;

    function setUp() public {
        c1 = new Contract1();
        c2 = new Contract2();

    }

    function testGas() public {
        address[] memory Inputs = new address[](6);
        Inputs[0] = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
        Inputs[1] = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
        Inputs[2] = 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db;
        Inputs[3] = 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB;
        Inputs[4] = 0x617F2E2fD72FD9D5503197092aC168c91465E7f2;
        Inputs[5] = 0x17F6AD8Ef982297579C203069C1DbfFE4348c372;

        c1.executeProposal(Inputs);
        c2.executeProposal(Inputs);
    }
}

contract Contract1 {

    function executeProposal(address[] memory test) public pure {
        uint256 a = test.length;
        for (uint256 step; step  < a; ) {
            unchecked {
                ++step;
            }
        }
    }
}

contract Contract2 { 

    function executeProposal(address[] memory test) public pure {
        for (uint256 step; step < test.length; ) {
            unchecked {
                ++step;
            }
        }
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 92941                                      496                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 executeProposal                            1653             1653  1653    1653  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract2 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 92541                                      494                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 executeProposal                            1666             1666  1666    1666  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

15 – Direct definition of boolean literals consumes more gas When we use if [9 gas per instance]

Context:
Governance.sol#L223-L224
Governance.sol#L306

Description:
Direct definition of boolean literals consumes more gas When we use if

Proof Of Concept
The optimizer was turned on and set to 10000 runs

use for GasTest : Governance.sol#L223-L224

contract GasTest is DSTest {
    
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0.activateProposal(2);
        c1.activateProposal(2);
    }
}

contract Contract0 {
    mapping(uint256 => bool) public proposalHasBeenActivated;
    error ProposalAlreadyActivated();

    function activateProposal(uint256 proposalId_) public {
        if (proposalHasBeenActivated[proposalId_] == true) {
            revert ProposalAlreadyActivated();
        }
    }
}

contract Contract1 {
    mapping(uint256 => bool) public proposalHasBeenActivated;
    error ProposalAlreadyActivated();
   
    function activateProposal(uint256 proposalId_) public {
        if (proposalHasBeenActivated[proposalId_]) {
            revert ProposalAlreadyActivated();
        }
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 56305                                      313                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 activateProposal                           2427             2427  2427    2427  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬──────┬────────┬──────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                               
╞═══════════════════════════════════════════╪═════════════════╪══════╪════════╪══════╪═════════╡
 Deployment Cost                            Deployment Size                              
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 55505                                      309                                          
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg   median  max   # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 activateProposal                           2418             2418  2418    2418  1       
╰───────────────────────────────────────────┴─────────────────┴──────┴────────┴──────┴─────────╯

16 - Using private rather than public for constans, saves gas [7 gas per instance]

Context:
Governance.sol#L121
Governance.sol#L124
Governance.sol#L127
Governance.sol#L130
Governance.sol#L133
Governance.sol#L137
RANGE.sol#L65
Operator.sol#L89

Proof Of Concept
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0._getPriceDecimals();
        c1._getPriceDecimals();
    }
}

contract Contract0 {
    uint32 public constant FACTOR_SCALE = 1e4;
        function _getPriceDecimals() public returns(uint32) {
        return FACTOR_SCALE;
    }
}
contract Contract1 {
    uint32 private constant FACTOR_SCALE = 1e4;
     function _getPriceDecimals() public returns(uint32) {
        return FACTOR_SCALE;
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 29281                                      176                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 _getPriceDecimals                          156              156  156     156  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 24075                                      149                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 _getPriceDecimals                          149              149  149     149  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯

17 - Use assembly to check for address(0) [6 gas per instance]

Context:
BondCallback.sol#L191

Proof Of Concept:
The optimizer was turned on and set to 10000 runs

contract GasTest is DSTest {
    Contract0 c0;
    Contract1 c1;
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    function testGas() public view {
        c0.setOperator(address(this));
        c1.setOperator(address(this));
    }
}
contract Contract0 {
    error Callback_InvalidParams();
    function setOperator(address operator_) public pure {
        if (address(operator_) == address(0)) revert Callback_InvalidParams();
    }
}
contract Contract1 {
    function setOperator(address operator_) public pure {
        assembly {
            if iszero(operator_) {
                mstore(0x00, "Callback_InvalidParams")
                revert(0x00, 0x20)
            }
        }
    }
}

Gas Report:

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 50899                                      285                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 setOperator                                258              258  258     258  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 44893                                      255                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 setOperator                                252              252  252     252  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯

18 - Using > instead of >= is more gas efficient [3 gas per instance]

Context:
Operator.sol#L486

Proof Of Concept
The optimizer was turned on and set to 10000 runs
use for GasTest : Operator.sol#L486

contract GasTest is DSTest {
    
    Contract0 c0;
    Contract1 c1;
    
    function setUp() public {
        c0 = new Contract0();
        c1 = new Contract1();
    }
    
    function testGas() public {
        c0._getPriceDecimals(2);
        c1._getPriceDecimals(2);
    }
}
contract Contract0 {
     function _getPriceDecimals(uint256 price_) public view returns (int8) {
        int8 decimals;
        while (price_ >= 10) {
            price_ = price_ / 10;
            decimals++;
        }
    }
}
 
contract Contract1 {
     function _getPriceDecimals(uint256 price_) public view returns (int8) {
        int8 decimals;
        while (price_ > 9) {
            price_ = price_ / 10;
            decimals++;
        }
    }
}

Gas Report

╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract0 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 69517                                      379                                        
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 Function Name                              min              avg  median  max  # calls 
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 _getPriceDecimals                          298              298  298     298  1       
╰───────────────────────────────────────────┴─────────────────┴─────┴────────┴─────┴─────────╯
╭───────────────────────────────────────────┬─────────────────┬─────┬────────┬─────┬─────────╮
 src/test/GasTest.t.sol:Contract1 contract                                             
╞═══════════════════════════════════════════╪═════════════════╪═════╪════════╪═════╪═════════╡
 Deployment Cost                            Deployment Size                            
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
 69717                                      380            
... See the rest this report [here](https://github.com/code-423n4/2022-08-olympus-findings/blob/main/data/0xSmartContract-G.md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant