EIP2018 - Clearable Token
# Simple Summary
"In banking and finance, clearing denotes all activities from the time a commitment is made for a transaction until it is settled." [1] (opens new window)
# Actors
# Clearing Agent
An account which processes, executes or rejects a clearable transfer.
# Operator
An account which has been approved by an account to order clearable transfers on its behalf.
# Orderer
The account which orders a clearable transfer. This can be the account owner itself, or any account, which has been approved as an operator for the account.
# Abstract
The clearing process turns the promise of a transfer into the actual movement of money from one account to another. A clearing agent decides if the transfer can be executed or not. The amount which should be transferred is not deducted from the balance of the payer, but neither is it available for another transfer and therefore ensures, that the execution of the transfer will be successful when it is executed.
# Motivation
A regulated token needs to comply with all the legal requirements, especially KYC (opens new window) and AML (opens new window). Some of these checks may not be able to be done on-chain and therefore a transfer may not be completed in one step. Currently there is no EIP to make such off-chain checks possible. This proposal allows a user to order a transfer, which can be checked by a clearing agent off-chain. Depending on the result of it, the clearing agent will either execute or cancel the transfer. To provide more information why a transfer is cancelled, the clearing agent can add a reason why it is not executed.
# Specification
interface ClearableToken /* is ERC-1996 */ {
enum ClearableTransferStatusCode { Nonexistent, Ordered, InProcess, Executed, Rejected, Cancelled }
function orderTransfer(string calldata operationId, address to, uint256 value) external returns (bool);
function orderTransferFrom(string calldata operationId, address from, address to, uint256 value) external returns (bool);
function cancelTransfer(string calldata operationId) external returns (bool);
function processClearableTransfer(string calldata operationId) external returns (bool);
function executeClearableTransfer(string calldata operationId) external returns (bool);
function rejectClearableTransfer(string calldata operationId, string calldata reason) external returns (bool);
function retrieveClearableTransferData(string calldata operationId) external view returns (address from, address to, uint256 value, ClearableTransferStatusCode status);
function authorizeClearableTransferOperator(address operator) external returns (bool);
function revokeClearableTransferOperator(address operator) external returns (bool);
function isClearableTransferOperatorFor(address operator, address from) external view returns (bool);
event ClearableTransferOrdered(address indexed orderer, string operationId, address indexed from, address indexed to, uint256 value);
event ClearableTransferInProcess(address indexed orderer, string operationId);
event ClearableTransferExecuted(address indexed orderer, string operationId);
event ClearableTransferRejected(address indexed orderer, string operationId, string reason);
event ClearableTransferCancelled(address indexed orderer, string operationId);
event AuthorizedClearableTransferOperator(address indexed operator, address indexed account);
event RevokedClearableTransferOperator(address indexed operator, address indexed account);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Functions
# orderTransfer
Orders a clearable transfer on behalf of the msg.sender in favor of to
. A clearing agent is responsible to either execute or reject the transfer. The function must revert if the operation ID has been used before.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
to | The address of the payee, to whom the tokens are to be paid if executed |
value | The amount to be transferred. Must be less or equal than the balance of the payer. |
# orderTransferFrom
Orders a clearable transfer on behalf of the payer in favor of the to
. A clearing agent is responsible to either execute or reject the transfer. The function must revert if the operation ID has been used before.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
from | The address of the payer, from whom the tokens are to be taken if executed |
to | The address of the payee, to whom the tokens are to be paid if executed |
value | The amount to be transferred. Must be less or equal than the balance of the payer. |
# cancelTransfer
Cancels the order of a clearable transfer. Only the orderer can cancel their own orders. It must not be successful as soon as the transfer is in status InProcess
.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
# processClearableTransfer
Sets a clearable transfer to status InProcess
. Only a clearing agent can successfully execute this action. This status is optional, but without it the orderer can cancel the transfer at any time.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
# executeClearableTransfer
Executes a clearable transfer, which means that the tokens are transferred from the payer to the payee. Only a clearing agent can successfully execute this action.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
# rejectClearableTransfer
Rejects a clearable transfer, which means that the amount that is held is available again to the payer and no transfer is done. Only a clearing agent can successfully execute this action.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
reason | A reason given by the clearing agent why the transfer has been rejected |
# retrieveClearableTransferData
Retrieves all the information available for a particular clearable transfer.
Parameter | Description |
---|---|
operationId | The unique ID to identify the clearable transfer |
# authorizeClearableTransferOperator
Approves an operator to order transfers on behalf of msg.sender.
Parameter | Description |
---|---|
operator | The address to be approved as operator of clearable transfers |
# revokeClearableTransferOperator
Revokes the approval to order transfers on behalf of msg.sender.
Parameter | Description |
---|---|
operator | The address to be revoked as operator of clearable transfers |
# isClearableTransferOperatorFor
Returns if an operator is approved to order transfers on behalf of from
.
Parameter | Description |
---|---|
operator | The address to be an operator of clearable transfers |
from | The address on which the holds would be created |
# transfer
It is up to the implementer of the EIP if the transfer
function of ERC-20 should always revert or is allowed under certain circumstances.
# transferFrom
It is up to the implementer of the EIP if the transferFrom
function of ERC-20 should always revert or is allowed under certain circumstances.
# Events
# ClearableTransferOrdered
Must be emitted when a clearable transfer is ordered.
Parameter | Description |
---|---|
orderer | The address of the orderer of the transfer |
operationId | The unique ID to identify the clearable transfer |
from | The address of the payer, from whom the tokens are to be taken if executed |
to | The address of the payee, to whom the tokens are to be paid if executed |
value | The amount to be transferred if executed |
# ClearableTransferInProcess
Must be emitted when a clearable transfer is put in status ÌnProcess
.
Parameter | Description |
---|---|
orderer | The address of the orderer of the transfer |
operationId | The unique ID to identify the clearable transfer |
# ClearableTransferExecuted
Must be emitted when a clearable transfer is executed.
Parameter | Description |
---|---|
orderer | The address of the orderer of the transfer |
operationId | The unique ID to identify the clearable transfer |
# ClearableTransferRejected
Must be emitted when a clearable transfer is rejected.
Parameter | Description |
---|---|
orderer | The address of the orderer of the transfer |
operationId | The unique ID to identify the clearable transfer |
reason | A reason given by the clearing agent why the transfer has been rejected |
# ClearableTransferCancelled
Must be emitted when a clearable transfer is cancelled by its orderer.
Parameter | Description |
---|---|
orderer | The address of the orderer of the transfer |
operationId | The unique ID to identify the clearable transfer |
# AuthorizedClearableTransferOperator
Emitted when an operator has been approved to order transfers on behalf of another account.
Parameter | Description |
---|---|
operator | The address which has been approved as operator of clearable transfers |
account | Address on which behalf transfers will potentially be ordered |
# RevokedClearableTransferOperator
Emitted when an operator has been revoked from ordering transfers on behalf of another account.
Parameter | Description |
---|---|
operator | The address which has been revoked as operator of clearable transfers |
account | Address on which behalf transfers could potentially be ordered |
# Rationale
This EIP uses EIP-1996 to hold the money after a transfer is ordered. A clearing agent, whose implementation is not part of this proposal, acts as a predefined notary to decide if the transfer complies with the rules of the token or not.
The operationId
is a string and not something more gas efficient to allow easy traceability of the hold and allow human readable ids. It is up to the implementer if the string should be stored on-chain or only its hash, as it is enough to identify a hold.
The operationId
is a competitive resource. It is recommended, but not required, that the hold issuers used a unique prefix to avoid collisions.
While not requiring it, the naming of the functions authorizeClearableTransferOperator
, revokeClearableTransferOperator
and isClearableTransferOperatorFor
follows the naming convention of ERC-777.
# Backwards Compatibility
This EIP is fully backwards compatible as its implementation extends the functionality of EIP-1996.
# Implementation
The GitHub repository IoBuilders/clearable-token (opens new window) contains the reference implementation.
# Contributors
This proposal has been collaboratively implemented by adhara.io (opens new window) and io.builders (opens new window).
# Copyright
Copyright and related rights waived via CC0 (opens new window).
[1] https://en.wikipedia.org/wiki/Clearing_(finance)