Skip to content

Commit

Permalink
Merge branch 'develop' into refactor/ts-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonard-Pat committed Jun 6, 2024
2 parents 633aa2c + c037542 commit b9e1a0c
Show file tree
Hide file tree
Showing 14 changed files with 67 additions and 179 deletions.
69 changes: 0 additions & 69 deletions scripts/double-transfer.js

This file was deleted.

17 changes: 0 additions & 17 deletions scripts/monitor-nonce.js

This file was deleted.

1 change: 1 addition & 0 deletions scripts/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ for (const useTxV3 of [false, true]) {

// Ensure there is a contract for the claim
const claimAddress = await factory.get_claim_address(
claimAccountClassHash,
deployer.address,
amount,
maxFee,
Expand Down
25 changes: 18 additions & 7 deletions src/contracts/claim_account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ mod ClaimAccount {
use openzeppelin::token::erc20::interface::{IERC20, IERC20DispatcherTrait, IERC20Dispatcher};
use starknet::{
ClassHash, account::Call, VALIDATED, call_contract_syscall, ContractAddress, get_contract_address,
get_caller_address, contract_address::contract_address_const, get_execution_info
get_caller_address, contract_address::contract_address_const, get_execution_info, info::v2::ResourceBounds,
};
use starknet_gifting::contracts::claim_hash::{ClaimExternal, IOffChainMessageHashRev1};
use starknet_gifting::contracts::claim_utils::calculate_claim_account_address;
use starknet_gifting::contracts::interface::{IAccount, IGiftAccount, ClaimData, AccountConstructorArguments};
use starknet_gifting::contracts::utils::{
full_deserialize, STRK_ADDRESS, ETH_ADDRESS, TX_V1_ESTIMATE, TX_V1, TX_V3, TX_V3_ESTIMATE, compute_max_fee_v3,
execute_multicall
full_deserialize, STRK_ADDRESS, ETH_ADDRESS, TX_V1_ESTIMATE, TX_V1, TX_V3, TX_V3_ESTIMATE, execute_multicall
};
#[storage]
struct Storage {}
Expand Down Expand Up @@ -56,12 +55,10 @@ mod ClaimAccount {
if claim.token == STRK_ADDRESS() {
assert(tx_version == TX_V3 || tx_version == TX_V3_ESTIMATE, 'gift-acc/invalid-tx3-version');
let tx_fee = compute_max_fee_v3(tx_info.resource_bounds, tx_info.tip);
// TODO: should this error be max fee too high?
assert(tx_fee <= claim.max_fee, 'gift-acc/insufficient-v3-fee');
assert(tx_fee <= claim.max_fee, 'gift-acc/max-fee-too-high-v3');
} else if claim.token == ETH_ADDRESS() {
assert(tx_version == TX_V1 || tx_version == TX_V1_ESTIMATE, 'gift-acc/invalid-tx1-version');
// TODO: should this error be max fee too high?
assert(tx_info.max_fee <= claim.max_fee, 'gift-acc/insufficient-v1-fee');
assert(tx_info.max_fee <= claim.max_fee, 'gift-acc/max-fee-too-high-v1');
} else {
core::panic_with_felt252('gift-acc/invalid-token');
}
Expand Down Expand Up @@ -99,4 +96,18 @@ mod ClaimAccount {
assert(calculated_address == get_contract_address(), 'gift-acc/invalid-claim-address');
}
}

fn compute_max_fee_v3(mut resource_bounds: Span<ResourceBounds>, tip: u128) -> u128 {
let mut max_fee: u128 = 0;
let mut max_tip: u128 = 0;
while let Option::Some(r) = resource_bounds
.pop_front() {
let max_resource_amount: u128 = (*r.max_amount).into();
max_fee += *r.max_price_per_unit * max_resource_amount;
if *r.resource == 'L2_GAS' {
max_tip += tip * max_resource_amount;
}
};
max_fee + max_tip
}
}
1 change: 0 additions & 1 deletion src/contracts/claim_hash.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct StarknetDomain {

#[derive(Drop, Copy)]
struct ClaimExternal {
claim: ClaimData,
receiver: ContractAddress
}

Expand Down
40 changes: 13 additions & 27 deletions src/contracts/gift_factory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,15 @@ mod GiftFactory {
) {
self.pausable.assert_not_paused();
assert(token == STRK_ADDRESS() || token == ETH_ADDRESS(), 'gift-fac/invalid-token');
// TODO: Assert max_fee is not zero?
assert(max_fee.into() < amount, 'gift-fac/fee-too-high');

let sender = get_caller_address();
let factory = get_contract_address();
// TODO We could manually serialize for better performance
// TODO pubkey can be zero?
let class_hash = self.claim_class_hash.read();
let constructor_arguments = AccountConstructorArguments { sender, amount, max_fee, token, claim_pubkey };
let (claim_contract, _) = deploy_syscall(
self.claim_class_hash.read(), // class_hash
class_hash, // class_hash
0, // salt
serialize(@constructor_arguments).span(), // constructor data
false // deploy_from_zero
Expand All @@ -120,14 +119,7 @@ mod GiftFactory {
self
.emit(
GiftCreated {
claim_pubkey,
factory,
gift_address: claim_contract,
class_hash: self.claim_class_hash.read(),
sender,
amount,
max_fee,
token,
claim_pubkey, factory, gift_address: claim_contract, class_hash, sender, amount, max_fee, token,
}
);
let transfer_status = IERC20Dispatcher { contract_address: token }
Expand All @@ -139,7 +131,7 @@ mod GiftFactory {
let claim_address = self.check_factory_and_get_account_address(claim);
assert(get_caller_address() == claim_address, 'gift/only-claim-account');
let balance = IERC20Dispatcher { contract_address: claim.token }.balance_of(claim_address);
assert(balance > claim.amount, 'gift-acc/gift-canceled');
assert(balance >= claim.amount, 'gift/already-claimed-or-cancel');
self.transfer_from_account(claim, claim_address, claim.token, claim.amount, receiver);
self.emit(GiftClaimed { receiver });
}
Expand All @@ -148,25 +140,26 @@ mod GiftFactory {
ref self: ContractState, claim: ClaimData, receiver: ContractAddress, signature: Array<felt252>
) {
let claim_address = self.check_factory_and_get_account_address(claim);
let claim_external_hash = ClaimExternal { claim, receiver }.get_message_hash_rev_1(claim_address);
let claim_external_hash = ClaimExternal { receiver }.get_message_hash_rev_1(claim_address);
assert(
check_ecdsa_signature(claim_external_hash, claim.claim_pubkey, *signature[0], *signature[1]),
'gift-acc/invalid-ext-signature'
'gift/invalid-ext-signature'
);

let balance = IERC20Dispatcher { contract_address: claim.token }.balance_of(claim_address);
assert(balance >= claim.amount, 'gift/already-claimed-or-cancel');
self.transfer_from_account(claim, claim_address, claim.token, balance, receiver);
self.emit(GiftClaimed { receiver });
}

fn cancel(ref self: ContractState, claim: ClaimData) {
let claim_address = self.check_factory_and_get_account_address(claim);
assert(get_caller_address() == claim.sender, 'gift-acc/wrong-sender');
assert(get_caller_address() == claim.sender, 'gift/wrong-sender');

let balance = IERC20Dispatcher { contract_address: claim.token }.balance_of(claim_address);
// Won't that lead to the sender also being able to get the extra dust?
// assert(balance > claim.max_fee, 'already claimed');
assert(balance > 0, 'gift-acc/already-claimed');
assert(balance > 0, 'gift/already-claimed');
self.transfer_from_account(claim, claim_address, claim.token, balance, claim.sender);
self.emit(GiftCanceled {});
}
Expand All @@ -181,28 +174,21 @@ mod GiftFactory {
self.transfer_from_account(claim, claim_address, claim.token, balance, receiver);
}

fn get_claim_class_hash(ref self: ContractState) -> ClassHash {
fn get_latest_claim_class_hash(self: @ContractState) -> ClassHash {
self.claim_class_hash.read()
}

fn get_claim_address(
self: @ContractState,
class_hash: ClassHash,
sender: ContractAddress,
amount: u256,
max_fee: u128,
token: ContractAddress,
claim_pubkey: felt252
) -> ContractAddress {
calculate_claim_account_address(
ClaimData {
factory: get_contract_address(),
class_hash: self.claim_class_hash.read(),
sender,
amount,
max_fee,
token,
claim_pubkey,
}
ClaimData { factory: get_contract_address(), class_hash, sender, amount, max_fee, token, claim_pubkey, }
)
}
}
Expand Down Expand Up @@ -254,7 +240,7 @@ mod GiftFactory {
]
);
let transfer_status = full_deserialize::<bool>(*results.at(0)).expect('gift/invalid-result-calldata');
assert(transfer_status, 'gift-acc/transfer-failed');
assert(transfer_status, 'gift/transfer-failed');
}
}
}
16 changes: 7 additions & 9 deletions src/contracts/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@ trait IAccount<TContractState> {
#[starknet::interface]
trait IGiftFactory<TContractState> {
fn deposit(ref self: TContractState, amount: u256, max_fee: u128, token: ContractAddress, claim_pubkey: felt252);
fn claim_internal(ref self: TContractState, claim: ClaimData, receiver: ContractAddress);
fn claim_external(ref self: TContractState, claim: ClaimData, receiver: ContractAddress, signature: Array<felt252>);
fn cancel(ref self: TContractState, claim: ClaimData);
fn get_dust(ref self: TContractState, claim: ClaimData, receiver: ContractAddress);

fn get_latest_claim_class_hash(self: @TContractState) -> ClassHash;
fn get_claim_address(
self: @TContractState,
class_hash: ClassHash,
sender: ContractAddress,
amount: u256,
max_fee: u128,
token: ContractAddress,
claim_pubkey: felt252
) -> ContractAddress;
fn get_claim_class_hash(ref self: TContractState) -> ClassHash;

fn claim_internal(ref self: TContractState, claim: ClaimData, receiver: ContractAddress);

fn claim_external(ref self: TContractState, claim: ClaimData, receiver: ContractAddress, signature: Array<felt252>);

fn cancel(ref self: TContractState, claim: ClaimData);

fn get_dust(ref self: TContractState, claim: ClaimData, receiver: ContractAddress);
}

#[starknet::interface]
Expand Down
20 changes: 1 addition & 19 deletions src/contracts/utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
use core::hash::{HashStateTrait, HashStateExTrait, Hash};
use core::poseidon::{PoseidonTrait, HashState};
use openzeppelin::token::erc20::interface::IERC20Dispatcher;
use starknet::{
ContractAddress, account::Call, contract_address::contract_address_const, info::v2::ResourceBounds,
call_contract_syscall
};
use starknet::{ContractAddress, account::Call, contract_address::contract_address_const, call_contract_syscall};

pub const TX_V1: felt252 = 1; // INVOKE
pub const TX_V1_ESTIMATE: felt252 = consteval_int!(0x100000000000000000000000000000000 + 1); // 2**128 + TX_V1
Expand Down Expand Up @@ -37,21 +34,6 @@ fn serialize<E, impl ESerde: Serde<E>>(value: @E) -> Array<felt252> {
output
}


fn compute_max_fee_v3(mut resource_bounds: Span<ResourceBounds>, tip: u128) -> u128 {
let mut max_fee: u128 = 0;
let mut max_tip: u128 = 0;
while let Option::Some(r) = resource_bounds
.pop_front() {
let max_resource_amount: u128 = (*r.max_amount).into();
max_fee += *r.max_price_per_unit * max_resource_amount;
if *r.resource == 'L2_GAS' {
max_tip += tip * max_resource_amount;
}
};
max_fee + max_tip
}

fn execute_multicall(mut calls: Span<Call>) -> Array<Span<felt252>> {
let mut result = array![];
let mut index = 0;
Expand Down
Loading

0 comments on commit b9e1a0c

Please sign in to comment.