Skip to content

Commit

Permalink
feat(executor): add get_fees_amount view to retrieve fees for a giv…
Browse files Browse the repository at this point in the history
…en token
  • Loading branch information
ptisserand committed Aug 27, 2024
1 parent 6662fa3 commit c9ee8f4
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 10 deletions.
72 changes: 62 additions & 10 deletions contracts/ark_starknet/src/executor.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ mod executor {
use ark_oz::erc2981::{FeesRatio, FeesRatioDefault, FeesImpl};

use ark_starknet::interfaces::{IExecutor, IUpgradable};
use ark_starknet::interfaces::FeesAmount;

use ark_starknet::appchain_messaging::{
IAppchainMessagingDispatcher, IAppchainMessagingDispatcherTrait,
Expand Down Expand Up @@ -222,6 +223,32 @@ mod executor {
self.creator_fees.write(nft_address, (receiver, fees_ratio));
}

fn get_fees_amount(
self: @ContractState,
fulfill_broker: ContractAddress,
listing_broker: ContractAddress,
nft_address: ContractAddress,
nft_token_id: u256,
payment_amount: u256
) -> FeesAmount {
let (
fulfill_broker_fees_amount,
listing_broker_fees_amount,
ark_fees_amount,
creator_fees_amount
) =
_compute_fees_amount(
self, fulfill_broker, listing_broker, nft_address, nft_token_id, payment_amount
);

FeesAmount {
fulfill_broker: fulfill_broker_fees_amount,
listing_broker: listing_broker_fees_amount,
ark: ark_fees_amount,
creator: creator_fees_amount,
}
}

fn get_messaging_address(self: @ContractState) -> ContractAddress {
self.messaging_address.read()
}
Expand Down Expand Up @@ -355,22 +382,21 @@ mod executor {
contract_address: execution_info.payment_currency_address.try_into().unwrap()
};

let fulfill_broker_fees = self.get_broker_fees(execution_info.fulfill_broker_address);
let listing_broker_fees = self.get_broker_fees(execution_info.listing_broker_address);
let ark_fees = self.ark_fees.read();

let fulfill_broker_fees_amount = fulfill_broker_fees
.compute_amount(execution_info.payment_amount);
let listing_broker_fees_amount = listing_broker_fees
.compute_amount(execution_info.payment_amount);
let (creator_address, creator_fees_amount) = _compute_creator_fees_amount(
@self,
@execution_info.nft_address,
execution_info.payment_amount,
execution_info.nft_token_id
);
let ark_fees_amount = ark_fees.compute_amount(execution_info.payment_amount);

let (fulfill_broker_fees_amount, listing_broker_fees_amount, ark_fees_amount, _) =
_compute_fees_amount(
@self,
execution_info.fulfill_broker_address,
execution_info.listing_broker_address,
execution_info.nft_address,
execution_info.nft_token_id,
execution_info.payment_amount
);
assert!(
execution_info
.payment_amount > (fulfill_broker_fees_amount
Expand Down Expand Up @@ -772,4 +798,30 @@ mod executor {
let amount = fees_ratio.compute_amount(payment_amount);
(receiver, amount)
}

fn _compute_fees_amount(
self: @ContractState,
fulfill_broker_address: ContractAddress,
listing_broker_address: ContractAddress,
nft_address: ContractAddress,
nft_token_id: u256,
payment_amount: u256
) -> (u256, u256, u256, u256) {
let fulfill_broker_fees = self.get_broker_fees(fulfill_broker_address);
let listing_broker_fees = self.get_broker_fees(listing_broker_address);
let ark_fees = self.ark_fees.read();

let fulfill_broker_fees_amount = fulfill_broker_fees.compute_amount(payment_amount);
let listing_broker_fees_amount = listing_broker_fees.compute_amount(payment_amount);
let (_, creator_fees_amount) = _compute_creator_fees_amount(
self, @nft_address, payment_amount, nft_token_id
);
let ark_fees_amount = ark_fees.compute_amount(payment_amount);
(
fulfill_broker_fees_amount,
listing_broker_fees_amount,
ark_fees_amount,
creator_fees_amount,
)
}
}
16 changes: 16 additions & 0 deletions contracts/ark_starknet/src/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ use ark_common::protocol::order_types::OrderV1;
use ark_common::protocol::order_types::{FulfillInfo, CancelInfo};
use ark_oz::erc2981::FeesRatio;

#[derive(Serde, Drop)]
struct FeesAmount {
fulfill_broker: u256,
listing_broker: u256,
ark: u256,
creator: u256,
}

#[starknet::interface]
trait IExecutor<T> {
Expand Down Expand Up @@ -32,6 +39,15 @@ trait IExecutor<T> {
fn set_collection_creator_fees(
ref self: T, nft_address: ContractAddress, receiver: ContractAddress, fees_ratio: FeesRatio
);

fn get_fees_amount(
self: @T,
fulfill_broker: ContractAddress,
listing_broker: ContractAddress,
nft_address: ContractAddress,
nft_token_id: u256,
payment_amount: u256
) -> FeesAmount;
}

#[starknet::interface]
Expand Down
89 changes: 89 additions & 0 deletions contracts/ark_starknet/tests/integration/fees_amount.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use starknet::{ContractAddress, contract_address_const};

use ark_starknet::interfaces::{
IExecutorDispatcher, IExecutorDispatcherTrait, FeesAmount, FeesRatio
};

use snforge_std as snf;
use snf::{ContractClass, ContractClassTrait, CheatTarget};

use super::super::common::setup::setup;


#[test]
fn test_get_fees_amount_default_creator() {
let admin = contract_address_const::<'admin'>();
let creator = contract_address_const::<'creator'>();
let listing_broker = contract_address_const::<'listing_broker'>();
let fulfill_broker = contract_address_const::<'fulfill_broker'>();

let amount = 10_000_000;
let (executor_address, _, nft_address) = setup();
let executor = IExecutorDispatcher { contract_address: executor_address };

let fulfill_fees_ratio = FeesRatio { numerator: 10, denominator: 100 };
let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 };
let ark_fees_ratio = FeesRatio { numerator: 1, denominator: 100 };
let default_creator_fees_ratio = FeesRatio { numerator: 2, denominator: 100 };

snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker);
executor.set_broker_fees(fulfill_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker);
executor.set_broker_fees(listing_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

snf::start_prank(CheatTarget::One(executor.contract_address), admin);
executor.set_ark_fees(ark_fees_ratio);
executor.set_default_creator_fees(creator, default_creator_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

let fees_amount = executor
.get_fees_amount(fulfill_broker, listing_broker, nft_address, 1, amount);

assert_eq!(fees_amount.fulfill_broker, 1_000_000, "Wrong amount for fulfill broker");
assert_eq!(fees_amount.listing_broker, 500_000, "Wrong amount for listing broker");
assert_eq!(fees_amount.ark, 100_000, "Wrong amount for Ark");
assert_eq!(fees_amount.creator, 200_000, "Wrong amount for creator");
}

#[test]
fn test_get_fees_amount_collection_creator() {
let admin = contract_address_const::<'admin'>();
let creator = contract_address_const::<'creator'>();
let listing_broker = contract_address_const::<'listing_broker'>();
let fulfill_broker = contract_address_const::<'fulfill_broker'>();

let amount = 10_000_000;
let (executor_address, _, nft_address) = setup();
let executor = IExecutorDispatcher { contract_address: executor_address };

let fulfill_fees_ratio = FeesRatio { numerator: 10, denominator: 100 };
let listing_fees_ratio = FeesRatio { numerator: 5, denominator: 100 };
let ark_fees_ratio = FeesRatio { numerator: 1, denominator: 100 };
let default_creator_fees_ratio = FeesRatio { numerator: 2, denominator: 100 };
let collection_creator_fees_ratio = FeesRatio { numerator: 3, denominator: 100 };

snf::start_prank(CheatTarget::One(executor.contract_address), fulfill_broker);
executor.set_broker_fees(fulfill_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

snf::start_prank(CheatTarget::One(executor.contract_address), listing_broker);
executor.set_broker_fees(listing_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

snf::start_prank(CheatTarget::One(executor.contract_address), admin);
executor.set_ark_fees(ark_fees_ratio);
executor.set_default_creator_fees(creator, default_creator_fees_ratio);
executor.set_collection_creator_fees(nft_address, creator, collection_creator_fees_ratio);
snf::stop_prank(CheatTarget::One(executor.contract_address));

let fees_amount = executor
.get_fees_amount(fulfill_broker, listing_broker, nft_address, 1, amount);

assert_eq!(fees_amount.fulfill_broker, 1_000_000, "Wrong amount for fulfill broker");
assert_eq!(fees_amount.listing_broker, 500_000, "Wrong amount for listing broker");
assert_eq!(fees_amount.ark, 100_000, "Wrong amount for Ark");
assert_eq!(fees_amount.creator, 300_000, "Wrong amount for creator");
}
1 change: 1 addition & 0 deletions contracts/ark_starknet/tests/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod unit {
}
mod integration {
mod create_order;
mod fees_amount;
mod fulfill_order;
mod execute_order;
}

0 comments on commit c9ee8f4

Please sign in to comment.