Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add HTS Fungible Token Standard Collection #1240

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

Nana-EC
Copy link
Collaborator

@Nana-EC Nana-EC commented Feb 9, 2025

Description:
Currently developers need to have a deep understanding of IHederaTokenService.sol to expose all the features for fungible tokens and management contracts.

Add a set of standard contracts a developer can simple inherit from and deploy that offer expected ERC20 functions

  • Add a description to the HTS README section with an initial overview of the standard
  • Add an IHtsFungibleToken.sol that cover HTS token + ERC20 behaviour that can be operated on a token via a deployed contract
  • Add an IHtsFungibleTokenProxy.sol that extends IHtsFungibleToken.sol behaviour to support interaction with an already existing token that can be operated on a token directly via an EOA
  • Add a HtsFungibleToken.sol abstract contract that implements creation flow of a new fungible token and allows key delegated transfer related behaviour
  • Add an ExampleHtsFungibleToken.sol that showcases the ease in which the standard can be used to create a fungible token
  • Add a HtsFungibleTokenSupplyManager.sol abstract contract that implements creation flow of a new fungible token and allows supply management via mint and burn functions
  • Add an ExampleHtsFungibleToken.sol that show cases the ease in which the standard can be used to create a fungible token
  • Add an ExampleHtsFungibleTokenSupplyManager.sol that showcases the ease in which the standard can be used to create a fungible token with mint and burn support
  • Add an IHtsNonFungibleToken.sol that cover HTS token + ERC721 behaviour that can be operated on a token via a deployed contract
  • Add an IHtsNonFungibleTokenProxy.sol that extends IHtsNonFungibleToken.sol behaviour to support interaction with an already existing token that can be operated on a token directly via an EOA
  • Add a test file nativeFungibleToken.js with test coverage for initial fungible use cases
  • Add a GHA test suite with coverage for native token standard

These contract aren't meant to satisfy requests from community so that devs don't have to worry about all the innards and amongst other things a dev can easily take a contract and

  1. deploy a FT native Hedera token like they do ERC20 w access to additional HTS functionality
  2. deploy a NFT native Hedera Token like they do ERC 721 w access to additional HTS functionality
  3. interact with an existing native Hedera Token like they do ERC 20
  4. interact with an existing native Hedera Token like they do ERC 721
  5. deploy a contract that manages the supply of said tokens and supports transfer where Hedera permissions are present

Related issue(s):

Fixes #1026
Fixes #781

Notes for reviewer:

  • Current implementation is missing all FT functions under IHederaTokenService.sol, these could be added to abstract contracts.
  • NFT related abstract and concrete example contracts are missing

Checklist

  • Documented (Code comments, README, etc.)
  • Tested (unit, integration, etc.)

@Nana-EC Nana-EC self-assigned this Feb 9, 2025
@Nana-EC Nana-EC added this to the 0.12.0 milestone Feb 9, 2025
Copy link

github-actions bot commented Feb 9, 2025

Test Results

 18 files  + 1  110 suites  +7   13m 3s ⏱️ - 3m 21s
318 tests  - 19  303 ✅  - 10   9 💤  - 4  6 ❌  - 5 
474 runs  + 7  457 ✅ +15  10 💤  - 4  7 ❌  - 4 

For more details on these failures, see this check.

Results for commit f77bcfb. ± Comparison against base commit 3aa1542.

