From 8671650478da23020e06028845511063732800ea Mon Sep 17 00:00:00 2001 From: Jack Lee <280147597@qq.com> Date: Wed, 6 Nov 2024 16:21:09 +0700 Subject: [PATCH 1/3] add useSUBorXOR.md --- .../gas-optimization/useSUBorXOR.md | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md diff --git a/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md new file mode 100644 index 0000000000..a8ed086d73 --- /dev/null +++ b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md @@ -0,0 +1,138 @@ +--- +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.0; + +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 + +#### SUB (Subtraction) +- Best for comparing numerical values or addresses +- Clearer intention in code +- No risk of bit-flip issues + +```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 + +```solidity +assembly { + // Warning: XOR considers a value with all bits flipped as equal + if xor(caller(), sload(owner.slot)) { + revert(0, 0) + } +} +``` + +### Security Considerations + +⚠️ **XOR Vulnerability** +When using XOR for comparisons, be aware that it will consider a value with all bits flipped to be equal: +```solidity +A ⊕ B = 0 // Equal values +A ⊕ (NOT A) = 0 // Also considered equal! +``` + +### Best Practices + +1. **Choose the Right Operation** + - Use SUB for general equality checks + - Use XOR only when bit manipulation is specifically needed + - Consider readability vs gas savings + +2. **Security First** + - Avoid XOR for security-critical comparisons + - Document the reason for using SUB/XOR over ISZERO(EQ) + - Always test thoroughly with different inputs + +3. **Context Matters** + - Consider compiler optimizations + - Test gas costs in your specific context + - Balance minimal gas savings against code clarity + +### 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 + +**Warning**: Always verify that gas savings are meaningful in your specific context, as compiler optimizations might affect the actual benefits. + +#### Gas Optimization Tips + +🌟 For optimal results: +- Use SUB for most equality checks +- Avoid XOR unless specifically needed for bitwise operations +- Test gas costs with different compiler versions +- Document your optimization choices clearly From 49f5b776d8ba0d6c72d50dec090ae6eb4f15059e Mon Sep 17 00:00:00 2001 From: Jack Lee <280147597@qq.com> Date: Mon, 9 Dec 2024 23:07:02 +0800 Subject: [PATCH 2/3] update content --- .../gas-optimization/useSUBorXOR.md | 42 ++++--------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md index a8ed086d73..d1f3cddc00 100644 --- a/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md +++ b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md @@ -61,10 +61,16 @@ contract ComparisonExample { ### 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 { @@ -79,42 +85,16 @@ assembly { - 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 { - // Warning: XOR considers a value with all bits flipped as equal if xor(caller(), sload(owner.slot)) { revert(0, 0) } } ``` -### Security Considerations - -⚠️ **XOR Vulnerability** -When using XOR for comparisons, be aware that it will consider a value with all bits flipped to be equal: -```solidity -A ⊕ B = 0 // Equal values -A ⊕ (NOT A) = 0 // Also considered equal! -``` - -### Best Practices - -1. **Choose the Right Operation** - - Use SUB for general equality checks - - Use XOR only when bit manipulation is specifically needed - - Consider readability vs gas savings - -2. **Security First** - - Avoid XOR for security-critical comparisons - - Document the reason for using SUB/XOR over ISZERO(EQ) - - Always test thoroughly with different inputs - -3. **Context Matters** - - Consider compiler optimizations - - Test gas costs in your specific context - - Balance minimal gas savings against code clarity - ### When to Use This Optimization ✅ **Recommended for:** @@ -127,12 +107,6 @@ A ⊕ (NOT A) = 0 // Also considered equal! - Complex comparison logic - When code clarity is paramount -**Warning**: Always verify that gas savings are meaningful in your specific context, as compiler optimizations might affect the actual benefits. - #### Gas Optimization Tips -🌟 For optimal results: -- Use SUB for most equality checks -- Avoid XOR unless specifically needed for bitwise operations -- Test gas costs with different compiler versions -- Document your optimization choices clearly +🌟 Use SUB for equality checks to save gas, avoid XOR unless necessary for bitwise operations, and ensure to document your optimization decisions clearly. From 8ab356c8d5ef251156a26f7725b4e715bd10f9f6 Mon Sep 17 00:00:00 2001 From: Jack Lee <280147597@qq.com> Date: Mon, 9 Dec 2024 23:07:15 +0800 Subject: [PATCH 3/3] update content --- .../build/smart-contracts/gas-optimization/useSUBorXOR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md index d1f3cddc00..fa4840bbed 100644 --- a/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md +++ b/docs/general/build/smart-contracts/gas-optimization/useSUBorXOR.md @@ -12,7 +12,7 @@ Here's a comparison showing different approaches: ```solidity // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; contract ComparisonExample { address public owner;