An ERC404 token is a digital asset that combines the characteristics of ERC20 fungible tokens and ERC721 non-fungible tokens (aka NFT’s) to enable fractional ownership of an NFT.
In essence, ERC404 tokens represent divisible parts of an NFT, allowing multiple individuals to own shares of a single NFT. This approach is designed to enhance the liquidity and accessibility of NFTs by enabling them to be broken down into smaller, more affordable units.
ERC404 tokens have a dynamic minting and burning process, which adjusts the underlying NFT in response to the trading of its fractional parts. This functionality allows for a more flexible and fluid management of NFT ownership, opening up new possibilities for digital assets.
In this tutorial I’ll show you how to create a ERC404 token using Solidity and deploy it via remix to Ethereum or an alternative blockchain.
ERC404 Solidity Code Example
Here is a very simple contract which mints 10000 NFT’s and links them to JSON data stored on a server (you could also use IPFS).
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC404} from "./ERC404.sol";
contract Semi is ERC404 {
constructor() ERC404("Semi Fungible Token", "SEMI", 18) {
_setERC721TransferExempt(msg.sender, true);
_mintERC20(msg.sender, 10000 * units);
}
function tokenURI(uint256 id_) public pure override returns (string memory) {
return string.concat("https://jamesbachini.com/", Strings.toString(id_));
}
}
In the constructor argument we are setting a name, ticker symbol and specifying 18 decimals. We then call _setERC721TransferExempt for the deployer address and mint all the tokens to that address.
Note that the contract imports an external ERC404.sol library so we will need to clone this into Remix before we begin. I used the Pandora ERC404 library which can be seen here: https://github.com/Pandora-Labs-Org/erc404
Let’s go ahead and clone this URL in to remix by clicking on the menu next to workspaces and then clicking clone and adding the Github URL above.
Now let’s go into the contracts directory and create a new file called Semi.sol and paste in our ERC404 code from above.
If we compile the code using CTRL + S and get the little green tick we can then go to the deploy tab and either deploy it locally or to a remote network using metamask.
Note the first option is set to “Injected Provider – Metamask” and I have Metamask connected to the Goerli test network.
Deep Dive In To The ERC404 Library
Let’s take a closer look at that ERC404 library to see how this contract works.
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) public virtual returns (bool) {
if (_isValidTokenId(valueOrId_)) {
erc721TransferFrom(from_, to_, valueOrId_);
} else {
// Intention is to transfer as ERC-20 token (value).
return erc20TransferFrom(from_, to_, valueOrId_);
}
return true;
}
If we look at the transferFrom function we can start to get a feel for how this works. We are checking to see if _isValidTokenId returns true and if it does we direct the logic to the erc721TransferFrom function and if not we direct it to erc20TransferFrom instead.
The code that works this out is:
return id_ > ID_ENCODING_PREFIX && id_ != type(uint256).max;
So this could perhaps cause some issues if someone tried to transfer 1 wei of the fractional tokens because it would recognize it as a NFT transfer rather than a fungible transfer.
Here are the internal functions which control the fractionalization of NFT’s to fungible tokens and redemption.
_retrieveOrMintERC721
This internal function is used to either distribute an existing NFT or create a new one, depending on availability.
It checks to see if there are any tokens already stored in the contract. If there are, it takes one of those tokens. If there are no tokens available, it mints a new token.
_withdrawAndStoreERC721
This function finds the most recently acquired token by that address and transfers it to 0x0. The token is recorded in the contract, ready to be given out to someone else in the future.
_setERC721TransferExempt
This function is used to mark an address as exempt from transfers and will call one of the following two functions depending if true/false is passed through.
_reinstateERC721Balance
This function is used when an address is no longer marked as exempt. It reinstates the ERC721 balance for the address.
_clearERC721Balance
This function is used when an address is marked as exempt. It removes all the ERC721 tokens from that address.
Use Cases For ERC404
Fractionalized NFT’s aren’t new but if ERC404 becomes the default way Solidity developers go about creating these assets it could be used to develop solutions such as:
Art Investments High value artworks can be fractionalized, allowing smaller investors to own a share of a piece of art that they couldn’t afford outright. This democratizes access to art investment and potentially increases the liquidity of art as an asset class.
Real Estate Tokenization Fractionalized NFTs can represent shares in real estate properties, enabling investors to purchase a stake in property without needing to buy the entire asset. This could open up the real estate market to a broader range of investors.
Collective Purchases tangible objects such as antiques or memorabilia can be owned collectively, allowing collectors to come together and put a group bid into owning a piece of something they value highly but cannot afford individually.
Fan Engagement Musicians, filmmakers, and authors could fractionalize ownership of their works (songs, movies, books) and offer them to fans. This has the potential to create a novel revenue stream and deepen fan engagement.
GameFi In games and metaverses, users can buy fractional shares of virtual land or items. This can make high-value virtual assets more accessible to a wider range of players.
Crowdfunding & Investments Startups and crypto projects can issue fractionalized NFTs representing a stake in the project or company, offering a new form of fundraising and ICO’s v2.
Philanthropy Charitable organizations can create fractional NFTs for high value items or experiences, allowing for broader participation in fundraising efforts.
I hope you’ve found this tutorial into how to create an ERC404 token useful. The standard offers Solidity developers a simple way to combine ERC20 and ERC721 contracts to create a digital asset which can function both as a fungible and non-fungible token.