Added ERC20 proxy

This commit is contained in:
The3D 2020-10-13 13:21:11 +02:00
parent 6839be6dca
commit 1b4bc6f855
3 changed files with 102 additions and 10 deletions

View File

@ -7,8 +7,8 @@ import {
VersionedInitializable
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
import {
InitializableImmutableAdminUpgradeabilityProxy
} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
ERC20InitializableImmutableAdminUpgradeabilityProxy
} from '../libraries/aave-upgradeability/ERC20InitializableImmutableAdminUpgradeabilityProxy.sol';
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
@ -479,7 +479,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
emit ReserveBaseLtvChanged(asset, ltv);
}
/**
/**
* @dev updates the reserve factor of a reserve
* @param asset the address of the reserve
* @param reserveFactor the new reserve factor of the reserve
@ -494,7 +494,6 @@ contract LendingPoolConfigurator is VersionedInitializable {
emit ReserveFactorChanged(asset, reserveFactor);
}
/**
* @dev updates the liquidation threshold of a reserve.
* @param asset the address of the reserve
@ -559,7 +558,9 @@ contract LendingPoolConfigurator is VersionedInitializable {
* @param decimals the decimals of the token
**/
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
InitializableImmutableAdminUpgradeabilityProxy proxy = new InitializableImmutableAdminUpgradeabilityProxy(address(this));
ERC20InitializableImmutableAdminUpgradeabilityProxy proxy
= new ERC20InitializableImmutableAdminUpgradeabilityProxy(address(this));
bytes memory params = abi.encodeWithSignature(
'initialize(uint8,string,string)',
@ -578,9 +579,9 @@ contract LendingPoolConfigurator is VersionedInitializable {
address proxyAddress,
address implementation
) internal {
InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(
payable(proxyAddress)
);
ERC20InitializableImmutableAdminUpgradeabilityProxy proxy
= ERC20InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
(uint256 decimals, , , , , , , , , , ) = pool.getReserveConfigurationData(asset);

View File

@ -4,9 +4,11 @@ pragma solidity ^0.6.8;
import '../openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol';
/**
* @title BaseAdminUpgradeabilityProxy
* @title BaseImmutableAdminUpgradeabilityProxy
* @author Aave, inspired by the OpenZeppelin upgradeability proxy pattern
* @dev This contract combines an upgradeability proxy with an authorization
* mechanism for administrative tasks.
* mechanism for administrative tasks. The admin role is stored in an immutable, which
* helps saving transactions costs
* All external functions in this contract must be guarded by the
* `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
* feature proposal that would enable this to be done automatically.

View File

@ -0,0 +1,89 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import './InitializableImmutableAdminUpgradeabilityProxy.sol';
import '../openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol';
/**
* @title ERC20InitializableImmutableAdminUpgradeabilityProxy
* @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for
* initializing the implementation, admin, and init data.
* It also implement native functions to map the ERC20 calls, to further save gas
* by directly calling the implementation.
*/
contract ERC20InitializableImmutableAdminUpgradeabilityProxy is
InitializableImmutableAdminUpgradeabilityProxy
{
constructor(address admin) public InitializableImmutableAdminUpgradeabilityProxy(admin) {}
function totalSupply() external view returns (uint256) {
abi.decode(_delegateView(abi.encodeWithSignature('totalSupply()')), (uint256));
}
function balanceOf(address account) external view returns (uint256) {
abi.decode(_delegateView(abi.encodeWithSignature('balanceOf(address)', account)), (uint256));
}
function transfer(address recipient, uint256 amount) external returns (bool) {
abi.decode(
_delegateToImpl(abi.encodeWithSignature('balanceOf(address,uint256)', recipient, amount)),
(bool)
);
}
function allowance(address owner, address spender) external view returns (uint256) {
abi.decode(
_delegateView(abi.encodeWithSignature('allowance(address,address)', owner, spender)),
(uint256)
);
}
function approve(address spender, uint256 amount) external returns (bool) {
abi.decode(
_delegateToImpl(abi.encodeWithSignature('approve(address,uint256)', spender, amount)),
(bool)
);
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool) {
abi.decode(
_delegateToImpl(
abi.encodeWithSignature('transferFrom(address,address,uint256)', sender, recipient, amount)
),
(bool)
);
}
/**
* @notice Delegates execution to an implementation contract
* @dev It returns to the external caller whatever the implementation returns or forwards reverts
* There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.
* @param data The raw data to delegatecall
* @return The returned bytes from the delegatecall
*/
function _delegateView(bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returnData) = address(this).staticcall(
abi.encodeWithSignature('delegateToImpl(bytes)', data)
);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
}
return returnData;
}
function _delegateToImpl(bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returnData) = _implementation().delegatecall(data);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
}
return returnData;
}
}