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

ERC auth / fix / tests #830

Merged
merged 6 commits into from
Aug 30, 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
52 changes: 45 additions & 7 deletions crates/dojo-erc/src/erc1155/components.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,38 @@ struct ERC1155Balance {
#[key]
token: ContractAddress,
#[key]
token_id: felt252,
#[key]
account: ContractAddress,
#[key]
token_id: felt252,
amount: u128
}

trait ERC1155BalanceTrait {
fn balance_of(
world: IWorldDispatcher, token: ContractAddress, account: ContractAddress, id: felt252
) -> u128;
fn transfer_tokens(
fn unchecked_transfer_tokens(
world: IWorldDispatcher,
token: ContractAddress,
from: ContractAddress,
to: ContractAddress,
ids: Span<felt252>,
amounts: Span<u128>,
);
fn unchecked_increase_balance(
world: IWorldDispatcher,
token: ContractAddress,
owner: ContractAddress,
id: felt252,
amount: u128,
);
fn unchecked_decrease_balance(
world: IWorldDispatcher,
token: ContractAddress,
owner: ContractAddress,
id: felt252,
amount: u128,
);
}

impl ERC1155BalanceImpl of ERC1155BalanceTrait {
Expand All @@ -54,10 +68,10 @@ impl ERC1155BalanceImpl of ERC1155BalanceTrait {
) -> u128 {
// ERC1155: address zero is not a valid owner
assert(account.is_non_zero(), 'ERC1155: invalid owner address');
get!(world, (token, id, account), ERC1155Balance).amount
get!(world, (token, account, id), ERC1155Balance).amount
}

fn transfer_tokens(
fn unchecked_transfer_tokens(
world: IWorldDispatcher,
token: ContractAddress,
from: ContractAddress,
Expand All @@ -73,16 +87,40 @@ impl ERC1155BalanceImpl of ERC1155BalanceTrait {
let amount: u128 = *amounts.pop_front().unwrap();

if (from.is_non_zero()) {
let mut from_balance = get!(world, (token, id, from), ERC1155Balance);
let mut from_balance = get!(world, (token, from, id), ERC1155Balance);
from_balance.amount -= amount;
set!(world, (from_balance));
}

if (to.is_non_zero()) {
let mut to_balance = get!(world, (token, id, to), ERC1155Balance);
let mut to_balance = get!(world, (token, to, id), ERC1155Balance);
to_balance.amount += amount;
set!(world, (to_balance));
};
};
}

fn unchecked_increase_balance(
world: IWorldDispatcher,
token: ContractAddress,
owner: ContractAddress,
id: felt252,
amount: u128,
) {
let mut balance = get!(world, (token, owner, id), ERC1155Balance);
balance.amount += amount;
set!(world, (balance));
}

fn unchecked_decrease_balance(
world: IWorldDispatcher,
token: ContractAddress,
owner: ContractAddress,
id: felt252,
amount: u128,
) {
let mut balance = get!(world, (token, owner, id), ERC1155Balance);
balance.amount -= amount;
set!(world, (balance));
}
}
13 changes: 7 additions & 6 deletions crates/dojo-erc/src/erc1155/erc1155.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ mod ERC1155 {
};
use dojo_erc::erc165::interface::{IERC165, IERC165_ID};

use dojo_erc::erc_common::utils::{to_calldata, ToCallDataTrait, system_calldata};
use dojo_erc::erc_common::utils::{
to_calldata, ToCallDataTrait, system_calldata, PartialEqArray
};

use dojo_erc::erc1155::systems::{
ERC1155SetApprovalForAllParams, ERC1155SafeTransferFromParams,
Expand All @@ -29,8 +31,7 @@ mod ERC1155 {
const UNLIMITED_ALLOWANCE: felt252 =
3618502788666131213697322783095070105623107215331596699973092056135872020480;


#[derive(Clone, Drop, Serde, starknet::Event)]
#[derive(Clone, Drop, Serde, PartialEq, starknet::Event)]
struct TransferSingle {
operator: ContractAddress,
from: ContractAddress,
Expand All @@ -39,7 +40,7 @@ mod ERC1155 {
value: u256
}

#[derive(Clone, Drop, Serde, starknet::Event)]
#[derive(Clone, Drop, Serde, PartialEq, starknet::Event)]
struct TransferBatch {
operator: ContractAddress,
from: ContractAddress,
Expand All @@ -48,7 +49,7 @@ mod ERC1155 {
values: Array<u256>
}

#[derive(Clone, Drop, Serde, starknet::Event)]
#[derive(Clone, Drop, Serde, PartialEq, starknet::Event)]
struct ApprovalForAll {
owner: ContractAddress,
operator: ContractAddress,
Expand All @@ -63,7 +64,7 @@ mod ERC1155 {
}

#[event]
#[derive(Drop, starknet::Event)]
#[derive(Drop, PartialEq, starknet::Event)]
enum Event {
TransferSingle: TransferSingle,
TransferBatch: TransferBatch,
Expand Down
66 changes: 46 additions & 20 deletions crates/dojo-erc/src/erc1155/systems.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ fn emit_transfer_batch(
amounts_u256.append((*amounts.pop_front().unwrap()).into());
};
let event = TransferBatch {
operator: operator, from: from, to: to, ids: ids_u256, values: amounts_u256,
operator: operator, from: from, to: to, ids: ids_u256, values: amounts_u256,
};
IERC1155EventsDispatcher { contract_address: token }.on_transfer_batch(event.clone());
emit!(world, event);
}

fn update(
fn unchecked_update(
world: IWorldDispatcher,
operator: ContractAddress,
token: ContractAddress,
Expand All @@ -71,13 +71,7 @@ fn update(
) {
assert(ids.len() == amounts.len(), 'ERC1155: invalid length');

assert(
operator == from
|| OperatorApprovalTrait::is_approved_for_all(world, token, from, operator),
'ERC1155: insufficient approval'
);

ERC1155BalanceTrait::transfer_tokens(world, token, from, to, ids.span(), amounts.span());
ERC1155BalanceTrait::unchecked_transfer_tokens(world, token, from, to, ids.span(), amounts.span());

if (ids.len() == 1) {
let id = *ids.at(0);
Expand All @@ -103,9 +97,10 @@ fn do_safe_transfer_acceptance_check(
) {
if (IERC165Dispatcher { contract_address: to }.supports_interface(IERC1155_RECEIVER_ID)) {
assert(
IERC1155TokenReceiverDispatcher {
contract_address: to
}.on_erc1155_received(operator, from, id, amount, data) == ON_ERC1155_RECEIVED_SELECTOR,
IERC1155TokenReceiverDispatcher { contract_address: to }
.on_erc1155_received(
operator, from, id, amount, data
) == ON_ERC1155_RECEIVED_SELECTOR,
'ERC1155: ERC1155Receiver reject'
);
return ();
Expand All @@ -126,9 +121,7 @@ fn do_safe_batch_transfer_acceptance_check(
) {
if (IERC165Dispatcher { contract_address: to }.supports_interface(IERC1155_RECEIVER_ID)) {
assert(
IERC1155TokenReceiverDispatcher {
contract_address: to
}
IERC1155TokenReceiverDispatcher { contract_address: to }
.on_erc1155_batch_received(
operator, from, ids, amounts, data
) == ON_ERC1155_BATCH_RECEIVED_SELECTOR,
Expand Down Expand Up @@ -172,7 +165,7 @@ mod ERC1155SetApprovalForAll {
let ERC1155SetApprovalForAllParams{token, owner, operator, approved } = params;
assert(owner != operator, 'ERC1155: wrong approval');

OperatorApprovalTrait::set_approval_for_all(ctx.world, token, owner, operator, approved);
OperatorApprovalTrait::unchecked_set_approval_for_all(ctx.world, token, owner, operator, approved);

let event = ApprovalForAll { owner, operator, approved };
IERC1155EventsDispatcher { contract_address: token }.on_approval_for_all(event.clone());
Expand Down Expand Up @@ -205,6 +198,7 @@ mod ERC1155SafeTransferFrom {
use zeroable::Zeroable;
use starknet::ContractAddress;


#[derive(Drop, Serde)]
struct ERC1155SafeTransferFromParams {
token: ContractAddress,
Expand All @@ -220,8 +214,19 @@ mod ERC1155SafeTransferFrom {
let ERC1155SafeTransferFromParams{token, operator, from, to, id, amount, data } = params;
assert(ctx.origin == operator || ctx.origin == token, 'ERC1155: not authorized');
assert(to.is_non_zero(), 'ERC1155: to cannot be 0');
assert(from.is_non_zero(), 'ERC1155: from cannot be 0');

super::update(ctx.world, operator, token, from, to, array![id], array![amount], data);
assert(
operator == from
|| super::OperatorApprovalTrait::is_approved_for_all(
ctx.world, token, from, operator
),
'ERC1155: insufficient approval'
);

super::unchecked_update(
ctx.world, operator, token, from, to, array![id], array![amount], data
);
}
}

Expand Down Expand Up @@ -251,8 +256,17 @@ mod ERC1155SafeBatchTransferFrom {

assert(ctx.origin == operator || ctx.origin == token, 'ERC1155: not authorized');
assert(to.is_non_zero(), 'ERC1155: to cannot be 0');
assert(from.is_non_zero(), 'ERC1155: from cannot be 0');

super::update(ctx.world, operator, token, from, to, ids, amounts, data);
assert(
operator == from
|| super::OperatorApprovalTrait::is_approved_for_all(
ctx.world, token, from, operator
),
'ERC1155: insufficient approval'
);

super::unchecked_update(ctx.world, operator, token, from, to, ids, amounts, data);
}
}

Expand Down Expand Up @@ -282,7 +296,9 @@ mod ERC1155Mint {
assert(ctx.origin == operator || ctx.origin == token, 'ERC1155: not authorized');
assert(to.is_non_zero(), 'ERC1155: invalid receiver');

super::update(ctx.world, operator, token, Zeroable::zero(), to, ids, amounts, data);
super::unchecked_update(
ctx.world, operator, token, Zeroable::zero(), to, ids, amounts, data
);
}
}

Expand Down Expand Up @@ -310,6 +326,16 @@ mod ERC1155Burn {
assert(ctx.origin == operator || ctx.origin == token, 'ERC1155: not authorized');
assert(from.is_non_zero(), 'ERC1155: invalid sender');

super::update(ctx.world, operator, token, from, Zeroable::zero(), ids, amounts, array![]);
assert(
operator == from
|| super::OperatorApprovalTrait::is_approved_for_all(
ctx.world, token, from, operator
),
'ERC1155: insufficient approval'
);

super::unchecked_update(
ctx.world, operator, token, from, Zeroable::zero(), ids, amounts, array![]
);
}
}
29 changes: 14 additions & 15 deletions crates/dojo-erc/src/erc721/components.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ trait ERC721OwnerTrait {
fn owner_of(
world: IWorldDispatcher, token: ContractAddress, token_id: felt252
) -> ContractAddress;
fn set_owner(
fn unchecked_set_owner(
world: IWorldDispatcher, token: ContractAddress, token_id: felt252, account: ContractAddress
);
}
Expand All @@ -42,8 +42,7 @@ impl ERC721OwnerImpl of ERC721OwnerTrait {
get!(world, (token, token_id), ERC721Owner).address
}

// perform safety checks before calling this fn
fn set_owner(
fn unchecked_set_owner(
world: IWorldDispatcher, token: ContractAddress, token_id: felt252, account: ContractAddress
) {
let mut owner = get!(world, (token, token_id), ERC721Owner);
Expand All @@ -70,20 +69,20 @@ trait ERC721BalanceTrait {
fn balance_of(
world: IWorldDispatcher, token: ContractAddress, account: ContractAddress
) -> u128;
fn transfer_token(
fn unchecked_transfer_token(
world: IWorldDispatcher,
token: ContractAddress,
from: ContractAddress,
to: ContractAddress,
amount: u128,
);

fn increase_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
fn unchecked_increase_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
);

fn decrease_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
fn unchecked_decrease_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
);
}

Expand All @@ -96,7 +95,7 @@ impl ERC721BalanceImpl of ERC721BalanceTrait {
get!(world, (token, account), ERC721Balance).amount
}

fn transfer_token(
fn unchecked_transfer_token(
world: IWorldDispatcher,
token: ContractAddress,
from: ContractAddress,
Expand All @@ -112,16 +111,16 @@ impl ERC721BalanceImpl of ERC721BalanceTrait {
set!(world, (to_balance));
}

fn increase_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
fn unchecked_increase_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
) {
let mut balance = get!(world, (token, owner), ERC721Balance);
balance.amount += amount;
set!(world, (balance));
}

fn decrease_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
fn unchecked_decrease_balance(
world: IWorldDispatcher, token: ContractAddress, owner: ContractAddress, amount: u128,
) {
let mut balance = get!(world, (token, owner), ERC721Balance);
balance.amount -= amount;
Expand Down Expand Up @@ -149,7 +148,7 @@ trait ERC721TokenApprovalTrait {
world: IWorldDispatcher, token: ContractAddress, token_id: felt252
) -> ContractAddress;

fn approve(
fn unchecked_approve(
world: IWorldDispatcher, token: ContractAddress, token_id: felt252, to: ContractAddress
);
}
Expand All @@ -162,7 +161,7 @@ impl ERC721TokenApprovalImpl of ERC721TokenApprovalTrait {
approval.address
}

fn approve(
fn unchecked_approve(
world: IWorldDispatcher, token: ContractAddress, token_id: felt252, to: ContractAddress
) {
let mut approval = get!(world, (token, token_id), ERC721TokenApproval);
Expand Down
Loading