pragma solidity ^0.4.18;
contract DelegateProxy {
/**
* @dev Performs a delegatecall and returns whatever the delegatecall returned (entire context execution will return!)
* @param _dst Destination address to perform the delegatecall
* @param _calldata Calldata for the delegatecall
*/
function delegatedFwd(address _dst, bytes _calldata) internal {
assembly {
let result := delegatecall(sub(gas, 10000), _dst, add(_calldata, 0x20), mload(_calldata), 0, 0)
let size := returndatasize
let ptr := mload(0x40)
returndatacopy(ptr, 0, size)
// revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
// if the call returned error data, forward it
switch result case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}
}
contract Delegatable {
address empty1; // unknown slot
address empty2; // unknown slot
address empty3; // unknown slot
address public owner; // matches owner slot in controller
address public delegation; // matches thisAddr slot in controller
event DelegationTransferred(address indexed previousDelegate, address indexed newDelegation);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows owner to transfer delegation of the contract to a newDelegation.
* @param newDelegation The address to transfer delegation to.
*/
function transferDelegation(address newDelegation) public onlyOwner {
require(newDelegation != address(0));
DelegationTransferred(delegation, newDelegation);
delegation = newDelegation;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title Parsec
* Basic proxy implementation to controller
*/
contract Parsec is Delegatable, DelegateProxy {
/**
* @dev Function to invoke all function that are implemented in controler
*/
function () public {
delegatedFwd(delegation, msg.data);
}
/**
* @dev Function to initialize storage of proxy
* @param _controller The address of the controller to load the code from
* @param _cap Max amount of tokens that should be mintable
*/
function initialize(address _controller, uint256 _cap) public {
require(owner == 0);
owner = msg.sender;
delegation = _controller;
delegatedFwd(_controller, msg.data);
}
}
{
"compilationTarget": {
"Parsec.sol": "Parsec"
},
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[{"name":"newDelegation","type":"address"}],"name":"transferDelegation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_controller","type":"address"},{"name":"_cap","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delegation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousDelegate","type":"address"},{"indexed":true,"name":"newDelegation","type":"address"}],"name":"DelegationTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]