Skip to content

Commit

Permalink
erc20_metadata component
Browse files Browse the repository at this point in the history
  • Loading branch information
notV4l committed Dec 5, 2023
1 parent c6a7608 commit 4b75394
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 57 deletions.
4 changes: 2 additions & 2 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ source = "git+https://github.com/influenceth/cubit?rev=b459053#b4590530d5aeae9aa

[[package]]
name = "dojo"
version = "0.3.14"
source = "git+https://github.com/dojoengine/dojo?tag=v0.3.14#d7e9788459f3b2e797b6565f1057c96a6f5f8cc2"
version = "0.3.15"
source = "git+https://github.com/dojoengine/dojo?tag=v0.3.15#cdbaca4121b1642e1a8ca40d6831bad73d28ed26"
dependencies = [
"dojo_plugin",
]
Expand Down
2 changes: 1 addition & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ authors = ["[email protected]"]

[workspace.dependencies]
cubit = { git = "https://github.com/influenceth/cubit", rev = "b459053" }
dojo = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.14" }
dojo = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.15" }
origami = { path = "crates" }
44 changes: 30 additions & 14 deletions token/src/components/token/erc20_metadata.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct ERC20MetadataModel {
name: felt252,
symbol: felt252,
decimals: u8,
total_supply: u256,
}

