Skip to content

Commit

Permalink
implement limit placement logic and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AlpinYukseloglu committed Feb 18, 2024
1 parent 3fc8189 commit 0dd1863
Show file tree
Hide file tree
Showing 6 changed files with 368 additions and 18 deletions.
19 changes: 12 additions & 7 deletions contracts/orderbook/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, C
/// Handling contract execution
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
Expand All @@ -60,16 +60,21 @@ pub fn execute(
ExecuteMsg::CreateOrderbook {
quote_denom,
base_denom,
} => orderbook::create_orderbook(_deps, _env, _info, quote_denom, base_denom),
} => orderbook::create_orderbook(deps, env, info, quote_denom, base_denom),

// Places limit order on given market
ExecuteMsg::PlaceLimit => order::place_limit(_deps, _env, _info),
ExecuteMsg::PlaceLimit {
book_id,
tick_id,
order_direction,
quantity,
} => order::place_limit(deps, env, info, book_id, tick_id, order_direction, quantity),

// Cancels limit order with given ID
ExecuteMsg::CancelLimit => order::cancel_limit(_deps, _env, _info),
ExecuteMsg::CancelLimit => order::cancel_limit(deps, env, info),

// Places a market order on the passed in market
ExecuteMsg::PlaceMarket => order::place_market(_deps, _env, _info),
ExecuteMsg::PlaceMarket => order::place_market(deps, env, info),
}
}

Expand Down
14 changes: 13 additions & 1 deletion contracts/orderbook/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmwasm_std::StdError;
use cosmwasm_std::{StdError, Uint128};
use thiserror::Error;

#[derive(Error, Debug)]
Expand All @@ -8,4 +8,16 @@ pub enum ContractError {

#[error("Unauthorized")]
Unauthorized {},

#[error("Invalid tick ID: {tick_id:?}")]
InvalidTickId { tick_id: i64 },

#[error("Invalid quantity: {quantity:?}")]
InvalidQuantity { quantity: Uint128 },

#[error("Insufficient funds. Balance: {balance:?}, Required: {required:?}")]
InsufficientFunds { balance: Uint128, required: Uint128 },

#[error("Invalid book ID: {book_id:?}")]
InvalidBookId { book_id: u64 },
}
13 changes: 9 additions & 4 deletions contracts/orderbook/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::types::OrderDirection;
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Uint128;

/// Message type for `instantiate` entry_point
#[cw_serde]
Expand All @@ -7,14 +9,17 @@ pub struct InstantiateMsg {}
/// Message type for `execute` entry_point
#[cw_serde]
pub enum ExecuteMsg {

// === Orderbook ===

CreateOrderbook{
CreateOrderbook {
quote_denom: String,
base_denom: String,
},
PlaceLimit,
PlaceLimit {
book_id: u64,
tick_id: i64,
order_direction: OrderDirection,
quantity: Uint128,
},
CancelLimit,
PlaceMarket,
}
Expand Down
84 changes: 78 additions & 6 deletions contracts/orderbook/src/order.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,88 @@
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
use crate::error::ContractError;
use crate::state::*;
use crate::state::{MAX_TICK, MIN_TICK, ORDERBOOKS};
use crate::types::{LimitOrder, OrderDirection};
use cosmwasm_std::{
coin, Addr, BalanceResponse, BankMsg, BankQuery, Coin, DepsMut, Env, MessageInfo,
QuerierWrapper, QueryRequest, Response, StdResult, Uint128,
};

// TODO: move this into a balance helper file
pub fn query_balance(querier: &QuerierWrapper, addr: &Addr, denom: &str) -> StdResult<Coin> {
let res: BalanceResponse = querier.query(&QueryRequest::Bank(BankQuery::Balance {
address: addr.to_string(),
denom: denom.to_string(),
}))?;
Ok(Coin {
denom: denom.to_string(),
amount: res.amount.amount,
})
}

pub fn place_limit(
_deps: DepsMut,
_env: Env,
deps: DepsMut,
env: Env,
info: MessageInfo,
book_id: u64,
tick_id: i64,
order_direction: OrderDirection,
quantity: Uint128,
) -> Result<Response, ContractError> {
// TODO: Implement place_limit
// Validate book_id exists
let orderbook = ORDERBOOKS
.load(deps.storage, &book_id)
.map_err(|_| ContractError::InvalidBookId { book_id })?;

// Validate tick_id is within valid range
if tick_id < MIN_TICK || tick_id > MAX_TICK {
return Err(ContractError::InvalidTickId { tick_id });
}

// Validate order_quantity is > 0
if quantity.is_zero() {
return Err(ContractError::InvalidQuantity { quantity });
}

// Verify the sender has `quantity` balance of the correct denom
let denom = match order_direction {
OrderDirection::Bid => orderbook.quote_denom,
OrderDirection::Ask => orderbook.base_denom,
};
let balance = query_balance(&deps.querier, &info.sender, &denom)?.amount;
if balance < quantity {
return Err(ContractError::InsufficientFunds {
balance,
required: quantity,
});
}

// Generate a new order ID
let order_id = new_order_id(deps.storage)?;

let limit_order = LimitOrder::new(
book_id,
tick_id,
order_id,
order_direction.clone(),
info.sender.clone(),
quantity,
);

// Save the order to the orderbook
orders().save(deps.storage, &(book_id, tick_id, order_id), &limit_order)?;

Ok(Response::new()
.add_message(BankMsg::Send {
to_address: env.contract.address.to_string(),
amount: vec![coin(quantity.u128(), denom)],
})
.add_attribute("method", "placeLimit")
.add_attribute("owner", info.sender))
.add_attribute("owner", info.sender.to_string())
.add_attribute("book_id", book_id.to_string())
.add_attribute("tick_id", tick_id.to_string())
.add_attribute("order_id", order_id.to_string())
.add_attribute("order_direction", format!("{:?}", order_direction))
.add_attribute("quantity", quantity.to_string()))
}

pub fn cancel_limit(
Expand All @@ -35,4 +107,4 @@ pub fn place_market(
Ok(Response::new()
.add_attribute("method", "placeMarket")
.add_attribute("owner", info.sender))
}
}
1 change: 1 addition & 0 deletions contracts/orderbook/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod test_order;
pub mod test_orderbook;
pub mod test_state;
Loading

0 comments on commit 0dd1863

Please sign in to comment.