Skip to content

Commit

Permalink
Merge pull request #378 from primitivefinance/feat/middleware
Browse files Browse the repository at this point in the history
We have been waiting a while for this one!!!
  • Loading branch information
Autoparallel authored Aug 16, 2023
2 parents 296ea8f + 54671d2 commit d39ddaa
Show file tree
Hide file tree
Showing 183 changed files with 3,362 additions and 91,206 deletions.
12 changes: 1 addition & 11 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ updates:
interval: "daily"

- package-ecosystem: "cargo"
directory: "crates/bindings/"
schedule:
interval: "daily"

- package-ecosystem: "cargo"
directory: "lib/chain/"
schedule:
interval: "daily"

- package-ecosystem: "cargo"
directory: "lib/simulations/"
directory: "arbiter-core"
schedule:
interval: "daily"
39 changes: 0 additions & 39 deletions .github/workflows/bump_version.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: lint

on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened]

jobs:
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: test

on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened]

jobs:
Expand All @@ -19,7 +21,7 @@ jobs:
toolchain: stable

- name: test
run: cargo test --all --all-features --exclude bindings
run: cargo test --all --all-features

codecov:
name: codecov
Expand All @@ -36,4 +38,4 @@ jobs:
uses: taiki-e/install-action@cargo-llvm-cov

- name: codecov
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --exclude bindings
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ Cargo.lock

.DS_Store
# /contracts/*
arbiter/
arbiter/

.vscode
34 changes: 0 additions & 34 deletions .gitmodules

This file was deleted.

6 changes: 5 additions & 1 deletion .rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ group_imports = "StdExternalCrate"

format_code_in_doc_comments = true

use_field_init_shorthand = true
use_field_init_shorthand = true

wrap_comments = true
normalize_comments = true
comment_width = 80
54 changes: 11 additions & 43 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# Workspace configuration
[workspace]

# List of crates included in this workspace
members = [
"crates/bindings",
"crates/simulate",
"crates/onchain",
"arbiter-core",
]

# Package configuration
[package]
name = "arbiter"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["Colin Roberts", "Waylon Jepsen"]

Expand All @@ -19,51 +17,21 @@ authors = ["Colin Roberts", "Waylon Jepsen"]
name = "arbiter"
path = "bin/main.rs"

# Dependency configuration
[dependencies]
# Local dependencies
simulate = {path = "crates/simulate"}
bindings = {path = "crates/bindings"}
onchain = {path = "crates/onchain"}

# Primitive dependencies
visualize = { git = "https://github.com/primitivefinance/visualization-rs.git"}

# External dependencies
# Dependencies for the release build
[dependencies]
# Command line and config
clap = { version = "4.3.0", features = ["derive"] }
csv = "1.2.1"
eyre = "0.6.8"
itertools-num = "0.1.3"
serde = { version = "1.0.163", features =["derive"] }
thiserror = "1.0.40"
tokio = { version = "1.28.1", features = ["macros", "full"] }
toml = "0.7.4"
chrono = "0.4"
log = "0.4.19"

# Revm and related dependencies
bytes = "1.4.0"
hex = { version = "0.4.3", default-features = false }
revm = "3.3.0"
ruint = "1.8.0"
ethers = { version = "2.0.4", default-features = false, features = ["abigen"] }

# Simulation dependencies
crossbeam-channel = "0.5.8"
polars = "0.29.0"
quote = "1.0.29"
# Building files
quote = "1.0.28"

# workspace dependencies
[workspace.dependencies]
futures = { version = "0.3.28" }
csv = { version = "1.2.1" }
ethers = { version = "2.0.4", default-features = false, features = ["abigen"] }
serde = { version = "1.0.163", features= ["derive"]}
serde_json = { version = "1.0.96" }
bindings = {path = "crates/bindings"}
tokio = { version = "1.28.1", features = ["macros", "full"] }
# Errors
thiserror = "1.0.40"

# Development dependencies
# Dependencies for the test build and development
[dev-dependencies]
assert_cmd = "2.0.11"

Expand Down
77 changes: 47 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,86 @@
> Expanding the EVM tooling ecosystem.
![Github Actions](https://github.com/primitivefinance/arbiter/workflows/test/badge.svg)
[![codecov](https://codecov.io/gh/funkycadet/arbiter/branch/main/graph/badge.svg?token=UQ1SE0D9IN)](https://codecov.io/gh/funkycadet/arbiter)
![](https://visitor-badge.laobi.icu/badge?page_id=arbiter)
[![](https://dcbadge.vercel.app/api/server/primitive?style=flat)](https://discord.gg/primitive)
[![Codecov badge](https://codecov.io/gh/funkycadet/arbiter/branch/main/graph/badge.svg?token=UQ1SE0D9IN)](https://codecov.io/gh/funkycadet/arbiter)
![Visitors badge](https://visitor-badge.laobi.icu/badge?page_id=arbiter)
![Telegram badge](https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Farbiter_rs)
[![Discord badge](https://dcbadge.vercel.app/api/server/primitive?style=flat)](https://discord.gg/primitive)
[![Twitter Badge](https://badgen.net/badge/icon/twitter?icon=twitter&label)](https://twitter.com/primitivefi)

The Ethereum blockchain's execution environment, the Ethereum Virtual machine (EVM), contains a rich collection of decentralized applications. The EVM is stack machine that sequentially executes opcodes sent to it by users and smart contracts. Arbiter is a highly configurable rust interface over [revm](https://github.com/bluealloy/revm) which is a Rust implementation of the EVM stack machine logic. The purpose of Arbiter is to interface with arbitrary agents and contracts and run this all directly on a blazing-fast simulated EVM.
**Arbiter** is a framework for stateful Ethereum smart-contract simulation.
The framework features an [`ethers-rs`](https://github.com/gakonst/ethers-rs) middleware built on top of [revm](https://github.com/bluealloy/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.

Financial engineers need to study a wide array of complex portfolio management strategies against thousands of market conditions, contract parameters, and agents. To configure such a rich simulation environment on a test network could be possible, but a more efficient choice for getting the most robust, yet quick, simulations would bypass any local networking and use a low level language's implementation of the EVM.
## Overview

Arbiter is being primarily developed to be a tool in evaluating economic and game theoretic security of DeFi applications.
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.

Arbiter can be used for:
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`](https://github.com/paradigmxyz/reth)) so that your contracts are tested in the exact same type of environment that they are deployed in.

- Evaluating the game theoretic and composable security of smart contracts in production environments (security firms and academics)
- investigating risk, capital efficiency, rebalancing strategies, and portfolio replication (or performance). (LPs, funds, quants, traders)
- Engineering and testing new financial products built on top of more primitive financial products (DeFi firms and academics)
## Motivation

## Features:
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.

For our next beta release, we will be focusing on the following features:
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.

## Build From Source
### Sim Driven Development and Strategization

First, clone the repository to your local environment so
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](https://www.rust-lang.org/tools/install). Once you have Rust installed, you can install Arbiter by running the following commands:

```bash
git clone https://github.com/primitivefinance/arbiter.git
cd arbiter
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.

Install arbiter on your system:
## Command Line Interface

The Arbiter binary provides a CLI for creating new projects much like [Foundry](https://github.com/foundry-rs/foundry), which Arbiter aims to work alongside with. To create a new project, you can run:

```bash
cargo install --path . --force
arbiter init your-project-name
cd your-project-name
```

With the `arbiter` binary generated, you can run commands such as:
This initializes a new Arbiter project with a template. The next step require you to have foundry installed. If you do not have foundry installed you can install it [here](https://getfoundry.sh/). Then you can generate the template bindings by running:

```bash
arbiter simulate uniswap
arbiter bind
```

## Generating Docs

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

The template is executable at this point and you can run it by running:
```bash
cargo doc --workspace --no-deps --open
cargo run
```

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.
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](https://github.com/foundry-rs/foundry) power-users are welcome to use `forge` directly.

## Including More Contracts
## Documentation

In the `contracts/` directory you can add additional smart contracts or regenerate Rust bindings. Once that is done, you will want to make sure the bindings are generated in the script:
To see the documentation for Arbiter, after cloning the repo, you can run:

```bash
./bind.sh
cargo doc --workspace --no-deps --open
```
You will need to add the relevant directory for your new contracts to the script above and make sure they are also handled by `forge install`. We look forward to improving upon this UX in the future.

At the moment, this only builds the bindings for the contracts in the `lib/arbmod/contracts/` and `lib/portfolio/contracts`. You can of course add an additional directory of contracts in `lib/`. Just be sure to include it when you generate bindings!
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.

## Contributing

Expand Down
41 changes: 41 additions & 0 deletions arbiter-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "arbiter-core"
version = "0.3.0"
edition = "2021"

# Dependencies for the release build
[dependencies]

# Ethereum and EVM
ethers = { git = "https://github.com/primitivefinance/ethers-rs.git"} # Custom fork for middleware integration
revm = "3.3.0"

# Serialization
bytes = "1.4.0"
serde = { version = "1.0.163", features= ["derive"]}
serde_json = { version = "1.0.96" }

# Concurrency/async
tokio = { version = "1.28.1", features = ["macros", "full"] }
async-trait = "0.1.68"
crossbeam-channel = "0.5.8"
atomic_enum = "0.2.0"

# Randomness
rand = "0.8.5"
rand_distr = "0.4.3"
statrs = "0.16.0"
RustQuant = "*"

# Errors
thiserror = "1.0.30"

# Logging
log = "0.4.19"

# Dependencies for the test build and development
[dev-dependencies]
hex = { version = "0.4.3", default-features = false }
anyhow = "1.0.71"
env_logger = "0.10.0"
test-log = "0.2.12"
File renamed without changes.
Loading

0 comments on commit d39ddaa

Please sign in to comment.