1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00
ZoKrates/zokrates_cli/examples/dex/ringtrade_example.code

99 lines
No EOL
4.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import "./decodeOrder.code"
import "./limitLessThanPrice.code"
def tupleForTokensWithValue(field value) -> (field[3]):
return [value, value, value]
def tupleForTokenPairsWithValue(field value) -> (field[9]):
return [value, value, value, value, value, value, value, value, value]
def findPairInTokenPairList(field[9] pairs, field sourceToken, field targetToken) -> (field):
return pairs[sourceToken * 3 + targetToken]
// add `volume` to element `token` in `volumeToken`
def addVolumesForOrder(field[3] volumeToken, field token, field volume) -> (field[3]):
for field i in 0..3 do
volumeToken[i] = volumeToken[i] + if token == i then volume else 0 fi
endfor
return volumeToken
def updateHighestTouchedOrder(field[9] highestTouchedOrder, field sourceToken, field targetToken, field limit, field volume) -> (field[9]):
field highest = findPairInTokenPairList(highestTouchedOrder, sourceToken, targetToken)
field shouldUpdate = if 0 < volume then 1 else 0 fi
shouldUpdate = if highest < limit then shouldUpdate else 0 fi
highestTouchedOrder[sourceToken * 3 + targetToken] = if shouldUpdate == 1 then limit else highestTouchedOrder[sourceToken * 3 + targetToken] fi
return highestTouchedOrder
def verifyCompletelyFulfilledIfLimitLowerHighestTouchedOrder(field[9] highestTouchedOrder, field sourceAmount, field sourceToken, field targetToken, field limit, field volume) -> (field):
field highest = findPairInTokenPairList(highestTouchedOrder, sourceToken, targetToken)
field valid = if limit < highest then 1 - (sourceAmount - volume) else 1 fi
return valid
def checkConstraints(field[3] amount, field[3] sourceToken, field[3] targetToken, field[3] limit, field[3] volume, field[3] priceToken) -> (field):
// volumes are not larger than in original offer
for field i in 0..3 do
1 == if amount[i] < volume[i] then 0 else 1 fi
endfor
field[3] sourceTokenPriceOrder = [0, 0, 0]
field[3] targetTokenPriceOrder = [0, 0, 0]
for field i in 0..3 do
sourceTokenPriceOrder[i] = priceToken[sourceToken[i]]
targetTokenPriceOrder[i] = priceToken[targetToken[i]]
endfor
// orders are only touched, if the limit price is below the calculated price:
for field i in 0..3 do
1 == if volume[i] == 0 then 1 else limitLessThanPrice(sourceTokenPriceOrder[i], targetTokenPriceOrder[i], limit[i]) fi
endfor
// the amount of sell volume for a token equals its buy volume:
buyVolumeToken = tupleForTokensWithValue(0)
sellVolumeToken = tupleForTokensWithValue(0)
for field i in 0..3 do
buyVolumeToken = addVolumesForOrder(buyVolumeToken, targetToken[i], volume[i] * sourceTokenPriceOrder[i])
sellVolumeToken = addVolumesForOrder(sellVolumeToken, sourceToken[i], volume[i] * sourceTokenPriceOrder[i])
endfor
buyVolumeToken == sellVolumeToken
// If an order σ ∈ Oi→j with a limit price p has a positive trading volume, then every order in Oi→j with a lower limit price should be completely fulfilled.
highestTouchedOrder = tupleForTokenPairsWithValue(0)
for field i in 0..3 do
highestTouchedOrder = updateHighestTouchedOrder(highestTouchedOrder, sourceToken[i], targetToken[i], limit[i], volume[i])
endfor
for field i in 0..3 do
1 == verifyCompletelyFulfilledIfLimitLowerHighestTouchedOrder(highestTouchedOrder, amount[i], sourceToken[i], targetToken[i], limit[i], volume[i])
endfor
return 1 // Could return total volume to maximize for
def main(private field[3] encodedOrder, private field[3] bitmapOrder, private field[3] volume, private field[3] priceToken) -> (field):
// Remove orders that are not double signed
encodedOrder = [if bitmapOrder[0] == 1 then encodedOrder[0] else 0 fi, if bitmapOrder[1] == 1 then encodedOrder[1] else 0 fi, if bitmapOrder[2] == 1 then encodedOrder[2] else 0 fi]
field[3] amount = [0, 0, 0]
field[3] sourceToken = [0, 0, 0]
field[3] targetToken = [0, 0, 0]
field[3] limit = [0, 0, 0]
// Decode orders
for field i in 0..3 do
a, s, t, l = decodeOrder(encodedOrder[i])
amount[i] = a
sourceToken[i] = s
targetToken[i] = t
limit[i] = l
endfor
return checkConstraints(amount, sourceToken, targetToken, limit, volume, priceToken)