Contract Name:
TimeOwnedUpgradeabilityProxy
Contract Source Code:
File 1 of 1 : TimeOwnedUpgradeabilityProxy
// File: @trusttoken/trusttokens/contracts/Proxy/OwnedUpgradeabilityProxy.sol
pragma solidity 0.5.13;
/**
* @title OwnedUpgradeabilityProxy
* @dev This contract combines an upgradeability proxy with basic authorization control functionalities
*/
contract OwnedUpgradeabilityProxy {
/**
* @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 = 0x6279e8199720cf3557ecd8b58d667c8edc486bd1cf3ad59ea9ebdfcae0d0dfac;//keccak256("trueUSD.proxy.owner");
bytes32 private constant pendingProxyOwnerPosition = 0x8ddbac328deee8d986ec3a7b933a196f96986cb4ee030d86cc56431c728b83f4;//keccak256("trueUSD.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) public 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 = 0x6e41e0fbe643dfdb6043698bf865aada82dc46b953f754a3468eaa272a362dc7; //keccak256("trueUSD.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 {
bytes32 position = implementationPosition;
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, returndatasize, calldatasize)
let result := delegatecall(gas, sload(position), ptr, calldatasize, returndatasize, returndatasize)
returndatacopy(ptr, 0, returndatasize)
switch result
case 0 { revert(ptr, returndatasize) }
default { return(ptr, returndatasize) }
}
}
}
// File: @trusttoken/trusttokens/contracts/Proxy/TimeOwnedUpgradeabilityProxy.sol
pragma solidity 0.5.13;
/**
* @title TimeOwnedUpgradeabilityProxy
* @dev This contract combines an upgradeability proxy with
* basic authorization control functionalities
*
* This contract allows us to specify a time at which the proxy can no longer
* be upgraded
*/
contract TimeOwnedUpgradeabilityProxy is OwnedUpgradeabilityProxy {
bytes32 private constant expirationPosition = bytes32(uint256(keccak256('trusttoken.expiration')) - 1);
/**
* @dev the constructor sets the original owner of the contract to the sender account.
*/
constructor() public {
_setUpgradeabilityOwner(msg.sender);
// set expiration to ~4 months from now
_setExpiration(block.timestamp + 124 days);
}
/**
* @dev sets new expiration time
*/
function setExpiration(uint256 newExpirationTime) external onlyProxyOwner {
require(block.timestamp < expiration(), "after expiration time");
require(block.timestamp < newExpirationTime, "new expiration time must be in the future");
_setExpiration(newExpirationTime);
}
function _setExpiration(uint256 newExpirationTime) internal onlyProxyOwner {
bytes32 position = expirationPosition;
assembly {
sstore(position, newExpirationTime)
}
}
function expiration() public view returns (uint256 _expiration) {
bytes32 position = expirationPosition;
assembly {
_expiration := sload(position)
}
}
/**
* @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) public onlyProxyOwner {
require(block.timestamp < expiration(), "after expiration date");
super.upgradeTo(implementation);
}
}