Skip to content

Contract Analysis

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

Analysis Date: 2026-02-13


Metadata

Primary Contract

PROPERTY VALUE
Contract Address 0xfD2487cc0e5dCe97F08BE1Bc8eF1DCE8D5988B4D (etherscan)
Network Ethereum Mainnet
Contract Type Standalone Ponzi Scheme
Deployment Date 2016-03-13 14:40:17 UTC
Deployment Block 1,143,960
Contract Creator 0x45ab6108cc41c20f416a98615aa8c349f02a275b (etherscan)
Creation TX 0x61894a6bffbe5f3a9d58674a1241bf2ebe62e6b9c512eea505b17f4148c3df41 (tx)
Compiler Version Solidity v0.2.0-2016-01-15-cc4b4f5 (optimized, 200 runs)
Total Functions 5 (constructor, fallback, enter, collectFees, setOwner)
External Contract Dependencies 0
Upgrade Mechanism ☒ None - Not Upgradable
Verification Status ☑ Verified - Exact Match
Audit Status ☒ No Audit Available
TYPE ADDRESS NOTES
Owner/Admin 0x45ab6108cc41c20f416a98615aa8c349f02a275b (etherscan) Original deployer - ownership has NEVER changed since deployment (March 2016)
Public Tag etherdoubler.com Historic Ponzi scheme website (no longer active)

Attempted Ownership Transfers

Multiple addresses have called setOwner() since 2019 (most recently January 2026), but due to the broken onlyowner modifier, all transactions succeeded while doing nothing. The owner has never changed. See Critical Security Discovery below for details.


Executive Summary

The Doubler contract is a historically significant Ethereum Smart Contract deployed in March 2016 that implements a queue-based Ponzi Scheme. The contract promised to double participants' investments by using funds from new participants to pay earlier participants, while extracting a 10% fee for the owner on each deposit. The mechanics are visible in the verified source code, though the associated website (etherdoubler.com) is no longer available and no archived version of its claims has been found.

Primary Purpose: Accept ETH deposits of 1+ ETH and promise to return 2x the deposited amount (minus 10% fee), funded by subsequent participants' deposits.

Intended Audience: Early Ethereum users. Whether participants understood the Ponzi mechanics is unknown — the website (etherdoubler.com) is no longer available.

Key Mechanisms:

  • Queue-based payout system: participants are added to an array and paid out in FIFO order
  • Minimum deposit: 1 ETH
  • Payout trigger: when contract balance exceeds 2x the next participant's deposit
  • Owner fee: 10% of each deposit (except the first participant, who paid 100% in fees)
  • No events emitted, making on-chain tracking difficult without storage queries

Significant Trust Assumptions:

  • Contract owner could transfer ownership to malicious address
  • Participants must trust the Ponzi mechanics will continue (no guarantee of payout)
  • No Timelock or Multisig protection on owner functions
  • Uses deprecated send() which can fail silently if recipient has Fallback Function logic

Notable Risks:

  • Guaranteed Losses: Mathematical certainty that late participants lose 100% of deposits
  • Broken Access Control: The onlyowner modifier silently fails instead of reverting (see Potential Risks)
  • Old Solidity Version: Contains multiple known compiler vulnerabilities
  • Failed Sends: send() returns false on failure but contract doesn't handle it
  • Centralization: Single owner can withdraw all accumulated fees at any time
  • Accounting Mismatch: Contract's internal balance variable doesn't match actual ETH balance

Architecture

graph TB
    User[Participant] -->|1+ ETH| Fallback[Fallback Function]
    Fallback --> Enter[enter Function]

    Enter --> Check{msg.value >= 1 ETH?}
    Check -->|No| Refund[Refund via send]
    Check -->|Yes| AddQueue[Add to participants array]

    AddQueue --> CalcFees[Calculate 10% fee]
    CalcFees --> UpdateBalance[Update internal balance]
    UpdateBalance --> PayoutCheck{Balance > 2x next payout?}

    PayoutCheck -->|No| End1[Wait for more deposits]
    PayoutCheck -->|Yes| Payout[Send 2x - 10% to participants payoutIdx]
    Payout --> IncrementIdx[payoutIdx += 1]
    IncrementIdx --> End2[Transaction Complete]

    Owner[Contract Owner] -->|onlyowner| CollectFees[collectFees Function]
    CollectFees --> SendFees[Send collectedFees to owner]

    Owner -->|onlyowner| SetOwner[setOwner Function]
    SetOwner --> TransferOwnership[Change owner address]

    style Check fill:#fff4cc
    style PayoutCheck fill:#fff4cc
    style Payout fill:#ccffcc
    style CollectFees fill:#ffcccc
    style SetOwner fill:#ffcccc

