• Stars
    star
    669
  • Rank 67,451 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 2 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A blazing-fast Ethereum sandbox that lets developers orchestrate event-driven simulations.

arbiter

Expanding the EVM tooling ecosystem.

Github Actions Codecov badge Visitors badge Telegram badge Discord badge Twitter Badge

Arbiter is a framework for stateful Ethereum smart-contract simulation. The framework features an ethers-rs middleware built on top of revm which allows the end user to interact with a sandboxed revm instance as if it were an Ethereum node. This provides a familiar interface for interacting with the Ethereum Virtual Machine (EVM), but with unrivaled speed. Furthermore, Arbiter provides containment and management for simulations.

Overview

The Arbiter workspace has two crates:

  • arbiter-core: The lib crate that contains the core logic for the Arbiter framework including the RevmMiddleware discussed before, the Environment which envelopes simulations, and the Manager who controls a collection of environments.
  • arbiter: The binary crate that exposes a command line interface for initializing simulations via a templated repository and generating contract bindings needed for the simulation.

The purpose of Arbiter is to provide a toolset to construct arbitrary agents (defined in Rust, by smart contracts, or even other FFI) and have these agents interact with an Ethereum-like environment of your design. All contract bytecode is run directly using a blazing-fast EVM instance revm (which is used in live RPC nodes such as reth) so that your contracts are tested in the exact same type of environment that they are deployed in.

Motivation

Smart contract engineers need to test their contracts against a wide array of potentially adversarial environments and contract parameters. The static stateless testing of contracts can only take you so far. To truly test the security of a contract, you need to test it against a wide array of dynamic environments that encompass the externalities of Ethereum mainnet. We wanted to do just that with Arbiter.

Both smart contract and financial engineers come together in Decentralized Finance (DeFi) to build and deploy a wide array of complex decentralized applications as well as fincancial strategies respectively. For the latter, a financial engineer may want to test their strategies against thousands of market conditions, contract settings, shocks, and autonomous or random or even AI agents all while making sure their strategy isn't vulnerable to bytecode-level exploits.

To configure such a rich simulation environment on a test or local network is also possible with Arbiter by a change in choice of middleware. The most efficient choice for getting robust, yet quick, simulations would bypass any networking and use a low level language's implementation of the EVM. Furthermore, we can gain control over the EVM worldstate by working directly on revm. We would like the user to have a choice in how they want to simulate their contracts and Arbiter provides that choice.

Sim Driven Development and Strategization

Test driven development is a popular engineering practice to write tests first, which fail, and implement logic to get the test to eventually pass. With simulation driven development, it's possible to build "tests" that can only pass if the incentives actually work. For example, a sim driven test might be is_loan_liquidated, and a simulation must be made for a liquidator agent to do the liquidation. This approach significantly improves the testing of economic systems and other mechanism designs, which is important in the world of networks that are mostly incentive driven.

The same goes with developing strategies that one would like to deploy on a live Ethereum network. One can use Arbiter to simulate their strategy with an intended goal and see if it actually works. This is especially important in the world of DeFi where strategies are often a mix of on and offchain and are susceptible to exploits.

Installation

To install Arbiter, you will need to have Rust installed on your machine. You can install Rust by following the instructions here. Once you have Rust installed, you can install Arbiter by running the following commands:

git clone https://github.com/primitivefinance/arbiter.git
cargo install --path ./arbiter

This will install the Arbiter binary on your machine. You can then run arbiter --help to see that Arbiter was installed properly as well as see the help menu.

Command Line Interface

The Arbiter binary provides a CLI for creating new projects much like Foundry, which Arbiter aims to work alongside with. This requires you to have foundry installed. If you do not have foundry installed you can install it here. To create a new project, you can run:

arbiter init your-project-name
cd your-project-name

This initializes a new Arbiter project with a template. You can generate the bindings again by running:

arbiter bind

The template is executable at this point and you can run it by running:

cargo run

