A pyramid scheme promising 2x returns to ETH participants. 28 ETH remains locked — those who entered last will never be paid out.
Key Facts
Description
The Doubler was one of the most common Ethereum contract patterns in early 2016: a straightforward pyramid scheme that promised to double every participant's ETH deposit.
The mechanics were simple. Call enter() with at least 1 ETH, and the contract records your position in a queue. A 10% fee is skimmed into a pool for the owner; the remaining 90% goes into the balance pool. Once the pool contains twice the deposit of the next person in line, that participant receives 180% of their original deposit — double, minus the 10% fee already taken.
The first participant always loses: their deposit goes entirely to fees with no one above them to pay. Everyone else's fate depends on whether enough new money enters after them.
Deployed on February 19, 2016 (block 1,028,387), this instance attracted 12 transactions during 2016 and left 28 ETH permanently locked. The participants at the tail of the queue will never receive payouts — the pyramid stopped growing before it could reach them.
The Doubler contract pattern was deployed dozens of times across Ethereum during 2015 and 2016. This instance was compiled with soljson v0.2.1 (the emscripten JavaScript build), producing 1,137 bytes of runtime bytecode.
Source Verified
Runtime bytecode reproduced exactly (1,137 bytes) using soljson v0.2.1+commit.91a6b35f with optimizer enabled.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Source CodeShow source code (Solidity)
pragma solidity ^0.2.0;
contract Doubler {
struct Participant {
address etherAddress;
uint amount;
}
Participant[] public participants;
uint public payoutIdx = 0;
uint public collectedFees;
uint public balance;
address public owner;
function Doubler() {
owner = msg.sender;
}
function() {
enter();
}
function enter() {
if (msg.value < 1 ether) {
msg.sender.send(msg.value);
return;
}
uint idx = participants.length;
participants.length += 1;
participants[idx].etherAddress = msg.sender;
participants[idx].amount = msg.value;
if (idx == 0) {
collectedFees += msg.value;
} else {
collectedFees += msg.value / 10;
balance += msg.value;
}
while (balance > participants[payoutIdx].amount * 2) {
uint payout = participants[payoutIdx].amount * 2 - participants[payoutIdx].amount / 10;
participants[payoutIdx].etherAddress.send(payout);
balance -= participants[payoutIdx].amount * 2;
payoutIdx++;
}
}
function collectFees() {
if (msg.sender != owner) return;
if (collectedFees == 0) return;
owner.send(collectedFees);
collectedFees = 0;
}
function setOwner(address _owner) {
if (msg.sender != owner) return;
owner = _owner;
}
}