From e32c32e5a165f8337a3de9525cc953b52bbf4d95 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 12:41:01 +0300 Subject: [PATCH 01/13] adds auction creation fee --- contracts/auctions/src/contract.rs | 19 +++++--- contracts/auctions/src/error.rs | 2 +- contracts/auctions/src/storage.rs | 76 +++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/contracts/auctions/src/contract.rs b/contracts/auctions/src/contract.rs index 03fbce3..30d31b9 100644 --- a/contracts/auctions/src/contract.rs +++ b/contracts/auctions/src/contract.rs @@ -4,10 +4,10 @@ use crate::{ collection, error::ContractError, storage::{ - generate_auction_id, get_admin, get_auction_by_id, get_auction_token, get_auctions, - get_auctions_by_seller_id, get_highest_bid, is_initialized, save_admin, save_auction_by_id, - save_auction_by_seller, save_auction_token, set_highest_bid, set_initialized, update_admin, - validate_input_params, Auction, AuctionStatus, HighestBid, ItemInfo, + generate_auction_id, get_admin, get_auction_by_id, get_auctions, get_auctions_by_seller_id, + get_config, get_highest_bid, is_initialized, save_admin, save_auction_by_id, + save_auction_by_seller, save_config, set_highest_bid, set_initialized, update_admin, + validate_input_params, Auction, AuctionStatus, Config, HighestBid, ItemInfo, }, token, }; @@ -22,6 +22,7 @@ impl MarketplaceContract { env: Env, admin: Address, auction_token: Address, + auction_creation_fee: u128, ) -> Result<(), ContractError> { admin.require_auth(); @@ -31,7 +32,13 @@ impl MarketplaceContract { } save_admin(&env, &admin); - save_auction_token(&env, auction_token); + + let config = Config { + auction_token, + auction_creation_fee, + }; + + save_config(&env, config); set_initialized(&env); @@ -59,7 +66,7 @@ impl MarketplaceContract { ]; validate_input_params(&env, &input_values[..])?; - let auction_token = get_auction_token(&env)?; + let auction_token = get_config(&env)?.auction_token; let nft_client = collection::Client::new(&env, &item_info.collection_addr); let item_balance = nft_client.balance_of(&seller, &item_info.item_id); diff --git a/contracts/auctions/src/error.rs b/contracts/auctions/src/error.rs index 53ec611..c5ae3fe 100644 --- a/contracts/auctions/src/error.rs +++ b/contracts/auctions/src/error.rs @@ -21,5 +21,5 @@ pub enum ContractError { InvalidBidder = 14, AdminNotFound = 15, NoBidFound = 16, - AuctionTokenNotFound = 17, + ConfigNotFound = 17, } diff --git a/contracts/auctions/src/storage.rs b/contracts/auctions/src/storage.rs index e633510..6bdc2c3 100644 --- a/contracts/auctions/src/storage.rs +++ b/contracts/auctions/src/storage.rs @@ -1,6 +1,6 @@ use soroban_sdk::{contracttype, log, panic_with_error, vec, Address, Env, Vec}; -use crate::error::ContractError; +use crate::{collection::DataKey, error::ContractError}; // Values used to extend the TTL of storage pub const DAY_IN_LEDGERS: u32 = 17280; @@ -20,7 +20,7 @@ pub enum DataKey { AuctionId, AllAuctions, HighestBid(u64), - AuctionToken, + Config, } #[derive(Clone, Debug, PartialEq)] @@ -60,6 +60,13 @@ pub enum AuctionStatus { Paused, } +#[derive(Clone, Debug)] +#[contracttype] +pub struct Config { + pub auction_token: Address, + pub auction_creation_fee: u128, +} + pub fn generate_auction_id(env: &Env) -> Result { let id = env .storage() @@ -269,37 +276,60 @@ pub fn set_highest_bid( Ok(()) } -pub fn save_auction_token(env: &Env, auction_token: Address) { +pub fn save_config(env: &Env, config: Config) { + env.storage().persistent().set(&DataKey::Config, &config); env.storage() .persistent() - .set(&DataKey::AuctionToken, &auction_token); - - env.storage() - .persistent() - .extend_ttl(&DataKey::AuctionToken, LIFETIME_THRESHOLD, BUMP_AMOUNT); + .extend_ttl(&DataKey::Config, LIFETIME_THRESHOLD, BUMP_AMOUNT); } -pub fn get_auction_token(env: &Env) -> Result { - let auction_token = env +pub fn get_config(env: &Env) -> Result { + let config = env .storage() .persistent() - .get(&DataKey::AuctionToken) - .ok_or(ContractError::AuctionTokenNotFound)?; + .get(&DataKey::Config) + .ok_or(ContractError::ConfigNotFound); - env.storage() - .persistent() - .has(&DataKey::AuctionToken) - .then(|| { - env.storage().persistent().extend_ttl( - &DataKey::AuctionToken, - LIFETIME_THRESHOLD, - BUMP_AMOUNT, - ); - }); + env.storage().persistent().has(&DataKey::Config).then(|| { + env.storage() + .persistent() + .extend_ttl(&DataKey::Config, LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); - Ok(auction_token) + Ok(config)? } +//pub fn save_auction_token(env: &Env, auction_token: Address) { +// env.storage() +// .persistent() +// .set(&DataKey::AuctionToken, &auction_token); +// +// env.storage() +// .persistent() +// .extend_ttl(&DataKey::AuctionToken, LIFETIME_THRESHOLD, BUMP_AMOUNT); +//} +// +//pub fn get_auction_token(env: &Env) -> Result { +// let auction_token = env +// .storage() +// .persistent() +// .get(&DataKey::AuctionToken) +// .ok_or(ContractError::CurrencyNotFound)?; +// +// env.storage() +// .persistent() +// .has(&DataKey::AuctionToken) +// .then(|| { +// env.storage().persistent().extend_ttl( +// &DataKey::AuctionToken, +// LIFETIME_THRESHOLD, +// BUMP_AMOUNT, +// ); +// }); +// +// Ok(auction_token) +//} + #[cfg(test)] mod test { use soroban_sdk::Env; From 73f48f89ac981684173912c0908dbbfb7d59d9d8 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:45:30 +0300 Subject: [PATCH 02/13] fixes the compiler issues --- contracts/auctions/src/contract.rs | 23 ++++++++++++++++++- contracts/auctions/src/error.rs | 1 + contracts/auctions/src/storage.rs | 2 +- contracts/auctions/src/test/bids.rs | 17 ++++++++------ contracts/auctions/src/test/initialization.rs | 4 ++-- contracts/auctions/src/test/setup.rs | 2 +- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/contracts/auctions/src/contract.rs b/contracts/auctions/src/contract.rs index 30d31b9..fef3cf8 100644 --- a/contracts/auctions/src/contract.rs +++ b/contracts/auctions/src/contract.rs @@ -66,7 +66,28 @@ impl MarketplaceContract { ]; validate_input_params(&env, &input_values[..])?; - let auction_token = get_config(&env)?.auction_token; + let config = get_config(&env)?; + let auction_token = config.auction_token; + let auction_creation_fee = config.auction_creation_fee as i128; + + let token_client = token::Client::new(&env, &auction_token); + + if token_client.balance(&seller) < auction_creation_fee { + log!( + &env, + "Auction: Create Auctoin: Not enough balance to cover the auction creation fee. ", + "Required: ", + auction_creation_fee + ); + return Err(ContractError::AuctionCreationFeeNotCovered); + } + + token_client.transfer( + &seller, + &env.current_contract_address(), + &auction_creation_fee, + ); + let nft_client = collection::Client::new(&env, &item_info.collection_addr); let item_balance = nft_client.balance_of(&seller, &item_info.item_id); diff --git a/contracts/auctions/src/error.rs b/contracts/auctions/src/error.rs index c5ae3fe..d44a046 100644 --- a/contracts/auctions/src/error.rs +++ b/contracts/auctions/src/error.rs @@ -22,4 +22,5 @@ pub enum ContractError { AdminNotFound = 15, NoBidFound = 16, ConfigNotFound = 17, + AuctionCreationFeeNotCovered = 18, } diff --git a/contracts/auctions/src/storage.rs b/contracts/auctions/src/storage.rs index 6bdc2c3..7b37b0a 100644 --- a/contracts/auctions/src/storage.rs +++ b/contracts/auctions/src/storage.rs @@ -1,6 +1,6 @@ use soroban_sdk::{contracttype, log, panic_with_error, vec, Address, Env, Vec}; -use crate::{collection::DataKey, error::ContractError}; +use crate::error::ContractError; // Values used to extend the TTL of storage pub const DAY_IN_LEDGERS: u32 = 17280; diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 0cca3ba..bf77fe4 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -26,6 +26,7 @@ fn should_place_a_bid() { let bidder_c = Address::generate(&env); let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, @@ -267,6 +268,7 @@ fn buy_now() { let fomo_buyer = Address::generate(&env); let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&fomo_buyer, &100); token_client.mint(&bidder_a, &100); @@ -297,14 +299,14 @@ fn buy_now() { env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS); mp_client.place_bid(&1, &bidder_a, &5); assert_eq!(token_client.balance(&bidder_a), 95); - assert_eq!(token_client.balance(&mp_client.address), 5); + assert_eq!(token_client.balance(&mp_client.address), 15); // 8 hours in and we have a second highest bid env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 2); mp_client.place_bid(&1, &bidder_b, &10); assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 90); - assert_eq!(token_client.balance(&mp_client.address), 10); + assert_eq!(token_client.balance(&mp_client.address), 20); // 16 hours in and we have a third highest bid env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 4); @@ -312,7 +314,7 @@ fn buy_now() { assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&fomo_buyer), 75); - assert_eq!(token_client.balance(&mp_client.address), 25); + assert_eq!(token_client.balance(&mp_client.address), 35); // 24 hours in and we have a 4th highest bid env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 6); @@ -320,7 +322,7 @@ fn buy_now() { assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 70); assert_eq!(token_client.balance(&fomo_buyer), 100); - assert_eq!(token_client.balance(&mp_client.address), 30); + assert_eq!(token_client.balance(&mp_client.address), 40); // 36 hours in and we have a 5th highest bid, which is over the buy now price env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 9); @@ -328,7 +330,7 @@ fn buy_now() { assert_eq!(token_client.balance(&bidder_a), 40); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&fomo_buyer), 100); - assert_eq!(token_client.balance(&mp_client.address), 60); + assert_eq!(token_client.balance(&mp_client.address), 70); // 40 hours in and the fomo buyer sees the previous user mistake and buys now env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 10); @@ -336,7 +338,8 @@ fn buy_now() { assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&fomo_buyer), 50); - assert_eq!(token_client.balance(&mp_client.address), 0); + // mp_client has the fees from the auction creation + assert_eq!(token_client.balance(&mp_client.address), 10); assert_eq!(token_client.balance(&seller), 50); assert_eq!( @@ -549,7 +552,7 @@ fn multiple_auction_by_multiple_sellers() { let mp_client = MarketplaceContractClient::new(&env, &env.register_contract(None, MarketplaceContract {})); - mp_client.initialize(&admin, &token_client.address); + mp_client.initialize(&admin, &token_client.address, &10); // ============ Collections client setup ============ let collection_a_client = diff --git a/contracts/auctions/src/test/initialization.rs b/contracts/auctions/src/test/initialization.rs index 0051e64..3e65052 100644 --- a/contracts/auctions/src/test/initialization.rs +++ b/contracts/auctions/src/test/initialization.rs @@ -24,7 +24,7 @@ fn initialize_and_update_admin_should_work() { let mp_client = MarketplaceContractClient::new(&env, &env.register_contract(None, MarketplaceContract {})); - mp_client.initialize(&admin, &token_client.address); + mp_client.initialize(&admin, &token_client.address, &10); mp_client.update_admin(&new_admin); } @@ -88,7 +88,7 @@ fn initialize_twice_should_fail() { ); assert_eq!( - mp_client.try_initialize(&admin, &token_client.address), + mp_client.try_initialize(&admin, &token_client.address, &10), Err(Ok(ContractError::AlreadyInitialized)) ); } diff --git a/contracts/auctions/src/test/setup.rs b/contracts/auctions/src/test/setup.rs index 9d1c7f0..dc115e4 100644 --- a/contracts/auctions/src/test/setup.rs +++ b/contracts/auctions/src/test/setup.rs @@ -31,7 +31,7 @@ pub fn generate_marketplace_and_collection_client<'a>( let mp_client = MarketplaceContractClient::new(env, &env.register_contract(None, MarketplaceContract {})); - mp_client.initialize(admin, auction_token); + mp_client.initialize(admin, auction_token, &10); let alt_name = String::from_str(env, "Stellar kitties"); let alt_symbol = String::from_str(env, "STK"); From 08fe50d95117ccc8a9b043f7fa9d864d3bfaae64 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:54:53 +0300 Subject: [PATCH 03/13] fixes should_place_a_bid --- contracts/auctions/src/test/bids.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index bf77fe4..753caba 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -55,7 +55,7 @@ fn should_place_a_bid() { bidder: bidder_a.clone() } ); - assert_eq!(token_client.balance(&mp_client.address), 10i128); + assert_eq!(token_client.balance(&mp_client.address), 20i128); assert_eq!(token_client.balance(&bidder_a), 0i128); mp_client.place_bid(&1, &bidder_b, &20); @@ -66,7 +66,7 @@ fn should_place_a_bid() { bidder: bidder_b.clone() } ); - assert_eq!(token_client.balance(&mp_client.address), 20i128); + assert_eq!(token_client.balance(&mp_client.address), 30i128); assert_eq!(token_client.balance(&bidder_a), 10i128); assert_eq!(token_client.balance(&bidder_b), 0i128); @@ -75,7 +75,7 @@ fn should_place_a_bid() { mp_client.try_place_bid(&1, &bidder_a, &15), Err(Ok(ContractError::BidNotEnough)) ); - assert_eq!(token_client.balance(&mp_client.address), 20i128); + assert_eq!(token_client.balance(&mp_client.address), 30i128); assert_eq!(token_client.balance(&bidder_a), 10i128); assert_eq!(token_client.balance(&bidder_b), 0i128); @@ -95,7 +95,7 @@ fn should_place_a_bid() { bidder: bidder_c.clone() } ); - assert_eq!(token_client.balance(&mp_client.address), 40i128); + assert_eq!(token_client.balance(&mp_client.address), 50i128); assert_eq!(token_client.balance(&bidder_a), 10i128); assert_eq!(token_client.balance(&bidder_b), 20i128); assert_eq!(token_client.balance(&bidder_c), 0i128); From 034a492093f9a1b0fbd44ae2638190e1cd630ae7 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:08:31 +0300 Subject: [PATCH 04/13] fixes a broken and incorrect test --- contracts/auctions/src/test/bids.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 753caba..61afa7e 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -10,7 +10,6 @@ use crate::{ test::setup::{ deploy_token_contract, generate_marketplace_and_collection_client, DAY, FOUR_HOURS, WEEKLY, }, - token, }; use super::setup::create_and_initialize_collection; @@ -109,7 +108,9 @@ fn fail_to_place_bid_when_auction_inactive() { let seller = Address::generate(&env); let bidder_a = Address::generate(&env); - let token_client = token::Client::new(&env, &Address::generate(&env)); + let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); + let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, From eddad4815382ddafae4de60cffed70f0fb410ac5 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:09:20 +0300 Subject: [PATCH 05/13] fixes another test --- contracts/auctions/src/test/bids.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 61afa7e..85217d4 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -148,7 +148,7 @@ fn seller_tries_to_place_a_bid_should_fail() { let seller = Address::generate(&env); let token_client = deploy_token_contract(&env, &Address::generate(&env)); - token_client.mint(&seller, &1); + token_client.mint(&seller, &11); let (mp_client, collection_client) = generate_marketplace_and_collection_client( &env, &seller, From 97f00be4a57b0df06d8ee3c0b0a556647d1560a8 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:20:27 +0300 Subject: [PATCH 06/13] fixes test --- contracts/auctions/src/test/bids.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 85217d4..f38737e 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -188,6 +188,7 @@ fn buy_now_should_fail_when_auction_not_active() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&fomo_buyer, &50); let (mp_client, collections_client) = generate_marketplace_and_collection_client( From bdb50da1dc24964998802d571ddc4eeb93bef8b7 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:21:03 +0300 Subject: [PATCH 07/13] wip fixing tests --- contracts/auctions/src/test/bids.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index f38737e..6c0671c 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -230,6 +230,7 @@ fn buy_now_should_fail_when_no_buy_now_price_has_been_set() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&fomo_buyer, &50); let (mp_client, collections_client) = generate_marketplace_and_collection_client( From a1a9d7d62466fcde49a09976f18f494d3f6a7394 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:33:53 +0300 Subject: [PATCH 08/13] multiple auctions works --- contracts/auctions/src/test/bids.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 6c0671c..73404c0 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -371,6 +371,7 @@ fn pause_changes_status_and_second_attempt_fails_to_pause() { let seller = Address::generate(&env); let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); let (mp_client, collections_client) = generate_marketplace_and_collection_client( &env, @@ -422,6 +423,7 @@ fn pause_after_enddate_should_fail() { let seller = Address::generate(&env); let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); let (mp_client, collections_client) = generate_marketplace_and_collection_client( &env, @@ -461,6 +463,7 @@ fn unpause_changes_status_and_second_attempt_fails_to_unpause() { let bidder = Address::generate(&env); let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&bidder, &100); let (mp_client, collections_client) = generate_marketplace_and_collection_client( @@ -513,7 +516,7 @@ fn unpause_changes_status_and_second_attempt_fails_to_unpause() { mp_client.place_bid(&1, &bidder, &100); assert_eq!(token_client.balance(&bidder), 0); - assert_eq!(token_client.balance(&mp_client.address), 100); + assert_eq!(token_client.balance(&mp_client.address), 110); assert_eq!( mp_client.get_highest_bid(&1), HighestBid { bid: 100, bidder } @@ -548,6 +551,10 @@ fn multiple_auction_by_multiple_sellers() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller_a, &20); + token_client.mint(&seller_b, &10); + token_client.mint(&seller_c, &10); + token_client.mint(&bidder_a, &1_000); token_client.mint(&bidder_b, &1_000); token_client.mint(&bidder_c, &1_000); @@ -682,7 +689,7 @@ fn multiple_auction_by_multiple_sellers() { assert_eq!(token_client.balance(&bidder_a), 900); assert_eq!(token_client.balance(&bidder_b), 900); assert_eq!(token_client.balance(&bidder_c), 974); - assert_eq!(token_client.balance(&mp_client.address), 226); + assert_eq!(token_client.balance(&mp_client.address), 266); // within day #2 // here auction #4 has ended @@ -694,7 +701,7 @@ fn multiple_auction_by_multiple_sellers() { ); mp_client.finalize_auction(&4); - assert_eq!(token_client.balance(&mp_client.address), 126); + assert_eq!(token_client.balance(&mp_client.address), 166); assert_eq!(token_client.balance(&bidder_a), 900); assert_eq!(token_client.balance(&bidder_b), 900); assert_eq!(token_client.balance(&bidder_c), 974); @@ -718,7 +725,7 @@ fn multiple_auction_by_multiple_sellers() { // `bidder_c`places a bit for 75 he now has 925 in total assert_eq!(token_client.balance(&bidder_c), 925); // total of the assets locked in the contract - assert_eq!(token_client.balance(&mp_client.address), 225); + assert_eq!(token_client.balance(&mp_client.address), 265); // day #4 env.ledger().with_mut(|li| li.timestamp = DAY * 4); @@ -842,7 +849,8 @@ fn multiple_auction_by_multiple_sellers() { assert_eq!(token_client.balance(&bidder_c), 1_000); // make sure that we don't hold any tokens, as we are just intermediary - assert_eq!(token_client.balance(&mp_client.address), 0); + // market place has kept all the fees for creating the auctions + assert_eq!(token_client.balance(&mp_client.address), 40); // let's check the item info // auction #1 sold item #1 from `collection_a` and the winner is `bidder_a` From 4c22fb8e5e86982767fe94601ae078d9da195706 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:36:59 +0300 Subject: [PATCH 09/13] bids working --- contracts/auctions/src/test/bids.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/contracts/auctions/src/test/bids.rs b/contracts/auctions/src/test/bids.rs index 73404c0..606c66e 100644 --- a/contracts/auctions/src/test/bids.rs +++ b/contracts/auctions/src/test/bids.rs @@ -873,6 +873,7 @@ fn buy_now_should_fail_when_status_is_different_from_active() { let bidder = Address::generate(&env); let token = deploy_token_contract(&env, &admin); + token.mint(&seller, &10); token.mint(&bidder, &10); let (mp_client, collection) = @@ -912,6 +913,7 @@ fn buy_now_should_work_when_no_previous_bid() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&fomo_buyer, &100); let (mp_client, collections_client) = generate_marketplace_and_collection_client( @@ -940,7 +942,7 @@ fn buy_now_should_work_when_no_previous_bid() { mp_client.buy_now(&1, &fomo_buyer); assert_eq!(token_client.balance(&fomo_buyer), 50); - assert_eq!(token_client.balance(&mp_client.address), 0); + assert_eq!(token_client.balance(&mp_client.address), 10); assert_eq!(token_client.balance(&seller), 50); } @@ -957,6 +959,7 @@ fn buy_now_should_refund_previous_buyer() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); token_client.mint(&fomo_buyer, &100); token_client.mint(&bidder, &100); @@ -985,7 +988,7 @@ fn buy_now_should_refund_previous_buyer() { mp_client.place_bid(&1, &bidder, &40); assert_eq!(token_client.balance(&bidder), 60); - assert_eq!(token_client.balance(&mp_client.address), 40); + assert_eq!(token_client.balance(&mp_client.address), 50); env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS * 2); @@ -993,6 +996,6 @@ fn buy_now_should_refund_previous_buyer() { assert_eq!(token_client.balance(&fomo_buyer), 50); assert_eq!(token_client.balance(&bidder), 100); - assert_eq!(token_client.balance(&mp_client.address), 0); + assert_eq!(token_client.balance(&mp_client.address), 10); assert_eq!(token_client.balance(&seller), 50); } From 3266c1394d8807dac56021ef3d6735a87bd2d0b1 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:41:59 +0300 Subject: [PATCH 10/13] initialization done --- contracts/auctions/src/test/initialization.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/contracts/auctions/src/test/initialization.rs b/contracts/auctions/src/test/initialization.rs index 3e65052..4afb704 100644 --- a/contracts/auctions/src/test/initialization.rs +++ b/contracts/auctions/src/test/initialization.rs @@ -1,5 +1,5 @@ extern crate std; -use soroban_sdk::{testutils::Address as _, token, Address, Env}; +use soroban_sdk::{testutils::Address as _, Address, Env}; use crate::{ collection, @@ -35,7 +35,8 @@ fn mp_should_create_auction() { env.budget().reset_unlimited(); let seller = Address::generate(&env); - let token_client = token::Client::new(&env, &Address::generate(&env)); + let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, @@ -79,6 +80,8 @@ fn initialize_twice_should_fail() { let seller = Address::generate(&env); let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); + let (mp_client, _) = generate_marketplace_and_collection_client( &env, &seller, @@ -100,7 +103,8 @@ fn mp_should_fail_to_create_auction_where_not_enought_balance_of_the_item() { env.budget().reset_unlimited(); let seller = Address::generate(&env); - let token_client = token::Client::new(&env, &Address::generate(&env)); + let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); // we don't want to use the collection from the setup method, as this will automatically // mint an item for the auction. let (mp_client, _) = generate_marketplace_and_collection_client( @@ -141,6 +145,7 @@ fn mp_should_be_able_create_multiple_auctions_and_query_them_with_pagination() { let seller = Address::generate(&env); let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &250); let (mp_client, collection_client) = generate_marketplace_and_collection_client( &env, From 77b4ede3c674c316ec68564cccfd3369f9c24504 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:20:42 +0300 Subject: [PATCH 11/13] finalize done --- .../auctions/src/test/finalize_auction.rs | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/contracts/auctions/src/test/finalize_auction.rs b/contracts/auctions/src/test/finalize_auction.rs index f1aa88e..4c5ffae 100644 --- a/contracts/auctions/src/test/finalize_auction.rs +++ b/contracts/auctions/src/test/finalize_auction.rs @@ -9,7 +9,6 @@ use crate::{ test::setup::{ deploy_token_contract, generate_marketplace_and_collection_client, DAY, FOUR_HOURS, WEEKLY, }, - token, }; #[test] @@ -27,6 +26,8 @@ fn finalize_auction() { let token_client = deploy_token_contract(&env, &admin); + token_client.mint(&seller, &10); + token_client.mint(&bidder_a, &100); token_client.mint(&bidder_b, &100); token_client.mint(&bidder_c, &100); @@ -53,7 +54,7 @@ fn finalize_auction() { env.ledger().with_mut(|li| li.timestamp = FOUR_HOURS); mp_client.place_bid(&1, &bidder_a, &5); assert_eq!(token_client.balance(&bidder_a), 95); - assert_eq!(token_client.balance(&mp_client.address), 5); + assert_eq!(token_client.balance(&mp_client.address), 15); // another 4 hours pass by and `bidder_b` places a higher bid env.ledger().with_mut(|li| { @@ -62,7 +63,7 @@ fn finalize_auction() { mp_client.place_bid(&1, &bidder_b, &10); assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 90); - assert_eq!(token_client.balance(&mp_client.address), 10); + assert_eq!(token_client.balance(&mp_client.address), 20); // 12 hours in total pass by and `bidder_c` places a higher bid env.ledger().with_mut(|li| { @@ -72,7 +73,7 @@ fn finalize_auction() { assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&bidder_c), 50); - assert_eq!(token_client.balance(&mp_client.address), 50); + assert_eq!(token_client.balance(&mp_client.address), 60); // 13 hours in total pass by and `bidder_b` tries to place a bid, but that's not enough env.ledger().with_mut(|li| { @@ -82,7 +83,7 @@ fn finalize_auction() { assert_eq!(token_client.balance(&bidder_a), 100); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&bidder_c), 50); - assert_eq!(token_client.balance(&mp_client.address), 50); + assert_eq!(token_client.balance(&mp_client.address), 60); // 16 hours in total pass by and `bidder_a` places the highest bid env.ledger().with_mut(|li| { @@ -92,7 +93,7 @@ fn finalize_auction() { assert_eq!(token_client.balance(&bidder_a), 25); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&bidder_c), 100); - assert_eq!(token_client.balance(&mp_client.address), 75); + assert_eq!(token_client.balance(&mp_client.address), 85); // we wrap it up and the winner is `bidder_a` with a highest bid of 75 env.ledger().with_mut(|li| li.timestamp = WEEKLY + DAY); @@ -102,7 +103,8 @@ fn finalize_auction() { assert_eq!(token_client.balance(&bidder_a), 25); assert_eq!(token_client.balance(&bidder_b), 100); assert_eq!(token_client.balance(&bidder_c), 100); - assert_eq!(token_client.balance(&mp_client.address), 0); + // market place has the initial auction creation fee + assert_eq!(token_client.balance(&mp_client.address), 10); // check if `bidder_a` has 1 NFT of the item assert_eq!(collections_client.balance_of(&bidder_a, &1), 1); @@ -120,6 +122,8 @@ fn fail_to_finalyze_auction_when_endtime_not_reached() { let bidder = Address::generate(&env); let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); + let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, @@ -141,7 +145,7 @@ fn fail_to_finalyze_auction_when_endtime_not_reached() { mp_client.place_bid(&1, &bidder, &50); - assert_eq!(token_client.balance(&mp_client.address), 50i128); + assert_eq!(token_client.balance(&mp_client.address), 60i128); assert_eq!(token_client.balance(&bidder), 0i128); env.ledger().with_mut(|li| li.timestamp = DAY); @@ -151,9 +155,10 @@ fn fail_to_finalyze_auction_when_endtime_not_reached() { ); // auction is not yet over, so the bid is still in place - assert_eq!(token_client.balance(&mp_client.address), 50i128); + assert_eq!(token_client.balance(&mp_client.address), 60i128); assert_eq!(token_client.balance(&bidder), 0i128); } + #[test] fn finalize_auction_when_minimal_price_not_reached_should_refund_last_bidder() { let env = Env::default(); @@ -164,6 +169,8 @@ fn finalize_auction_when_minimal_price_not_reached_should_refund_last_bidder() { let bidder_a = Address::generate(&env); let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); + let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, @@ -186,7 +193,7 @@ fn finalize_auction_when_minimal_price_not_reached_should_refund_last_bidder() { env.ledger().with_mut(|li| li.timestamp = DAY); mp_client.place_bid(&1, &bidder_a, &5); - assert_eq!(token_client.balance(&mp_client.address), 5i128); + assert_eq!(token_client.balance(&mp_client.address), 15i128); assert_eq!(token_client.balance(&bidder_a), 0i128); // we try to finalize the auction 2 weeks later @@ -206,7 +213,7 @@ fn finalize_auction_when_minimal_price_not_reached_should_refund_last_bidder() { auction_token: token_client.address.clone() } ); - assert_eq!(token_client.balance(&mp_client.address), 0i128); + assert_eq!(token_client.balance(&mp_client.address), 10i128); assert_eq!(token_client.balance(&bidder_a), 5i128); } @@ -217,7 +224,9 @@ fn fail_to_finalyze_auction_when_not_correct_state() { env.budget().reset_unlimited(); let seller = Address::generate(&env); - let token_client = token::Client::new(&env, &Address::generate(&env)); + let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &10); + let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, @@ -252,7 +261,9 @@ fn get_active_auctions_should_list_correct_number_of_active_auctions() { let seller = Address::generate(&env); - let token_client = token::Client::new(&env, &Address::generate(&env)); + let token_client = deploy_token_contract(&env, &Address::generate(&env)); + token_client.mint(&seller, &30); + let (mp_client, nft_collection_client) = generate_marketplace_and_collection_client( &env, &seller, From d2bc2b1229001ebde4f275808456d98a3908d9b6 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:24:43 +0300 Subject: [PATCH 12/13] adds a test that check when the seller cannot pay the fees --- contracts/auctions/src/test/initialization.rs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/contracts/auctions/src/test/initialization.rs b/contracts/auctions/src/test/initialization.rs index 4afb704..cd52256 100644 --- a/contracts/auctions/src/test/initialization.rs +++ b/contracts/auctions/src/test/initialization.rs @@ -243,3 +243,30 @@ fn get_auction_by_seller_should_return_an_err_when_id_not_found() { Err(Ok(ContractError::AuctionNotFound)) ) } + +#[test] +fn should_fail_to_create_auction_when_seller_cannot_cover_the_fees() { + let env = Env::default(); + env.mock_all_auths(); + + let seller = Address::generate(&env); + + let token = deploy_token_contract(&env, &Address::generate(&env)); + + let (mp_client, collection) = + generate_marketplace_and_collection_client(&env, &seller, &token.address, None, None); + + collection.mint(&seller, &seller, &1, &1); + + let item_info = ItemInfo { + collection_addr: collection.address, + item_id: 1, + minimum_price: None, + buy_now_price: None, + }; + + assert_eq!( + mp_client.try_create_auction(&item_info, &seller, &WEEKLY), + Err(Ok(ContractError::AuctionCreationFeeNotCovered)) + ); +} From 21b637c8d699c902c16ffe8b02c596534ccb7e7f Mon Sep 17 00:00:00 2001 From: gangov <6922910+gangov@users.noreply.github.com> Date: Thu, 5 Dec 2024 12:22:25 +0200 Subject: [PATCH 13/13] removes commented code --- contracts/auctions/src/storage.rs | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/contracts/auctions/src/storage.rs b/contracts/auctions/src/storage.rs index a4c0c11..3ee83b2 100644 --- a/contracts/auctions/src/storage.rs +++ b/contracts/auctions/src/storage.rs @@ -304,37 +304,6 @@ pub fn get_config(env: &Env) -> Result { Ok(config)? } -//pub fn save_auction_token(env: &Env, auction_token: Address) { -// env.storage() -// .persistent() -// .set(&DataKey::AuctionToken, &auction_token); -// -// env.storage() -// .persistent() -// .extend_ttl(&DataKey::AuctionToken, LIFETIME_THRESHOLD, BUMP_AMOUNT); -//} -// -//pub fn get_auction_token(env: &Env) -> Result { -// let auction_token = env -// .storage() -// .persistent() -// .get(&DataKey::AuctionToken) -// .ok_or(ContractError::CurrencyNotFound)?; -// -// env.storage() -// .persistent() -// .has(&DataKey::AuctionToken) -// .then(|| { -// env.storage().persistent().extend_ttl( -// &DataKey::AuctionToken, -// LIFETIME_THRESHOLD, -// BUMP_AMOUNT, -// ); -// }); -// -// Ok(auction_token) -//} - #[cfg(test)] mod test { use soroban_sdk::Env;