Self-adjusting pyramid scheme with declining multipliers (3x to 1.5x), deployed February 23, 2016. 140 participants entered, 136 still waiting for payout. Sourc
Historical Significance
An example of a more sophisticated pyramid design that attempted to address the sustainability problem of simple pyramids through dynamic multiplier adjustment. Despite this innovation, the contract still ran out of funds. Demonstrates the limits of pyramid economics regardless of implementation cleverness.
Context
Deployed in February 2016, during a period of active experimentation with financial contracts on Ethereum. By this point, several simpler pyramid contracts had already failed, and DynamicPyramid represents an attempt to iterate on the design.
Key Facts
Description
DynamicPyramid was a self-adjusting pyramid scheme that changed its payout multiplier as participation grew, designed to extend the pyramid's lifespan beyond simple fixed-ratio schemes.
The contract started with a 3x multiplier: deposit 1 ETH, receive 3 ETH when your turn came. At 10 participants, the multiplier dropped to 2x. At 25 participants, it dropped to 1.5x. A 10% fee was collected on each deposit (halved to 5% for deposits of 50 ETH or more).
The pyramid collected 140 participants before running out of funds. 136 participants are still waiting for their payout. The creator (0xe5478b...) extracted fees but left participants stranded.
37 ETH remains locked in the contract, not enough to cover remaining obligations.
The source was found in hrishioa/smart-contract-benchmark, originally from Etherscan. Compiled with native C++ solc v0.2.0 from webthree-umbrella v1.1.2 with optimizer enabled.
Source Verified
Exact byte-for-byte creation bytecode match. Compiler: soljson-v0.2.0-nightly.2016.1.20+commit.67c855c5.js (optimizer ON). Key finding: The soljson nightly from January 20, 2016 also produces an exact match alongside the native C++ build. Previously only the native C++ webthree-umbrella v1.1.2 build was confirmed.
Historian Categories
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 Verification ProofShow source code (Solidity)
contract DynamicPyramid {
//Declare variables for storage critical to contract
uint private balance = 0;
uint private collectedFees = 0;
uint private feePercent = 10;
uint private pyramidMultiplier = 300;
uint private payoutOrder = 0;
address private creator;
//Sets creator
function DynamicPyramid() {
creator = msg.sender;
}
modifier onlyowner { if (msg.sender == creator) _ }
struct Participant {
address etherAddress;
uint payout;
}
Participant[] private participants;
//Fallback function
function() {
init();
}
//init function run on fallback
function init() private{
//Ensures only tx with value of 1 ether or greater are processed and added to pyramid
if (msg.value < 1 ether) {
collectedFees += msg.value;
return;
}
uint _fee = feePercent;
//50% fee rebate on any ether value of 50 or greater
if (msg.value >= 50 ether) _fee /= 2;
addPayout(_fee);
}
//Function called for valid tx to the contract
function addPayout(uint _fee) private {
//Adds new address to participant array
participants.push(Participant(msg.sender, (msg.value * pyramidMultiplier) / 100));
//These statements ensure a quicker payout system to later pyramid entrants, so the pyramid has a longer lifespan
if (participants.length == 10) pyramidMultiplier = 200;
else if (participants.length == 25) pyramidMultiplier = 150;
// collect fees and update contract balance
balance += (msg.value * (100 - _fee))/100;
collectedFees += (msg.value * _fee)/100;
//Pays earlier participiants if balance sufficient
while (balance > participants[payoutOrder].payout) {
uint payoutToSend = participants[payoutOrder].payout;
participants[payoutOrder].etherAddress.send(payoutToSend);
balance -= participants[payoutOrder].payout;
payoutOrder += 1;
}
}
//Fee functions for creator
function collectAllFees() onlyowner {
if (collectedFees == 0) throw;
creator.send(collectedFees);
collectedFees = 0;
}
function collectFeesInEther(uint _amt) onlyowner {
_amt *= 1 ether;
if (_amt > collectedFees) collectAllFees();
if (collectedFees == 0) throw;
creator.send(_amt);
collectedFees -= _amt;
}
function collectPercentOfFees(uint _pcent) onlyowner {
if (collectedFees == 0 || _pcent > 100) throw;
uint feesToCollect = collectedFees / 100 * _pcent;
creator.send(feesToCollect);
collectedFees -= feesToCollect;
}
//Functions for changing variables related to the contract
function changeOwner(address _owner) onlyowner {
creator = _owner;
}
function changeMultiplier(uint _mult) onlyowner {
if (_mult > 300 || _mult < 120) throw;
pyramidMultiplier = _mult;
}
function changeFeePercentage(uint _fee) onlyowner {
if (_fee > 10) throw;
feePercent = _fee;
}
//Functions to provide information to end-user using JSON interface or other interfaces
function currentMultiplier() constant returns (uint multiplier, string info) {
multiplier = pyramidMultiplier;
info = 'This multiplier applies to you as soon as transaction is received, may be lowered to hasten payouts or increased if payouts are fast enough. Due to no float or decimals, multiplier is x100 for a fractional multiplier e.g. 250 is actually a 2.5x multiplier. Capped at 3x max and 1.2x min.';
}
function currentFeePercentage() constant returns (uint fee, string info) {
fee = feePercent;
info = 'Shown in % form. Fee is halved(50%) for amounts equal or greater than 50 ethers. (Fee may change, but is capped to a maximum of 10%)';
}
function currentPyramidBalanceApproximately() constant returns (uint pyramidBalance, string info) {
pyramidBalance = balance / 1 ether;
info = 'All balance values are measured in Ethers, note that due to no decimal placing, these values show up as integers only, within the contract itself you will get the exact decimal value you are supposed to';
}
function nextPayoutWhenPyramidBalanceTotalsApproximately() constant returns (uint balancePayout) {
balancePayout = participants[payoutOrder].payout / 1 ether;
}
function feesSeperateFromBalanceApproximately() constant returns (uint fees) {
fees = collectedFees / 1 ether;
}
function totalParticipants() constant returns (uint count) {
count = participants.length;
}
function numberOfParticipantsWaitingForPayout() constant returns (uint count) {
count = participants.length - payoutOrder;
}
function participantDetails(uint orderInPyramid) constant returns (address Address, uint Payout)
{
if (orderInPyramid <= participants.length) {
Address = participants[orderInPyramid].etherAddress;
Payout = participants[orderInPyramid].payout / 1 ether;
}
}
}External Links
Related contracts
MyScheme
Same eraOne of Ethereum's earliest pyramid-style chain letter contracts, deployed 9 days after genesis. Required 10 ETH per entry and distributed payouts to earlier par
0xa32707...30f955August 7, 2015Ponzi
Same eraA 102 percent pay-forward queue from 8 August 2015 that reverts on every deposit, appending to an array it never lengthens.
0xce44c7...75f579August 8, 2015MyScheme
Same eraAn early 100 ETH tree-payout chain letter (MyScheme) deployed on Frontier, Aug 9 2015; still holds 1 ETH.
0x4364ef...39df3cAugust 9, 2015MyScheme (100ETH)
Same eraA 100-ETH chain-letter investment contract deployed August 9, 2015, part of an early family of Frontier-era financial experiment contracts with variants accepti
0x020522...767d64August 9, 2015Pyramid
Same eraMember-added pyramid/chain list with equal-share claim distribution.
0xdf4b51...dc9b87August 10, 2015PyramidQueue
Same eraA 1,746-byte owner-operated funnel into a 2016 pyramid scheme. forward() buys the operator a 1 ether entry in the pyramid and pays the operator 0.5 ether on top.
0xbe1f4a...9f550dSeptember 7, 2015