Skip to content

Commit

Permalink
Improve structure of swaps fuzz tests, add valid pool creation (#542)
Browse files Browse the repository at this point in the history
* Improve structure of swaps fuzz tests, add valid pool creation

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>
  • Loading branch information
Chralt98 and maltekliemann committed Jul 6, 2022
1 parent fc3de00 commit 464180f
Show file tree
Hide file tree
Showing 16 changed files with 620 additions and 151 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@
**/artifacts/

# NPM
**/node_modules/
**/node_modules/

# Visual Studio Code
.vscode
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion scripts/tests/fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ set -euxo pipefail
# a hardware- and fuzz target specific run count.
BASE=1000
RUNS="${RUNS:-50000}"

CREATE_POOL_FACT=500
POOL_JOIN_FACT=150
POOL_JOIN_WITH_EXACT_POOL_AMOUNT_FACT=150
POOL_JOIN_WITH_EXACT_ASSET_AMOUNT_FACT=150
SWAP_EXACT_AMOUNT_IN_FACT=500
SWAP_EXACT_AMOUNT_OUT_FACT=500
POOL_EXIT_WITH_EXACT_ASSET_AMOUNT_FACT=150
POOL_EXIT_WITH_EXACT_POOL_AMOUNT_FACT=150
POOL_EXIT_FACT=150

FEE_SIGMOID_FACT=50000
FIXEDI_TO_FIXEDU_FACT=100000
FIXEDU_TO_FIXEDI_FACT=100000
Expand All @@ -25,7 +36,15 @@ RIKIDDO_PALLET_FACT=1000
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/prediction-markets/fuzz pm_full_workflow -- -runs=$RUNS

# --- Swaps Pallet fuzz tests ---
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz swaps_full_workflow -- -runs=$RUNS
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz create_pool -- -runs=$(($(($RUNS * $CREATE_POOL_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_join -- -runs=$(($(($RUNS * $POOL_JOIN_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_join_with_exact_pool_amount -- -runs=$(($(($RUNS * $POOL_JOIN_WITH_EXACT_POOL_AMOUNT_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_join_with_exact_asset_amount -- -runs=$(($(($RUNS * $POOL_JOIN_WITH_EXACT_ASSET_AMOUNT_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz swap_exact_amount_in -- -runs=$(($(($RUNS * $SWAP_EXACT_AMOUNT_IN_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz swap_exact_amount_out -- -runs=$(($(($RUNS * $SWAP_EXACT_AMOUNT_OUT_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_exit_with_exact_asset_amount -- -runs=$(($(($RUNS * $POOL_EXIT_WITH_EXACT_ASSET_AMOUNT_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_exit_with_exact_pool_amount -- -runs=$(($(($RUNS * $POOL_EXIT_WITH_EXACT_POOL_AMOUNT_FACT)) / $BASE))
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/swaps/fuzz pool_exit -- -runs=$(($(($RUNS * $POOL_EXIT_FACT)) / $BASE))

# --- Orderbook-v1 Pallet fuzz tests ---
RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir zrml/orderbook-v1/fuzz orderbook_v1_full_workflow -- -runs=$RUNS
Expand Down
56 changes: 54 additions & 2 deletions zrml/swaps/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,66 @@
[[bin]]
doc = false
name = "swaps_full_workflow"
path = "swaps_full_workflow.rs"
name = "create_pool"
path = "create_pool.rs"
test = false

[[bin]]
doc = false
name = "pool_join"
path = "pool_join.rs"
test = false

[[bin]]
doc = false
name = "pool_join_with_exact_pool_amount"
path = "pool_join_with_exact_pool_amount.rs"
test = false

[[bin]]
doc = false
name = "pool_join_with_exact_asset_amount"
path = "pool_join_with_exact_asset_amount.rs"
test = false

[[bin]]
doc = false
name = "swap_exact_amount_in"
path = "swap_exact_amount_in.rs"
test = false

[[bin]]
doc = false
name = "swap_exact_amount_out"
path = "swap_exact_amount_out.rs"
test = false

[[bin]]
doc = false
name = "pool_exit_with_exact_asset_amount"
path = "pool_exit_with_exact_asset_amount.rs"
test = false

[[bin]]
doc = false
name = "pool_exit_with_exact_pool_amount"
path = "pool_exit_with_exact_pool_amount.rs"
test = false

[[bin]]
doc = false
name = "pool_exit"
path = "pool_exit.rs"
test = false

[dependencies]
arbitrary = { features = ["derive"], version = "1.0" }
libfuzzer-sys = "0.4"
zrml-swaps = { features = ["mock"], path = ".." }
zeitgeist-primitives = { path = "../../../primitives" }
sp-runtime = { branch = "moonbeam-polkadot-v0.9.19", default-features = false, git = "https://github.com/purestake/substrate" }
frame-support = { branch = "moonbeam-polkadot-v0.9.19", default-features = false, git = "https://github.com/purestake/substrate" }
orml-traits = { branch = "polkadot-0.9.19-latest", default-features = false, git = "https://github.com/zeitgeistpm/open-runtime-module-library" }
rand = "0.8.4"

[package]
authors = ["Automatically generated"]
Expand Down
26 changes: 26 additions & 0 deletions zrml/swaps/fuzz/create_pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zeitgeist_primitives::{traits::Swaps as SwapsTrait, types::ScoringRule};

use zrml_swaps::mock::{ExtBuilder, Swaps};

mod utils;
use utils::{construct_asset, PoolCreationData};

fuzz_target!(|data: PoolCreationData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
let _ = Swaps::create_pool(
data.origin,
data.assets.into_iter().map(construct_asset).collect(),
construct_asset(data.base_asset),
data.market_id,
ScoringRule::CPMM,
data.swap_fee,
data.amount,
data.weights,
);
});
let _ = ext.commit_all();
});
40 changes: 40 additions & 0 deletions zrml/swaps/fuzz/pool_exit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};

mod utils;
use orml_traits::MultiCurrency;
use utils::{construct_asset, GeneralPoolData};
use zeitgeist_primitives::types::{Asset, SerdeWrapper};
use zrml_swaps::mock::Shares;

fuzz_target!(|data: GeneralPoolData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
data.pool_creation.amount,
);
}
let pool_creator = data.pool_creation.origin;
let pool_id = data.pool_creation.create_pool();
// to exit a pool, origin also needs to have the pool tokens of the pool that they're exiting
let _ = Shares::deposit(
Asset::PoolShare(SerdeWrapper(pool_id)),
&pool_creator,
data.pool_amount,
);
let _ = Swaps::pool_exit(
Origin::signed(data.origin),
pool_id,
data.pool_amount,
data.asset_bounds,
);
});
let _ = ext.commit_all();
});
43 changes: 43 additions & 0 deletions zrml/swaps/fuzz/pool_exit_with_exact_asset_amount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};

mod utils;
use orml_traits::MultiCurrency;
use utils::{construct_asset, ExactAssetAmountData};
use zrml_swaps::mock::Shares;

use zeitgeist_primitives::types::{Asset, SerdeWrapper};

fuzz_target!(|data: ExactAssetAmountData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
data.pool_creation.amount,
);
}

let pool_creator = data.pool_creation.origin;
let pool_id = data.pool_creation.create_pool();
// to exit a pool, origin also needs to have the pool tokens of the pool that they're exiting
let _ = Shares::deposit(
Asset::PoolShare(SerdeWrapper(pool_id)),
&pool_creator,
data.pool_amount,
);
let _ = Swaps::pool_exit_with_exact_asset_amount(
Origin::signed(data.origin),
pool_id,
construct_asset(data.asset),
data.asset_amount,
data.pool_amount,
);
});
let _ = ext.commit_all();
});
42 changes: 42 additions & 0 deletions zrml/swaps/fuzz/pool_exit_with_exact_pool_amount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};

mod utils;
use orml_traits::MultiCurrency;
use utils::{construct_asset, ExactAmountData};
use zeitgeist_primitives::types::{Asset, SerdeWrapper};
use zrml_swaps::mock::Shares;

fuzz_target!(|data: ExactAmountData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
data.pool_creation.amount,
);
}

let pool_creator = data.pool_creation.origin;
let pool_id = data.pool_creation.create_pool();
// to exit a pool, origin also needs to have the pool tokens of the pool that they're exiting
let _ = Shares::deposit(
Asset::PoolShare(SerdeWrapper(pool_id)),
&pool_creator,
data.pool_amount,
);
let _ = Swaps::pool_exit_with_exact_pool_amount(
Origin::signed(data.origin),
pool_id,
construct_asset(data.asset),
data.pool_amount,
data.asset_amount,
);
});
let _ = ext.commit_all();
});
36 changes: 36 additions & 0 deletions zrml/swaps/fuzz/pool_join.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#![no_main]

use libfuzzer_sys::fuzz_target;

use utils::GeneralPoolData;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};
mod utils;
use utils::construct_asset;
use zrml_swaps::mock::Shares;

use orml_traits::MultiCurrency;

fuzz_target!(|data: GeneralPoolData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
data.pool_creation.amount,
);
}
let pool_id = data.pool_creation.create_pool();
// join a pool with a valid pool id
let _ = Swaps::pool_join(
Origin::signed(data.origin),
pool_id,
data.pool_amount,
data.asset_bounds,
);
});

let _ = ext.commit_all();
});
35 changes: 35 additions & 0 deletions zrml/swaps/fuzz/pool_join_with_exact_asset_amount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};

use utils::ExactAssetAmountData;
mod utils;
use orml_traits::MultiCurrency;
use utils::construct_asset;
use zrml_swaps::mock::Shares;

fuzz_target!(|data: ExactAssetAmountData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
// In order to successfully join the pool, data.asset_amount more tokens needed
data.pool_creation.amount.saturating_add(data.asset_amount),
);
}
let pool_id = data.pool_creation.create_pool();
let _ = Swaps::pool_join_with_exact_asset_amount(
Origin::signed(data.origin),
pool_id,
construct_asset(data.asset),
data.asset_amount,
data.pool_amount,
);
});
let _ = ext.commit_all();
});
35 changes: 35 additions & 0 deletions zrml/swaps/fuzz/pool_join_with_exact_pool_amount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use zrml_swaps::mock::{ExtBuilder, Origin, Swaps};

use utils::ExactAmountData;
mod utils;
use orml_traits::MultiCurrency;
use utils::construct_asset;
use zrml_swaps::mock::Shares;

fuzz_target!(|data: ExactAmountData| {
let mut ext = ExtBuilder::default().build();
let _ = ext.execute_with(|| {
// ensure that the account origin has a sufficient balance
// use orml_traits::MultiCurrency; required for this
for a in &data.pool_creation.assets {
let _ = Shares::deposit(
construct_asset(*a),
&data.pool_creation.origin,
// In order to successfully join the pool, data.asset_amount more tokens needed
data.pool_creation.amount.saturating_add(data.asset_amount),
);
}
let pool_id = data.pool_creation.create_pool();
let _ = Swaps::pool_join_with_exact_pool_amount(
Origin::signed(data.origin),
pool_id,
construct_asset(data.asset),
data.pool_amount,
data.asset_amount,
);
});
let _ = ext.commit_all();
});
Loading

0 comments on commit 464180f

Please sign in to comment.