
# Introducing arbos-foundry: Native Stylus Testing with Foundry
We're excited to announce the initial release of [**arbos-foundry**](https://github.com/iosiro/arbos-foundry) – a fork of Foundry with native support for testing Arbitrum Stylus programs. Developed by [iosiro](https://www.iosiro.com/) as part of the [Arbitrum Stylus Sprint](https://blog.arbitrum.io/stylus-sprint/), this tool brings the developer experience you know and love from Foundry directly to the Stylus ecosystem.
## What is Stylus?
For those unfamiliar, [Arbitrum Stylus](https://docs.arbitrum.io/stylus/stylus-gentle-introduction) introduces a new approach to smart contract execution, adding a WebAssembly virtual machine that runs alongside the EVM. Enabling developers to write smart contracts in Rust, C, C++, or any language that compiles to WASM. The benefits are significant: access to mature libraries and tooling, lower gas costs for computation-heavy applications, and full interoperability with existing Solidity contracts.
## The problem we solved
Until now, full integration testing of Stylus programs required deploying to a live testnet or running a local Arbitrum node. This friction slowed down the development cycle and made it harder for teams to adopt Stylus with confidence.
arbos-foundry changes that. You can now run `arbos-forge test` and have your Stylus WASM programs execute natively – no network fork required, no external dependencies, just fast local testing.
## Built on arbos-revm
The heavy lifting for Arbitrum compatibility lives in [arbos-revm](https://github.com/iosiro/arbos-revm), a companion library we developed that provides a complete ArbOS execution environment built on [revm](https://github.com/bluealloy/revm). This includes:
- **Native WASM Execution**: Stylus programs run through the Wasmer runtime with proper gas-to-ink conversion
- **13 Arbitrum Precompiles**: Full implementations of ArbSys, ArbWasm, ArbGasInfo, ArbRetryableTx, and more
- **ArbOS State Management**: Proper initialization of chain parameters, gas pricing, and Stylus configuration
- **Dual-Layer Gas Pricing**: Accurate L1 data costs and L2 execution fees
By separating the core Arbitrum logic into arbos-revm, we've created a reusable foundation that other tools can build on.
## Key features
### Stylus deployment cheatcodes
New cheatcodes let you deploy Stylus contracts directly from your Solidity test files by pointing at a `.wasm` artifact. Variants support constructor arguments and value transfers. [See below for a full example](#getting-started).
### Automatic activation and caching
Stylus programs require activation before execution. arbos-foundry handles this transparently – your programs activate on first call and benefit from an LRU cache that avoids recompilation. Need more control? Disable auto-activation and call `ArbWasm.activateProgram()` manually.
### Full configuration control
Tune Stylus parameters via CLI, `foundry.toml`, or inline config comments:
```toml
[profile.default.stylus]
ink_price = 10000
max_stack_depth = 262144
free_pages = 2
```
## Getting started
Installation takes seconds with `arbos-foundryup`:
```bash
# Install the installer
curl -L https://raw.githubusercontent.com/iosiro/arbos-foundry/HEAD/foundryup/arbos-install | bash
# Install arbos-foundry
arbos-foundryup
```
This gives you `arbos-forge`, `arbos-cast`, `arbos-anvil`, and `arbos-chisel` in `~/.foundry/bin/`.
### Defining the Stylus cheatcodes
The new Stylus cheatcodes aren't part of `forge-std` yet, so you'll need to define them in your project. In a future release, we'll provide a `forge-std` fork with these cheatcodes included. For now, create an interface that extends Foundry's `Vm`:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {Vm} from "forge-std/Vm.sol";
interface StylusVm is Vm {
function deployStylusCode(string calldata artifactPath) external returns (address);
function deployStylusCode(string calldata artifactPath, bytes calldata constructorArgs) external returns (address);
function deployStylusCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value) external returns (address);
function getStylusCode(string calldata artifactPath) external returns (bytes memory);
function brotliCompress(bytes calldata data) external returns (bytes memory);
function brotliDecompress(bytes calldata data) external returns (bytes memory);
}
```
Then wrap the standard `vm` instance in your tests:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "forge-std/Test.sol";
contract MyStylusTest is Test {
StylusVm svm = StylusVm(address(vm));
function testStylusProgram() public {
address counter = svm.deployStylusCode("counter.wasm");
// Call increment
(bool success,) = counter.call(abi.encodeWithSignature("increment()"));
assertTrue(success);
// Verify the count
(, bytes memory result) = counter.call(abi.encodeWithSignature("get()"));
uint256 count = abi.decode(result, (uint256));
assertEq(count, 1);
}
}
```
Run it:
```sh
arbos-forge test
```
## What's next
This v0.1.0 release provides a solid foundation for Stylus development. We're continuing to improve test coverage, add more comprehensive documentation, and gather feedback from the community.
If you encounter issues or have feature requests, please open an issue on [GitHub](https://github.com/iosiro/arbos-foundry/issues).
## Acknowledgements
This project wouldn't exist without:
- The [Foundry](https://github.com/foundry-rs/foundry) team, who built the blazing-fast toolkit we forked.
- [Arbitrum](https://arbitrum.io/), who created Stylus and funded development through the [Stylus Sprint](https://blog.arbitrum.io/stylus-sprint/) program.
- The broader Arbitrum developer community, who continually push the boundaries of what's possible on L2.
We're thrilled to contribute to the Stylus ecosystem and can't wait to see what you build.
---
*arbos-foundry is developed by [iosiro](https://www.iosiro.com/), a blockchain security firm specializing in smart contract auditing and security research.*