forked from cerc-io/laconicd-deprecated
35 lines
1.3 KiB
Solidity
35 lines
1.3 KiB
Solidity
|
// 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) }
|
||
|
}
|
||
|
}
|
||
|
}
|