Skip to content

Commit 550c238

Browse files
authored
Add Using SUB or XOR Instead of ISZERO(EQ) (#812)
* add useSUBorXOR.md * update content * update content
1 parent f6fc06f commit 550c238

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
displayed_sidebar: generalSidebar
3+
---
4+
5+
# Using SUB or XOR Instead of ISZERO(EQ)
6+
7+
When optimizing gas usage in Ethereum smart contracts, comparison operations in assembly can be optimized by using SUB or XOR instead of ISZERO(EQ). This optimization can lead to gas savings in specific scenarios, particularly for equality checks.
8+
9+
### Standard EQ vs SUB/XOR Comparison
10+
11+
Here's a comparison showing different approaches:
12+
13+
```solidity
14+
// SPDX-License-Identifier: MIT
15+
pragma solidity ^0.8.24;
16+
17+
contract ComparisonExample {
18+
address public owner;
19+
20+
constructor() {
21+
owner = msg.sender;
22+
}
23+
24+
// Standard EQ approach
25+
function checkOwnerEQ() external view {
26+
assembly {
27+
if iszero(eq(caller(), sload(owner.slot))) {
28+
revert(0, 0)
29+
}
30+
}
31+
}
32+
33+
// Optimized SUB approach
34+
function checkOwnerSUB() external view {
35+
assembly {
36+
if sub(caller(), sload(owner.slot)) {
37+
revert(0, 0)
38+
}
39+
}
40+
}
41+
42+
// Alternative XOR approach
43+
function checkOwnerXOR() external view {
44+
assembly {
45+
if xor(caller(), sload(owner.slot)) {
46+
revert(0, 0)
47+
}
48+
}
49+
}
50+
}
51+
```
52+
53+
### Gas Comparison
54+
55+
| Implementation | Gas Cost (Approximate) |
56+
| ----------------- | --------------------- |
57+
| ISZERO(EQ) | ~22 gas |
58+
| SUB | ~20 gas |
59+
| XOR | ~20 gas |
60+
| Potential Savings | ~2 gas per check |
61+
62+
### When to Use Each Approach
63+
64+
#### ISZERO(EQ)
65+
- Standard approach for equality checks
66+
- Clear and straightforward
67+
- Slightly higher gas cost compared to SUB and XOR
68+
69+
#### SUB (Subtraction)
70+
- Best for comparing numerical values or addresses
71+
- Clearer intention in code
72+
- No risk of bit-flip issues
73+
- Slightly more gas efficient than ISZERO(EQ)
74+
75+
```solidity
76+
assembly {
77+
// Reverts if caller is not owner
78+
if sub(caller(), sload(owner.slot)) {
79+
revert(0, 0)
80+
}
81+
}
82+
```
83+
84+
#### XOR (Exclusive OR)
85+
- Slightly more efficient for bitwise operations
86+
- Must be used carefully due to bit-flip vulnerability
87+
- Not recommended for security-critical comparisons
88+
- Slightly more gas efficient than ISZERO(EQ)
89+
90+
```solidity
91+
assembly {
92+
if xor(caller(), sload(owner.slot)) {
93+
revert(0, 0)
94+
}
95+
}
96+
```
97+
98+
### When to Use This Optimization
99+
100+
**Recommended for:**
101+
- High-frequency equality checks
102+
- Gas-critical loops or functions
103+
- Simple numerical or address comparisons
104+
105+
**Not recommended for:**
106+
- Security-critical comparisons (when using XOR)
107+
- Complex comparison logic
108+
- When code clarity is paramount
109+
110+
#### Gas Optimization Tips
111+
112+
🌟 Use SUB for equality checks to save gas, avoid XOR unless necessary for bitwise operations, and ensure to document your optimization decisions clearly.

0 commit comments

Comments
 (0)