From f78cc8b8a9cd1d50505959102a395e7d49d3e9e7 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Fri, 10 Jan 2025 14:16:01 +0100 Subject: [PATCH] feat: update customizing decimals guide --- docs/modules/ROOT/pages/erc20.adoc | 56 +++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/docs/modules/ROOT/pages/erc20.adoc b/docs/modules/ROOT/pages/erc20.adoc index 3a4ac4e2c..5cf2deae4 100644 --- a/docs/modules/ROOT/pages/erc20.adoc +++ b/docs/modules/ROOT/pages/erc20.adoc @@ -125,6 +125,8 @@ Some notable differences, however, can still be found, such as: == Customizing decimals +:SRC-107: https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-107.md[SRC-107] + :floating-point: https://en.wikipedia.org//wiki/Floating-point_arithmetic[floating-point numbers] :eip-discussion: https://github.com/ethereum/EIPs/issues/724[EIP discussion] @@ -136,28 +138,56 @@ In the actual contract, however, the supply would still be the integer `1234`. In other words, *the decimals field in no way changes the actual arithmetic* because all operations are still performed on integers. Most contracts use `18` decimals and this was even proposed to be compulsory (see the {eip-discussion}). -The Contracts for Cairo `ERC20` component includes a `decimals` function that returns `18` by default to save on gas fees. -For those who want an ERC20 token with a configurable number of decimals, the following guide shows two ways to achieve this. - -NOTE: Both approaches require creating a custom implementation of the `IERC20Metadata` interface. -=== The static approach +=== The static approach (SRC-107) -The simplest way to customize `decimals` consists of returning the target value from the `decimals` method. -For example: +The Contracts for Cairo `ERC20` component leverages {SRC-107} to allow for a static and configurable number of decimals. +To use the default `18` decimals, you can use the `DefaultConfig` implementation by just importing it: [,cairo] ---- -#[abi(embed_v0)] -impl ERC20MetadataImpl of interface::IERC20Metadata { - fn decimals(self: @ContractState) -> u8 { - // Change the `3` below to the desired number of decimals - 3 - } +#[starknet::contract] +mod MyToken { + // Importing the DefaultConfig implementation would make decimals 18 by default. + use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl, DefaultConfig}; + use starknet::ContractAddress; + + component!(path: ERC20Component, storage: erc20, event: ERC20Event); + + #[abi(embed_v0)] + impl ERC20Impl = ERC20Component::ERC20Impl; + #[abi(embed_v0)] + impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl; + impl ERC20InternalImpl = ERC20Component::InternalImpl; (...) } +---- +To customize this value, you can implement the ImmutableConfig trait locally in the contract. +The following example shows how to set the decimals to `6`: + +[,cairo] +---- +mod MyToken { + use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl}; + use starknet::ContractAddress; + + component!(path: ERC20Component, storage: erc20, event: ERC20Event); + + #[abi(embed_v0)] + impl ERC20Impl = ERC20Component::ERC20Impl; + #[abi(embed_v0)] + impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl; + impl ERC20InternalImpl = ERC20Component::InternalImpl; + + (...) + + // Custom implementation of the ERC20Component ImmutableConfig. + impl ERC20ImmutableConfig of ERC20Component::ImmutableConfig { + const DECIMALS: u8 = 6; + } +} ---- === The storage approach