From a59a8871fe10e53199669f41d7dd572fdc3400e3 Mon Sep 17 00:00:00 2001 From: Lasse Herskind <16536249+LHerskind@users.noreply.github.com> Date: Thu, 28 Oct 2021 20:28:03 +0100 Subject: [PATCH] fix: Remove stale implementation --- .../protocol/tokenization/StaticAToken.sol | 393 ------------------ 1 file changed, 393 deletions(-) delete mode 100644 contracts/protocol/tokenization/StaticAToken.sol diff --git a/contracts/protocol/tokenization/StaticAToken.sol b/contracts/protocol/tokenization/StaticAToken.sol deleted file mode 100644 index fe3df2d7..00000000 --- a/contracts/protocol/tokenization/StaticAToken.sol +++ /dev/null @@ -1,393 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.6.12; -pragma experimental ABIEncoderV2; - -import {ILendingPool} from '../../interfaces/ILendingPool.sol'; -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IAToken} from '../../interfaces/IAToken.sol'; -import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol'; -import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; - -/** - * @title StaticAToken - * @dev Wrapper token that allows to deposit tokens on the Aave protocol and receive - * a token which balance doesn't increase automatically, but uses an ever-increasing exchange rate - * - Only supporting deposits and withdrawals - * @author Aave - **/ -contract StaticAToken is ERC20 { - using SafeERC20 for IERC20; - using WadRayMath for uint256; - - struct SignatureParams { - uint8 v; - bytes32 r; - bytes32 s; - } - - 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_TYPEHASH = - keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); - bytes32 public constant METADEPOSIT_TYPEHASH = - keccak256( - 'Deposit(address depositor,address recipient,uint256 value,uint16 referralCode,bool fromUnderlying,uint256 nonce,uint256 deadline)' - ); - bytes32 public constant METAWITHDRAWAL_TYPEHASH = - keccak256( - 'Withdraw(address owner,address recipient,uint256 staticAmount, uint256 dynamicAmount, bool toUnderlying, uint256 nonce,uint256 deadline)' - ); - - ILendingPool public immutable LENDING_POOL; - IERC20 public immutable ATOKEN; - IERC20 public immutable ASSET; - - /// @dev owner => next valid nonce to submit with permit(), metaDeposit() and metaWithdraw() - /// We choose to have sequentiality on them for each user to avoid potentially dangerous/bad UX cases - mapping(address => uint256) public _nonces; - - constructor( - ILendingPool lendingPool, - address aToken, - string memory wrappedTokenName, - string memory wrappedTokenSymbol - ) public ERC20(wrappedTokenName, wrappedTokenSymbol) { - LENDING_POOL = lendingPool; - ATOKEN = IERC20(aToken); - - IERC20 underlyingAsset = IERC20(IAToken(aToken).UNDERLYING_ASSET_ADDRESS()); - ASSET = underlyingAsset; - underlyingAsset.approve(address(lendingPool), type(uint256).max); - } - - /** - * @dev Deposits `ASSET` in the Aave protocol and mints static aTokens to msg.sender - * @param recipient The address that will receive the static aTokens - * @param amount The amount of underlying `ASSET` to deposit (e.g. deposit of 100 USDC) - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param fromUnderlying bool - * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) - * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) - * @return uint256 The amount of StaticAToken minted, static balance - **/ - function deposit( - address recipient, - uint256 amount, - uint16 referralCode, - bool fromUnderlying - ) external returns (uint256) { - return _deposit(msg.sender, recipient, amount, referralCode, fromUnderlying); - } - - /** - * @dev Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET` - * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol - * @param amount The amount to withdraw, in static balance of StaticAToken - * @param toUnderlying bool - * - `true` for the recipient to get underlying tokens (e.g. USDC) - * - `false` for the recipient to get aTokens (e.g. aUSDC) - * @return amountToBurn: StaticATokens burnt, static balance - * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance - **/ - function withdraw( - address recipient, - uint256 amount, - bool toUnderlying - ) external returns (uint256, uint256) { - return _withdraw(msg.sender, recipient, amount, 0, toUnderlying); - } - - /** - * @dev Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET` - * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol - * @param amount The amount to withdraw, in dynamic balance of aToken/underlying asset - * @param toUnderlying bool - * - `true` for the recipient to get underlying tokens (e.g. USDC) - * - `false` for the recipient to get aTokens (e.g. aUSDC) - * @return amountToBurn: StaticATokens burnt, static balance - * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance - **/ - function withdrawDynamicAmount( - address recipient, - uint256 amount, - bool toUnderlying - ) external returns (uint256, uint256) { - return _withdraw(msg.sender, recipient, 0, amount, toUnderlying); - } - - /** - * @dev Implements the permit function as for - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param owner The owner of the funds - * @param spender The spender - * @param value The amount - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param v Signature param - * @param s Signature param - * @param r Signature param - * @param chainId Passing the chainId in order to be fork-compatible - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s, - uint256 chainId - ) external { - require(owner != address(0), 'INVALID_OWNER'); - //solium-disable-next-line - require(block.timestamp <= deadline, 'INVALID_EXPIRATION'); - uint256 currentValidNonce = _nonces[owner]; - bytes32 digest = - keccak256( - abi.encodePacked( - '\x19\x01', - getDomainSeparator(chainId), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline)) - ) - ); - require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE'); - _nonces[owner] = currentValidNonce.add(1); - _approve(owner, spender, value); - } - - /** - * @dev Allows to deposit on Aave via meta-transaction - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param depositor Address from which the funds to deposit are going to be pulled - * @param recipient Address that will receive the staticATokens, in the average case, same as the `depositor` - * @param value The amount to deposit - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param fromUnderlying bool - * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) - * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param sigParams Signature params: v,r,s - * @param chainId Passing the chainId in order to be fork-compatible - * @return uint256 The amount of StaticAToken minted, static balance - */ - function metaDeposit( - address depositor, - address recipient, - uint256 value, - uint16 referralCode, - bool fromUnderlying, - uint256 deadline, - SignatureParams calldata sigParams, - uint256 chainId - ) external returns (uint256) { - require(depositor != address(0), 'INVALID_DEPOSITOR'); - //solium-disable-next-line - require(block.timestamp <= deadline, 'INVALID_EXPIRATION'); - uint256 currentValidNonce = _nonces[depositor]; - bytes32 digest = - keccak256( - abi.encodePacked( - '\x19\x01', - getDomainSeparator(chainId), - keccak256( - abi.encode( - METADEPOSIT_TYPEHASH, - depositor, - recipient, - value, - referralCode, - fromUnderlying, - currentValidNonce, - deadline - ) - ) - ) - ); - require( - depositor == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), - 'INVALID_SIGNATURE' - ); - _nonces[depositor] = currentValidNonce.add(1); - _deposit(depositor, recipient, value, referralCode, fromUnderlying); - } - - /** - * @dev Allows to withdraw from Aave via meta-transaction - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param owner Address owning the staticATokens - * @param recipient Address that will receive the underlying withdrawn from Aave - * @param staticAmount The amount of staticAToken to withdraw. If > 0, `dynamicAmount` needs to be 0 - * @param dynamicAmount The amount of underlying/aToken to withdraw. If > 0, `staticAmount` needs to be 0 - * @param toUnderlying bool - * - `true` for the recipient to get underlying tokens (e.g. USDC) - * - `false` for the recipient to get aTokens (e.g. aUSDC) - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param sigParams Signature params: v,r,s - * @param chainId Passing the chainId in order to be fork-compatible - * @return amountToBurn: StaticATokens burnt, static balance - * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance - */ - function metaWithdraw( - address owner, - address recipient, - uint256 staticAmount, - uint256 dynamicAmount, - bool toUnderlying, - uint256 deadline, - SignatureParams calldata sigParams, - uint256 chainId - ) external returns (uint256, uint256) { - require(owner != address(0), 'INVALID_DEPOSITOR'); - //solium-disable-next-line - require(block.timestamp <= deadline, 'INVALID_EXPIRATION'); - uint256 currentValidNonce = _nonces[owner]; - bytes32 digest = - keccak256( - abi.encodePacked( - '\x19\x01', - getDomainSeparator(chainId), - keccak256( - abi.encode( - METAWITHDRAWAL_TYPEHASH, - owner, - recipient, - staticAmount, - dynamicAmount, - toUnderlying, - currentValidNonce, - deadline - ) - ) - ) - ); - require(owner == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), 'INVALID_SIGNATURE'); - _nonces[owner] = currentValidNonce.add(1); - return _withdraw(owner, recipient, staticAmount, dynamicAmount, toUnderlying); - } - - /** - * @dev Utility method to get the current aToken balance of an user, from his staticAToken balance - * @param account The address of the user - * @return uint256 The aToken balance - **/ - function dynamicBalanceOf(address account) external view returns (uint256) { - return staticToDynamicAmount(balanceOf(account)); - } - - /** - * @dev Converts a static amount (scaled balance on aToken) to the aToken/underlying value, - * using the current liquidity index on Aave - * @param amount The amount to convert from - * @return uint256 The dynamic amount - **/ - function staticToDynamicAmount(uint256 amount) public view returns (uint256) { - return amount.rayMul(rate()); - } - - /** - * @dev Converts an aToken or underlying amount to the what it is denominated on the aToken as - * scaled balance, function of the principal and the liquidity index - * @param amount The amount to convert from - * @return uint256 The static (scaled) amount - **/ - function dynamicToStaticAmount(uint256 amount) public view returns (uint256) { - return amount.rayDiv(rate()); - } - - /** - * @dev Returns the Aave liquidity index of the underlying aToken, denominated rate here - * as it can be considered as an ever-increasing exchange rate - * @return bytes32 The domain separator - **/ - function rate() public view returns (uint256) { - return LENDING_POOL.getReserveNormalizedIncome(address(ASSET)); - } - - /** - * @dev Function to return a dynamic domain separator, in order to be compatible with forks changing chainId - * @param chainId The chain id - * @return bytes32 The domain separator - **/ - function getDomainSeparator(uint256 chainId) public view returns (bytes32) { - return - keccak256( - abi.encode( - EIP712_DOMAIN, - keccak256(bytes(name())), - keccak256(EIP712_REVISION), - chainId, - address(this) - ) - ); - } - - function _deposit( - address depositor, - address recipient, - uint256 amount, - uint16 referralCode, - bool fromUnderlying - ) internal returns (uint256) { - require(recipient != address(0), 'INVALID_RECIPIENT'); - - if (fromUnderlying) { - ASSET.safeTransferFrom(depositor, address(this), amount); - LENDING_POOL.deposit(address(ASSET), amount, address(this), referralCode); - } else { - ATOKEN.safeTransferFrom(depositor, address(this), amount); - } - - uint256 amountToMint = dynamicToStaticAmount(amount); - _mint(recipient, amountToMint); - return amountToMint; - } - - function _withdraw( - address owner, - address recipient, - uint256 staticAmount, - uint256 dynamicAmount, - bool toUnderlying - ) internal returns (uint256, uint256) { - require(recipient != address(0), 'INVALID_RECIPIENT'); - require(staticAmount == 0 || dynamicAmount == 0, 'ONLY_ONE_AMOUNT_FORMAT_ALLOWED'); - - uint256 userBalance = balanceOf(owner); - - uint256 amountToWithdraw; - uint256 amountToBurn; - - uint256 currentRate = rate(); - if (staticAmount > 0) { - amountToBurn = (staticAmount > userBalance) ? userBalance : staticAmount; - amountToWithdraw = (staticAmount > userBalance) - ? _staticToDynamicAmount(userBalance, currentRate) - : _staticToDynamicAmount(staticAmount, currentRate); - } else { - uint256 dynamicUserBalance = _staticToDynamicAmount(userBalance, currentRate); - amountToWithdraw = (dynamicAmount > dynamicUserBalance) ? dynamicUserBalance : dynamicAmount; - amountToBurn = _dynamicToStaticAmount(amountToWithdraw, currentRate); - } - - _burn(owner, amountToBurn); - - if (toUnderlying) { - LENDING_POOL.withdraw(address(ASSET), amountToWithdraw, recipient); - } else { - ATOKEN.safeTransfer(recipient, amountToWithdraw); - } - - return (amountToBurn, amountToWithdraw); - } - - function _dynamicToStaticAmount(uint256 amount, uint256 rate) internal pure returns (uint256) { - return amount.rayDiv(rate); - } - - function _staticToDynamicAmount(uint256 amount, uint256 rate) internal pure returns (uint256) { - return amount.rayMul(rate); - } -}