Skip to content

Commit

Permalink
Automatically merged updates to draft EIP(s) 3005 (#3021)
Browse files Browse the repository at this point in the history
Hi, I'm a bot! This change was automatically merged because:

 - It only modifies existing Draft or Last Call EIP(s)
 - The PR was approved or written by at least one author of each modified EIP
 - The build is passing
  • Loading branch information
defifuture authored Oct 3, 2020
1 parent 4093b5a commit 6d540e2
Showing 1 changed file with 88 additions and 12 deletions.
100 changes: 88 additions & 12 deletions EIPS/eip-3005.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,41 +33,117 @@ The motivation behind this EIP is to find a way to allow relaying batched meta t

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

The key words "MUST (BUT WE KNOW YOU WON'T)", "SHOULD CONSIDER", "REALLY SHOULD NOT", "OUGHT TO", "WOULD PROBABLY", "MAY WISH TO", "COULD", "POSSIBLE", and "MIGHT" in this document are to be interpreted as described in RFC 6919.

### Meta transaction data

In order to successfully validate and transfer tokens, the `processMetaBatch()` function needs to process the following data about a meta transaction:
In order to successfully validate and transfer tokens, the `processMetaBatch()` function MUST process the following data about a meta transaction:

- sender address
- receiver address
- token amount
- relayer fee
- a (meta tx) nonce
- a timestamp or a block number (which represents a due date to process a meta tx)
- an expiration date (this COULD be a block number, or it COULD be a block timestamp)
- a token address
- a relayer address
- a signature

Not all of the data needs to be sent to the function by the relayer. Some of the data can be deduced or extracted from other sources (from transaction data and contract state).
Not all of the data needs to be sent to the function by the relayer (see the function interface specification). Some of the data can be deduced or extracted from other sources (from transaction data and contract state).

### `processMetaBatch()` function input data

The `processMetaBatch()` function MUST receive the following data:

- sender address
- receiver address
- token amount
- relayer fee
- an expiration date (this COULD be a block number, or it COULD be a block timestamp)
- a signature

The following data is OPTIONAL to be sent to the function, because it can be extracted or derived from other sources:

- a (meta tx) nonce
- a token address
- a relayer address

### Meta transaction data hash

The pseudocode for creating a hash of meta transaction data is the following:

```
keccak256(address(sender)
++ address(recipient)
++ uint256(amount)
++ uint256(relayerFee)
++ uint256(nonce)
++ uint256(expirationDate)
++ address(tokenContract)
++ address(relayer)
)
```

The created hash MUST then be signed with the sender's private key.

### Validation rules

- Nonce of a new transaction MUST always be bigger by exactly 1 from the nonce of the last successfully processed meta transaction of the same sender to the same token contract.
- Sending to and from a 0x0 address MUST be prohibited.
- A meta transaction MUST be processed before the expiration date.
- Each sender's token balance MUST be equal or greater than the sum of their respective meta transaction token amount and relayer fee.
- A transaction where at least one meta transaction in the batch does not satisfy the above requirements MUST not be reverted. Instead, a failed meta transaction MUST be skipped or ignored.

### `processMetaBatch()` function interface

The `processMetaBatch()` function MUST have the following interface:

```solidity
function processMetaBatch(address[] memory senders,
address[] memory recipients,
uint256[] memory amounts,
uint256[] memory relayerFees,
uint256[] memory blocks,
uint8[] memory sigV,
bytes32[] memory sigR,
bytes32[] memory sigS) public returns (bool);
```

The overview of parameters that are passed:

- `senders`: an array of meta transaction sender addresses (token senders)
- `recipients `: an array of token recipients addresses
- `amounts`: an array of token amounts that are sent from each sender to each recipient, respectively
- `relayerFees`: an array of the relayer fees paid in tokens by senders. The fee receiver is a relayer (`msg.address`)
- `blocks`: an array of block numbers that represent an expiration date by which the meta transaction must be processed (alternatively, a timestamp could be used instead of a block number)
- `sigV`, `sigR`, `sigS`: three arrays that represent parts of meta transaction signatures

Each entry in each of the arrays MUST represent data from one meta transaction. The order of the data is very important. Data from a single meta transaction MUST have the same index in every array.

### Meta transaction nonce

The token smart contract must keep track of a meta transaction nonce for each token holder.

### Meta transaction validation
```solidity
mapping (address => uint256) private _metaNonces;
```

Validation requirements:
The interface for the `nonceOf()` function is the following:

- sender and receiver addresses cannot be 0x0
- timestamp or block number must not be expired
- the sender's balance be equal or greater than the sum of the token amount and the relayer fee
- all of the data described in *Meta transaction data* (except the signature) must be hashed. The signed hash must be validated in the function.
```solidity
function nonceOf(address account) public view returns (uint256);
```

### Token transfers

If validation is successful, the meta nonce can be increased by 1 and the token transfers can occur:
After a meta transaction is successfully validated, the meta nonce of the meta transaction sender MUST be increased by 1.

Then two token transfers MUST occur:

- The specified token amount goes to the receiver
- The relayer fee goes to the relayer (`msg.sender`)
- The specified token amount MUST go to the recipient.
- The relayer fee MUST go to the relayer (`msg.sender`).

## Implementation

Expand Down

0 comments on commit 6d540e2

Please sign in to comment.