Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

ReplaySafe Contract Stealing funds ??? #1128

Closed
goodday1 opened this issue Aug 29, 2016 · 4 comments
Closed

ReplaySafe Contract Stealing funds ??? #1128

goodday1 opened this issue Aug 29, 2016 · 4 comments

Comments

@goodday1
Copy link

goodday1 commented Aug 29, 2016

Version: 0.8.2 OS & Version: windows10 64bit Node type: `geth(default)

I just updated to version 8.2 of ethereum wallet. I ran the wallet which was already synced, then executed the REPLAYSAFECONTRACT (from ethereum blog) to split 92 ethers in one of my accounts

I double checked both addresses, fork and no fork to make sure they are correct, then put in my password to execute and instead of splitting my ether it sent 92 ethers to this address without splitting.

http://etherscan.io/address/0x0000000000000000000000000000000000000000

contract execution : http://etherscan.io/tx/0xacf45617a60827ceb931a419034af9da97b5676e17107c547c9c11b04db1355a

my address with classic and ether balance : http://etherscan.io/address/0x6Cf0569bf06069e27fca1Ff3d6cb398116F0a097

address I tried to split classic to(poloniex) : https://gastracker.io/addr/0x850e230251913fdcdde0da6bfb53f338f6f7b021

How is this possible and why would it happen? How do I get my ethers back ?

@luclu
Copy link
Contributor

luclu commented Sep 17, 2016

@goodday1 please excuse my late reply.

There are currently two replaysafe/split-contracts:

  • (i) was introduces by Vitalik on the ethereum blog.
    (contract address: 0xaa1a6e3e6ef20068f7f8d8c835d2d22fd5116444)
  • (ii) was introduces with the 0.8.2 release of Mist/Ethereum-Wallet. (contract address: 0x1cA4A86BBa124426507d1EF67Ad271CC5A02820a)

(ii) is based on (i) with the addition of token support and got integrated into the send interface of Ethereum-Wallet. Using the replaysplit option on the wallet's send screen should prohibit the use of 0x0000000000000000000000000000000000000000 as a primary recipient as this gets filtered in the address input field.

Should you be using any of (i) or (ii) as a custom contract or invoke it via a command-line interface of any ethereum node, you won't be protected from specifying 0x0000000000000000000000000000000000000000 as a recipient (This might also happen if you don't specify any address at all).


I tried to gather some statistics about lost Ether on (i) and (ii):

(i) 22 of 88929 TXs (0.025%) affected

Total lost ETH: 1874.14
List of Transactions:
0x50afe918c63234bd16b88c21986820fa7449a84eae4b65dd2ff2816216116684
0x3dd29aaeed661092e11230eed64c715c5cb5e436fbfe0a99d0a2420158dd70a0
0x1503e9a5ce2fdc764a998016931f417d59811e09a27dce47a16a2909f9719709
0x2c055794145952d373bf98cbba0b25c09ecb3fd9bfdb8f7302124986b9ebefcd
0xd14c87fc138e59161c4b42c926a5b3302198a6c4a756dd98dfbf524f57c0076f
0xc31f1f7c64770795d4d8663d996613e0b000a3ff9d1e3559488e3426c847a06d
0x58904fad6572db5239d7f58108ed087d15d57cf89ff6103fd5bcb9b6c5a346e6
0x6142e6aaca179b1f086c61d17ed026b73e3c425ed7cfe447401cc2bb1b090616
0x25052e3be9d852ab11ddfc08a2654d05fab447cd4b8d2dd95c5cce3ca5756d4f
0x1c96608bda6ce4be0d0f30b3a5b3a9d9c94930291a168a0dbddfe9be24ac70d1
0x8fd034bed3498d9ee89131c556e44f9caf0a6f04ff4f10149c685661733944e1
0xffa0036838ad6fab37f00ffd9b823c01efd17c5c9f25746817dab724cb7d7d23
0x31edcc555c69753e8613b8c275e33759fa051013a3b45c3984de91dbc5a616f7
0xa72fa8f3b4da6d273903311f1c7b02091605ce7239eb603d1d41b2614a44a82e
0x9e4852b0fdabd367e8241121d7eee7cecd5e8b7000704aa60d62e685834ba08b
0x0d9d581afc0c351248452ac13a1be633eca9d6435ed06774e9bdaba285b67212
0xa71e7fc1872f20d64760116df009298c930c4af07863f40a7f4cbbddaa90b20d
0x3f0fa5610da64a259bbab32ea3f34cb18ab02f0257d4419c27b5b1b3f6c1f26b
0xacf45617a60827ceb931a419034af9da97b5676e17107c547c9c11b04db1355a
0xb29c87aae696d28eff90fed8d8f21f53f978e54adfe0967c2812fa14dd9ca05a
0xf644d44c97fc95c8d63108b30a6b85e8a2ea31b8fadf8c114f5f50cfa168c405
0x89966accaaad94de399aa84adc575cd65794649db2ee93a4c575940514c405c6

(ii) 1 of 340 TXs (0.294%) affected

Total lost ETH: 1.0
List of Transactions:
0x0c796fbbbbee18dfba0f0ce735b7828771c4e4b247e7b97b361e37e90eac6ead

Source code (python):

import json, requests, time

urlPrefix = "http://api.etherscan.io/api?module=account&action=txlist&address=0x1cA4A86BBa124426507d1EF67Ad271CC5A02820a&startblock="
urlMid = "&endblock="
urlSufix = "&sort=asc&apikey=YourApiKeyToken"
firstBlock = 1920419
latestBlock = int(json.loads(requests.get(url="https://api.etherscan.io/api?module=proxy&action=eth_blockNumber").text)['result'], 0)
chunkSize = 10000
txs = []
ether = 0
for i in range(firstBlock, latestBlock, chunkSize):
    print("Scanning block " + str(i) + " to " + str(i + chunkSize) + " - " + str(100*(i - firstBlock) / (latestBlock - firstBlock)) + "%")
    data = json.loads(requests.get(url=urlPrefix + str(i) + urlMid + str(i + chunkSize) + urlSufix).text)['result']
    for k in range(0, len(data)):
        if (data[k]['input'][10:74] == '0000000000000000000000000000000000000000000000000000000000000000'):
            txs.append(data[k]['hash'])
            ether += int(data[k]['value'])


print("Total lost ETH: " + str(float(ether)/(10**18)) + "\nList of Transactions:")
for tx in txs:
    print(tx)

To check locally instead of using etherscan.io's API you can use this code (node.js):

var Parallel = require('paralleljs')
var Web3 = require('web3');
var _ = require('underscore');

var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

var startBlock = 1920419;
var endBlock = web3.eth.blockNumber;

var chunks = [];
var chunksCount = 10
var step = Math.floor((endBlock - startBlock) / chunksCount);

for (var i = 0; i < chunksCount; i ++) {
    chunks.push(_.range(startBlock + i*step, startBlock + i*step + step));
}
console.log(chunks)

var p = new Parallel(chunks);

function scan(chunk) {
    var Web3 = require('web3');
    var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

    console.log('processing block', chunk[0], '-', chunk[chunk.length - 1]);
    chunk.forEach((blocknumber) => {
        console.log(blocknumber)
        var block = web3.eth.getBlock(blocknumber);
        for (var i in block.transactions) {
            var tx = web3.eth.getTransaction(block.transactions[i]);
            if (tx.to == '0xaa1a6e3e6ef20068f7f8d8c835d2d22fd5116444') {
                var input = tx.input;
                console.log(blocknumber + ' - 0x' + input.slice(34,74));
                if (input.slice(34,74) == 0)
                    console.log(tx.hash);
            }
        }
    })
    return 0;
}

p.map(scan);

How is this possible and why would it happen? How do I get my ethers back ?

Unfortunately it is not possible to retrieve the lost ether.

@luclu luclu added the question label Sep 17, 2016
@chevdor
Copy link

chevdor commented Oct 25, 2016

There is also 0xaBbb6bEbFA05aA13e908EaA492Bd7a8343760477

You can read the details here: https://medium.com/@chevdor/safer-version-of-the-replaysafesplit-smart-contract-a29c347e8a7#.xhfg8z383

This version adds some checks to prevent users/clients errors. So the contract will throw if you call it without funds or if any of the 2 addresses is missing.

@luclu
Copy link
Contributor

luclu commented Oct 25, 2016

Thank you @chevdor for pointing this out!
pinging @alexvandesande

@lock
Copy link

lock bot commented Apr 11, 2018

This thread has been automatically locked because it has not had recent activity. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked and limited conversation to collaborators Apr 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants