Skip to content

Commit

Permalink
adds arbitrage bot address for selling, adds some test cases for runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
vanderian committed Nov 26, 2024
1 parent a8ea7eb commit 70d49a9
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion pallets/market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ pub mod pallet {
/// A list of Foundation members with elevated rights
type FoundationAccountsProvider: Get<Vec<Self::AccountId>>;

/// A special account used for nontransferable tokens to allow 'selling' to balance pools
type ArbitrageBot: Contains<Self::AccountId>;

#[cfg(feature = "runtime-benchmarks")]
type ComputeIssuance: ComputeIssuance;
}
Expand Down Expand Up @@ -975,7 +978,7 @@ pub mod pallet {
// check input asset id, or the foundation has a veto
ensure!(
!T::NontransferableTokens::contains(&swap.0) ||
T::FoundationAccountsProvider::get().contains(&sender),
T::ArbitrageBot::contains(sender),
Error::<T>::NontransferableToken
);

Expand Down
5 changes: 3 additions & 2 deletions rollup/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ targets = ["x86_64-unknown-linux-gnu"]
substrate-wasm-builder = { workspace = true }

[dependencies]
array-bytes = { workspace = true }
codec = { workspace = true, default-features = false, features = ["derive"] }
scale-info = { workspace = true, default-features = false, features = ["derive"] }
hex-literal = { workspace = true }
log = { workspace = true, default-features = false }
array-bytes = { workspace = true }
scale-info = { workspace = true, default-features = false, features = ["derive"] }
smallvec = "1.6.1"
static_assertions = "1.1.0"

Expand Down
1 change: 1 addition & 0 deletions rollup/runtime/integration-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod identity;
mod maintenance;
mod market;
mod membership;
mod nontransfer;
mod proof_of_stake;
mod proxy;
mod setup;
Expand Down
230 changes: 230 additions & 0 deletions rollup/runtime/integration-test/src/nontransfer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
use sp_runtime::AccountId20;

use crate::setup::*;

const ASSET_ID_1: TokenId = NATIVE_ASSET_ID + 1;
const POOL_ID: TokenId = ASSET_ID_1 + 1;
const ARB: [u8; 20] = hex_literal::hex!["fc741134c82b81b7ab7efbf334b0c90ff8dbf22c"];

fn test_env() -> TestExternalities {
ExtBuilder {
balances: vec![
(AccountId::from(ALICE), NATIVE_ASSET_ID, 100 * UNIT),
(AccountId::from(ARB), NATIVE_ASSET_ID, 100 * UNIT),
(AccountId::from(ALICE), ASSET_ID_1, 100 * UNIT),
],
..ExtBuilder::default()
}
.build()
}

fn root() -> RuntimeOrigin {
RuntimeOrigin::root().into()
}

fn origin() -> RuntimeOrigin {
RuntimeOrigin::signed(AccountId::from(ALICE))
}

#[test]
fn test_tokens_calls_should_block() {
let mut ext = test_env();
ext.execute_with(|| {
let who = AccountId::from(ALICE);
let bob = AccountId::from(BOB);
let amount = UNIT;
assert_err!(
orml_tokens::Pallet::<Runtime>::mint(root(), NATIVE_ASSET_ID, who, amount),
orml_tokens::Error::<Runtime>::NontransferableToken
);
assert_err!(
orml_tokens::Pallet::<Runtime>::set_balance(
root(),
who,
NATIVE_ASSET_ID,
amount,
amount
),
orml_tokens::Error::<Runtime>::NontransferableToken
);
assert_err!(
orml_tokens::Pallet::<Runtime>::transfer(origin(), bob, NATIVE_ASSET_ID, amount),
orml_tokens::Error::<Runtime>::NontransferableToken
);
assert_err!(
orml_tokens::Pallet::<Runtime>::force_transfer(
root(),
who,
bob,
NATIVE_ASSET_ID,
amount
),
orml_tokens::Error::<Runtime>::NontransferableToken
);
assert_err!(
orml_tokens::Pallet::<Runtime>::transfer_all(origin(), bob, NATIVE_ASSET_ID, false),
orml_tokens::Error::<Runtime>::NontransferableToken
);
assert_err!(
orml_tokens::Pallet::<Runtime>::transfer_keep_alive(
origin(),
bob,
NATIVE_ASSET_ID,
amount
),
orml_tokens::Error::<Runtime>::NontransferableToken
);
});
}

#[test]
fn test_market_should_block() {
let mut ext = test_env();
ext.execute_with(|| {
let foundation = AccountId::from(ALICE);
let bob = AccountId::from(BOB);
let amount = 100 * UNIT;

// user cannot create pool, foundation can
assert_err!(
pallet_market::Pallet::<Runtime>::create_pool(
RuntimeOrigin::signed(bob),
pallet_market::PoolKind::Xyk,
NATIVE_ASSET_ID,
amount,
ASSET_ID_1,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_ok!(pallet_market::Pallet::<Runtime>::create_pool(
RuntimeOrigin::signed(foundation),
pallet_market::PoolKind::Xyk,
NATIVE_ASSET_ID,
amount,
ASSET_ID_1,
amount,
));

// none can mint
assert_err!(
pallet_market::Pallet::<Runtime>::mint_liquidity(
RuntimeOrigin::signed(foundation),
POOL_ID,
NATIVE_ASSET_ID,
amount,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_err!(
pallet_market::Pallet::<Runtime>::mint_liquidity_fixed_amounts(
RuntimeOrigin::signed(foundation),
POOL_ID,
(amount, amount),
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_err!(
pallet_market::Pallet::<Runtime>::mint_liquidity_using_vesting_native_tokens(
RuntimeOrigin::signed(foundation),
POOL_ID,
amount,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_err!(
pallet_market::Pallet::<Runtime>::mint_liquidity_using_vesting_native_tokens_by_vesting_index(
RuntimeOrigin::signed(foundation),
POOL_ID,
0,
None,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);

// user cannot burn, foundation can
assert_err!(
pallet_market::Pallet::<Runtime>::burn_liquidity(
RuntimeOrigin::signed(bob),
POOL_ID,
amount,
amount,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_ok!(pallet_market::Pallet::<Runtime>::burn_liquidity(
RuntimeOrigin::signed(foundation),
POOL_ID,
UNIT,
0,
0,
));

// user & foundation cannot sell, ARB bot can
assert_err!(
pallet_market::Pallet::<Runtime>::multiswap_asset(
RuntimeOrigin::signed(bob),
vec![POOL_ID],
NATIVE_ASSET_ID,
UNIT,
ASSET_ID_1,
0,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_err!(
pallet_market::Pallet::<Runtime>::multiswap_asset(
RuntimeOrigin::signed(foundation),
vec![POOL_ID],
NATIVE_ASSET_ID,
UNIT,
ASSET_ID_1,
0,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_ok!(pallet_market::Pallet::<Runtime>::multiswap_asset(
RuntimeOrigin::signed(AccountId::from(ARB)),
vec![POOL_ID],
NATIVE_ASSET_ID,
UNIT,
ASSET_ID_1,
0,
));
assert_err!(
pallet_market::Pallet::<Runtime>::multiswap_asset_buy(
RuntimeOrigin::signed(bob),
vec![POOL_ID],
ASSET_ID_1,
UNIT,
NATIVE_ASSET_ID,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_err!(
pallet_market::Pallet::<Runtime>::multiswap_asset_buy(
RuntimeOrigin::signed(foundation),
vec![POOL_ID],
ASSET_ID_1,
UNIT,
NATIVE_ASSET_ID,
amount,
),
pallet_market::Error::<Runtime>::NontransferableToken
);
assert_ok!(pallet_market::Pallet::<Runtime>::multiswap_asset_buy(
RuntimeOrigin::signed(AccountId::from(ARB)),
vec![POOL_ID],
ASSET_ID_1,
UNIT,
NATIVE_ASSET_ID,
amount,
));
});
}
1 change: 1 addition & 0 deletions rollup/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ impl pallet_market::Config for Runtime {
type ComputeIssuance = Issuance;
type NontransferableTokens = tokens::NontransferableTokens;
type FoundationAccountsProvider = cfg::pallet_membership::FoundationAccountsProvider;
type ArbitrageBot = tokens::ArbitrageBot;
}

// Create the runtime by composing the FRAME pallets that were previously configured.
Expand Down
8 changes: 8 additions & 0 deletions rollup/runtime/src/runtime_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,17 @@ pub mod tokens {
#[cfg(not(feature = "unlocked"))]
pub type NontransferableTokens = Equals<ConstU32<RX_TOKEN_ID>>;

#[cfg(any(feature = "unlocked", feature = "runtime-benchmarks"))]
pub type ArbitrageBot = Nothing;
#[cfg(not(feature = "unlocked"))]
pub type ArbitrageBot = Equals<ArbitrageBotAddr>;

parameter_types! {
pub const RxTokenId: TokenId = RX_TOKEN_ID;
pub const EthTokenId: TokenId = ETH_TOKEN_ID;
pub ArbitrageBotAddr: AccountId = sp_runtime::AccountId20::from(
hex_literal::hex!["fc741134c82b81b7ab7efbf334b0c90ff8dbf22c"]
);
}
}

Expand Down

0 comments on commit 70d49a9

Please sign in to comment.