/** * Source Code first verified at https://etherscan.io on Saturday, April 27, 2019 (UTC) */ pragma solidity ^0.4.23; // File: contracts/Proxy/OwnedUpgradeabilityProxy.sol /** * @title OwnedUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with basic authorization control functionalities */ contract TrueCAD { /** * @dev Event to show ownership has been transferred * @param previousOwner representing the address of the previous owner * @param newOwner representing the address of the new owner */ event ProxyOwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Event to show ownership transfer is pending * @param currentOwner representing the address of the current owner * @param pendingOwner representing the address of the pending owner */ event NewPendingOwner(address currentOwner, address pendingOwner); // Storage position of the owner and pendingOwner of the contract bytes32 private constant proxyOwnerPosition = 0x136d55780fb1583e87bb6fa1fda0bbe2746553b012c9291a830fad1e95c269cc;//keccak256("trueCAD.proxy.owner"); bytes32 private constant pendingProxyOwnerPosition = 0xca6c24188764c50fa5c7b728d85fdd98bea1991968b9f4bd4000ae3ace49faac;//keccak256("trueCAD.pending.proxy.owner"); /** * @dev the constructor sets the original owner of the contract to the sender account. */ constructor() public { _setUpgradeabilityOwner(msg.sender); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyProxyOwner() { require(msg.sender == proxyOwner(), "only Proxy Owner"); _; } /** * @dev Throws if called by any account other than the pending owner. */ modifier onlyPendingProxyOwner() { require(msg.sender == pendingProxyOwner(), "only pending Proxy Owner"); _; } /** * @dev Tells the address of the owner * @return the address of the owner */ function proxyOwner() public view returns (address owner) { bytes32 position = proxyOwnerPosition; assembly { owner := sload(position) } } /** * @dev Tells the address of the owner * @return the address of the owner */ function pendingProxyOwner() public view returns (address pendingOwner) { bytes32 position = pendingProxyOwnerPosition; assembly { pendingOwner := sload(position) } } /** * @dev Sets the address of the owner */ function _setUpgradeabilityOwner(address newProxyOwner) internal { bytes32 position = proxyOwnerPosition; assembly { sstore(position, newProxyOwner) } } /** * @dev Sets the address of the owner */ function _setPendingUpgradeabilityOwner(address newPendingProxyOwner) internal { bytes32 position = pendingProxyOwnerPosition; assembly { sstore(position, newPendingProxyOwner) } } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. *changes the pending owner to newOwner. But doesn't actually transfer * @param newOwner The address to transfer ownership to. */ function transferProxyOwnership(address newOwner) external onlyProxyOwner { require(newOwner != address(0)); _setPendingUpgradeabilityOwner(newOwner); emit NewPendingOwner(proxyOwner(), newOwner); } /** * @dev Allows the pendingOwner to claim ownership of the proxy */ function claimProxyOwnership() external onlyPendingProxyOwner { emit ProxyOwnershipTransferred(proxyOwner(), pendingProxyOwner()); _setUpgradeabilityOwner(pendingProxyOwner()); _setPendingUpgradeabilityOwner(address(0)); } /** * @dev Allows the proxy owner to upgrade the current version of the proxy. * @param implementation representing the address of the new implementation to be set. */ function upgradeTo(address implementation) external onlyProxyOwner { address currentImplementation; bytes32 position = implementationPosition; assembly { currentImplementation := sload(position) } require(currentImplementation != implementation); assembly { sstore(position, implementation) } emit Upgraded(implementation); } /** * @dev This event will be emitted every time the implementation gets upgraded * @param implementation representing the address of the upgraded implementation */ event Upgraded(address indexed implementation); // Storage position of the address of the current implementation bytes32 private constant implementationPosition = 0xecfd2ee7a4295d533a08882dec6729582fc6bda7812f32b75ae1ea4807d08982; //keccak256("trueCAD.proxy.implementation"); function implementation() public view returns (address impl) { bytes32 position = implementationPosition; assembly { impl := sload(position) } } /** * @dev Fallback function allowing to perform a delegatecall to the given implementation. * This function will return whatever the implementation call returns */ function() external payable { assembly { let ptr := mload(0x40) calldatacopy(ptr, returndatasize, calldatasize) let result := delegatecall(gas, sload(0xecfd2ee7a4295d533a08882dec6729582fc6bda7812f32b75ae1ea4807d08982), ptr, calldatasize, returndatasize, returndatasize) returndatacopy(ptr, 0, returndatasize) switch result case 0 { revert(ptr, returndatasize) } default { return(ptr, returndatasize) } } } }