diff --git a/onchain/cairo/.snfoundry_cache/.prev_tests_failed b/onchain/cairo/.snfoundry_cache/.prev_tests_failed index d2d6a781..99d6e529 100644 --- a/onchain/cairo/.snfoundry_cache/.prev_tests_failed +++ b/onchain/cairo/.snfoundry_cache/.prev_tests_failed @@ -1,14 +1,14 @@ -afk::tests::launchpad_tests::launchpad_tests::launchpad_test_calculation -afk::tests::launchpad_tests::launchpad_tests::test_get_coin_amount_by_quote_amount_for_buy_steps -afk::tests::launchpad_tests::launchpad_tests::test_get_coin_launch -afk::tests::launchpad_tests::launchpad_tests::test_get_share_key_of_user -afk::tests::launchpad_tests::launchpad_tests::test_launch_token -afk::tests::launchpad_tests::launchpad_tests::test_launch_token_with_uncreated_token -afk::tests::launchpad_tests::launchpad_tests::test_sell_coin_when_quote_amount_is_greater_than_liquidity_raised -afk::tests::launchpad_tests::launchpad_tests::test_sell_coin_when_share_too_low -afk::tests::launchpad_tests::launchpad_tests::test_set_protocol_fee_percent_non_admin -afk::tests::launchpad_tests::launchpad_tests::test_buy_coin_with_different_supply -afk::tests::launchpad_tests::launchpad_tests::launchpad_integration -afk::tests::launchpad_tests::launchpad_tests::launchpad_buy_all -afk::tests::launchpad_tests::launchpad_tests::test_launchpad_end_to_end -afk::tests::launchpad_tests::launchpad_tests::launchpad_end_to_end +afk::tests::launchpad_tests::launchpad_tests::launchpad_test_calculation +afk::tests::launchpad_tests::launchpad_tests::test_get_coin_amount_by_quote_amount_for_buy_steps +afk::tests::launchpad_tests::launchpad_tests::test_get_coin_launch +afk::tests::launchpad_tests::launchpad_tests::test_get_share_key_of_user +afk::tests::launchpad_tests::launchpad_tests::test_launch_token +afk::tests::launchpad_tests::launchpad_tests::test_launch_token_with_uncreated_token +afk::tests::launchpad_tests::launchpad_tests::test_sell_coin_when_quote_amount_is_greater_than_liquidity_raised +afk::tests::launchpad_tests::launchpad_tests::test_sell_coin_when_share_too_low +afk::tests::launchpad_tests::launchpad_tests::test_set_protocol_fee_percent_non_admin +afk::tests::launchpad_tests::launchpad_tests::test_buy_coin_with_different_supply +afk::tests::launchpad_tests::launchpad_tests::launchpad_integration +afk::tests::launchpad_tests::launchpad_tests::launchpad_buy_all +afk::tests::launchpad_tests::launchpad_tests::test_launchpad_end_to_end +afk::tests::launchpad_tests::launchpad_tests::launchpad_end_to_end \ No newline at end of file diff --git a/onchain/cairo/src/afk_id/nameservice.cairo b/onchain/cairo/src/afk_id/nameservice.cairo index f5ba8f3f..26027fd0 100644 --- a/onchain/cairo/src/afk_id/nameservice.cairo +++ b/onchain/cairo/src/afk_id/nameservice.cairo @@ -7,6 +7,13 @@ pub mod UserNameClaimErrors { pub const INVALID_PRICE: felt252 = 'Invalid price setting'; pub const INVALID_USERNAME: felt252 = 'Invalid username format'; pub const INVALID_DOMAIN_SUFFIX: felt252 = 'Domain must end with .afk'; + pub const AUCTION_DOESNT_EXIST: felt252 = 'Auction does not exist'; + pub const USER_NOT_OWNER: felt252 = 'User not owner'; + pub const BID_LOW: felt252 = 'Bid too low'; + pub const INVALID_CANCEL_ORDER: felt252 = 'Invalid cancel order'; + pub const USER_NOT_AUCTION_OWNER: felt252 = 'Not the auction owner'; + pub const ACCEPTED_PRICE_REACHED: felt252 = 'Accepted Price Reached'; + pub const ORDER_INACTIVE: felt252 = 'Order is Inactive'; } const ADMIN_ROLE: felt252 = selector!("ADMIN_ROLE"); @@ -94,6 +101,22 @@ pub mod Nameservice { pub is_claimed: bool } + #[derive(Drop, Debug, Serde, Copy, starknet::Store)] + pub struct Auction { + pub owner: ContractAddress, + pub minimal_price: u256, + pub highest_bid: u256, + pub highest_bidder: ContractAddress, + } + + #[derive(Drop, Debug, Serde, Copy, starknet::Store, PartialEq)] + struct Order { + id: u256, + bidder: ContractAddress, + amount: u256, + is_active: bool + } + #[storage] struct Storage { usernames: Map::, @@ -101,6 +124,10 @@ pub mod Nameservice { usernames_claimed_by_user: Map>, subscription_expiry: Map::, username_storage: Map::, + auctions: Map::, + orders: Map::<(felt252, u256), Order>, + order_count: Map::, + order_return: Map::>, subscription_price: u256, token_quote: ContractAddress, is_payment_enabled: bool, @@ -120,6 +147,8 @@ pub mod Nameservice { erc20: ERC20Component::Storage, } + + #[event] #[derive(Drop, starknet::Event)] pub enum Event { @@ -127,6 +156,7 @@ pub mod Nameservice { UsernameChanged: UsernameChanged, SubscriptionRenewed: SubscriptionRenewed, PriceUpdated: PriceUpdated, + AuctionCreated: AuctionCreated, #[flat] AccessControlEvent: AccessControlComponent::Event, #[flat] @@ -174,6 +204,14 @@ pub mod Nameservice { new_price: u256 } + #[derive(Drop, starknet::Event)] + struct AuctionCreated { + #[key] + owner: ContractAddress, + username: felt252, + minimal_price: u256, + + } // Required for hash computation. pub impl SNIP12MetadataImpl of SNIP12Metadata { @@ -318,22 +356,143 @@ pub mod Nameservice { // TODO change main username fn change_main_username(ref self: ContractState, new_username: felt252) {} + // TODO fn create_auction_for_username( ref self: ContractState, username: felt252, minimal_price: u256, - is_accepted_price_reached: bool - ) {} + ) { + let caller_address = get_caller_address(); + let username_address = self.get_username_address(username); + + assert( + username_address == caller_address, + UserNameClaimErrors::USER_NOT_OWNER + ); + + let existing_auction = self.auctions.read(username); + // TODO change ERROR NAME + assert( + existing_auction.minimal_price == 0, + UserNameClaimErrors::AUCTION_DOESNT_EXIST + ); + + // Create a new auction + let new_auction = Auction { + owner: caller_address, + minimal_price: minimal_price, + highest_bid: 0, + highest_bidder: contract_address_const::<0>(), + }; + + // Store the auction + self.auctions.write(username, new_auction); + self + .emit( + AuctionCreated { + owner: caller_address, + username: username, + minimal_price, + } + ); + } // TODO - fn place_order(ref self: ContractState, username: felt252, amount: u256) {} + fn place_order(ref self: ContractState, username: felt252, amount: u256) { + let auction = self.auctions.read(username); + assert( + auction.minimal_price > 0, + UserNameClaimErrors::AUCTION_DOESNT_EXIST + ); + assert(amount > auction.highest_bid, UserNameClaimErrors::BID_LOW); + + // Create a new order + let bidder = get_caller_address(); + + let payment_token = IERC20Dispatcher { contract_address: self.token_quote.read() }; + payment_token.transfer_from(bidder, get_contract_address(), amount); + + let order_id = self.order_count.entry(username).read() + 1_u256; + let new_order = Order { id: order_id, bidder: bidder, amount: amount, is_active: true }; + + // Store the order + self.orders.entry((username, order_id)).write(new_order); + self.order_count.entry(username).write(order_id); + + // Update auction if this is the highest bid + let mut updated_auction = auction; + updated_auction.highest_bid = amount; + updated_auction.highest_bidder = bidder; + self.auctions.write(username, updated_auction); + } // TODO - fn accept_order(ref self: ContractState, username: felt252, id: u64) {} + fn accept_order(ref self: ContractState, username: felt252, id: u64) { + let caller = get_caller_address(); + let id: u256 = id.into(); + + let auction = self.auctions.read(username); + assert(auction.owner == caller, UserNameClaimErrors::USER_NOT_AUCTION_OWNER); + + let order = self.orders.entry((username, id)).read(); + assert(order.is_active == true, UserNameClaimErrors::ORDER_INACTIVE); + + let bidder = order.bidder; + + // Update Order to inactive + let mut updated_order = order; + updated_order.is_active = false; + self.orders.entry((username, id)).write(order); + + let mut updated_auction = auction; + + // Send token from contract to auction owner + let token = IERC20Dispatcher { contract_address: self.token_quote.read() }; + token.transfer(caller, order.amount); + + self.usernames.entry(username).write(bidder); + self.user_to_username.entry(bidder).write(username); + + let username_storage_value = self.username_storage.entry(username).read(); + let mut updated_username_storage_value = username_storage_value; + updated_username_storage_value.owner = bidder; + updated_username_storage_value.username = username; + + self.erc20.burn(caller, 1_u256); + self.erc20.mint(bidder, 1_u256); + } // TODO - fn cancel_order(ref self: ContractState, username: felt252, id: u64) {} + fn cancel_order(ref self: ContractState, username: felt252, id: u64) { + let caller = get_caller_address(); + let auction = self.auctions.read(username); + let id: u256 = id.into(); + let order = self.orders.entry((username, id)).read(); + + assert((order.bidder == caller), UserNameClaimErrors::INVALID_CANCEL_ORDER); + // Update order + let amount = order.amount; + let mut updated_order = order; + updated_order.amount = 0; + updated_order.is_active = false; + self.orders.entry((username, id)).write(updated_order); + + // Update auction if the caller is the highest bid + let mut updated_auction = auction; + updated_auction.highest_bid = 0; + updated_auction.highest_bidder = contract_address_const::<0>(); + self.auctions.write(username, updated_auction); + + let token = IERC20Dispatcher { contract_address: self.token_quote.read() }; + token.transfer(caller, amount); + } + + fn get_auction(self: @ContractState, username: felt252) -> Auction { + // Read the auction from storage + let auction = self.auctions.read(username); + auction + } // TODO fn renew_subscription(ref self: ContractState) { @@ -385,7 +544,6 @@ pub mod Nameservice { ); } - // ADMIN // Admin functions fn update_subscription_price(ref self: ContractState, new_price: u256) { @@ -413,6 +571,9 @@ pub mod Nameservice { fn get_subscription_expiry(self: @ContractState, address: ContractAddress) -> u64 { self.subscription_expiry.read(address) } + + + fn withdraw_fees(ref self: ContractState, amount: u256) { self.accesscontrol.assert_only_role(ADMIN_ROLE); let token = IERC20Dispatcher { contract_address: self.token_quote.read() }; diff --git a/onchain/cairo/src/interfaces/nameservice.cairo b/onchain/cairo/src/interfaces/nameservice.cairo index e9a8b2d1..dd268e1e 100644 --- a/onchain/cairo/src/interfaces/nameservice.cairo +++ b/onchain/cairo/src/interfaces/nameservice.cairo @@ -1,4 +1,5 @@ use starknet::ContractAddress; +use afk::afk_id::nameservice::Nameservice::{Auction}; #[starknet::interface] pub trait INameservice { @@ -9,7 +10,6 @@ pub trait INameservice { ref self: TContractState, username: felt252, minimal_price: u256, - is_accepted_price_reached: bool ); fn place_order(ref self: TContractState, username: felt252, amount: u256); fn cancel_order(ref self: TContractState, username: felt252, id: u64); @@ -27,4 +27,5 @@ pub trait INameservice { fn update_subscription_price(ref self: TContractState, new_price: u256); fn set_is_payment_enabled(ref self: TContractState, new_status: bool) -> bool; fn get_is_payment_enabled(self: @TContractState) -> bool; + fn get_auction(self: @TContractState, username: felt252) -> Auction; } diff --git a/onchain/cairo/src/lib.cairo b/onchain/cairo/src/lib.cairo index d87422c2..4651c386 100644 --- a/onchain/cairo/src/lib.cairo +++ b/onchain/cairo/src/lib.cairo @@ -14,7 +14,7 @@ pub mod launchpad { // pub mod exponential; // pub mod linear; // pub mod launch; - + pub mod errors; pub mod helpers; pub mod launchpad; @@ -117,7 +117,6 @@ pub mod tests { // pub mod identity_tests; pub mod keys_tests; pub mod launchpad_tests; - pub mod liquidity_tests; pub mod nameservice_tests; pub mod quest_factory_test; pub mod tap_tests; diff --git a/onchain/cairo/src/tests/launchpad_tests.cairo b/onchain/cairo/src/tests/launchpad_tests.cairo index e58a3e3b..913d36b9 100644 --- a/onchain/cairo/src/tests/launchpad_tests.cairo +++ b/onchain/cairo/src/tests/launchpad_tests.cairo @@ -1565,4 +1565,4 @@ mod launchpad_tests { // Unit test // -} +} \ No newline at end of file diff --git a/onchain/cairo/src/tests/nameservice_tests.cairo b/onchain/cairo/src/tests/nameservice_tests.cairo index f60b76b0..05f968c8 100644 --- a/onchain/cairo/src/tests/nameservice_tests.cairo +++ b/onchain/cairo/src/tests/nameservice_tests.cairo @@ -15,6 +15,13 @@ mod nameservice_tests { fn CALLER() -> ContractAddress { starknet::contract_address_const::<2>() } + fn NEW_CALLER() -> ContractAddress { + starknet::contract_address_const::<3>() + } + fn THIRD_CALLER() -> ContractAddress { + starknet::contract_address_const::<4>() + } + const ADMIN_ROLE: felt252 = selector!("ADMIN_ROLE"); const YEAR_IN_SECONDS: u64 = 31536000_u64; const PAYMENT_AMOUNT: felt252 = 10; @@ -114,8 +121,6 @@ mod nameservice_tests { let contract_balance = payment_token_dispatcher .balance_of(nameservice_dispatcher.contract_address); - println!("The contract_balance is : {}", contract_balance); - assert(contract_balance == 10_u256, 'token balance incorrect'); } @@ -251,4 +256,481 @@ mod nameservice_tests { assert(subscription_price == 10_u256, 'Price is not correct'); assert(new_subscription_price == 30_u256, 'Price is not correct'); } + + #[test] + fn test_create_auction_for_username() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + nameservice_dispatcher.create_auction_for_username(username, 100_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let existing_auction = nameservice_dispatcher.get_auction(username); + assert(existing_auction.minimal_price == 100, 'Minimal price not correct'); + assert(existing_auction.highest_bid == 0, 'highest_bid not correct'); + assert(existing_auction.highest_bidder == starknet::contract_address_const::<0>(), 'highest_bidder not correct'); + } + + #[test] + #[should_panic(expected: 'User not owner')] + fn test_create_auction_for_username_fail() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.create_auction_for_username(username, 100_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + } + + #[test] + fn test_place_order() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 15_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let existing_auction = nameservice_dispatcher.get_auction(username); + assert(existing_auction.highest_bid == 15, 'highest_bid not correct'); + assert(existing_auction.highest_bidder == NEW_CALLER(), 'highest_bidder not correct'); + + let caller_balance = payment_token_dispatcher.balance_of(CALLER()); + assert(caller_balance == 10_u256, 'balance incorrect'); + + let new_caller_balance = payment_token_dispatcher.balance_of(NEW_CALLER()); + assert(new_caller_balance == 5_u256, 'balance incorrect'); + + let contract_balance = payment_token_dispatcher + .balance_of(nameservice_dispatcher.contract_address); + assert(contract_balance == 25_u256, 'token balance incorrect'); + } + + #[test] + fn test_place_order_three() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 30_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); //10 + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 30_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, THIRD_CALLER()); //5 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, THIRD_CALLER()); + nameservice_dispatcher.place_order(username, 15_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 18_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let caller_balance = payment_token_dispatcher.balance_of(CALLER()); + let new_caller_balance = payment_token_dispatcher.balance_of(NEW_CALLER()); + let third_caller_balance = payment_token_dispatcher.balance_of(THIRD_CALLER()); + let contract_balance = payment_token_dispatcher + .balance_of(nameservice_dispatcher.contract_address); + assert(contract_balance == 53_u256, 'token balance incorrect'); + assert(caller_balance == 10_u256, 'caller balance incorrect'); + assert(new_caller_balance == 2_u256, 'new_caller balance incorrect'); + assert(third_caller_balance == 5_u256, 'third_caller balance incorrect'); + } + + #[test] + #[should_panic(expected: 'Bid too low')] + fn test_place_order_fail() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 15_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, THIRD_CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, THIRD_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + } + + #[test] + fn test_cancel_order() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); //10 + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, THIRD_CALLER()); //5 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, THIRD_CALLER()); + nameservice_dispatcher.place_order(username, 15_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.cancel_order(username, 1); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let caller_balance = payment_token_dispatcher.balance_of(CALLER()); + let new_caller_balance = payment_token_dispatcher.balance_of(NEW_CALLER()); + let third_caller_balance = payment_token_dispatcher.balance_of(THIRD_CALLER()); + let contract_balance = payment_token_dispatcher + .balance_of(nameservice_dispatcher.contract_address); + assert(contract_balance == 25_u256, 'token balance incorrect'); + assert(caller_balance == 10_u256, 'caller balance incorrect'); + assert(new_caller_balance == 20_u256, 'new_caller balance incorrect'); + assert(third_caller_balance == 5_u256, 'third_caller balance incorrect'); + + } + + #[test] + fn test_accept_order() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let stored_username = nameservice_dispatcher.get_username(CALLER()); + assert(stored_username == username, 'Username not set'); + + let stored_address = nameservice_dispatcher.get_username_address(username); + assert(stored_address == CALLER(), 'Address not set'); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); //10 + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.accept_order(username, 1); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + + let stored_username = nameservice_dispatcher.get_username(NEW_CALLER()); + assert(stored_username == username, 'Username not set'); + + let stored_address = nameservice_dispatcher.get_username_address(username); + assert(stored_address == NEW_CALLER(), 'Address not set'); + + let caller_balance = payment_token_dispatcher.balance_of(CALLER()); + let new_caller_balance = payment_token_dispatcher.balance_of(NEW_CALLER()); + let contract_balance = payment_token_dispatcher + .balance_of(nameservice_dispatcher.contract_address); + assert(contract_balance == 10_u256, 'token balance incorrect'); + assert(caller_balance == 20_u256, 'caller balance incorrect'); + assert(new_caller_balance == 10_u256, 'new_caller balance incorrect'); + } + + #[test] + fn test_accept_order_and_cancel_order() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let stored_username = nameservice_dispatcher.get_username(CALLER()); + assert(stored_username == username, 'Username not set'); + + let stored_address = nameservice_dispatcher.get_username_address(username); + assert(stored_address == CALLER(), 'Address not set'); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); //10 + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, THIRD_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, THIRD_CALLER()); + nameservice_dispatcher.place_order(username, 15_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.accept_order(username, 2); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.cancel_order(username, 1); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let stored_username = nameservice_dispatcher.get_username(THIRD_CALLER()); + assert(stored_username == username, 'Username not set'); + + let stored_address = nameservice_dispatcher.get_username_address(username); + assert(stored_address == THIRD_CALLER(), 'Address not set'); + + let caller_balance = payment_token_dispatcher.balance_of(CALLER()); + let new_caller_balance = payment_token_dispatcher.balance_of(NEW_CALLER()); + let third_caller_balance = payment_token_dispatcher.balance_of(THIRD_CALLER()); + let contract_balance = payment_token_dispatcher + .balance_of(nameservice_dispatcher.contract_address); + assert(contract_balance == 10_u256, 'token balance incorrect'); + assert(caller_balance == 25_u256, 'caller balance incorrect'); + assert(new_caller_balance == 20_u256, 'new_caller balance incorrect'); + assert(third_caller_balance == 5_u256, 'third_caller balance incorrect'); + } + + #[test] + #[should_panic(expected: 'Not the auction owner')] + fn test_accept_order_fail() { + let (nameservice_dispatcher, payment_token_dispatcher, payment_token_mintable_dispatcher) = + setup(); + + let MINTER_ROLE: felt252 = selector!("MINTER_ROLE"); + + start_cheat_caller_address(payment_token_mintable_dispatcher.contract_address, ADMIN()); + payment_token_mintable_dispatcher + .set_role(recipient: ADMIN(), role: MINTER_ROLE, is_enable: true); + payment_token_mintable_dispatcher.mint(CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(NEW_CALLER(), 20_u256); // Reduced amount + payment_token_mintable_dispatcher.mint(THIRD_CALLER(), 20_u256); // Reduced amount + stop_cheat_caller_address(payment_token_mintable_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, ADMIN()); + nameservice_dispatcher.set_is_payment_enabled(true); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, CALLER()); + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + + let username = selector!("test"); + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); + nameservice_dispatcher.claim_username(username); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + let stored_username = nameservice_dispatcher.get_username(CALLER()); + assert(stored_username == username, 'Username not set'); + + let stored_address = nameservice_dispatcher.get_username_address(username); + assert(stored_address == CALLER(), 'Address not set'); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, CALLER()); //10 + nameservice_dispatcher.create_auction_for_username(username, 5_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(payment_token_dispatcher.contract_address, NEW_CALLER()); //2 + payment_token_dispatcher.approve(nameservice_dispatcher.contract_address, 20_u256); + stop_cheat_caller_address(payment_token_dispatcher.contract_address); + start_cheat_caller_address(nameservice_dispatcher.contract_address, NEW_CALLER()); + nameservice_dispatcher.place_order(username, 10_u256); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + + start_cheat_caller_address(nameservice_dispatcher.contract_address, THIRD_CALLER()); + nameservice_dispatcher.accept_order(username, 1); + stop_cheat_caller_address(nameservice_dispatcher.contract_address); + } }