Smart Contract Gas Optimization
We were approached by a DeFi project: deploying their ERC-1155 contract cost 0.8 ETH instead of the expected 0.3. Users were paying $15 per transfer() at 30 gwei gas price, while competitors paid $4. The cause was poor storage layout and suboptimal patterns that the Solidity compiler doesn't fix for you. We conducted a gas audit and reduced deployment cost by 62%, and transaction costs by 3x, saving the project over $50,000 in user fees annually. Our experience optimizing 50+ contracts shows that 80% of losses are eliminated by proper storage architecture. Every extra SLOAD or SSTORE operation multiplies across thousands of calls. In this article, we'll cover specific patterns that save 30-50% on typical contracts.
Why Storage Is the Main Source of Gas Loss
SSTORE costs 20,000 gas when writing to a cold slot, 2,900 gas when updating a warm one. SLOAD costs 2,100 gas for cold, 100 for warm (per EIP-2929). That's why storage architecture determines 60-80% of a contract's cost.
Slot packing is the first tool. The EVM stores data in 32-byte slots. If you declare variables like this:
// Bad: 3 slots
uint128 a;
uint256 b;
uint128 c;
// Good: 2 slots (a and c packed)
uint128 a;
uint128 c;
uint256 b;
This saves two SLOADs on read. On a contract with 10,000 deployments, the savings total hundreds of ETH.
Storage Operation Gas Costs
| Operation | Gas (cold) | Gas (warm) |
|---|---|---|
| SLOAD | 2100 | 100 |
| SSTORE (new) | 20000 | 20000 |
| SSTORE (update) | 2900 | 2900 |
| BALANCE | 2600 | 100 |
These aren't just numbers—knowing them lets you choose between reading from storage and computing.
How to Find Bottlenecks in Your Contract
Analysis Tools
| Tool | What It Shows |
|---|---|
| Hardhat Gas Reporter | Gas per function call in tests |
Foundry forge test --gas-report |
Same, but faster with diff between commits |
eth-gas-reporter |
Opcode breakdown via --verbose |
| Tenderly Gas Profiler | EVM trace breakdown of real transactions |
| Remix Gas Estimation | Quick check without setup |
Foundry is our preferred choice. forge snapshot creates a .gas-snapshot file that can be committed and tracked in CI:
forge snapshot
# change code
forge snapshot --diff
Differences are shown line by line per function.
Mappings vs Arrays
mapping(uint256 => address) is O(1) access, gas-efficient. address[] with value lookup is O(n) and an architecture mistake 99% of the time. If iteration is needed, index via events and read off-chain through The Graph.
Unobvious Source: keccak256 on Short Strings
string memory name in a function called thousands of times incurs ABI encoding overhead. Replacing strings with bytes32 constants where strings are known upfront saves 200-500 gas per call.
Specific Optimization Patterns
Custom Errors Instead of require with Strings
// Before: 24,000 gas to deploy one string
require(amount > 0, "Amount must be positive");
// After: ~200 gas saved per revert + smaller bytecode
error AmountZero();
if (amount == 0) revert AmountZero();
Custom errors (EIP-838) became standard with Solidity 0.8.4. Strings in require are bytecode that increases deployment cost and revert cost.
Unchecked Arithmetic
Since Solidity 0.8.0, all arithmetic operations check for overflow by default. The check costs ~100 gas per operation. Where overflow is mathematically impossible:
unchecked {
++i; // in for loop – standard pattern
total += amounts[i]; // if sums are bounded and validated above
}
On a loop of 100 iterations, that saves 10,000+ gas.
Immutable and Constant
constant values are inlined into bytecode—no SLOAD needed. immutable values are written into bytecode at deploy time, read as PUSH32. Both are ~3x cheaper than reading from storage. Token addresses, fee basis points, owner addresses in non-upgradeable contracts—all candidates for immutable.
Calldata vs Memory for Input Parameters
// memory – copies data to memory
function process(uint256[] memory ids) external
// calldata – reads directly from calldata, no copy
function process(uint256[] calldata ids) external
For external functions that only read data, calldata is cheaper. The difference grows with array size: for an array of 50 elements, it's 3,000-5,000 gas.
What Our Gas Optimization Service Includes
- Baseline audit: run all tests with
forge test --gas-report, record baseline. No changes without before/after measurements. - Profiling via Tenderly: take real mainnet transactions (if already deployed) or simulate in Tenderly fork. See breakdown by EVM opcodes.
- Iterative optimization: apply changes one at a time, measure. Slot packing usually gives the biggest effect—we start there.
- Regression testing:
forge snapshotin CI. Any PR that increases gas by more than 1% requires justification. - Documentation and report: record all changes, savings per function, recommendations for ongoing maintenance.
Example: Savings from storage packing
Contract with 1,000,000 `mint` calls using 3 slots instead of 2: each extra SLOAD costs 100 gas (warm) or 2100 (cold). At 30 gwei, savings range from a few hundred dollars.Our Process
- Analysis: audit current contract, analyze gas profile.
- Design: identify patterns that will yield the biggest savings.
- Implementation: modify code, write tests.
- Testing: regression, stress test, deploy to testnet.
- Deployment: deploy optimized contract, migrate data (if needed).
Timeline Estimates
Gas audit of existing contract + report with recommendations: 1-2 days. Optimization with implementation and testing: 2-3 days depending on contract complexity. Full storage layout redesign (if architecture is initially suboptimal): from 1 week, as it requires migration scripts for existing data.
Cost is determined after analyzing the contract and current gas profile. Typical audit costs range from $5,000 to $15,000 depending on complexity, with guaranteed 20-50% gas reduction on key functions.
What's Included in the Work
- Detailed gas audit report with breakdown per function
- Optimized smart contract code with diff from original
- Test suite covering regressions and gas savings
- Deployment scripts and migration support (if needed)
- Access to our gas monitoring dashboard via Tenderly
- Training session for your team on best practices
- 30 days of post-deployment support
Why Choose Us?
- Over 5 years of experience developing smart contracts in Solidity, Rust, and Vyper.
- Performed audits and optimizations for 30+ DeFi projects, including protocols with TVL > $50M.
- Guarantee 20-50% gas reduction on key functions.
- Work with contracts on Ethereum, Polygon, Arbitrum, Optimism, Base, Solana, BNB Chain.
Our gas optimization service focuses on storage packing to achieve gas savings. If you're looking to reduce transaction costs and save on deployment, contact us for a free preliminary assessment. Get an engineer's consultation—we'll determine the optimization potential in 1 hour.
Note: Memory expansion costs linearly with data size due to the quadratic gas cost formula (G_memory + expansion_cost). Understanding this helps in choosing the right data location for variables to minimize gas overhead.







