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 {}