laconicd-deprecated/tests/solidity/suites/staking/contracts/lib/os/DelegateProxy.sol

35 lines
1.3 KiB
Solidity
Raw Permalink Normal View History

// Brought from https://github.com/aragon/aragonOS/blob/v4.3.0/contracts/common/Autopetrified.sol
// Adapted to use pragma ^0.5.17 and satisfy our linter rules
pragma solidity 0.5.17;
import "./ERCProxy.sol";
import "./IsContract.sol";
contract DelegateProxy is ERCProxy, IsContract {
uint256 internal constant FWD_GAS_LIMIT = 10000;
/**
* @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 memory _calldata) internal {
require(isContract(_dst));
uint256 fwdGasLimit = FWD_GAS_LIMIT;
assembly {
let result := delegatecall(sub(gas, fwdGasLimit), _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) }
}
}
}