// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;/**
* @dev Collection of functions related to the address type
*/libraryAddress{
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned// for accounts without code, i.e. `keccak256('')`bytes32 codehash;
bytes32 accountHash =0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assemblyassembly {
codehash :=extcodehash(account)
}
return (codehash != accountHash && codehash !=0x0);
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, 'Address: insufficient balance');
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{value: amount}('');
require(success, 'Address: unable to send value, recipient may have reverted');
}
}
Contract Source Code
File 2 of 6: BaseImmutableAdminUpgradeabilityProxy.sol
// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;import {BaseUpgradeabilityProxy} from'../../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol';
/**
* @title BaseImmutableAdminUpgradeabilityProxy
* @author Aave, inspired by the OpenZeppelin upgradeability proxy pattern
* @notice This contract combines an upgradeability proxy with an authorization
* mechanism for administrative tasks.
* @dev 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.
*/contractBaseImmutableAdminUpgradeabilityProxyisBaseUpgradeabilityProxy{
addressinternalimmutable _admin;
/**
* @dev Constructor.
* @param admin The address of the admin
*/constructor(address admin) {
_admin = admin;
}
modifierifAdmin() {
if (msg.sender== _admin) {
_;
} else {
_fallback();
}
}
/**
* @notice Return the admin address
* @return The address of the proxy admin.
*/functionadmin() externalifAdminreturns (address) {
return _admin;
}
/**
* @notice Return the implementation address
* @return The address of the implementation.
*/functionimplementation() externalifAdminreturns (address) {
return _implementation();
}
/**
* @notice Upgrade the backing implementation of the proxy.
* @dev Only the admin can call this function.
* @param newImplementation The address of the new implementation.
*/functionupgradeTo(address newImplementation) externalifAdmin{
_upgradeTo(newImplementation);
}
/**
* @notice Upgrade the backing implementation of the proxy and call a function
* on the new implementation.
* @dev This is useful to initialize the proxied contract.
* @param newImplementation The address of the new implementation.
* @param data Data to send as msg.data in the low level call.
* It should include the signature and the parameters of the function to be called, as described in
* https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
*/functionupgradeToAndCall(address newImplementation,
bytescalldata data
) externalpayableifAdmin{
_upgradeTo(newImplementation);
(bool success, ) = newImplementation.delegatecall(data);
require(success);
}
/**
* @notice Only fall back when the sender is not the admin.
*/function_willFallback() internalvirtualoverride{
require(msg.sender!= _admin, 'Cannot call fallback function from the proxy admin');
super._willFallback();
}
}
Contract Source Code
File 3 of 6: BaseUpgradeabilityProxy.sol
// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;import'./Proxy.sol';
import'../contracts/Address.sol';
/**
* @title BaseUpgradeabilityProxy
* @dev This contract implements a proxy that allows to change the
* implementation address to which it will delegate.
* Such a change is called an implementation upgrade.
*/contractBaseUpgradeabilityProxyisProxy{
/**
* @dev Emitted when the implementation is upgraded.
* @param implementation Address of the new implementation.
*/eventUpgraded(addressindexed implementation);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/bytes32internalconstant IMPLEMENTATION_SLOT =0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation.
* @return impl Address of the current implementation
*/function_implementation() internalviewoverridereturns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
//solium-disable-next-lineassembly {
impl :=sload(slot)
}
}
/**
* @dev Upgrades the proxy to a new implementation.
* @param newImplementation Address of the new implementation.
*/function_upgradeTo(address newImplementation) internal{
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Sets the implementation address of the proxy.
* @param newImplementation Address of the new implementation.
*/function_setImplementation(address newImplementation) internal{
require(
Address.isContract(newImplementation),
'Cannot set a proxy implementation to a non-contract address'
);
bytes32 slot = IMPLEMENTATION_SLOT;
//solium-disable-next-lineassembly {
sstore(slot, newImplementation)
}
}
}
Contract Source Code
File 4 of 6: InitializableImmutableAdminUpgradeabilityProxy.sol
// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;import {InitializableUpgradeabilityProxy} from'../../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol';
import {Proxy} from'../../../dependencies/openzeppelin/upgradeability/Proxy.sol';
import {BaseImmutableAdminUpgradeabilityProxy} from'./BaseImmutableAdminUpgradeabilityProxy.sol';
/**
* @title InitializableAdminUpgradeabilityProxy
* @author Aave
* @dev Extends BaseAdminUpgradeabilityProxy with an initializer function
*/contractInitializableImmutableAdminUpgradeabilityProxyisBaseImmutableAdminUpgradeabilityProxy,
InitializableUpgradeabilityProxy{
/**
* @dev Constructor.
* @param admin The address of the admin
*/constructor(address admin) BaseImmutableAdminUpgradeabilityProxy(admin) {
// Intentionally left blank
}
/// @inheritdoc BaseImmutableAdminUpgradeabilityProxyfunction_willFallback() internaloverride(BaseImmutableAdminUpgradeabilityProxy, Proxy) {
BaseImmutableAdminUpgradeabilityProxy._willFallback();
}
}
Contract Source Code
File 5 of 6: InitializableUpgradeabilityProxy.sol
// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;import'./BaseUpgradeabilityProxy.sol';
/**
* @title InitializableUpgradeabilityProxy
* @dev Extends BaseUpgradeabilityProxy with an initializer for initializing
* implementation and init data.
*/contractInitializableUpgradeabilityProxyisBaseUpgradeabilityProxy{
/**
* @dev Contract initializer.
* @param _logic Address of the initial implementation.
* @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
* It should include the signature and the parameters of the function to be called, as described in
* https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
* This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
*/functioninitialize(address _logic, bytesmemory _data) publicpayable{
require(_implementation() ==address(0));
assert(IMPLEMENTATION_SLOT ==bytes32(uint256(keccak256('eip1967.proxy.implementation')) -1));
_setImplementation(_logic);
if (_data.length>0) {
(bool success, ) = _logic.delegatecall(_data);
require(success);
}
}
}
Contract Source Code
File 6 of 6: Proxy.sol
// SPDX-License-Identifier: AGPL-3.0pragmasolidity 0.8.10;/**
* @title Proxy
* @dev Implements delegation of calls to other contracts, with proper
* forwarding of return values and bubbling of failures.
* It defines a fallback function that delegates all calls to the address
* returned by the abstract _implementation() internal function.
*/abstractcontractProxy{
/**
* @dev Fallback function.
* Will run if no other function in the contract matches the call data.
* Implemented entirely in `_fallback`.
*/fallback() externalpayable{
_fallback();
}
/**
* @return The Address of the implementation.
*/function_implementation() internalviewvirtualreturns (address);
/**
* @dev Delegates execution to an implementation contract.
* This is a low level function that doesn't return to its internal call site.
* It will return to the external caller whatever the implementation returns.
* @param implementation Address to delegate.
*/function_delegate(address implementation) internal{
//solium-disable-next-lineassembly {
// Copy msg.data. We take full control of memory in this inline assembly// block because it will not return to Solidity code. We overwrite the// Solidity scratch pad at memory position 0.calldatacopy(0, 0, calldatasize())
// Call the implementation.// out and outsize are 0 because we don't know the size yet.let result :=delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.case0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev Function that is run as the first thing in the fallback function.
* Can be redefined in derived contracts to add functionality.
* Redefinitions must call super._willFallback().
*/function_willFallback() internalvirtual{}
/**
* @dev fallback implementation.
* Extracted to enable manual triggering.
*/function_fallback() internal{
_willFallback();
_delegate(_implementation());
}
}