///
Expand Down Expand Up @@ -40,38 +41,53 @@ mod ERC20MetadataComponent {
#[storage]
struct Storage {}

mod Errors {
// const INITIALIZED: felt252 = 'Initializable: is initialized';
}

#[embeddable_as(ERC20MetadataImpl)]
impl ERC20Metadata<
TContractState, +HasComponent<TContractState>, +IWorldProvider<TContractState>
> of IERC20Metadata<ComponentState<TContractState>> {
fn name(self: @ComponentState<TContractState>) -> felt252{
self.get_metadata().name
fn name(self: @ComponentState<TContractState>) -> felt252 {
self.get_metadata().name
}
fn symbol(self: @ComponentState<TContractState>) -> felt252{
self.get_metadata().symbol
fn symbol(self: @ComponentState<TContractState>) -> felt252 {
self.get_metadata().symbol
}
fn decimals(self: @ComponentState<TContractState>) -> u8{
self.get_metadata().decimals
fn decimals(self: @ComponentState<TContractState>) -> u8 {
self.get_metadata().decimals
}
}

#[generate_trait]
impl ERC20MetadataInternalImpl<
impl InternalImpl<
TContractState, +HasComponent<TContractState>, +IWorldProvider<TContractState>
> of InternalTrait<TContractState> {
fn initialize(ref self: ComponentState<TContractState>, name:felt252, symbol: felt252, decimals: u8) {
fn initialize(
ref self: ComponentState<TContractState>, name: felt252, symbol: felt252, decimals: u8
) {
set!(
self.get_contract().world(),
ERC20MetadataModel { token: get_contract_address(), name, symbol, decimals }
ERC20MetadataModel {
token: get_contract_address(), name, symbol, decimals, total_supply: 0
}
)
}

fn get_metadata(self: @ComponentState<TContractState>) -> ERC20MetadataModel {
get!(self.get_contract().world(), get_contract_address(),(ERC20MetadataModel))
get!(self.get_contract().world(), get_contract_address(), (ERC20MetadataModel))
}

fn total_supply(self: @ComponentState<TContractState>) -> u256 {
self.get_metadata().total_supply
}

// Helper function to update total_supply model
fn update_total_supply(
ref self: ComponentState<TContractState>, subtract: u256, add: u256
) {
let mut meta = self.get_metadata();
// // adding and subtracting is fewer steps than if
meta.total_supply = meta.total_supply - subtract;
meta.total_supply = meta.total_supply + add;
set!(self.get_contract().world(), (meta));
}
}
}
80 changes: 40 additions & 40 deletions token/src/preset/erc20.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ mod ERC20 {
use zeroable::Zeroable;

use token::components::token::erc20_metadata::ERC20MetadataComponent;
use token::components::security::initializable::InitializableComponent;

component!(path: InitializableComponent, storage: initializable, event: InitializableEvent);
component!(path: ERC20MetadataComponent, storage: erc20_metadata, event: ERC20MetadataEvent);

#[storage]
struct Storage {
#[substorage(v0)]
erc20_metadata: ERC20MetadataComponent::Storage
initializable: InitializableComponent::Storage,
#[substorage(v0)]
erc20_metadata: ERC20MetadataComponent::Storage,
}

#[event]
Expand All @@ -23,7 +27,9 @@ mod ERC20 {
Transfer: Transfer,
Approval: Approval,
#[flat]
ERC20MetadataEvent: ERC20MetadataComponent::Event
InitializableEvent: InitializableComponent::Event,
#[flat]
ERC20MetadataEvent: ERC20MetadataComponent::Event,
}

#[derive(Copy, Drop, starknet::Event)]
Expand All @@ -41,6 +47,9 @@ mod ERC20 {
}

mod Errors {
const ALREADY_INITIALIZED: felt252 = 'ERC20: already initialized';
const CALLER_IS_NOT_OWNER: felt252 = 'ERC20: caller is not owner';

const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0';
const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0';
const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0';
Expand All @@ -49,32 +58,39 @@ mod ERC20 {
const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0';
}

#[constructor]
fn constructor(
#[abi(embed_v0)]
impl InitializableImpl =
InitializableComponent::InitializableImpl<ContractState>;

#[abi(embed_v0)]
impl ERC20MetadataImpl =
ERC20MetadataComponent::ERC20MetadataImpl<ContractState>;


#[external(v0)]
fn initializer(
ref self: ContractState,
name: felt252,
symbol: felt252,
initial_supply: u256,
recipient: ContractAddress
recipient: ContractAddress,
initial_supply: u256
) {
self.initializer(name, symbol);
self._mint(recipient, initial_supply);
}

//
// External
//
assert(!self.initializable.is_initialized(), Errors::ALREADY_INITIALIZED);
assert(
self.world().is_owner(get_caller_address(), get_contract_address().into()),
Errors::CALLER_IS_NOT_OWNER
);

self.erc20_metadata.initialize(name, symbol, 18);
self._mint(recipient, initial_supply);

#[abi(embed_v0)]
impl ERC20MetadataImpl =
ERC20MetadataComponent::ERC20MetadataImpl<ContractState>;
self.initializable.initialize();
}

#[external(v0)]
impl ERC20Impl of interface::IERC20<ContractState> {
fn total_supply(self: @ContractState) -> u256 {
//self.get_meta().total_supply
0.into()
self.erc20_metadata.get_metadata().total_supply
}

fn balance_of(self: @ContractState, account: ContractAddress) -> u256 {
Expand Down Expand Up @@ -118,8 +134,7 @@ mod ERC20 {
#[external(v0)]
impl ERC20CamelOnlyImpl of interface::IERC20CamelOnly<ContractState> {
fn totalSupply(self: @ContractState) -> u256 {
// ERC20Impl::total_supply(self)
0.into()
ERC20Impl::total_supply(self)
}

fn balanceOf(self: @ContractState, account: ContractAddress) -> u256 {
Expand Down Expand Up @@ -170,21 +185,11 @@ mod ERC20 {
// Internal
//

impl InitializableInternalImpl = InitializableComponent::InternalImpl<ContractState>;
impl ERC20MetadataInternalImpl = ERC20MetadataComponent::InternalImpl<ContractState>;

#[generate_trait]
impl WorldInteractionsImpl of WorldInteractionsTrait {
fn get_meta(self: @ContractState) -> ERC20Meta {
get!(self.world(), get_contract_address(), ERC20Meta)
}

// Helper function to update total_supply model
fn update_total_supply(ref self: ContractState, subtract: u256, add: u256) {
let mut meta = self.get_meta();
// adding and subtracting is fewer steps than if
meta.total_supply = meta.total_supply - subtract;
meta.total_supply = meta.total_supply + add;
set!(self.world(), (meta));
}

// Helper function for balance model
fn get_balance(self: @ContractState, account: ContractAddress) -> ERC20Balance {
get!(self.world(), (get_contract_address(), account), ERC20Balance)
Expand Down Expand Up @@ -245,21 +250,16 @@ mod ERC20 {

#[generate_trait]
impl InternalImpl of InternalTrait {
fn initializer(ref self: ContractState, name: felt252, symbol: felt252) {
let meta = ERC20Meta { token: get_contract_address(), name, symbol, total_supply: 0 };
set!(self.world(), (meta));
}

fn _mint(ref self: ContractState, recipient: ContractAddress, amount: u256) {
assert(!recipient.is_zero(), Errors::MINT_TO_ZERO);
self.update_total_supply(0, amount);
self.erc20_metadata.update_total_supply(0, amount);
self.update_balance(recipient, 0, amount);
self.emit_event(Transfer { from: Zeroable::zero(), to: recipient, value: amount });
}

fn _burn(ref self: ContractState, account: ContractAddress, amount: u256) {
assert(!account.is_zero(), Errors::BURN_FROM_ZERO);
self.update_total_supply(amount, 0);
self.erc20_metadata.update_total_supply(amount, 0);
self.update_balance(account, amount, 0);
self.emit_event(Transfer { from: account, to: Zeroable::zero(), value: amount });
}
Expand Down

0 comments on commit 4b75394

Please sign in to comment.