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
|
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 | 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 | 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 (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 |
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:
|
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: |
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: |
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 |
|
Create wFIO on Ethereum chain.
wFIO is created using the wrap
action
New action: wrap
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 |
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", "amount": 100000000000, "obtid": "dfe50aad8e2271f84f87b8e603776d7e7970c636bb899c8993c08e9e2d21c106" } |
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 approved
The final oracle approval executes the wrap
.
wFIO is minted and transferred to account
Cannot be called when contract is in paused state
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" |
Convert wFIO on Ethereum chain to FIO Tokens on FIO chain.
New action: unwrap
Called by the user
Cannot be called when the contract is in paused state
User [Alice] pays the unwrap
gas fees.
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. |
{ "amount": 100000000000, "fio_address": "alice@wallet" } |
Request is validated per Exception handling.
No Oracle Consensus required.
Contract burns wFIO and event is emitted
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" |
Register Oracle.
Each Oracle is registered by custodians using regoracle
action.
New action: regoracle
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" } |
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.
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” |
Unregister Oracle.
New action: unregoracle
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" } |
Consensus required. Oracle is removed after 2/3+1 Custodians have called unregoracle
with same ethereum 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.
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" |
Register Custodian
Each Custodian is registered using regcust
action.
New action: regcust
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" } |
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.
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” |
Unregister Custodian.
New action: unregcust
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" } |
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.
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 contract.
New action: pause
Parameter | Required | Format | Definition |
---|---|---|---|
None | No |
Any custodian can pause/unpause the erc20 contract.
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 contract.
New action: unpause
Parameter | Required | Format | Definition |
---|---|---|---|
None | No |
Any custodian can pause/unpause the erc20 contract.
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” |
{ tx: '0x3c9ffdcf06ac984b93f5c302cf63bdb33ddb9479eba34737dc1ff3cf819ef0a7', receipt: { transactionHash: '0x3c9ffdcf06ac984b93f5c302cf63bdb33ddb9479eba34737dc1ff3cf819ef0a7', transactionIndex: 0, blockHash: '0xc3503388ba0748373ab2596609b001391636a9a1d469fca73352a2f5709595af', blockNumber: 2, from: '0x996e32a723cfe4afcb30f5ee3db78808ee816114', to: '0x5f953f03c166d1609101ebfb7286b3526fea768b', gasUsed: 70446, cumulativeGasUsed: 70446, contractAddress: null, logs: [], status: true, logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', rawLogs: [] }, logs: [] } |