Open codeislight1 opened 1 year ago
Hello @co
Have you measured the gas savings this would bring ?
I have tested it on Remix, the following are the gas savings:
// add saves 136 - 87 = 49
// sub saves 136 - 82 = 54
// mul saves 152 - 111 = 41
// div saves 121 - 108 = 13
// mod saves 121 - 108 = 13
// tryAdd saves 112 - 103 = 9
// trySub saves 101 - 97 = 4
// tryMul saves 159 - 155 = 4
// tryDiv saves 127 - 123 = 4
// tryMod saves 127 - 123 = 4
The following is the script used to profile the gas savings:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./SafeMath.sol";
abstract contract gasProfiler{
event Gas(uint gas);
event EmitMsg(string message);
event Gas(string message, uint gas);
modifier profile(){
uint gas = gasleft();
_;
emit Gas(gas - gasleft());
}
}
contract Test is gasProfiler {
using SafeMath for uint256;
// 0 appended functions are the original one, while 1 refers for the optimized version
function testAdd0(uint a, uint b) internal profile() { // 136
a.add(b);
}
function testAdd1(uint a, uint b) internal profile() { // 87
a.add1(b);
}
function testSub0(uint a, uint b) internal profile() { // 136
a.sub(b);
}
function testSub1(uint a, uint b) internal profile() { // 82
a.sub1(b);
}
function testMul0(uint a, uint b) internal profile() { // 152
a.mul(b);
}
function testMul1(uint a, uint b) internal profile() { // 111
a.mul1(b);
}
function testDiv0(uint a, uint b) internal profile() { // 121
a.div(b);
}
function testDiv1(uint a, uint b) internal profile() { // 108
a.div1(b);
}
function testMod0(uint a, uint b) internal profile() { // 121
a.mod(b);
}
function testMod1(uint a, uint b) internal profile() { // 108
a.mod1(b);
}
function testTryAdd0(uint a, uint b) internal profile() { // 112
a.tryAdd(b);
}
function testTryAdd1(uint a, uint b) internal profile() { // 103
a.tryAdd1(b);
}
function testTrySub0(uint a, uint b) internal profile() { // 101
a.trySub(b);
}
function testTrySub1(uint a, uint b) internal profile() { // 97
a.trySub1(b);
}
function testTryMul0(uint a, uint b) internal profile() { // 159
a.tryMul(b);
}
function testTryMul1(uint a, uint b) internal profile() { // 155
a.tryMul1(b);
}
function testTryDiv0(uint a, uint b) internal profile() { // 127
a.tryDiv(b);
}
function testTryDiv1(uint a, uint b) internal profile() { // 123
a.tryDiv1(b);
}
function testTryMod0(uint a, uint b) internal profile() { // 127
a.tryMod(b);
}
function testTryMod1(uint a, uint b) internal profile() { // 123
a.tryMod1(b);
}
enum Operations {
add, sub, mul, div, mod, tryAdd, trySub, tryMul, tryDiv, tryMod
}
function run(uint a, uint b, Operations op) external {
if(op == Operations.add){
testAdd0(a,b);
testAdd1(a,b);
} else if(op == Operations.sub){
testSub0(a,b);
testSub1(a,b);
} else if(op == Operations.mul){
testMul0(a,b);
testMul1(a,b);
} else if(op == Operations.div){
testDiv0(a,b);
testDiv1(a,b);
} else if(op == Operations.mod){
testMod0(a,b);
testMod1(a,b);
} else if(op == Operations.tryAdd){
testTryAdd0(a,b);
testTryAdd1(a,b);
} else if(op == Operations.trySub){
testTrySub0(a,b);
testTrySub1(a,b);
} else if(op == Operations.tryMul){
testTryMul0(a,b);
testTryMul1(a,b);
} else if(op == Operations.tryDiv){
testTryDiv0(a,b);
testTryDiv1(a,b);
} else if(op == Operations.tryMod){
testTryMod0(a,b);
testTryMod1(a,b);
}
}
}
Brief: I was reviewing the contract, i noticed that there are couple of gas optimizations that are worth implementing:
Implementation: