Skip to content

Commit

Permalink
Vault simulator (#11)
Browse files Browse the repository at this point in the history
* First version of the simulator

* Add to pre-commit formatting

* Refactor setup script

* Add setupTestnet script

* Small changes to TokenVault contract for easier integration with the actual pyth contract

* Use price feed id as the name of WETH contract for consistency

* Update docs

* Update .gitignore

* Update token vault searcher

* Add value field to Adapter structs and logic

* Add new command to setup a new searcher account from scratch

* Clean up errors and add signatures

* Implement bid on opportunity endpoint

* Fix on searcher and vault monitor

vault monitor needs to include value and WETH if necessary
searcher uses the new endpoint for bidding

* Setup poetry and replace autopep8 with black

* Rename beacon server to liquidation server

* Fix ci

* Get hermes endpoint as parameter in simulator

* Add interval option for simulator to create vaults periodically

* Improve logging on per_sdk

* Reduce ETH amounts to be more reasonable in actual testnets

* Correct usage of chain_id in scripts

* Minor refactor

* Fix api docs

* Remove the opportunity upon successful submission

* Move error handling logic partly into auction

Converting ContractError to RestErrors remain in api but logical error
handling moved inside the auction module

* Add build scripts

* Use config for poll interval

* Direct parsing of U256 and Signature using serde custom module

* Add comment on why token names are pricefeed ids
  • Loading branch information
m30m authored Feb 4, 2024
1 parent 44cf436 commit fe7e0c6
Show file tree
Hide file tree
Showing 52 changed files with 8,187 additions and 787 deletions.
24 changes: 24 additions & 0 deletions .github/actions/python-poetry/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Python Poetry
description: Sets up a Python environment with Poetry

inputs:
python-version:
required: false
description: Python version
default: "3.11"
poetry-version:
required: false
description: Poetry version
default: "1.6.1"

runs:
using: composite
steps:
- uses: actions/setup-python@v2
with:
python-version: ${{ inputs.python-version }}
- uses: abatilo/actions-poetry@v2.0.0
with:
poetry-version: ${{ inputs.poetry-version }}
- run: poetry -C per_sdk install
shell: sh
2 changes: 1 addition & 1 deletion .github/workflows/ci-pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
with:
# Need to grab the history of the PR
fetch-depth: 0
- uses: actions/setup-python@v2
- uses: ./.github/actions/python-poetry
- uses: actions-rs/toolchain@v1
with:
profile: minimal
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ api_keys.py
# env files
*.env
per_multicall/latestEnvironment.json

**/target/
node_modules
.idea
28 changes: 25 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,31 @@ repos:
entry: cargo +nightly-2023-07-23 fmt --manifest-path ./auction-server/Cargo.toml --all -- --config-path rustfmt.toml
pass_filenames: false
files: auction-server
- repo: local
hooks:
# Hooks for vault-simulator
- id: cargo-fmt-vault-simulator
name: Cargo format for vault simulator
language: "rust"
entry: cargo +nightly-2023-07-23 fmt --manifest-path ./vault-simulator/Cargo.toml --all -- --config-path rustfmt.toml
pass_filenames: false
files: vault-simulator

# for python files
- repo: https://github.com/hhatto/autopep8
rev: "v2.0.4"
- repo: local
hooks:
- id: autopep8
- id: isort
name: isort
entry: poetry -C per_sdk run isort --profile=black per_sdk
pass_filenames: false
language: system
- id: black
name: black
entry: poetry -C per_sdk run black per_sdk
pass_filenames: false
language: system
- id: pyflakes
name: pyflakes
entry: poetry -C per_sdk run pyflakes per_sdk
pass_filenames: false
language: system
1 change: 0 additions & 1 deletion auction-server/.gitignore

This file was deleted.

26 changes: 26 additions & 0 deletions auction-server/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::process::Command;

fn main() {
let contract_setup = r#"
cd ../per_multicall
forge build --via-ir
"#;
println!("cargo:rerun-if-changed=../per_multicall");

// Build the contracts and generate the ABIs. This is required for abigen! macro expansions to work.
let output = Command::new("sh")
.args(["-c", contract_setup])
.output()
.expect("Failed to run build contracts command");
if !output.status.success() {
panic!(
"Failed to build contracts: {}",
String::from_utf8_lossy(&output.stderr)
);
} else {
println!(
"Built all solidity contracts {}",
String::from_utf8_lossy(&output.stdout)
);
}
}
4 changes: 3 additions & 1 deletion auction-server/config.sample.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
chains:
development:
geth_rpc_addr: http://localhost:8545
contract_addr: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853
per_contract: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853
adapter_contract: 0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e
legacy_tx: false
poll_interval: 1
2 changes: 2 additions & 0 deletions auction-server/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "stable"
23 changes: 21 additions & 2 deletions auction-server/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ use {
LocalWallet,
Signer,
},
types::Bytes,
},
futures::future::join_all,
std::{
Expand All @@ -58,6 +59,7 @@ use {
},
Arc,
},
time::Duration,
},
tower_http::cors::CorsLayer,
utoipa::{
Expand Down Expand Up @@ -90,6 +92,12 @@ pub enum RestError {
BadParameters(String),
/// The chain id is not supported
InvalidChainId,
/// The simulation failed
SimulationError {
#[schema(value_type=String)]
result: Bytes,
reason: String,
},
/// The order was not found
OpportunityNotFound,
/// The server cannot currently communicate with the blockchain, so is not able to verify
Expand All @@ -108,6 +116,11 @@ impl IntoResponse for RestError {
RestError::InvalidChainId => {
(StatusCode::BAD_REQUEST, "The chain id is not supported").into_response()
}
RestError::SimulationError { result, reason } => (
StatusCode::BAD_REQUEST,
format!("Simulation failed: {} ({})", result, reason),
)
.into_response(),
RestError::OpportunityNotFound => (
StatusCode::NOT_FOUND,
"Order with the specified id was not found",
Expand Down Expand Up @@ -141,6 +154,7 @@ pub async fn start_server(run_options: RunOptions) -> Result<()> {
paths(
rest::bid,
marketplace::submit_opportunity,
marketplace::bid_opportunity,
marketplace::fetch_opportunities,
),
components(
Expand All @@ -165,15 +179,16 @@ pub async fn start_server(run_options: RunOptions) -> Result<()> {

let chain_store: Result<HashMap<ChainId, ChainStore>> = join_all(config.chains.iter().map(
|(chain_id, chain_config)| async move {
let provider =
Provider::<Http>::try_from(chain_config.geth_rpc_addr.clone()).map_err(|err| {
let mut provider = Provider::<Http>::try_from(chain_config.geth_rpc_addr.clone())
.map_err(|err| {
anyhow!(
"Failed to connect to chain({chain_id}) at {rpc_addr}: {:?}",
err,
chain_id = chain_id,
rpc_addr = chain_config.geth_rpc_addr
)
})?;
provider.set_interval(Duration::from_secs(chain_config.poll_interval));
let id = provider.get_chainid().await?.as_u64();
Ok((
chain_id.clone(),
Expand Down Expand Up @@ -212,6 +227,10 @@ pub async fn start_server(run_options: RunOptions) -> Result<()> {
"/liquidation/fetch_opportunities",
get(marketplace::fetch_opportunities),
)
.route(
"/liquidation/bid_opportunity",
post(marketplace::bid_opportunity),
)
.layer(CorsLayer::permissive())
.with_state(server_store);

Expand Down
Loading

0 comments on commit fe7e0c6

Please sign in to comment.