Last active
January 29, 2017 08:23
-
-
Save etscrivner/33a94718f425c12f6321a0e3f4bc83dd to your computer and use it in GitHub Desktop.
Safe splitting contract that accounts for EIP-150 and ETH/ETC hard forks.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.2; | |
contract EIP150ReplaySafeSplit { | |
// Fork oracle for EIP-150 fork | |
AmIOnEIP150Fork amIOnEIP150Fork = AmIOnEIP150Fork(/* To be deployed */); | |
// Fork oracle for ETH/ETC fork | |
AmIOnTheFork amIOnDAOFork = AmIOnTheFork(0x2bd2326c993dfaef84f696526064ff22eba5b362); | |
// This routine provides a way to route funds across Ethereum chain forks. It preserves | |
// the signature of split method from DAO hard-fork replay split contract. If the current | |
// blockchain is determined to be the Ethereum chain (EIP150 forked chain) then funds | |
// are sent to `ethTarget`. If the current chain is the ETC chain, then funds are sent to | |
// `etcTarget`. On the unforked EIP-150 chain funds are returned to sender. | |
// | |
// Params: | |
// ethTarget - The target address on the Ethereum blockchain. | |
// etcTarget - The target on the unforked DAO (Ethereum Classic) blockchain. | |
function split(address ethTarget, address etcTarget) returns(bool) { | |
return tripleSplit(ethTarget, etcTarget, msg.sender); | |
} | |
// This routine provides a way to route funds across three separate Ethereum forked chains. | |
// It first determines the current chain as one of: Forked EIP-150 chain, Unforked EIP-150 chain, | |
// or Ethereum Classic chain. Funds are then routed to the appropriate target for a given chain | |
// as follows: | |
// | |
// Params: | |
// ethTarget - Target on forked EIP-150 chain. | |
// etcTarget - Target on Ethereum Classic (DAO hard-fork) chain. | |
// unforkedEIP150Target - Target on unforked EIP-150 chain. | |
function tripleSplit(address ethTarget, address etcTarget, address unforkedEIP150Target) returns(bool) { | |
bool onEIP150Fork = amIOnEIP150Fork.forked(); | |
bool onDAOFork = amIOnDAOFork.forked(); | |
if (onEIP150Fork && !onDAOFork && ethTarget.send(msg.value)) { | |
return true; | |
} else if (!onEIP150Fork && onDAOFork && etcTarget.send(msg.value)) { | |
return true; | |
} else if (!onEIP150Fork && !onDAOFork && unforkedEIP150Target.send(msg.value)) { | |
return true; | |
} | |
// NOTE: We explicitly do not handle the (onEIP150Fork && onDAOFork) case | |
throw; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I would change
amIOnEtcFork
toamIOnDAOFork
for less ambiguity.EtcFork
sounds like it could be a subsequent fork on the ETC chain.Drop the fallback function.
Store the results of
amIOnEip150Fork.forked()
andamIOnEtcFork.forked()
in local variables since I believe external contract calls cost more gas.