Skip to content
2 changes: 1 addition & 1 deletion crates/chainspec/src/hardfork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ hardfork!(

impl TempoHardfork {
/// Returns `true` if this hardfork is Moderato or later.
#[inline]
pub fn is_moderato(self) -> bool {
self >= Self::Moderato
}
Expand Down Expand Up @@ -144,7 +145,6 @@ mod tests {
#[test]
fn test_is_moderato() {
assert!(!TempoHardfork::Adagio.is_moderato());

assert!(TempoHardfork::Moderato.is_moderato());
}

Expand Down
16 changes: 15 additions & 1 deletion crates/precompiles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
nonce::NonceManager,
path_usd::PathUSD,
stablecoin_exchange::StablecoinExchange,
storage::evm::EvmPrecompileStorageProvider,
storage::{PrecompileStorageProvider, evm::EvmPrecompileStorageProvider},
tip_account_registrar::TipAccountRegistrar,
tip_fee_manager::TipFeeManager,
tip20::{TIP20Token, address_to_token_id_unchecked, is_tip20},
Expand Down Expand Up @@ -277,6 +277,20 @@ fn mutate_void<T: SolCall>(
f(sender, call).into_precompile_result(0, |()| Bytes::new())
}

#[inline]
fn fill_precompile_output(
mut output: PrecompileOutput,
storage: &mut impl PrecompileStorageProvider,
) -> PrecompileOutput {
output.gas_used = storage.gas_used();

// add refund only if it is not reverted
if !output.reverted && storage.spec().is_allegretto() {
output.gas_refunded = storage.gas_refunded();
}
output
}

/// Helper function to return an unknown function selector error
///
/// Before Moderato: Returns a generic PrecompileError::Other
Expand Down
9 changes: 3 additions & 6 deletions crates/precompiles/src/nonce/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
Precompile, input_cost, nonce::NonceManager, storage::PrecompileStorageProvider,
unknown_selector, view,
Precompile, fill_precompile_output, input_cost, nonce::NonceManager,
storage::PrecompileStorageProvider, unknown_selector, view,
};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};
Expand Down Expand Up @@ -33,10 +33,7 @@ impl<S: PrecompileStorageProvider> Precompile for NonceManager<'_, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
7 changes: 2 additions & 5 deletions crates/precompiles/src/path_usd/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
Precompile, input_cost, metadata, mutate, mutate_void,
Precompile, fill_precompile_output, input_cost, metadata, mutate, mutate_void,
path_usd::PathUSD,
storage::{ContractStorage, PrecompileStorageProvider},
tip20::{IRolesAuth, ITIP20},
Expand Down Expand Up @@ -218,10 +218,7 @@ impl<S: PrecompileStorageProvider> Precompile for PathUSD<'_, S> {
_ => Err(PrecompileError::Other("Unknown selector".into())),
};

result.map(|mut res| {
res.gas_used = self.token.storage().gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.token.storage()))
}
}

Expand Down
7 changes: 2 additions & 5 deletions crates/precompiles/src/stablecoin_exchange/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};

use crate::{
Precompile, input_cost, mutate, mutate_void,
Precompile, fill_precompile_output, input_cost, mutate, mutate_void,
stablecoin_exchange::{IStablecoinExchange, StablecoinExchange},
storage::PrecompileStorageProvider,
unknown_selector, view,
Expand Down Expand Up @@ -183,10 +183,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for StablecoinExchange<'a, S>
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
18 changes: 18 additions & 0 deletions crates/precompiles/src/storage/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct EvmPrecompileStorageProvider<'a> {
internals: EvmInternals<'a>,
chain_id: u64,
gas_remaining: u64,
gas_refunded: i64,
gas_limit: u64,
spec: TempoHardfork,
}
Expand All @@ -29,6 +30,7 @@ impl<'a> EvmPrecompileStorageProvider<'a> {
internals,
chain_id,
gas_remaining: gas_limit,
gas_refunded: 0,
gas_limit,
spec,
}
Expand Down Expand Up @@ -103,6 +105,12 @@ impl<'a> PrecompileStorageProvider for EvmPrecompileStorageProvider<'a> {
result.is_cold,
))?;

// refund gas.
self.refund_gas(revm::interpreter::gas::sstore_refund(
SpecId::AMSTERDAM,
&result.data,
));

Ok(())
}

Expand Down Expand Up @@ -165,11 +173,21 @@ impl<'a> PrecompileStorageProvider for EvmPrecompileStorageProvider<'a> {
Ok(())
}

#[inline]
fn refund_gas(&mut self, gas: i64) {
self.gas_refunded = self.gas_refunded.saturating_add(gas);
}

#[inline]
fn gas_used(&self) -> u64 {
self.gas_limit - self.gas_remaining
}

