diff --git a/batcher-ui/src/config/env.ts b/batcher-ui/src/config/env.ts index 7ed1731e..24362694 100644 --- a/batcher-ui/src/config/env.ts +++ b/batcher-ui/src/config/env.ts @@ -6,9 +6,9 @@ module.exports = { 'https://storage.googleapis.com/marigold-public-bucket/batcher-logo.png', NEXT_PUBLIC_TEZOS_NODE_URI: 'https://ghostnet.tezos.marigold.dev/', NEXT_PUBLIC_TZKT_URI_API: 'https://api.ghostnet.tzkt.io', - NEXT_PUBLIC_BATCHER_CONTRACT_HASH: 'KT1UPMR3WkoFRJYmBBbvv4Z9bBhKYuhCx7Cq', + NEXT_PUBLIC_BATCHER_CONTRACT_HASH: 'KT1LhTpwSGcFAUUM3JYjW8XW74UHP82YzERy', NEXT_PUBLIC_MARKETMAKER_CONTRACT_HASH: - 'KT1TNX1YLCmPJN4rbwAUsUAdnqVYrZ5X5YNB', + 'KT1XKvKiTTj8N6WKv3MhnZhFjZopFGQGBTdT', NEXT_PUBLIC_LOCAL_STORAGE_KEY_STATE: 'batcher-state', NEXT_PUBLIC_GA_TRACKING_ID: 'G-2K59PEELC8', }, diff --git a/batcher/batcher.mligo b/batcher/batcher.mligo index 42cf8c84..942ccf0b 100644 --- a/batcher/batcher.mligo +++ b/batcher/batcher.mligo @@ -1486,15 +1486,6 @@ let redeemable_holdings_available ((), storage : unit * storage) : bool = | None -> false | Some bots -> Map.fold find_non_zero_holding bots false -(* Mapping order type to total amount of placed orders *) -type ordertypes = (ordertype, nat) map - -(* pairing of batch_id and ordertypes. *) -type batch_ordertypes = (nat, ordertypes) map - -(* Associated user address to a given set of batches and ordertypes *) -type user_batch_ordertypes = (address, batch_ordertypes) big_map - [@view] let get_current_batches ((),storage: unit * storage) : batch list= let collect_batches (acc, (_s, i) : batch list * (string * nat)) : batch list = @@ -1504,17 +1495,6 @@ let get_current_batches ((),storage: unit * storage) : batch list= in Map.fold collect_batches storage.batch_set.current_batch_indices [] -[@view] -let get_current_batches_reduced ((), storage: unit * storage) : reduced_batch list = - let current_batches: batch list = get_current_batches ((),storage) in - let map_to_reduced (b: batch) : reduced_batch = { - status = b.status; - volumes = b.volumes; - market_vault_used = b.market_vault_used; - } - in - List.map map_to_reduced current_batches - let main (action, storage : entrypoint * storage) : operation list * storage = diff --git a/batcher/errors.mligo b/batcher/errors.mligo index 732c15ed..d53824ed 100644 --- a/batcher/errors.mligo +++ b/batcher/errors.mligo @@ -57,7 +57,7 @@ [@inline] let no_holdings_to_claim = 155n [@inline] let incorrect_side_specified = 156n [@inline] let entrypoint_does_not_exist = 157n -[@inline] let unable_to_get_reduced_batches_from_batcher = 158n +[@inline] let unable_to_get_batches_from_batcher = 158n [@inline] let unable_to_get_oracle_price = 159n [@inline] let contract_does_not_exist = 160n [@inline] let unable_to_call_on_chain_view = 161n diff --git a/batcher/marketmaker-ghostnet.tz b/batcher/marketmaker-ghostnet.tz index 0753dad8..76526f76 100644 --- a/batcher/marketmaker-ghostnet.tz +++ b/batcher/marketmaker-ghostnet.tz @@ -1025,8 +1025,9 @@ CAR ; CDR ; UNIT ; - VIEW "get_current_batches_reduced" - (list (pair (or %status + VIEW "get_current_batches" + (list (pair (nat %batch_number) + (or %status (or (pair %cleared (pair (timestamp %at) (pair %clearing @@ -1056,15 +1057,19 @@ (nat %sell_exact_volume) (nat %sell_plus_volume) (nat %sell_total_volume)) + (pair %pair string string) + (nat %holdings) (bool %market_vault_used))) ; - IF_NONE { PUSH nat 158 ; FAILWITH } { DROP } ; + IF_NONE { PUSH nat 158 ; FAILWITH } {} ; NIL string ; - DUP 2 ; + DUP 3 ; CAR ; CDR ; CDR ; CDR ; ITER { CAR ; CONS } ; + DIG 2 ; + SWAP ; ITER { SWAP ; DUP ; CDR ; @@ -1174,7 +1179,7 @@ SUB ; PUSH int 10 ; PAIR ; - DUP 15 ; + DUP 16 ; SWAP ; EXEC ; DIG 3 ; @@ -1188,11 +1193,11 @@ INT ; PUSH int 10 ; PAIR ; - DUP 15 ; + DUP 16 ; SWAP ; EXEC ; SWAP } - { INT ; PUSH int 10 ; PAIR ; DUP 15 ; SWAP ; EXEC ; DIG 3 } ; + { INT ; PUSH int 10 ; PAIR ; DUP 16 ; SWAP ; EXEC ; DIG 3 } ; INT ; PUSH int 1 ; DIG 2 ; @@ -1244,7 +1249,7 @@ INT ; PUSH int 10 ; PAIR ; - DUP 13 ; + DUP 14 ; SWAP ; EXEC ; PUSH int 0 ; @@ -1361,7 +1366,7 @@ PUSH nat 0 ; PUSH nat 10 ; PAIR 3 ; - DUP 14 ; + DUP 15 ; SWAP ; EXEC ; DIG 2 ; @@ -1385,7 +1390,7 @@ PUSH nat 0 ; PUSH nat 10 ; PAIR 3 ; - DUP 14 ; + DUP 15 ; SWAP ; EXEC ; DIG 2 ; @@ -1656,8 +1661,8 @@ CDR ; UPDATE 2 ; UPDATE 2 } } ; - SWAP ; DIG 2 ; + DIG 3 ; DROP 2 ; DUP ; CAR ; @@ -1679,8 +1684,470 @@ TRANSFER_TOKENS ; SOME } { NONE operation } ; + DUP 2 ; NIL operation ; - DUG 2 ; + PAIR ; + DIG 3 ; + ITER { SWAP ; + UNPAIR ; + DUP 5 ; + CAR ; + CAR ; + CAR ; + CDR ; + DUP 4 ; + GET 10 ; + IF { DIG 3 ; DROP 2 ; DUP 2 ; CDR ; CDR ; NIL operation ; PAIR } + { PUSH nat 0 ; + DUP 5 ; + GET 5 ; + GET 7 ; + COMPARE ; + EQ ; + IF { NONE nat } { DUP 4 ; GET 5 ; GET 7 ; SOME } ; + PUSH nat 0 ; + DUP 6 ; + GET 5 ; + GET 14 ; + COMPARE ; + EQ ; + IF { NONE nat } { DUP 5 ; GET 5 ; GET 14 ; SOME } ; + IF_NONE + { IF_NONE + { DIG 3 ; DROP 2 ; DUP 2 ; CDR ; CDR ; NIL operation ; PAIR } + { DIG 4 ; + GET 7 ; + UNPAIR ; + DUP 6 ; + CAR ; + CDR ; + CDR ; + CDR ; + SWAP ; + GET ; + IF_NONE + { DROP 3 ; PUSH nat 138 ; FAILWITH } + { DUP 6 ; + CAR ; + CDR ; + CDR ; + CDR ; + DIG 2 ; + GET ; + IF_NONE + { DROP 3 ; PUSH nat 138 ; FAILWITH } + { DUP 6 ; + CDR ; + CDR ; + DUP ; + DUP 4 ; + GET 3 ; + GET ; + IF_NONE + { DIG 3 ; DROP 2 ; PUSH nat 152 ; FAILWITH } + { DUP ; + CDR ; + CAR ; + DUP 2 ; + CDR ; + CAR ; + CDR ; + DUP ; + DUP 8 ; + COMPARE ; + LT ; + IF { DROP ; DIG 5 } { DIG 6 ; DROP } ; + DUP 2 ; + DUP 2 ; + DIG 3 ; + CDR ; + SUB ; + ABS ; + UPDATE 2 ; + DIG 3 ; + DUP 4 ; + DIG 4 ; + CDR ; + DIG 3 ; + UPDATE 1 ; + UPDATE 2 ; + SOME ; + DUP 5 ; + GET 3 ; + UPDATE ; + SWAP ; + PAIR } ; + UNPAIR ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + EQ ; + IF { DIG 2 ; DIG 3 ; DIG 4 ; DROP 4 ; NIL operation } + { DIG 2 ; + DIG 3 ; + UNIT ; + LEFT unit ; + UNIT ; + LEFT unit ; + LEFT unit ; + IF_LEFT + { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 0 } } + { DROP ; PUSH nat 2 } ; + SWAP ; + IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } ; + NOW ; + DIG 4 ; + DIG 5 ; + DIG 5 ; + PAIR ; + PAIR ; + PAIR 4 ; + DUP ; + CAR ; + CAR ; + CAR ; + GET 5 ; + IF_NONE + { DIG 2 ; DROP 2 ; PUSH nat 109 ; FAILWITH } + { DUP 2 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA1.2 token" ; SWAP ; COMPARE ; EQ } ; + IF { DUP ; + CONTRACT %approve (pair (address %spender) (nat %value)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 4 ; + CAR ; + CAR ; + CDR ; + DUP 7 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 2 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA2 token" ; SWAP ; COMPARE ; EQ } ; + IF { SELF_ADDRESS ; + DUP 2 ; + CONTRACT %add_operator + (pair (pair (address %operator) (address %owner)) (nat %token_id)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 5 ; + CAR ; + CAR ; + CAR ; + CAR ; + DIG 3 ; + DUP 8 ; + PAIR ; + PAIR ; + TRANSFER_TOKENS } + { PUSH nat 108 ; FAILWITH } } ; + DUP 5 ; + CONTRACT %deposit + (pair (pair %swap + (pair %from + (pair %token + (nat %token_id) + (string %name) + (option %address address) + (nat %decimals) + (option %standard string)) + (nat %amount)) + (pair %to + (nat %token_id) + (string %name) + (option %address address) + (nat %decimals) + (option %standard string))) + (timestamp %created_at) + (nat %side) + (nat %tolerance)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 5 ; + TRANSFER_TOKENS ; + DUP 4 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA1.2 token" ; SWAP ; COMPARE ; EQ } ; + IF { DIG 2 ; DIG 3 ; DIG 5 ; DROP 3 ; NONE operation } + { DUP 4 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA2 token" ; SWAP ; COMPARE ; EQ } ; + IF { SELF_ADDRESS ; + DIG 3 ; + CONTRACT %remove_operator + (pair (pair (address %operator) (address %owner)) (nat %token_id)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 5 ; + CAR ; + CAR ; + CAR ; + CAR ; + DIG 3 ; + DIG 7 ; + PAIR ; + PAIR ; + TRANSFER_TOKENS ; + SOME } + { DIG 2 ; DIG 3 ; DIG 5 ; DROP 3 ; PUSH nat 108 ; FAILWITH } } ; + IF_NONE { NIL operation } { NIL operation ; SWAP ; CONS } ; + SWAP ; + CONS ; + SWAP ; + CONS } } ; + PAIR } } } } + { SWAP ; + IF_NONE + { DIG 4 ; + GET 7 ; + UNPAIR ; + DUP 6 ; + CAR ; + CDR ; + CDR ; + CDR ; + SWAP ; + GET ; + IF_NONE + { DROP 3 ; PUSH nat 138 ; FAILWITH } + { DUP 6 ; + CAR ; + CDR ; + CDR ; + CDR ; + DIG 2 ; + GET ; + IF_NONE + { DROP 3 ; PUSH nat 138 ; FAILWITH } + { DUP 6 ; + CDR ; + CDR ; + DUP ; + DUP 3 ; + GET 3 ; + GET ; + IF_NONE + { DIG 3 ; DROP 2 ; PUSH nat 152 ; FAILWITH } + { DUP ; + CDR ; + CAR ; + DUP 2 ; + CDR ; + CAR ; + CDR ; + DUP ; + DUP 8 ; + COMPARE ; + LT ; + IF { DROP ; DIG 5 } { DIG 6 ; DROP } ; + DUP 2 ; + DUP 2 ; + DIG 3 ; + CDR ; + SUB ; + ABS ; + UPDATE 2 ; + DIG 3 ; + DUP 4 ; + DIG 4 ; + CDR ; + DIG 3 ; + UPDATE 1 ; + UPDATE 2 ; + SOME ; + DUP 4 ; + GET 3 ; + UPDATE ; + SWAP ; + PAIR } ; + UNPAIR ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + EQ ; + IF { DIG 2 ; DIG 3 ; DIG 4 ; DROP 4 ; NIL operation } + { DIG 3 ; + DIG 3 ; + UNIT ; + RIGHT unit ; + UNIT ; + LEFT unit ; + LEFT unit ; + IF_LEFT + { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 0 } } + { DROP ; PUSH nat 2 } ; + SWAP ; + IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } ; + NOW ; + DIG 4 ; + DIG 5 ; + DIG 5 ; + PAIR ; + PAIR ; + PAIR 4 ; + DUP ; + CAR ; + CAR ; + CAR ; + GET 5 ; + IF_NONE + { DIG 2 ; DROP 2 ; PUSH nat 109 ; FAILWITH } + { DUP 2 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA1.2 token" ; SWAP ; COMPARE ; EQ } ; + IF { DUP ; + CONTRACT %approve (pair (address %spender) (nat %value)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 4 ; + CAR ; + CAR ; + CDR ; + DUP 7 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 2 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA2 token" ; SWAP ; COMPARE ; EQ } ; + IF { SELF_ADDRESS ; + DUP 2 ; + CONTRACT %add_operator + (pair (pair (address %operator) (address %owner)) (nat %token_id)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 5 ; + CAR ; + CAR ; + CAR ; + CAR ; + DIG 3 ; + DUP 8 ; + PAIR ; + PAIR ; + TRANSFER_TOKENS } + { PUSH nat 108 ; FAILWITH } } ; + DUP 5 ; + CONTRACT %deposit + (pair (pair %swap + (pair %from + (pair %token + (nat %token_id) + (string %name) + (option %address address) + (nat %decimals) + (option %standard string)) + (nat %amount)) + (pair %to + (nat %token_id) + (string %name) + (option %address address) + (nat %decimals) + (option %standard string))) + (timestamp %created_at) + (nat %side) + (nat %tolerance)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DUP 5 ; + TRANSFER_TOKENS ; + DUP 4 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA1.2 token" ; SWAP ; COMPARE ; EQ } ; + IF { DIG 2 ; DIG 3 ; DIG 5 ; DROP 3 ; NONE operation } + { DUP 4 ; + CAR ; + CAR ; + CAR ; + GET 8 ; + IF_NONE + { PUSH bool False } + { PUSH string "FA2 token" ; SWAP ; COMPARE ; EQ } ; + IF { SELF_ADDRESS ; + DIG 3 ; + CONTRACT %remove_operator + (pair (pair (address %operator) (address %owner)) (nat %token_id)) ; + IF_NONE { PUSH nat 157 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 5 ; + CAR ; + CAR ; + CAR ; + CAR ; + DIG 3 ; + DIG 7 ; + PAIR ; + PAIR ; + TRANSFER_TOKENS ; + SOME } + { DIG 2 ; DIG 3 ; DIG 5 ; DROP 3 ; PUSH nat 108 ; FAILWITH } } ; + IF_NONE { NIL operation } { NIL operation ; SWAP ; CONS } ; + SWAP ; + CONS ; + SWAP ; + CONS } } ; + PAIR } } } + { SWAP ; DIG 2 ; DIG 5 ; DROP 4 ; DUP 2 ; CDR ; CDR ; NIL operation ; PAIR } } } ; + UNPAIR ; + DUP 4 ; + DIG 4 ; + CDR ; + DIG 3 ; + UPDATE 2 ; + UPDATE 2 ; + NIL operation ; + DIG 3 ; + ITER { CONS } ; + DIG 2 ; + NIL operation ; + SWAP ; + ITER { CONS } ; + ITER { CONS } ; + NIL operation ; + SWAP ; + ITER { CONS } ; + PAIR } ; + DIG 2 ; + DROP ; + UNPAIR ; + SWAP ; + DIG 2 ; IF_NONE { SWAP } { DIG 2 ; SWAP ; CONS } } ; PAIR } } ; view "get_market_vault_holdings" diff --git a/batcher/marketmaker.mligo b/batcher/marketmaker.mligo index f610c728..eb884c75 100644 --- a/batcher/marketmaker.mligo +++ b/batcher/marketmaker.mligo @@ -24,7 +24,7 @@ type metadata_update = Types.metadata_update type swap_order = Types.swap_order type batch = Types.batch type batch_set = Types.batch_set -type reduced_batch = Types.reduced_batch +type external_swap_order = Types.external_swap_order module Storage = struct type t = { @@ -86,48 +86,6 @@ let create_liq_order redeemed = false; } -(* -let inject_buy_side_liquidity - (non: nat) - (last_rate:exchange_rate) - (sell_volume: nat) - (batch:batch) - (batch_set: batch_set) - (storage: Storage.t): batch * Storage.t = - let (buy_token,sell_token) = batch.pair in - match Big_map.find_opt buy_token storage.vaults with - | None -> batch,storage - | Some v -> let liq_amount = find_liquidity_amount last_rate v.native_token.amount sell_volume in - let order = create_liq_order batch.batch_number non buy_token sell_token Buy liq_amount storage.valid_tokens in - Batch_Utils.update_storage_with_order order non batch.number batch batch_set storage - -let inject_sell_side_liquidity - (non: nat) - (last_rate:exchange_rate) - (buy_volume: nat) - (batch:batch) - (batch_set: batch_set) - (storage: Storage.t): batch * Storage.t = - let (buy_token, sell_token) = batch.pair in - let mm = storage.market_maker in - match Big_map.find_opt sell_token mm.vaults with - | None -> batch,storage - | Some v -> let liq_amount = find_liquidity_amount last_rate v.native_token.amount buy_volume in - let order = create_liq_order batch.batch_number non sell_token buy_token Sell liq_amount storage.valid_tokens in - Batch_Utils.update_storage_with_order order non batch.number batch batch_set storage - -let inject_jit_liquidity - (last_rate:exchange_rate) - (batch:batch) - (next_order_number:nat) - (storage: Storage.t): batch * Storage.t = - let batch_set = storage.batch_set in - let buy_volume = batch.volumes.buy_total_volume in - let sell_volume = batch.volumes.sell_total_volume in - if (buy_volume > 0n) && (sell_volume = 0n) then inject_sell_side_liquidity next_order_number last_rate buy_volume batch batch_set storage else - if (buy_volume = 0n) && (sell_volume > 0n) then inject_buy_side_liquidity next_order_number last_rate sell_volume batch batch_set storage else - batch,storage -*) let create_or_update_market_vault_holding (id: nat) @@ -466,11 +424,109 @@ let redeem (storage: Storage.t): (operation option * Storage.t) = if Utils.has_redeemable_holdings storage.batcher then redeem_holdings storage else None,storage +[@inline] +let construct_order + (side:side) + (from_token:token) + (to_token:token) + (amount:nat) : external_swap_order = + let side_nat = Utils.side_to_nat side in + let tolerance = Utils.tolerance_to_nat Exact in + let swap = { + from= { + token = from_token; + amount= amount + }; + to = to_token; + } in + { + swap = swap; + created_at = Tezos.get_now (); + side = side_nat; + tolerance = tolerance; + } + + +[@inline] +let find_available_liquidity + (token:token) + (volume:nat) + (vaults:market_vaults): nat * market_vaults = + match Big_map.find_opt token.name vaults with + | None -> failwith Errors.no_market_vault_for_token + | Some v -> let nt = v.native_token in + let avail_liq = v.native_token.amount in + let liq = if volume < avail_liq then volume else avail_liq in + let nt = { nt with amount = abs(nt.amount - liq); } in + let v = { v with native_token = nt; } in + let uvs = Big_map.update token.name (Some v) vaults in + liq, uvs + +[@inline] +let inject_buy_side_liq + (sell_side_volume:nat) + (batcher:address) + (batch:batch) + (storage:Storage.t) : (operation list * market_vaults) = + let (buy_token,sell_token) = batch.pair in + let buy_token_opt = Map.find_opt buy_token storage.valid_tokens in + let sell_token_opt = Map.find_opt sell_token storage.valid_tokens in + match (buy_token_opt,sell_token_opt) with + | Some bt, Some st -> let liq,vaults = find_available_liquidity bt sell_side_volume storage.vaults in + if liq = 0n then + ([],vaults) + else + let order = construct_order Buy bt st liq in + let ops = Utils.execute_deposit order batcher in + (ops, vaults) + | _, _ -> failwith Errors.token_name_not_in_list_of_valid_tokens + +[@inline] +let inject_sell_side_liq + (buy_side_volume:nat) + (batcher:address) + (batch:batch) + (storage:Storage.t) : (operation list * market_vaults) = + let (buy_token,sell_token) = batch.pair in + let buy_token_opt = Map.find_opt buy_token storage.valid_tokens in + let sell_token_opt = Map.find_opt sell_token storage.valid_tokens in + match (buy_token_opt,sell_token_opt) with + | Some bt, Some st -> let liq, vaults = find_available_liquidity st buy_side_volume storage.vaults in + if liq = 0n then + ([],vaults) + else + let order = construct_order Sell st bt liq in + let ops = Utils.execute_deposit order batcher in + (ops, vaults) + | _, _ -> failwith Errors.token_name_not_in_list_of_valid_tokens + +[@inline] +let inject_liquidity_if_required + (batcher:address) + (batch:batch) + (storage: Storage.t): (operation list * market_vaults) = + if batch.market_vault_used then ([], storage.vaults) else + let buy_vol_opt = if batch.volumes.sell_total_volume = 0n then None else Some batch.volumes.sell_total_volume in + let sell_vol_opt = if batch.volumes.buy_total_volume = 0n then None else Some batch.volumes.buy_total_volume in + match (buy_vol_opt, sell_vol_opt) with + | Some _,Some _ -> ([], storage.vaults) + | Some bv, None -> inject_sell_side_liq bv batcher batch storage + | None, Some sv -> inject_buy_side_liq sv batcher batch storage + | None, None -> ([], storage.vaults) + + [@inline] let deposit - (_batcher:address) - (_batches: reduced_batch list) - (storage: Storage.t): (operation list * Storage.t) = ([]: operation list), storage + (batcher:address) + (batches: batch list) + (storage: Storage.t): (operation list * Storage.t) = + let inject = fun ((ol,s),rb:((operation list* Storage.t) * batch)) -> + let (iops,vaults) = inject_liquidity_if_required batcher rb s in + let s = {s with vaults = vaults; } in + (Utils.concatlo iops ol,s) + in + let (deposit_ops,storage) = List.fold inject batches ([],storage) in + deposit_ops, storage end @@ -533,21 +589,21 @@ let change_batcher_address no_op storage [@inline] -let get_reduced_batches +let get_batches (failure_code: nat) - (batcher: address) : reduced_batch list = - match Tezos.call_view "get_current_batches_reduced" () batcher with - | Some rbl -> rbl + (batcher: address) : batch list = + match Tezos.call_view "get_current_batches" () batcher with + | Some bl -> bl | None -> failwith failure_code [@inline] let tick (storage: Storage.t) : result = let () = Utils.reject_if_tez_supplied () in - let reduced_batches = get_reduced_batches Errors.unable_to_get_reduced_batches_from_batcher storage.batcher in + let batches = get_batches Errors.unable_to_get_batches_from_batcher storage.batcher in let storage = TickUtils.rebalance_vaults storage in let (redeem_op_opt, storage) = TickUtils.redeem storage in - let (deposit_ops, storage) = TickUtils.deposit storage.batcher reduced_batches storage in + let (deposit_ops, storage) = TickUtils.deposit storage.batcher batches storage in let ops = match redeem_op_opt with | Some op -> op :: deposit_ops | None -> deposit_ops diff --git a/batcher/storage/initial_storage_ghostnet.mligo b/batcher/storage/initial_storage_ghostnet.mligo index 205680e5..a6dac013 100644 --- a/batcher/storage/initial_storage_ghostnet.mligo +++ b/batcher/storage/initial_storage_ghostnet.mligo @@ -2,77 +2,114 @@ let meta : bytes = 0x68747470733a2f2f697066732e6763702e6d617269676f6c642e6465762f697066732f516d56375a534b6358324d4e75656938745a3268723555484d5a66737039476b375675345878766d6246734a4e45 -let f (_ : unit) : Batcher.Storage.t = - { - metadata = Big_map.literal [("", meta)]; - valid_tokens = - Map.literal - [ - (("tzBTC"), - { - token_id = 0n; - name = "tzBTC"; - address = Some (("KT1P8RdJ5MfHMK5phKJ5JsfNfask5v2b2NQS" : address)); - decimals = 8n; - standard = Some "FA1.2 token" - }); - (("EURL"), - { - token_id = 0n; - name = "EURL"; - address = Some (("KT1RcHjqDWWycYQGrz4KBYoGZSMmMuVpkmuS" : address)); - decimals = 6n; - standard = Some "FA2 token" - }); - (("USDT"), - { - token_id = 0n; - name = "USDT"; - address = Some (("KT1WNrZ7pEbpmYBGPib1e7UVCeC6GA6TkJYR" : address)); - decimals = 6n; - standard = Some "FA2 token" - }) - ]; - valid_swaps = - Map.literal - [ - ("tzBTC/USDT", - { - swap = - { - from = "tzBTC"; - to = "USDT" - }; - oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ" : address); - oracle_asset_name = "BTC-USDT"; - oracle_precision = 6n; - is_disabled_for_deposits = false - }); - ("tzBTC/EURL", - { - swap = - { - from = "tzBTC"; - to = "EURL" - }; - oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ" : address); - oracle_asset_name = "BTC-EUR"; - oracle_precision = 6n; - is_disabled_for_deposits = false - }) - ]; - rates_current = (Big_map.empty : Batcher.rates_current); - batch_set = - { - current_batch_indices = (Map.empty : (string, nat) map); - batches = (Big_map.empty : (nat, Batcher.batch) big_map) - }; - last_order_number = 0n; - user_batch_ordertypes = (Big_map.empty : Batcher.user_batch_ordertypes); - fee_in_mutez = 10000mutez; - fee_recipient = ("tz1burnburnburnburnburnburnburjAYjjX" : address); - administrator = ("tz1aSL2gjFnfh96Xf1Zp4T36LxbzKuzyvVJ4" : address); - marketmaker = ("tz1aSL2gjFnfh96Xf1Zp4T36LxbzKuzyvVJ4" : address); - limit_on_tokens_or_pairs = 10n; - deposit_time_window_in_seconds = 600n - } +let f(_:unit) : Batcher.Storage.t = { + metadata = (Big_map.empty : Batcher.metadata); + valid_tokens = Map.literal [ + (("tzBTC"), { + token_id = 0n; + name = "tzBTC"; + address = Some(("KT1P8RdJ5MfHMK5phKJ5JsfNfask5v2b2NQS" : address)); + decimals = 8n; + standard = Some "FA1.2 token" + }); + (("BTCtz"), { + token_id = 0n; + name = "tzBTC"; + address = Some(("KT1ErLEYVsxqHxLgLucXViq5DYrtSyDuSFTe" : address)); + decimals = 8n; + standard = Some "FA2 token" + }); + (("EURL"),{ + token_id = 0n; + name = "EURL"; + address = Some(("KT1RcHjqDWWycYQGrz4KBYoGZSMmMuVpkmuS" : address)); + decimals = 6n; + standard = Some "FA2 token" + }); + (("USDT"),{ + token_id = 0n; + name = "USDT"; + address = Some(("KT1WNrZ7pEbpmYBGPib1e7UVCeC6GA6TkJYR" : address)); + decimals = 6n; + standard = Some "FA2 token" + }); + (("USDtz"),{ + token_id = 0n; + name = "USDtz"; + address = Some(("KT1B8tP5Q8Cb7HctLfxt4MVk2cWouHFrnbjW" : address)); + decimals = 6n; + standard = Some "FA1.2 token" + }) + ]; + valid_swaps = Map.literal [ + ("tzBTC/USDT", { + swap = { + from = "tzBTC"; + to = "USDT"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("BTCtz/USDtz", { + swap = { + from = "BTCtz"; + to = "USDtz"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("tzBTC/USDtz", { + swap = { + from = "tzBTC"; + to = "USDtz"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("BTCtz/USDT", { + swap = { + from = "BTCtz"; + to = "USDT"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("tzBTC/EURL", { + swap = { + from = "tzBTC"; + to = "EURL"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-EUR"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ) + ]; + rates_current = (Big_map.empty : Batcher.rates_current); + batch_set = { + current_batch_indices = (Map.empty : (string,nat) map); + batches = (Big_map.empty : (nat,Batcher.batch) big_map); + }; + last_order_number = 0n; + user_batch_ordertypes = (Big_map.empty: Batcher.user_batch_ordertypes); + fee_in_mutez = 10_000mutez; + fee_recipient = ("tz1burnburnburnburnburnburnburjAYjjX" : address); + administrator = ("tz1ca4batAsNxMYab3mUK5H4QRjY8drV4ViL" : address); + marketmaker = ("KT1XKvKiTTj8N6WKv3MhnZhFjZopFGQGBTdT" : address); + limit_on_tokens_or_pairs = 10n; + deposit_time_window_in_seconds = 600n; +} + diff --git a/batcher/storage/marketmaker_storage_ghostnet.mligo b/batcher/storage/marketmaker_storage_ghostnet.mligo index 2e61f594..c8adb6be 100644 --- a/batcher/storage/marketmaker_storage_ghostnet.mligo +++ b/batcher/storage/marketmaker_storage_ghostnet.mligo @@ -10,6 +10,13 @@ let f(_:unit) : MarketMaker.Storage.t = { decimals = 8n; standard = Some "FA1.2 token" }); + (("BTCtz"), { + token_id = 0n; + name = "tzBTC"; + address = Some(("KT1ErLEYVsxqHxLgLucXViq5DYrtSyDuSFTe" : address)); + decimals = 8n; + standard = Some "FA2 token" + }); (("EURL"),{ token_id = 0n; name = "EURL"; @@ -23,6 +30,13 @@ let f(_:unit) : MarketMaker.Storage.t = { address = Some(("KT1WNrZ7pEbpmYBGPib1e7UVCeC6GA6TkJYR" : address)); decimals = 6n; standard = Some "FA2 token" + }); + (("USDtz"),{ + token_id = 0n; + name = "USDtz"; + address = Some(("KT1B8tP5Q8Cb7HctLfxt4MVk2cWouHFrnbjW" : address)); + decimals = 6n; + standard = Some "FA1.2 token" }) ]; valid_swaps = Map.literal [ @@ -37,6 +51,39 @@ let f(_:unit) : MarketMaker.Storage.t = { is_disabled_for_deposits = false } ); + ("BTCtz/USDtz", { + swap = { + from = "BTCtz"; + to = "USDtz"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("tzBTC/USDtz", { + swap = { + from = "tzBTC"; + to = "USDtz"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); + ("BTCtz/USDT", { + swap = { + from = "BTCtz"; + to = "USDT"; + }; + oracle_address = ("KT1DG2g5DPYWqyHKGpRL579YkYZwJxibwaAZ": address); + oracle_asset_name = "BTC-USDT"; + oracle_precision = 6n; + is_disabled_for_deposits = false + } + ); ("tzBTC/EURL", { swap = { from = "tzBTC"; @@ -49,8 +96,8 @@ let f(_:unit) : MarketMaker.Storage.t = { } ) ]; - batcher = ("tz1burnburnburnburnburnburnburjAYjjX" : address); - administrator = ("tz1aSL2gjFnfh96Xf1Zp4T36LxbzKuzyvVJ4" : address); + batcher = ("KT1LhTpwSGcFAUUM3JYjW8XW74UHP82YzERy" : address); + administrator = ("tz1ca4batAsNxMYab3mUK5H4QRjY8drV4ViL" : address); vaults = Big_map.literal [ ("tzBTC", { total_shares = 0n; @@ -67,6 +114,21 @@ let f(_:unit) : MarketMaker.Storage.t = { }; foreign_tokens = (Map.empty: MarketMaker.token_amount_map); }); + ("BTCtz", { + total_shares = 0n; + holdings = (Set.empty: nat set); + native_token = { + token = { + token_id = 0n; + name = "BTCtz"; + address = Some(("KT1ErLEYVsxqHxLgLucXViq5DYrtSyDuSFTe" : address)); + decimals = 8n; + standard = Some "FA2 token" + }; + amount= 0n; + }; + foreign_tokens = (Map.empty: MarketMaker.token_amount_map); + }); ("EURL", { total_shares = 0n; holdings = (Set.empty: nat set); @@ -82,6 +144,21 @@ let f(_:unit) : MarketMaker.Storage.t = { }; foreign_tokens = (Map.empty: MarketMaker.token_amount_map); }); + ("USDtz", { + total_shares = 0n; + holdings = (Set.empty: nat set); + native_token = { + token = { + token_id = 0n; + name = "USDtz"; + address = Some(("KT1B8tP5Q8Cb7HctLfxt4MVk2cWouHFrnbjW" : address)); + decimals = 6n; + standard = Some "FA1.2 token" + }; + amount= 0n; + }; + foreign_tokens = (Map.empty: MarketMaker.token_amount_map); + }); ("USDT", { total_shares = 0n; holdings = (Set.empty: nat set); diff --git a/batcher/utils.mligo b/batcher/utils.mligo index fc75fff9..7906e91c 100644 --- a/batcher/utils.mligo +++ b/batcher/utils.mligo @@ -25,9 +25,6 @@ type token_amount = Types.token_amount type ordertype = Types.ordertype type swap_order = Types.swap_order - - - [@inline] let get_vault () : address = Tezos.get_self_address () @@ -194,6 +191,13 @@ let get_clearing_price (exchange_rate : exchange_rate) (buy_side : buy_side) (se clearing_rate = exchange_rate } +[@inline] +let side_to_nat + (side:Types.side): nat = + match side with + | Buy -> 0n + | Sell -> 1n + [@inline] let nat_to_side (order_side : nat) : side = @@ -202,6 +206,13 @@ let nat_to_side if order_side = 1n then Sell else failwith Errors.unable_to_parse_side_from_external_order +[@inline] +let tolerance_to_nat (tolerance:tolerance) : nat = + match tolerance with + | Minus -> 0n + | Exact -> 1n + | Plus-> 2n + [@inline] let nat_to_tolerance (tolerance : nat) : tolerance = if tolerance = 0n then Minus @@ -254,13 +265,19 @@ let get_highest_batch_index in Map.fold return_highest batch_indices 0n +(** [rev list] should return the same list reversed. *) +let rev1 (type a) (list: a list) : a list = + List.fold_left (fun (xs, x : a list * a) -> x :: xs) ([] : a list) list + (** [concat a b] concat [a] and [b]. *) let concat1 (type a) (left: a list) (right: a list) : a list = List.fold_right (fun (x, xs: a * a list) -> x :: xs) left right -(** [rev list] should return the same list reversed. *) -let rev1 (type a) (list: a list) : a list = - List.fold_left (fun (xs, x : a list * a) -> x :: xs) ([] : a list) list +(** concat two list but preserve order *) +let concatlo (type a) (left: a list) (right: a list) : a list = + let right_rev = rev1 right in + let to_rev = List.fold_right (fun (x, xs: a * a list) -> x :: xs) left right_rev in + rev1 to_rev [@inline] let update_if_more_recent