Skip to content

Commit

Permalink
Fees and cancel order (#8)
Browse files Browse the repository at this point in the history
* base fee mechanism; mmb bot using the withdraw fallback on storage proof fail

* add fee checking conditions on the mm bot

* add cancel order logic

---------

Co-authored-by: rcatalan98 <[email protected]>
  • Loading branch information
d-roak and rcatalan98 authored Dec 21, 2023
1 parent fdd9c01 commit 09b9f31
Show file tree
Hide file tree
Showing 6 changed files with 2,862 additions and 374 deletions.
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

0 comments on commit 09b9f31

Please sign in to comment.