GitHub repository: rutisan/XBN-Contrac
Description: // SPDX-License-Identifier: MIT  pragma solidity ^0.6.0;  import './UpgradeabilityProxy.sol';  /**  * @title AdminUpgradeabilityProxy  * @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 AdminUpgradeabilityProxy is UpgradeabilityProxy {   /**    * Contract constructor.    * @param _logic address of the initial implementation.    * @param _admin Address of the proxy administrator.    * @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.    */   constructor(address _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {     assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));     _setAdmin(_admin);   }    /**    * @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) payable external 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;     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;      assembly {       sstore(slot, newAdmin)     }   }    /**    * @dev Only fall back when the sender is not the admin.    */   function _willFallback() internal override virtual {     require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");     super._willFallback();   } }