Skip to content

Commit

Permalink
EIP-6120: add the UTR contract address (ethereum#6614)
Browse files Browse the repository at this point in the history
* Update TRANSFER_FROM_ROUTER sample text and data

* update text and UTR contract address

* add @blackskin18 to author

* fix markdown-refs for ERC refs
  • Loading branch information
Zergity authored Mar 5, 2023
1 parent 1fcbab5 commit 58cee57
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions EIPS/eip-6120.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 6120
title: Universal Token Router
description: A single router contract enables tokens to be sent to application contracts in the transfer-and-call manner instead of approve-then-call.
author: Zergity (@Zergity), Ngo Quang Anh (@anhnq82), BerlinP (@BerlinP)
author: Zergity (@Zergity), Ngo Quang Anh (@anhnq82), BerlinP (@BerlinP), Khanh Pham (@blackskin18)
discussions-to: https://ethereum-magicians.org/t/eip-6120-universal-token-router/12142
status: Review
type: Standards Track
Expand All @@ -13,15 +13,15 @@ requires: 20, 721, 1014, 1155

## Abstract

ETH is designed with transfer-and-call as the default behavior in a transaction. Unfortunately, [EIP-20](./eip-20.md) is not designed with that pattern in mind and newer standards are too late to replace it as the de facto standard.
ETH is designed with transfer-and-call as the default behavior in a transaction. Unfortunately, [ERC-20](./eip-20.md) is not designed with that pattern in mind and newer standards cannot apply to the token contracts that have already been deployed.

Application and router contracts have to use the approve-then-call pattern which costs additional `n*m*l` `allow` (or `permit`) transactions, for `n` contracts, `m` tokens, and `l` user addresses. These allowance transactions not only cost enormous amounts of user gas, waste network storage and throughput, and worsen user experience, but also put users at serious security risks as they often have to approve unaudited, unverified and upgradable proxy contracts.
Application and router contracts have to use the approve-then-call pattern which costs additional `n*m*l` `allow` (or `permit`) transactions, for `n` contracts, `m` tokens, and `l` user addresses. These allowance transactions not only cost a lot of user gas, worsen user experience, waste network storage and throughput, but they also put users at serious security risks as they often have to approve unaudited, unverified and upgradable proxy contracts.

The Universal Token Router (UTR) separates the token allowance from the application logic, allowing any token to be spent in a contract call the same way with ETH, without approving any other application contracts.

Tokens approved to the Universal Token Router can only be spent in transactions directly signed by their owner, and they have clearly visible token transfer behavior, including token types (ETH, [EIP-20](./eip-20.md), [EIP-721](./eip-721.md) or [EIP-1155](./eip-1155.md)), `amountInMax`, `amountOutMin`, and `recipient`.
Tokens approved to the Universal Token Router can only be spent in transactions directly signed by their owner, and they have clearly visible token transfer behavior, including token types (ETH, [ERC-20](./eip-20.md), [ERC-721](./eip-721.md) or [ERC-1155](./eip-1155.md)), `amountInMax`, `amountOutMin`, and `recipient`.

The Universal Token Router contract is counter-factually deployed using [EIP-1014](./eip-1014.md) at a single address across all EVM-compatible networks, so new token contracts can pre-configure it as a trusted spender and no approval transaction is necessary ever again.
The Universal Token Router contract is counter-factually deployed using [EIP-1014](./eip-1014.md) at `0x6120245B546F2F0ce439186cAae8181007366120` across all EVM-compatible networks, so new token contracts can pre-configure it as a trusted spender and no approval transaction is necessary.

## Motivation

Expand All @@ -36,7 +36,7 @@ Before this EIP, when users sign transactions to spend their approved tokens, th

The Universal Token Router function arguments can act as a manifest for users when signing a transaction. With the support from wallets, users can see and review their expected token behavior instead of blindly trusting the application contracts and front-end code. Phishing sites will be much easier to detect and avoid for users.

Application contracts follow this standard can use the Universal Token Router to have the following benefits:
Most of the application contracts are already compatible with the Universal Token Router and can use it to have the following benefits:

* Safely share the user token allowance with all other applications.
* Freely update their helper contract logic.
Expand Down Expand Up @@ -69,14 +69,14 @@ struct Output {
address recipient;
uint eip; // token standard: 0 for ETH or EIP number
address token; // token contract address
uint id; // token id for EIP-721 and EIP-1155
uint id; // token id for ERC-721 and ERC-1155
uint amountOutMin;
}
```

Token balances of the `recipient` address are recorded at the beginning and the end of the `exec` function for each item in `outputs`. Transaction will revert with `INSUFFICIENT_OUTPUT_AMOUNT` if any of the balance changes are less than its `amountOutMin`.

A special id `ID_721_ALL` is reserved for EIP-721, which can be used in output actions to verify the total amount of all ids owned by the `recipient` address.
A special id `ID_721_ALL` is reserved for ERC-721, which can be used in output actions to verify the total amount of all ids owned by the `recipient` address.

```solidity
ID_721_ALL = keccak256('UniversalTokenRouter.ID_721_ALL')
Expand Down Expand Up @@ -111,7 +111,7 @@ struct Input {
address recipient;
uint eip; // token standard: 0 for ETH or EIP number
address token; // token contract address
uint id; // token id for EIP721 and EIP1155
uint id; // token id for ERC-721 and ERC-1155
uint amountInMax;
uint amountSource; // where to get the actual amountIn
}
Expand Down Expand Up @@ -469,7 +469,7 @@ The `Permit` type signature is not supported since the purpose of the Universal

### Tokens

Old token contracts (EIP-20, EIP-721 and EIP-1155) require approval for the Universal Token Router once for each account.
Old token contracts (ERC-20, ERC-721 and ERC-1155) require approval for the Universal Token Router once for each account.

New token contracts can pre-configure the Universal Token Router as a trusted spender, and no approval transaction is required.

Expand All @@ -479,7 +479,7 @@ Application contracts that use `msg.sender` as the beneficiary address in their

All application contracts that accept `recipient` (or `to`) argument instead of using `msg.sender` as the beneficiary address are compatible with the UTR out of the box.

Application contracts that transfer tokens (EIP-20, EIP-721, and EIP-1155) to `msg.sender` can use the UTR output token transfer sub-action to re-direct tokens to another `recipient` address.
Application contracts that transfer tokens (ERC-20, ERC-721, and ERC-1155) to `msg.sender` can use the `TRANSFER_FROM_ROUTER` input mode to re-direct tokens to another `recipient` address.

```javascript
// sample code to deposit WETH and transfer them out
Expand All @@ -504,11 +504,11 @@ UniversalTokenRouter.exec([{
data: encodeFunctionData('deposit', []), // WETH.deposit returns WETH token to the UTR contract
}, {
inputs: [{
mode: TRANSFER_FROM_ROUTER,
mode: TRANSFER_FROM_ROUTER, // transfer token out from this UTR contract
eip: 20,
token: WETH.address,
id: 0,
amountInMax: 0, // no limit
amountInMax: 123,
amountSource: AMOUNT_ALL, // entire WETH balance of this UTR contract
recipient: SomeRecipient,
}],
Expand Down Expand Up @@ -837,7 +837,7 @@ contract UniversalTokenRouter is IUniversalTokenRouter {

## Security Considerations

`ACTION_INJECT_CALL_RESULT` SHOULD only be used for gas optimization, not as trusted conditions. Application contract code MUST always expect arbitruary, malformed or mallicious data can be passed in where the call result `bytes` is expected.
`ACTION_INJECT_CALL_RESULT` SHOULD only be used for gas optimization, not as trusted conditions. Application contract code MUST always expect arbitruary, malformed or mallicious data can be passed in where the call result `bytes` is injected.

## Copyright

Expand Down

0 comments on commit 58cee57

Please sign in to comment.