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 #169

Open
code423n4 opened this issue Aug 6, 2022 · 0 comments
Open

Gas Optimizations #169

code423n4 opened this issue Aug 6, 2022 · 0 comments
Labels

Comments

@code423n4
Copy link
Contributor

[G01] Repeated Use of State Variable projectCount

Description:
The state variable projectCount is referenced 3 times without ever being modified. 3 SLOAD's can be saved by saving the return value of mintNFT() on L225 to a local variable and using that instead.

LOC:
HomeFi.sol#L225-L231

[G02] Packing State Variables

Description:
The state variable contractorDelegated can be moved up to line 70 to be packed into 1 storage slot with contractor & contractorConfirmed. This will save 1 storage slot (~20,000 gas).

LOC:
Project.sol#L78

[G03] Custom Errors

Description:
As your using a solidity version > 0.8.4 you can replace revert strings with custom errors. This will save in deployment costs and runtime costs.
Based on a test in remix, replacing a single revert string with a custom error saved 12,404 gas in deployment cost and 86 gas on each function call.

contract Test {
	uint256 a;
	function check() external {
		require(a != 0, "check failed");
	}
}   (Deployment cost: 114,703, Cost on Function call: 23,392)
vs 
contract Test {
	uint256 a;
	error checkFailed();
	function check() external {
		if (a != 0) revert checkFailed();
	}
}   (Deployment cost: 102,299, Cost on Function call: 23,306)

LOC:
Their are 74 instances of revert strings throughout the Rigor contracts that can be replaced with custom errors.

[G04] For Loop Optimisations

Description:
When incrementing i in for loops there is no chance of overflow so unchecked can be used to save gas. I ran a simple test in remix and found deployment savings of 31,653 gas and on each function call saved ~141 gas per iteration.

contract Test {
	function loopTest() external {
		for (uint256 i; i < 1; ++i) {
		Deployment Cost: 125,637, Cost on function call: 24,601
		vs
		for (uint256 i; i < 1; ) {
		// for loop body
		unchecked { ++i; }
		Deployment Cost: 93,984, Cost on function call: 24,460
		}
	}
}

In for loops pre increments can also be used to save a small amount of gas per iteration.
I ran a test in remix using a for loop and found the deployment savings of 497 gas and ~5 gas per iteration.

contract Test {
	function loopTest() external {
		for (uint256 i; i < 1; i++) {
		(Deployment cost: 118,408, Cost on function call: 24,532)
		vs
		for (uint256 i; i < 1; ++i) {
		(Deployment cost: 117,911, Cost on function call: 24,527)
		}
	}
}

It is also recommended not to loop over state variables as an SLOAD will need to be done every loop. Recommend caching to memory and looping over that instead.

LOC:
Community.sol#L624-L626
HomeFiProxy.sol#L87-L89
HomeFiProxy.sol#L136-L138
Project.sol#L248-L257
Project.sol#L311-L313
Project.sol#L322-L324
Project.sol#L368-L370
Project.sol#L603-L631
Project.sol#L650-L678
Project.sol#L710-L712
Tasks.sol#L181

[G05] x = x + y is Cheaper than x += y

Description:
Based on test in remix you can save ~1,007 gas on deployment and ~15 gas on execution cost if you use x = x + y over x += y. (Is only true for storage variables)

contract Test {
	uint256 x = 1;
	function test() external {
		x += 3; 
		(Deployment Cost: 153,124, Execution Cost: 30,369)
		vs
		x = x + 1;
		(Deployment Cost: 152,117, Execution Cost: 30,354)
	}

}

LOC:
Community.sol#L423
Community.sol#L433
HomeFi.sol#L289
Project.sol#L179
Project.sol#L290
Project.sol#L440

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Aug 6, 2022
code423n4 added a commit that referenced this issue Aug 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants