Skip to content

Commit

Permalink
test setup fo marketplace
Browse files Browse the repository at this point in the history
added all tests for marketplace
  • Loading branch information
ametel01 committed Jan 14, 2024
1 parent c8de16b commit 845f144
Show file tree
Hide file tree
Showing 16 changed files with 1,039 additions and 499 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Build
on: [push, pull_request]

env:
SCARB_VERSION: 2.4.0
SCARB_VERSION: 2.4.3

jobs:
check:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push, pull_request]

env:
SCARB_VERSION: 2.4.3
SNFORGE_VERSION: 0.13.1
SNFORGE_VERSION: 0.14.0

jobs:
check:
Expand Down
4 changes: 2 additions & 2 deletions flex_marketplace/Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ source = "git+https://github.com/openzeppelin/cairo-contracts?tag=v0.8.0#c23e8e9

[[package]]
name = "snforge_std"
version = "0.1.0"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.13.0#99c2f9d33159988efd339bd969c78d82b0b4b6f7"
version = "0.14.0"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.14.0#e8cbecee4e31ed428c76d5173eaa90c8df796fe3"
6 changes: 3 additions & 3 deletions flex_marketplace/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ version = "0.1.0"
edition = "2023_01"

[dependencies]
starknet = "2.4.0"
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.13.0" }
openzeppelin = { git = "https://github.com/openzeppelin/cairo-contracts", tag = "v0.8.0" }
starknet = "2.4.3"
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.14.0" }
openzeppelin = { git = "https://github.com/openzeppelin/cairo-contracts", tag = "v0.8.0" }

[scripts]
test = "snforge test"
Expand Down
5 changes: 4 additions & 1 deletion flex_marketplace/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt::{Display, Error, Formatter, Debug};
use starknet::contract_address_to_felt252;
use starknet::{contract_address_to_felt252, ContractAddress, contract_address_const};

impl DisplayContractAddress of Display<starknet::ContractAddress> {
fn fmt(self: @starknet::ContractAddress, ref f: Formatter) -> Result<(), Error> {
Expand Down Expand Up @@ -58,6 +58,9 @@ mod marketplace {
}

mod mocks {
mod account;
mod erc20;
mod erc1155;
mod erc721;
mod strategy;
}
53 changes: 17 additions & 36 deletions flex_marketplace/src/marketplace/marketplace.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,11 @@ trait IMarketPlace<TState> {

#[starknet::interface]
trait IExecutionStrategy<TState> {
fn protocol_fee(self: @TState) -> u128;

fn can_execute_taker_ask(
fn protocolFee(self: @TState) -> u128;
fn canExecuteTakerAsk(
self: @TState, taker_ask: TakerOrder, maker_bid: MakerOrder, extra_params: Array<felt252>
) -> (bool, u256, u128);

fn can_execute_taker_bid(
fn canExecuteTakerBid(
self: @TState, taker_bid: TakerOrder, maker_ask: MakerOrder
) -> (bool, u256, u128);
}
Expand Down Expand Up @@ -125,6 +123,7 @@ mod MarketPlace {
impl ReentrancyGuardInternalImpl = ReentrancyGuardComponent::InternalImpl<ContractState>;


use snforge_std::PrintTrait;
#[storage]
struct Storage {
hash_domain: felt252,
Expand Down Expand Up @@ -340,13 +339,11 @@ mod MarketPlace {
assert!(!caller.is_zero(), "MarketPlace: invalid caller address {:?}", caller);
assert!(maker_ask.is_order_ask, "MarketPlace: maker ask is not an ask order");
assert!(!taker_bid.is_order_ask, "MarketPlace: taker bid is an ask order");

self.validate_order(@maker_ask, maker_ask_signature);

let (can_execute, token_id, amount) = IExecutionStrategyDispatcher {
contract_address: maker_ask.strategy
}
.can_execute_taker_bid(taker_bid, maker_ask);
.canExecuteTakerBid(taker_bid, maker_ask);

assert!(can_execute, "Marketplace: order cannot be executed");

Expand All @@ -365,26 +362,20 @@ mod MarketPlace {
taker_bid.price,
maker_ask.min_percentage_to_ask
);

let mut non_fungible_token_recipient = contract_address_const::<0>();
if custom_non_fungible_token_recepient.is_zero() {
non_fungible_token_recipient = taker_bid.taker;
} else {
non_fungible_token_recipient = custom_non_fungible_token_recepient;
};

self
.transfer_fees_and_funds(
maker_ask.strategy,
.transfer_non_fungible_token(
maker_ask.collection,
token_id,
maker_ask.currency,
taker_bid.taker,
maker_ask.signer,
taker_bid.price,
maker_ask.min_percentage_to_ask
non_fungible_token_recipient,
token_id,
amount
);

let order_hash = self
.signature_checker
.read()
Expand Down Expand Up @@ -436,19 +427,17 @@ mod MarketPlace {
let (can_execute, token_id, amount) = IExecutionStrategyDispatcher {
contract_address: maker_bid.strategy
}
.can_execute_taker_ask(taker_ask, maker_bid, extra_params);
.canExecuteTakerAsk(taker_ask, maker_bid, extra_params);

assert!(can_execute, "Marketplace: taker ask cannot be executed");

self
.is_user_order_nonce_executed_or_cancelled
.write((maker_bid.signer, maker_bid.nonce), true);

self
.transfer_non_fungible_token(
maker_bid.collection, taker_ask.taker, maker_bid.signer, token_id, amount
);

self
.transfer_fees_and_funds(
maker_bid.strategy,
Expand All @@ -460,7 +449,6 @@ mod MarketPlace {
taker_ask.price,
taker_ask.min_percentage_to_ask
);

let order_hash = self
.signature_checker
.read()
Expand Down Expand Up @@ -504,7 +492,7 @@ mod MarketPlace {
contract_address: maker_ask.strategy
};
let relayer = auction_strategy.auctionRelayer();
assert!(caller == relayer, "MarketPlace: caller {} is not relayer {}", caller, relayer);
assert!(caller == relayer, "MarketPlace: caller is not relayer");

self.validate_order(@maker_ask, maker_ask_signature);
self.validate_order(@maker_bid, maker_bid_signature);
Expand All @@ -531,7 +519,6 @@ mod MarketPlace {
maker_bid.price,
maker_ask.min_percentage_to_ask
);

self
.transfer_non_fungible_token(
maker_ask.collection, maker_ask.signer, maker_bid.signer, token_id, amount
Expand Down Expand Up @@ -667,21 +654,16 @@ mod MarketPlace {

let protocol_fee_amount = self.calculate_protocol_fee(strategy, amount);
let recipient = self.get_protocol_fee_recipient();

let currency_erc20 = IERC20CamelDispatcher { contract_address: currency };

if !protocol_fee_amount.is_zero() && !recipient.is_zero() {
currency_erc20.transferFrom(from, recipient, protocol_fee_amount.into());
}

let (recipient, royalty_amount) = self
.royalty_fee_manager
.read()
.calculate_royalty_fee_and_get_recipient(collection, token_id, amount);

if !royalty_amount.is_zero() && !recipient.is_zero() {
currency_erc20.transferFrom(from, recipient, royalty_amount.into());

self
.emit(
RoyaltyPayment {
Expand Down Expand Up @@ -724,7 +706,7 @@ mod MarketPlace {
self: @ContractState, execution_strategy: ContractAddress, amount: u128
) -> u128 {
let fee = IExecutionStrategyDispatcher { contract_address: execution_strategy }
.protocol_fee();
.protocolFee();
amount * fee / 10_000
}

Expand All @@ -733,7 +715,6 @@ mod MarketPlace {
) {
let executed_order_cancelled = self
.get_is_user_order_nonce_executed_or_cancelled(*order.signer, *order.nonce);

let min_nonce = self.get_user_min_order_nonce(*order.signer);
assert!(!executed_order_cancelled, "MarketPlace: executed order is cancelled");
assert!(
Expand All @@ -742,32 +723,32 @@ mod MarketPlace {
min_nonce,
*order.nonce
);

assert!(
!(*order.signer).is_zero(), "MarketPlace: invalid order signer {}", *order.signer
);
assert!(
!(*order.amount).is_zero(), "MarketPlace: invalid order amount {}", *order.amount
);

self
.signature_checker
.read()
.verify_maker_order_signature(self.get_hash_domain(), *order, order_signature);

let currency_whitelisted = self
.currency_manager
.read()
.is_currency_whitelisted(*order.currency);
assert!(
currency_whitelisted, "MarketPlace: currency {} is not whitelisted", *order.currency
);

let strategy_whitelisted = self
.execution_manager
.read()
.is_strategy_whitelisted(*order.strategy);
assert!(strategy_whitelisted, "MarketPlace: strategy is not whitelisted");
assert!(
strategy_whitelisted,
"MarketPlace: strategy {} is not whitelisted",
(*order.strategy)
);
}
}
}
2 changes: 2 additions & 0 deletions flex_marketplace/src/marketplace/transfer_selector_NFT.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ mod TransferSelectorNFT {
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

use snforge_std::PrintTrait;

#[storage]
struct Storage {
initialized: bool,
Expand Down
73 changes: 73 additions & 0 deletions flex_marketplace/src/mocks/account.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts for Cairo v0.7.0 (account/account.cairo)

trait PublicKeyTrait<TState> {
fn set_public_key(ref self: TState, new_public_key: felt252);
fn get_public_key(self: @TState) -> felt252;
}

trait PublicKeyCamelTrait<TState> {
fn setPublicKey(ref self: TState, newPublicKey: felt252);
fn getPublicKey(self: @TState) -> felt252;
}

#[starknet::contract]
mod Account {
use ecdsa::check_ecdsa_signature;

use openzeppelin::account::interface;
use openzeppelin::introspection::interface::ISRC5;
use openzeppelin::introspection::interface::ISRC5Camel;
use openzeppelin::account::account::AccountComponent;
use starknet::account::Call;
use starknet::get_caller_address;
use starknet::get_contract_address;
use starknet::get_tx_info;
use openzeppelin::introspection::src5::SRC5Component;

component!(path: SRC5Component, storage: src5, event: SRC5Event);

#[abi(embed_v0)]
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;
#[abi(embed_v0)]
impl SRC5CamelImpl = SRC5Component::SRC5CamelImpl<ContractState>;
impl SRC5InternalImpl = SRC5Component::InternalImpl<ContractState>;

component!(path: AccountComponent, storage: account, event: AccountEvent);
#[abi(embed_v0)]
impl SRC6Impl = AccountComponent::SRC6Impl<ContractState>;
#[abi(embed_v0)]
impl DeployableImpl = AccountComponent::DeployableImpl<ContractState>;
#[abi(embed_v0)]
impl DeclarerImpl = AccountComponent::DeclarerImpl<ContractState>;
#[abi(embed_v0)]
impl PublicKeyImpl = AccountComponent::PublicKeyImpl<ContractState>;
#[abi(embed_v0)]
impl SRC6CamelOnlyImpl = AccountComponent::SRC6CamelOnlyImpl<ContractState>;
#[abi(embed_v0)]
impl PublicKeyCamelImpl = AccountComponent::PublicKeyCamelImpl<ContractState>;
impl InternalImpl = AccountComponent::InternalImpl<ContractState>;

#[storage]
struct Storage {
#[substorage(v0)]
src5: SRC5Component::Storage,
#[substorage(v0)]
account: AccountComponent::Storage
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
SRC5Event: SRC5Component::Event,
#[flat]
AccountEvent: AccountComponent::Event
}

#[constructor]
fn constructor(ref self: ContractState, _public_key: felt252) {
self.account.initializer(_public_key);
}
}

Loading

0 comments on commit 845f144

Please sign in to comment.