You can load or write your own smart contracts in the templates contracts/ directory and begin writing your own simulations. Arbiter treats Rust smart-contract bindings as first-class citizens. The contract bindings are generated via Foundry's forge command. arbiter bind wraps forge with some convenience features that will generate all your bindings to src/biindings as a rust module. Foundry power-users are welcome to use forge directly.

Documentation

To see the documentation for Arbiter, after cloning the repo, you can run:

cargo doc --workspace --no-deps --open

This will generate and open the docs in your browser. From there, you can look at the documentation for each crate in the Arbiter workspace. We will post both crates to crates.io once we have removed any and all Github linked crates.

Benchmarks

In arbiter-core, we have a a small benchmarking suite that compares the RevmMiddleware implementation over the Environment to the Anvil local testnet chain implementation. The biggest reasons why we chose to build Arbiter was to gain more control over the EVM environment and to have a more robust simulation framework, but we also wanted to gain in speed which is why we chose to build our own interface over revm as opposed to using Anvil (which does use revm under the hood). For the following, Anvil was set to mine blocks for each transaction as opposed to setting an enforced block time and the Environment was set with a block rate of 10.0 (this was chosen somewhat arbitrarily as we will add in more block control in the future). Preliminary benchmarks of the RevmMiddleware interface over revm against Anvil are given in the following table.

Operation RevmMiddlwware Anvil Relative Difference
Deploy 241.819µs 8.215446ms ~33.97x
Lookup 480.319µs 13.052063ms ~27.17x
Stateless Call 4.03235ms 10.238771ms ~2.53x
Stateful Call 843.296µs 153.102478ms ~181.55x

The above can be described by:

  • Deploy: Deploying a contract to the EVM. We deployed both ArbiterToken and ArbiterMath in this method, so you can divide the time by two to get an estimate for the time it takes to deploy a single contract.

  • Lookup: Looking up a the balanceOf for a client's address for ArbiterToken. We called ArbiterToken's balanceOf function 100 times in this method. Divide by 100 to get the time it takes to lookup a single balance.

  • Stateless Call: Calling a contract that does not mutate state. We called ArbiterMath's cdf function 100 times in this method. Divide by 100 to get the time it takes to call a single stateless function.

  • Stateful Call: Calling a contract that mutates state. We called ArbiterToken's mint function 100 times in this call. Divide by 100 to get the time it takes to call a single stateful function.

The benchmarking code can be found in the arbiter-core/benches/ directory and these specific times were achieved over a 1000 run average. The above was achieved running cargo bench --package arbiter-core which will automatically run with the release profile. Times were achieved on an Apple Macbook Pro M1 Max with 8 performance and 2 efficiency cores, and with 32GB of RAM.

Of course, the use cases of Anvil and the RevmMiddleware can be different. Anvil represents a more realistic environment with networking and mining, while the RevmMiddleware is simpler environment with the bare essentials to running stateful simulations. Anvil also mines blocks for each transaction, while the RevmMiddleware does not. We hope to improve our API to allow the end user to be able to interface with their own choice of EVM environment to suit what ever their needs may be!

Please let us know if you find any issues with these benchmarks or if you have any suggestions on how to improve them!

Contributing

See our Contributing Guidelines

More Repositories

1

hardhat-marmite

🥘 Hassle-free Hardhat plugin to compare gas cost among different Solidity code snippets.
TypeScript
196
star
2

primitive-dodoc

☄️ Zero-config Hardhat plugin to generate documentation for all your Solidity contracts.
TypeScript
135
star
3

rmm-core

Primitive Replicating Market Maker smart contracts
Solidity
131
star
4

solstat

Math library written in solidity for statistical function approximations like the Normal Cumulative Distribution Function.
Solidity
118
star
5

portfolio

Portfolio is an automated market making protocol for implementing custom strategies at the lowest cost possible.
Solidity
113
star
6

hardhat-foundry

Forkable hardhat & foundry template for thorough evm development.
Solidity
87
star
7

soulbound

Implementation of a non-transferrable NFT using non-financial incentivization.
Solidity
85
star
8

rmms-py

Python simulator to test implementation of the RMMS paper results.
Python
55
star
9

RMM01-Simulations

RMM-01 Simulations
Python
50
star
10

arbiter-template

Minimal template for simulating contracts with arbiter.
Rust
45
star
11

v1-contracts

Primitive protocol solidity contracts.
Solidity
43
star
12

rmm-manager

Manager and Routing smart contracts for Primitive RMM
Solidity
34
star
13

univ3-kit

An open simulation for Uniswap V3 contracts
Rust
34
star
14

sybil-detection

Python
31
star
15

open-research-questions

This is a collection of open research questions in the DeFi mechanism design space pertinent to the Primitive R&D Team. This serves as a public forum and is open to discussion and changes amongst the broader DeFi research and development community.
26
star
16

excalibur

Excalibur
Rust
21
star
17

rmm-math

Typescript math library for cumulative distributions, black-scholes, and the RMM trading function.
TypeScript
21
star
18

proto-sim-portfolio

Prototype risk modeling simulation for Portfolio using Arbiter.
Rust
20
star
19

DFMM

Smart contracts of the DFMM protocol
Rust
18
star
20

rmm-ethers

Library for interacting with RMM protocol through ethers.js.
TypeScript
15
star
21

aika

Discrete event simulator built in Rust 🦀
Rust
13
star
22

Topological-Data-Analysis

This repository is for topologic and geometric data analysis.
Python
13
star
23

m3-rs

Simple rust interface to get derived analytical information of algorithmic market making models (M3).
Rust
12
star
24

portfolio_simulations

Moving to the new Arbiter framework to test Portfolio.
Rust
10
star
25

rmm-sdk

Typescript based entity classes and transaction builders for the rmm-core and rmm-periphery smart contracts.
TypeScript
10
star
26

rmm-examples

Solidity
10
star
27

portfolio-rs

SDK for the Portfolio protocol written in rust.
Rust
9
star
28

DisputeGameSimulations

Rust
9
star
29

v1-connectors

Smart contracts that connect Primitive V1 to other Ethereum protocols and standards.
Solidity
9
star
30

CFMMRouter.py

Python implementation of CFMMRouter.jl
Python
9
star
31

visualization-rs

This is a collection of math and plotting tools for us to use for visualizing data.
Rust
8
star
32

rmm-docs

Primitive and RMM Protocol Documentation - Crypto Derivatives without Counterparties
JavaScript
7
star
33

fvm.ts

TypeScript
4
star
34

pool-analytics

Jupyter Notebook
4
star
35

v1-interface

An open-source interface for the Primitive protocol.
TypeScript
4
star
36

dagger

A lightweight interface for the DFMM smart contracts
TypeScript
4
star
37

Research

Research papers and repository directory
3
star
38

v1-sdk

An SDK for the Primitive Protocol.
TypeScript
3
star
39

portfolio-ts

Minimal toolkit for building TypeScript based applications for Portfolio by Primitive.
TypeScript
3
star
40

Arbitrum-Transaction-Data-Analysis

This repository is for transaction data analysis on the the Arbitrum Network
3
star
41

amm-auction

Solidity
3
star
42

portfolio-examples-solidity

Solidity
3
star
43

arbmod

git submodule for arbiter
Solidity
3
star
44

v1-subgraph

A graph for the Primitive Protocol.
TypeScript
3
star
45

dfmm-indexer

Indexer for the DFMM protocol
TypeScript
3
star
46

security

All security reports for Primitive products and protocols.
2
star
47

discord-bot

TypeScript
2
star
48

rmm-core-dapptools

Rmm protocol core contracts in dapptools testing environment.
Solidity
2
star
49

arbiter-dispute-game

TeX
2
star
50

brand

Primitive's brand assets.
2
star
51

v1-amm-spec

Derivative focused AMM for the Primitive Protocol.
Solidity
2
star
52

arbiter-portfolio-sim

Migration from old middleware to new.
Solidity
1
star
53

rmm

Solidity
1
star
54

nugu

Solidity
1
star
55

fee-generation-py

Python
1
star