diff --git a/zkevm-circuits/src/evm_circuit/execution/sstore.rs b/zkevm-circuits/src/evm_circuit/execution/sstore.rs index 6280dcb70b..daf3f99847 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sstore.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sstore.rs @@ -358,6 +358,10 @@ pub(crate) struct SstoreTxRefundGadget { original_eq_value: IsEqualGadget, prev_eq_value: IsEqualGadget, original_eq_prev: IsEqualGadget, + nz_nz_allne_case_refund: Cell, + nz_ne_ne_case_refund: Cell, + ez_ne_ne_case_refund: Cell, + eq_ne_case_refund: Cell, } impl SstoreTxRefundGadget { @@ -376,43 +380,50 @@ impl SstoreTxRefundGadget { let original_eq_prev = IsEqualGadget::construct(cb, committed_value.expr(), value_prev.expr()); + // original_value, value_prev, value all are different; + // original_value!=0&&value_prev!=0 + let nz_nz_allne_case_refund = cb.copy(select::expr( + value_is_zero.expr(), + tx_refund_old.expr() + GasCost::SSTORE_CLEARS_SCHEDULE.expr(), + tx_refund_old.expr(), + )); // original_value, value_prev, value all are different; original_value!=0 let nz_allne_case_refund = select::expr( value_prev_is_zero.expr(), tx_refund_old.expr() - GasCost::SSTORE_CLEARS_SCHEDULE.expr(), - select::expr( - value_is_zero.expr(), - tx_refund_old.expr() + GasCost::SSTORE_CLEARS_SCHEDULE.expr(), - tx_refund_old.expr(), - ), + nz_nz_allne_case_refund.expr(), ); // original_value!=value_prev, value_prev!=value, original_value!=0 - let nz_ne_ne_case_refund = select::expr( + let nz_ne_ne_case_refund = cb.copy(select::expr( not::expr(original_eq_value.expr()), nz_allne_case_refund.expr(), nz_allne_case_refund.expr() + GasCost::SSTORE_RESET_GAS.expr() - GasCost::SLOAD_GAS.expr(), - ); + )); + // original_value!=value_prev, value_prev!=value, original_value==0 + let ez_ne_ne_case_refund = cb.copy(select::expr( + original_eq_value.expr(), + tx_refund_old.expr() + GasCost::SSTORE_SET_GAS.expr() - GasCost::SLOAD_GAS.expr(), + tx_refund_old.expr(), + )); // original_value!=value_prev, value_prev!=value let ne_ne_case_refund = select::expr( not::expr(original_is_zero.expr()), nz_ne_ne_case_refund.expr(), - select::expr( - original_eq_value.expr(), - tx_refund_old.expr() + GasCost::SSTORE_SET_GAS.expr() - GasCost::SLOAD_GAS.expr(), - tx_refund_old.expr(), - ), + ez_ne_ne_case_refund.expr(), ); + // original_value==value_prev, value_prev!=value + let eq_ne_case_refund = cb.copy(select::expr( + not::expr(original_is_zero.expr()) * value_is_zero.expr(), + tx_refund_old.expr() + GasCost::SSTORE_CLEARS_SCHEDULE.expr(), + tx_refund_old.expr(), + )); let tx_refund_new = select::expr( prev_eq_value.expr(), tx_refund_old.expr(), select::expr( original_eq_prev.expr(), - select::expr( - not::expr(original_is_zero.expr()) * value_is_zero.expr(), - tx_refund_old.expr() + GasCost::SSTORE_CLEARS_SCHEDULE.expr(), - tx_refund_old.expr(), - ), + eq_ne_case_refund.expr(), ne_ne_case_refund.expr(), ), ); @@ -429,6 +440,10 @@ impl SstoreTxRefundGadget { original_eq_value, prev_eq_value, original_eq_prev, + nz_nz_allne_case_refund, + nz_ne_ne_case_refund, + ez_ne_ne_case_refund, + eq_ne_case_refund, } } @@ -504,6 +519,48 @@ impl SstoreTxRefundGadget { Word::random_linear_combine(committed_value.to_le_bytes(), randomness), Word::random_linear_combine(value_prev.to_le_bytes(), randomness), )?; + + let nz_nz_allne_case_refund = if value == eth_types::Word::zero() { + tx_refund_old + GasCost::SSTORE_CLEARS_SCHEDULE.as_u64() + } else { + tx_refund_old + }; + self.nz_nz_allne_case_refund.assign( + region, + offset, + Some(F::from(nz_nz_allne_case_refund)), + )?; + + let nz_allne_case_refund = if value_prev == eth_types::Word::zero() { + tx_refund_old - GasCost::SSTORE_CLEARS_SCHEDULE.as_u64() + } else { + nz_nz_allne_case_refund + }; + let nz_ne_ne_case_refund = if committed_value != value { + nz_allne_case_refund + } else { + nz_allne_case_refund + GasCost::SSTORE_RESET_GAS.as_u64() - GasCost::SLOAD_GAS.as_u64() + }; + self.nz_ne_ne_case_refund + .assign(region, offset, Some(F::from(nz_ne_ne_case_refund)))?; + + let ez_ne_ne_case_refund = if committed_value == value { + tx_refund_old + GasCost::SSTORE_SET_GAS.as_u64() - GasCost::SLOAD_GAS.as_u64() + } else { + tx_refund_old + }; + self.ez_ne_ne_case_refund + .assign(region, offset, Some(F::from(ez_ne_ne_case_refund)))?; + + let eq_ne_case_refund = + if (committed_value != eth_types::Word::zero()) && (value == eth_types::Word::zero()) { + tx_refund_old + GasCost::SSTORE_CLEARS_SCHEDULE.as_u64() + } else { + tx_refund_old + }; + self.eq_ne_case_refund + .assign(region, offset, Some(F::from(eq_ne_case_refund)))?; + Ok(()) } }