Lotteresque: reimbursement + lottery + dividend.

Cost to participate: one ether.

Begins with zero participants. First participant fills up level one. Next two participants fill up level two. Next three participants fill up level three, and so on.

When a level fills up, three things happen:

1. Every participant in the previous two levels receives 0.5 ether (the "reimbursement").

2. Every participant in every level participates in a one-ether lottery.

3. Any remaining balance is divided equally amongst all participants in all levels (the "dividend").

Beginning with level two, the remaining balance is a minimum of 0.5 ether. It might also be higher; see "Errata", below.

To participate:

eth.sendTransaction({from:eth.accounts[0],to:"0xfbc128067a2fe13c11bbc6cc55f29aa1f27630da",value:web3.toWei(1,"ether"),gas:500000});

To monitor:

var lotteresqueContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"next","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"participants","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"balance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[],"type":"constructor"}]);

var lotteresque = lotteresqueContract.at("0xfbc128067a2fe13c11bbc6cc55f29aa1f27630da");

lotteresque.balance();

lotteresque.participants();

lotteresque.next();

Errata:

If less than one ether is sent, the sender does not participate and the entire amount is added to the contract balance for distribution to the participants.

If more than one ether is sent, the sender does participate and the surplus amount is added to the contract balance for distribution to the participants.

Code:

contract lotteresque {

uint public balance;

uint depth;

uint public participants;

address[] tree;

function lotteresque() {

tree.length = 1;

}

function () {

uint dividend;

uint i;

uint lower;

uint upper;

balance += msg.value;

if ( msg.value >= 1000000000000000000 ) {

tree[ participants++ ] = msg.sender;

if ( participants == tree.length ) {

depth++;

// reimbursement

if ( depth > 1 ) {

lower = participants - 3 * ( depth - 1 );

upper = participants - depth;

for ( i = lower; i < upper; i++ ) {

tree[ i ].send( 500000000000000000 );

}

balance -= ( upper - lower ) * 500000000000000000;

}

// lottery

tree[ uint( block.blockhash( block.number - 1 ) ) % participants ].send( 1000000000000000000 );

balance -= 1000000000000000000;

// dividend

if ( balance > 0 ) {

dividend = balance / participants;

for ( i = 0; i < participants; i++ ) {

tree[ i ].send( dividend );

}

balance -= participants * dividend;

}

tree.length += depth + 1;

}

}

}

function next() constant returns ( uint ) {

return tree.length;

}