fip | title | status | type | author | created | updated |
---|---|---|---|---|---|---|
17b |
FIO Domain Wrapping |
Final |
Functionality |
Pawel Mastalerz <pawel@fioprotocol.io> |
2020-09-17 |
2022-10-19 |
Functionality proposed in this FIP is intended to make wrapping of FIO Domains easier.
Wrapping cannot be accomplished entirely inside the FIO Protocol and therefore will not be possible with this FIP alone. This FIP only defines the functionality required in FIO Protocol. For detailed overview of the greater initiative see Enable FIO Token and Domain NFT wrapping.
Proposed new actions:
Contract | Action | Endpoint | Description |
---|---|---|---|
fio.oracle | wrapdomain | wrap_fio_domain | Transfers FIO Domain to designated FIO account on the way to another chain. |
fio.oracle | unwrapdomain | Transfers FIO Domain to designated FIO account back from another chain. |
Modified actions:
Contract | Action | Endpoint | Description |
---|---|---|---|
fio.address | xferdomain | transfer_fio_domain | Transfer of FIO Domain is now allowed even if the domain has expired. |
It is believed that the ability to wrap FIO Tokens and Domain NFTs will be beneficial to the FIO Community. It will open up new use cases for FIO Tokens and Domains such as:
- Enable FIO Domains to be traded on NFT trading sites such as Open Sea as ERC-721s.
- Enable FIO tokens to be used in a rapidly growing Defi ecosystem such as Uniswap which rewards token holders for providing liquidity to decentralized exchanges.
This FIP proposes a new fio.oracle system contract (controlled by eosio account or block producers). It will allow pre-defined oracles to transfer FIO Domains owned by the smart contract if all oracles agree to do so.
- User A wants to wrap FIO Domain to P public address on C chain.
- User A fetches amount of Oracle fee using /get_oracle_fees.
- User A executes wrapdomain action and passes in:
- fio_domain (D) to wrap
- public_address (P) on chain C where domain should be delivered
- chain_code C
- max_oracle_fee - maximum amount of FIO user A is willing to pay the Oracles
- FIO Domain is transferred to wrapping smart contract account
- Oracle fee is transferred from user A and distributed evenly to all registered Oracles.
- Oracles monitor every block looking for wrapdomain action (not covered by this FIP).
- Once detected Oracles trigger minting of FIO Domain NFT on another chain (not covered by this FIP).
- User A wants to unwrap FIO Domain to F FIO Address on the FIO Chain.
- User A executes action on another chain (not covered by this FIP):
- Oracles monitor every block on another chain (not covered by this FIP).
- Once detected each Oracle executes unwrapdomain action and passes in:
- fio_address (F) where to transfer domain
- fio_domain (D) to transfer
- Once the last Oracle executes unwrapdomain action, FIO Domain is transferred to P.
Transfers FIO Domain to designated FIO account for the purpose of wrapping.
Parameter | Required | Format | Definition |
---|---|---|---|
fio_domain | Yes | FIO Domain | Valid and unexpired FIO Domain. |
chain_code | Yes | String | Chain code of destination blockchain. Min chars: 1, Max chars: 10, Characters allowed: ASCII a-z0-9, case-insensitive. |
public_address | Yes | String | Public address on destination blockchain where wrapped domain should be delivered. |
max_oracle_fee | Yes | Positive Int | Maximum amount of SUFs the user is willing to pay as Oracle fee. Should be preceded by /get_oracle_fees |
max_fee | Yes | Positive Int | Maximum amount of SUFs the user is willing to pay for fee. Should be preceded by /get_fee for correct value. |
tpid | Yes | FIO Address | FIO Address of the entity which generates this transaction. TPID rewards will be paid to this address. Set to empty if not known. |
actor | Yes | 12 character string | Valid actor of signer |
{
"fio_domain": "alice",
"chain_code": "ETH",
"public_address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"max_oracle_fee": 1000000000,
"max_fee": 1000000000,
"tpid": "rewards@wallet",
"actor": "aftyershcu22"
}
- Request is validated per Exception handling.
- Oracle fee is transferred from actor account to fio.oracle.
- Chain wrap_fio_domain fee is collected.
- RAM of signer is increased
- Owner of domain is changed from current account to fio.oracle.
- Action explicitly not taken:
- Domain expiration date is not updated
- is_public flag is not updated
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid FIO Domain format | FIO Domain format is not valid | 400 | "fio_domain" | Value sent in, e.g. "alice" | "Invalid FIO domain" |
Invalid oracle fee value | max_oracle_fee format is not valid | 400 | "max_oracle_fee" | Value sent in, e.g. "-100" | "Invalid oracle fee value" |
Oracle fee exceeds maximum | Actual oracle fee is greater than supplied max_oracle_fee | 400 | "max_oracle_fee" | Value sent in, e.g. "1000000000" | "Oracle fee exceeds supplied maximum" |
Invalid fee value | max_fee format is not valid | 400 | "max_fee" | Value sent in, e.g. "-100" | "Invalid fee value" |
Fee exceeds maximum | Actual fee is greater than supplied max_fee | 400 | "max_fee" | Value sent in, e.g. "1000000000" | "Fee exceeds supplied maximum" |
Insufficient balance | Balance is less than oracle fee + chain fee | 400 | "max_oracle_fee" | Value sent in, e.g. "100000000000" | "Insufficient balance" |
Invalid chain code | Recipient chain code is not valid | 400 | "chain_code" | Value sent in, e.g. "BTC!@#$%^&()" | "Invalid chain code" |
Invalid TPID | tpid format is not valid | 400 | "tpid" | Value sent in, e.g. "notvalidfioaddress" | "TPID must be empty or valid FIO address" |
FIO Domain expired | FIO Domain is expired | 400 | "fio_domain" | Value sent in, e.g. "alice" | "FIO Domain expired. Renew first." |
FIO Domain not registered | FIO Domain is not registered | 400 | "fio_domain" | Value sent in, e.g. "alice" | "FIO Domain not registered" |
Not owner of FIO Domain | The signer does not own the domain | 403 | Type: invalid_signature |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
oracle_fee_collected | Int | Amount of SUFs collected as Oracle fee |
fee_collected | Int | Amount of SUFs collected as fee |
{
"status": "OK",
"oracle_fee_collected": 2000000000,
"fee_collected": 2000000000
}
Transfers FIO Domain from fio.oracle to designated FIO account.
Parameter | Required | Format | Definition |
---|---|---|---|
fio_domain | Yes | FIO Domain | Valid and unexpired FIO Domain. |
obt_id | Yes | String | Other Blockchain Transaction ID to identify specific transaction which triggers the unwrap. |
fio_address | Yes | String | FIO Address where domain should be delivered. |
actor | Yes | 12 character string | Valid actor of signer |
{
"fio_domain": "alice",
"obt_id": "0x399b9129571fee35d450d60fffe3652433b5295b0161e622d2d27b18b04784fe",
"fio_address": "alice@wallet",
"actor": "aftyershcu22"
}
- Request is validated per Exception handling.
- If all other Oracles have alreday called unwrapdomain for supplied fio_domain and obt_id, owner of domain is changed from fio.oracle to account which hashes down from FIO Public Key mapped to supplied FIO Address. If does not exist, it is created.
- RAM of signer is increased
- Action explicitly not taken:
- Domain expiration date is not updated
- is_public flag is not updated
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid FIO Domain format | FIO Domain format is not valid | 400 | "fio_domain" | Value sent in, e.g. "alice" | "Invalid FIO domain" |
Invalid FIO Address | FIO Address is invalid or does not exist | 400 | "fio_address" | Value sent in, e.g. "alice@wallet" | "Invalid FIO Address" |
Not an Oracle | actor is not a registered Oracle | 400 | "actor" | Value sent in, e.g. "aftyershcu22" | "Not a registered Oracle" |
Domain not wrapped or not registered | The domain to unwrap is not owned by fio.oracle or does not exist. | 400 | "fio_domain" | Value sent in, e.g. "alice" | "Domain not wrapped or not registered" |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
{
"status": "OK"
}
Transfer of FIO Domain is now allowed even if the domain has expired.
Remove the check for expired domain and 400:FIO Domain expired assertion.
Even though wrapping could be accomplished without any new functionality being added to the FIO Protocol, it would be hard. Specifically:
- /transfer_fio_domain does not support memo to pass intended destination public address on another chain. This would require the information to be exchanged off-chain.
- /transfer_tokens_pub_key does not support memo either. /transfer_tokens_fio_add or /record_obt_data would have to be used, but even then the information would have to be provided as part of free-form memo field.
get_wrapped_fio_domains and get_wrapped_fio_tokens calls were considered, but deemed unnecessary, as selected FIO Token and Domain NFT wrapping solution will rely on monitoring every block.
An approach was considered to make the contract generic, so that anyone could create a wrapping system, but configuring that generic contract and building their own oracles and smart contracts on another chain. This approach was deemed too complex to consider at this stage, but could be revisited in the future. In the meantime anyone can submit their own FIP to deploy a new wrapping contract to the FIO Chain.
Transfer of FIO Domains was allowed after domain is expired to ensure that the oracles do not have to handle an assertion of attempting to unwrap a domain which has expired, but has not yet been burned. It is not deemed a critical action to disable after expiration.
TBD
The following changes were included in fio.contracts v2.8.0
- New contract actions
wrapdomain
andunwrapdomain
were added - Contract action
xferdomain
was modified
The following changes were included in fio v3.4.0
- New
wrap_fio_domains
API endpoints were added - API endpoint
transfer_fio_domain
was modified
New actions with no impact on existing functionality.
- Consider generic wrapping contract.