HIP-719: Associate and Dissociate Tokens via Facade Contract
Author | Luke Lee |
---|---|
Working Group | Nana Essilfie-Conduah, Danno Ferrin, Mohammed Shaikjee |
Discussions-To | https://github.com/hashgraph/hedera-improvement-proposal/discussions/722 |
Status | Final ⓘ |
Needs Council Approval | Yes ⓘ |
Review period ends ⓘ | Wed, 10 May 2023 07:00:00 +0000 |
Type | Standards Track ⓘ |
Category | Service ⓘ |
Created | 2023-04-19 |
Updated | 2024-12-16 |
Requires | 206, 218, 376 |
Release | v0.53.0 |
Table of Contents
Abstract
HIP-218 proposed a way to enable treating HTS tokens in an equivalent manner
to ERC-20 and ERC-721 tokens by creating a proxy redirect facade contract. This proposal extends
this functionality to include the HTS associate
dissociate
and isAssociated
functions.
Motivation
There are some functions that are unique to Hedera HTS tokens that are not part of the ERC standard. A mechanism should be provided to enable developers to call these functions on HTS tokens in a way that is familiar to users of ERC-20 and ERC-721 tokens. Additionally, these token functions should be callable by both EOAs and contracts.
Rationale
By adding associate
dissociate
and isAssociated
functions to the token proxy redirect facade contract, functionality
that is only available to HTS tokens can be included to the available capabilities of token contracts.
User stories
- As a developer, I want to be able to call the
associate
dissociate
andisAssociated
functions on HTS tokens in a way that is similar to calling functions on the IERC20 and IERC721 interfaces. - As a DApp, I want to be able to enable users to call the
associate
dissociate
andisAssociated
functions without having to have intermediary contracts.
Specification
The method by which the redirection to proxy contract is currently implemented is that during the execution of an EVM request, the contract address is examined to determine whether it is an HTS token address and if so then the request execution is redirected to the proxy contract.
More specifically the algorithm by which the system gets from (a) the call to the token address to (b) the precompiled contract is as follows:
- The EVM encounters a call such as this
tokenAddress.<functionName>(<params>);
- The EVM calls
HederaStackedWorldStateUpdater.get()
and loads the code stored ontokenAddress
- In
HederaStackedWorldStateUpdater.get()
, we intercept the loading of the account code, determine if this is actually a contract address, and, if true, we return an instance ofHederaEvmWorldStateTokenAccount
which wraps the redirect token bytecode - The redirect bytecode is obtained by compiling the following contract, which accepts all the inputs the user provided (including function selector and function arguments), precedes the argument list with the token address, and delegatecalls the HTS precompile:
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.5.5; contract Assembly { fallback() external { address precompileAddress = address(0x167); assembly { mstore(0, 0xFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE) calldatacopy(32, 0, calldatasize()) let result := delegatecall(gas(), precompileAddress, 8, add(24, calldatasize()), 0, 0) let size := returndatasize() returndatacopy(0, 0, size) switch result case 0 { revert(0, size) } default { return(0, size) } } } }
- This means that any function can be redirected-to as long as the HTS precompile handles the redirect call.
For this HIP, the mechanism described above will be extended to include handling calls to associate
dissociate
and isAssociated
functions in the HTSPrecompileContract class method which handles the ABI_ID_REDIRECT_FOR_TOKEN function selector.
The following table describes the function selector for the new associate
, dissociate
and isAssociated
functions and the associated function signatures.
Function Selector | Function Signature |
---|---|
0x0a754de6 | associate() |
0x5c9217e0 | dissociate() |
0x4d8fdd6d | isAssociated() |
No arguments are necessary because
- The token address was already determined by looking up the contract address to determine if it is an HTS token address.
- The address to associate/dissociate will be the caller (i.e. msg.sender)
The solidity interface for IHRC will be the following
interface IHRC {
function associate() external returns (responseCode);
function dissociate() external returns (responseCode);
function isAssociated() external view returns (bool);
}
Once the above functionality has been implemented in services, the end user will be able to call the associate
, dissociate
and isAssociated
functions as follows:
IHRC(tokenAddress).associate()
IHRC(tokenAddress).dissociate()
IHRC(tokenAddress).isAssociated()
A token contract which needs the capability of both ERC-20 or ERC-721 and HTS functionality can implement both the IERC
interfaces and IHRC
interface.
Backwards Compatibility
This HIP builds on HIP-218 and adds a new way to access existing functionality and thus does not impact backwards compatibility.
Security Implications
By design, the association and dissociation of tokens can only occur from the sender of the transaction which is in line with the existing security model.
How to Teach This
The associate
, dissociate
and isAssociated
functions can be invoked on an HTS tokens just like other functions on the IERC20 and IERC721 interfaces
by casting the token with the IHTS
interface.
Reference Implementation
Rejected Ideas
Open Issues
References
Copyright/license
This document is licensed under the Apache License, Version 2.0 – see LICENSE or (https://www.apache.org/licenses/LICENSE-2.0)
Citation
Please cite this document as: