Skip to content

Commit

Permalink
Correct format and language.
Browse files Browse the repository at this point in the history
  • Loading branch information
cygnusv committed Mar 24, 2022
1 parent 2602b81 commit 8484572
Showing 1 changed file with 25 additions and 28 deletions.
53 changes: 25 additions & 28 deletions EIPS/eip-4931.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The following standard allows for the implementation of a standard API for ERC20

## Motivation

Token contract upgrades typically require each asset holder to exchange their old tokens for new ones using a bespoke interface provided by the developers.This standard interface will allow asset holders as well as centralized and decentralized exchanges to conduct token upgrades more efficiently since token contract upgrade scripts will be essentially reusable. Standardization will reduce the security overhead involved in verifying the functionality of the upgrade contracts. It will also provide asset issuers clear guidance on how to effectively implement a token upgrade.
Token contract upgrades typically require each asset holder to exchange their old tokens for new ones using a bespoke interface provided by the developers. This standard interface will allow asset holders as well as centralized and decentralized exchanges to conduct token upgrades more efficiently since token contract upgrade scripts will be essentially reusable. Standardization will reduce the security overhead involved in verifying the functionality of the upgrade contracts. It will also provide asset issuers clear guidance on how to effectively implement a token upgrade.

## 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.
Expand All @@ -30,7 +30,7 @@ interface IEIP4931 {
```
#### Methods

#### upgradeSource
##### upgradeSource

Returns the address of the original (source) token that will be upgraded.

Expand All @@ -40,7 +40,7 @@ Returns the address of the original (source) token that will be upgraded.
function upgradeSource() external view returns(address)
```

#### upgradeDestination
##### upgradeDestination

Returns the address of the token contract that is being upgraded to.

Expand All @@ -50,27 +50,27 @@ Returns the address of the token contract that is being upgraded to.
function upgradeDestination() external view returns(address)
```

#### isUpgradeActive
##### isUpgradeActive

Returns the current status of the upgrade contract. Status MUST return "true" when the upgrade contract is functional and serving upgrades. It MUST return "false" when the upgrade contract is not currently serving upgrades.
Returns the current status of the upgrade functionality. Status MUST return `true` when the upgrade contract is functional and serving upgrades. It MUST return `false` when the upgrade contract is not currently serving upgrades.

``` solidity
/// @dev The method will return true when the contract is serving upgrades and otherwise false
/// @return The status of the upgrade as a boolean
function isUpgradeActive() external view returns(bool)
```
#### isDowngradeActive
##### isDowngradeActive

Returns the current status of the downgrade functionality. Status MUST return true when the upgrade contract is functional and serving downgrades. It MUST return false when the upgrade contract is not currently serving downgrades. When the downgrade Optional Ext. is not implemented, this method will always return false to signify downgrades are not available.
Returns the current status of the downgrade functionality. Status MUST return `true` when the upgrade contract is functional and serving downgrades. It MUST return `false` when the upgrade contract is not currently serving downgrades. When the downgrade Optional Ext. is not implemented, this method will always return `false` to signify downgrades are not available.

``` solidity
/// @dev The method will return true when the contract is serving downgrades and otherwise false
/// @return The status of the downgrade as a boolean
function isDowngradeActive() external view returns(bool)
```
#### ratio
##### ratio

Returns the ratio of destination token to source token that the upgrade will use. E.g. ```(3, 1)``` means the upgrade will provide 3 destination tokens for every 1 source token being upgraded.
Returns the ratio of destination token to source token, expressed as a 2-tuple, that the upgrade will use. E.g. `(3, 1)` means the upgrade will provide 3 destination tokens for every 1 source token being upgraded.

``` solidity
/// @dev A getter for the ratio of destination tokens to source tokens received when conducting an upgrade
Expand All @@ -79,19 +79,19 @@ Returns the ratio of destination token to source token that the upgrade will use
function ratio() external view returns(uint256, uint256)
```

#### totalUpgraded
##### totalUpgraded

Returns the total number of tokens that have been upgraded from source to destination. If the downgrade Optional Ext. is implemented, calls to ```downgrade``` will reduce the ```totalUpgraded``` return value making it possible for the value to decrease between calls. The return value will be strictly increasing if downgrades are not implemented.
Returns the total number of tokens that have been upgraded from source to destination. If the downgrade Optional Ext. is implemented, calls to `downgrade` will reduce the `totalUpgraded` return value making it possible for the value to decrease between calls. The return value will be strictly increasing if downgrades are not implemented.

``` solidity
/// @dev A getter for the total amount of source tokens that have been upgraded to destination tokens.
/// The value may not be strictly increasing if the downgrade Optional Ext. is implemented.
/// @return The number of source tokens that have been upgraded to destination tokens
function totalUpgraded() external view returns(uint256)
```
#### computeUpgrade
##### computeUpgrade

Computes the `destinationAmount` of destination tokens that correspond to a given `sourceAmount` of source tokens, according to the predefined conversion ratio, as well as the `sourceRemainder` amount of source tokens that can't be upgraded. For example, let's consider a (3, 2) ratio, which means that 3 destination tokens are provided for every 2 source tokens; then, for a source amount of 5 tokens, `computeUpgrade(5)` should return `(6, 1)`, meaning that 6 destination tokens are expected (in this case, from 4 source tokens) and 1 source token is left as remainder.
Computes the `destinationAmount` of destination tokens that correspond to a given `sourceAmount` of source tokens, according to the predefined conversion ratio, as well as the `sourceRemainder` amount of source tokens that can't be upgraded. For example, let's consider a (3, 2) ratio, which means that 3 destination tokens are provided for every 2 source tokens; then, for a source amount of 5 tokens, `computeUpgrade(5)` must return `(6, 1)`, meaning that 6 destination tokens are expected (in this case, from 4 source tokens) and 1 source token is left as remainder.
``` solidity
/// @dev A method to mock the upgrade call determining the amount of destination tokens received from an upgrade
/// as well as the amount of source tokens that are left over as remainder
Expand All @@ -102,9 +102,9 @@ function computeUpgrade(uint256 sourceAmount) external view
returns (uint256 destinationAmount, uint256 sourceRemainder)
```

#### computeDowngrade (Optional Ext.)
##### computeDowngrade (Optional Ext.)

Computes the `sourceAmount` of source tokens that correspond to a given `destinationAmount` of destination tokens, according to the predefined conversion ratio, as well as the `destinationRemainder` amount of destination tokens that can't be downgraded. For example, let's consider a (3, 2) ratio, which means that 3 destination tokens are provided for every 2 source tokens; for a destination amount of 13 tokens, `computeDowngrade(13)` should return `(4, 1)`, meaning that 4 source tokens are expected (in this case, from 12 destination tokens) and 1 destination token is left as remainder.
Computes the `sourceAmount` of source tokens that correspond to a given `destinationAmount` of destination tokens, according to the predefined conversion ratio, as well as the `destinationRemainder` amount of destination tokens that can't be downgraded. For example, let's consider a (3, 2) ratio, which means that 3 destination tokens are provided for every 2 source tokens; for a destination amount of 13 tokens, `computeDowngrade(13)` must return `(4, 1)`, meaning that 4 source tokens are expected (in this case, from 12 destination tokens) and 1 destination token is left as remainder.
``` solidity
/// @dev A method to mock the downgrade call determining the amount of source tokens received from a downgrade
/// as well as the amount of destination tokens that are left over as remainder
Expand All @@ -116,9 +116,9 @@ function computeDowngrade(uint256 destinationAmount) external view
```


#### upgrade
##### upgrade

Upgrades the `amount` of source token to the destination token in the specified ratio. The destination tokens will be sent to the ```_to``` address. The function MUST lock the source tokens in the upgrade contract or burn them. If the downgrade Optional Ext. is implemented, the source tokens MUST be locked instead of burning. The function MUST `throw` if the caller's address does not have enough source token to upgrade or if ```isUpgradeActive``` is returning ```false```. The function MUST also fire the `Upgrade` event. `approve` MUST be called first on the source contract.
Upgrades the `amount` of source token to the destination token in the specified ratio. The destination tokens will be sent to the `_to` address. The function MUST lock the source tokens in the upgrade contract or burn them. If the downgrade Optional Ext. is implemented, the source tokens MUST be locked instead of burning. The function MUST `throw` if the caller's address does not have enough source token to upgrade or if `isUpgradeActive` is returning `false`. The function MUST also fire the `Upgrade` event. `approve` MUST be called first on the source contract.
``` solidity
/// @dev A method to conduct an upgrade from source token to destination token.
/// The call will fail if upgrade status is not true, if approve has not been called
Expand All @@ -132,8 +132,8 @@ function upgrade(address _to, uint256 sourceAmount) external
```


#### downgrade (Optional Ext.)
Downgrades the `amount` of destination token to the source token in the specified ratio. The source tokens will be sent to the ```_to``` address. The function MUST unwrap the destination tokens back to the source tokens. The function MUST `throw` if the caller's address does not have enough destination token to downgrade or if ```isDowngradeActive``` is returning ```false```. The function MUST also fire the `Downgrade` event. `approve` MUST be called first on the destination contract.
##### downgrade (Optional Ext.)
Downgrades the `amount` of destination token to the source token in the specified ratio. The source tokens will be sent to the `_to` address. The function MUST unwrap the destination tokens back to the source tokens. The function MUST `throw` if the caller's address does not have enough destination token to downgrade or if `isDowngradeActive` is returning `false`. The function MUST also fire the `Downgrade` event. `approve` MUST be called first on the destination contract.
``` solidity
/// @dev A method to conduct a downgrade from destination token to source token.
/// The call will fail if downgrade status is not true, if approve has not been called
Expand All @@ -146,9 +146,9 @@ Downgrades the `amount` of destination token to the source token in the specifie
function downgrade(address _to, uint256 destinationAmount) external
```

### Events
#### Events

#### Upgrade
##### Upgrade

MUST trigger when tokens are upgraded.

Expand All @@ -160,7 +160,7 @@ MUST trigger when tokens are upgraded.
event Upgrade(address indexed _from, address indexed _to, uint256 sourceAmount, uint256 destinationAmount)
```

#### Downgrade (Optional Ext.)
##### Downgrade (Optional Ext.)

MUST trigger when tokens are downgraded.

Expand All @@ -174,13 +174,10 @@ event Downgrade(address indexed _from, address indexed _to, uint256 sourceAmount
```

## Rationale
There have been several notable ERC20 upgrades (Ex. Golem: GNT -> GLM) where the upgrade functionality is written directly into the token contracts. We view this as a suboptimal approach to upgrades since it tightly couples the upgrade with the existing tokens. This EIP promotes the use of a third contract to facilitate the token upgrade to decouple the functionality of the upgrade from the functionality of the token contracts. Standardizing the upgrade functionality will allow asset holders and exchanges to write simplified reusable scripts to conduct upgrades which will reduce the overhead of conducting upgrades in the future. The interface aims to be intentionally broad leaving much of the specifics of the upgrade to the implementer, so that the token contract implementations do not interfere with the upgrade process. Finally, we hope to create a greater sense of security and validity for token upgrades by enforcing strict means of disposing of the source tokens during the upgrade. This is achieved by the specification of the ```upgrade``` method. The agreed upon norm is that burnable tokens shall be burned. Otherwise, tokens shall be effectively burned by being sent to the ```0x00``` address. When downgrade Optional Ext. is implemented, the default is instead to lock source tokens in the upgrade contract to avoid a series of consecutive calls to ```upgrade``` and ```downgrade``` from artificially inflating the supply of either token (source or destination).
There have been several notable ERC20 upgrades (Ex. Golem: GNT -> GLM) where the upgrade functionality is written directly into the token contracts. We view this as a suboptimal approach to upgrades since it tightly couples the upgrade with the existing tokens. This EIP promotes the use of a third contract to facilitate the token upgrade to decouple the functionality of the upgrade from the functionality of the token contracts. Standardizing the upgrade functionality will allow asset holders and exchanges to write simplified reusable scripts to conduct upgrades which will reduce the overhead of conducting upgrades in the future. The interface aims to be intentionally broad leaving much of the specifics of the upgrade to the implementer, so that the token contract implementations do not interfere with the upgrade process. Finally, we hope to create a greater sense of security and validity for token upgrades by enforcing strict means of disposing of the source tokens during the upgrade. This is achieved by the specification of the `upgrade` method. The agreed upon norm is that burnable tokens shall be burned. Otherwise, tokens shall be effectively burned by being sent to the `0x00` address. When downgrade Optional Ext. is implemented, the default is instead to lock source tokens in the upgrade contract to avoid a series of consecutive calls to `upgrade` and `downgrade` from artificially inflating the supply of either token (source or destination).

## Backwards Compatibility
There are no breaking backwards compatibility issues. There are previously implemented token upgrades that likely do not adhere to this standard. In these cases, it may be relevant for the asset issuers to communicate that their upgrade is not EIP4931 compliant.

## Test Cases
WIP
There are no breaking backwards compatibility issues. There are previously implemented token upgrades that likely do not adhere to this standard. In these cases, it may be relevant for the asset issuers to communicate that their upgrade is not EIP-4931 compliant.

## Reference Implementation
``` solidity
Expand Down Expand Up @@ -346,7 +343,7 @@ contract SourceUpgrade is IEIP4931 {


## Security Considerations
The main security consideration is ensuring the implementation of the interface handles the source tokens during the upgrade in such a way that they are no longer accessible. Without careful handling, the validity of the upgrade may come into question since source tokens could potentially be upgraded multiple times. This is why EIP-XXXX will strictly enforce the use of ```burn``` for source tokens that are burnable. For non-burnable tokens, the accepted method is to send the source tokens to the ```0x00``` address. When the downgrade Optional Ext. is implemented, the constraint will be relaxed, so that the source tokens can be held by the upgrade contract.
The main security consideration is ensuring the implementation of the interface handles the source tokens during the upgrade in such a way that they are no longer accessible. Without careful handling, the validity of the upgrade may come into question since source tokens could potentially be upgraded multiple times. This is why EIP-4931 will strictly enforce the use of `burn` for source tokens that are burnable. For non-burnable tokens, the accepted method is to send the source tokens to the `0x00` address. When the downgrade Optional Ext. is implemented, the constraint will be relaxed, so that the source tokens can be held by the upgrade contract.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Expand Down

0 comments on commit 8484572

Please sign in to comment.