pragma solidity ^0.4.24;
/// @title Smart contract for forwarding ETH to a pre-defined recipient in the passive mode i.e. someone has to trigger the transfer.
/// It also allows recipient to call any smart contracts. For example: Calling Trustcoin smart contract to transfer TRST.
/// @author WeTrustPlatform
contract PassiveForwarder {
/// @dev recipient must be a normal account or a smart contract with the standard payable fallback method.
/// Otherwise, fund will be stuck!
address public recipient;
event Received(address indexed sender, uint256 value);
constructor(address _recipient) public {
recipient = _recipient;
}
function () public payable {
require(msg.value > 0);
emit Received(msg.sender, msg.value);
}
function sweep() public {
recipient.transfer(address(this).balance);
}
/// @dev Courtesy of https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol
/// This method allows the pre-defined recipient to call other smart contracts.
function externalCall(address destination, uint256 value, bytes data) public returns (bool) {
require(msg.sender == recipient, "Sender must be the recipient.");
uint256 dataLength = data.length;
bool result;
assembly {
let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
result := call(
sub(gas, 34710), // 34710 is the value that solidity is currently emitting
// It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
// callNewAccountGas (25000, in case the destination address does not exist and needs creating)
destination,
value,
d,
dataLength, // Size of the input (in bytes) - this is what fixes the padding problem
x,
0 // Output is ignored, therefore the output size is zero
)
}
return result;
}
}
{
"compilationTarget": {
"PassiveForwarder.sol": "PassiveForwarder"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[],"name":"sweep","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"destination","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"externalCall","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"recipient","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_recipient","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Received","type":"event"}]