Skip to content

Commit

Permalink
Permissionless Pool Creation (#322)
Browse files Browse the repository at this point in the history
* first iteration of permissionless pool creation

* permissionless pool creation

* whitelist false for permissionless
  • Loading branch information
tonylee08 authored Jan 31, 2025
1 parent 870f4aa commit 0040493
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 15 deletions.
10 changes: 6 additions & 4 deletions packages/deepbook/sources/helper/constants.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

module deepbook::constants;

const CURRENT_VERSION: u64 = 1; // Update version during upgrades
const POOL_CREATION_FEE: u64 = 0 * 1_000_000; // 0 DEEP
const CURRENT_VERSION: u64 = 2; // Update version during upgrades
const POOL_CREATION_FEE: u64 = 500 * 1_000_000; // 500 DEEP
const FLOAT_SCALING: u64 = 1_000_000_000;
const FLOAT_SCALING_U128: u128 = 1_000_000_000;
const MAX_U64: u64 = ((1u128 << 64) - 1) as u64;
Expand All @@ -19,9 +19,11 @@ const FEE_PENALTY_MULTIPLIER: u64 = 250_000_000; // 25%
// Restrictions on limit orders.
// No restriction on the order.
const NO_RESTRICTION: u8 = 0;
// Mandates that whatever amount of an order that can be executed in the current transaction, be filled and then the rest of the order canceled.
// Mandates that whatever amount of an order that can be executed in the current
// transaction, be filled and then the rest of the order canceled.
const IMMEDIATE_OR_CANCEL: u8 = 1;
// Mandates that the entire order size be filled in the current transaction. Otherwise, the order is canceled.
// Mandates that the entire order size be filled in the current transaction.
// Otherwise, the order is canceled.
const FILL_OR_KILL: u8 = 2;
// Mandates that the entire order be passive. Otherwise, cancel the order.
const POST_ONLY: u8 = 3;
Expand Down
48 changes: 43 additions & 5 deletions packages/deepbook/sources/pool.move
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,42 @@ public struct DeepBurned<
deep_burned: u64,
}

// === Public-Mutative Functions * POOL CREATION * ===
/// Create a new pool. The pool is registered in the registry.
/// Checks are performed to ensure the tick size, lot size,
/// and min size are valid.
/// The creation fee is transferred to the treasury address.
/// Returns the id of the pool created
public fun create_permissionless_pool<BaseAsset, QuoteAsset>(
registry: &mut Registry,
tick_size: u64,
lot_size: u64,
min_size: u64,
creation_fee: Coin<DEEP>,
ctx: &mut TxContext,
): ID {
assert!(
creation_fee.value() == constants::pool_creation_fee(),
EInvalidFee,
);
let base_type = type_name::get<BaseAsset>();
let quote_type = type_name::get<QuoteAsset>();
let whitelisted_pool = false;
let stable_pool =
registry.is_stablecoin(base_type) && registry.is_stablecoin(quote_type);

create_pool<BaseAsset, QuoteAsset>(
registry,
tick_size,
lot_size,
min_size,
creation_fee,
whitelisted_pool,
stable_pool,
ctx,
)
}

