mirror of https://github.com/status-im/EIPs.git
ERC902 updates
* Modernize formatting * Specify return codes as following ERC1066 * Use author GitHub usernames instead of emails * Update implementation repo * Set discussions-to
This commit is contained in:
parent
98998028f2
commit
b0239ee1cc
147
EIPS/eip-902.md
147
EIPS/eip-902.md
|
@ -1,56 +1,51 @@
|
||||||
---
|
---
|
||||||
eip: 902
|
eip: 902
|
||||||
title: Token Validation
|
title: Token Validation
|
||||||
author: Brooklyn Zelenka <brooklyn@finhaven.com>, Tom Carchrae <tom@finhaven.com>, Gleb Naumenko <gleb@finhaven.com>
|
author: Brooklyn Zelenka (@expede), Tom Carchrae (@carchrae), Gleb Naumenko (@naumenkogs)
|
||||||
|
discussions-to: https://ethereum-magicians.org/t/update-on-erc902-validated-token/1639
|
||||||
type: Standards Track
|
type: Standards Track
|
||||||
category: ERC
|
category: ERC
|
||||||
status: Draft
|
status: Draft
|
||||||
created: 2018-02-14
|
created: 2018-02-14
|
||||||
|
require: 1066
|
||||||
---
|
---
|
||||||
|
|
||||||
## Simple Summary
|
# Simple Summary
|
||||||
A protocol for services providing token ownership and transfer validation.
|
A protocol for services providing token ownership and transfer validation.
|
||||||
|
|
||||||
## Abstract
|
# Abstract
|
||||||
This standard provides a registry contract method for authorizing token transfers.
|
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.
|
||||||
By nature, this covers both initially issuing tokens to users (ie: transfer from contract to owner),
|
|
||||||
transferring tokens between users, and token spends.
|
|
||||||
|
|
||||||
## Motivation
|
# Motivation
|
||||||
The tokenization of assets has wide application,
|
The tokenization of assets has wide application, not least of which is financial instruments such as securities and security tokens. 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.
|
||||||
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
|
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.
|
||||||
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
|
Rather than each token maintaining its own whitelist (or other mechanism), it is preferable to share on-chain resources, rules, lists, and so on. There is also a desire to aggregate data and rules spread across multiple validators, or to apply complex behaviours (ex. switching logic, gates, state machines) to apply distributed data to an application.
|
||||||
|
|
||||||
### TokenValidator
|
# Specification
|
||||||
|
|
||||||
|
## `TokenValidator`
|
||||||
|
|
||||||
```solidity
|
```solidity
|
||||||
interface TokenValidator {
|
interface TokenValidator {
|
||||||
function check(
|
function check(
|
||||||
address _token,
|
address _token,
|
||||||
address _subject
|
address _subject
|
||||||
) public returns(byte result)
|
) public returns(byte statusCode)
|
||||||
|
|
||||||
function check(
|
function check(
|
||||||
address _token,
|
address _token,
|
||||||
address _from,
|
address _from,
|
||||||
address _to,
|
address _to,
|
||||||
uint256 _amount
|
uint256 _amount
|
||||||
) public returns (byte result)
|
) public returns (byte statusCode)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Methods
|
### Methods
|
||||||
|
|
||||||
##### check/2
|
#### `check`/2
|
||||||
|
|
||||||
`function check(address _token, address _subject) public returns (byte _resultCode)`
|
`function check(address _token, address _subject) public returns (byte _resultCode)`
|
||||||
|
|
||||||
|
@ -58,9 +53,9 @@ interface TokenValidator {
|
||||||
> * `_token`: the token under review
|
> * `_token`: the token under review
|
||||||
> * `_subject`: the user or contract to check
|
> * `_subject`: the user or contract to check
|
||||||
>
|
>
|
||||||
> *returns* a one-byte status code, often encoded as hex
|
> *returns* an ERC1066 status code
|
||||||
|
|
||||||
##### check/4
|
#### `check`/4
|
||||||
|
|
||||||
`function check(address token, address from, address to, uint256 amount) public returns (byte resultCode)`
|
`function check(address token, address from, address to, uint256 amount) public returns (byte resultCode)`
|
||||||
|
|
||||||
|
@ -70,29 +65,29 @@ interface TokenValidator {
|
||||||
> * `_to`: in the case of a transfer, who is accepting token ownership
|
> * `_to`: in the case of a transfer, who is accepting token ownership
|
||||||
> * `_amount`: The number of tokens being transferred
|
> * `_amount`: The number of tokens being transferred
|
||||||
>
|
>
|
||||||
> *returns* a one-byte status code, often encoded as hex
|
> *returns* an ERC1066 status code
|
||||||
|
|
||||||
### ValidatedToken
|
## `ValidatedToken`
|
||||||
|
|
||||||
```solidity
|
```solidity
|
||||||
interface ValidatedToken {
|
interface ValidatedToken {
|
||||||
event Validation(
|
event Validation(
|
||||||
address indexed subject,
|
address indexed subject,
|
||||||
byte indexed result
|
byte indexed result
|
||||||
)
|
)
|
||||||
|
|
||||||
event Validation(
|
event Validation(
|
||||||
address indexed from,
|
address indexed from,
|
||||||
address indexed to,
|
address indexed to,
|
||||||
uint256 value,
|
uint256 value,
|
||||||
byte indexed result
|
byte indexed statusCode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Events
|
### Events
|
||||||
|
|
||||||
##### Validation/2
|
#### `Validation`/2
|
||||||
|
|
||||||
`event Validation(address indexed subject, byte indexed resultCode)`
|
`event Validation(address indexed subject, byte indexed resultCode)`
|
||||||
|
|
||||||
|
@ -100,17 +95,17 @@ This event MUST be fired on return from a call to a `TokenValidator.check/2`.
|
||||||
|
|
||||||
> parameters
|
> parameters
|
||||||
> * `subject`: the user or contract that was checked
|
> * `subject`: the user or contract that was checked
|
||||||
> * `resultCode`: a status code
|
> * `statusCode`: an ERC1066 status code
|
||||||
|
|
||||||
|
|
||||||
##### Validation/4
|
#### `Validation`/4
|
||||||
|
|
||||||
```solidity
|
```solidity
|
||||||
event Validation(
|
event Validation(
|
||||||
address indexed from,
|
address indexed from,
|
||||||
address indexed to,
|
address indexed to,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
byte indexed result
|
byte indexed statusCode
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -120,26 +115,16 @@ This event MUST be fired on return from a call to a `TokenValidator.check/4`.
|
||||||
> * `from`: in the case of a transfer, who is relinquishing token ownership
|
> * `from`: in the case of a transfer, who is relinquishing token ownership
|
||||||
> * `to`: in the case of a transfer, who is accepting token ownership
|
> * `to`: in the case of a transfer, who is accepting token ownership
|
||||||
> * `amount`: The number of tokens being transferred
|
> * `amount`: The number of tokens being transferred
|
||||||
> * `resultCode`: a status code
|
> * `statusCode`: an ERC1066 status code
|
||||||
|
|
||||||
## Rationale
|
# Rationale
|
||||||
|
|
||||||
This proposal includes a financial permissions system on top of any financial token.
|
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.
|
||||||
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
|
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
|
||||||
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.
|
||||||
`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`.
|
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:
|
||||||
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
|
```solidity
|
||||||
function approve(address spender, uint amount) public returns (bool success) {
|
function approve(address spender, uint amount) public returns (bool success) {
|
||||||
|
@ -153,28 +138,16 @@ function approve(address spender, uint amount) public returns (bool success) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
A second `check/2` function is also required, that is more general-purpose, and does not
|
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.
|
||||||
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
|
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.
|
||||||
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
|
The status codes in the `byte` returns are unspecified. Any status code scheme may be used, though a general status code proposal is fortcoming.
|
||||||
may be used, though a general status code proposal is fortcoming.
|
|
||||||
|
|
||||||
By only defining the validation check, this standard is widely compatible with
|
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.
|
||||||
ERC-20, EIP-721, EIP-777, future token standards, centralized and decentralized exchanges,
|
|
||||||
and so on.
|
|
||||||
|
|
||||||
## Implementation
|
# Implementation
|
||||||
[Reference implementations](https://github.com/Finhaven/ValidatedToken/)
|
[Reference implementation](https://github.com/expede/validated-token/)
|
||||||
|
|
||||||
## Copyright
|
# Copyright
|
||||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||||
|
|
Loading…
Reference in New Issue