Skip to content

Commit

Permalink
Merge pull request #323 from public-awesome/tasiov/mp-v2-listing-fee
Browse files Browse the repository at this point in the history
Add listing_fee map to marketplace v2 with unit tests
  • Loading branch information
jhernandezb authored Oct 16, 2024
2 parents d34a55f + 201f313 commit b9d2868
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 45 deletions.
19 changes: 18 additions & 1 deletion contracts/stargaze-marketplace-v2/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
state::Config,
};

use cosmwasm_std::{attr, Addr, Event};
use cosmwasm_std::{attr, Addr, Event, Uint128};
use std::vec;

pub struct ConfigEvent<'a> {
Expand Down Expand Up @@ -43,6 +43,23 @@ impl<'a> From<CollectionDenomEvent<'a>> for Event {
}
}

pub struct ListingFeeEvent<'a> {
pub ty: &'a str,
pub denom: &'a str,
pub amount: &'a Option<Uint128>,
}

impl<'a> From<ListingFeeEvent<'a>> for Event {
fn from(lfe: ListingFeeEvent) -> Self {
let mut event = Event::new(lfe.ty.to_string());
event = event.add_attribute("denom", lfe.denom.to_string());
if let Some(amount) = lfe.amount {
event = event.add_attribute("fee", amount.to_string());
}
event
}
}

pub struct AskEvent<'a> {
pub ty: &'a str,
pub ask: &'a Ask,
Expand Down
93 changes: 79 additions & 14 deletions contracts/stargaze-marketplace-v2/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
use cosmwasm_std::{ensure, ensure_eq, has_coins, Addr, Coin, DepsMut, Env, MessageInfo, Response};
use cw_utils::{nonpayable, one_coin, NativeBalance};
use sg_marketplace_common::{
coin::{transfer_coin, transfer_coins},
nft::{only_owner, only_tradable, transfer_nft},
MarketplaceStdError,
};
use std::ops::{Add, Sub};

use crate::{
error::ContractError,
events::{AskEvent, BidEvent, CollectionBidEvent, CollectionDenomEvent, ConfigEvent},
events::{
AskEvent, BidEvent, CollectionBidEvent, CollectionDenomEvent, ConfigEvent, ListingFeeEvent,
},
helpers::{finalize_sale, generate_id, only_contract_admin, only_valid_price},
msg::ExecuteMsg,
orders::{Ask, Bid, CollectionBid, MatchingBid, OrderDetails},
state::{
asks, bids, collection_bids, Config, Denom, OrderId, TokenId, COLLECTION_DENOMS, CONFIG,
NONCE,
LISTING_FEES, NONCE,
},
};

use cosmwasm_std::{ensure, ensure_eq, has_coins, Addr, DepsMut, Env, MessageInfo, Response};
use cw_utils::{nonpayable, NativeBalance};
use sg_marketplace_common::{
coin::{transfer_coin, transfer_coins},
nft::{only_owner, only_tradable, transfer_nft},
MarketplaceStdError,
};
use std::ops::{Add, Sub};

#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;

Expand All @@ -38,6 +40,10 @@ pub fn execute(
ExecuteMsg::UpdateCollectionDenom { collection, denom } => {
execute_update_collection_denom(deps, env, info, api.addr_validate(&collection)?, denom)
}
ExecuteMsg::SetListingFee { fee } => execute_set_listing_fee(deps, env, info, fee),
ExecuteMsg::RemoveListingFee { denom } => {
execute_remove_listing_fee(deps, env, info, denom)
}
ExecuteMsg::SetAsk {
collection,
token_id,
Expand Down Expand Up @@ -185,6 +191,50 @@ pub fn execute_update_collection_denom(
Ok(response)
}

pub fn execute_set_listing_fee(
deps: DepsMut,
env: Env,
info: MessageInfo,
fee: Coin,
) -> Result<Response, ContractError> {
only_contract_admin(&deps.querier, &env, &info)?;

LISTING_FEES.save(deps.storage, fee.denom.clone(), &fee.amount)?;

let response = Response::new().add_event(
ListingFeeEvent {
ty: "set-listing-fee",
denom: &fee.denom,
amount: &Some(fee.amount),
}
.into(),
);

Ok(response)
}

pub fn execute_remove_listing_fee(
deps: DepsMut,
env: Env,
info: MessageInfo,
denom: Denom,
) -> Result<Response, ContractError> {
only_contract_admin(&deps.querier, &env, &info)?;

LISTING_FEES.remove(deps.storage, denom.clone());

let response = Response::new().add_event(
ListingFeeEvent {
ty: "remove-listing-fee",
denom: &denom,
amount: &None,
}
.into(),
);

Ok(response)
}

pub fn execute_set_ask(
deps: DepsMut,
env: Env,
Expand All @@ -194,16 +244,31 @@ pub fn execute_set_ask(
details: OrderDetails<Addr>,
sell_now: bool,
) -> Result<Response, ContractError> {
nonpayable(&info)?;
only_owner(&deps.querier, &info, &collection, &token_id)?;
only_tradable(&deps.querier, &env.block, &collection)?;

let config = CONFIG.load(deps.storage)?;
only_valid_price(deps.storage, &config, &collection, &details.price)?;

let ask = Ask::new(info.sender.clone(), collection, token_id, details);
// Check and collect listing fee
let listing_payment = one_coin(&info)?;
let listing_fee = LISTING_FEES.may_load(deps.storage, listing_payment.denom.clone())?;
if let Some(_listing_fee) = listing_fee {
ensure_eq!(
listing_payment.amount,
_listing_fee,
ContractError::InvalidInput("payment amount does not match listing fee".to_string())
);
} else {
Err(ContractError::InvalidInput(format!(
"listing fee for {} not found",
listing_payment.denom
)))?;
}

let mut response = Response::new();
let mut response = transfer_coin(listing_payment, &config.fee_manager, Response::new());

let ask = Ask::new(info.sender.clone(), collection, token_id, details);

let match_result = ask.match_with_bid(deps.as_ref())?;

Expand Down
8 changes: 7 additions & 1 deletion contracts/stargaze-marketplace-v2/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};

use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Addr;
use cosmwasm_std::{Addr, Coin};
use sg_index_query::QueryOptions;

#[cw_serde]
Expand All @@ -23,6 +23,12 @@ pub enum ExecuteMsg {
collection: String,
denom: Denom,
},
SetListingFee {
fee: Coin,
},
RemoveListingFee {
denom: Denom,
},
// Marketplace messages
SetAsk {
collection: String,
Expand Down
4 changes: 3 additions & 1 deletion contracts/stargaze-marketplace-v2/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::ContractError;
use crate::{constants::MAX_BASIS_POINTS, orders::Ask};

use cosmwasm_schema::cw_serde;
use cosmwasm_std::{ensure, Addr, Api, Storage};
use cosmwasm_std::{ensure, Addr, Api, Storage, Uint128};
use cw_address_like::AddressLike;
use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex};

Expand Down Expand Up @@ -66,6 +66,8 @@ pub const CONFIG: Item<Config<Addr>> = Item::new("C");

pub const COLLECTION_DENOMS: Map<Addr, Denom> = Map::new("D");

pub const LISTING_FEES: Map<Denom, Uint128> = Map::new("L");

pub const NONCE: Item<u64> = Item::new("N");

/// Defines indices for accessing Asks
Expand Down
16 changes: 12 additions & 4 deletions contracts/stargaze-marketplace-v2/src/tests/helpers/marketplace.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{msg::ExecuteMsg, orders::OrderDetails};
use crate::{
msg::ExecuteMsg,
orders::OrderDetails,
tests::setup::setup_contracts::{LISTING_FEE, NATIVE_DENOM},
};

use cosmwasm_std::{Addr, Coin, Empty};
use cosmwasm_std::{coin, Addr, Empty};
use cw721_base::msg::ExecuteMsg as Cw721ExecuteMsg;
use cw_multi_test::{App, Executor};

Expand Down Expand Up @@ -33,7 +37,6 @@ pub fn mint_and_set_ask(
marketplace: &Addr,
collection: &Addr,
token_id: &str,
send_funds: &[Coin],
details: OrderDetails<String>,
) {
mint(app, creator, owner, collection, token_id);
Expand All @@ -45,7 +48,12 @@ pub fn mint_and_set_ask(
details,
};

let response = app.execute_contract(owner.clone(), marketplace.clone(), &set_ask, send_funds);
let response = app.execute_contract(
owner.clone(),
marketplace.clone(),
&set_ask,
&[coin(LISTING_FEE, NATIVE_DENOM)],
);

assert!(response.is_ok());
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::ContractError;
use crate::{msg::InstantiateMsg, state::Config};
use crate::{
msg::{ExecuteMsg, InstantiateMsg},
state::Config,
ContractError,
};

use cosmwasm_std::{Addr, Decimal, Empty};
use cosmwasm_std::{Addr, Coin, Decimal, Empty, Uint128};
use cw721_base::InstantiateMsg as Cw721InstantiateMsg;
use cw_multi_test::{App, Contract, ContractWrapper, Executor};
use stargaze_royalty_registry::msg::InstantiateMsg as RoyaltyRegistryInstantiateMsg;
Expand All @@ -10,6 +13,7 @@ use stargaze_royalty_registry::state::Config as RoyaltyRegistryConfig;
pub const NATIVE_DENOM: &str = "ustars";
pub const ATOM_DENOM: &str = "uatom";
pub const JUNO_DENOM: &str = "ujuno";
pub const LISTING_FEE: u128 = 1000000u128;

pub fn contract_cw721() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(
Expand Down Expand Up @@ -106,5 +110,32 @@ pub fn setup_marketplace(
Some(marketplace_admin.to_string()),
)
.unwrap();

app.execute_contract(
marketplace_admin.clone(),
marketplace.clone(),
&ExecuteMsg::SetListingFee {
fee: Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::from(LISTING_FEE),
},
},
&[],
)
.unwrap();

app.execute_contract(
marketplace_admin.clone(),
marketplace.clone(),
&ExecuteMsg::SetListingFee {
fee: Coin {
denom: ATOM_DENOM.to_string(),
amount: Uint128::from(LISTING_FEE),
},
},
&[],
)
.unwrap();

Ok(marketplace)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ fn try_query_asks_by_collection() {
&marketplace,
&collection,
&token_id.to_string(),
&[],
OrderDetails {
price,
recipient: None,
Expand Down Expand Up @@ -129,7 +128,6 @@ fn try_query_asks_by_creator() {
&marketplace,
&collection,
&token_id.to_string(),
&[],
OrderDetails {
price,
recipient: None,
Expand Down
Loading

0 comments on commit b9d2868

Please sign in to comment.