mirror of
				https://github.com/Instadapp/aave-protocol-v2.git
				synced 2024-07-29 21:47:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
| // SPDX-License-Identifier: agpl-3.0
 | |
| pragma solidity ^0.6.8;
 | |
| 
 | |
| import './UpgradeabilityProxy.sol';
 | |
| 
 | |
| /**
 | |
|  * @title BaseAdminUpgradeabilityProxy
 | |
|  * @dev This contract combines an upgradeability proxy with an authorization
 | |
|  * mechanism for administrative tasks.
 | |
|  * 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.
 | |
|  */
 | |
| contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
 | |
|   /**
 | |
|    * @dev Emitted when the administration has been transferred.
 | |
|    * @param previousAdmin Address of the previous admin.
 | |
|    * @param newAdmin Address of the new admin.
 | |
|    */
 | |
|   event AdminChanged(address previousAdmin, address newAdmin);
 | |
| 
 | |
|   /**
 | |
|    * @dev Storage slot with the admin of the contract.
 | |
|    * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
 | |
|    * validated in the constructor.
 | |
|    */
 | |
|   bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
 | |
| 
 | |
|   /**
 | |
|    * @dev Modifier to check whether the `msg.sender` is the admin.
 | |
|    * If it is, it will run the function. Otherwise, it will delegate the call
 | |
|    * to the implementation.
 | |
|    */
 | |
|   modifier ifAdmin() {
 | |
|     if (msg.sender == _admin()) {
 | |
|       _;
 | |
|     } else {
 | |
|       _fallback();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @return The address of the proxy admin.
 | |
|    */
 | |
|   function admin() external ifAdmin returns (address) {
 | |
|     return _admin();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @return The address of the implementation.
 | |
|    */
 | |
|   function implementation() external ifAdmin returns (address) {
 | |
|     return _implementation();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Changes the admin of the proxy.
 | |
|    * Only the current admin can call this function.
 | |
|    * @param newAdmin Address to transfer proxy administration to.
 | |
|    */
 | |
|   function changeAdmin(address newAdmin) external ifAdmin {
 | |
|     require(newAdmin != address(0), 'Cannot change the admin of a proxy to the zero address');
 | |
|     emit AdminChanged(_admin(), newAdmin);
 | |
|     _setAdmin(newAdmin);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Upgrade the backing implementation of the proxy.
 | |
|    * Only the admin can call this function.
 | |
|    * @param newImplementation Address of the new implementation.
 | |
|    */
 | |
|   function upgradeTo(address newImplementation) external ifAdmin {
 | |
|     _upgradeTo(newImplementation);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Upgrade the backing implementation of the proxy and call a function
 | |
|    * on the new implementation.
 | |
|    * This is useful to initialize the proxied contract.
 | |
|    * @param newImplementation 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.
 | |
|    */
 | |
|   function upgradeToAndCall(address newImplementation, bytes calldata data)
 | |
|     external
 | |
|     payable
 | |
|     ifAdmin
 | |
|   {
 | |
|     _upgradeTo(newImplementation);
 | |
|     (bool success, ) = newImplementation.delegatecall(data);
 | |
|     require(success);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @return adm The admin slot.
 | |
|    */
 | |
|   function _admin() internal view returns (address adm) {
 | |
|     bytes32 slot = ADMIN_SLOT;
 | |
|     //solium-disable-next-line
 | |
|     assembly {
 | |
|       adm := sload(slot)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Sets the address of the proxy admin.
 | |
|    * @param newAdmin Address of the new proxy admin.
 | |
|    */
 | |
|   function _setAdmin(address newAdmin) internal {
 | |
|     bytes32 slot = ADMIN_SLOT;
 | |
|     //solium-disable-next-line
 | |
|     assembly {
 | |
|       sstore(slot, newAdmin)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @dev Only fall back when the sender is not the admin.
 | |
|    */
 | |
|   function _willFallback() internal virtual override {
 | |
|     require(msg.sender != _admin(), 'Cannot call fallback function from the proxy admin');
 | |
|     super._willFallback();
 | |
|   }
 | |
| }
 | 
