---
eip: 2019
title: Fundable Token
author: Fernando Paris <fer@io.builders>, Julio Faura <julio@adhara.io>, Daniel Lehrner <daniel@io.builders>
discussions-to: https://github.com/ethereum/EIPs/issues/2105
status: Stagnant
type: Standards Track
category: ERC
created: 2019-05-10
requires: 20
---

## Simple Summary
An extension to the [ERC-20] standard token that allows Token wallet owners to request a wallet to be funded, by calling the smart contract and attaching a fund instruction string.

## Actors

#### Token Wallet Owners
The person or company who owns the wallet, and will order a token fund request into the wallet.

#### Token contract owner / agent 
The entity, company responsible/owner of the token contract, and token issuing/minting. This actor is in charge of trying to fulfill all fund request(s), reading the fund instruction(s), and correlate the private payment details.

#### Orderer
An actor who is enabled to initiate funding orders on behalf of a token wallet owner.

## Abstract
Token wallet owners (or approved addresses) can order tokenization requests through  blockchain. This is done by calling the ```orderFund``` or ```orderFundFrom``` methods, which initiate the workflow for the token contract operator to either honor or reject the fund request. In this case, fund instructions are provided when submitting the request, which are used by the operator to determine the source of the funds to be debited in order to do fund the token wallet (through minting).

In general, it is not advisable to place explicit routing instructions for debiting funds on a verbatim basis on the blockchain, and it is advised to use a private communication alternatives, such as private channels, encrypted storage or similar,  to do so (external to the blockchain ledger). Another (less desirable) possibility is to place these instructions on the instructions field in encrypted form.

## Motivation
Nowadays most of the token issuing/funding request, based on any fiat based payment method  need a previous centralized transaction, to be able to get the desired tokens issued on requester's wallet.
In the aim of trying to bring all the needed steps into decentralization, exposing all the needed steps of token lifecycle and payment transactions, a funding request can allow wallet owner to initiate the funding request via  blockchain.
Key benefits:

* Funding and payment traceability is enhanced bringing the initiation into the ledger. All payment stat
s can be stored on chain.
* Almost all money/token lifecycle is covered via a decentralized approach, complemented with private communications which is common use in the ecosystem.

## Specification

```solidity
interface IFundable /* is ERC-20 */ {
    enum FundStatusCode {
        Nonexistent,
        Ordered,
        InProcess,
        Executed,
        Rejected,
        Cancelled
    }
    function authorizeFundOperator(address orderer) external returns (bool);
    function revokeFundOperator(address orderer) external returns (bool) ;
    function orderFund(string calldata operationId, uint256 value, string calldata instructions) external returns (bool);
    function orderFundFrom(string calldata operationId, address walletToFund, uint256 value, string calldata instructions) external returns (bool);
    function cancelFund(string calldata operationId) external returns (bool);
    function processFund(string calldata operationId) external returns (bool);
    function executeFund(string calldata operationId) external returns (bool);
    function rejectFund(string calldata operationId, string calldata reason) external returns (bool);

    function isFundOperatorFor(address walletToFund, address orderer) external view returns (bool);
    function retrieveFundData(address orderer, string calldata operationId) external view returns (address walletToFund,       uint256 value, string memory instructions, FundStatusCode status);

    event FundOrdered(address indexed orderer, string indexed operationId, address indexed , uint256 value,         string instructions);
    event FundInProcess(address indexed orderer, string indexed operationId);
    event FundExecuted(address indexed orderer, string indexed operationId);
    event FundRejected(address indexed orderer, string indexed operationId, string reason);
    event FundCancelled(address indexed orderer, string indexed operationId);
    event FundOperatorAuthorized(address indexed walletToFund, address indexed orderer);
    event FundOperatorRevoked(address indexed walletToFund, address indexed orderer);
}
```

### Functions

#### authorizeFundOperator

Wallet owner, authorizes a given address to be fund orderer.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the orderer.

#### revokeFundOperator

Wallet owner, revokes a given address to be fund orderer.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the orderer.

#### orderFund

Creates a fund request, that will be processed by the token operator. The function must revert if the operation ID has been used before.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request |
| value | The amount to be funded. |
| instruction | A string including the payment instruction. |

#### orderFundFrom

Creates a fund request, on behalf of a wallet owner, that will be processed by the token operator. The function must revert if the operation ID has been used before.

| Parameter | Description |
| ---------|-------------|
| operationId |The unique ID to identify the request |
| walletToFund | The wallet to be funded on behalf.
| value | The amount to be funded. |
| instruction | A string including the payment instruction. |

#### cancelFund

Cancels a funding request.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request that is going to be cancelled. This can only be done by token holder, or the fund initiator. |

#### processFund

Marks a funding request as on process. After the status is on process, order cannot be cancelled.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request is in process.

#### executeFund

Issues the amount of tokens and marks a funding request as executed.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request that has been executed.

#### rejectFund

Rejects a given operation with a reason.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request that has been executed.
| reason | The specific reason that explains why the fund request was rejected. EIP 1066 codes can be used |

#### isFundOperatorFor

Checks that given player is allowed to order fund requests, for a given wallet.

| Parameter | Description |
| ---------|-------------|
| walletToFund | The wallet to be funded, and checked for approval permission.
| orderer | The address of the orderer, to be checked for approval permission.

#### retrieveFundData

Retrieves all the fund request data. Only operator, tokenHolder, and orderer can get the given operation data.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the fund order.

### Events

#### FundOrdered

Emitted when an token wallet owner orders a funding request.

| Parameter | Description |
| ---------|-------------|
| operationId | The unique ID to identify the request |
| walletToFund | The wallet that the player is allowed to start funding requests |
| value | The amount to be funded. |
| instruction | A string including the payment instruction. |

#### FundInProcess

Emitted when an operator starts a funding request after validating the instruction, and the operation is marked as in process.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the fund request orderer. |
| operationId | The unique ID to identify the fund. |

#### FundExecuted

Emitted when an operator has executed a funding request.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the fund request orderer. |
| operationId | The unique ID to identify the fund. |

#### FundRejected

Emitted when an operator has rejected a funding request.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the fund request orderer. |
| operationId | The unique ID to identify the fund. |
| reason | The specific reason that explains why the fund request was rejected. EIP 1066 codes can be used |

#### FundCancelled

Emitted when a token holder, orderer,  has cancelled a funding request. This can only be done if the operator hasn't put the funding order in process.

| Parameter | Description |
| ---------|-------------|
| orderer | The address of the fund request orderer. |
| operationId | The unique ID to identify the fund. |

#### FundOperatorAuthorized

Emitted when a given player, operator, company or a given persona, has been approved to start fund request for a given token holder.

| Parameter | Description |
| ---------|-------------|
| walletToFund | The wallet that the player is allowed to start funding requests |
| orderer | The address that allows the the player to start requests. |

#### FundOperatorRevoked

Emitted when a given player has been revoked initiate funding requests.

| Parameter | Description |
| ---------|-------------|
| walletToFund | The wallet that the player is allowed to start funding requests |
| orderer | The address that allows the the player to start requests. |

## Rationale
This standards provides a functionality to allow token holders to start funding requests in a decentralized way.

It's important to highlight that the token operator, need to process all funding request, updating the fund status based on the linked payment that will be done.

Funding instruction format is open. ISO payment standard like is a good start point,

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.

## Backwards Compatibility
This EIP is fully backwards compatible as its implementation extends the functionality of [ERC-20].

## Implementation
The GitHub repository [IoBuilders/fundable-token](https://github.com/IoBuilders/fundable-token) contains the work in progress implementation.

## Contributors
This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/).

## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).

[ERC-20]: ./eip-20.md