This pull request removes 37 and adds 18 tests. Note that renamed tests count towards both.
"before each" hook for "Should check if an address is another address's operator" ‑ @OZERC1155Token Test Suite "before each" hook for "Should check if an address is another address's operator"
should airdrop 10 NFTs to multiple accounts ‑ HIP904 AirdropContract Test Suite should airdrop 10 NFTs to multiple accounts
should airdrop 10 tokens to multiple accounts ‑ HIP904 AirdropContract Test Suite should airdrop 10 tokens to multiple accounts
should airdrop a fungible token (FT) to a single account ‑ HIP904 AirdropContract Test Suite should airdrop a fungible token (FT) to a single account
should airdrop a non-fungible token (NFT) to a single account ‑ HIP904 AirdropContract Test Suite should airdrop a non-fungible token (NFT) to a single account
should airdrop fungible token (FT) to a single account using distribute ‑ HIP904 AirdropContract Test Suite should airdrop fungible token (FT) to a single account using distribute
should airdrop fungible tokens (FT) to multiple accounts ‑ HIP904 AirdropContract Test Suite should airdrop fungible tokens (FT) to multiple accounts
should airdrop non-fungible token (NFT) to a single account using distribute ‑ HIP904 AirdropContract Test Suite should airdrop non-fungible token (NFT) to a single account using distribute
should airdrop non-fungible tokens (NFT) to multiple accounts ‑ HIP904 AirdropContract Test Suite should airdrop non-fungible tokens (NFT) to multiple accounts
should cancel a pending airdrop for a fungible token (FT) ‑ HIP904 IHRC904Facade ContractTest Suite should cancel a pending airdrop for a fungible token (FT)
…
"before all" hook for "should airdrop a fungible token (FT) to a single account" ‑ HIP904 AirdropContract Test Suite "before all" hook for "should airdrop a fungible token (FT) to a single account"
Confirm initial balance values ‑ NativeTokenStandard Test Suite ExampleHtsFungibleToken Tests Confirm initial balance values
Confirm initial balance values ‑ NativeTokenStandard Test Suite ExampleHtsFungibleTokenSupplyManager Tests Confirm initial balance values
Confirm mint, mintTo and burn effects on balances ‑ NativeTokenStandard Test Suite ExampleHtsFungibleTokenSupplyManager Tests Confirm mint, mintTo and burn effects on balances
Confirm name, symbol, decimals and totalSupply default values ‑ NativeTokenStandard Test Suite ExampleHtsFungibleToken Tests Confirm name, symbol, decimals and totalSupply default values
Confirm name, symbol, decimals and totalSupply default values ‑ NativeTokenStandard Test Suite ExampleHtsFungibleTokenSupplyManager Tests Confirm name, symbol, decimals and totalSupply default values
Confirm name, symbol, decimals and totalSupply default values ‑ NativeTokenStandard Test Suite IHtsFungibleTokenProxy Tests Confirm name, symbol, decimals and totalSupply default values
Should NOT allow a non-operator to transfer tokens to another account ‑ @OZERC1155Token Test Suite Should NOT allow a non-operator to transfer tokens to another account
Should NOT burn insufficient amount of token ‑ @OZERC1155Token Test Suite Should NOT burn insufficient amount of token
Should NOT transfer the ownership to another account if the caller is not owner ‑ @OZERC1155Token Test Suite Should NOT transfer the ownership to another account if the caller is not owner
…

♻️ This comment has been updated with latest results.

@Nana-EC Nana-EC added the enhancement New feature or request label Feb 10, 2025
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
@Nana-EC Nana-EC force-pushed the 1026-hts-token-standard branch from 5937416 to 925d1c9 Compare February 10, 2025 02:37
Signed-off-by: Nana Essilfie-Conduah <[email protected]>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should remove this.

function _createHTSToken(string memory _name, string memory _symbol, int64 _initialTotalSupply, uint8 _decimals) internal virtual {
IHederaTokenService.HederaToken memory tokenInfo = _setupHTSToken(_name, _symbol);

(bool success, bytes memory result) = htsSystemContractAddress.call{value : msg.value}(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a specific reason to use .call here? should we call it using IHederaTokenService(0x167).createFungibleToken(...) instead?


(int responseCode, address tokenAddress) = success ? abi.decode(result, (int32, address)) : (HederaResponseCodes.UNKNOWN, address(0));

require(responseCode == HederaResponseCodes.SUCCESS, "Failed to create HTS token");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this pattern masks the responseCode in case of error, making it difficult to debug. Should we introduce a custom error, such as HtsError(int), so at least the caller can see the error code?


require(responseCode == HederaResponseCodes.SUCCESS, "Failed to create HTS token");

htsTokenAddress = tokenAddress;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd moved this into the constructor so it's clear that htsTokenAddress is only assigned once.

Comment on lines +4 to +5
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "../../IHTSStructs.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: list imported symbols

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Include "facade" interface for HTS fungible and non-fungible tokens ERC20 Wrapper Example
2 participants