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

Add Using SUB or XOR Instead of ISZERO(EQ) #812

Merged
merged 3 commits into from
Dec 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
displayed_sidebar: generalSidebar
---

# Using SUB or XOR Instead of ISZERO(EQ)

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.

### Standard EQ vs SUB/XOR Comparison

Here's a comparison showing different approaches:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract ComparisonExample {
address public owner;

constructor() {
owner = msg.sender;
}

// Standard EQ approach
function checkOwnerEQ() external view {
assembly {
if iszero(eq(caller(), sload(owner.slot))) {
revert(0, 0)
}
}
}

// Optimized SUB approach
function checkOwnerSUB() external view {
assembly {
if sub(caller(), sload(owner.slot)) {
revert(0, 0)
}
}
}

// Alternative XOR approach
function checkOwnerXOR() external view {
assembly {
if xor(caller(), sload(owner.slot)) {
revert(0, 0)
}
}
}
}
```

### Gas Comparison

| Implementation | Gas Cost (Approximate) |
| ----------------- | --------------------- |
| ISZERO(EQ) | ~22 gas |
| SUB | ~20 gas |
| XOR | ~20 gas |
| Potential Savings | ~2 gas per check |

### When to Use Each Approach

#### ISZERO(EQ)
- Standard approach for equality checks
- Clear and straightforward
- Slightly higher gas cost compared to SUB and XOR

#### SUB (Subtraction)
- Best for comparing numerical values or addresses
- Clearer intention in code
- No risk of bit-flip issues
- Slightly more gas efficient than ISZERO(EQ)

```solidity
assembly {
// Reverts if caller is not owner
if sub(caller(), sload(owner.slot)) {
revert(0, 0)
}
}
```

#### XOR (Exclusive OR)
- Slightly more efficient for bitwise operations
- Must be used carefully due to bit-flip vulnerability
- Not recommended for security-critical comparisons
- Slightly more gas efficient than ISZERO(EQ)

```solidity
assembly {
if xor(caller(), sload(owner.slot)) {
revert(0, 0)
}
}
```

### When to Use This Optimization

✅ **Recommended for:**
- High-frequency equality checks
- Gas-critical loops or functions
- Simple numerical or address comparisons

❌ **Not recommended for:**
- Security-critical comparisons (when using XOR)
- Complex comparison logic
- When code clarity is paramount

#### Gas Optimization Tips

🌟 Use SUB for equality checks to save gas, avoid XOR unless necessary for bitwise operations, and ensure to document your optimization decisions clearly.
Loading