diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/cyberdyne/market.se')
-rw-r--r-- | Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/cyberdyne/market.se | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/cyberdyne/market.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/cyberdyne/market.se new file mode 100644 index 000000000..2303a0b60 --- /dev/null +++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/cyberdyne/market.se @@ -0,0 +1,117 @@ +# Creates a decentralized market between any two subcurrencies + +# Here, the first subcurrency is the base asset and the second +# subcurrency is the asset priced against the base asset. Hence, +# "buying" refers to trading the first for the second, and +# "selling" refers to trading the second for the first + +# storage 0: buy orders +# storage 1: sell orders +# storage 1000: first subcurrency +# storage 1001: last first subcurrency txid +# storage 2000: second subcurrency +# storage 2001: last second subcurrency txid +# storage 3000: current epoch +# storage 4000: price +# storage 4001: volume + +init: + # Heap for buy orders + contract.storage[0] = create('heap.se') + # Heap for sell orders + contract.storage[1] = create('heap.se') +code: + # Initialize with [ first_subcurrency, second_subcurrency ] + if !contract.storage[1000]: + contract.storage[1000] = msg.data[0] # First subcurrency + contract.storage[1001] = -1 + contract.storage[2000] = msg.data[1] # Second subcurrency + contract.storage[2001] = -1 + contract.storage[3000] = block.number / 1000 + stop + first_subcurrency = contract.storage[1000] + second_subcurrency = contract.storage[2000] + buy_heap = contract.storage[0] + sell_heap = contract.storage[1] + # This contract operates in "epochs" of 100 blocks + # At the end of each epoch, we process all orders + # simultaneously, independent of order. This algorithm + # prevents front-running, and generates a profit from + # the spread. The profit is permanently kept in the + # market (ie. destroyed), making both subcurrencies + # more valuable + + # Epoch transition code + if contract.storage[3000] < block.number / 100: + done = 0 + volume = 0 + while !done: + # Grab the top buy and sell order from each heap + topbuy = call(buy_heap, 1) + topsell = call(sell_heap, 1) + # An order is recorded in the heap as: + # Buys: (2^48 - 1 - price) * 2^208 + units of first currency * 2^160 + from + # Sells: price * 2^208 + units of second currency * 2^160 + from + buyprice = -(topbuy / 2^208) + buyfcvalue = (topbuy / 2^160) % 2^48 + buyer = topbuy % 2^160 + sellprice = topsell / 2^208 + sellscvalue = (topsell / 2^160) % 2^48 + seller = topsell % 2^160 + # Heap empty, or no more matching orders + if not topbuy or not topsell or buyprice < sellprice: + done = 1 + else: + # Add to volume counter + volume += buyfcvalue + # Calculate how much of the second currency the buyer gets, and + # how much of the first currency the seller gets + sellfcvalue = sellscvalue / buyprice + buyscvalue = buyfcvalue * sellprice + # Send the currency units along + call(second_subcurrency, [buyer, buyscvalue], 2) + call(first_subcurrency, [seller, sellfcvalue], 2) + if volume: + contract.storage[4000] = (buyprice + sellprice) / 2 + contract.storage[4001] = volume + contract.storage[3000] = block.number / 100 + # Make buy order [0, price] + if msg.data[0] == 0: + # We ask the first subcurrency contract what the last transaction was. The + # way to make a buy order is to send the amount of first currency units that + # you wish to buy 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] + price = msg.data[1] + if txid > contract.storage[1001] and to == contract.address: + contract.storage[1001] = txid + # Adds the order to the heap + call(buy_heap, [0, -price * 2^208 + (value % 2^48) * 2^160 + from], 2) + # Make sell order [1, price] + elif msg.data[0] == 1: + # Same mechanics as buying + data = call(second_subcurrency, [], 0, 4) + from = data[0] + to = data[1] + value = data[2] + txid = data[3] + price = msg.data[1] + if txid > contract.storage[2001] and to == contract.address: + contract.storage[2001] = txid + call(sell_heap, [0, price * 2^208 + (value % 2^48) * 2^160 + from], 2) + # Ask for price + elif msg.data[0] == 2: + return(contract.storage[4000]) + # Ask for volume + elif msg.data[0] == 3: + return(contract.storage[1000]) + # Ask for first currency + elif msg.data[0] == 4: + return(contract.storage[2000]) + # Ask for second currency + elif msg.data[0] == 5: + return(contract.storage[4001]) |