Skip to content

Latest commit

 

History

History
366 lines (336 loc) · 16.1 KB

fip-0017a.md

File metadata and controls

366 lines (336 loc) · 16.1 KB
fip title status type author created updated
17a
FIO Token Wrapping
Final
Functionality
Pawel Mastalerz <[email protected]>
2020-09-17
2022-10-19

Abstract

Functionality proposed in this FIP is intended to make wrapping of FIO Tokens 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 wraptokens wrap_fio_tokens Transfers FIO Tokens to designated FIO account on the way to another chain.
fio.oracle unwraptokens Transfers FIO Tokens to designated FIO account back from another chain.
fio.oracle regoracle Registers an Oracle.
fio.oracle unregoracle Unregisters an Oracle.
fio.oracle setoraclefee Allows Oracle to set Oracle fee.
get_oracle_fees Fetches Oracles fees.

Motivation

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.

Specification

Overview

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 Tokens owned by the smart contract if all oracles agree to do so.

Use cases

Wrapping FIO Tokens

  • User A wants to wrap X FIO Tokens to P public address on C chain.
  • User A fetches amount of Oracle fee using /get_oracle_fees.
  • User A executes wraptokens action and passes in:
    • amount (X) of FIO tokens to wrap
    • public_address (P) on chain C where tokens should be delivered
    • chain_code C
    • max_oracle_fee - maximum amount of FIO user A is willing to pay the Oracles
  • X FIO Tokens are 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 wraptoken action (not covered by this FIP).
  • Once detected Oracles trigger minting of wrapped tokens on another chain (not covered by this FIP).

Un-wrapping of FIO Tokens

  • User A wants to unwrap X FIO Tokens to P public address on 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 unwraptoken action and passes in:
    • fio_public_key where to transfer tokens
    • amount (X) of FIO tokens to transfer
  • Once the last Oracle executes unwraptoken action, the tokens are transferred to P.

Registering oracles

  • Each Oracle is registered using regoracle action. Only top 21 BPs can register Oracles via an msig.

Setting oracle fees

  • Each Oracle submits a fee for token and domain wrapping using setoraclefee.
  • Oracle fee is set to median of fees provided by all Oracles and then multiplied by number of registered oracles.

New actions

Wrap FIO Tokens

Transfers FIO Tokens to designated FIO account for the purpose of wrapping.

Contract: fio.oracle

New action: wraptokens

New end point: /wrap_fio_tokens

New fee: wrap_fio_tokens, not bundle-eligible

RAM increase: To be determined during implementation

Request body

Parameter Required Format Definition
amount Yes Positive Int Amount of SUFs to wrap.
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 token 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
Example
{
  "amount": 100000000000,
  "chain_code": "ETH",
  "public_address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
  "max_oracle_fee": 1000000000,
  "max_fee": 1000000000,
  "tpid": "rewards@wallet",
  "actor": "aftyershcu22"
}

Processing

  • Request is validated per Exception handling.
  • Chain wrap_fio_token fee is collected.
  • RAM of signer is increased
  • Tokens are transferred to fio.oracle contract.
  • Fee distribution:
    • Oracle fee is transferred from actor account to all registered oracles in even amount.

Exception handling

Error condition Trigger Type fields:name fields:value Error message
Invalid amount Transfer amount is not valid. 400 "amount" Value sent in, e.g. "-1" "Invalid amount"
Insufficient balance Balance is less than amount + oracle fee + chain fee 400 "amount" Value sent in, e.g. "100000000000" "Insufficient balance"
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"
Invalid public address Recipient public address is not valid 400 "public_address" Value sent in, e.g. "notvalidethaddress" "Invalid public address"
Invalid chain code Recipient chain code is not valid 400 "chain_code" Value sent in, e.g. "BTC!@#$%^&()" "Invalid chain code"
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"
Invalid TPID tpid format is not valid 400 "tpid" Value sent in, e.g. "notvalidfioaddress" "TPID must be empty or valid FIO address"

Response body

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
Example
{
  "status": "OK",
  "oracle_fee_collected": 2000000000,
  "fee_collected": 2000000000
}

Unwrap FIO Tokens

Transfers FIO Tokens from fio.oracle to designated FIO account.

Contract: fio.oracle

New action: unwraptokens

Fee: none

RAM increase: To be determined during implementation

Request body

Parameter Required Format Definition
amount Yes Positive Int Amount of SUFs to unwrap.
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
Example
{
  "amount": 100000000000,
  "obt_id": "0x399b9129571fee35d450d60fffe3652433b5295b0161e622d2d27b18b04784fe",
  "fio_address": "alice@wallet",
  "actor": "aftyershcu22"
}

Processing

  • Request is validated per Exception handling.
  • If all other Oracles have alreday called unwraptokens for supplied obt_id, amount is transferred 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
  • Consensus
    • verify fio.address is registered
    • search for obt_id inside oracle_votes
    • if found, search if oracle has voted prior. If oracle has not voted, add the account to the voters' vector
    • if not found, emplace a new record into oracle_votes table.
    • compute the number of registered oracles and total votes inside the record for that obt_id
    • If 100% consensus is achieved, isComplete flag is set as true, and tokens are transferred to the fio.address supplied.

Exception handling

Error condition Trigger Type fields:name fields:value Error message
Invalid amount Transfer amount is not valid. 400 "amount" Value sent in, e.g. "-1" "Invalid amount"
Invalid FIO Address FIO Address is invalid or does not exist 400 "fio_address" Value sent in, e.g. "alice@wallet" "Invalid FIO Address"
Insufficient balance Balance is less than amount 400 "amount" Value sent in, e.g. "100000000000" "Insufficient balance"
Not an Oracle actor is not a registered Oracle 400 "actor" Value sent in, e.g. "aftyershcu22" "Not a registered Oracle"
Oracle already voted Oracle has already called unwraptokens for obt_id 400 "actor" Value sent in, e.g. "aftyershcu22" "Oracle has already voted."