#[inline]
fn gas_refunded(&self) -> i64 {
self.gas_refunded
}

#[inline]
fn spec(&self) -> TempoHardfork {
self.spec
Expand Down
8 changes: 8 additions & 0 deletions crates/precompiles/src/storage/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,18 @@ impl PrecompileStorageProvider for HashMapStorageProvider {
Ok(())
}

fn refund_gas(&mut self, _gas: i64) {
// No-op
}

fn gas_used(&self) -> u64 {
0
}

fn gas_refunded(&self) -> i64 {
0
}

fn spec(&self) -> TempoHardfork {
self.spec
}
Expand Down
6 changes: 6 additions & 0 deletions crates/precompiles/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,15 @@ pub trait PrecompileStorageProvider {
/// Deducts gas from the remaining gas and return an error if the gas is insufficient.
fn deduct_gas(&mut self, gas: u64) -> Result<(), TempoPrecompileError>;

/// Add refund to the refund gas counter.
fn refund_gas(&mut self, gas: i64);

/// Returns the gas used so far.
fn gas_used(&self) -> u64;

/// Returns the gas refunded so far.
fn gas_refunded(&self) -> i64;

/// Currently active hardfork.
fn spec(&self) -> TempoHardfork;
}
Expand Down
7 changes: 2 additions & 5 deletions crates/precompiles/src/tip20/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::ITIP20;
use crate::{
Precompile, input_cost, metadata, mutate, mutate_void,
Precompile, fill_precompile_output, input_cost, metadata, mutate, mutate_void,
storage::PrecompileStorageProvider,
tip20::{IRolesAuth, TIP20Token},
unknown_selector, view,
Expand Down Expand Up @@ -251,10 +251,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TIP20Token<'a, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
9 changes: 4 additions & 5 deletions crates/precompiles/src/tip20_factory/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{Precompile, input_cost, mutate, tip20::is_tip20, unknown_selector, view};
use crate::{
Precompile, fill_precompile_output, input_cost, mutate, tip20::is_tip20, unknown_selector, view,
};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};

Expand Down Expand Up @@ -36,10 +38,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TIP20Factory<'a, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
7 changes: 2 additions & 5 deletions crates/precompiles/src/tip20_rewards_registry/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Precompile, input_cost, mutate_void, unknown_selector};
use crate::{Precompile, fill_precompile_output, input_cost, mutate_void, unknown_selector};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};
use tempo_contracts::precompiles::ITIP20RewardsRegistry;
Expand Down Expand Up @@ -30,10 +30,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TIP20RewardsRegistry<'a, S
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
9 changes: 4 additions & 5 deletions crates/precompiles/src/tip403_registry/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{Precompile, input_cost, mutate, mutate_void, unknown_selector, view};
use crate::{
Precompile, fill_precompile_output, input_cost, mutate, mutate_void, unknown_selector, view,
};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};

Expand Down Expand Up @@ -69,10 +71,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TIP403Registry<'a, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
10 changes: 5 additions & 5 deletions crates/precompiles/src/tip_account_registrar/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{Precompile, input_cost, mutate, storage::PrecompileStorageProvider, unknown_selector};
use crate::{
Precompile, fill_precompile_output, input_cost, mutate, storage::PrecompileStorageProvider,
unknown_selector,
};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};

Expand Down Expand Up @@ -46,10 +49,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TipAccountRegistrar<'a, S>
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
7 changes: 2 additions & 5 deletions crates/precompiles/src/tip_fee_manager/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
Precompile,
error::TempoPrecompileError,
input_cost, mutate, mutate_void,
fill_precompile_output, input_cost, mutate, mutate_void,
storage::PrecompileStorageProvider,
tip_fee_manager::{IFeeManager, ITIPFeeAMM, TipFeeManager, amm::MIN_LIQUIDITY},
unknown_selector, view,
Expand Down Expand Up @@ -153,10 +153,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for TipFeeManager<'a, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
8 changes: 3 additions & 5 deletions crates/precompiles/src/validator_config/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{IValidatorConfig, ValidatorConfig};
use crate::{
Precompile, input_cost, mutate_void, storage::PrecompileStorageProvider, unknown_selector, view,
Precompile, fill_precompile_output, input_cost, mutate_void,
storage::PrecompileStorageProvider, unknown_selector, view,
};
use alloy::{primitives::Address, sol_types::SolCall};
use revm::precompile::{PrecompileError, PrecompileResult};
Expand Down Expand Up @@ -61,10 +62,7 @@ impl<'a, S: PrecompileStorageProvider> Precompile for ValidatorConfig<'a, S> {
_ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
};

result.map(|mut res| {
res.gas_used = self.storage.gas_used();
res
})
result.map(|res| fill_precompile_output(res, self.storage))
}
}

Expand Down
Loading