Skip to content

Commit

Permalink
Merge pull request #20 from lana-shanghai/li/dev/fmt
Browse files Browse the repository at this point in the history
Li/dev/fmt
  • Loading branch information
lana-shanghai authored Dec 5, 2024
2 parents 27c42e8 + fff15e8 commit 1542a05
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 129 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:

- name: Run tests and generate report
run: snforge test
working-directory: packages/onchain
working-directory: packages/onchain
29 changes: 16 additions & 13 deletions packages/onchain/src/orderbook/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use core::starknet::contract_address::ContractAddress;
#[derive(Default, Drop, PartialEq, starknet::Store)]
pub enum Status {
Open,
Locked,
Canceled,
Locked,
Canceled,
Closed,
#[default]
Undefined,
Expand All @@ -13,12 +13,12 @@ pub enum Status {
#[starknet::interface]
pub trait IOrderbook<TContractState> {
fn request_inscription(
ref self: TContractState,
ref self: TContractState,
inscription_data: ByteArray,
receiving_address: ByteArray,
satoshi: felt252,
currency_fee: felt252,
submitter_fee: u256
satoshi: felt252,
currency_fee: felt252,
submitter_fee: u256,
) -> u32;
fn cancel_inscription(ref self: TContractState, inscription_id: u32, currency_fee: felt252);
fn lock_inscription(ref self: TContractState, inscription_id: u32, tx_hash: ByteArray);
Expand All @@ -31,12 +31,12 @@ pub trait IOrderbook<TContractState> {
#[starknet::interface]
pub trait OrderbookABI<TContractState> {
fn request_inscription(
ref self: TContractState,
ref self: TContractState,
inscription_data: ByteArray,
receiving_address: ByteArray,
satoshi: felt252,
currency_fee: felt252,
submitter_fee: u256
satoshi: felt252,
currency_fee: felt252,
submitter_fee: u256,
) -> u32;
fn cancel_inscription(ref self: TContractState, inscription_id: u32, currency_fee: felt252);
fn lock_inscription(ref self: TContractState, inscription_id: u32, tx_hash: ByteArray);
Expand All @@ -49,11 +49,14 @@ pub trait OrderbookABI<TContractState> {
fn balance_of(self: @TContractState, account: ContractAddress) -> felt252;
fn transfer(ref self: TContractState, recipient: ContractAddress, amount: felt252);
fn transfer_from(
ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: felt252
ref self: TContractState,
sender: ContractAddress,
recipient: ContractAddress,
amount: felt252,
);
fn approve(ref self: TContractState, spender: ContractAddress, amount: felt252);
fn increase_allowance(ref self: TContractState, spender: ContractAddress, added_value: felt252);
fn decrease_allowance(
ref self: TContractState, spender: ContractAddress, subtracted_value: felt252
ref self: TContractState, spender: ContractAddress, subtracted_value: felt252,
);
}
}
115 changes: 46 additions & 69 deletions packages/onchain/src/orderbook/orderbook.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ mod Orderbook {
use core::byte_array::ByteArray;
use onchain::orderbook::interface::Status;
use openzeppelin_token::erc20::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait};
use starknet::storage::{
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePathEntry,
StoragePointerReadAccess, StoragePointerWriteAccess,
use starknet::storage::{
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePathEntry,
StoragePointerReadAccess, StoragePointerWriteAccess,
};
use starknet::{ContractAddress, get_caller_address, get_contract_address, get_block_number};

#[storage]
struct Storage {
// ID of the next inscription.
new_inscription_id: u32,
// A map from the inscription ID to a tuple with the inscribed
// A map from the inscription ID to a tuple with the inscribed
// data and submitter fee.
inscriptions: Map<u32, (ByteArray, u256)>,
// A map from the inscription ID to status. Possible values:
Expand All @@ -26,22 +26,20 @@ mod Orderbook {
// Locks on inscriptions. Maps the inscription ID to a tuple of
// submitter address, precomputed transaction hash, and block number.
inscription_locks: Map<u32, (ContractAddress, ByteArray, u64)>,
// STRK fee token.
// STRK fee token.
strk_token: ERC20ABIDispatcher,
}

#[constructor]
fn constructor(
ref self: ContractState, strk_token: ContractAddress
) {
fn constructor(ref self: ContractState, strk_token: ContractAddress) {
// initialize contract
self.initializer(:strk_token);
}

#[abi(embed_v0)]
impl OrderbookImpl of super::IOrderbook<ContractState> {
/// Called by a user.
/// Inputs:
/// Called by a user.
/// Inputs:
/// - `inscription_data: ByteArray`, the data to be inscribed on Bitcoin.
/// - `receiving_address: ByteArray`, the taproot address that will own the inscription.
/// - `satoshi: felt252`, the Sat where the user wants to inscribe data.
Expand All @@ -50,27 +48,27 @@ mod Orderbook {
/// Returns:
/// - `id: felt252`, the ID of the created inscription.
fn request_inscription(
ref self: ContractState,
ref self: ContractState,
inscription_data: ByteArray,
receiving_address: ByteArray,
satoshi: felt252,
currency_fee: felt252,
satoshi: felt252,
currency_fee: felt252,
submitter_fee: u256,
) -> u32 {
assert(
self.is_valid_bitcoin_address(receiving_address) == true,
'Not a valid bitcoin address'
);
assert(
currency_fee == 'STRK'.into(),
'The currency is not supported'
self.is_valid_bitcoin_address(receiving_address) == true,
'Not a valid bitcoin address',
);
assert(currency_fee == 'STRK'.into(), 'The currency is not supported');
let caller = get_caller_address();
let escrow_address = get_contract_address();
if (currency_fee == 'STRK'.into()) {
let strk_token = self.strk_token.read();
// TODO: change the transfer to the escrow contract once it's implemented.
strk_token.transfer_from(sender: caller, recipient: escrow_address, amount: submitter_fee);
strk_token
.transfer_from(
sender: caller, recipient: escrow_address, amount: submitter_fee,
);
}
let id = self.new_inscription_id.read();
self.inscriptions.write(id, (inscription_data, submitter_fee));
Expand All @@ -79,7 +77,7 @@ mod Orderbook {
}

/// Helper function that checks the format of the taproot address.
/// Inputs:
/// Inputs:
/// - `receiving_address: ByteArray`, the ID of the inscription.
/// Returns:
/// - `bool`
Expand All @@ -88,37 +86,25 @@ mod Orderbook {
true
}

/// Inputs:
/// Inputs:
/// - `inscription_id: felt252`, the ID of the inscription.
/// Returns:
/// - `(ByteArray, felt252)`, the tuple with the inscribed data and the fee.
fn query_inscription(self: @ContractState, inscription_id: u32) -> (ByteArray, u256) {
self.inscriptions.read(inscription_id)
}

/// Called by a user.
/// Inputs:
/// - `inscription_id: felt252`, the ID of the inscription the user wants to
/// cancel.
/// Called by a user.
/// Inputs:
/// - `inscription_id: felt252`, the ID of the inscription the user wants to
/// cancel.
/// - `currency_fee: felt252`, the token that the user paid the submitter fee in.
fn cancel_inscription(ref self: ContractState, inscription_id: u32, currency_fee: felt252) {
let status = self.inscription_statuses.read(inscription_id);
assert(
status != Status::Undefined,
'Inscription does not exist'
);
assert(
status != Status::Locked,
'The inscription is locked'
);
assert(
status != Status::Canceled,
'The inscription is canceled'
);
assert(
status != Status::Closed,
'The inscription has been closed'
);
assert(status != Status::Undefined, 'Inscription does not exist');
assert(status != Status::Locked, 'The inscription is locked');
assert(status != Status::Canceled, 'The inscription is canceled');
assert(status != Status::Closed, 'The inscription has been closed');

let caller = get_caller_address();
// TODO: change the address to the actual escrow contract once it's implemented.
Expand All @@ -133,35 +119,26 @@ mod Orderbook {
self.inscription_statuses.write(inscription_id, Status::Canceled);
}

/// Called by a submitter. Multiple submitters are allowed to lock the
/// inscription simultaneously. The fee will be received only by the
/// submitter that will actually create the inscription on Bitcoin.
/// Assert that the inscription has not been closed yet. If there is a
/// Called by a submitter. Multiple submitters are allowed to lock the
/// inscription simultaneously. The fee will be received only by the
/// submitter that will actually create the inscription on Bitcoin.
/// Assert that the inscription has not been closed yet. If there is a
/// prior lock on the inscription, X blocks have to pass before a new
/// lock can be created.
/// Inputs:
/// - `inscription_id: u32`, the ID of the inscription being locked.
/// Inputs:
/// - `inscription_id: u32`, the ID of the inscription being locked.
/// - `tx_hash: ByteArray`, the precomputed bitcoin transaction hash that will be
/// submitted onchain by the submitter.
/// submitted onchain by the submitter.
fn lock_inscription(ref self: ContractState, inscription_id: u32, tx_hash: ByteArray) {
let status = self.inscription_statuses.read(inscription_id);
assert(
status != Status::Undefined,
'Inscription does not exist'
);
assert(
status != Status::Canceled,
'The inscription is canceled'
);
assert(
status != Status::Closed,
'The inscription has been closed'
);
assert(status != Status::Undefined, 'Inscription does not exist');
assert(status != Status::Canceled, 'The inscription is canceled');
assert(status != Status::Closed, 'The inscription has been closed');

if (status == Status::Locked) {
let (_, _, blocknumber) = self.inscription_locks.read(inscription_id);
// TODO: replace block time delta
assert(get_block_number() - blocknumber < 100, 'Prior lock has not expired');
assert(get_block_number() - blocknumber < 100, 'Prior lock has not expired');
}

let submitter = get_caller_address();
Expand All @@ -171,11 +148,11 @@ mod Orderbook {
self.inscription_statuses.write(inscription_id, Status::Locked);
}

/// Called by a submitter. The fee is transferred to the submitter if
/// the inscription on Bitcoin has been made. The submitted hash must
/// match the precomputed transaction hash in storage. If successful,
/// Called by a submitter. The fee is transferred to the submitter if
/// the inscription on Bitcoin has been made. The submitted hash must
/// match the precomputed transaction hash in storage. If successful,
/// the status of the inscription changes from 'Locked' to 'Closed'.
/// Inputs:
/// Inputs:
/// - `inscription_id: felt252`, the ID of the inscription being locked.
/// - `tx_hash: ByteArray`, the hash of the transaction submitted to Bitcoin.
fn submit_inscription(ref self: ContractState, inscription_id: u32, tx_hash: ByteArray) {
Expand All @@ -188,8 +165,8 @@ mod Orderbook {
}

/// Helper function that checks if the inscription has already been locked.
/// Inputs:
/// - `tx_hash: ByteArray`, the precomputed transaction hash for the inscription
/// Inputs:
/// - `tx_hash: ByteArray`, the precomputed transaction hash for the inscription
/// being locked.
/// Returns:
/// - `(bool, ContractAddress)`
Expand All @@ -203,7 +180,7 @@ mod Orderbook {

#[generate_trait]
pub impl InternalImpl of InternalTrait {
/// Executed once when the Orderbook contract is deployed. Used to set
/// Executed once when the Orderbook contract is deployed. Used to set
/// initial values for contract storage variables for the fee tokens.
fn initializer(ref self: ContractState, strk_token: ContractAddress) {
self.strk_token.write(ERC20ABIDispatcher { contract_address: strk_token });
Expand Down
Loading

0 comments on commit 1542a05

Please sign in to comment.