stylus_core/calls/mod.rs
1// Copyright 2025-2026, Offchain Labs, Inc.
2// For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/licenses/COPYRIGHT.md
3
4use alloy_primitives::{Address, U256};
5
6pub mod context;
7pub mod errors;
8
9/// Trait for accessing a safe API for calling other contracts.
10/// Its implementation should have reentrancy awareness and protections depending
11/// on the SDK configuration.
12pub trait CallAccess {
13 /// Static calls the contract at the given address.
14 fn static_call(
15 &self,
16 context: &dyn StaticCallContext,
17 to: Address,
18 data: &[u8],
19 ) -> Result<Vec<u8>, errors::Error>;
20 /// Delegate calls the contract at the given address.
21 ///
22 /// # Safety
23 ///
24 /// A delegate call must trust the other contract to uphold safety requirements.
25 /// Though this function clears any cached values, the other contract may arbitrarily change storage,
26 /// spend ether, and do other things one should never blindly allow other contracts to do.
27 unsafe fn delegate_call(
28 &self,
29 context: &dyn MutatingCallContext,
30 to: Address,
31 data: &[u8],
32 ) -> Result<Vec<u8>, errors::Error>;
33 /// Calls the contract at the given address.
34 fn call(
35 &self,
36 context: &dyn MutatingCallContext,
37 to: Address,
38 data: &[u8],
39 ) -> Result<Vec<u8>, errors::Error>;
40}
41
42/// Trait for transferring ETH.
43pub trait ValueTransfer {
44 #[cfg(feature = "reentrant")]
45 /// Transfers an amount of ETH in wei to the given account.
46 /// Note that this method will call the other contract, which may in turn call others.
47 ///
48 /// All gas is supplied, which the recipient may burn.
49 /// If this is not desired, the [`call`] method on the CallAccess trait may be used directly.
50 fn transfer_eth(
51 &self,
52 storage: &mut dyn crate::storage::TopLevelStorage,
53 to: Address,
54 amount: U256,
55 ) -> Result<(), Vec<u8>>;
56 #[cfg(not(feature = "reentrant"))]
57 /// Transfers an amount of ETH in wei to the given account.
58 /// Note that this method will call the other contract, which may in turn call others.
59 ///
60 /// All gas is supplied, which the recipient may burn.
61 /// If this is not desired, the [`call`] method on the CallAccess trait may be used directly.
62 fn transfer_eth(&self, to: Address, amount: U256) -> Result<(), Vec<u8>>;
63}
64
65/// Trait for calling other contracts.
66/// Users should rarely implement this trait outside of proc macros.
67pub trait CallContext {
68 /// Amount of gas to supply the call.
69 /// Note: values are clipped to the amount of gas remaining.
70 fn gas(&self) -> u64;
71}
72
73/// Trait for calling the `view` methods of other contracts.
74/// Users should rarely implement this trait outside of proc macros.
75pub trait StaticCallContext: CallContext {}
76
77/// Trait for calling the mutable methods of other contracts.
78/// Users should rarely implement this trait outside of proc macros.
79///
80/// # Safety
81///
82/// The type must contain a [`TopLevelStorage`][TLS] to prevent aliasing in cases of reentrancy.
83///
84/// [TLS]: stylus_core::storage::TopLevelStorage
85pub unsafe trait MutatingCallContext: CallContext {
86 /// Amount of ETH in wei to give the other contract.
87 fn value(&self) -> U256;
88}
89
90/// Trait for calling the `write` methods of other contracts.
91/// Users should rarely implement this trait outside of proc macros.
92///
93/// Note: any implementations of this must return zero for [`MutatingCallContext::value`].
94pub trait NonPayableCallContext: MutatingCallContext {}