Skip to content
Open
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion crates/precompiles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ macro_rules! tempo_precompile {
amsterdam_eip8037_enabled,
$input.is_static,
gas_params.clone(),
);
)
.with_msg_sender($input.caller);
crate::storage::StorageCtx::enter(&mut storage, || {
$impl.call($input.data, $input.caller)
})
Expand Down
4 changes: 4 additions & 0 deletions crates/precompiles/src/stablecoin_dex/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2230,6 +2230,7 @@ mod tests {
let (base_token, _) = setup_test_tokens(admin, alice, exchange.address, escrow)?;
exchange.create_pair(base_token)?;

StorageCtx.set_msg_sender(alice);
let result = exchange.place_flip(
alice,
base_token,
Expand Down Expand Up @@ -2364,6 +2365,7 @@ mod tests {

// Place same-tick flip bid FIRST so it sits at the head of the bid
// level and is the order consumed by the next swap-sell.
StorageCtx.set_msg_sender(alice);
let flip_id = exchange
.place_flip(alice, base_token, amount, true, tick, tick, false)
.expect("same-tick flip should succeed on T5");
Expand All @@ -2377,6 +2379,7 @@ mod tests {
// Bob sells exactly `amount` base, which fully consumes only the
// flip bid (FIFO) and triggers the post-fill flip into an ask at
// the same tick.
StorageCtx.set_msg_sender(bob);
exchange.swap_exact_amount_in(bob, base_token, quote_token, amount, 0)?;

// Flip bid is gone, regular bid remains untouched.
Expand Down Expand Up @@ -2881,6 +2884,7 @@ mod tests {
setup_test_tokens(admin, alice, exchange.address, expected_escrow * 2)?;
exchange.create_pair(base_token)?;

StorageCtx.set_msg_sender(alice);
let flip_order_id =
exchange.place_flip(alice, base_token, amount, true, tick, flip_tick, false)?;

Expand Down
13 changes: 13 additions & 0 deletions crates/precompiles/src/storage/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct EvmPrecompileStorageProvider<'a> {
amsterdam_eip8037_enabled: bool,
is_static: bool,
gas_params: GasParams,
msg_sender: Option<Address>,
/// Debug-only LIFO checkpoint validator. See [`Self::assert_lifo`].
#[cfg(debug_assertions)]
checkpoint_stack: Vec<(usize, usize)>,
Expand All @@ -45,6 +46,7 @@ impl<'a> EvmPrecompileStorageProvider<'a> {
gas_params,
#[cfg(debug_assertions)]
checkpoint_stack: Vec::new(),
msg_sender: None,
}
}

Expand Down Expand Up @@ -86,6 +88,12 @@ impl<'a> EvmPrecompileStorageProvider<'a> {
}
Ok(())
}

/// Sets the `msg.sender`.
pub fn with_msg_sender(mut self, msg_sender: Address) -> Self {
self.msg_sender = Some(msg_sender);
self
}
}

impl<'a> PrecompileStorageProvider for EvmPrecompileStorageProvider<'a> {
Expand Down Expand Up @@ -349,6 +357,11 @@ impl<'a> PrecompileStorageProvider for EvmPrecompileStorageProvider<'a> {
self.assert_lifo(&checkpoint, "revert");
self.internals.checkpoint_revert(checkpoint)
}

#[inline]
fn msg_sender(&self) -> Option<Address> {
self.msg_sender
}
}

/// LIFO checkpoint validation (debug builds only).
Expand Down
11 changes: 11 additions & 0 deletions crates/precompiles/src/storage/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct HashMapStorageProvider {
counter_sload: u64,
counter_sstore: u64,
snapshots: Vec<Snapshot>,
msg_sender: Option<Address>,

/// Emitted events keyed by contract address.
pub events: HashMap<Address, Vec<LogData>>,
Expand Down Expand Up @@ -63,6 +64,7 @@ impl HashMapStorageProvider {
.as_secs(),
),
beneficiary: Address::ZERO,
msg_sender: None,
block_number: 0,
spec,
amsterdam_eip8037_enabled: false,
Expand Down Expand Up @@ -239,6 +241,10 @@ impl PrecompileStorageProvider for HashMapStorageProvider {
self.events = snapshot.events;
}
}

fn msg_sender(&self) -> Option<Address> {
self.msg_sender
}
}

#[cfg(any(test, feature = "test-utils"))]
Expand Down Expand Up @@ -320,4 +326,9 @@ impl HashMapStorageProvider {
.into_iter()
.map(|((addr, slot), value)| (addr, slot, value))
}

/// Overrides the message sender.
pub fn set_msg_sender(&mut self, msg_sender: Address) {
self.msg_sender = Some(msg_sender);
}
}
3 changes: 3 additions & 0 deletions crates/precompiles/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ pub trait PrecompileStorageProvider {

Ok(recovered.ok().filter(|addr| !addr.is_zero()))
}

/// Returns the address of the caller of the current precompile invocation.
fn msg_sender(&self) -> Option<Address>;
}

/// Storage operations for a given (contract) address.
Expand Down
10 changes: 10 additions & 0 deletions crates/precompiles/src/storage/thread_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ impl StorageCtx {
Self::try_with_storage(|storage| storage.recover_signer(digest, v, r, s))
}

/// Returns the address of the caller of the current precompile invocation.
pub fn msg_sender(&self) -> Option<Address> {
Self::with_storage(|storage| storage.msg_sender())
}

/// Returns a [`PrecompileOutput`] with [`revm::precompile::PrecompileStatus::Success`] and the current gas values.
pub fn success_output(&self, output: Bytes) -> PrecompileOutput {
PrecompileOutput::new(self.gas_used(), output, self.reservoir())
Expand Down Expand Up @@ -452,6 +457,11 @@ impl StorageCtx {
self.as_hashmap().set_spec(spec)
}

/// NOTE: assumes storage tests always use the `HashMapStorageProvider`
pub fn set_msg_sender(&mut self, msg_sender: Address) {
self.as_hashmap().set_msg_sender(msg_sender)
}

/// NOTE: assumes storage tests always use the `HashMapStorageProvider`
pub fn clear_transient(&mut self) {
self.as_hashmap().clear_transient()
Expand Down
6 changes: 6 additions & 0 deletions crates/precompiles/src/tip20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,10 @@ impl TIP20Token {
return Err(TIP20Error::unauthorized().into());
}

if self.storage.msg_sender() != Some(from) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an assert?

return Err(TIP20Error::unauthorized().into());
}

let to = Recipient::resolve(caller)?;
self.validate_transfer(from, &to)?;
self.check_and_update_spending_limit(from, amount)?;
Expand Down Expand Up @@ -1843,6 +1847,7 @@ pub(crate) mod tests {
.apply()?;

// Pre-T5: caller is unchecked (preserves pre-TIP-1035 FeeAMM behavior).
StorageCtx.set_msg_sender(from);
assert!(token.system_transfer_from(to, from, amount).is_ok());
assert_eq!(
token.emitted_events().last().unwrap(),
Expand All @@ -1867,6 +1872,7 @@ pub(crate) mod tests {
.apply()?;

// Listed precompile is allowed to invoke `system_transfer_from`.
StorageCtx.set_msg_sender(from);
assert!(
token
.system_transfer_from(TIP_FEE_MANAGER_ADDRESS, from, amount)
Expand Down
11 changes: 11 additions & 0 deletions crates/precompiles/src/tip_fee_manager/amm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ mod tests {

let mut amm = TipFeeManager::new();
let amount = uint!(10000_U256);
StorageCtx.set_msg_sender(admin);
let result = amm.mint(admin, token1, token2, amount, admin)?;
let expected_mean = amount / uint!(2_U256);
let expected_liquidity = expected_mean - MIN_LIQUIDITY;
Expand Down Expand Up @@ -1162,6 +1163,7 @@ mod tests {
let amount_out = uint!(1000_U256);
let expected_in = (amount_out * N) / SCALE + U256::ONE;

StorageCtx.set_msg_sender(admin);
let amount_in =
amm.rebalance_swap(admin, user_token, validator_token, amount_out, recipient)?;

Expand Down Expand Up @@ -1202,6 +1204,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let initial_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let first_liquidity =
amm.mint(admin, user_token, validator_token, initial_amount, admin)?;

Expand All @@ -1216,6 +1219,7 @@ mod tests {
let reserve_val = U256::from(pool_after_first.reserve_validator_token);

let second_amount = uint!(50000_U256);
StorageCtx.set_msg_sender(second_user);
let second_liquidity = amm.mint(
second_user,
user_token,
Expand Down Expand Up @@ -1264,6 +1268,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let deposit_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let liquidity = amm.mint(admin, user_token, validator_token, deposit_amount, admin)?;

let expected_liquidity = deposit_amount / uint!(2_U256) - MIN_LIQUIDITY;
Expand Down Expand Up @@ -1327,6 +1332,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let deposit_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let liquidity = amm.mint(admin, user_token, validator_token, deposit_amount, admin)?;

let result = amm.burn(
Expand Down Expand Up @@ -1440,6 +1446,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let deposit_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let liquidity = amm.mint(admin, user_token, validator_token, deposit_amount, admin)?;

let pool_id = amm.pool_id(user_token, validator_token);
Expand Down Expand Up @@ -1484,6 +1491,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let deposit_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let liquidity = amm.mint(admin, user_token, validator_token, deposit_amount, admin)?;

let pool_id = amm.pool_id(user_token, validator_token);
Expand Down Expand Up @@ -1529,6 +1537,7 @@ mod tests {
let amount_out = amm.check_sufficient_liquidity(pool_id, uint!(50000_U256))?;
amm.reserve_pool_liquidity(pool_id, amount_out)?;

StorageCtx.set_msg_sender(admin);
amm.rebalance_swap(admin, user_token, validator_token, uint!(5000_U256), to)?;
let pool = amm.pools[pool_id].read()?;
let reserved = amm.pending_fee_swap_reservation[pool_id].t_read()?;
Expand Down Expand Up @@ -1564,6 +1573,7 @@ mod tests {
let pool_id =
setup_pool_with_liquidity(&mut amm, user_token, validator_token, liq, liq)?;
amm.check_sufficient_liquidity(pool_id, uint!(90000_U256))?;
StorageCtx.set_msg_sender(admin);
assert!(
amm.rebalance_swap(admin, user_token, validator_token, uint!(5000_U256), to)
.is_ok()
Expand Down Expand Up @@ -1595,6 +1605,7 @@ mod tests {
let mut amm = TipFeeManager::new();

let deposit_amount = uint!(100000_U256);
StorageCtx.set_msg_sender(admin);
let liquidity = amm.mint(admin, user_token, validator_token, deposit_amount, admin)?;

let pool_id = amm.pool_id(user_token, validator_token);
Expand Down
4 changes: 4 additions & 0 deletions crates/revm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,10 @@ where
fn checkpoint_revert(&mut self, _: revm::context::journaled_state::JournalCheckpoint) {
unreachable!("'checkpoint_revert' not supported in read-only context")
}

fn msg_sender(&self) -> Option<Address> {
None
}
}

#[cfg(test)]
Expand Down
Loading