I have been getting into mitigating reentrancy issues and safe ether transfer recently and have come up with the following 'safe transfer' code.
Workflow:
- deploy contract Foo
- send ether to Foo
-
execute function safeTransfer specifying the destination address and value in wei
pragma solidity ^0.4.11; contract Interface { function pay(); } contract Foo { function safeTransfer (address _to, uint256 _amount) { Bar a = new Bar(_to); a.transfer(_amount); Interface b = Interface(a); b.pay(); } function () payable {} } contract Bar { address payee; function Bar (address _payee) { payee = _payee; } function () payable {} function pay () { selfdestruct(payee); } }
At ~150k gas this is rather expensive but it works. I am aware of the pull payment best practise but would much prefer a convenient automated payments method. Any thoughts on how to potentially optimise this idea for use as payment option in a contract?
Best Answer
If your goal is to mitigate reentrancy vulnerability, transfer() has a gas stipend of only
2300
which is enough only to publish an event. In other words, as long as you stick to `transfer it's not possible to call back your contract.There is a small potential for improvement if you pass _payee directly to pay() function saving a bit of storage:
But I'm afraid that if you want to use a selfdestruct safety feature you will need to pay for contract creation every time - which is a very expensive operation.