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


Metadata
Status: DraftStandards Track: ERCCreated: 2023-09-03
Authors
Elaine Zhang (@lanyinzly) (lz8aj@virginia.edu), Jerry (jerrymindflow@gmail.com), Amandafanny (amandafanny200@gmail.com), Shouhao Wong (@wangshouh) (wongshouhao@outlook.com), 0xPoet (0xpoets@gmail.com)
Requires

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() and onlyApp() 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.