pragma solidity ^0.4.24; /** * @title Proxy * @dev Gives the possibility to delegate any call to a foreign implementation. */ contract Proxy { /** * @dev Tells the address of the implementation where every call will be delegated. * @return address of the implementation to which it will be delegated */ function _implementation() internal view returns (address); /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ function _fallback() internal { _delegate(_implementation()); } /** * @dev Fallback function allowing to perform a delegatecall to the given implementation. * This function will return whatever the implementation call returns */ function _delegate(address implementation) internal { /*solium-disable-next-line security/no-inline-assembly*/ 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) } } } function () public payable { _fallback(); } }