Skip to content

Instantly share code, notes, and snippets.

@sambacha
Created February 8, 2022 03:45
Show Gist options
  • Save sambacha/25e167ef0a5093f206bb5a9ba9900b57 to your computer and use it in GitHub Desktop.
Save sambacha/25e167ef0a5093f206bb5a9ba9900b57 to your computer and use it in GitHub Desktop.

posted Jun 18, 2016 https://gist.github.com/holiman/f66bae83540728c209e521c42bd06362

Additional usage of this pattern:

https://github.com/nexusdev/solidity-quirks/blob/3ebdffe3425f47b84538631f811b81a49e4c54d8/contracts/delivery_test.sol

// testing transfer via `selfdestruct` to avoid executing code on recipient
// source: https://gist.github.com/holiman/f66bae83540728c209e521c42bd06362

import 'dapple/test.sol';

contract DeliveryBoy {
    /*
     * Delivery boy is very important, but not so clever
     */
    function deliver(address recipient){
        selfdestruct(recipient);
    }
}

contract MailMan {
    
    /*
     * The MailMan delivers
     * No-fuzz delivery of ether to the recipient. 
     * Mailman tolerates no code-execution or funny stuff on cash delivery
     * Nobody owns the mailman (no 'owner')
     * Mailman remembers nothing (no storage slots)
     *
     * You wanna use mailman for payment?
     * Go ahead, but its'a gonna cost'ya some extra gas, capisce...
     */
     function payRecipient(address recipient)
     {
        DeliveryBoy d = new DeliveryBoy();
        d.deliver.value(msg.value)(recipient);
     }
}

contract StatefulFallbackGuy {
    bool public touched;
    function() {
        touched = true;
    }
}

contract DeliveryBoyTest is Test {
    MailMan mm;
    StatefulFallbackGuy bob;
    function setUp() {
        mm = new MailMan();
        bob = new StatefulFallbackGuy();
        assertEq(bob.balance, 0);
    }
    function testDelivery() {
        mm.payRecipient.value(100)(bob);
        assertEq(bob.balance, 100);
        assertFalse(bob.touched());
    }
}
// SPDX-License-Identifier: MIT
// @summary Conduit - Transfers ETH via selfdestruct()
// @filename TransactionConduit
pragma solidity >=0.7.6 <0.9.0;
contract TransactionConduit {
function massTeleport(address payable[] memory _recipients, uint[] memory _amounts) public payable returns (bool) {
uint numRecipients = _recipients.length;
require(numRecipients == _amounts.length, 'FAIL! PARAM SIZE');
Conduit unstablePortal = new Conduit();
for (uint i=0; i < numRecipients; i++) {
unstablePortal.teleportEtherTo{value: _amounts[i]}(_recipients[i]);
}
uint remainingBalance = address(this).balance;
if (remainingBalance > 0) {
unstablePortal.teleportEtherTo{value: remainingBalance}(payable(msg.sender));
}
return true;
}
function voidEther() public payable {
Conduit unstablePortal = new Conduit();
unstablePortal.teleportEtherTo{value: msg.value}(payable(address(unstablePortal)));
}
}
contract Conduit {
function teleportEtherTo(address payable _recipient) public payable {
selfdestruct(_recipient);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment