Overview
Dynamic Oracle Approach
FIO is automatically converted to ETH to cover gas costs
NFT Redemption Approach
The NFT is not actually minted until there is an action on the Ethereum chain where Bob can pay the gas fee
Notes on FIO Domain Expiration as an ETH NFT
Expiration is not stored on the minted eth NFT
The oracle will enact actions on the NFT after checking the FIO chain for validity
if unwrapped and expired
Cannot be placed in escrow
Cannot be wrapped
If held in escrow and expired
Can be released back to the FIO owner
Can be renewed on FIO chain
Once valid, can be transferred
Can not be approved by new owner (when ETH gas is paid)
wrapping process is not completed, NFT does not yet exist on ETH chain
if wrapped and not expired
Can be released from escrow to new owner
The FIO Domain can be wrapped assuming it has not expired or about to expire.
Do not wrap tokens that will expire in about 2 weeks?
An FIO domain NFT that has been wrapped on Ethereum chain does not need to be used on the Ethereum chain, so the resolvers used in ENS are not necessary.
NFTs as tradable assets have images associated with them via a uri string
The image of the NFT is not pertinent to FIO domains.
NFTs minted for trade on OpenSea use their own servers to store the image uri
More universal approach will require an IPFS node
Can make FIO endpoint available to retrieve string from FIO state.
Can be configured by block producers
v1/chain/get_nft_image example
POST:
'{“url”:”https://fio.eosrio.io/v1/chain/get_nft_image”}'
RESPONSE:
'{“image”:”https://imgur.com/exampleimage.png”}'
IPFS Url formatting:
'{“image”:”https://{gatewayURL}/ipfs/{content ID}/{optional path to resource}”}'
OLD: Moved specification info to fio.erc20 - wFIO Contract Specification
Wrap/Unwrap
wrap
Create wFIO on Ethereum chain
Registering oracles
wFIO is created using the
wrap
action
Implementation
New action:
wrap
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | String | Public address on ETH blockchain where wrapped FIO should be delivered. |
amount | Yes | Positive Int | Amount of wFIO (in SUFs) to unwrap. TBD (Paweł): So if I wrap 1,000,000,001 SUFs, how many WFIO will I get? |
Example
{ "amount": 100000000000, "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Transaction is executed when all registered oracles have called
wrap
(submitted their “observation”).wFIO is minted and transferred to
account
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 public address | Recipient public address is not valid | 400 | "account" | Value sent in, e.g. "notvalidethaddress" | "Invalid public address" |
No authority | The signer is not a registered Oracle and does not have authority to call this function | 403 | "Only a wFIO Oracle may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
unwrap
Convert wFIO on Ethereum chain to FIO Tokens on FIO chain.
Implementation
New action:
unwrap
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
amount | Yes | Positive Int | Amount of wFIO (in SUFs) to unwrap. |
fio_address (hash) | Yes | String | Hash of the FIO Address where FIO Tokens should be delivered. |
max_oracle_fee? | Yes | Positive Int | TBD (Paweł): Oracle fees only charged on Wrap? |
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. |
Example
{ "amount": 100000000000, "fio_address": "FIO8k7N7jU9eyj57AfazGxMuvPGZG5hvXNUyxt9pBchnkXXx9KUuD", "max_oracle_fee": 1000000000, "max_fee": 1000000000, "tpid": "rewards@wallet" }
Processing
Request is validated per Exception handling.
No Oracle Consensus required.
Oracle fee is transferred from actor account to all registered oracles in even amount.
wFIO is burned.
Exception handling
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid FIO address | Recipient public address is not valid | 400 | "account" | Value sent in, e.g. "notvalidethaddress" | "Invalid FIO address" |
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" |
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" |
No authority | The signer is not a registered Oracle and does not have authority to call this function | 403 | "Only a wFIO Oracle may call this function" | ||
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 |
Example
{ "status": "OK", "oracle_fee_collected": 2000000000 }
Oracles
regoracle
Register Oracle.
Registering oracles
Each Oracle is registered by custodians using
regoracle
action.
Implementation
New action:
regoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
ethaddress | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
{ "ethaddress": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Oracle is added after 2/3+1 Custodians have called
regoracle
with sameethaddress
.Ethereum address is registered as a valid Oracle.
Exception handling
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid address | Ethereum address is not valid | 400 | "ethaddress" | Value sent in, e.g. "notvalidethaddress" | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a wFIO custodian may call this function" | ||
Already registered | The Ethereum address is already registered as an Oracle | 400 | "ethaddress" | “Oracle is already registered” |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
unregoracle
Unregister Oracle.
Implementation
New action:
unregoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
ethaddress | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
{ "ethaddress": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Oracle is removed after 2/3+1 Custodians have unregistered the same Oracle Ethereum address
Consensus required. Oracle is removed after 2/3+1 Custodians have called
unregoracle
with sameethaddress
.Ethereum address is removed as a valid Oracle.
Exception handling
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid oracle | Oracle is not registered | 400 | "ethaddress" | Value sent in, e.g. "ethaddressnotinoracletable" | "Invalid oracle" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a wFIO custodian may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
Custodians
regcust
Register Custodian
Registering Custodians
Each Custodian is registered using
regcust
action.
Implementation
New action:
regcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
ethaddress | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
{ "ethaddress": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Custodian is added after 2/3+1 custodians have registered the same Ethereum address.
Ethereum address is added as a valid Custodian.
Exception handling
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid address | Ethereum address is not valid | 400 | "ethaddress" | Value sent in, e.g. "notvalidethaddress" | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a wFIO custodian may call this function" | ||
Already registered | The Ethereum address is already registered as an Custodian | 400 | "ethaddress" | “Custodian is already registered” |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
unregcust
Unregister Custodian.
Implementation
New action: unregcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
ethaddress | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
{ "ethaddress": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Custodian is removed after 2/3+1 custodians have registered the same Ethereum address.
Ethereum address is removed as a valid Custodian.
Exception handling
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Invalid custodian | Custodian is not registered | 400 | "ethaddress" | Value sent in, e.g. "ethaddressnotincusttable" | "Invalid custodian" |
Invalid address | Ethereum address is not valid | 400 | "ethaddress" | Value sent in, e.g. "notvalidethaddress" | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a wFIO custodian may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
Add Comment