ERC-7527: Token Bound Function Oracle AMM
Interfaces that wrap FT to NFT and unwrap NFT to FT based on an embedded Function Oracle AMM
Abstract
This proposal outlines interfaces for wrapping ERC-20 or ETH to ERC-721 and unwrap ERC-721 to ERC-20 or ETH. A function oracle feeds mint/burn prices based on an embedded equation of Function Oracle Automated Market Maker(FOAMM), which executes and clears the mint and burn of NFT.
Motivation
Liquidity can be a significant challenge in decentralized systems, especially for unique or less commonly traded tokens like NFTs. To foster a trustless NFT ecosystem, the motivation behind Function Oracle Automated Market Maker(FOAMM) is to provide automated pricing solutions for NFTs with liquidity through transparent, smart contract mechanisms.
This ERC provides innovative solutions for the following aspects:
- Automated Price Discovery
- Liquidity Enhancement
Automated Price Discovery
Transactions under FOAMM can occur without the need for a matching counterparty. When interacting directly with the pool, FOAMM automatically feeds prices based on the oracle with predefined function.
Liquidity Enhancement
In traditional DEX models, liquidity is supplied by external parties, known as Liquidity Providers(LP). These LPs deposit tokens into liquidity pools, facilitating exchanges by providing the liquidity. The removal or withdrawal of these LPs can introduce significant volatility, as it directly impacts the available liquidity in the market.
In a FOAMM system, the liquidity is added or removed internally through wrap
or unwrap
. FOAMM reduces reliance on external LPs and mitigates the risk of volatility caused by their sudden withdrawal, as the liquidity is continuously replenished and maintained through ongoing participant interactions.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Contract Interfaces:
Three interfaces are included here: Agency
, App
, and Factory
.
Agency
and App
MAY be implemented by the same contract or MAY be separately implemented. If separately implemented, they SHALL be mutually bounded and not upgradable after initialization.
Agency
and App
should implement iconstructor
interface to initialize the parameters within the contract and validate the configuration parameters. If factory is used to deploy Agency
and App
, factory will automatically call the two functions when deploying.
App
SHALL implement onlyAgency()
modifier and mint
and burn
SHALL apply onlyAgency()
as a modifier, which restricts calls to Mint
and Burn
only have effect if they are called through the corresponding Agency
.
Agency
is OPTIONAL to implement onlyApp()
.
The Factory
interface is OPTIONAL. It is most useful if Agency
and App
need to be deployed repeatedly.
Function Oracle is implemented through getWrapOracle
and getUnwrapOracle
, which feeds prices based on parameters and mathematical equations defined in the functions.
FOAMM is implemented through wrap
and unwrap
, which calls getWrapOracle
and getUnwrapOracle
to get the feed and automatically clears. To perform wrap
, FOAMM receives the premium and initiate mint
in App
. To perform unwrap
, FOAMM transfer the premium and initiate burn
in App
.
Agency
serves as a single entry point for all mint
and burn
transfer.
Agency Interface
App Interface
ERC7527App
SHALL inherit name
from interface ERC721Metadata
.
Token ID can be specified in data
parameter of mint
function.
Factory Interface
OPTIONAL - This interface can be used to deploy App and Agency, but interfaces and other contracts MUST NOT expect this interface to be present.
If a factory is needed to deploy bounded App and Agency, the factory SHALL implement the following interface:
Rationale
Prior Interfaces
ERC-5679 proposed IERC5679Ext721
interface for introducing a consistent way to extend ERC-721 token standards for minting and burning. To ensure the backward compatibility, considering some contracts which do not implement ERC721TokenReceiver
, IERC7527App
employ mint
function instead of safeMint
. To ensure the safety and the uniqueness of mutual bound, the _from
parameter of the burn
function in IERC5679Ext721
must be the contract address of the bounded agency. Thus, burn
function in IERC7527App
does not contain the _from
parameter.
Mutual Bound
Implement contracts for IERC7527App
and IERC7527Agency
so that they are each other's only owner. The wrap process is to check the premium amount of the fungible token received and then mint non-fungible token in the App. Only the owner or an approver of the non-fungible token can unwrap it.
Implementation Diversity
Users can customize function and fee percentage when implement the Agency and the App interfaces.
Different Agency implementations have distinct wrap, unwrap function logic, and different oracleFunction. Users can customize the currency, initial price, fee receiving address, fee rate, etc., to initialize the Agency contract.
Different App implementations cater to various use cases. Users can initialize the App contract.
Factory is not required. Factory implementation is need-based. Users can deploy their own contracts by selecting different Agency implementations and different App implementations through the Factory, combining them to create various products.
Currency types
currency
in IERC7527Agency
is the address of fungible token. Asset
can only define one type of currency
as the fungible token in the system. currency
supports various kinds of fungible tokens including ETH and ERC-20.
Token id
For each wrap process, a unique tokenId
should be generated. This tokenId
is essential for verification during the unwrap process. It also serves as the exclusive credential for the token. This mechanism ensures the security of assets in contracts.
Wrap and Mint
The strategy
is set while implementing the Agency interface, and it should be ensured not upgradable once deployed.
When executing the wrap
function, the predetermined strategy parameters are passed into the getWrapOracle
function to fetch the current premium and fee. The respective premium is then transferred to the Agency instance; the fee, according to mintFeePercent
is transferred to feeRecipient
. Subsequently, the App mints the NFT to the user's address.
Premium(tokens) transferred into the Agency cannot be moved, except through the unwrap process. The act of executing wrap is the sole trigger for the mint process.
Unwrap and Burn
When executing the unwrap
function, predetermined strategy parameters are passed into the getUnwrapOracle
function to read the current premium and fee. The App burns the NFT. Then, the corresponding premium, subtracting the fee according to burnFeePercent
, is then transferred to the user's address; the fee is transferred to feeRecipient
. The act of executing 'unwrap' is the sole trigger for the 'burn' process.
Two interfaces use together
IERC7527App
and IERC7527Agency
can be implemented together for safety, but they can be independently implemented before initialization for flexibiliy.
Pricing
getWrapOracle
and getUnwrapOracle
are used to fetch the current premium and fee. They implement on-chain price fetching through oracle functions. They not only support fetching the premium and fee during the wrap and unwrap processes but also support other contracts calling them to obtain the premium and fee, such as lending contracts.
They can support function oracle based on on-chain and off-chain parameters, but on-chain parameters are suggested only for consensus of on-chain reality.
initData
and iconstructor
During the deployment of App
and Agency
by the Factory, the Factory uses initData
as Calldata to call the Agency
and App
contracts and also invokes the iconstructor
functions within App
and Agency
.
The initData is mainly used to call the parameterized initialization functions, while iconstructor
is often used to validate configuration parameters and non-parameterized initialization functions.
Backwards Compatibility
No backward compatibility issues found.
Reference Implementation
Security Considerations
Fraud Prevention
Consider the following for the safety of the contracts:
-
Check whether modifiers
onlyAgency()
andonlyApp()
are proporly implemented and applied. -
Check the function strategies.
-
Check whether the contracts can be subject to re-entrancy attack.
-
Check whether all non-fungible tokens can be unwrapped with the premium calculated from FOAMM.
Copyright
Copyright and related rights waived via CC0.