---
eip: 823
title: Token Exchange Standard
author: Kashish Khullar <kkhullar7@gmail.com>
type: Standards Track
category: ERC
status: Stagnant
created: 2018-01-06
requires: 20
---

## Simple Summary
A standard for token contracts, providing token exchange services thereby facilitating cross token payments.

## Abstract
The following standard provides functionally to make payments in the form of any other registered tokens, as well as allow token contracts to store any other tokens in an existing token contract. This standard allows ERC20 token holders to exchange their token with another ERC20 token and use the exchanged tokens to make payments. After a successful payment, the former specified ERC20 tokens, will be stored within the ERC20 token contract they are exchanged with. This proposal uses the term target contract which is used to denote the contract to the token with whom we want to exchange our tokens.

## Motivation
Existing token standards do not provide functionality to exchange tokens. Existing token converters reduce the total supply of an existing token, which in the sense destroys the currency. Token converters do not solve this problem and hence discourages creation of new tokens. This solution does not destroy the existing token but in essence preserve them in the token contract that they are exchanged with, which in turn increases the market value of the latter.

## Specification
### Sender Interface
This interface must be inherited by a ERC20 token contract that wants to exchange its tokens with another token.

#### Storage Variables
##### exchnagedWith
This mapping stores the number of tokens exchanged with another token, along with the latter’s address. Every time more tokens are exchanged the integer value is incremented consequently. This mapping acts as a record to denote which target contract holds our tokens.

```solidity
mapping ( address => uint ) private exchangedWith;
```
##### exchangedBy
This mapping stores the address of the person who initiated the exchange and the amount of tokens exchanged.

```solidity
mapping ( address => uint ) private exhangedBy;
```

#### Methods

NOTE: Callers MUST handle false from returns (bool success). Callers MUST NOT assume that false is never returned!

##### exchangeToken
This function calls the intermediate exchange service contract that handles the exchanges. This function takes the address of the target contract and the amount we want to exchange as parameters and returns boolean `success` and `creditedAmount`.

```solidity
function exchangeToken(address _targetContract, uint _amount) public returns(bool success, uint creditedAmount)
```

##### exchangeAndSpend
This function calls an intermediate exchange service contract that handles exchange and expenditure. This function takes the address of the target contract, the amount we want to spend in terms of target contract tokens and address of the receiver as parameters and returns boolean `success`.

```solidity
function exchangeAndSpend(address _targetContract, uint _amount,address _to) public returns(bool success)
```

##### __exchangerCallback
This function is called by the exchange service contract to our token contract to deduct calculated amount from our balance. It takes the address of the targert contract , the address of the person who exchanged the tokens and amount to be deducted from exchangers account as parameters and returns boolean `success`.

NOTE: It is required that only the exchange service contract has the authority to call this function.

```solidity
function __exchangerCallback(address _targetContract,address _exchanger, uint _amount) public returns(bool success)
```

#### Events

##### Exchange
This event logs any new exchanges that have taken place.

```solidity
event Exchange(address _from, address _ targetContract, uint _amount)
```

##### ExchangeSpent
This event logs any new exchange that have taken place and have been spent immediately.

```solidity
event ExchangeSpent(address _from, address _targetContract, address _to, uint _amount)
```

### Receiver Interface
This interface must be inherited by a ERC20 token contract that wants to receive exchanged tokens.

#### Storage Variables
##### exchangesRecieved
This mapping stores the number of tokens received in terms of another token, along with its address. Every time more tokens are exchanged the integer value is incremented consequently. This mapping acts as a record to denote which tokens do this contract holds apart from its own.

```solidity
mapping ( address => uint ) private exchnagesReceived;
```
#### Methods

NOTE: Callers MUST handle false from returns (bool success). Callers MUST NOT assume that false is never returned!

##### __targetExchangeCallback
This function is called by the intermediate exchange service contract. This function should add `_amount` tokens of the target contract to the exchangers address for exchange to be completed successfully.

NOTE: It is required that only the exchange service contract has the authority to call this function.

```solidity
function __targetExchangeCallback (uint _to, uint _amount) public returns(bool success)
```

##### __targetExchangeAndSpendCallback
This function is called by the intermediate exchange service contract. This function should add `_amount` tokens of the target contract to the exchangers address and transfer it to the `_to` address for the exchange and expenditure to be completed successfully.

NOTE: It is required that only the exchange service contract has the authority to call this function.

```solidity
function __targetExchangeAndSpendCallback (address _from, address _to, uint _amount) public returns(bool success)
```

#### Events
##### Exchange
This event logs any new exchanges that have taken place.

```solidity
event Exchange(address _from, address _with, uint _amount)
```

##### ExchangeSpent
This event logs any new exchange that have taken place and have been spent immediately.
```solidity
event ExchangeSpent(address _from, address _ targetContract, address _to, uint _amount)
```

### Exchange Service Contract

This is an intermediate contract that provides a gateway for exchanges and expenditure. This contract uses oracles to get the authenticated exchange rates.

#### Storage Variables

##### registeredTokens

This array stores all the tokens that are registered for exchange. Only register tokens can participate in exchanges.

```solidity
address[] private registeredTokens;
```

#### Methods

##### registerToken

This function is called by the owner of the token contract to get it’s tokens registered. It takes the address of the token as the parameter and return boolean `success`.

NOTE: Before any exchange it must be ensured that the token is registered.

```solidity
function registerToken(address _token) public returns(bool success)
```

##### exchangeToken

This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited.

```solidity
function exchangeToken(address _targetContract, uint _amount, address _from) public returns(bool success, uint creditedAmount)
```

##### exchangeAndSpend

This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeAndSpendCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited.

```solidity
function exchangeAndSpend(address _targetContract, uint _amount, address _from, address _to) public returns(bool success)
```

#### Events

##### Exchanges

This event logs any new exchanges that have taken place.

```solidity
event Exchange( address _from, address _by, uint _value ,address _target )
```
##### ExchangeAndSpent

This event logs any new exchange that have taken place and have been spent immediately.

```solidity
event ExchangeAndSpent ( address _from, address _by, uint _value ,address _target ,address _to)
```

### Diagramatic Explanation

#### Exchanging Tokens
![token-exchange-standard-visual-representation-1](../assets/eip-823/eip-823-token-exchange-standard-visual-representation-1.png)

NOTE: After the successful exchange the contract on right owns some tokens of the contract on the left.

#### Exchanging And Spending Tokens

![token-exchange-standard-visual-representation-2](../assets/eip-823/eip-823-token-exchange-standard-visual-representation-2.png)

NOTE: After the successful exchange the contract on right owns some tokens of the contract on the left.

## Rationale

Such a design provides a consistent exchange standard 
applicable to all ERC20 tokens that follow it.
The primary advantage for of this strategy is that the exchanged tokens will not be lost. They can either be spent or preserved.
Token convert face a major drawback of destroying tokens after conversion. This mechanism treats tokens like conventional currency where tokens are not destroyed but are stored.

## Backward Compatibility

This proposal is fully backward compatible. Tokens extended by this proposal should also be following ERC20 standard. The functionality of ERC20 standard should not be affected by this proposal but will provide additional functionality to it.

## Copyright

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

