Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
137 lines (135 sloc) 5.87 KB
# 0: current epoch
# 1: number of proposals
# 2: master currency
# 3: last winning market
# 4: last txid
# 5: long-term ema currency units purchased
# 6: last block when currency units purchased
# 7: ether allocated to last round
# 8: last block when currency units claimed
# 9: ether allocated to current round
# 1000+: [proposal address, market ID, totprice, totvolume]
init:
# We technically have two levels of epoch here. We have
# one epoch of 1000, to synchronize with the 1000 epoch
# of the market, and then 100 of those epochs make a
# meta-epoch (I'll nominate the term "seculum") over
# which the futarchy protocol will take place
contract.storage[0] = block.number / 1000
# The master currency of the futarchy. The futarchy will
# assign currency units to whoever the prediction market
# thinks will best increase the currency's value
master_currency = create('subcurrency.se')
contract.storage[2] = master_currency
code:
curepoch = block.number / 1000
prevepoch = contract.storage[0]
if curepoch > prevepoch:
if (curepoch % 100) > 50:
# Collect price data
# We take an average over 50 subepochs to determine
# the price of each asset, weighting by volume to
# prevent abuse
contract.storage[0] = curepoch
i = 0
numprop = contract.storage[1]
while i < numprop:
market = contract.storage[1001 + i * 4]
price = call(market, 2)
volume = call(market, 3)
contract.storage[1002 + i * 4] += price
contract.storage[1003 + i * 4] += volume * price
i += 1
if (curepoch / 100) > (prevepoch / 100):
# If we are entering a new seculum, we determine the
# market with the highest total average price
best = 0
bestmarket = 0
besti = 0
i = 0
while i < numprop:
curtotprice = contract.storage[1002 + i * 4]
curvolume = contract.storage[1002 + i * 4]
curavgprice = curtotprice / curvolume
if curavgprice > best:
best = curavgprice
besti = i
bestmarket = contract.storage[1003 + i * 4]
i += 1
# Reset the number of proposals to 0
contract.storage[1] = 0
# Reward the highest proposal
call(contract.storage[2], [best, 10^9, 0], 3)
# Record the winning market so we can later appropriately
# compensate the participants
contract.storage[2] = bestmarket
# The amount of ether allocated to the last round
contract.storage[7] = contract.storage[9]
# The amount of ether allocated to the next round
contract.storage[9] = contract.balance / 2
# Make a proposal [0, address]
if msg.data[0] == 0 and curepoch % 100 < 50:
pid = contract.storage[1]
market = create('market.se')
c1 = create('subcurrency.se')
c2 = create('subcurrency.se')
call(market, [c1, c2], 2)
contract.storage[1000 + pid * 4] = msg.data[1]
contract.storage[1001 + pid * 4] = market
contract.storage[1] += 1
# Claim ether [1, address]
# One unit of the first currency in the last round's winning
# market entitles you to a quantity of ether that was decided
# at the start of that epoch
elif msg.data[0] == 1:
first_subcurrency = call(contract.storage[2], 3)
# We ask the first subcurrency contract what the last transaction was. The
# way to make a claim is to send the amount of first currency units that
# you wish to claim with, and then immediately call this contract. For security
# it makes sense to set up a tx which sends both messages in sequence atomically
data = call(first_subcurrency, [], 0, 4)
from = data[0]
to = data[1]
value = data[2]
txid = data[3]
if txid > contract.storage[4] and to == contract.address:
send(to, contract.storage[7] * value / 10^9)
contract.storage[4] = txid
# Claim second currency [2, address]
# One unit of the second currency in the last round's winning
# market entitles you to one unit of the futarchy's master
# currency
elif msg.data[0] == 2:
second_subcurrency = call(contract.storage[2], 3)
data = call(first_subcurrency, [], 0, 4)
from = data[0]
to = data[1]
value = data[2]
txid = data[3]
if txid > contract.storage[4] and to == contract.address:
call(contract.storage[2], [to, value], 2)
contract.storage[4] = txid
# Purchase currency for ether (target releasing 10^9 units per seculum)
# Price starts off 1 eth for 10^9 units but increases hyperbolically to
# limit issuance
elif msg.data[0] == 3:
pre_ema = contract.storage[5]
post_ema = pre_ema + msg.value
pre_reserve = 10^18 / (10^9 + pre_ema / 10^9)
post_reserve = 10^18 / (10^9 + post_ema / 10^9)
call(contract.storage[2], [msg.sender, pre_reserve - post_reserve], 2)
last_sold = contract.storage[6]
contract.storage[5] = pre_ema * (100000 + last_sold - block.number) + msg.value
contract.storage[6] = block.number
# Claim all currencies as the ether miner of the current block
elif msg.data[0] == 2 and msg.sender == block.coinbase and block.number > contract.storage[8]:
i = 0
numproposals = contract.storage[1]
while i < numproposals:
market = contract.storage[1001 + i * 3]
fc = call(market, 4)
sc = call(market, 5)
call(fc, [msg.sender, 1000], 2)
call(sc, [msg.sender, 1000], 2)
i += 1
contract.storage[8] = block.number