System Overview

The Doubler contract operates as a queue-based Ponzi Scheme where participants are paid from subsequent participants' deposits. The system is entirely self-contained with no external dependencies.

Core Mechanics:

  • Deposit: Any address sends 1+ ETH to the contract (via Fallback Function or direct enter() call)
  • Queueing: Participant's address and deposit amount are appended to the participants array
  • Fee Extraction: 10% of each deposit is added to collectedFees (owner's revenue)
  • Balance Tracking: 90% of each deposit (or 100% for first participant) is added to internal balance
  • Payout Trigger: When balance > participants[payoutIdx].amount * 2, the next queued participant receives 180% of their deposit (200% minus 10% entry fee)
  • Owner Withdrawal: Owner can withdraw collectedFees at any time via collectFees()

What This Contract Does:

  • Accepts ETH deposits and promises eventual 2x return
  • Maintains FIFO queue of participants waiting for payouts
  • Extracts 10% fee for contract owner on every deposit
  • Attempts to pay earlier participants when sufficient funds accumulate

What This Contract Does Not Do:

  • Does NOT generate any revenue or investment returns
  • Does NOT guarantee payouts (depends entirely on future deposits)
  • Does NOT emit Events (no transparency without direct storage queries)
  • Does NOT handle failed send() calls (silent failures possible)
  • Does NOT prevent owner from draining fees during active payouts

Design Patterns Used

Ponzi/Pyramid Queue Pattern: Maintains ordered array of participants with FIFO payout logic. This pattern is mathematically guaranteed to fail when new deposits stop, leaving unpaid participants with total losses.

Modifier-Based Access Control: Uses simple onlyowner modifier for privileged functions. However, the modifier uses deprecated syntax (if (msg.sender == owner) _) without explicit require() or revert().

Fallback Delegation: The unnamed fallback function delegates all direct ETH transfers to the enter() function, allowing seamless deposits without function calls.

Fee Extraction Pattern: Separates user deposits from owner revenue via collectedFees accumulator and withdrawal function, allowing owner to extract profits independently of participant payouts.


Access Control

Roles & Permissions

ROLE ASSIGNED BY REVOKABLE CALL COUNT
Owner Constructor (set to msg.sender at deployment) Yes - via setOwner() Owner functions callable unlimited times
Participant Self-assignment (anyone who sends 1+ ETH) No - permanent queue position Unlimited participants (array grows unbounded)

Permission Matrix

FUNCTION OWNER PARTICIPANT ANYONE
Doubler() (constructor) N/A N/A
fallback()
enter()
collectFees()
setOwner()

Time Locks & Delays

ACTION TIME LOCK CAN CANCEL PURPOSE
Transfer Ownership ☒ None - Immediate ☒ No △ No protection - owner can be changed instantly
Collect Fees ☒ None - Immediate ☒ No △ No protection - fees can be withdrawn at any time
Participant Payout ☒ None - Immediate ☒ No ☑ Automatic when balance threshold met

Economic Model

Ponzi Payout Flow

flowchart TD
    Start([Participant Sends 1+ ETH]) --> QueueAdd[Added to participants array at index N]

    QueueAdd --> FeeSplit{First Participant?}
    FeeSplit -->|Yes idx=0| Fee100[100% → collectedFees]
    FeeSplit -->|No idx>0| Fee10[10% → collectedFees<br/>90% → balance]

    Fee100 --> WaitInQueue[Wait in Queue Position 0]
    Fee10 --> WaitInQueue2[Wait in Queue Position N]

    WaitInQueue --> CheckPayout{Enough balance to pay<br/>participant at payoutIdx?}
    WaitInQueue2 --> CheckPayout

    CheckPayout -->|No| KeepWaiting[Remain in Queue]
    CheckPayout -->|Yes| Calculate[Calculate Payout:<br/>2 × deposit × 0.9 = 180%]

    Calculate --> SendPayout[Send payout via .send]
    SendPayout --> Success{Send Successful?}

    Success -->|Yes| UpdateQueue[payoutIdx += 1<br/>balance -= 2 × deposit]
    Success -->|No| SilentFail[△ Send failed silently<br/>payoutIdx still incremented]

    UpdateQueue --> NextInLine[Next participant in queue]
    SilentFail --> NextInLine

    KeepWaiting --> MoreDeposits{More deposits arrive?}
    MoreDeposits -->|Yes| CheckPayout
    MoreDeposits -->|No| StuckForever[☒ Stuck in queue permanently]

    style Fee100 fill:#ffcccc
    style Fee10 fill:#fff4cc
    style StuckForever fill:#ffcccc
    style SilentFail fill:#ffcccc

Fee Structure

FEE TYPE PERCENTAGE RECIPIENT PURPOSE NOTES
Entry Fee (First Participant) 100% Owner (via collectedFees) Owner revenue First participant receives nothing, pure fee
Entry Fee (All Others) 10% Owner (via collectedFees) Owner revenue Reduces effective balance for payouts
Payout Amount 180% of deposit Earlier participants Ponzi payout 200% gross - 10% entry fee = 180% net

Funding Sources & Sinks

Inflows:

  • Participant deposits via fallback function or enter() (minimum 1 ETH)
  • No external revenue generation
  • System is closed-loop (payouts funded only by new deposits)

Outflows:

  • Participant payouts: 180% of original deposit (when queue position reached)
  • Owner fee withdrawal: 10% of all deposits (via collectFees())
  • Refunds: Full refund for deposits < 1 ETH

Economic Invariants

Broken Invariants:

  1. Balance Accounting Mismatch: The contract's internal balance variable (27.44 ETH) does not match the actual ETH balance (32.44 ETH). This 5 ETH discrepancy suggests either:
    - Failed send() calls that didn't revert the transaction
    - Accounting errors in the balance update logic
    - Direct ETH transfers to the contract that bypassed enter()

  2. Guaranteed Insolvency: With 321 participants and only 118 paid out, 203 participants remain in queue. The current contract balance (32.44 ETH) is insufficient to pay even the next participant, let alone all 203 remaining. The contract is mathematically insolvent.

  3. No New Deposits: The last transaction occurred years ago. With no new deposits, the remaining 203 participants have zero chance of receiving payouts.


Summary of Observations

The Doubler contract is a historically significant artifact from early Ethereum (2016) that implemented a Ponzi scheme with mechanics clearly visible in its verified source code. The code is straightforward in its intent: accept deposits, queue participants, extract 10% fees for the owner, and pay earlier participants 180% when sufficient funds accumulate from later participants.

Primary Purpose: The contract implemented a Ponzi scheme on Ethereum. The mechanics are visible in the verified source code, though how the scheme was marketed to participants via etherdoubler.com is unknown.

Significant Mechanisms:

  • FIFO queue with unbounded array growth (321 participants total)
  • Simple arithmetic for fee extraction and payout calculation
  • No emergency stop, pause, or recovery mechanisms
  • Deprecated send() instead of modern call{value: x}("") pattern

Significant Financial Observations:

  • Total Deposits: Approximately 32.44 ETH currently locked in contract
  • Participants Paid: 118 out of 321 (36.8% payout rate)
  • Participants Stuck: 203 participants will never receive payouts
  • Owner Fees: All collected fees (10% of deposits) have been withdrawn (collectedFees = 0)
  • Accounting Error: 5 ETH discrepancy between internal balance and actual ETH balance

Significant Concerns:

  • Contract is mathematically insolvent and cannot pay remaining participants
  • Uses Solidity v0.2.0 which contains numerous known vulnerabilities
  • No events make it difficult for participants to track queue position
  • Silent send failures could result in payoutIdx incrementing without actual payment
  • Owner can change ownership without any delay or governance

Strengths:

  • Source code is verified and publicly auditable
  • Logic is simple and easy to understand (no obfuscation)
  • Ponzi mechanics are visible in verified source code (no obfuscation)
  • Immutable code (no upgrade mechanism)

Weaknesses:

  • Economically guaranteed to fail (Ponzi mathematics)
  • Old Solidity version with known security issues
  • Poor error handling (send failures ignored)
  • No participant protections or recovery mechanisms
  • Centralized owner control over fees and ownership transfer

This contract represents a category of early Ethereum experiments that tested social and economic mechanisms on-chain. While technically functional, it is economically predatory and serves primarily as a historical example of what NOT to build. The 203 remaining participants who deposited approximately 32.44 ETH have lost their funds permanently.

This analysis was performed for educational purposes and should not be considered an official security audit or financial advice. This contract is defunct and should not be interacted with except for academic study.


References

RESOURCE NOTES
Etherscan Contract Page Verified source code and transaction history
Solidity v0.2.0 Documentation Legacy compiler version documentation
Ethereum Yellow Paper EVM specification for understanding bytecode

Change Log

DATE AUTHOR NOTES
2026-02-13 Artificial. Generated by robots. Gas: 75 tok
2026-02-13 Denizen. Reviewed, edited, and curated by humans.