feat: added permitDelegation functions to stable and variable debt tokens

This commit is contained in:
Hadrien Charlanes 2021-07-05 12:03:06 +02:00
parent fce470cfb7
commit 3aacd06fff
4 changed files with 186 additions and 0 deletions

View File

@ -69,6 +69,26 @@ interface IStableDebtToken is IInitializableDebtToken {
uint256 rate
) external returns (bool);
/**
* @dev implements the credit delegation with ERC712 signature
* @param delegator The delegator of the credit
* @param delegatee The delegatee that can use the credit
* @param value The amount to be delegated
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permitDelegation(
address delegator,
address delegatee,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Burns debt of `user`
* - The resulting rate is the weighted average between the rate of the new debt

View File

@ -36,6 +36,26 @@ interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken {
uint256 index
) external returns (bool);
/**
* @dev implements the credit delegation with ERC712 signature
* @param delegator The delegator of the credit
* @param delegatee The delegatee that can use the credit
* @param value The amount to be delegated
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permitDelegation(
address delegator,
address delegatee,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Emitted when variable debt is burnt
* @param user The user which debt has been burned

View File

@ -18,6 +18,14 @@ import {Errors} from '../libraries/helpers/Errors.sol';
contract StableDebtToken is IStableDebtToken, DebtTokenBase {
using WadRayMath for uint256;
bytes public constant EIP712_REVISION = bytes('1');
bytes32 internal constant EIP712_DOMAIN =
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');
bytes32 public constant PERMIT_DELEGATION_TYPEHASH =
keccak256(
'PermitDelegation(address delegator,address delegatee,uint256 value,uint256 nonce,uint256 deadline)'
);
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
uint256 internal _avgStableRate;
@ -29,6 +37,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
address internal _underlyingAsset;
IAaveIncentivesController internal _incentivesController;
mapping(address => uint256) public _nonces;
bytes32 public DOMAIN_SEPARATOR;
/**
* @dev Initializes the debt token.
* @param pool The address of the lending pool where this aToken will be used
@ -47,6 +58,13 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
string memory debtTokenSymbol,
bytes calldata params
) public override initializer {
uint256 chainId;
//solium-disable-next-line
assembly {
chainId := chainid()
}
_setName(debtTokenName);
_setSymbol(debtTokenSymbol);
_setDecimals(debtTokenDecimals);
@ -55,6 +73,16 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
_underlyingAsset = underlyingAsset;
_incentivesController = incentivesController;
DOMAIN_SEPARATOR = keccak256(
abi.encode(
EIP712_DOMAIN,
keccak256(bytes(debtTokenName)),
keccak256(EIP712_REVISION),
chainId,
address(this)
)
);
emit Initialized(
underlyingAsset,
address(pool),
@ -256,6 +284,51 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
emit Transfer(user, address(0), amount);
}
/**
* @dev implements the credit delegation with ERC712 signature
* @param delegator The delegator of the credit
* @param delegatee The delegatee that can use the credit
* @param value The amount to be delegated
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permitDelegation(
address delegator,
address delegatee,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require(delegator != address(0), 'INVALID_DELEGATOR');
//solium-disable-next-line
require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
uint256 currentValidNonce = _nonces[delegator];
bytes32 digest =
keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(
abi.encode(
PERMIT_DELEGATION_TYPEHASH,
delegator,
delegatee,
value,
currentValidNonce,
deadline
)
)
)
);
require(delegator == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
_nonces[delegator] = currentValidNonce.add(1);
_approveDelegation(delegator, delegatee, value);
}
/**
* @dev Calculates the increase in balance since the last user interaction
* @param user The address of the user for which the interest is being accumulated

View File

@ -17,12 +17,23 @@ import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesControl
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
using WadRayMath for uint256;
bytes public constant EIP712_REVISION = bytes('1');
bytes32 internal constant EIP712_DOMAIN =
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');
bytes32 public constant PERMIT_DELEGATION_TYPEHASH =
keccak256(
'PermitDelegation(address delegator,address delegatee,uint256 value,uint256 nonce,uint256 deadline)'
);
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
ILendingPool internal _pool;
address internal _underlyingAsset;
IAaveIncentivesController internal _incentivesController;
mapping(address => uint256) public _nonces;
bytes32 public DOMAIN_SEPARATOR;
/**
* @dev Initializes the debt token.
* @param pool The address of the lending pool where this aToken will be used
@ -41,6 +52,13 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
string memory debtTokenSymbol,
bytes calldata params
) public override initializer {
uint256 chainId;
//solium-disable-next-line
assembly {
chainId := chainid()
}
_setName(debtTokenName);
_setSymbol(debtTokenSymbol);
_setDecimals(debtTokenDecimals);
@ -49,6 +67,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
_underlyingAsset = underlyingAsset;
_incentivesController = incentivesController;
DOMAIN_SEPARATOR = keccak256(
abi.encode(
EIP712_DOMAIN,
keccak256(bytes(debtTokenName)),
keccak256(EIP712_REVISION),
chainId,
address(this)
)
);
emit Initialized(
underlyingAsset,
address(pool),
@ -135,6 +163,51 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
emit Burn(user, amount, index);
}
/**
* @dev implements the credit delegation with ERC712 signature
* @param delegator The delegator of the credit
* @param delegatee The delegatee that can use the credit
* @param value The amount to be delegated
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permitDelegation(
address delegator,
address delegatee,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require(delegator != address(0), 'INVALID_DELEGATOR');
//solium-disable-next-line
require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
uint256 currentValidNonce = _nonces[delegator];
bytes32 digest =
keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(
abi.encode(
PERMIT_DELEGATION_TYPEHASH,
delegator,
delegatee,
value,
currentValidNonce,
deadline
)
)
)
);
require(delegator == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
_nonces[delegator] = currentValidNonce.add(1);
_approveDelegation(delegator, delegatee, value);
}
/**
* @dev Returns the principal debt balance of the user from
* @return The debt balance of the user since the last burn/mint action