Skip to content

Commit

Permalink
Merge pull request #2 from zlace0x/feat/refactor-rename
Browse files Browse the repository at this point in the history
refactor: rename event, function, change recoveryRate type & additional interfaces
  • Loading branch information
zlace0x authored Oct 28, 2022
2 parents e34f13d + 31bf394 commit d66419f
Showing 1 changed file with 129 additions and 33 deletions.
162 changes: 129 additions & 33 deletions EIPS/eip-5827.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,65 +31,161 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL
```solidity
pragma solidity ^0.8.0;
interface IERC5827 {
/// @notice Emitted when a new allowance is set.
/// @param _owner owner of token
/// @param _spender allowed spender of token
/// @param _value initial and maximum allowance given to spender
/// @param _recoveryRate recovery amount per second
event SetRenewableAllowance(
interface IERC5827 /* is ERC20, ERC165 */ {
/*
* Note: the ERC-165 identifier for this interface is 0x93cd7af6.
* 0x93cd7af6 ===
* bytes4(keccak256('approveRenewable(address,uint256,uint256)')) ^
* bytes4(keccak256('renewableAllowance(address,address)')) ^
* bytes4(keccak256('approve(address,uint256)') ^
* bytes4(keccak256('transferFrom(address,address,uint256)') ^
* bytes4(keccak256('allowance(address,address)') ^
*/
/*
* @notice Emitted when a new renewable allowance is set.
* @param _owner owner of token
* @param _spender allowed spender of token
* @param _value initial and maximum allowance given to spender
* @param _recoveryRate recovery amount per second
*/
event RenewableApproval(
address indexed _owner,
address indexed _spender,
uint256 _value,
uint192 _recoveryRate
uint256 _recoveryRate
);
/// @notice Grants an allowance of `_value` to `_spender` initially, which recovers over time based on `_recoveryRate` up to a limit of `_value`.
/// SHOULD throw when `_recoveryRate` is larger than `_value`.
/// MUST emit `SetRenewableAllowance` event.
/// @param _spender allowed spender of token
/// @param _value initial and maximum allowance given to spender
/// @param _recoveryRate recovery amount per second
function approve(
/*
* @notice Grants an allowance of `_value` to `_spender` initially, which recovers over time based on `_recoveryRate` up to a limit of `_value`.
* SHOULD throw when `_recoveryRate` is larger than `_value`.
* MUST emit `RenewableApproval` event.
* @param _spender allowed spender of token
* @param _value initial and maximum allowance given to spender
* @param _recoveryRate recovery amount per second
*/
function approveRenewable(
address _spender,
uint256 _value,
uint192 _recoveryRate
uint256 _recoveryRate
) external returns (bool success);
/// @notice Moves `amount` tokens from `from` to `to` using the
/// allowance mechanism. `amount` is then deducted from the caller's
/// allowance factoring in recovery rate logic.
/// SHOULD throw when there is insufficient allowance
/// @param from token owner address
/// @param to token recipient
/// @param amount amount of token to transfer
/// Overridden EIP-20 functions
/*
* @notice Returns approved max amount and recovery rate.
* @return amount initial and maximum allowance given to spender
* @return recoveryRate recovery amount per second
*/
function renewableAllowance(address _owner, address _spender)
external
view
returns (uint256 amount, uint256 recoveryRate);
/*
* @notice Grants a (non-increasing) allowance of _value to _spender.
* MUST clear set _recoveryRate to 0 on the corresponding renewable allowance, if any.
* @param _spender allowed spender of token
* @param _value allowance given to spender
*/
function approve(address _spender, uint256 _value)
external
returns (bool success);
/*
* @notice Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance factoring in recovery rate logic.
* SHOULD throw when there is insufficient allowance
* @param from token owner address
* @param to token recipient
* @param amount amount of token to transfer
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
/// @notice Returns amounts spendable by `_spender`.
/// @return remaining allowance at the current point in time
/*
* @notice Returns amounts spendable by `_spender`.
* @return remaining allowance at the current point in time
*/
function allowance(address _owner, address _spender)
external
view
returns (uint256 remaining);
}
```

Base method `approve(address _spender, uint256 _value)` MUST set `recoveryRate` to 0.

Both `allowance()` and `transferFrom()` MUST be updated to include allowance recovery logic.

`_value` within `approveRenewable(address _spender, uint256 _value, uint256 _recoveryRate)` method sets both initial allowance amount and the maximum allowance limit it can regain to.

### Additional interfaces

Existing EIP-20 tokens can delegate allowance enforcement to a proxy contract that implements this specification. Additional query function exist to get the underlying EIP-20 token.

/// @notice Returns approved max amount and recovery rate.
/// @return amount initial and maximum allowance given to spender
/// @return recoveryRate recovery amount per second
```solidity
interface IERC5827Proxy {
/*
* Note: the ERC-165 identifier for this interface is 0xc55dae63.
* 0xc55dae63 ===
* bytes4(keccak256('baseToken()')
*/
/*
* @notice Get the underlying base token being proxied.
* @returns baseToken address of the base token
*/
function baseToken() external view returns (address);
}
```

Automatic Expiration

```solidity
interface IERC5827Expirable {
/*
* Note: the ERC-165 identifier for this interface is 0x46c5b619.
* 0x46c5b619 ===
* bytes4(keccak256('approveRenewable(address,uint256,uint256,uint64)')) ^
* bytes4(keccak256('renewableAllowance(address,address)')) ^
*/
/*
* @notice Grants an allowance of `_value` to `_spender` initially, which recovers over time based on `_recoveryRate` up to a limit of `_value`. The allowance expires at `_expiration`.
* SHOULD throw when `_recoveryRate` is larger than `_value`.
* MUST emit `RenewableApproval` event.
* @param _spender allowed spender of token
* @param _value initial allowance given to spender
* @param _recoveryRate recovery amount per second
* @param _expiration time in which the allowance expires
*/
function approveRenewable(
address _spender,
uint256 _value,
uint256 _recoveryRate,
uint64 _expiration
) external returns (bool success);
/*
* @notice Returns approved max amount and recovery rate.
* @return amount initial and maximum allowance given to spender
* @return recoveryRate recovery amount per second
* @return expiration time in which the allowance expires
*/
function renewableAllowance(address _owner, address _spender)
external
view
returns (uint256 amount, uint192 recoveryRate);
returns (uint256 amount, uint256 recoveryRate, uint64 expiration);
}
```

Base method `approve(address _spender, uint256 _value)` MAY emit `SetRenewableAllowance` with a `recoveryRate` of 0.

Both `allowance()` and `transferFrom()` MUST be updated to include allowance recovery logic.

## Rationale

Renewable allowances can be implemented with discrete resets per time cycle. However, a continuous `recoveryRate` allows for more flexible use cases not bound by reset cycles and can be implemented with simpler logic.
Expand Down

0 comments on commit d66419f

Please sign in to comment.