mirror of https://github.com/status-im/EIPs.git
181 lines
6.1 KiB
Markdown
181 lines
6.1 KiB
Markdown
---
|
|
eip: 902
|
|
title: Token Validation
|
|
author: Brooklyn Zelenka <brooklyn@finhaven.com>, Tom Carchrae <tom@finhaven.com>, Gleb Naumenko <gleb@finhaven.com>
|
|
type: Standards Track
|
|
category: ERC
|
|
status: Draft
|
|
created: 2018-02-14
|
|
---
|
|
|
|
## Simple Summary
|
|
A protocol for services providing token ownership and transfer validation.
|
|
|
|
## Abstract
|
|
This standard provides a registry contract method for authorizing token transfers.
|
|
By nature, this covers both initially issuing tokens to users (ie: transfer from contract to owner),
|
|
transferring tokens between users, and token spends.
|
|
|
|
## Motivation
|
|
The tokenization of assets has wide application,
|
|
not least of which is financial instruments such as securities.
|
|
Most jurisdictions have placed legal constraints on what may be traded,
|
|
and who can hold such tokens which are regarded as securities. Broadly this includes KYC and AML validation,
|
|
but may also include time-based spend limits, total volume of transactions, and so on.
|
|
|
|
Regulators and sanctioned third-party compliance agencies need some way to link
|
|
off-chain compliance information such as identity and residency to an on-chain service.
|
|
The application of this design is broader than legal regulation, encompassing all manner
|
|
of business logic permissions for the creation, management, and trading of tokens.
|
|
|
|
## Specification
|
|
|
|
### TokenValidator
|
|
|
|
```solidity
|
|
interface TokenValidator {
|
|
function check(
|
|
address _token,
|
|
address _subject
|
|
) public returns(byte result)
|
|
|
|
function check(
|
|
address _token,
|
|
address _from,
|
|
address _to,
|
|
uint256 _amount
|
|
) public returns (byte result)
|
|
}
|
|
```
|
|
|
|
#### Methods
|
|
|
|
##### check/2
|
|
|
|
`function check(address _token, address _subject) public returns (byte _resultCode)`
|
|
|
|
> parameters
|
|
> * `_token`: the token under review
|
|
> * `_subject`: the user or contract to check
|
|
>
|
|
> *returns* a one-byte status code, often encoded as hex
|
|
|
|
##### check/4
|
|
|
|
`function check(address token, address from, address to, uint256 amount) public returns (byte resultCode)`
|
|
|
|
> parameters
|
|
> * `_token`: the token under review
|
|
> * `_from`: in the case of a transfer, who is relinquishing token ownership
|
|
> * `_to`: in the case of a transfer, who is accepting token ownership
|
|
> * `_amount`: The number of tokens being transferred
|
|
>
|
|
> *returns* a one-byte status code, often encoded as hex
|
|
|
|
### ValidatedToken
|
|
|
|
```solidity
|
|
interface ValidatedToken {
|
|
event Validation(
|
|
address indexed subject,
|
|
byte indexed result
|
|
)
|
|
|
|
event Validation(
|
|
address indexed from,
|
|
address indexed to,
|
|
uint256 value,
|
|
byte indexed result
|
|
)
|
|
}
|
|
```
|
|
|
|
#### Events
|
|
|
|
##### Validation/2
|
|
|
|
`event Validation(address indexed subject, byte indexed resultCode)`
|
|
|
|
This event MUST be fired on return from a call to a `TokenValidator.check/2`.
|
|
|
|
> parameters
|
|
> * `subject`: the user or contract that was checked
|
|
> * `resultCode`: a status code
|
|
|
|
|
|
##### Validation/4
|
|
|
|
```solidity
|
|
event Validation(
|
|
address indexed from,
|
|
address indexed to,
|
|
uint256 amount,
|
|
byte indexed result
|
|
)
|
|
```
|
|
|
|
This event MUST be fired on return from a call to a `TokenValidator.check/4`.
|
|
|
|
> parameters
|
|
> * `from`: in the case of a transfer, who is relinquishing token ownership
|
|
> * `to`: in the case of a transfer, who is accepting token ownership
|
|
> * `amount`: The number of tokens being transferred
|
|
> * `resultCode`: a status code
|
|
|
|
## Rationale
|
|
|
|
This proposal includes a financial permissions system on top of any financial token.
|
|
This design is not a general roles/permission system. In any system, the more you know
|
|
about the context where a function will be called, the more powerful your function can be.
|
|
By restricting ourselves to token transfers (ex. ERC20 or EIP-777), we can make
|
|
assumptions about the use cases our validators will need to handle, and can make
|
|
the API both small, useful, and extensible.
|
|
|
|
The events are fired by the calling token. Since `Validator`s may aggregate or delegate
|
|
to other `Validator`s, it would generate a lot of useless events were it the
|
|
`Validator`'s responsibility. This is also the reason why we include the `token`
|
|
in the `call/4` arguments: a `Validator` cannot rely on `msg.sender` to determine
|
|
the token that the call is concerning.
|
|
|
|
We have also seen a similar design from [R-Token](https://github.com/harborhq/r-token) that uses an additional field: `spender`.
|
|
While there are potential use cases for this, it's not widely used enough to justify passing
|
|
a dummy value along with every call. Instead, such a call would look more like this:
|
|
|
|
```solidity
|
|
function approve(address spender, uint amount) public returns (bool success) {
|
|
if (validator.check(this, msg.sender, spender, amount) == okStatusCode) {
|
|
allowed[msg.sender][spender] = amount;
|
|
Approval(msg.sender, spender, amount);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
```
|
|
|
|
A second `check/2` function is also required, that is more general-purpose, and does not
|
|
specify a transfer amount or recipient. This is intended for general checks,
|
|
such as checking roles (admin, owner, &c), or if a user is on a simple whitelist.
|
|
|
|
We have left the decision to make associated `Validator` addresses public, private, or hardcoded
|
|
up to the implementer. The proposed design does not include a centralized registry.
|
|
It also does not include an interface for a `Validated` contract.
|
|
A token may require one or many `Validator`s for different purposes,
|
|
requiring different validations for different, or just a single `Validator`.
|
|
The potential use cases are too varied to provide a single unified set of methods.
|
|
We have provided a set of example contracts [here](https://github.com/Finhaven/ValidatedToken/)
|
|
that may be inherited from for common use cases.
|
|
|
|
The status codes in the `byte` returns are unspecified. Any status code scheme
|
|
may be used, though a general status code proposal is fortcoming.
|
|
|
|
By only defining the validation check, this standard is widely compatible with
|
|
ERC-20, EIP-721, EIP-777, future token standards, centralized and decentralized exchanges,
|
|
and so on.
|
|
|
|
## Implementation
|
|
[Reference implementations](https://github.com/Finhaven/ValidatedToken/)
|
|
|
|
## Copyright
|
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|