Skip to content

Commit

Permalink
Introduce set_base_uri; cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
kfastov committed Mar 26, 2024
1 parent f6ad3e7 commit a7a4017
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 96 deletions.
33 changes: 16 additions & 17 deletions src/extensions/slotapprovable/module.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod ERC3525SlotApprovableComponent {
use openzeppelin::introspection::src5::SRC5Component;

use openzeppelin::token::erc721::erc721::ERC721Component::InternalTrait as ERC721InternalTrait;
use openzeppelin::token::erc721::erc721::ERC721Component::ERC721; // TODO remove all unused imports
use openzeppelin::token::erc721::erc721::ERC721Component::ERC721;
use openzeppelin::token::erc721::erc721::ERC721Component;

// Local deps
Expand Down Expand Up @@ -180,24 +180,23 @@ mod ERC3525SlotApprovableComponent {

// [Effect] Transfer value to address
let mut erc3525_comp = get_dep_component_mut!(ref self, ERC3525Comp);
match to_token_id.try_into() { // TODO maybe if let
if let Option::Some(token_id) = to_token_id.try_into() {
// Into felt252 works
Option::Some(token_id) => {
match token_id {
// If token_id is zero, transfer value to address
0 => erc3525_comp._transfer_value_to(
from_token_id, to, value
),
// Otherwise, transfer value to token
_ => erc3525_comp._transfer_value_to_token(
from_token_id, to_token_id, value
),
}
},
match token_id {
// If token_id is zero, transfer value to address
0 => erc3525_comp._transfer_value_to(
from_token_id, to, value
),
// Otherwise, transfer value to token
_ => erc3525_comp._transfer_value_to_token(
from_token_id, to_token_id, value
),
}
} else {
// Into felt252 fails, so token_id is not zero
Option::None(()) => erc3525_comp._transfer_value_to_token(
erc3525_comp._transfer_value_to_token(
from_token_id, to_token_id, value
),
)
}
}
}
Expand All @@ -211,7 +210,7 @@ mod ERC3525SlotApprovableComponent {
impl SRC5: SRC5Component::HasComponent<TContractState>,
impl ERC721Comp: ERC721Component::HasComponent<TContractState>
> of InternalTrait<TContractState> {
fn initializer(ref self: ComponentState<TContractState>) { // TODO initializable
fn initializer(ref self: ComponentState<TContractState>) {
// [Effect] Register interfaces
let mut src5_comp = get_dep_component_mut!(ref self, SRC5);
src5_comp.register_interface(IERC3525_SLOT_APPROVABLE_ID);
Expand Down
3 changes: 0 additions & 3 deletions src/extensions/slotenumerable/module.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ mod ERC3525SlotEnumerableComponent {

// External deps
use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use openzeppelin::introspection::src5::SRC5Component::{SRC5, SRC5Camel};
use openzeppelin::introspection::src5::SRC5Component;

use openzeppelin::token::erc721::erc721::ERC721Component::InternalTrait as ERC721InternalTrait;
use openzeppelin::token::erc721::erc721::ERC721Component::ERC721; // TODO remove all unused imports
use openzeppelin::token::erc721::erc721::ERC721Component;

// Local deps
Expand Down
63 changes: 48 additions & 15 deletions src/module.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ mod ERC3525Component {
use openzeppelin::introspection::src5::SRC5Component;
use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait};
use openzeppelin::token::erc721::erc721::ERC721Component::InternalTrait as ERC721InternalTrait;
use openzeppelin::token::erc721::erc721::ERC721Component::ERC721; // TODO remove all unused imports
use openzeppelin::token::erc721::erc721::ERC721Component::ERC721;
use openzeppelin::token::erc721::erc721::ERC721Component;
use openzeppelin::account::interface::ISRC6_ID;

// Local deps
use cairo_erc_3525::interface::{
IERC3525_ID, IERC3525_RECEIVER_ID, IERC3525, IERC3525ReceiverDispatcher,
IERC3525_ID, IERC3525_RECEIVER_ID, IERC3525, IERC3525CamelOnly, IERC3525ReceiverDispatcher,
IERC3525ReceiverDispatcherTrait
};

Expand Down Expand Up @@ -95,7 +95,7 @@ mod ERC3525Component {
+HasComponent<TContractState>,
+Drop<TContractState>,
impl SRC5: SRC5Component::HasComponent<TContractState>,
impl ERC721Comp: ERC721Component::HasComponent<TContractState>
impl ERC721: ERC721Component::HasComponent<TContractState>
> of IERC3525<ComponentState<TContractState>> {
fn value_decimals(self: @ComponentState<TContractState>) -> u8 {
// [Compute] Value decimals
Expand Down Expand Up @@ -125,7 +125,7 @@ mod ERC3525Component {
assert(!operator.is_zero(), Errors::INVALID_OPERATOR);

// [Check] Operator is not owner and caller is approved or owner
let erc721_comp = get_dep_component!(@self, ERC721Comp);
let erc721_comp = get_dep_component!(@self, ERC721);
let owner = erc721_comp.owner_of(token_id);
assert(owner != operator, Errors::APPROVAL_TO_OWNER);
assert(
Expand All @@ -139,7 +139,7 @@ mod ERC3525Component {

fn allowance(self: @ComponentState<TContractState>, token_id: u256, operator: ContractAddress) -> u256 {
// [Check]
let erc721_comp = get_dep_component!(self, ERC721Comp);
let erc721_comp = get_dep_component!(self, ERC721);
let owner = erc721_comp.owner_of(token_id);
self._erc3525_approved_values.read((owner, token_id, operator))
}
Expand Down Expand Up @@ -182,13 +182,46 @@ mod ERC3525Component {
}
}

#[embeddable_as(ERC3525CamelOnlyImpl)]
impl ERC3525CamelOnly<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
impl SRC5: SRC5Component::HasComponent<TContractState>,
impl ERC721: ERC721Component::HasComponent<TContractState>
> of IERC3525CamelOnly<ComponentState<TContractState>> {
fn valueDecimals(self: @ComponentState<TContractState>) -> u8 {
ERC3525::value_decimals(self)
}
fn valueOf(self: @ComponentState<TContractState>, tokenId: u256) -> u256 {
ERC3525::value_of(self, tokenId)
}
fn slotOf(self: @ComponentState<TContractState>, tokenId: u256) -> u256 {
ERC3525::slot_of(self, tokenId)
}
fn approveValue(
ref self: ComponentState<TContractState>, tokenId: u256, operator: ContractAddress, value: u256
) {
ERC3525::approve_value(ref self, tokenId, operator, value)
}
fn transferValueFrom(
ref self: ComponentState<TContractState>,
fromTokenId: u256,
toTokenId: u256,
to: ContractAddress,
value: u256
) -> u256 {
ERC3525::transfer_value_from(ref self, fromTokenId, toTokenId, to, value)
}
}

#[generate_trait]
impl InternalImpl<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
impl SRC5: SRC5Component::HasComponent<TContractState>,
impl ERC721Comp: ERC721Component::HasComponent<TContractState>
impl ERC721: ERC721Component::HasComponent<TContractState>
> of InternalTrait<TContractState> {
fn initializer(ref self: ComponentState<TContractState>, value_decimals: u8) {
// [Effect] Store value decimals
Expand All @@ -211,7 +244,7 @@ mod ERC3525Component {
ref self: ComponentState<TContractState>, token_id: u256, operator: ContractAddress, value: u256
) {
// [Effect] Store approved value
let erc721_comp = get_dep_component!(@self, ERC721Comp);
let erc721_comp = get_dep_component!(@self, ERC721);
let owner = erc721_comp.owner_of(token_id);
self._erc3525_approved_values.write((owner, token_id, operator), value);

Expand Down Expand Up @@ -242,7 +275,7 @@ mod ERC3525Component {
ref self: ComponentState<TContractState>, spender: ContractAddress, token_id: u256, value: u256
) {
// [Compute] Spender allowance
let erc721_comp = get_dep_component!(@self, ERC721Comp);
let erc721_comp = get_dep_component!(@self, ERC721);
let owner = erc721_comp.owner_of(token_id);
let current_allowance = self._erc3525_approved_values.read((owner, token_id, spender));
let infinity: u256 = BoundedInt::max();
Expand Down Expand Up @@ -286,7 +319,7 @@ mod ERC3525Component {

fn _mint_token(ref self: ComponentState<TContractState>, to: ContractAddress, token_id: u256, slot: u256) {
// [Effect] Mint a new enumerable token if supported, standard token otherwise
let mut erc721_comp = get_dep_component_mut!(ref self, ERC721Comp);
let mut erc721_comp = get_dep_component_mut!(ref self, ERC721);
erc721_comp._mint(to, token_id);

// [Effect] Store slot
Expand Down Expand Up @@ -356,7 +389,7 @@ mod ERC3525Component {
self._assert_minted(token_id);

// [Effect] Burn token
let mut erc721_comp = get_dep_component_mut!(ref self, ERC721Comp);
let mut erc721_comp = get_dep_component_mut!(ref self, ERC721);
erc721_comp._burn(token_id);

// [Effect] Update token and total value
Expand Down Expand Up @@ -439,7 +472,7 @@ mod ERC3525Component {

// [Effect] Update token and total value
let slot = self._erc3525_slots.read(token_id);
let erc721_comp = get_dep_component!(@self, ERC721Comp);
let erc721_comp = get_dep_component!(@self, ERC721);
let owner = erc721_comp.owner_of(token_id);
self._erc3525_values.write(token_id, balance - total_amount);

Expand All @@ -463,7 +496,7 @@ mod ERC3525Component {
assert(token_ids.len() > 1, Errors::INVALID_TOKEN_IDS);

// [Effect] Merge token values
let erc721_comp = get_dep_component!(@self, ERC721Comp);
let erc721_comp = get_dep_component!(@self, ERC721);
let mut index = 0;
loop {
if index + 1 >= token_ids.len() {
Expand Down Expand Up @@ -500,16 +533,16 @@ mod ERC3525Component {
+HasComponent<TContractState>,
+Drop<TContractState>,
impl SRC5: SRC5Component::HasComponent<TContractState>,
impl ERC721Comp: ERC721Component::HasComponent<TContractState> // TODO
impl ERC721: ERC721Component::HasComponent<TContractState>
> of AssertTrait<TContractState> {
fn _assert_minted(self: @ComponentState<TContractState>, token_id: u256) {
let erc721_comp = get_dep_component!(self, ERC721Comp);
let erc721_comp = get_dep_component!(self, ERC721);
let exists = erc721_comp._exists(token_id);
assert(exists, Errors::TOKEN_NOT_MINTED);
}

fn _assert_not_minted(self: @ComponentState<TContractState>, token_id: u256) {
let erc721_comp = get_dep_component!(self, ERC721Comp);
let erc721_comp = get_dep_component!(self, ERC721);
let exists = erc721_comp._exists(token_id);
assert(!exists, Errors::TOKEN_ALREADY_MINTED);
}
Expand Down
13 changes: 2 additions & 11 deletions src/presets/erc3525_mintable_burnable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,23 @@ mod ERC3525MintableBurnable {

// ERC721
use openzeppelin::token::erc721::erc721::ERC721Component;
use openzeppelin::token::erc721::interface::{
IERC721, IERC721CamelOnly, IERC721Metadata, IERC721MetadataCamelOnly
};

// ERC3525
use cairo_erc_3525::module::ERC3525Component;
use cairo_erc_3525::interface::{IERC3525, IERC3525CamelOnly};

// Declare components
component!(path: SRC5Component, storage: src5, event: SRC5Event);
component!(path: ERC721Component, storage: erc721, event: ERC721Event);
component!(path: ERC3525Component, storage: erc3525, event: ERC3525Event);

// Component implementations
// TODO embed missing ABIs
#[abi(embed_v0)]
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;
#[abi(embed_v0)]
impl ERC3525Impl = ERC3525Component::ERC3525Impl<ContractState>;
#[abi(embed_v0)]
impl ERC3525CamelOnlyImpl = ERC3525Component::ERC3525CamelOnlyImpl<ContractState>;
impl ERC3525InternalImpl = ERC3525Component::InternalImpl<ContractState>;

#[storage]
Expand Down Expand Up @@ -68,12 +65,6 @@ mod ERC3525MintableBurnable {
self.initializer(value_decimals);
}

// TODO check support for the following impls:
// impl SRC5Impl of ISRC5<ContractState> {
// impl SRC5CamelImpl of ISRC5Camel<ContractState> {
// impl ERC721Impl of IERC721<ContractState> {
// impl ERC3525Impl of IERC3525<ContractState> {

#[abi(embed_v0)]
impl ExternalImpl of super::IExternal<ContractState> {
fn total_value(self: @ContractState, slot: u256) -> u256 {
Expand Down
35 changes: 11 additions & 24 deletions src/presets/erc3525_mintable_burnable_metadata.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ trait IExternal<TContractState> {
fn mint_value(ref self: TContractState, token_id: u256, value: u256);
fn burn(ref self: TContractState, token_id: u256);
fn burn_value(ref self: TContractState, token_id: u256, value: u256);
fn set_token_uri(ref self: TContractState, token_id: u256, token_uri: felt252);
fn set_base_uri(ref self: TContractState, base_uri: ByteArray);
fn set_contract_uri(ref self: TContractState, uri: felt252);
fn set_slot_uri(ref self: TContractState, slot: u256, uri: felt252);
}
Expand Down Expand Up @@ -44,15 +44,18 @@ mod ERC3525MintableBurnableMetadata {
component!(path: ERC3525MetadataComponent, storage: erc3525_metadata, event: ERC3525MetadataEvent);

// Component implementations
// TODO embed missing ABIs
#[abi(embed_v0)]
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;
#[abi(embed_v0)]
impl ERC3525Impl = ERC3525Component::ERC3525Impl<ContractState>;
#[abi(embed_v0)]
impl ERC3525CamelOnlyImpl = ERC3525Component::ERC3525CamelOnlyImpl<ContractState>;
impl ERC3525InternalImpl = ERC3525Component::InternalImpl<ContractState>;
#[abi(embed_v0)]
impl ERC3525MetadataImpl = ERC3525MetadataComponent::ERC3525MetadataImpl<ContractState>;
#[abi(embed_v0)]
impl ERC3525MetadataCamelOnlyImpl = ERC3525MetadataComponent::ERC3525MetadataCamelOnlyImpl<ContractState>;
impl ERC3525MetadataInternalImpl = ERC3525MetadataComponent::InternalImpl<ContractState>;

#[storage]
Expand Down Expand Up @@ -81,25 +84,10 @@ mod ERC3525MintableBurnableMetadata {
}

#[constructor]
fn constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, value_decimals: u8) {
self.initializer(name, symbol, value_decimals);
fn constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, base_uri: ByteArray, value_decimals: u8) {
self.initializer(name, symbol, base_uri, value_decimals);
}

// TODO check support of these implementations
// ERC721Mixin:
// impl SRC5Impl of ISRC5<ContractState> {
// impl SRC5CamelImpl of ISRC5Camel<ContractState> {
// impl ERC721Impl of IERC721<ContractState> {
// impl ERC721CamelOnlyImpl of IERC721CamelOnly<ContractState> {
// impl ERC721MetadataImpl of IERC721Metadata<ContractState> {
// impl ERC721MetadataCamelOnlyImpl of IERC721MetadataCamelOnly<ContractState> {
// ERC3525:
// impl ERC3525Impl of IERC3525<ContractState> {
// impl ERC3525CamelOnlyImpl of IERC3525CamelOnly<ContractState> {
// ERC3525Metadata:
// impl ERC3525MetadataImpl of IERC3525Metadata<ContractState> {
// impl ERC3525MetadataCamelOnlyImpl of IERC3525MetadataCamelOnly<ContractState> {

#[abi(embed_v0)]
impl ExternalImpl of super::IExternal<ContractState> {
fn total_value(self: @ContractState, slot: u256) -> u256 {
Expand Down Expand Up @@ -130,9 +118,8 @@ mod ERC3525MintableBurnableMetadata {
self.erc3525._burn_value(token_id, value)
}

fn set_token_uri(ref self: ContractState, token_id: u256, token_uri: felt252) {
// TODO
// self.erc721._set_token_uri(token_id, token_uri)
fn set_base_uri(ref self: ContractState, base_uri: ByteArray) {
self.erc721._set_base_uri(base_uri)
}

fn set_contract_uri(ref self: ContractState, uri: felt252) {
Expand All @@ -147,9 +134,9 @@ mod ERC3525MintableBurnableMetadata {
#[generate_trait]
impl InternalImpl of InternalTrait {
fn initializer(
ref self: ContractState, name: ByteArray, symbol: ByteArray, value_decimals: u8
ref self: ContractState, name: ByteArray, symbol: ByteArray, base_uri: ByteArray, value_decimals: u8
) {
self.erc721.initializer(name, symbol, "");
self.erc721.initializer(name, symbol, base_uri);
self.erc3525.initializer(value_decimals);
self.erc3525_metadata.initializer();
}
Expand Down
Loading

0 comments on commit a7a4017

Please sign in to comment.