From bea333822cecd21886d175ea03fbd13542155615 Mon Sep 17 00:00:00 2001 From: Charlotte <49371958+chachaleo@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:31:11 +0800 Subject: [PATCH] feat : escrow component (#45) * feat : escrow component * review fix : lock_from * review changes --------- Co-authored-by: Chqrles --- contracts/src/components.cairo | 1 + contracts/src/components/escrow.cairo | 3 + contracts/src/components/escrow/escrow.cairo | 76 +++++++++++++++++++ .../src/components/escrow/interface.cairo | 15 ++++ 4 files changed, 95 insertions(+) create mode 100644 contracts/src/components/escrow.cairo create mode 100644 contracts/src/components/escrow/escrow.cairo create mode 100644 contracts/src/components/escrow/interface.cairo diff --git a/contracts/src/components.cairo b/contracts/src/components.cairo index d633012..791afd3 100644 --- a/contracts/src/components.cairo +++ b/contracts/src/components.cairo @@ -1,2 +1,3 @@ +pub mod escrow; pub mod processors; pub mod registry; diff --git a/contracts/src/components/escrow.cairo b/contracts/src/components/escrow.cairo new file mode 100644 index 0000000..fc733ae --- /dev/null +++ b/contracts/src/components/escrow.cairo @@ -0,0 +1,3 @@ +pub mod escrow; +pub mod interface; + diff --git a/contracts/src/components/escrow/escrow.cairo b/contracts/src/components/escrow/escrow.cairo new file mode 100644 index 0000000..0393f50 --- /dev/null +++ b/contracts/src/components/escrow/escrow.cairo @@ -0,0 +1,76 @@ +#[starknet::component] +pub mod EscrowComponent { + use openzeppelin_token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; + use starknet::storage::Map; + use starknet::{ContractAddress, get_contract_address}; + use zkramp::components::escrow::interface; + + // + // Storage + // + + #[storage] + struct Storage { + // (owner, token) -> amount + deposits: Map::<(ContractAddress, ContractAddress), u256>, + } + + // + // Errors + // + + pub mod Errors { + pub const PROOF_OF_DEPOSIT_FAILED: felt252 = 'Proof of deposit failed'; + pub const INSUFFICIENT_BALANCE: felt252 = 'Insufficient deposit balance'; + } + + // + // Escrow impl + // + + #[embeddable_as(RegistryImpl)] + impl Escrow< + TContractState, +HasComponent, +Drop, + > of interface::IEscrow> { + fn lock_from( + ref self: ComponentState, + from: ContractAddress, + token: ContractAddress, + amount: u256 + ) { + let locked_amount = self.deposits.read((from, token)); + + // transfers funds to escrow + let erc20_dispatcher = IERC20Dispatcher { contract_address: token }; + + erc20_dispatcher.transfer_from(from, get_contract_address(), amount); + + self.deposits.write((from, token), amount + locked_amount); + } + + fn unlock_to( + ref self: ComponentState, + from: ContractAddress, + to: ContractAddress, + token: ContractAddress, + amount: u256 + ) { + let locked_amount = self.deposits.read((from, token)); + + // TODO + // check for proof of deposit + assert(true, Errors::PROOF_OF_DEPOSIT_FAILED); + + // check deposit balance + assert(locked_amount >= amount, Errors::INSUFFICIENT_BALANCE); + + // transfert of the amount to `to` + let erc20_dispatcher = IERC20Dispatcher { contract_address: token }; + + erc20_dispatcher.transfer_from(get_contract_address(), to, amount); + + // update locked amount + self.deposits.write((from, token), locked_amount - amount); + } + } +} diff --git a/contracts/src/components/escrow/interface.cairo b/contracts/src/components/escrow/interface.cairo new file mode 100644 index 0000000..c8f1079 --- /dev/null +++ b/contracts/src/components/escrow/interface.cairo @@ -0,0 +1,15 @@ +use core::hash::HashStateExTrait; +use starknet::ContractAddress; + +#[starknet::interface] +pub trait IEscrow { + fn lock_from(ref self: TState, from: ContractAddress, token: ContractAddress, amount: u256); + fn unlock_to( + ref self: TState, + from: ContractAddress, + to: ContractAddress, + token: ContractAddress, + amount: u256 + ); +} +