/**
*Submitted for verification at Etherscan.io on 2020-09-23
*/
pragma solidity 0.5.11;
/**
* @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.
*/
contract Proxy {
/**
* @dev Fallback function.
* Implemented entirely in `_fallback`.
*/
function () payable external {
_fallback();
}
/**
* @return The Address of the implementation.
*/
function _implementation() internal view returns (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 {
assembly {
// 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.
case 0 { 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() internal {
}
/**
* @dev fallback implementation.
* Extracted to enable manual triggering.
*/
function _fallback() internal {
_willFallback();
_delegate(_implementation());
}
}
/**
* Utility library of inline functions on addresses
*
* Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/utils/Address.sol
* This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts
* when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the
* build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version.
*/
library OpenZeppelinUpgradesAddress {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param account address of the account to check
* @return whether the target address is a contract
*/
function isContract(address account) internal view returns (bool) {
uint256 size;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
/**
* @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.
*/
contract BaseUpgradeabilityProxy is Proxy {
/**
* @dev Emitted when the implementation is upgraded.
* @param implementation Address of the new implementation.
*/
event Upgraded(address indexed 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.
*/
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation.
* @return Address of the current implementation
*/
function _implementation() internal view returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
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(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
}
}
/**
* @title OUSD Governable Contract
* @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change
* from owner to governor and renounce methods removed. Does not use
* Context.sol like Ownable.sol does for simplification.
* @author Origin Protocol Inc
*/
contract Governable {
// Storage position of the owner and pendingOwner of the contract
bytes32
private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;
//keccak256("OUSD.governor");
bytes32
private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;
//keccak256("OUSD.pending.governor");
event PendingGovernorshipTransfer(
address indexed previousGovernor,
address indexed newGovernor
);
event GovernorshipTransferred(
address indexed previousGovernor,
address indexed newGovernor
);
/**
* @dev Initializes the contract setting the deployer as the initial Governor.
*/
constructor() internal {
_setGovernor(msg.sender);
emit GovernorshipTransferred(address(0), _governor());
}
/**
* @dev Returns the address of the current Governor.
*/
function governor() public view returns (address) {
return _governor();
}
function _governor() internal view returns (address governorOut) {
bytes32 position = governorPosition;
assembly {
governorOut := sload(position)
}
}
function _pendingGovernor()
internal
view
returns (address pendingGovernor)
{
bytes32 position = pendingGovernorPosition;
assembly {
pendingGovernor := sload(position)
}
}
/**
* @dev Throws if called by any account other than the Governor.
*/
modifier onlyGovernor() {
require(isGovernor(), "Caller is not the Governor");
_;
}
/**
* @dev Returns true if the caller is the current Governor.
*/
function isGovernor() public view returns (bool) {
return msg.sender == _governor();
}
function _setGovernor(address newGovernor) internal {
bytes32 position = governorPosition;
assembly {
sstore(position, newGovernor)
}
}
function _setPendingGovernor(address newGovernor) internal {
bytes32 position = pendingGovernorPosition;
assembly {
sstore(position, newGovernor)
}
}
/**
* @dev Transfers Governance of the contract to a new account (`newGovernor`).
* Can only be called by the current Governor. Must be claimed for this to complete
* @param _newGovernor Address of the new Governor
*/
function transferGovernance(address _newGovernor) external onlyGovernor {
_setPendingGovernor(_newGovernor);
emit PendingGovernorshipTransfer(_governor(), _newGovernor);
}
/**
* @dev Claim Governance of the contract to a new account (`newGovernor`).
* Can only be called by the new Governor.
*/
function claimGovernance() external {
require(
msg.sender == _pendingGovernor(),
"Only the pending Governor can complete the claim"
);
_changeGovernor(msg.sender);
}
/**
* @dev Change Governance of the contract to a new account (`newGovernor`).
* @param _newGovernor Address of the new Governor
*/
function _changeGovernor(address _newGovernor) internal {
require(_newGovernor != address(0), "New Governor is address(0)");
emit GovernorshipTransferred(_governor(), _newGovernor);
_setGovernor(_newGovernor);
}
}
/**
* @title BaseGovernedUpgradeabilityProxy
* @dev This contract combines an upgradeability proxy with our governor system
* @author Origin Protocol Inc
*/
contract InitializeGovernedUpgradeabilityProxy is
Governable,
BaseUpgradeabilityProxy
{
/**
* @dev Contract initializer with Governor enforcement
* @param _logic Address of the initial implementation.
* @param _initGovernor Address of the initial Governor.
* @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.
*/
function initialize(
address _logic,
address _initGovernor,
bytes memory _data
) public payable onlyGovernor {
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);
}
_changeGovernor(_initGovernor);
}
/**
* @return The address of the proxy admin/it's also the governor.
*/
function admin() external view returns (address) {
return _governor();
}
/**
* @return The address of the implementation.
*/
function implementation() external view returns (address) {
return _implementation();
}
/**
* @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 onlyGovernor {
_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
onlyGovernor
{
_upgradeTo(newImplementation);
(bool success, ) = newImplementation.delegatecall(data);
require(success);
}
}
/**
* @notice OUSDProxy delegates calls to a OUSD implementation
*/
contract OUSDProxy is InitializeGovernedUpgradeabilityProxy {
}
{
"compilationTarget": {
"InitializeGovernedUpgradeabilityProxy.sol": "InitializeGovernedUpgradeabilityProxy"
},
"evmVersion": "petersburg",
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"claimGovernance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"_initGovernor","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"transferGovernance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"PendingGovernorshipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"GovernorshipTransferred","type":"event"}]