// === Public-Mutative Functions * EXCHANGE * ===
/// Place a limit order. Quantity is in base asset terms.
/// For current version pay_with_deep must be true, so the fee will be paid with
Expand Down Expand Up @@ -660,7 +696,6 @@ public fun burn_deep<BaseAsset, QuoteAsset>(
/// Create a new pool. The pool is registered in the registry.
/// Checks are performed to ensure the tick size, lot size, and min size are
/// valid.
/// The creation fee is transferred to the treasury address.
/// Returns the id of the pool created
public fun create_pool_admin<BaseAsset, QuoteAsset>(
registry: &mut Registry,
Expand Down Expand Up @@ -768,6 +803,13 @@ public fun whitelisted<BaseAsset, QuoteAsset>(
self.load_inner().state.governance().whitelisted()
}

/// Accessor to check if the pool is a stablecoin pool.
public fun stable_pool<BaseAsset, QuoteAsset>(
self: &Pool<BaseAsset, QuoteAsset>,
): bool {
self.load_inner().state.governance().stable()
}

public fun registered_pool<BaseAsset, QuoteAsset>(
self: &Pool<BaseAsset, QuoteAsset>,
): bool {
Expand Down Expand Up @@ -1072,10 +1114,6 @@ public(package) fun create_pool<BaseAsset, QuoteAsset>(
stable_pool: bool,
ctx: &mut TxContext,
): ID {
assert!(
creation_fee.value() == constants::pool_creation_fee(),
EInvalidFee,
);
assert!(tick_size > 0, EInvalidTickSize);
assert!(math::is_power_of_ten(tick_size), EInvalidTickSize);
assert!(lot_size > 0, EInvalidLotSize);
Expand Down
80 changes: 79 additions & 1 deletion packages/deepbook/sources/registry.move
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module deepbook::registry;
use deepbook::constants;
use std::type_name::{Self, TypeName};
use sui::bag::{Self, Bag};
use sui::dynamic_field;
use sui::vec_set::{Self, VecSet};
use sui::versioned::{Self, Versioned};

Expand All @@ -17,6 +18,8 @@ const EPackageVersionNotEnabled: u64 = 3;
const EVersionNotEnabled: u64 = 4;
const EVersionAlreadyEnabled: u64 = 5;
const ECannotDisableCurrentVersion: u64 = 6;
const ECoinAlreadyWhitelisted: u64 = 7;
const ECoinNotWhitelisted: u64 = 8;

public struct REGISTRY has drop {}

Expand All @@ -42,6 +45,8 @@ public struct PoolKey has copy, drop, store {
quote: TypeName,
}

public struct StableCoinKey has store, copy, drop {}

fun init(_: REGISTRY, ctx: &mut TxContext) {
let registry_inner = RegistryInner {
allowed_versions: vec_set::singleton(constants::current_version()),
Expand Down Expand Up @@ -103,6 +108,78 @@ public fun disable_version(
self.allowed_versions.remove(&version);
}

/// Adds a stablecoin to the whitelist
/// Only Admin can add stablecoin
public fun add_stablecoin<StableCoin>(
self: &mut Registry,
_cap: &DeepbookAdminCap,
) {
let _: &mut RegistryInner = self.load_inner_mut();
let stable_type = type_name::get<StableCoin>();
if (
!dynamic_field::exists_(
&self.id,
StableCoinKey {},
)
) {
dynamic_field::add(
&mut self.id,
StableCoinKey {},
vec_set::singleton(stable_type),
);
} else {
let stable_coins: &mut VecSet<TypeName> = dynamic_field::borrow_mut(
&mut self.id,
StableCoinKey {},
);
assert!(!stable_coins.contains(&stable_type), ECoinAlreadyWhitelisted);
stable_coins.insert(stable_type);
};
}

/// Removes a stablecoin from the whitelist
/// Only Admin can remove stablecoin
public fun remove_stablecoin<StableCoin>(
self: &mut Registry,
_cap: &DeepbookAdminCap,
) {
let _: &mut RegistryInner = self.load_inner_mut();
let stable_type = type_name::get<StableCoin>();
assert!(
dynamic_field::exists_(
&self.id,
StableCoinKey {},
),
ECoinNotWhitelisted,
);
let stable_coins: &mut VecSet<TypeName> = dynamic_field::borrow_mut(
&mut self.id,
StableCoinKey {},
);
assert!(stable_coins.contains(&stable_type), ECoinNotWhitelisted);
stable_coins.remove(&stable_type);
}

/// Returns whether the given coin is whitelisted
public fun is_stablecoin(self: &Registry, stable_type: TypeName): bool {
let _: &RegistryInner = self.load_inner();
if (
!dynamic_field::exists_(
&self.id,
StableCoinKey {},
)
) {
false
} else {
let stable_coins: &VecSet<TypeName> = dynamic_field::borrow(
&self.id,
StableCoinKey {},
);

stable_coins.contains(&stable_type)
}
}

// === Public-Package Functions ===
public(package) fun load_inner_mut(self: &mut Registry): &mut RegistryInner {
let inner: &mut RegistryInner = self.inner.load_value_mut();
Expand All @@ -116,7 +193,8 @@ public(package) fun load_inner_mut(self: &mut Registry): &mut RegistryInner {
}

/// Register a new pool in the registry.
/// Asserts if (Base, Quote) pool already exists or (Quote, Base) pool already exists.
/// Asserts if (Base, Quote) pool already exists or
/// (Quote, Base) pool already exists.
public(package) fun register_pool<BaseAsset, QuoteAsset>(
self: &mut Registry,
pool_id: ID,
Expand Down
9 changes: 4 additions & 5 deletions packages/deepbook/sources/state/governance.move
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ public(package) fun whitelisted(self: &Governance): bool {
self.whitelisted
}

public(package) fun stable(self: &Governance): bool {
self.stable
}

public(package) fun quorum(self: &Governance): u64 {
self.quorum
}
Expand Down Expand Up @@ -312,11 +316,6 @@ public fun voting_power(self: &Governance): u64 {
self.voting_power
}

#[test_only]
public fun stable(self: &Governance): bool {
self.stable
}

#[test_only]
public fun proposals(self: &Governance): VecMap<ID, Proposal> {
self.proposals
Expand Down
Loading

0 comments on commit 0040493

Please sign in to comment.