Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fees and cancel order #8

Merged
merged 4 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/cairo/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ echo $NATIVE_TOKEN_ETH_STARKNET
CONTRACT_ADDRESS=`starkli deploy --rpc $SN_RPC_URL $CLASS_HASH $HERODOTUS_FACTS_REGISTRY $ETH_CONTRACT_ADDR $MM_ETHEREUM_WALLET $SN_WALLET_ADDR $NATIVE_TOKEN_ETH_STARKNET 2>&1 | grep -A1 "Contract deployed" | sed '1d'`

echo $CONTRACT_ADDRESS

starkli invoke --rpc $SN_RPC_URL eth approve $CONTRACT_ADDRESS 1000000000 1000000000
44 changes: 33 additions & 11 deletions contracts/cairo/src/escrow.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use starknet::{ContractAddress, EthAddress};
#[derive(Copy, Drop, Serde, starknet::Store)]
struct Order {
recipient_address: EthAddress,
amount: u256
amount: u256,
fee: u256
}

#[starknet::interface]
Expand All @@ -16,6 +17,8 @@ trait IEscrow<ContractState> {

fn get_order_used(self: @ContractState, order_id: u256) -> bool;

fn get_order_fee(self: @ContractState, order_id: u256) -> u256;

fn withdraw(ref self: ContractState, order_id: u256, block: u256, slot: u256);

fn get_herodotus_facts_registry_contract(self: @ContractState) -> ContractAddress;
Expand All @@ -34,7 +37,7 @@ trait IEscrow<ContractState> {
mod Escrow {
use super::{IEscrow, Order};

use starknet::{ContractAddress, EthAddress, get_caller_address, get_contract_address};
use starknet::{ContractAddress, EthAddress, get_caller_address, get_contract_address, get_block_timestamp};

use yab::interfaces::IERC20::{IERC20Dispatcher, IERC20DispatcherTrait};
use yab::interfaces::IEVMFactsRegistry::{
Expand All @@ -59,6 +62,7 @@ mod Escrow {
order_id: u256,
recipient_address: EthAddress,
amount: u256,
fee: u256
}

#[derive(Drop, starknet::Event)]
Expand All @@ -74,6 +78,8 @@ mod Escrow {
current_order_id: u256,
orders: LegacyMap::<u256, Order>,
orders_used: LegacyMap::<u256, bool>,
orders_senders: LegacyMap::<u256, ContractAddress>,
orders_timestamps: LegacyMap::<u256, u64>,
herodotus_facts_registry_contract: ContractAddress,
eth_transfer_contract: EthAddress, // our transfer contract in L1
mm_ethereum_wallet: EthAddress,
Expand Down Expand Up @@ -107,22 +113,22 @@ mod Escrow {
}

fn set_order(ref self: ContractState, order: Order) -> u256 {
// TODO expiry can't be less than 24h
assert(order.amount > 0, 'Amount must be greater than 0');

let mut order_id = self.current_order_id.read();
self.orders.write(order_id, order);
self.orders_used.write(order_id, false);

// TODO: add allowance ?
self.orders_senders.write(order_id, get_caller_address());
self.orders_timestamps.write(order_id, get_block_timestamp());
let payment_amount = order.amount + order.fee;

IERC20Dispatcher { contract_address: self.native_token_eth_starknet.read() }
.transferFrom(get_caller_address(), get_contract_address(), order.amount);
.transferFrom(get_caller_address(), get_contract_address(), payment_amount);

self
.emit(
SetOrder {
order_id, recipient_address: order.recipient_address, amount: order.amount
order_id, recipient_address: order.recipient_address, amount: order.amount, fee: order.fee
}
);

Expand All @@ -132,14 +138,28 @@ mod Escrow {

fn cancel_order(
ref self: ContractState, order_id: u256
) { // TODO the order can be cancelled if no one reserved yet
// the user can retrieve all the funds without waiting for the expiry
) {
assert(!self.orders_used.read(order_id), 'Order already withdrawed');
assert(get_block_timestamp() - self.orders_timestamps.read(order_id) < 43200, 'Didnt passed enough time');

let sender = self.orders_senders.read(order_id);
assert(sender == get_caller_address(), 'Only sender allowed');
let order = self.orders.read(order_id);
let payment_amount = order.amount + order.fee;

IERC20Dispatcher { contract_address: self.native_token_eth_starknet.read() }
.transfer(sender, payment_amount);
}

fn get_order_used(self: @ContractState, order_id: u256) -> bool {
self.orders_used.read(order_id)
}

fn get_order_fee(self: @ContractState, order_id: u256) -> u256 {
let order: Order = self.orders.read(order_id);
order.fee
}

fn withdraw(ref self: ContractState, order_id: u256, block: u256, slot: u256) {
assert(!self.orders_used.read(order_id), 'Order already withdrawed');

Expand Down Expand Up @@ -182,9 +202,10 @@ mod Escrow {
assert(order.amount == amount, 'amount not match L1');

self.orders_used.write(order_id, true);
let payment_amount = order.amount + order.fee;

IERC20Dispatcher { contract_address: self.native_token_eth_starknet.read() }
.transfer(self.mm_starknet_wallet.read(), amount);
.transfer(self.mm_starknet_wallet.read(), payment_amount);

self.emit(Withdraw { order_id, address: self.mm_starknet_wallet.read(), amount });
}
Expand Down Expand Up @@ -258,9 +279,10 @@ mod Escrow {
assert(order.amount == amount, 'amount not match L1');

self.orders_used.write(order_id, true);
let payment_amount = order.amount + order.fee;

IERC20Dispatcher { contract_address: self.native_token_eth_starknet.read() }
.transfer(self.mm_starknet_wallet.read(), amount);
.transfer(self.mm_starknet_wallet.read(), payment_amount);

self.emit(Withdraw { order_id, address: self.mm_starknet_wallet.read(), amount });
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/cairo/src/mocks/mock_EVMFactsRegistry.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod EVMFactsRegistry {
#[constructor]
fn constructor(ref self: ContractState) {
self.slots.write(0, 12345); // mock recipient_address
self.slots.write(2, 500); // mock amount
self.slots.write(1, 500); // mock amount
}

#[external(v0)]
Expand Down
2 changes: 1 addition & 1 deletion contracts/cairo/src/tests/test_escrow.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ mod Escrow {
assert(eth_token.balanceOf(MM_STARKNET()) == 0, 'init: wrong balance');

start_prank(escrow.contract_address, USER());
let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500 };
let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500, fee: 0 };
let order_id = escrow.set_order(order);
stop_prank(escrow.contract_address);

Expand Down
Loading