05.15.2025|Matthias SeitzYash AtreyaArsenii KulikovJennifer ParakDani PopesGeorgios Konstantopoulos
In June 2024, we released Alloy 0.1 as the successor to ethers-rs
to offer a robust, high-performance Rust toolkit for Ethereum development. Since then, Alloy has grown to become the backbone across the tooling and infrastructure spectrum, with projects such as Reth, Foundry, Revm, and SP1 zkVM using it as a core dependency.
Today, we’re excited to release Alloy v1.0, our first stable release, reaffirming our commitment to performance, stability, and great developer experience. Alloy is a complete re-write of ethers-rs
and builds on years of experience on shipping successful tooling for the Rust Ethereum ecosystem.
Read on to learn why the best teams in the industry are using alloy.
https://x.com/gakonst/status/1905661358739521792
cargo add alloy
Check out our polished docs and the examples repository for inspiration.
Writing performant and state of the art code is not enough. Documentation should be equally good. In lieu of this we have completely revamped the alloy docs by dropping the mdbook for vocs.
Resources on all things alloy:
Please open issues for anything we’re missing.
With v1.0, we're committing to a stable and reliable, ready for production use API that you can rely on for long-term projects.
Alloy is the Rust toolkit for building high-performance applications on Ethereum and other EVM chains. For upcoming protocol upgrades like new EIPs, we’ll continue to ship updates as specs evolve. These will follow semver and may include breaking changes where needed to stay aligned with core protocol changes. This ensures that Alloy always reflects the latest network behavior, without falling behind.
sol!
macro lets you write Solidity in Rust and generate bindings to interact with the contract.ethers-rs
, with up to 60% faster U256 arithmetic operations and 10x faster ABI encoding.ethers-rs
, migrate today following– our migration guide.With Alloy v1.0, interacting with Solidity smart contracts is easier, faster, and safer than ever.
At the center of this is the sol!
macro, a compile-time Solidity parser that generates type-safe Rust bindings from Solidity code or artifacts. This enables seamless contract interaction with strong typing and removes the need for manual ABI handling. We’ve overhauled the sol!
bindings for better Rust representation and ease of use. This revamp involves improvements targeted to both high-level contract interactions and usage of low-level bindings.
Previously, developers often had to use the ._0
notation to access the actual result of a function call, which made simple contract interactions less intuitive. With this update, the need for ._0
has been eliminated. See an example of the improved user experience below.
The sol!
macro supports Solidity syntax directly in Rust, Solidity files, or JSON ABI artifacts. This lets you bring verified contract interfaces into your codebase with one macro call.
You can call any function on the contract with native Rust types, and Alloy handles the ABI encoding and decoding internally.
Whether you’re deploying contracts or simulating low-level calldata, the sol! macro makes smart contract interaction fast and reliable.
Alloy ships with a set of primitive types including U256
, I256
, Address
, and Bytes
— that are faster and more ergonomic than their equivalents in ethers-rs.
These types are foundational across the stack: they're used for balance math, calldata encoding, transaction simulation, and more. If you're building bots, indexers, or any compute-heavy service, switching to Alloy’s primitives can yield immediate performance wins.
Alloy’s U256
is built on top of the ruint
crate, delivering 35–60% faster arithmetic in common DeFi calculations like AMM math and arbitrage. We benchmarked two core methods from a UniswapV2 arbitrage bot get_amount_in
and get_amount_out
to compare both ethers-rs and Alloy types:
These methods are used in MEV bots to calculate optimal input amounts for arbitrage swaps. If you want to learn more about how to build fast MEV bots with Alloy’s Primitive types, read our guide.
Alloy generates Rust types that encode Solidity calls directly. This removes the need for runtime JSON ABI parsing and avoids encoding bugs. Static ABI encoding is up to 10x faster in Alloy, while dynamic ABI encoding sees around 10% improvement.
In cases where ABI information is only available at runtime (e.g. wallet frontends or ABI fetchers), Alloy provides dynamic ABI encoding via DynSolValue. You can read more about dynamic ABI encoding in our docs.
These benchmarks use Criterion and are available in the Alloy examples repo.
Alloy’s RPC provider offers a clean, modular abstraction over Ethereum RPC endpoints with built-in support for HTTP, WebSockets, and IPC, along with advanced patterns like provider layering, transport wrapping, and middleware composition. Our goal is to eliminate boilerplate and let developers connect to the chain in just a few lines of code.
At its core is the ProviderBuilder
, which simplifies connection setup and hides the complexity of underlying transports:
Alloy makes it easy to build higher-level abstractions by wrapping providers in your own types. This helps isolate logic, reduce repetition, and create intuitive workflows for specific tasks like deployment, data fetching, or transaction simulation.
There are two primary ways to wrap a provider, depending on whether you want to preserve type information or prioritize simplicity.
Use generics when you want static dispatch, full type safety, and optimal runtime performance. This is ideal for library code or scenarios where you want to preserve exact type information.
This has been enabled with the removal of the T: Transport
generic from the provider. These changes have also been propagated to the sol!
macro bindings making it easier to work with types that wrap the provider.
You can now wrap providers without wrestling with complex generic types:
This approach lets you construct tightly-coupled components that are easy to test and optimize, while keeping the interface generic over different transports or layers.
Use DynProvider
when you want to simplify types and avoid dealing with generics — especially useful in applications, scripts, or dynamic settings.
DynProvider
erases the concrete type of the provider while preserving full functionality, including layering and middleware. This simplifies signatures and reduces binary size at the cost of a small runtime overhead. Use this when working with heterogeneous providers or when you want faster compile times and cleaner interfaces in high-level code. You can read more about the best practices of wrapping a provider in the docs.
Alloy’s provider is designed for the multi-chain world by being generic over the Network
trait. The Network
trait defines the structures of the network and its RPC types which are used by the provider. By default the ProviderBuilder
creates a provider for the Ethereum
network. One can use the .network()
method to change that. For example, we can use the Optimism
network type from op-alloy to instantiate a provider for interacting with OP-stack chains such as Base.
This enables the provider to deserialize the OP specific types such as the Deposit transaction.
Alloy makes it easy to batch multiple read-only contract calls using Multicall, a smart contract and design pattern for aggregating calls into a single RPC request. Multicall aggregates contract reads and writes. This is useful for reducing the number of RPC requests you’re making and execute calls atomically by guaranteeing that the numerous state reads/writes are in the same block. Alloy provides first class support to leverage Multicall3 in two ways:
The .multicall()
method on the provider gives you full control over which calls are batched together. It works directly with contract bindings generated by the sol!
macro to provide an intuitive and simple API to batch and execute calls while also handling decoding of the response. A simple multicall looks like:
Use this approach when you want to explicitly group related calls, fetch state from multiple contracts, or control call ordering and deduplication.
For a more seamless experience, you can enable the CallBatchLayer
to automatically group eth_call
requests that are made in parallel. The CallBatchLayer
is a ProviderLayer
that spawns a background task aggregating eth_call
requests made using provider.call(tx)
. This is extremely useful for reducing the number of RPC requests and automatically enable batching while using the provider as usual.
This approach is ideal when you want automatic batching for parallel calls without touching existing logic, especially when your app already uses concurrent tasks.
We want to thank the vibrant community of contributors who have helped shape Alloy's development. Thank you to James Prestwich for co-developing many of the exciting features in this release, and Remco Bloemen for building Ruint. We're grateful to the thousands of developers building with Alloy and pushing the boundaries of what's possible in Ethereum development with Rust.
Alloy 1.0 brings unmatched developer experience to the Rust Ethereum ecosystem. From turbocharged primitives and intuitive contract interfaces to modular provider architecture, this release sets a new standard for blockchain development tooling.
Explore the documentation at alloy.rs and get started today.
We’re hiring across all our open source projects, including Reth, Foundry and Alloy. Reach out with your Github and resume to georgios@paradigm.xyz.
Copyright © 2025 Paradigm Operations LP All rights reserved. “Paradigm” is a trademark, and the triangular mobius symbol is a registered trademark of Paradigm Operations LP