diff --git a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-custom-erc20s.mdx b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-custom-erc20s.mdx index 9a8ac99f..3fe17221 100644 --- a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-custom-erc20s.mdx +++ b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-custom-erc20s.mdx @@ -1,8 +1,10 @@ --- -title: Creating Custom ERC20s +title: Custom ERC20s --- -[Tutorial GitHub Repository](https://github.com/initia-labs/examples/tree/main/evm/initia-custom-erc20) +To create custom ERC20s, you can inherit and extend the +[InitiaERC20](/resources/developer/contract-references/evm/initia-erc20) +contract. ## Prerequisites @@ -22,7 +24,7 @@ mkdir initia-erc20 cd initia-erc20 ``` -Next, we will initialize a new Foundry project side that directory. +Next, we will initialize a new Foundry project inside that directory. ```sh forge init @@ -46,26 +48,27 @@ mv src/Counter.sol src/NewInitiaERC20.sol ``` We then update the contract from the template to be our custom ERC20 contract. -Start by importing the `InitiaCustomERC20` contract from the -`@initia/initia-evm-contracts` package. +Start by importing the `InitiaERC20` contract from the +[initia-evm-contracts](https://github.com/initia-labs/initia-evm-contracts) +package. ```solidity src/NewInitiaERC20.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; -import "initia-evm-contracts/src/InitiaCustomERC20.sol"; +import "initia-evm-contracts/src/InitiaERC20.sol"; ``` -Next, we need to extend the `InitiaCustomERC20` contract and add the constructor -to initialize the contract with the name, symbol, and decimals of our custom -ERC20. For this tutorial, we will simply customize the base contract by adding a -logic to mint tokens to the contract deployer. during deployment. +Next, we need to extend the `InitiaERC20` contract and add the constructor to +initialize the contract with the name, symbol, and decimals of our custom ERC20. +For this tutorial, we will simply customize the base contract by adding a logic +to mint tokens to the contract deployer during deployment. ```solidity src/NewInitiaERC20.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; -import "initia-evm-contracts/src/InitiaCustomERC20.sol"; +import "initia-evm-contracts/src/InitiaERC20.sol"; /** * @title NewInitiaERC20 @@ -98,7 +101,7 @@ mv test/Counter.t.sol test/NewInitiaERC20.t.sol mv script/Counter.s.sol script/NewInitiaERC20.s.sol ``` -We will now replace the contents of the `NewInitiaERC20.t.sol` file with +We will now replace the contents of the `NewInitiaERC20.t.sol` file with the following placeholder content. ```solidity test/NewInitiaERC20.t.sol @@ -113,7 +116,7 @@ contract NewInitiaERC20Test is Test { } ``` -And replace the contents of the `NewInitiaERC20.s.sol` file with following +And replace the contents of the `NewInitiaERC20.s.sol` file with the following placeholder content. ```solidity script/NewInitiaERC20.s.sol @@ -156,7 +159,7 @@ Compiler run successful! ## Deploying the Contract Now that our contract is compiled and ready, we can deploy it to the MiniEVM. To -accomplish this, we will use Foundry's `forge create` command +accomplish this, we will use Foundry's `forge create` command. **Security Note:** In this tutorial we export a private key directly in the diff --git a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-standard-erc20s.mdx b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-standard-erc20s.mdx index aa73ec6b..f09c5447 100644 --- a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-standard-erc20s.mdx +++ b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-standard-erc20s.mdx @@ -1,13 +1,11 @@ --- -title: Creating Standard ERC20s via ERC20Factory +title: Using ERC20Factory --- -[Tutorial GitHub Repository](https://github.com/initia-labs/examples/tree/main/evm/erc20-factory) - -For developers looking to create standard ERC20 tokens on EVM rollups, we -recommend using the -[ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) -contract. +To create standard ERC20s, you can use the +[ERC20Factory](/resources/developer/contract-references/evm/erc20-factory)'s +`createErc20` function. Tokens created via this method are fully compatible with +the chain and Initia's core products by default. ## Project Setup @@ -57,15 +55,15 @@ touch .env This file will store your private environment variables, such as your wallet's private key and the deployed ERC20Factory contract address. These values are -required for signing transactions and interacting with the MiniEVM. +required for signing transactions and interacting with the chain's EVM module. -The `ERC20Factory` contract is automatically deployed on all MiniEVM rollups as +The `ERC20Factory` contract is automatically deployed on all EVM appchains as part of the chain’s bootstrapping process. To retrieve the deployed factory address, query -`{ROLLUP_REST_URL}/minievm/evm/v1/contracts/erc20_factory`. +`{APPCHAIN_REST_URL}/evm/v1/contracts/erc20_factory`. -`{ROLLUP_REST_URL}` refers to the REST endpoint of the rollup you are +`{APPCHAIN_REST_URL}` refers to the REST endpoint of the chain you are interacting with. Example: @@ -166,7 +164,7 @@ Load the environment variables: You can also find factory addresses on the [Networks](/resources/developer/initia-l1) page or by calling the - `/minievm/evm/v1/contracts/erc20_factory` endpoint on any MiniEVM rollup. + `/minievm/evm/v1/contracts/erc20_factory` endpoint on any EVM appchain. ```js diff --git a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/initiaerc20.mdx b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/initiaerc20.mdx new file mode 100644 index 00000000..6be51742 --- /dev/null +++ b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/initiaerc20.mdx @@ -0,0 +1,33 @@ +--- +title: InitiaERC20 +--- + +InitiaERC20 is Initia's native token standard for EVM appchains. It extends the +ERC20 standard with additional modifiers and functions required for full +compatibility with the Cosmos SDK and Initia's core products. See the +[InitiaERC20 contract reference](/resources/developer/contract-references/evm/initia-erc20) +for implementation details. + + + **Do not deploy or use normal ERC20 contracts** on Initia EVM appchains. + Tokens that do not follow the InitiaERC20 standard will not display correctly + in Initia's products and will have limited transfer and bridging + functionalities. + + +Developers looking to create and deploy ERC20s on EVM appchains have two +options: + +1. For creating standard ERC20 tokens, use the + [ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) + contract (which deploys the + [ERC20](/resources/developer/contract-references/evm/erc20) contract). +2. For creating ERC20 tokens with custom functionality, inherit and extend the + [InitiaERC20](/resources/developer/contract-references/evm/initia-erc20) + contract. + + + For Initia's products to correctly display your token's symbol, logo, and + other details, it must still be added to the [Initia + Registry](/developers/developer-guides/integrating-initia-apps/registry/introduction). + diff --git a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/introduction.mdx b/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/introduction.mdx deleted file mode 100644 index c7d8d177..00000000 --- a/developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/introduction.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Introduction ---- - -To ensure compatibility with Initia's EVM module and the Cosmos SDK in general, -ERC20 tokens on rollups includes certain extensions beyond the standard ERC20 -template. - -Developers looking to create and deploy ERC20s on EVM rollups have two options: - -1. Deploy Initia ERC20s using the - [ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) - contract. -2. Extend and modify Initia's - [InitiaCustomERC20](/resources/developer/contract-references/evm/initia-custom-erc20) - contract. - - - While Initia's `CustomERC20.sol` contains additional logic, it is still fully - compatible with the ERC20 standard. - diff --git a/developers/developer-guides/vm-specific-tutorials/evm/update-fee-token.mdx b/developers/developer-guides/vm-specific-tutorials/evm/update-fee-token.mdx index a17fdc93..8f60657f 100644 --- a/developers/developer-guides/vm-specific-tutorials/evm/update-fee-token.mdx +++ b/developers/developer-guides/vm-specific-tutorials/evm/update-fee-token.mdx @@ -1,5 +1,5 @@ --- -title: Update Fee with ERC20 Token +title: Updating the Fee Token --- ## Prerequisites @@ -17,7 +17,8 @@ Fee Token as an ERC20 token. Use validator (admin) account to update the chain parameter. - The deployed ERC20 token must inherit the `InitiaERC20` contract. + The deployed ERC20 token must follow the InitiaERC20 standard—i.e. use the + `ERC20` contract (factory-created) or inherit from `InitiaERC20` (custom). ```ts diff --git a/docs.json b/docs.json index d2770fac..5bf10a6d 100644 --- a/docs.json +++ b/docs.json @@ -224,8 +224,8 @@ "developers/developer-guides/vm-specific-tutorials/evm/cosmos-coin-to-erc20", { "group": "Creating ERC20s", - "icon": "file-code", "pages": [ + "developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/initiaerc20", "developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-standard-erc20s", "developers/developer-guides/vm-specific-tutorials/evm/creating-erc20s/creating-custom-erc20s" ] @@ -522,9 +522,9 @@ "resources/developer/contract-references/evm/cosmos", "resources/developer/contract-references/evm/erc20-acl", "resources/developer/contract-references/evm/erc20-registry", + "resources/developer/contract-references/evm/erc20", "resources/developer/contract-references/evm/initia-erc20", - "resources/developer/contract-references/evm/erc20-factory", - "resources/developer/contract-references/evm/initia-custom-erc20" + "resources/developer/contract-references/evm/erc20-factory" ] } ] diff --git a/resources/developer/contract-references/evm/erc20-factory.mdx b/resources/developer/contract-references/evm/erc20-factory.mdx index 81502a0f..ed28ffc0 100644 --- a/resources/developer/contract-references/evm/erc20-factory.mdx +++ b/resources/developer/contract-references/evm/erc20-factory.mdx @@ -7,13 +7,13 @@ GitHub: ## Overview -The `ERC20Factory` contract is designed to create new InitiaERC20 tokens and -register them with the MiniEVM's ERC20Registry. +The `ERC20Factory` contract is designed to create new ERC20 tokens and register +them with the MiniEVM's ERC20Registry. ## Imports -- [InitiaERC20.sol](/resources/developer/contract-references/evm/initia-erc20): - Contains the implementation of the ERC20 token. +- [ERC20.sol](/resources/developer/contract-references/evm/erc20): Contains the + implementation of the factory-created ERC20 token. - [ERC20Registry.sol](/resources/developer/contract-references/evm/erc20-registry): Contains the implementation of the ERC20 registry. diff --git a/resources/developer/contract-references/evm/erc20.mdx b/resources/developer/contract-references/evm/erc20.mdx new file mode 100644 index 00000000..bdc29655 --- /dev/null +++ b/resources/developer/contract-references/evm/erc20.mdx @@ -0,0 +1,38 @@ +--- +title: ERC20 +--- + +GitHub: +[ERC20](https://github.com/initia-labs/initia-evm-contracts/blob/main/src/ERC20.sol) + +## Overview + +The `ERC20` contract is used by the +[ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) to +create standard tokens. It does not self-register in the constructor—the factory +calls `register_erc20_from_factory` after deployment. + +For custom ERC20 tokens with additional logic, use +[InitiaERC20](/resources/developer/contract-references/evm/initia-erc20) +instead. + +## Key Features + +- **metadataSealed**: Prevents metadata changes after sealing. Set via + `updateMetadata` by authority. +- **updateMetadata**: One-time metadata update by authority (gov). +- **sudoMint / sudoBurn**: Chain signer operations for bridging and module + interactions. + +## Constructor + +```solidity +constructor(string memory _name, string memory _symbol, uint8 _decimals, bool _metadataSealed) +``` + +| Name | Type | Description | +| ----------------- | --------------- | ------------------------------------------------- | +| `_name` | `string memory` | The name of the token. | +| `_symbol` | `string memory` | The symbol of the token. | +| `_decimals` | `uint8` | The number of decimals. | +| `_metadataSealed` | `bool` | If true, metadata cannot be updated by authority. | diff --git a/resources/developer/contract-references/evm/initia-custom-erc20.mdx b/resources/developer/contract-references/evm/initia-custom-erc20.mdx deleted file mode 100644 index 3b2994c7..00000000 --- a/resources/developer/contract-references/evm/initia-custom-erc20.mdx +++ /dev/null @@ -1,242 +0,0 @@ ---- -title: InitiaCustomERC20 ---- - -GitHub: -[InitiaCustomERC20](https://github.com/initia-labs/initia-evm-contracts/blob/main/src/InitiaCustomERC20.sol) - -## Overview - -The `InitiaCustomERC20` contract is a custom implementation of the ERC20 token -standard. It includes additional access control mechanisms and registry -functionalities to allow for better integration with the rollup's underlying -Cosmos SDK stack. - -This is the main ERC20 token contract that developers should use to create their -own custom ERC20 tokens on the MiniEVM. - -## Inheritance - -- `IERC20`: Interface for ERC20 standard functions. -- `Ownable`: Provides ownership control. -- `ERC20Registry`: Handles ERC20 registry functionalities. -- `ERC165`: Supports interface identification. -- `ERC20ACL`: Provides access control mechanisms. - -## State Variables - -- `mapping(address => uint256) public balanceOf`: Tracks the balance of each - address. -- `mapping(address => mapping(address => uint256)) public allowance`: Tracks the - allowance each address has given to another address. -- `string public name`: The name of the token. -- `string public symbol`: The symbol of the token. -- `uint8 public decimals`: The number of decimals the token uses. -- `uint256 public totalSupply`: The total supply of the token. - -## Constructor - -Initializes the contract with the token's name, symbol, and decimals. It also -registers the ERC20 token with the ERC20Registry. - -```solidity -constructor(string memory _name, string memory _symbol, uint8 _decimals) register_erc20 { - name = _name; - symbol = _symbol; - decimals = _decimals; -} -``` - -#### Parameters - -| Name | Type | Description | -| ----------- | --------------- | -------------------------------------- | -| `_name` | `string memory` | The name of the token. | -| `_symbol` | `string memory` | The symbol of the token. | -| `_decimals` | `uint8` | The number of decimals the token uses. | - -## Functions - -### `supportsInterface` - -Checks if the contract supports a given interface. - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) -``` - -#### Parameters - -| Name | Type | Description | -| ------------- | -------- | ------------------------- | -| `interfaceId` | `bytes4` | The interface identifier. | - -#### Returns - -| Type | Description | -| ------ | -------------------------------------------------------- | -| `bool` | `true` if the interface is supported, `false` otherwise. | - -### `_transfer` - -Transfers tokens from one address to another and registers the recipient's ERC20 -store if necessary. - -```solidity -function _transfer(address sender, address recipient, uint256 amount) internal register_erc20_store(recipient) -``` - -#### Parameters - -| Name | Type | Description | -| ----------- | --------- | --------------------------------- | -| `sender` | `address` | The address sending the tokens. | -| `recipient` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | - -### `_mint` - -Mints new tokens and assigns them to an address, registering the recipient's -ERC20 store if necessary. - -```solidity -function _mint(address to, uint256 amount) internal register_erc20_store(to) -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | --------------------------------- | -| `to` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to mint. | - -### `_burn` - -Burns tokens from an address. - -```solidity -function _burn(address from, uint256 amount) internal -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | ---------------------------------------- | -| `from` | `address` | The address whose tokens will be burned. | -| `amount` | `uint256` | The amount of tokens to burn. | - -### `transfer` - -Transfers tokens to a recipient, ensuring the recipient is not a blocked -address. - -```solidity -function transfer(address recipient, uint256 amount) external transferable(recipient) returns (bool) -``` - -#### Parameters - -| Name | Type | Description | -| ----------- | --------- | --------------------------------- | -| `recipient` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | - -#### Returns - -| Type | Description | -| ------ | -------------------------------------- | -| `bool` | `true` if the transfer was successful. | - -### `approve` - -Approves an address to spend a specified amount of tokens on behalf of the -caller. - -```solidity -function approve(address spender, uint256 amount) external returns (bool) -``` - -#### Parameters - -| Name | Type | Description | -| --------- | --------- | ---------------------------------------- | -| `spender` | `address` | The address allowed to spend the tokens. | -| `amount` | `uint256` | The amount of tokens to approve. | - -#### Returns - -| Type | Description | -| ------ | -------------------------------------- | -| `bool` | `true` if the approval was successful. | - -### `transferFrom` - -Transfers tokens from one address to another on behalf of the sender, ensuring -the recipient is not a blocked address. - -```solidity -function transferFrom(address sender, address recipient, uint256 amount) external transferable(recipient) returns (bool) -``` - -#### Parameters - -| Name | Type | Description | -| ----------- | --------- | --------------------------------- | -| `sender` | `address` | The address sending the tokens. | -| `recipient` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | - -#### Returns - -| Type | Description | -| ------ | -------------------------------------- | -| `bool` | `true` if the transfer was successful. | - -### `mint` - -Mints new tokens to a specified address, ensuring the recipient is not a blocked -address. This function can only be called by the owner. - -```solidity -function mint(address to, uint256 amount) external mintable(to) onlyOwner -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | --------------------------------- | -| `to` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to mint. | - -### `burn` - -Burns tokens from a specified address, ensuring the sender is not a module -address. This function can only be called by the owner. - -```solidity -function burn(address from, uint256 amount) external burnable(from) onlyOwner -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | ------------------------------------ | -| `from` | `address` | The address whose tokens are burned. | -| `amount` | `uint256` | The amount of tokens to burn. | - -### `sudoTransfer` - -Transfers tokens from one address to another, bypassing the usual access control -checks. This function can only be called by the chain signer. - -```solidity -function sudoTransfer(address sender, address recipient, uint256 amount) external onlyChain -``` - -#### Parameters - -| Name | Type | Description | -| ----------- | --------- | --------------------------------- | -| `sender` | `address` | The address sending the tokens. | -| `recipient` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | diff --git a/resources/developer/contract-references/evm/initia-erc20.mdx b/resources/developer/contract-references/evm/initia-erc20.mdx index 34e39729..de06bfae 100644 --- a/resources/developer/contract-references/evm/initia-erc20.mdx +++ b/resources/developer/contract-references/evm/initia-erc20.mdx @@ -13,14 +13,9 @@ support for Cosmos blockchain interactions. This contract inherits from multiple contracts including `IERC20`, `Ownable`, `ERC20Registry`, `ERC165`, and `ERC20ACL`. - -The InitiaERC20 contract is only meant to be used by the [ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) contract. It is not meant to be used directly and does not have the necessary modifiers for full compatibility with the MiniEVM. - -To deploy a custom ERC20 token, developers should use the -[InitiaCustomERC20](/resources/developer/contract-references/evm/initia-custom-erc20) -contract instead. - - +It can be used in two ways: via the +[ERC20Factory](/resources/developer/contract-references/evm/erc20-factory) for +standard tokens, or inherited directly for custom tokens with additional logic. ## Inheritance @@ -55,10 +50,13 @@ contract instead. ## Constructor -Initializes the contract with the token's name, symbol, and decimals. +Initializes the contract with the token's name, symbol, and decimals. The +`register_erc20` modifier registers the token with the ERC20 registry. +InitiaERC20 is used for custom deployments only; factory-created tokens use the +[ERC20](/resources/developer/contract-references/evm/erc20) contract. ```solidity -constructor(string memory _name, string memory _symbol, uint8 _decimals) { +constructor(string memory _name, string memory _symbol, uint8 _decimals) register_erc20 { name = _name; symbol = _symbol; decimals = _decimals; @@ -228,11 +226,26 @@ function mint(address to, uint256 amount) external mintable(to) onlyOwner ### `burn` -Burns tokens from a specified address, ensuring the sender is not a module -address. This function can only be called by the owner. +Burns tokens from the caller's address, ensuring the sender is not a module +address. ```solidity -function burn(address from, uint256 amount) external burnable(from) onlyOwner +function burn(uint256 amount) external burnable(msg.sender) +``` + +#### Parameters + +| Name | Type | Description | +| -------- | --------- | ----------------------------- | +| `amount` | `uint256` | The amount of tokens to burn. | + +### `burnFrom` + +Burns tokens from a specified address on behalf of the caller, ensuring the +address is not a module address. Requires prior allowance approval. + +```solidity +function burnFrom(address from, uint256 amount) external burnable(from) returns (bool) ``` #### Parameters @@ -242,6 +255,12 @@ function burn(address from, uint256 amount) external burnable(from) onlyOwner | `from` | `address` | The address whose tokens are burned. | | `amount` | `uint256` | The amount of tokens to burn. | +#### Returns + +| Type | Description | +| ------ | ---------------------------------- | +| `bool` | `true` if the burn was successful. | + ### `sudoTransfer` Transfers tokens from one address to another, bypassing the usual access control @@ -258,35 +277,3 @@ function sudoTransfer(address sender, address recipient, uint256 amount) externa | `sender` | `address` | The address sending the tokens. | | `recipient` | `address` | The address receiving the tokens. | | `amount` | `uint256` | The amount of tokens to transfer. | - -### `sudoMint` - -Mints new tokens to a specified address, bypassing the usual access control -checks. This function can only be called by the chain signer. - -```solidity -function sudoMint(address to, uint256 amount) external onlyChain -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | --------------------------------- | -| `to` | `address` | The address receiving the tokens. | -| `amount` | `uint256` | The amount of tokens to mint. | - -### `sudoBurn` - -Burns tokens from a specified address, bypassing the usual access control -checks. This function can only be called by the chain signer. - -```solidity -function sudoBurn(address from, uint256 amount) external onlyChain -``` - -#### Parameters - -| Name | Type | Description | -| -------- | --------- | ------------------------------------ | -| `from` | `address` | The address whose tokens are burned. | -| `amount` | `uint256` | The amount of tokens to burn. |