fio.erc20 - wFIO Contract Specification
Actions
Actions | Description |
---|---|
mint to address with oracle approvals | |
burn (called by user) | |
register oracle | |
unregister oracle | |
register custodian | |
unregister custodian | |
pause | pause wrap, unwrap or any built-in erc20 functions |
unpause | unpause wrap, unwrap or any build-in erc20 functions |
getOracle | Get oracle status by ethereum address |
getCustodian | Get custodian status by ethereum address |
getApproval | getApproval status by obtid
Result {
'0': '1',
'1': '0x009310e41f4746AFeca3Ac713e070598067A32db',
'2': '30000000000'
}
Result {
'0': '0',
'1': '0x0000000000000000000000000000000000000000',
'2': '0'
} |
State Variables
State variables | Description |
---|---|
custodian_count | Keeps track of the number of custodians active in the oracle. Required for consensus math |
oracle_count | Keeps track of the number of custodians active in the oracle. Required for consensus math |
uoracmapv | Incrementer used to generate unique id for unregoracle approval mapping |
roracmapv | Incrementer used to generate unique id for regoracle approval mapping |
ucustmapv | Incrementer used to generate unique id for unregcust approval mapping |
rcustmapv | Incrementer used to generate unique id for regcust approval mapping |
upausmapv | Incrementer used to generate unique id for unpause approval mapping |
pausemapv | Incrementer used to generate unique id for pause approval mapping |
owner | Used to store contract owner (msg.sender) when deployed |
oraclelist | A list of oracle addresses |
Events
Events | Description |
---|---|
wrapped | Event emitted when wrap has completed. |
unwrapped | Event emitted when user has unwrapped tokens. |
custodian_registered | Event emitted when a custodian has been registered |
custodian_unregistered | Event emitted when a custodian has been unregistered |
oracle_registered | Event emitted when an oracle has been registered |
oracle_unregistered | Event emitted when an oracle has been unregistered |
Paused | Event emitted when the contract has been paused by custodians |
Unpaused | Event emitted when the contract has been unpaused by custodians |
Mappings
Mappings | Members | Description |
---|---|---|
Custodians | custodian | Keeps track of the custodians that registered another custodian and their activation |
Oracles | oracle | Keeps track of the custodians that registered an oracle and the oracles activation count |
Approvals | pending | Keeps track of the approvals by obtid, the number of approvals, and the details of the approval
|
Modifiers
Modifiers (Perms) | Action | Description |
---|---|---|
onlyOracle | wrapunwrap | Only wFIO oracle may use this function |
onlyCustodian | regoracle | Only wFIO custodian may use this function |
whenPaused | unpause | Built into erc20 pausable security contract. Keeps an action from being called when paused |
whenNotPaused | pause | Built into erc20 pausable security contract. Keeps an action from being called when unpaused |
Misc. Requirements
Issue | Summary | Decision |
---|---|---|
Max supply | Should we put in a max supply to prevent over-minting of wFIO? This would track the maximum number of wFIO that could be in circulation. | Not needed Reason: if the ERC20 contract gets taken over an additional wFIO is minted, the most likely course of action will be to fork the contract and invalidate the bad transactions. |
Max transaction size | Should we put a max transaction size limit on mint into the ERC20 contract. | Not needed |
ERC20 contract key | What is the status of the key used to set the contract? | Key should only be used for spinning up the contract and should be burned. |
“Pause” function for Custodians | What is the process for locking the wFIO contract if it gets compromised? | Adam: contract is pausable. Tracked in: https://fioprotocol.atlassian.net/browse/BD-2585
|
Oracle “Admin” functions | Do we need to enable the ability for Oracles to call various contract actions such as approve, transfer, mint, etc. This can be performed in a couple of ways: Oracle 3 executes approval action for transfer, but wrong recipient is provided. Trx goes to Alice defined by oracle 1 and 2 2 - The Oracles can sign the next transfer action as a multisig | Pawel will create an Oracle/Custodian Wrapping Manual that includes use cases for how to respond to errors with wrap and unwrap. Tracked in: https://fioprotocol.atlassian.net/browse/WP-522 |
Custodian “Admin” functions | Are there contract actions that should be exposed to Custodian “admin” approval?
| Todo: Pawel will create an Oracle/Custodian Wrapping Manual that includes use cases for how to respond to errors with wrap and unwrap. Tracked in: https://fioprotocol.atlassian.net/browse/WP-522
|
Unwrap fee | Is there a fee for | On unwrap, the user pays the gas fees. |
ERC-20 contract key burn | Once we spin up the ERC-20 contract with multiple custodian keys, we will burn the contract key |
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 | uint256 | Amount of wFIO (in SUFs) to unwrap. |
obtid | Yes | string | FIO chain transaction ID |
Example
{
"account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"amount": 100000000000,
"obtid": "dfe50aad8e2271f84f87b8e603776d7e7970c636bb899c8993c08e9e2d21c106"
}
Processing
Request is validated per Exception handling.
Consensus required. Transaction is executed when all registered oracles have called
wrap
(submitted their “observation”).Current:
100% of oracles needed to approve (Minimum of 3 oracles) call
wrap
to get it approvedThe final oracle approval executes the
wrap
.
wFIO is minted and transferred to
account
Cannot be called when contract is in paused state
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid amount | Transfer amount is not valid. | 400 | "Invalid amount" |
Invalid public address | Recipient public address is not valid | 400 | "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" |
Contract paused | Contract is paused (built-in) | 400 | "Pausable: paused" |
unwrap
Convert wFIO on Ethereum chain to FIO Tokens on FIO chain.
Implementation
New action:
unwrap
Processing
Called by the user
Cannot be called when the contract is in paused state
Fees
User [Alice] pays the
unwrap
gas fees.
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
amount | Yes | uint256 | Amount of wFIO (in SUFs) to unwrap. |
fio_address | Yes | String | The FIO Address where FIO Tokens should be delivered. |
Example
Processing
Request is validated per Exception handling.
No Oracle Consensus required.
Contract burns wFIO and event is emitted
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid FIO address | Recipient public address is not valid | 400 | "Invalid FIO address" |
Invalid amount | Transfer amount is not valid. | 400 | "Invalid amount" |
Insufficient balance | Balance is less than amount + oracle fee + chain fee | 400 | "Insufficient balance" |
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" |
Contract paused | Contract is paused (built-in) | 400 | "Pausable: paused" |
Oracles - register/unregister
regoracle
Register Oracle.
Registering oracles
Each Oracle is registered by custodians using
regoracle
action.
Implementation
New action:
regoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
Processing
Request is validated per Exception handling.
Consensus required.
Oracles are registered by custodians. 2/3+1 of active custodians are required to complete registration of a new oracle.
A minimum of 3 oracles is required to approve a
wrap
transaction.After approval, the Ethereum address is registered as a valid Oracle.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid address | Ethereum address is not valid | 400 | "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 | “Oracle is already registered” |
unregoracle
Unregister Oracle.
Implementation
New action:
unregoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
Processing
Consensus required. Oracle is removed after 2/3+1 Custodians have called
unregoracle
with sameethereum account
.Ethereum address is removed as a valid Oracle.
A minimum of 3 oracles must be maintained. If only 3 Oracles are registered,
unregoracle
can not be called.Once an account has been unregistered as an oracle, it cannot be re-registered. If the same oracle gets unregistered and wants to re-register, they will need to generate a new key/account.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid oracle | Oracle is not registered | 400 | "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" |
Custodians - register/unregister
regcust
Register Custodian
Registering Custodians
Each Custodian is registered using
regcust
action.
Implementation
New action:
regcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
Processing
Request is validated per Exception handling.
Consensus required. Custodians are registered as follows:
The initial 10 custodians are set upon contract deployment by the contract owner.
Subsequently, 2/3+1 of active custodians must call
regcust
to register a new custodian.
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 | "account" | Value sent in, e.g. "invalid account" | "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 | "account" |
| “Custodian is already registered” |
unregcust
Unregister Custodian.
Implementation
New action: unregcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
Processing
Request is validated per Exception handling.
Consensus required. Custodian is removed after 2/3+1 of active custodians have called
unregcust
the same Ethereum address.Ethereum address is removed as a valid Custodian.
A minimum of 7 Custodians must be maintained. If only 7 Custodians are registered,
unregcust
can not be called.A custodian can not singlehandedly unregister themselves. All changes require 2/3+1. Bug, the custodian can call
unregcust
for themselves and be counted in the 2/3+1.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid custodian | Custodian is not registered | 400 | "Invalid custodian" |
Invalid address | Ethereum address is not valid | 400 | "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" |
pause
Pause contract.
Implementation
New action:
pause
Parameter | Required | Format | Definition |
---|---|---|---|
None | No |
|
|
Processing
Any custodian can pause/unpause the erc20 contract.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Contract paused | Contract is already paused (built-in) | 400 | "Pausable: paused" |
Already approved | Custodian already called pause | 400 | “msg.sender has already approved this pause” |
unpause
Unpause contract.
Implementation
New action:
unpause
Parameter | Required | Format | Definition |
---|---|---|---|
None | No |
|
|
Processing
Any custodian can pause/unpause the erc20 contract.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Contract unpaused | Contract is already unpaused (built-in) | 400 | "Pausable: unpaused" |
Already approved | Custodian already called unpause | 400 | “msg.sender has already approved this unpause” |