Skip to content

Commit

Permalink
fix sent token validation
Browse files Browse the repository at this point in the history
  • Loading branch information
AlpinYukseloglu committed Feb 18, 2024
1 parent f343c19 commit 39579da
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 34 deletions.
1 change: 1 addition & 0 deletions contracts/orderbook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ cosmwasm-std = {version = "1.5.0", features = [
"cosmwasm_1_3", # "cosmwasm_1_4" # <- Enable this if you only deploy to chains that have CosmWasm 1.4 or higher
]}
cw-storage-plus = "1.1.0"
cw-utils = "1.0.3"
cw2 = "1.1.1"
schemars = "0.8.15"
serde = {version = "1.0.189", default-features = false, features = ["derive"]}
Expand Down
9 changes: 8 additions & 1 deletion contracts/orderbook/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::{StdError, Uint128};
use cosmwasm_std::{CoinsError, StdError, Uint128};
use cw_utils::PaymentError;
use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
Expand All @@ -20,4 +21,10 @@ pub enum ContractError {

#[error("Invalid book ID: {book_id:?}")]
InvalidBookId { book_id: u64 },

#[error(transparent)]
Coins(#[from] CoinsError),

#[error(transparent)]
PaymentError(#[from] PaymentError),
}
37 changes: 13 additions & 24 deletions contracts/orderbook/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,8 @@ 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,
})
}
use cosmwasm_std::{coin, BankMsg, DepsMut, Env, MessageInfo, Response, Uint128};
use cw_utils::must_pay;

pub fn place_limit(
deps: DepsMut,
Expand All @@ -38,20 +24,23 @@ pub fn place_limit(
return Err(ContractError::InvalidTickId { tick_id });
}

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

// Verify the sender has `quantity` balance of the correct denom
let denom = match order_direction {
// Determine the correct denom based on order direction
let expected_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 {

// Verify the funds sent with the message match the `quantity` for the correct denom
// We reject any quantity that is not exactly equal to the amount in the limit order being placed
let received = must_pay(&info, &expected_denom)?;
if received != quantity {
return Err(ContractError::InsufficientFunds {
balance,
balance: received,
required: quantity,
});
}
Expand All @@ -74,7 +63,7 @@ pub fn place_limit(
Ok(Response::new()
.add_message(BankMsg::Send {
to_address: env.contract.address.to_string(),
amount: vec![coin(quantity.u128(), denom)],
amount: vec![coin(quantity.u128(), expected_denom)],
})
.add_attribute("method", "placeLimit")
.add_attribute("owner", info.sender.to_string())
Expand Down
18 changes: 9 additions & 9 deletions contracts/orderbook/src/tests/test_order.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::ContractError;
use crate::order::place_limit;
use crate::order::*;
use crate::orderbook::*;
use crate::state::*;
use crate::types::OrderDirection;
Expand All @@ -11,7 +11,7 @@ struct PlaceLimitTestCase {
book_id: u64,
tick_id: i64,
quantity: Uint128,
balance: Uint128,
sent: Uint128,
expected_error: Option<ContractError>,
}

Expand All @@ -25,15 +25,15 @@ fn test_place_limit_variations() {
book_id: valid_book_id,
tick_id: 1,
quantity: Uint128::new(100),
balance: Uint128::new(1000),
sent: Uint128::new(100),
expected_error: None,
},
PlaceLimitTestCase {
name: "invalid book id",
book_id: invalid_book_id,
tick_id: 1,
quantity: Uint128::new(100),
balance: Uint128::new(1000),
sent: Uint128::new(1000),
expected_error: Some(ContractError::InvalidBookId {
book_id: invalid_book_id,
}),
Expand All @@ -43,7 +43,7 @@ fn test_place_limit_variations() {
book_id: valid_book_id,
tick_id: MAX_TICK + 1,
quantity: Uint128::new(100),
balance: Uint128::new(1000),
sent: Uint128::new(1000),
expected_error: Some(ContractError::InvalidTickId {
tick_id: MAX_TICK + 1,
}),
Expand All @@ -53,7 +53,7 @@ fn test_place_limit_variations() {
book_id: valid_book_id,
tick_id: 1,
quantity: Uint128::zero(),
balance: Uint128::new(1000),
sent: Uint128::new(1000),
expected_error: Some(ContractError::InvalidQuantity {
quantity: Uint128::zero(),
}),
Expand All @@ -63,7 +63,7 @@ fn test_place_limit_variations() {
book_id: valid_book_id,
tick_id: 1,
quantity: Uint128::new(1000),
balance: Uint128::new(500),
sent: Uint128::new(500),
expected_error: Some(ContractError::InsufficientFunds {
balance: Uint128::new(500),
required: Uint128::new(1000),
Expand All @@ -72,11 +72,11 @@ fn test_place_limit_variations() {
];

for test in test_cases {
let coin_vec = vec![coin(test.balance.u128(), "base")];
let coin_vec = vec![coin(test.sent.u128(), "base")];
let balances = [("creator", coin_vec.as_slice())];
let mut deps = mock_dependencies_with_balances(&balances);
let env = mock_env();
let info = mock_info("creator", &[]);
let info = mock_info("creator", &coin_vec);
let quote_denom = "quote".to_string();
let base_denom = "base".to_string();
let _create_response = create_orderbook(
Expand Down

0 comments on commit 39579da

Please sign in to comment.