Response body

Parameter Format Definition
status String OK if successful
Example
{
  "status": "OK"
}

Register Oracle

Register Oracle.

Contract: fio.oracle

New action: regoracle

Fee: none

RAM increase: none

Request body

Parameter Required Format Definition
oracle_actor Yes 12 character string Valid actor (account) of oracle.
actor Yes 12 character string Valid actor of signer
Example
{
  "oracle_actor": "aftyershcu21",
  "actor": "eosio"
}

Processing

  • Request is validated per Exception handling.
  • regoracle must be approved by eosio permissions ( BP msig )
  • Verifies oracle is a top 21 block producer (Only top 21 BPs can register as an oracle )
  • Emplaces a new record into the oracles table

Exception handling

Error condition Trigger Type fields:name fields:value Error message
Invalid oracle Oracle is not valid or does not exist 400 "oracle_actor" Value sent in, e.g. "alice" "Invalid oracle"
No authority The signer does not have authority to register oracles 403 Type: invalid_signature

Response body

Parameter Format Definition
status String OK if successful
Example
{
  "status": "OK"
}

Unregister Oracle

Unregister Oracle.

Contract: fio.oracle

New action: unregoracle

Fee: none

RAM increase: none

Request body

Parameter Required Format Definition
oracle_actor Yes 12 character string Valid actor (account) of oracle.
Example
{
  "oracle_actor": "aftyershcu21"
}

Processing

  • Request is validated per Exception handling.
  • Only top 21 BPs via msig (eosio authority) can unregister an oracle
  • oracle_actor is removed

Exception handling

Error condition Trigger Type fields:name fields:value Error message
Invalid oracle Oracle is not registered 400 "oracle_actor" Value sent in, e.g. "alice" "Invalid oracle"
No authority The signer does not have authority to register oracles 403 Type: invalid_signature

Response body

Parameter Format Definition
status String OK if successful
Example
{
  "status": "OK"
}

Set Oracle fees

Allows Oracle to set a fee they desire for wrapping.

Contract: fio.oracle

New action: setoraclefee

No fee

RAM increase: To be determined during implementation

Request body

Parameter Required Format Definition
wrap_fio_domain Yes Positive Int Amount of SUFs the oracle is requesting for wrapping FIO Domain.
wrap_fio_tokens Yes Positive Int Amount of SUFs the oracle is requesting for wrapping FIO Tokens.
actor Yes 12 character string Valid actor of signer
Example
{
  "wrap_fio_domain": 2000000000,
  "wrap_fio_tokens": 2000000000,
  "actor": "aftyershcu21"
}

Processing

  • Request is validated per Exception handling.
    • Actor must be registered oracle.
  • Oracle fees are set
  • RAM of signer is increased
  • Each Oracle submits a fee for token and domain wrapping using setoraclefee.
  • Oracle fee is set to median of fees provided by all Oracles and then multiplied by number of registered oracles.

Exception handling

Error condition Trigger Type fields:name fields:value Error message
Invalid wrap_fio_domain value wrap_fio_domain format is not valid 400 "wrap_fio_domain" Value sent in, e.g. "-100" "Invalid wrap_fio_domain value"
Invalid wrap_fio_tokens value wrap_fio_tokens format is not valid 400 "wrap_fio_tokens" Value sent in, e.g. "-100" "Invalid wrap_fio_tokens value"
Not an Oracle actor is not a registered Oracle 400 "actor" Value sent in, e.g. "aftyershcu22" "Not a registered Oracle"

Response body

Parameter Format Definition
status String OK if successful
Example
{
  "status": "OK"
}

Get Oracle fees

Returns current fees for wrapping

New endpoint: /get_oracle_fees

Request body

None

Processing

  • Fees are computed and returned
    • Median is derived for each oracle fee type and multiplied by number of oracles
    • Example:
      • Oracle 1
        • wrap_fio_domain: 2000000000
        • wrap_fio_tokens: 2000000000
      • Oracle 2
        • wrap_fio_domain: 3000000000
        • wrap_fio_tokens: 5000000000
      • Oracle 3
        • wrap_fio_domain: 5000000000
        • wrap_fio_tokens: 9000000000
      • Fees are:
        • wrap_fio_domain: median is 3000000000 x 3 oracles = 9000000000
        • wrap_fio_domain: median is 5000000000 x 3 oracles = 15000000000

Response body

Parameter Format Definition
wrap_fio_domain Positive Int Fee to wrap domain in SUFs.
wrap_fio_tokens Positive Int Fee to wrap tokens in SUFs.
Example
{
  "wrap_fio_domain": 9000000000,
  "wrap_fio_tokens": 15000000000,
}

Rationale

Even though wrapping could be accomplished without any new functionality being added to the FIO Protocol, it would be hard. Specifically:

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.

Implementation

TBD

Release information

The following changes were included in fio.contracts v2.8.0

  • New contract actions wraptokens, unwraptokens, regoracle, unregoracle, and setoraclefee were added

The following changes were included in fio v3.4.0

  • New wrap_fio_tokens and get_oracle_fees API endpoints were added

Backwards Compatibility

New actions with no impact on existing functionality.

Future considerations

  • Consider generic wrapping contract.

Discussion link

https://fioprotocol.atlassian.net/wiki/spaces/WP/pages/7012357/Enable+FIO+Token+and+Domain+NFT+wrapping