From 1ac44ce70f90a4c1397d221d06f29df8ac497ca7 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Sun, 10 Dec 2023 13:25:42 +0530 Subject: [PATCH 1/7] Feat #53: Update to cabal.project file in sync with latest dependencies update --- cabal.project | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cabal.project b/cabal.project index b4ef702..f34675f 100644 --- a/cabal.project +++ b/cabal.project @@ -33,8 +33,8 @@ package strict-containers source-repository-package type: git location: https://github.com/maestro-org/haskell-sdk - tag: 3865f4465f05323a378dbed257c34450923e8c99 - --sha256: sha256-nQnvml8eelTw7HpzByC5Rv5XUD74oLJucRRg8OFz71s= + tag: fb8e32869f7a8f5fa2585b542e4eb4207eaf735b + --sha256: sha256-LOiC9zPXjPFshKfb/SKkFBkAFnOuQDwCqeDB7ZyB3b0= -- Unfortunately, cardano-node 8.1.2 is constrained with plutus-ledger-api 1.5.0.0 and we would like at least 1.6.0.0. -- This is done in accordance with changes in https://github.com/input-output-hk/cardano-ledger/pull/3430/files. @@ -64,8 +64,8 @@ source-repository-package source-repository-package type: git location: https://github.com/geniusyield/atlas - tag: 014f8b4ab5b21b1c54165716f3cb6e800b6defb9 - --sha256: sha256-1QhPygU0MyXO9QvJkJD4awNmWEhj79jSFbQBj0FQNfM= + tag: 44b235ac4f4337dd2b2488b4f79f33a987f2be72 + --sha256: sha256-EL7o0yYJIC8KvH0kZ9J0n+h/+w4GI4hCz39QyDA7Udg= source-repository-package type: git @@ -76,12 +76,12 @@ source-repository-package cardano-simple psm --- Temporary until the changes are merged upstream. Delete this afterwards. +-- This should be present for in hackage index state >= 18th of september, 23. Remove it when we update to it. source-repository-package type: git - location: https://github.com/sourabhxyz/blockfrost-haskell - tag: d1ace8d71512a70f37131e4d4c4d5ba67a6324c9 - --sha256: sha256-GXKuRyBnpITjxRDHauJwpjQu8qX4UPLud/opc+Mi9Fg= + location: https://github.com/blockfrost/blockfrost-haskell + tag: 206e1a0f62e2a7cc08d05db8d62cef8dc2fbd98e + --sha256: sha256-R6BP3hwrOBmlRabA3prUuOGkYzETmQIM+K+Oh+fczEY= subdir: blockfrost-api blockfrost-client-core @@ -128,8 +128,8 @@ source-repository-package source-repository-package type: git location: https://github.com/paolino/openapi3 - tag: c30d0de6875d75edd64d1aac2272886528bc492d - --sha256: 0b0fzj5vrnfrc8qikabxhsnp4p8lrjpssblbh2rb7aji5hzzfli9 + tag: f22c31611c295637a3e72b341cd1c56d1d87b993 + --sha256: 10l7wlaz9rcr3fysi1vwg7qqa826bb7nidkpx9jy1q7ja7ddw47i source-repository-package type: git From 061ad6dd41ee617d53b9d83b03e9d6449159b6e8 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Sun, 10 Dec 2023 17:02:47 +0530 Subject: [PATCH 2/7] Feat #53: Update to DEX API functions + added new compiled scripts --- compiled-scripts/minting-policy | 7 +- compiled-scripts/partial-order | 4 +- geniusyield-dex-api/geniusyield-dex-api.cabal | 2 +- .../src/GeniusYield/DEX/Api/Constants.hs | 16 - .../src/GeniusYield/DEX/Api/PartialOrder.hs | 624 ++++++++++++------ .../GeniusYield/DEX/Api/PartialOrderConfig.hs | 126 ++++ .../src/GeniusYield/DEX/Api/Types.hs | 49 +- 7 files changed, 587 insertions(+), 241 deletions(-) delete mode 100644 geniusyield-dex-api/src/GeniusYield/DEX/Api/Constants.hs create mode 100644 geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrderConfig.hs diff --git a/compiled-scripts/minting-policy b/compiled-scripts/minting-policy index 38bb140..8b8521b 100644 --- a/compiled-scripts/minting-policy +++ b/compiled-scripts/minting-policy @@ -1,11 +1,12 @@ { - "cborHex": "590cf4590cf1010000323232323232323232323232323232323232323232323232323232323232323232323232323232222232323232323232325333025302d3032002153330253302123031375a6068002666603e00c6eacc0a000c8004585840784c8c8c8c8c8c8c94ccc0a80045854ccc0b14cc08ccc0a08cc094020c0c0c0b800401054cc08cd5d198170008a99811981a1bad303a302f00113371e6eb8c0e4c0bc0040144c8ccccc0a88894ccc0b8004489400454ccc0c0c008c0cc0044c888c00800cc0cc0044cc00c008c0c80048c8c0dccccc08cdd718191818001a40004666604800490003ad37560026eacc0c8c0c4c0c0008dd71818981818178010021191929998182999818181b981e8010a5013371e02e6eb8c0cc0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc10cc128c1400084c8c94ccc114c134c14800854ccc114c13c02854ccc114cdc38048050a99982299b8f375c609001a03c2a66608a60980102a66608a609e00e2a66608a606e6607a00c00a2a66608a94454ccc114c0d4cc0bcdd598241823982300c199818b803330317006605a00c6ea0028cc0b4064128cc0b4cc0e9221004881003750056207c2c2c2c2c2c2c2c2c2a66608a609e0142a66608a66e1c02402854ccc114cdc79bae304800d01e15333045304c00815333045304f0071533304530373303d00600515333045337126eb4c12000cdd698240008a999822981a998179bab304830473046018333031700666062e00cc0b4018dd40051981680c825198169981d245004881003750056207c2c2c2c2c2c2c2c2c60a40026ea8c1180244c8c8c94ccc118c14002c54ccc118cdc38050058a99982319b8f375c609201c03e2a66608c609a0122a66608c60a00102a66608c60706607c00e00c2a66608c94454ccc118c0d8cc0c0dd598249824182380c9998193803330327006605c00e6ea002ccc0b806812ccc0b8cc0ed2201004881003750058207e2c2c2c2c2c2c2c2c60a600460a20026ea8c118024c140004dd51822004182180518210061bad3041303f3041007375a6080607e0066eb4c0fc020dd6981f003181e000981d800981d000981c800981c000981b800981b000981a981a981a2999819981d0010b0a99981999b87480100084c8c8c8c80114ccc0d8c0f4c10c00854ccc0d8c0fcdc69bae303900113232323232323232323232323232323232325333048304f3055001132323232533304c3375e6e9cc13800941604c94ccc134cdc49b8d375c60a00029020099191919191919191919191919029a99982b982d80108290b1bad305b00130590055333056305d002153330563061375a60b20022640a0a6660a860b0002209e2c2c2a6660ac60bc0042640a0a6660a8002209e2c2c60c600460c20026ea8c158004c1500154ccc144c16000854ccc144c170dd6982a000899025a999827982980088250b0b0a999828982c801099025a99982780088250b0b182f001182e0009baa3051001304f00116304e006163750607c6eb4c138004c130008dd69826000982b0008b1baa304a00130480045333045304c30520021325333046533045304d0011304f0011325333047337126e34dd71825000a4080264082a66608a609200220802c2c60900042c6e34dd718240008b18290009baa30460013044002375a608800260840046eb4c108004c1000114ccc0f4c110c1280084c94ccc0f94cc0f4c1140044c11c0044c94ccc0fccdc49b8d375c6084002902009901ca99981e9820800881c0b0b18200010b1b8d375c60800022c60940026ea8c0f8004c0f00114ccc0e4c100c1180084c8c8c8c8c8c8c8c8c8c80f14ccc100c11001440ec594ccc104c1200084c8c8c8c8c80fd4ccc10cc11c01440f8594ccc110c12c0084c8c8c8c8c81094ccc118c1280144104594ccc11cc13800854ccc11cc140dc69bae304a001132041533304530490011040161615333047304f002153330473050371a6eb8c1280044c81054ccc114c1240044100585858c150008c148004dd518238008a99982218260010991919191919021a999823982580108210b1bad304b0013049002375a6092002608e0046eb4c11c00458c144008c13c004dd518220008a999820982480109901da99981f800881d0b0b182700118260009baa3041001303f005533303c30430021533303c3045371a6eb8c0fc0044c80d94ccc0e8c0f800440d4585854ccc0f0c11000854ccc0f0c114dc69bae303f001132036533303a303e001103516161630490023047001375460780022c608c0026ea8c0e8004c0e00045858c10c004dd5000981b00089999981711911180100198210009ba9375c606c0020124646464008a66606c607a60860042a66606c607e6e34dd7181c800899191919191919191919191919191919191929998241827982a800899191919299982619baf374e609c004a0b0264a66609a66e24dc69bae3050001481004c8c8c8c8c8c8c8c8c8c8c8c8c814d4ccc15cc16c008414858dd6982d800982c802a99982b182e8010a99982b18309bad305900113205053330543058001104f161615333056305e0021320505333054001104f161630630023061001375460ac00260a800aa6660a260b00042a6660a260b86eb4c1500044c812d4ccc13cc14c0044128585854ccc144c1640084c812d4ccc13c00441285858c178008c170004dd5182880098278008b18270030b1ba8303e375a609c00260980046eb4c130004c15800458dd5182500098240022999822982618290010992999823299822982680089827800899299982399b89371a6eb8c12800520401320415333045304900110401616304800216371a6eb8c12000458c148004dd5182300098220011bad30440013042002375a60840026080008a66607a60886094004264a66607ca6607a608a0022608e002264a66607e66e24dc69bae3042001481004c80e54ccc0f4c10400440e05858c10000858dc69bae304000116304a0013754607c0026078008a6660726080608c004264646464646464646464078a666080608800a20762ca66608260900042646464646407ea666086608e00a207c2ca666088609600426464646464084a66608c609400a20822ca66608e609c0042a66608e60a06e34dd71825000899020a999822982480088200b0b0a99982398278010a99982398281b8d375c6094002264082a66608a609200220802c2c2c60a800460a40026ea8c11c00454ccc110c1300084c8c8c8c8c8c810d4ccc11cc12c008410858dd6982580098248011bad30490013047002375a608e0022c60a2004609e0026ea8c11000454ccc104c1240084c80ed4ccc0fc00440e85858c138008c130004dd51820800981f802a99981e18218010a99981e18229b8d375c607e00226406ca666074607c002206a2c2c2a66607860880042a666078608a6e34dd7181f80089901b299981d181f000881a8b0b0b182480118238009baa303c0011630460013754607400260700022c2c60860026ea800458c100008c0f8004dd518199819181918188018b181e8009baa3031302f3031302f001163302100d00516333302500c3756605c01240022c6eacc0b4c0b0c0b0c0b0c0b0c0b0c0b0020dd618160041bac302b008372466e2cdd6981518148009bae302a3028302a00130270013028001303200137540106048604800260466046002604260466042008a66603e604c605800426eb8c08800458c0b0004dd51810180f980f000911919299980e19baf0034c1010000020133005002374c6600a002006603c603a6038006603a6036004446601e66ec000800407c88ccc011c00011980191ba6330042375066e052000375a0026eac00400488cc050894ccc05c0040744cc03ccdd81813180e00098021813980e0009801180d800800911199802111ba63330062237506600e6eb4008dd68009bab00237560020040024446666026446600244a666030004200226666008010603a0046038004002444a6660320022660220060042646464a66603c66ebc0080044cc050cdd8001198059816003181600199980400680298100020a99980f19b90375c0046eb80044cc050018cccc02003000cc0800100144cc05000ccccc020030018014c080010c0a8008c0a4010c07800401400800488004880088cc0088cc00c8c078dd698108009bab30200010012300d22533301000114a22a660126006602a002260046028002466601e002941289299980719b89001480005840048c8888cc038894ccc044004401454ccc04ccdd79810180b000803098021810980b00089801180a8008009ba9001223374a9000198019ba900233003375200297ae0574044666016004002294088cdd79ba7300b002374e6016002931198011191118010019bab301600137520024446600a44a666010002244a0022a66601466ebcc05cc0340040104c014c0340044c008c0300040048c008894ccc0140045280a9980318019805000898011804800919180111980100100091801119801001000aab9f23300200114a2ae688c038dd5000aba25742200498010101004bd6f7b6301b8748000dc3a40046e1d2038371090001b89480004dd3a5eb8155ceaab9e1", + "cborHex": "591157591154010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323222222323232323232323232325333038303f304600213232323232323232323232323232533304700116153330465330393303e23303900f304630410010081533039303530440011533039304e375a60aa608a002266e3cdd7182a18228008048991999821918281981c1bab30473046304200100200823232533304a533304a3051305800214a0266e3c084dd7182480089919191919191919191919191919191919191919191919191919191919191929998349838983b80109919192999836183b8098a99983619b870120131533306c3371e6eb8c1ac0680bc54ccc1b0c1cc04454ccc1b0c1dc03c54ccc1b0c15ccc17801c01854ccc1b1288a99983619baf00e00a1533306c3370e01a0522a6660d86609e6eacc1acc1a8c198094c120ccc149c0198220039ba801330483330527006608804c0e060906660a4e00cc110cc16522010048810037500506666608a00e00c0140120102a6660d860e66eb402054ccc1b14cc17ccdc48159bad00a133712609c66098609605460940266eb402454ccc1b0c1cc040418458585858585858585858585858c1e8008c1e0004dd5183400a8991929998359839183c8010a999835983b0090a99983599b870110121533306b3371e6eb8c1a80640b854ccc1acc1c804054ccc1acc1d803854ccc1acc158cc17401801454ccc1accdc49bad306a003375a60d40022a6660d666ebc03402454ccc1accdc38060140a999835998271bab306a3069306502430473330517006608600c6ea0048c11cccc145c0198218128379823999828b803304333058488100488100375004e6666608800c00a01201000e2a6660d660e46eb401c54ccc1ad4cc178cdc48151bad009133712609a66096609405260920246eb402054ccc1acc1c803c41805858585858585858585858585854ccc1acc1d804854ccc1accdc38088090a99983599b8f375c60d403205c2a6660d660e40202a6660d660ec01c2a6660d660ac660ba00c00a2a6660d694454ccc1accdd78068048a99983599b8700c0281533306b3304e375660d460d260ca048608e6660a2e00cc10c018dd40091823999828b803304302506f304733305170066086660b091100488100375004e6666608800c00a01201000e2a6660d660e46eb401c54ccc1ad4cc178cdc48151bad009133712609a66096609405260920246eb402054ccc1acc1c803c418058585858585858585858585858c1e4004dd5183400a983b8009baa3066014306501630640183063306200330620023061002305f001305a305f008375a60bc01060ba0106eb4c170c15cc170030dd6982d982d0021bad305a006375a60b20186eb4c160028c158004c154004c150004c14c004c148004c144004c140004c13c004c138004c134004c130004c12cc12cc11d4ccc134c1540084ccccc1108c888c00800cc174004dd49bae304c00100d232323200453330503057305e00215333050305a371a6eb8c13c0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc188c1a4c1c00044c8c8c8c94ccc198cdd79ba7306400250731325333067337126e34dd71833000a4080264646464646464646464646464646464646464646464640e6a6660fc60f600420e42c6eb4c1ec004c1e40114ccc1e8c20404c220040084c8c8c8c8c8c81d54ccc20004c1f400841d058dd6983e800983d8011bad307b0013079002375a60f20022c6110020026ea8c1dc004c1d4008dd6983a80098398011bad30730013071002375a60e200260de00aa6660e060ee0042a6660e060f86eb4c1bc0044c81994ccc1c4c1b80044194585854ccc1c0c1e00084c81994ccc1c400441945858c1f8008c1f0004dd518360009835002a99983598390010a999835983b9bad306a001132061533306c3069001106016161533306b3073002132061533306c0011060161630790023077001375460ce00260ca0022c60c800c2c6ea0c144dd6983200098310011bad3062001307100116375460c000260bc008a6660be60cc60da004264a6660c0a660b260ce002260d4002264a6660c266e24dc69bae3060001481004c815d4ccc188c17c00441585858c17800858dc69bae305e00116306d001375460b800260b40046eb4c168004c160008dd6982c000982b002299982b982f1832801099299982c299828982f80089831000899299982c99b89371a6eb8c160005204013204f533305a3057001104e1616305600216371a6eb8c15800458c194004dd5182a00098290022999829982d1830801099191919191919191919029299982e982d00288288b299982d98310010991919191902aa999830182e802882a0b299982f18328010991919191902c29998319830002882b8b299983098340010a99983098359b8d375c60c00022640aea6660c460be00220ac2c2c2a6660c260d20042a6660c260d66e34dd7183000089902ba999831182f800882b0b0b0b183780118368009baa305d0011533305e3066002132323232323205953330643061002105816375a60c200260be0046eb4c17c004c174008dd6982e8008b183600118350009baa305a0011533305b3063002132051533305c0011050161630690023067001375460ae00260aa00aa6660ac60ba0042a6660ac60c06e34dd7182a800899026299982b982a00088258b0b0a99982b182f0010a99982b18301b8d375c60aa002264098a6660ae60a800220962c2c2c60c800460c40026ea8c14800458c184004dd5182800098270008b0b182f0009baa001161533304d305600213232323200453330503057305e00215333050305a371a6eb8c13c0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc188c1a4c1c00044c8c8c8c94ccc198cdd79ba7306400250731325333067337126e34dd71833000a4080264646464646464646464646464646464646464646464640e6a6660fc60f600420e42c6eb4c1ec004c1e40114ccc1e8c20404c220040084c8c8c8c8c8c81d54ccc20004c1f400841d058dd6983e800983d8011bad307b0013079002375a60f20022c6110020026ea8c1dc004c1d4008dd6983a80098398011bad30730013071002375a60e200260de00aa6660e060ee0042a6660e060f86eb4c1bc0044c81994ccc1c4c1b80044194585854ccc1c0c1e00084c81994ccc1c400441945858c1f8008c1f0004dd518360009835002a99983598390010a999835983b9bad306a001132061533306c3069001106016161533306b3073002132061533306c0011060161630790023077001375460ce00260ca0022c60c800c2c6ea0c144dd6983200098310011bad3062001307100116375460c000260bc008a6660be60cc60da004264a6660c0a660b260ce002260d4002264a6660c266e24dc69bae3060001481004c815d4ccc188c17c00441585858c17800858dc69bae305e00116306d001375460b800260b40046eb4c168004c160008dd6982c000982b002299982b982f1832801099299982c299828982f80089831000899299982c99b89371a6eb8c160005204013204f533305a3057001104e1616305600216371a6eb8c15800458c194004dd5182a00098290022999829982d1830801099191919191919191919029299982e982d00288288b299982d98310010991919191902aa999830182e802882a0b299982f18328010991919191902c29998319830002882b8b299983098340010a99983098359b8d375c60c00022640aea6660c460be00220ac2c2c2a6660c260d20042a6660c260d66e34dd7183000089902ba999831182f800882b0b0b0b183780118368009baa305d0011533305e3066002132323232323205953330643061002105816375a60c200260be0046eb4c17c004c174008dd6982e8008b183600118350009baa305a0011533305b3063002132051533305c0011050161630690023067001375460ae00260aa00aa6660ac60ba0042a6660ac60c06e34dd7182a800899026299982b982a00088258b0b0a99982b182f0010a99982b18301b8d375c60aa002264098a6660ae60a800220962c2c2c60c800460c40026ea8c14800458c184004dd5182800098270008b0b182f0009baa001304c00116305b0023059001375460926090609060880062c60b00026ea8c11cc108c11cc10800458cc0cc05802458cccc0ec054040800458dd6982198210049bad30420083041008375a60800106eacc0fcc0f8c0d0c0f8030dd6181f0061bac303d00d372466e2cdd6981e181d8009bae303c3037303c001303600430390013038001302d3033333303523253302e3302d303a001011130433302b37566074607200202060686072607060680026eb0c0e001c8c8c94ccc0f0c114c1280084c0ec00458c128004dd5181c981c181c181a181c981c181a0008b181b8008a99981c19818118229bad3048001333302e00800320011616102d304600137540146eacc0d0004c0c8c0c8004c0c4004c0c0004c0acc0c0c0ac0114ccc0c0c0dcc0f80084dd718178008b181f0009baa302d302c3028001223232533302c3375e00605e05c26600e0046e98cc01c00400cc0a8c0a4c09400cc0a4c09000888888ccc049c0198031980ca45004881000033330127006600c00a0046600c008002446464a66605466e24dd6801a400005826600a0046e98cc01400400cc0a0c09cc08c00cc09cc08800888cc054cdd800100081611980111919a999813980b000891280089118010019191118010019ba6001122500133003253330273375e002054244a00224460040066eac00400488cc088894ccc0a00040a44c8ccc014c0dcc09c0088cc05ccdd8181b981400180080108009801181280080091198008012400446464644660020060046eb4c08cc088008dd69811000980e00091180111180191191919191919191911980080180119b820023370600c00666e08004cdc1803001299981598190020a40002a66605666e2401120001480045200233025533302a3371200400220022004a66605466e2400800440084004c028008c024008cdc100200119b8200400225333020337120029000898050008800919299981018011119b88302800233704900000088008a99981018011119b873028002337046008e1000440044cdc0240040026002e1088cc0108cc0148c0b4dd698180009bab302f0013330057000046600646e98cc0108dd418059bad0013756002002446603644a66604200204426601c66ec0c0b8c07c004c010c0bcc07c004c008c0780040048c064894ccc07c0045288a998089801980e80089801180e000911199802111ba63330062237506600e6eb4008dd68009bab00237560020040024446666032446600244a666042004200226666008010603e004603c004002444a66604400226601e0060042646464a66604866ebc0080044cc048cdd8001198059819803181980199980400680298110020a99981219b90375c0046eb80044cc048018cccc02003000cc0880100144cc04800ccccc020030018014c088010c0c4008c0c0010c0800040140080048800488008dc0a4000466602c002941289299980a99b890014800058400488cdd2a4000660066ea4008cc00cdd4800a5eb815d02ba322323333004375c6024601a00490001199980280124000eb4dd58008019bae30113010300c001232222330112253330170011005153330163375e6048602a00200c26008604a602a0022600460280020026ea400488cdd79ba7300a002374e60140024466601e00400229408c02cc02cc02cc02c00526233002232223002003375660360026ea4004888cc024894ccc03c004489400454ccc038cdd7980e1806800802098029806800898011806000800918031129998060008a5015330043003300a00113002300900123300800114a24602c6ea8004c0088894ccc020c03c00440084cc00c004cdc30010009800911299980400089128008a9998039801180300089911180100198030008998018011802800919180111980100100091801119801001000aba25742ae6955cf8801a610100004c010101004bd6f7b6301b8248008dc3a40006e1d2002370e90021b87480e0dc4240006e2520001374e97ae05573aaae79", "description": "DEX.PartialOrderNFT", "params": [ "PlutusLedgerApi.V1.Scripts:ScriptHash", - "GHC.Num.Integer:Integer" + "PlutusLedgerApi.V1.Address:Address", + "PlutusLedgerApi.V1.Value:AssetClass" ], - "rawHex": "590cf1010000323232323232323232323232323232323232323232323232323232323232323232323232323232222232323232323232325333025302d3032002153330253302123031375a6068002666603e00c6eacc0a000c8004585840784c8c8c8c8c8c8c94ccc0a80045854ccc0b14cc08ccc0a08cc094020c0c0c0b800401054cc08cd5d198170008a99811981a1bad303a302f00113371e6eb8c0e4c0bc0040144c8ccccc0a88894ccc0b8004489400454ccc0c0c008c0cc0044c888c00800cc0cc0044cc00c008c0c80048c8c0dccccc08cdd718191818001a40004666604800490003ad37560026eacc0c8c0c4c0c0008dd71818981818178010021191929998182999818181b981e8010a5013371e02e6eb8c0cc0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc10cc128c1400084c8c94ccc114c134c14800854ccc114c13c02854ccc114cdc38048050a99982299b8f375c609001a03c2a66608a60980102a66608a609e00e2a66608a606e6607a00c00a2a66608a94454ccc114c0d4cc0bcdd598241823982300c199818b803330317006605a00c6ea0028cc0b4064128cc0b4cc0e9221004881003750056207c2c2c2c2c2c2c2c2c2a66608a609e0142a66608a66e1c02402854ccc114cdc79bae304800d01e15333045304c00815333045304f0071533304530373303d00600515333045337126eb4c12000cdd698240008a999822981a998179bab304830473046018333031700666062e00cc0b4018dd40051981680c825198169981d245004881003750056207c2c2c2c2c2c2c2c2c60a40026ea8c1180244c8c8c94ccc118c14002c54ccc118cdc38050058a99982319b8f375c609201c03e2a66608c609a0122a66608c60a00102a66608c60706607c00e00c2a66608c94454ccc118c0d8cc0c0dd598249824182380c9998193803330327006605c00e6ea002ccc0b806812ccc0b8cc0ed2201004881003750058207e2c2c2c2c2c2c2c2c60a600460a20026ea8c118024c140004dd51822004182180518210061bad3041303f3041007375a6080607e0066eb4c0fc020dd6981f003181e000981d800981d000981c800981c000981b800981b000981a981a981a2999819981d0010b0a99981999b87480100084c8c8c8c80114ccc0d8c0f4c10c00854ccc0d8c0fcdc69bae303900113232323232323232323232323232323232325333048304f3055001132323232533304c3375e6e9cc13800941604c94ccc134cdc49b8d375c60a00029020099191919191919191919191919029a99982b982d80108290b1bad305b00130590055333056305d002153330563061375a60b20022640a0a6660a860b0002209e2c2c2a6660ac60bc0042640a0a6660a8002209e2c2c60c600460c20026ea8c158004c1500154ccc144c16000854ccc144c170dd6982a000899025a999827982980088250b0b0a999828982c801099025a99982780088250b0b182f001182e0009baa3051001304f00116304e006163750607c6eb4c138004c130008dd69826000982b0008b1baa304a00130480045333045304c30520021325333046533045304d0011304f0011325333047337126e34dd71825000a4080264082a66608a609200220802c2c60900042c6e34dd718240008b18290009baa30460013044002375a608800260840046eb4c108004c1000114ccc0f4c110c1280084c94ccc0f94cc0f4c1140044c11c0044c94ccc0fccdc49b8d375c6084002902009901ca99981e9820800881c0b0b18200010b1b8d375c60800022c60940026ea8c0f8004c0f00114ccc0e4c100c1180084c8c8c8c8c8c8c8c8c8c80f14ccc100c11001440ec594ccc104c1200084c8c8c8c8c80fd4ccc10cc11c01440f8594ccc110c12c0084c8c8c8c8c81094ccc118c1280144104594ccc11cc13800854ccc11cc140dc69bae304a001132041533304530490011040161615333047304f002153330473050371a6eb8c1280044c81054ccc114c1240044100585858c150008c148004dd518238008a99982218260010991919191919021a999823982580108210b1bad304b0013049002375a6092002608e0046eb4c11c00458c144008c13c004dd518220008a999820982480109901da99981f800881d0b0b182700118260009baa3041001303f005533303c30430021533303c3045371a6eb8c0fc0044c80d94ccc0e8c0f800440d4585854ccc0f0c11000854ccc0f0c114dc69bae303f001132036533303a303e001103516161630490023047001375460780022c608c0026ea8c0e8004c0e00045858c10c004dd5000981b00089999981711911180100198210009ba9375c606c0020124646464008a66606c607a60860042a66606c607e6e34dd7181c800899191919191919191919191919191919191929998241827982a800899191919299982619baf374e609c004a0b0264a66609a66e24dc69bae3050001481004c8c8c8c8c8c8c8c8c8c8c8c8c814d4ccc15cc16c008414858dd6982d800982c802a99982b182e8010a99982b18309bad305900113205053330543058001104f161615333056305e0021320505333054001104f161630630023061001375460ac00260a800aa6660a260b00042a6660a260b86eb4c1500044c812d4ccc13cc14c0044128585854ccc144c1640084c812d4ccc13c00441285858c178008c170004dd5182880098278008b18270030b1ba8303e375a609c00260980046eb4c130004c15800458dd5182500098240022999822982618290010992999823299822982680089827800899299982399b89371a6eb8c12800520401320415333045304900110401616304800216371a6eb8c12000458c148004dd5182300098220011bad30440013042002375a60840026080008a66607a60886094004264a66607ca6607a608a0022608e002264a66607e66e24dc69bae3042001481004c80e54ccc0f4c10400440e05858c10000858dc69bae304000116304a0013754607c0026078008a6660726080608c004264646464646464646464078a666080608800a20762ca66608260900042646464646407ea666086608e00a207c2ca666088609600426464646464084a66608c609400a20822ca66608e609c0042a66608e60a06e34dd71825000899020a999822982480088200b0b0a99982398278010a99982398281b8d375c6094002264082a66608a609200220802c2c2c60a800460a40026ea8c11c00454ccc110c1300084c8c8c8c8c8c810d4ccc11cc12c008410858dd6982580098248011bad30490013047002375a608e0022c60a2004609e0026ea8c11000454ccc104c1240084c80ed4ccc0fc00440e85858c138008c130004dd51820800981f802a99981e18218010a99981e18229b8d375c607e00226406ca666074607c002206a2c2c2a66607860880042a666078608a6e34dd7181f80089901b299981d181f000881a8b0b0b182480118238009baa303c0011630460013754607400260700022c2c60860026ea800458c100008c0f8004dd518199819181918188018b181e8009baa3031302f3031302f001163302100d00516333302500c3756605c01240022c6eacc0b4c0b0c0b0c0b0c0b0c0b0c0b0020dd618160041bac302b008372466e2cdd6981518148009bae302a3028302a00130270013028001303200137540106048604800260466046002604260466042008a66603e604c605800426eb8c08800458c0b0004dd51810180f980f000911919299980e19baf0034c1010000020133005002374c6600a002006603c603a6038006603a6036004446601e66ec000800407c88ccc011c00011980191ba6330042375066e052000375a0026eac00400488cc050894ccc05c0040744cc03ccdd81813180e00098021813980e0009801180d800800911199802111ba63330062237506600e6eb4008dd68009bab00237560020040024446666026446600244a666030004200226666008010603a0046038004002444a6660320022660220060042646464a66603c66ebc0080044cc050cdd8001198059816003181600199980400680298100020a99980f19b90375c0046eb80044cc050018cccc02003000cc0800100144cc05000ccccc020030018014c080010c0a8008c0a4010c07800401400800488004880088cc0088cc00c8c078dd698108009bab30200010012300d22533301000114a22a660126006602a002260046028002466601e002941289299980719b89001480005840048c8888cc038894ccc044004401454ccc04ccdd79810180b000803098021810980b00089801180a8008009ba9001223374a9000198019ba900233003375200297ae0574044666016004002294088cdd79ba7300b002374e6016002931198011191118010019bab301600137520024446600a44a666010002244a0022a66601466ebcc05cc0340040104c014c0340044c008c0300040048c008894ccc0140045280a9980318019805000898011804800919180111980100100091801119801001000aab9f23300200114a2ae688c038dd5000aba25742200498010101004bd6f7b6301b8748000dc3a40046e1d2038371090001b89480004dd3a5eb8155ceaab9e1", + "rawHex": "591154010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323222222323232323232323232325333038303f304600213232323232323232323232323232533304700116153330465330393303e23303900f304630410010081533039303530440011533039304e375a60aa608a002266e3cdd7182a18228008048991999821918281981c1bab30473046304200100200823232533304a533304a3051305800214a0266e3c084dd7182480089919191919191919191919191919191919191919191919191919191919191929998349838983b80109919192999836183b8098a99983619b870120131533306c3371e6eb8c1ac0680bc54ccc1b0c1cc04454ccc1b0c1dc03c54ccc1b0c15ccc17801c01854ccc1b1288a99983619baf00e00a1533306c3370e01a0522a6660d86609e6eacc1acc1a8c198094c120ccc149c0198220039ba801330483330527006608804c0e060906660a4e00cc110cc16522010048810037500506666608a00e00c0140120102a6660d860e66eb402054ccc1b14cc17ccdc48159bad00a133712609c66098609605460940266eb402454ccc1b0c1cc040418458585858585858585858585858c1e8008c1e0004dd5183400a8991929998359839183c8010a999835983b0090a99983599b870110121533306b3371e6eb8c1a80640b854ccc1acc1c804054ccc1acc1d803854ccc1acc158cc17401801454ccc1accdc49bad306a003375a60d40022a6660d666ebc03402454ccc1accdc38060140a999835998271bab306a3069306502430473330517006608600c6ea0048c11cccc145c0198218128379823999828b803304333058488100488100375004e6666608800c00a01201000e2a6660d660e46eb401c54ccc1ad4cc178cdc48151bad009133712609a66096609405260920246eb402054ccc1acc1c803c41805858585858585858585858585854ccc1acc1d804854ccc1accdc38088090a99983599b8f375c60d403205c2a6660d660e40202a6660d660ec01c2a6660d660ac660ba00c00a2a6660d694454ccc1accdd78068048a99983599b8700c0281533306b3304e375660d460d260ca048608e6660a2e00cc10c018dd40091823999828b803304302506f304733305170066086660b091100488100375004e6666608800c00a01201000e2a6660d660e46eb401c54ccc1ad4cc178cdc48151bad009133712609a66096609405260920246eb402054ccc1acc1c803c418058585858585858585858585858c1e4004dd5183400a983b8009baa3066014306501630640183063306200330620023061002305f001305a305f008375a60bc01060ba0106eb4c170c15cc170030dd6982d982d0021bad305a006375a60b20186eb4c160028c158004c154004c150004c14c004c148004c144004c140004c13c004c138004c134004c130004c12cc12cc11d4ccc134c1540084ccccc1108c888c00800cc174004dd49bae304c00100d232323200453330503057305e00215333050305a371a6eb8c13c0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc188c1a4c1c00044c8c8c8c94ccc198cdd79ba7306400250731325333067337126e34dd71833000a4080264646464646464646464646464646464646464646464640e6a6660fc60f600420e42c6eb4c1ec004c1e40114ccc1e8c20404c220040084c8c8c8c8c8c81d54ccc20004c1f400841d058dd6983e800983d8011bad307b0013079002375a60f20022c6110020026ea8c1dc004c1d4008dd6983a80098398011bad30730013071002375a60e200260de00aa6660e060ee0042a6660e060f86eb4c1bc0044c81994ccc1c4c1b80044194585854ccc1c0c1e00084c81994ccc1c400441945858c1f8008c1f0004dd518360009835002a99983598390010a999835983b9bad306a001132061533306c3069001106016161533306b3073002132061533306c0011060161630790023077001375460ce00260ca0022c60c800c2c6ea0c144dd6983200098310011bad3062001307100116375460c000260bc008a6660be60cc60da004264a6660c0a660b260ce002260d4002264a6660c266e24dc69bae3060001481004c815d4ccc188c17c00441585858c17800858dc69bae305e00116306d001375460b800260b40046eb4c168004c160008dd6982c000982b002299982b982f1832801099299982c299828982f80089831000899299982c99b89371a6eb8c160005204013204f533305a3057001104e1616305600216371a6eb8c15800458c194004dd5182a00098290022999829982d1830801099191919191919191919029299982e982d00288288b299982d98310010991919191902aa999830182e802882a0b299982f18328010991919191902c29998319830002882b8b299983098340010a99983098359b8d375c60c00022640aea6660c460be00220ac2c2c2a6660c260d20042a6660c260d66e34dd7183000089902ba999831182f800882b0b0b0b183780118368009baa305d0011533305e3066002132323232323205953330643061002105816375a60c200260be0046eb4c17c004c174008dd6982e8008b183600118350009baa305a0011533305b3063002132051533305c0011050161630690023067001375460ae00260aa00aa6660ac60ba0042a6660ac60c06e34dd7182a800899026299982b982a00088258b0b0a99982b182f0010a99982b18301b8d375c60aa002264098a6660ae60a800220962c2c2c60c800460c40026ea8c14800458c184004dd5182800098270008b0b182f0009baa001161533304d305600213232323200453330503057305e00215333050305a371a6eb8c13c0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc188c1a4c1c00044c8c8c8c94ccc198cdd79ba7306400250731325333067337126e34dd71833000a4080264646464646464646464646464646464646464646464640e6a6660fc60f600420e42c6eb4c1ec004c1e40114ccc1e8c20404c220040084c8c8c8c8c8c81d54ccc20004c1f400841d058dd6983e800983d8011bad307b0013079002375a60f20022c6110020026ea8c1dc004c1d4008dd6983a80098398011bad30730013071002375a60e200260de00aa6660e060ee0042a6660e060f86eb4c1bc0044c81994ccc1c4c1b80044194585854ccc1c0c1e00084c81994ccc1c400441945858c1f8008c1f0004dd518360009835002a99983598390010a999835983b9bad306a001132061533306c3069001106016161533306b3073002132061533306c0011060161630790023077001375460ce00260ca0022c60c800c2c6ea0c144dd6983200098310011bad3062001307100116375460c000260bc008a6660be60cc60da004264a6660c0a660b260ce002260d4002264a6660c266e24dc69bae3060001481004c815d4ccc188c17c00441585858c17800858dc69bae305e00116306d001375460b800260b40046eb4c168004c160008dd6982c000982b002299982b982f1832801099299982c299828982f80089831000899299982c99b89371a6eb8c160005204013204f533305a3057001104e1616305600216371a6eb8c15800458c194004dd5182a00098290022999829982d1830801099191919191919191919029299982e982d00288288b299982d98310010991919191902aa999830182e802882a0b299982f18328010991919191902c29998319830002882b8b299983098340010a99983098359b8d375c60c00022640aea6660c460be00220ac2c2c2a6660c260d20042a6660c260d66e34dd7183000089902ba999831182f800882b0b0b0b183780118368009baa305d0011533305e3066002132323232323205953330643061002105816375a60c200260be0046eb4c17c004c174008dd6982e8008b183600118350009baa305a0011533305b3063002132051533305c0011050161630690023067001375460ae00260aa00aa6660ac60ba0042a6660ac60c06e34dd7182a800899026299982b982a00088258b0b0a99982b182f0010a99982b18301b8d375c60aa002264098a6660ae60a800220962c2c2c60c800460c40026ea8c14800458c184004dd5182800098270008b0b182f0009baa001304c00116305b0023059001375460926090609060880062c60b00026ea8c11cc108c11cc10800458cc0cc05802458cccc0ec054040800458dd6982198210049bad30420083041008375a60800106eacc0fcc0f8c0d0c0f8030dd6181f0061bac303d00d372466e2cdd6981e181d8009bae303c3037303c001303600430390013038001302d3033333303523253302e3302d303a001011130433302b37566074607200202060686072607060680026eb0c0e001c8c8c94ccc0f0c114c1280084c0ec00458c128004dd5181c981c181c181a181c981c181a0008b181b8008a99981c19818118229bad3048001333302e00800320011616102d304600137540146eacc0d0004c0c8c0c8004c0c4004c0c0004c0acc0c0c0ac0114ccc0c0c0dcc0f80084dd718178008b181f0009baa302d302c3028001223232533302c3375e00605e05c26600e0046e98cc01c00400cc0a8c0a4c09400cc0a4c09000888888ccc049c0198031980ca45004881000033330127006600c00a0046600c008002446464a66605466e24dd6801a400005826600a0046e98cc01400400cc0a0c09cc08c00cc09cc08800888cc054cdd800100081611980111919a999813980b000891280089118010019191118010019ba6001122500133003253330273375e002054244a00224460040066eac00400488cc088894ccc0a00040a44c8ccc014c0dcc09c0088cc05ccdd8181b981400180080108009801181280080091198008012400446464644660020060046eb4c08cc088008dd69811000980e00091180111180191191919191919191911980080180119b820023370600c00666e08004cdc1803001299981598190020a40002a66605666e2401120001480045200233025533302a3371200400220022004a66605466e2400800440084004c028008c024008cdc100200119b8200400225333020337120029000898050008800919299981018011119b88302800233704900000088008a99981018011119b873028002337046008e1000440044cdc0240040026002e1088cc0108cc0148c0b4dd698180009bab302f0013330057000046600646e98cc0108dd418059bad0013756002002446603644a66604200204426601c66ec0c0b8c07c004c010c0bcc07c004c008c0780040048c064894ccc07c0045288a998089801980e80089801180e000911199802111ba63330062237506600e6eb4008dd68009bab00237560020040024446666032446600244a666042004200226666008010603e004603c004002444a66604400226601e0060042646464a66604866ebc0080044cc048cdd8001198059819803181980199980400680298110020a99981219b90375c0046eb80044cc048018cccc02003000cc0880100144cc04800ccccc020030018014c088010c0c4008c0c0010c0800040140080048800488008dc0a4000466602c002941289299980a99b890014800058400488cdd2a4000660066ea4008cc00cdd4800a5eb815d02ba322323333004375c6024601a00490001199980280124000eb4dd58008019bae30113010300c001232222330112253330170011005153330163375e6048602a00200c26008604a602a0022600460280020026ea400488cdd79ba7300a002374e60140024466601e00400229408c02cc02cc02cc02c00526233002232223002003375660360026ea4004888cc024894ccc03c004489400454ccc038cdd7980e1806800802098029806800898011806000800918031129998060008a5015330043003300a00113002300900123300800114a24602c6ea8004c0088894ccc020c03c00440084cc00c004cdc30010009800911299980400089128008a9998039801180300089911180100198030008998018011802800919180111980100100091801119801001000aba25742ae6955cf8801a610100004c010101004bd6f7b6301b8248008dc3a40006e1d2002370e90021b87480e0dc4240006e2520001374e97ae05573aaae79", "role": "MintingPolicyRole", "type": "PlutusScriptV2", "version": "ScriptV2" diff --git a/compiled-scripts/partial-order b/compiled-scripts/partial-order index 6334d80..557cada 100644 --- a/compiled-scripts/partial-order +++ b/compiled-scripts/partial-order @@ -1,11 +1,11 @@ { - "cborHex": "590a3a590a370100003232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323222222323232323232323232323232325333038303e3042003132323232323232333303b23303a008303f303b0013758607c00c4646464666607e464a6607c6607e6088608000203e260966660786eacc110c10cc100004dd71822182000f1bae30443043304001e30433042303f0013758608401246464a66608c609a60a00042646464a666092609e66608000e00201226464646464646464a6660a260ac004264a6660a46609e44a6660aa002294054ccc150cdd798298008018a51130023052001375860a20282a6660a466e1c01cc11d20021048161637526eb8c14009854ccc144c15c0084c94ccc148cdc4240000022a6660a466e2000401854ccc148ccc101c49981d19981e380010301b001330440053750002666606260b46608c60a2609a0546608c60a260a0609a0546608c60a260a060a0609a0546608c60a26060609a0546608c6ea0cdc0803000998231828981798268151982318289828181798268151982318289817182681519823182898281817182681519823182898169826815198231ba8337006eb4c144c140c0b4c1340a920024bd70182898268088048040991919299982a982d982f80109919299982b982e18308010a99982b9981c181b9bad3056001005104d16104d3061001375460a80442a6660aa6606c60746eb4c15000400c4c8c94ccc15cc170c18400854ccc15ccc0e0c0dcdd6982b00080288268b082698308009baa305402216305f001375460a404260a202a2c2c2c6eb4c14000454ccc144cdc38031823240042a6660a266607ee24cc0e4cc0e4ccc0edc0007980d002998218021ba80053304330593304537520126608a6ea40452f5c098010101003333030019305002500800713232325333054305a305e002132325333056305b306000215333056330373036375a60aa00200a20982c209860c00026ea8c14c08454ccc150cc0d4c0e4dd6982980080189919299982b182d98300010a99982b1981b981b1bad3055001005104c16104c3060001375460a60422c60bc0026ea8c144080c1400505858c16c008c164004dd501298260101bad304b01e3330423756609401e0060166eb0c12403cdd5982418239823805881f9bae53330485333048304d00114a2266e1d2038001100216371a6eb8004c11400458c140004dd5182198211821181f98219821181f8008b1bab30413040303d0013040303f303c002375c607e01e2c607800260766076607600260746074002607200260700026068607000a606e0042c4646464646464646464646606860820266ea14ccc108cdc4182300199b8248000008400454ccc108cdc3982300199b82337080060040042002266e0120020013370800400266e08008cdc180300199b820013370600c004a66607c6086008290000a99981f19b890044800052001148008ccc0e88894ccc100c11400440084cc00c004cdc3001000a99981e99b8900200110011002533303d3371200400220042002605a0046058004607c6eb4c0e4c0e0008cdc10011bad3038001303330370083041001375460686066002605e01460620026060002605e002605c002605a0026058605800260560026054002604c006460486048600400246046604660040024604460446004002460426042604200244464604444a666050002052264a666050a6604266018604e604c604c0026062008266044604e00200c26eacc09cc098c08cc09c0084c00cc098008c088c098004cc060cc084894ccc09c004584c94ccc09ccdd798191813001003080089801981280118181812800800a5eb808c0a4cc054c0a4cc054c0a52f5c06602a60109452f5c06602a600e00297ae022323253301c33005302200230220011330053022302100130223021002301d002301c0022232323232323232325333028533302833710004002294454ccc0a0cdc38010008991929998151818002099b88375a60520046eb4c0a4004528181a00218198020a5014a22a6660506601800c00a26660506016604e604c0106016604e604c00e944528181880118180011baa002375400460440046042004603800460360044604860506ea800488c8c8c94ccc084c09c0084c8c94ccc08cc0a4c0b40084cdd79ba7003374e0022940c0b4004dd50020a999810981400109919299981198151816801099baf374e0066e9c00452818168009baa0041323253330233028302d00213375e6e9c00cdd38008a50302d0013754008605600460520026ea80088c090cc040c008004cc040c090cc040cdd2a400897ae03301030034a297ae04bd7011811998079812198079ba80014bd701980798012514bd70119ba533301a0014800920004bd7011199802380002330032374c6600846ea0c044dd68009bab001001223301622533301c00101d13300f33760604a60340026008604c603400260046032002002444666008446e98ccc01888dd4198039bad002375a0026eac008dd5800801000911199980a911980091299980e801080089999802004180d801180d001000911299980f0008998088018010991919299981019baf0020011330143376000466016605600c605600666601001a00a603c0082a66604066e40dd70011bae001133014006333300800c003301e004005133014003333300800c006005301e00430290023028004301c001005002001220012200223222333013222533301a00213300923300701d3756604a002002264a6660360042a660266600e00203a2660144660106eacc098004078c06000c4c8c8c94ccc074cdc78010008a9980b19805002001899803980d803180d8028a99980e99b9000200115330163300a004020133007301b00600515330163300a020003133007006301b005375c604c60360086eb8c094c068010dd59812980c8011bab30243018002002001223330122225333019002133008233007008375a6048002002264a6660340042a660246600e0020102660124660106eb4c094004024c05c00c4c8c8c94ccc070cdc78010008a9980a99805002001899803980d003180d0028a99980e19b9000200115330153300a00400b133007301a00600515330153300a00b003133007006301a005375c604a60340086eb8c090c064010dd69812180c0011bad30233017002002001480008c038894ccc0500045288a99806180198090008980118088009299980819b89001480044c014004400488c8c94ccc048cdd7801a601010000014133005002374c6600a0020066020601e6018006601e6016004446600666ec00080040495d01b8148001262223333004002480008cccc014009200075a6eac00400c8c8888cc028894ccc040004401454ccc03ccdd7980c980700080309802180d18070008980118068008009ba90012233300900200114a04466ebcdd398018011ba730030012301137540026002444a666010002244a0022a66600e6004600c002264446004006600c002266006004600a002464600446600400400246004466004004002ae895d0ab9a5573e200297adef6c60370490011b8748000dc3a40046e1d2004374a90001ba54800955ceaab9e01", + "cborHex": "5912f95912f6010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232222223232323232323232323232323232323232533304c3054305a002132323232323232333304f23304d0083053304e001375860a400c4646464646464a6660b460c46660a000800400c2646464646464646464646464646464a6660d260e0008264a6660d4660ce44a6660da002294054ccc1b0cdd798358008018a5113002306a001375860d20302a6660d466e1c034c161200213232323232533306f33051333305502300d01501430083333304601000f0030020011533306f53304f3076375a60dc0542660d001860f8660c40e8660c40e8660c40e897ae010631533306f33333304b0140150160744a04666660b00960480024646464646609a6666609802c02a0126ea0cdc09bad00853330753304b002077153330753304a002304730027082002266e040052002100100700530017086608c608a02a4660020060046eb4c1c40d0dd68020a5010631616306d306c003306c002306b00230690013064007161637526eb8c1a00b854ccc1a4c1c40104c94ccc1a8c1d800454ccc1a8cdc400080609929998359981b80098350140a9998359981b0009835013899191919191919191919191999983991299983c80089112800891919a99983d19839802983c80089999983102a9ba9022375660f260f00024a6660f8002244a002264a6660f86108026eb4c22c04c1ec00854ccc1f0c20c04ccc1c8080090004488c00800c48940044894004dd7184480983d000891280089128009299983d99b8f001027132223002233001007004307a00413300530790044a026600860f000600460e660f00040369448c00488c8d4ccc1e94cc1c800c4ccc1e80192825113232233001003002375066e00dd68071bad00933306970000200e246600200401c44646464646464646464a66610a02660ce0080162a66610a0266ebc014c24804cc1e0c21004128cc1e008ccc1e0098cc1e0c2100411ccc1e0dd419b8102701c3307802533078024330783752062660f0610802084660f0610802082660f06ea0cdc01bad30840104048008cc1e0c210040fccc1e004ccc1e0c24804cc1e0dd419b80375a014002660f002e660f06ea0cdc000b00125eb80cc1e0dd400a25eb8054ccc21404cdc49998331119b8000233308401222533308b010011002133003337000049001184400800a40006eacc2580400520000044805041e45858594ccc21004cc1f4090cc1bd221004881001480004cc1e4008cc1bd220100488100330780010233306e001008375661000200aa66610002610e020042c2a66610002611202004260fe002266660ce6eb8c1fc004098800458c23804008c23004004dd5183e183d800983d183b002199834380330620193750012660ca046660c40346ea004058c1d0080cccccc14006406806c0092812513305c3305e488100488100001307102b337006eb4c1c0c1bc0a4004c02001cdd69837183680198368011836001183500098328040b0b183480c8b0b1bad3068003153330693370e01860ae900109929998351981b00098348138a9998351981a80098348130991919299983699827999982981080580980919982e38030060013305600d3750600a01e26464a6660de66666609602802a02c004a660ce002266ebc0081d08ccccc16012c0900048cc1240140044008418c58cc19c02cc1eccc1841cccc1841cccc1841cd2f5c060d804c2c6666608601a01860d600460d600260d660d400260d200260c800e2c2c60d00302c46464646464a6660dc660880040e020022a6660dc6608600460806004e1040044cdc0240040026002e10cc0fcc0f80108cc00400c008dd6983518348011bad30690013063008233054012333057700660a2660a6020028981010100333057700660a20126ea0028004c1d4008c1cc004dd5015983100d98308131830010182f810182f0111bad305d01f333053001005009375660b60186eb0c168030dd5982c982c182c0040827182c182b8011bae30570013055305530513333053232533051330523058001023130613304e375660b060ae00204460a460ae60ac60a40026eb0c1580248c8c94ccc168c18cc1a00084c16400458c1a0004dd5182b982b182b1829182b982b18290008b1bab30553054001304f30543053304f002375c60a60242c60a0002609e609e609e002609c609c002609a0026098002608e609800860960022c60b40026ea8c124c120004c10c03cc118004c114004c110004c10c004c108004c104004c100004c0fc004c0f8004c0f4004c0f0004c0ec004c0e8004c0d400c88c8c94ccc0e4c104c11c008528899804182319816182319816182325eb80cc0b0c01d28a5eb80cc0b0c018dd6981c000a5eb80010c11c004dd5000911919299981c182018230010a5113300730453302b3005375a606e00266056608a6605666e9520044bd701981598032514bd7025eb80010c118004dd5000918209981399ba548008cc09cdd4000a5eb80cc09cc00928a5eb808cdd2999819800a4004900025eb8088c8c94cc0b4cc014c0d0008c0d00044cc014c0d0c0cc004c0d0c0cc008c0b8008c0b400888c8c8c8c8c8c8c8c94ccc0e94ccc0e8cdc40010008a511533303a3370e00400226464a6660786088008266e20dd6981d8011bad303b00114a06094008609200829405288991919299981ea99981e982280109919299981f98239826801099baf374e0066e9c00452818268009baa0081533303d304600213232533303f3048304d00213375e6e9c00cdd38008a50304d001375401026464a66607e608c609a004266ebcdd38019ba700114a0609a0026ea80204ccc0f4c038c0f0c0ec02cc038c0f0c0ec029288a50304b0023049001375400c608e004608c0046ea8008dd5001181a0011819801181680118160011181c181f1baa00122330010024800888c00888c00c88c8c8c8c8c8c8c8c88cc00400c008cdc100119b830060033370400266e0c0180094ccc0e0c0fc01052000153330383371200890000a40022900119819299981b99b8900200110011002533303733712004002200420026014004601200466e08010008cdc10020011299981699b89001480044c06c004400488c00888c00c88cdc399b82001004337040040064460044460064466e20cdc100080219b820020032222233301d7006602e660329110048810000333301d7006602e00a0046602e0080024466604e444a66605c00426602446600e0686eacc0f40040044c94ccc0bc00854cc098cc01c0040d04cc04c8cc020dd5981f00081a98160018991919299981899b8f00200115330293300a004003133007302f006302f00515333031337200040022a660526601400806e26600e605e00c00a2a660526601406e00626600e00c605e00a6eb8c0f8c0bc010dd7181e98170021bab303d302d0023756607860580040040024466604c444a66605a004266022466e2401cdd6981e00080089929998170010a9981299b890010071330122337126eb4c0f4004020c0ac00c4c8c8c94ccc0c0cdc78010008a9981419b89004003133007302e006302e00515333030337200040022a6605066e240100284cc01cc0b801801454cc0a0cdc480500189980380318170029bae303d302e004375c6078605a0086eb4c0f0c0b0008dd6981d9815801001000a40004644460040066eacc0d4004888888cccc0988cc090c0a8c0940040140188c8c8c8c8c8c94ccc0c4cc04ccc074dd598180031bab3030302f00233302070066602444666044e00008dd5982100081b8009980d1980e24410048810000a13008001163756605e0026052a66605e606c0042c2a66605e6070004264646464008a666064607260800042646464646464646464646464064a66607c607600a20622ca6660786086004264646464068a666080607a00820662ca66607c608a6098004264a66607e608c609a002264a66608060866e9cc0f800454ccc100c12cdc69bae303f001132323203753330433040002103616375a6080002607c0062c2c609c0022c6ea8c0f400458c130004dd5181d8008a99981e1822001099018a99981e80088180b0b182500118240009baa303800130360053016375600660286eac008cc0488c8c8c8cdd8299981ca9980c982000189821801898238020b1824002180b1bab30470033301423233760a66607266e24dc69bae3047002481004c11c00858c120008dd698238009bab3046002371a6eb8c110004dd58009819800981880119807919191919191919bb03047007304800730173756608e00ca66606e607c608a008264a666070607e608c002264a66607260786e9cc0dc00454ccc0e4c110dc69bae30380011323232030533303c3039002102f16375a6072002606e0082c2c608e0022c6ea8c0d800858c050dd59822802182200119808919191919bb05333038533018303f003130420031304600416304700430153756608c0066602646466ec14ccc0e0cdc49b8d375c608c0049020098230010b18238011bad30460013756608a0046e34dd718218009bab3043002375460820026eacc0c400458c100004dd500098170008999980b1bae302e00100a23232320045333032303930400021323232323232323232323232032533303e303b005103116533303c30430021323232320345333040303d004103316533303e3045304c002132533303f3046304d00113253330403043374e607c0022a66608060966e34dd7181f800899191901ba9998219820001081b0b1bad3040001303e0031616304e001163754607a0022c60980026ea8c0ec00454ccc0f0c1100084c80c54ccc0f400440c05858c128008c120004dd5181c000981b002980b1bab0033014375600466024464646466ec14ccc0e54cc064c10000c4c10c00c4c11c01058c120010c058dd598238019980a11919bb05333039337126e34dd71823801240802608e0042c60900046eb4c11c004dd598230011b8d375c60880026eac004c0cc004c0c4008cc03c8c8c8c8c8c8c8cdd818238039824003980b9bab30470065333037303e30450041325333038303f30460011325333039303c374e606e0022a66607260886e34dd7181c0008991919018299981e181c80108178b1bad3039001303700416163047001163754606c0042c60286eacc114010c110008cc0448c8c8c8cdd8299981c29980c181f80189821001898230020b1823802180a9bab30460033301323233760a66607066e24dc69bae3046002481004c11800858c11c008dd698230009bab3045002371a6eb8c10c004dd598218011baa3041001375660620022c60800026ea800458c0f4008c0ec004dd5181598150009814981280088011181091299981380081509980c98019812800980118120009199810112999813000890020991299981398008010b0998021812801919b90001003375c60666048002002494094ccc088cc0188cc0180bc0040044004588cc0840045289180e91129998120008801099801998020011811000981080091198021198021b8948000004cc03000800488cc0108c00cdd698178008009119801918019bab302e0010012301922533301f00114a22a6602c6006603a00226004603800244644603644a66604200204826464646464a66604aa66604a6058004294054ccc094c0b40084cccc030dd718120008041198050008028a5013300930240010041375660486046603e604800c2600e604600c606600460620026ea8c084c080c080008c080004c068c07c004894cc058cdd780100209980b80080191980111911180100198150009ba90012223301822533301e00112250011533301d3375e605660380020082600a6038002260046036002002446464a66603666e24dd6801a400003e26600a0046e98cc01400400cc064c060c05000cc060c04c00888cc02ccdd800100080f111812198051ba90023300a375200297ae0223330057000046600646e98cc0108dd418031bad0013756002002446602444a66603000203626601466ec0c094c058004c010c098c058004c008c054004004dc0a4000444666008446e98ccc01888dd4198039bad002375a0026eac008dd58008010009111999808111980091299980c001080089999802004180b001180a801000911299980c8008998058018010991919299980d99baf00200113300e3376000466016605400c605400666601001a00a60320082a66603666e40dd70011bae00113300e006333300800c003301900400513300e003333300800c00600530190043028002302700430170010050020012200122002574093111998018011bae300c3007001375c60186016600e002444666600800490001199980280124000eb4dd58008019191111980591299980880088028a99980819baf301e300f00100613004301f300f00113002300e001001375200244666014004002294088cdd79ba73003002374e60060024602c6ea8004c0088894ccc020c03c00440084cc00c004cdc30010009800911299980400089128008a9998039801180300089911180100198030008998018011802800919180111980100100091801119801001000aba25742ae6955cf919800a400090011baf374e97ae010024c010100004bd6f7b6301b8748000dc3a40046e1d2004370e901c1b8748100dc4240006e9520005573aaae79", "description": "DEX.PartialOrder", "params": [ "PlutusLedgerApi.V1.Address:Address", "PlutusLedgerApi.V1.Value:AssetClass" ], - "rawHex": "590a370100003232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323222222323232323232323232323232325333038303e3042003132323232323232333303b23303a008303f303b0013758607c00c4646464666607e464a6607c6607e6088608000203e260966660786eacc110c10cc100004dd71822182000f1bae30443043304001e30433042303f0013758608401246464a66608c609a60a00042646464a666092609e66608000e00201226464646464646464a6660a260ac004264a6660a46609e44a6660aa002294054ccc150cdd798298008018a51130023052001375860a20282a6660a466e1c01cc11d20021048161637526eb8c14009854ccc144c15c0084c94ccc148cdc4240000022a6660a466e2000401854ccc148ccc101c49981d19981e380010301b001330440053750002666606260b46608c60a2609a0546608c60a260a0609a0546608c60a260a060a0609a0546608c60a26060609a0546608c6ea0cdc0803000998231828981798268151982318289828181798268151982318289817182681519823182898281817182681519823182898169826815198231ba8337006eb4c144c140c0b4c1340a920024bd70182898268088048040991919299982a982d982f80109919299982b982e18308010a99982b9981c181b9bad3056001005104d16104d3061001375460a80442a6660aa6606c60746eb4c15000400c4c8c94ccc15cc170c18400854ccc15ccc0e0c0dcdd6982b00080288268b082698308009baa305402216305f001375460a404260a202a2c2c2c6eb4c14000454ccc144cdc38031823240042a6660a266607ee24cc0e4cc0e4ccc0edc0007980d002998218021ba80053304330593304537520126608a6ea40452f5c098010101003333030019305002500800713232325333054305a305e002132325333056305b306000215333056330373036375a60aa00200a20982c209860c00026ea8c14c08454ccc150cc0d4c0e4dd6982980080189919299982b182d98300010a99982b1981b981b1bad3055001005104c16104c3060001375460a60422c60bc0026ea8c144080c1400505858c16c008c164004dd501298260101bad304b01e3330423756609401e0060166eb0c12403cdd5982418239823805881f9bae53330485333048304d00114a2266e1d2038001100216371a6eb8004c11400458c140004dd5182198211821181f98219821181f8008b1bab30413040303d0013040303f303c002375c607e01e2c607800260766076607600260746074002607200260700026068607000a606e0042c4646464646464646464646606860820266ea14ccc108cdc4182300199b8248000008400454ccc108cdc3982300199b82337080060040042002266e0120020013370800400266e08008cdc180300199b820013370600c004a66607c6086008290000a99981f19b890044800052001148008ccc0e88894ccc100c11400440084cc00c004cdc3001000a99981e99b8900200110011002533303d3371200400220042002605a0046058004607c6eb4c0e4c0e0008cdc10011bad3038001303330370083041001375460686066002605e01460620026060002605e002605c002605a0026058605800260560026054002604c006460486048600400246046604660040024604460446004002460426042604200244464604444a666050002052264a666050a6604266018604e604c604c0026062008266044604e00200c26eacc09cc098c08cc09c0084c00cc098008c088c098004cc060cc084894ccc09c004584c94ccc09ccdd798191813001003080089801981280118181812800800a5eb808c0a4cc054c0a4cc054c0a52f5c06602a60109452f5c06602a600e00297ae022323253301c33005302200230220011330053022302100130223021002301d002301c0022232323232323232325333028533302833710004002294454ccc0a0cdc38010008991929998151818002099b88375a60520046eb4c0a4004528181a00218198020a5014a22a6660506601800c00a26660506016604e604c0106016604e604c00e944528181880118180011baa002375400460440046042004603800460360044604860506ea800488c8c8c94ccc084c09c0084c8c94ccc08cc0a4c0b40084cdd79ba7003374e0022940c0b4004dd50020a999810981400109919299981198151816801099baf374e0066e9c00452818168009baa0041323253330233028302d00213375e6e9c00cdd38008a50302d0013754008605600460520026ea80088c090cc040c008004cc040c090cc040cdd2a400897ae03301030034a297ae04bd7011811998079812198079ba80014bd701980798012514bd70119ba533301a0014800920004bd7011199802380002330032374c6600846ea0c044dd68009bab001001223301622533301c00101d13300f33760604a60340026008604c603400260046032002002444666008446e98ccc01888dd4198039bad002375a0026eac008dd5800801000911199980a911980091299980e801080089999802004180d801180d001000911299980f0008998088018010991919299981019baf0020011330143376000466016605600c605600666601001a00a603c0082a66604066e40dd70011bae001133014006333300800c003301e004005133014003333300800c006005301e00430290023028004301c001005002001220012200223222333013222533301a00213300923300701d3756604a002002264a6660360042a660266600e00203a2660144660106eacc098004078c06000c4c8c8c94ccc074cdc78010008a9980b19805002001899803980d803180d8028a99980e99b9000200115330163300a004020133007301b00600515330163300a020003133007006301b005375c604c60360086eb8c094c068010dd59812980c8011bab30243018002002001223330122225333019002133008233007008375a6048002002264a6660340042a660246600e0020102660124660106eb4c094004024c05c00c4c8c8c94ccc070cdc78010008a9980a99805002001899803980d003180d0028a99980e19b9000200115330153300a00400b133007301a00600515330153300a00b003133007006301a005375c604a60340086eb8c090c064010dd69812180c0011bad30233017002002001480008c038894ccc0500045288a99806180198090008980118088009299980819b89001480044c014004400488c8c94ccc048cdd7801a601010000014133005002374c6600a0020066020601e6018006601e6016004446600666ec00080040495d01b8148001262223333004002480008cccc014009200075a6eac00400c8c8888cc028894ccc040004401454ccc03ccdd7980c980700080309802180d18070008980118068008009ba90012233300900200114a04466ebcdd398018011ba730030012301137540026002444a666010002244a0022a66600e6004600c002264446004006600c002266006004600a002464600446600400400246004466004004002ae895d0ab9a5573e200297adef6c60370490011b8748000dc3a40046e1d2004374a90001ba54800955ceaab9e01", + "rawHex": "5912f6010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232222223232323232323232323232323232323232533304c3054305a002132323232323232333304f23304d0083053304e001375860a400c4646464646464a6660b460c46660a000800400c2646464646464646464646464646464a6660d260e0008264a6660d4660ce44a6660da002294054ccc1b0cdd798358008018a5113002306a001375860d20302a6660d466e1c034c161200213232323232533306f33051333305502300d01501430083333304601000f0030020011533306f53304f3076375a60dc0542660d001860f8660c40e8660c40e8660c40e897ae010631533306f33333304b0140150160744a04666660b00960480024646464646609a6666609802c02a0126ea0cdc09bad00853330753304b002077153330753304a002304730027082002266e040052002100100700530017086608c608a02a4660020060046eb4c1c40d0dd68020a5010631616306d306c003306c002306b00230690013064007161637526eb8c1a00b854ccc1a4c1c40104c94ccc1a8c1d800454ccc1a8cdc400080609929998359981b80098350140a9998359981b0009835013899191919191919191919191999983991299983c80089112800891919a99983d19839802983c80089999983102a9ba9022375660f260f00024a6660f8002244a002264a6660f86108026eb4c22c04c1ec00854ccc1f0c20c04ccc1c8080090004488c00800c48940044894004dd7184480983d000891280089128009299983d99b8f001027132223002233001007004307a00413300530790044a026600860f000600460e660f00040369448c00488c8d4ccc1e94cc1c800c4ccc1e80192825113232233001003002375066e00dd68071bad00933306970000200e246600200401c44646464646464646464a66610a02660ce0080162a66610a0266ebc014c24804cc1e0c21004128cc1e008ccc1e0098cc1e0c2100411ccc1e0dd419b8102701c3307802533078024330783752062660f0610802084660f0610802082660f06ea0cdc01bad30840104048008cc1e0c210040fccc1e004ccc1e0c24804cc1e0dd419b80375a014002660f002e660f06ea0cdc000b00125eb80cc1e0dd400a25eb8054ccc21404cdc49998331119b8000233308401222533308b010011002133003337000049001184400800a40006eacc2580400520000044805041e45858594ccc21004cc1f4090cc1bd221004881001480004cc1e4008cc1bd220100488100330780010233306e001008375661000200aa66610002610e020042c2a66610002611202004260fe002266660ce6eb8c1fc004098800458c23804008c23004004dd5183e183d800983d183b002199834380330620193750012660ca046660c40346ea004058c1d0080cccccc14006406806c0092812513305c3305e488100488100001307102b337006eb4c1c0c1bc0a4004c02001cdd69837183680198368011836001183500098328040b0b183480c8b0b1bad3068003153330693370e01860ae900109929998351981b00098348138a9998351981a80098348130991919299983699827999982981080580980919982e38030060013305600d3750600a01e26464a6660de66666609602802a02c004a660ce002266ebc0081d08ccccc16012c0900048cc1240140044008418c58cc19c02cc1eccc1841cccc1841cccc1841cd2f5c060d804c2c6666608601a01860d600460d600260d660d400260d200260c800e2c2c60d00302c46464646464a6660dc660880040e020022a6660dc6608600460806004e1040044cdc0240040026002e10cc0fcc0f80108cc00400c008dd6983518348011bad30690013063008233054012333057700660a2660a6020028981010100333057700660a20126ea0028004c1d4008c1cc004dd5015983100d98308131830010182f810182f0111bad305d01f333053001005009375660b60186eb0c168030dd5982c982c182c0040827182c182b8011bae30570013055305530513333053232533051330523058001023130613304e375660b060ae00204460a460ae60ac60a40026eb0c1580248c8c94ccc168c18cc1a00084c16400458c1a0004dd5182b982b182b1829182b982b18290008b1bab30553054001304f30543053304f002375c60a60242c60a0002609e609e609e002609c609c002609a0026098002608e609800860960022c60b40026ea8c124c120004c10c03cc118004c114004c110004c10c004c108004c104004c100004c0fc004c0f8004c0f4004c0f0004c0ec004c0e8004c0d400c88c8c94ccc0e4c104c11c008528899804182319816182319816182325eb80cc0b0c01d28a5eb80cc0b0c018dd6981c000a5eb80010c11c004dd5000911919299981c182018230010a5113300730453302b3005375a606e00266056608a6605666e9520044bd701981598032514bd7025eb80010c118004dd5000918209981399ba548008cc09cdd4000a5eb80cc09cc00928a5eb808cdd2999819800a4004900025eb8088c8c94cc0b4cc014c0d0008c0d00044cc014c0d0c0cc004c0d0c0cc008c0b8008c0b400888c8c8c8c8c8c8c8c94ccc0e94ccc0e8cdc40010008a511533303a3370e00400226464a6660786088008266e20dd6981d8011bad303b00114a06094008609200829405288991919299981ea99981e982280109919299981f98239826801099baf374e0066e9c00452818268009baa0081533303d304600213232533303f3048304d00213375e6e9c00cdd38008a50304d001375401026464a66607e608c609a004266ebcdd38019ba700114a0609a0026ea80204ccc0f4c038c0f0c0ec02cc038c0f0c0ec029288a50304b0023049001375400c608e004608c0046ea8008dd5001181a0011819801181680118160011181c181f1baa00122330010024800888c00888c00c88c8c8c8c8c8c8c8c88cc00400c008cdc100119b830060033370400266e0c0180094ccc0e0c0fc01052000153330383371200890000a40022900119819299981b99b8900200110011002533303733712004002200420026014004601200466e08010008cdc10020011299981699b89001480044c06c004400488c00888c00c88cdc399b82001004337040040064460044460064466e20cdc100080219b820020032222233301d7006602e660329110048810000333301d7006602e00a0046602e0080024466604e444a66605c00426602446600e0686eacc0f40040044c94ccc0bc00854cc098cc01c0040d04cc04c8cc020dd5981f00081a98160018991919299981899b8f00200115330293300a004003133007302f006302f00515333031337200040022a660526601400806e26600e605e00c00a2a660526601406e00626600e00c605e00a6eb8c0f8c0bc010dd7181e98170021bab303d302d0023756607860580040040024466604c444a66605a004266022466e2401cdd6981e00080089929998170010a9981299b890010071330122337126eb4c0f4004020c0ac00c4c8c8c94ccc0c0cdc78010008a9981419b89004003133007302e006302e00515333030337200040022a6605066e240100284cc01cc0b801801454cc0a0cdc480500189980380318170029bae303d302e004375c6078605a0086eb4c0f0c0b0008dd6981d9815801001000a40004644460040066eacc0d4004888888cccc0988cc090c0a8c0940040140188c8c8c8c8c8c94ccc0c4cc04ccc074dd598180031bab3030302f00233302070066602444666044e00008dd5982100081b8009980d1980e24410048810000a13008001163756605e0026052a66605e606c0042c2a66605e6070004264646464008a666064607260800042646464646464646464646464064a66607c607600a20622ca6660786086004264646464068a666080607a00820662ca66607c608a6098004264a66607e608c609a002264a66608060866e9cc0f800454ccc100c12cdc69bae303f001132323203753330433040002103616375a6080002607c0062c2c609c0022c6ea8c0f400458c130004dd5181d8008a99981e1822001099018a99981e80088180b0b182500118240009baa303800130360053016375600660286eac008cc0488c8c8c8cdd8299981ca9980c982000189821801898238020b1824002180b1bab30470033301423233760a66607266e24dc69bae3047002481004c11c00858c120008dd698238009bab3046002371a6eb8c110004dd58009819800981880119807919191919191919bb03047007304800730173756608e00ca66606e607c608a008264a666070607e608c002264a66607260786e9cc0dc00454ccc0e4c110dc69bae30380011323232030533303c3039002102f16375a6072002606e0082c2c608e0022c6ea8c0d800858c050dd59822802182200119808919191919bb05333038533018303f003130420031304600416304700430153756608c0066602646466ec14ccc0e0cdc49b8d375c608c0049020098230010b18238011bad30460013756608a0046e34dd718218009bab3043002375460820026eacc0c400458c100004dd500098170008999980b1bae302e00100a23232320045333032303930400021323232323232323232323232032533303e303b005103116533303c30430021323232320345333040303d004103316533303e3045304c002132533303f3046304d00113253330403043374e607c0022a66608060966e34dd7181f800899191901ba9998219820001081b0b1bad3040001303e0031616304e001163754607a0022c60980026ea8c0ec00454ccc0f0c1100084c80c54ccc0f400440c05858c128008c120004dd5181c000981b002980b1bab0033014375600466024464646466ec14ccc0e54cc064c10000c4c10c00c4c11c01058c120010c058dd598238019980a11919bb05333039337126e34dd71823801240802608e0042c60900046eb4c11c004dd598230011b8d375c60880026eac004c0cc004c0c4008cc03c8c8c8c8c8c8c8cdd818238039824003980b9bab30470065333037303e30450041325333038303f30460011325333039303c374e606e0022a66607260886e34dd7181c0008991919018299981e181c80108178b1bad3039001303700416163047001163754606c0042c60286eacc114010c110008cc0448c8c8c8cdd8299981c29980c181f80189821001898230020b1823802180a9bab30460033301323233760a66607066e24dc69bae3046002481004c11800858c11c008dd698230009bab3045002371a6eb8c10c004dd598218011baa3041001375660620022c60800026ea800458c0f4008c0ec004dd5181598150009814981280088011181091299981380081509980c98019812800980118120009199810112999813000890020991299981398008010b0998021812801919b90001003375c60666048002002494094ccc088cc0188cc0180bc0040044004588cc0840045289180e91129998120008801099801998020011811000981080091198021198021b8948000004cc03000800488cc0108c00cdd698178008009119801918019bab302e0010012301922533301f00114a22a6602c6006603a00226004603800244644603644a66604200204826464646464a66604aa66604a6058004294054ccc094c0b40084cccc030dd718120008041198050008028a5013300930240010041375660486046603e604800c2600e604600c606600460620026ea8c084c080c080008c080004c068c07c004894cc058cdd780100209980b80080191980111911180100198150009ba90012223301822533301e00112250011533301d3375e605660380020082600a6038002260046036002002446464a66603666e24dd6801a400003e26600a0046e98cc01400400cc064c060c05000cc060c04c00888cc02ccdd800100080f111812198051ba90023300a375200297ae0223330057000046600646e98cc0108dd418031bad0013756002002446602444a66603000203626601466ec0c094c058004c010c098c058004c008c054004004dc0a4000444666008446e98ccc01888dd4198039bad002375a0026eac008dd58008010009111999808111980091299980c001080089999802004180b001180a801000911299980c8008998058018010991919299980d99baf00200113300e3376000466016605400c605400666601001a00a60320082a66603666e40dd70011bae00113300e006333300800c003301900400513300e003333300800c00600530190043028002302700430170010050020012200122002574093111998018011bae300c3007001375c60186016600e002444666600800490001199980280124000eb4dd58008019191111980591299980880088028a99980819baf301e300f00100613004301f300f00113002300e001001375200244666014004002294088cdd79ba73003002374e60060024602c6ea8004c0088894ccc020c03c00440084cc00c004cdc30010009800911299980400089128008a9998039801180300089911180100198030008998018011802800919180111980100100091801119801001000aba25742ae6955cf919800a400090011baf374e97ae010024c010100004bd6f7b6301b8748000dc3a40046e1d2004370e901c1b8748100dc4240006e9520005573aaae79", "role": "ValidatorRole", "type": "PlutusScriptV2", "version": "ScriptV2" diff --git a/geniusyield-dex-api/geniusyield-dex-api.cabal b/geniusyield-dex-api/geniusyield-dex-api.cabal index ca2d67e..cee1279 100644 --- a/geniusyield-dex-api/geniusyield-dex-api.cabal +++ b/geniusyield-dex-api/geniusyield-dex-api.cabal @@ -101,7 +101,7 @@ library import: common-ghc-opts hs-source-dirs: src exposed-modules: - GeniusYield.DEX.Api.Constants GeniusYield.DEX.Api.PartialOrder + GeniusYield.DEX.Api.PartialOrderConfig GeniusYield.DEX.Api.Utils GeniusYield.DEX.Api.Types diff --git a/geniusyield-dex-api/src/GeniusYield/DEX/Api/Constants.hs b/geniusyield-dex-api/src/GeniusYield/DEX/Api/Constants.hs deleted file mode 100644 index cc1eaea..0000000 --- a/geniusyield-dex-api/src/GeniusYield/DEX/Api/Constants.hs +++ /dev/null @@ -1,16 +0,0 @@ -{-| -Module : GeniusYield.DEX.Api.Constants -Copyright : (c) 2023 GYELD GMBH -License : Apache 2.0 -Maintainer : support@geniusyield.co -Stability : develop - --} -module GeniusYield.DEX.Api.Constants ( minDeposit ) where - -import GeniusYield.Imports ( Natural ) - --- | Altering this constant will result in a modification of the --- validator address. -minDeposit :: Natural -minDeposit = 2_100_000 diff --git a/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs index 7ee292b..acc16e8 100644 --- a/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs +++ b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs @@ -11,59 +11,112 @@ module GeniusYield.DEX.Api.PartialOrder ( PartialOrderDatum (..) , PartialOrderAction (..) , PartialOrderInfo (..) - , minDeposit , partialOrders , completelyFillPartialOrder , partiallyFillPartialOrder + , fillMultiplePartialOrders , getPartialOrderInfo + , getPartialOrdersInfos ) where -import Control.Monad.Except (ExceptT (..), runExceptT) -import qualified PlutusLedgerApi.V1 as Plutus -import qualified PlutusLedgerApi.V1.Value as Plutus +import Control.Monad.Except (ExceptT (..), + runExceptT) +import qualified Data.Map.Merge.Strict as Map +import qualified Data.Map.Strict as Map +import qualified Data.Set as Set +import qualified PlutusLedgerApi.V1 as Plutus +import qualified PlutusLedgerApi.V1.Value as Plutus import qualified PlutusTx -import qualified PlutusTx.Prelude as PlutusTx -import qualified PlutusTx.Ratio as PlutusTx +import qualified PlutusTx.AssocMap as PlutusTx +import qualified PlutusTx.Prelude as PlutusTx +import qualified PlutusTx.Ratio as PlutusTx -import GeniusYield.DEX.Api.Constants +import Control.Monad.Error.Class (liftEither) +import Control.Monad.Reader +import Data.Foldable (foldlM) +import Data.Maybe (fromJust) +import GeniusYield.DEX.Api.PartialOrderConfig (PartialOrderConfigInfoF (..), + fetchPartialOrderConfig) import GeniusYield.DEX.Api.Types +import GeniusYield.HTTP.Errors (IsGYApiError (..)) import GeniusYield.Imports import GeniusYield.TxBuilder.Class +import GeniusYield.TxBuilder.Errors (GYTxMonadException, + throwAppError) import GeniusYield.Types -import GeniusYield.TxBuilder.Errors (throwAppError, GYTxMonadException) -import GeniusYield.HTTP.Errors (IsGYApiError (..)) -import Control.Monad.Error.Class (liftEither) -import Control.Monad.Reader ------------------------------------------------------------------------------- --- Partial Order datum +-- Partial Order Datum ------------------------------------------------------------------------------- +-- | Representation of total fees contained in the order. +data PartialOrderContainedFee = PartialOrderContainedFee + { pocfLovelaces :: Integer + -- ^ Fees explicitly charged in lovelaces, like flat lovelace fee collected + -- from maker and taker(s). + , pocfOfferedTokens :: Integer + -- ^ Fees explicitly collected as percentage of offered tokens from maker. + , pocfAskedTokens :: Integer + -- ^ Fees explicitly collected as percentage of asked tokens from taker. + } deriving stock (Generic, Show) + +PlutusTx.unstableMakeIsData ''PartialOrderContainedFee + + +instance Semigroup PartialOrderContainedFee where + (<>) a b = + PartialOrderContainedFee + { pocfLovelaces = pocfLovelaces a + pocfLovelaces b + , pocfOfferedTokens = pocfOfferedTokens a + pocfOfferedTokens b + , pocfAskedTokens = pocfAskedTokens a + pocfAskedTokens b + } + +instance Monoid PartialOrderContainedFee where mempty = PartialOrderContainedFee 0 0 0 + +-- | Datum of the fee output. +data PartialOrderFeeOutput = PartialOrderFeeOutput + { pofdMentionedFees :: PlutusTx.Map Plutus.TxOutRef Plutus.Value + -- ^ Map, mapping order being consumed to the collected fees. + , pofdReservedValue :: Plutus.Value + -- ^ Value reserved in this UTxO which is not to be considered as fees. + , pofdSpentUTxORef :: Maybe Plutus.TxOutRef + -- ^ If not @Nothing@, it mentions the UTxO being consumed, whose value is used to provide for UTxOs minimum ada requirement. + } deriving stock (Generic, Show) + +PlutusTx.unstableMakeIsData ''PartialOrderFeeOutput + data PartialOrderDatum = PartialOrderDatum - { podOwnerKey :: !Plutus.PubKeyHash + { podOwnerKey :: Plutus.PubKeyHash -- ^ Public key hash of the owner. Order cancellations must be signed by this. - , podOwnerAddr :: !Plutus.Address + , podOwnerAddr :: Plutus.Address -- ^ Address of the owner. Payments must be made to this address. - , podOfferedAsset :: !Plutus.AssetClass + , podOfferedAsset :: Plutus.AssetClass -- ^ The asset being offered. - , podOfferedOriginalAmount :: !Integer + , podOfferedOriginalAmount :: Integer -- ^ Original number of units being offered. Initially, this would be same as `podOfferedAmount`. - , podOfferedAmount :: !Integer + , podOfferedAmount :: Integer -- ^ The number of units being offered. - , podAskedAsset :: !Plutus.AssetClass + , podAskedAsset :: Plutus.AssetClass -- ^ The asset being asked for as payment. - , podPrice :: !PlutusTx.Rational + , podPrice :: PlutusTx.Rational -- ^ The price for one unit of the offered asset. - , podNFT :: !Plutus.TokenName + , podNFT :: Plutus.TokenName -- ^ Token name of the NFT identifying this order. - , podStart :: !(Maybe Plutus.POSIXTime) + , podStart :: Maybe Plutus.POSIXTime -- ^ The time when the order can earliest be filled (optional). - , podEnd :: !(Maybe Plutus.POSIXTime) + , podEnd :: Maybe Plutus.POSIXTime -- ^ The time when the order can latest be filled (optional). - , podPartialFills :: !Integer + , podPartialFills :: Integer -- ^ Number of partial fills order has undergone, initially would be 0. - } - deriving stock (Show) + , podMakerLovelaceFlatFee :: Integer + -- ^ Flat fee (in lovelace) paid by the maker. + , podTakerLovelaceFlatFee :: Integer + -- ^ Flat fee (in lovelace) paid by the taker. + , podContainedFee :: PartialOrderContainedFee + -- ^ Total fees contained in the order. + , podContainedPayment :: Integer + -- ^ Payment (in asked asset) contained in the order. + } deriving stock (Generic, Show) PlutusTx.makeIsDataIndexed ''PartialOrderDatum [('PartialOrderDatum, 0)] @@ -80,14 +133,18 @@ data PodException = PodNftNotAvailable | PodNonPositiveAmount !Integer | PodNonPositivePrice !GYRational | PodRequestedAmountGreaterOrEqualToOfferedAmount - { poeReqAmt:: !Natural + { poeReqAmt :: !Natural , poeOfferedAmount :: !Natural } + | PodRequestedAmountGreaterThanOfferedAmount {poeReqAmt:: !Natural, poeOfferedAmount :: !Natural} | PodNonDifferentAssets !GYAssetClass -- ^ Offered asset is same as asked asset. | PodEndEarlierThanStart !GYTime -- ^ Start time. !GYTime -- ^ End time. + | PodNegativeFrontendFee !GYValue + | PodNotAllOrderRefsPresent -- ^ We couldn't fetch information for some of the given `GYTxOutRef`s. Note that this does not relate to UTxO being spent as depending upon provider, we would fetch information for even those `GYTxOutRef` which have been spent. + !(Set.Set GYTxOutRef) -- ^ Missing output refs. deriving stock Show deriving anyclass (Exception, IsGYApiError) @@ -110,37 +167,60 @@ PlutusTx.makeIsDataIndexed ''PartialOrderAction [ ('PartialCancel, 0) -- Partial Order info ------------------------------------------------------------------------------- +data POIContainedFee = POIContainedFee + { poifLovelaces :: !Natural + , poifOfferedTokens :: !Natural + , poifAskedTokens :: !Natural + } deriving stock (Show, Eq, Generic) + +instance Semigroup POIContainedFee where + (<>) a b = + POIContainedFee + { poifLovelaces = poifLovelaces a + poifLovelaces b + , poifOfferedTokens = poifOfferedTokens a + poifOfferedTokens b + , poifAskedTokens = poifAskedTokens a + poifAskedTokens b + } + +instance Monoid POIContainedFee where mempty = POIContainedFee 0 0 0 + data PartialOrderInfo = PartialOrderInfo - { poiRef :: !GYTxOutRef - -- ^ Reference to the partial order. - , poiOwnerKey :: !GYPubKeyHash - -- ^ Public key hash of the owner. - , poiOwnerAddr :: !GYAddress - -- ^ Address of the owner. - , poiOfferedAsset :: !GYAssetClass - -- ^ The asset being offered. - , poiOfferedOriginalAmount :: !Natural - -- ^ The number of units originally offered. - , poiOfferedAmount :: !Natural - -- ^ The number of units being offered. - , poiAskedAsset :: !GYAssetClass - -- ^ The asset being asked for as payment. - , poiPrice :: !GYRational - -- ^ The price for one unit of the offered asset. - , poiNFT :: !GYTokenName - -- ^ Token name of the NFT identifying this partial order. - , poiStart :: !(Maybe GYTime) - -- ^ The time when the order can earliest be filled (optional). - , poiEnd :: !(Maybe GYTime) - -- ^ The time when the order can latest be filled (optional). - , poiPartialFills :: !Natural - -- ^ The number of past partial fills. - , poiUTxOValue :: !GYValue - -- ^ Total value in the UTxO. - , poiNFTCS :: !GYMintingPolicyId - -- ^ Caching the CS to avoid recalculating for it. + { poiRef :: !GYTxOutRef -- ^ Reference to the partial order. + , poiOwnerKey :: !GYPubKeyHash -- ^ Public key hash of the owner. + , poiOwnerAddr :: !GYAddress -- ^ Address of the owner. + , poiOfferedAsset :: !GYAssetClass -- ^ The asset being offered. + , poiOfferedOriginalAmount :: !Natural -- ^ The number of units originally offered. + , poiOfferedAmount :: !Natural -- ^ The number of units being offered. + , poiAskedAsset :: !GYAssetClass -- ^ The asset being asked for as payment. + , poiPrice :: !GYRational -- ^ The price for one unit of the offered asset. + , poiNFT :: !GYTokenName -- ^ Token name of the NFT identifying this partial order. + , poiStart :: !(Maybe GYTime) -- ^ The time when the order can earliest be filled (optional). + , poiEnd :: !(Maybe GYTime) -- ^ The time when the order can latest be filled (optional). + , poiPartialFills :: !Natural -- ^ The number of past partial fills. + , poiMakerLovelaceFlatFee :: !Natural -- ^ Flat fee (in lovelace) paid by the maker. + , poiTakerLovelaceFlatFee :: !Natural -- ^ Flat fee (in lovelace) paid by the taker. + , poiContainedFee :: !POIContainedFee -- ^ Fee contained in the order. + , poiContainedPayment :: !Natural -- ^ Payment (in asked asset) contained in the order. + , poiUTxOValue :: !GYValue -- ^ Total value in the UTxO. + , poiUTxOAddr :: !GYAddress -- ^ Address of the order UTxO. + , poiNFTCS :: !GYMintingPolicyId -- ^ Caching the CS to avoid recalculating for it. } deriving stock (Show, Eq, Generic) +poiContainedFeeToPlutus :: POIContainedFee -> PartialOrderContainedFee +poiContainedFeeToPlutus POIContainedFee {..} = + PartialOrderContainedFee + { pocfLovelaces = fromIntegral poifLovelaces + , pocfOfferedTokens = fromIntegral poifOfferedTokens + , pocfAskedTokens = fromIntegral poifAskedTokens + } + +poiContainedFeeFromPlutus :: PartialOrderContainedFee -> POIContainedFee +poiContainedFeeFromPlutus PartialOrderContainedFee {..} = + POIContainedFee + { poifLovelaces = fromIntegral pocfLovelaces + , poifOfferedTokens = fromIntegral pocfOfferedTokens + , poifAskedTokens = fromIntegral pocfAskedTokens + } + ------------------------------------------------------------------------------- -- Queries ------------------------------------------------------------------------------- @@ -148,7 +228,7 @@ data PartialOrderInfo = PartialOrderInfo -- | List and transform all the partial orders for the given function. partialOrders :: forall a m - . GYApiQueryMonad m + . GYApiQueryMonad m => (PartialOrderInfo -> Maybe a) -- ^ Filter + Transformer function. Nothing means ignore that partial order. -> m [a] @@ -156,7 +236,8 @@ partialOrders pOrderPredicate = do DEXInfo {dexPartialOrderValidator} <- ask addr <- scriptAddress dexPartialOrderValidator - foldM mkPOrderInfo [] =<< utxosAtAddressesWithDatums [addr] + let paymentCred = addressToPaymentCredential addr & fromJust + foldM mkPOrderInfo [] =<< utxosAtPaymentCredentialWithDatums paymentCred where mkPOrderInfo @@ -172,7 +253,10 @@ partialOrders pOrderPredicate = do runExceptT (makePartialOrderInfo utxoRef (utxoAddress, utxoValue, d)) - addPartialOrderInfo :: [a] -> PartialOrderInfo -> [a] + addPartialOrderInfo + :: [a] + -> PartialOrderInfo + -> [a] addPartialOrderInfo pois = maybe pois (:pois) . pOrderPredicate ------------------------------------------------------------------------------- @@ -180,144 +264,303 @@ partialOrders pOrderPredicate = do ------------------------------------------------------------------------------- -- | Completely fill a partially-fillable order. -completelyFillPartialOrder - :: (HasCallStack, GYApiMonad m) - => Either GYTxOutRef PartialOrderInfo - -- ^ The order reference. - -> m (GYTxSkeleton PlutusV2) +completelyFillPartialOrder :: + (HasCallStack, GYApiMonad m) => + -- | The order reference. + Either GYTxOutRef PartialOrderInfo -> + m (GYTxSkeleton PlutusV2) completelyFillPartialOrder poiSource = do - di@DEXInfo{dexPORefs} <- ask - - oi@PartialOrderInfo {..} <- case poiSource of - Left orderRef -> getPartialOrderInfo orderRef - Right poi -> return poi - - let refScript = maybe mempty mustHaveRefInput (porValidatorRef dexPORefs) - refMinting = maybe mempty mustHaveRefInput (porNftPolicyRef dexPORefs) - - cs <- validFillRangeConstraints poiStart poiEnd - return $ mconcat - [ mustHaveInput (partialOrderInfoToIn oi CompleteFill di) - , mustHaveOutput (partialOrderInfoToPayment oi $ expectedValueOut oi poiOfferedAmount) - , mustMint (mintingScript di) nothingRedeemer poiNFT (-1) - , cs - , refScript - , refMinting - , mustHaveRefInput (porRefNftRef dexPORefs) - ] + di@DEXInfo{dexPORefs} <- ask + + oi@PartialOrderInfo {..} <- case poiSource of + Left orderRef -> getPartialOrderInfo orderRef + Right poi -> return poi + + (cfgRef, poci) <- fetchPartialOrderConfig (porRefAddr dexPORefs) (porRefNft dexPORefs) + + let containedFee = poiGetContainedFeeValue oi + fee = containedFee <> valueFromLovelace (fromIntegral poiTakerLovelaceFlatFee) + feeOutput + | fee == mempty = mempty + | otherwise = mustHaveOutput $ mkGYTxOut + (pociFeeAddr poci) + fee + (datumFromPlutusData $ + PartialOrderFeeOutput + { pofdMentionedFees = PlutusTx.singleton (txOutRefToPlutus poiRef) (valueToPlutus containedFee) + , pofdReservedValue = mempty + , pofdSpentUTxORef = Nothing + } + ) + expectedValueOut = expectedPaymentWithDeposit oi True + cs <- validFillRangeConstraints poiStart poiEnd + + return $ + mustHaveInput (partialOrderInfoToIn oi CompleteFill di) + <> mustHaveOutput (partialOrderInfoToPayment oi expectedValueOut) + <> mustMint (mintingScript di) nothingRedeemer poiNFT (-1) + <> feeOutput + <> cs + <> mustHaveRefInput cfgRef -- | Partially fill a partially-fillable order. -partiallyFillPartialOrder +partiallyFillPartialOrder :: + (HasCallStack, GYApiMonad m) => + -- | The order reference. + Either GYTxOutRef PartialOrderInfo -> + -- | The amount of offered tokens to buy. + Natural -> + m (GYTxSkeleton PlutusV2) +partiallyFillPartialOrder poiSource amt = do + di@DEXInfo{dexPORefs} <- ask + + oi@PartialOrderInfo {..} <- case poiSource of + Left orderRef -> getPartialOrderInfo orderRef + Right poi -> return poi + + when (amt == 0) . throwAppError $ PodNonPositiveAmount $ toInteger amt + when (amt >= poiOfferedAmount) . throwAppError $ PodRequestedAmountGreaterOrEqualToOfferedAmount amt poiOfferedAmount + + (cfgRef, _pocd) <- fetchPartialOrderConfig (porRefAddr dexPORefs) (porRefNft dexPORefs) + + let price' = partialOrderPrice oi amt + od = partialOrderInfoToPartialOrderDatum oi + { poiOfferedAmount = poiOfferedAmount - amt + , poiPartialFills = poiPartialFills + 1 + , poiContainedFee = poiContainedFee <> mempty { poifLovelaces = fromIntegral poiTakerLovelaceFlatFee } + , poiContainedPayment = poiContainedPayment + fromIntegral (valueAssetClass price' poiAskedAsset) + } + + expectedValueOut = poiUTxOValue <> price' <> valueFromLovelace (fromIntegral poiTakerLovelaceFlatFee) `valueMinus` valueSingleton poiOfferedAsset (toInteger amt) + o = mkGYTxOut poiUTxOAddr expectedValueOut (datumFromPlutusData od) + + cs <- validFillRangeConstraints poiStart poiEnd + return $ + mustHaveInput (partialOrderInfoToIn oi (PartialFill $ toInteger amt) di) + <> mustHaveOutput o + <> cs + <> mustHaveRefInput cfgRef + +{- | Fills multiple orders. If the provided amount of offered tokens to buy in an order is equal to the offered amount, then we completely fill the order. Otherwise, it gets partially filled. +-} +fillMultiplePartialOrders :: (HasCallStack, GYApiMonad m) - => Either GYTxOutRef PartialOrderInfo - -- ^ The order reference. - -> Natural - -- ^ The amount of offered tokens to buy. + => [(Either GYTxOutRef PartialOrderInfo, Natural)] -> m (GYTxSkeleton PlutusV2) -partiallyFillPartialOrder poiSource amt = do - di@DEXInfo{dexPartialOrderValidator, dexPORefs} <- ask - - oi@PartialOrderInfo {..} <- case poiSource of - Left orderRef -> getPartialOrderInfo orderRef - Right poi -> return poi - - outAddr <- scriptAddress dexPartialOrderValidator - - when (amt == 0) . throwAppError - $ PodNonPositiveAmount $ toInteger amt - when (amt >= poiOfferedAmount) . throwAppError - $ PodRequestedAmountGreaterOrEqualToOfferedAmount amt poiOfferedAmount - - let od = partialOrderInfoToPartialOrderDatum oi - { poiOfferedAmount = poiOfferedAmount - amt - , poiPartialFills = poiPartialFills + 1 - } - o = mkGYTxOut outAddr (expectedValueOut oi amt) (datumFromPlutusData od) - refScript = maybe mempty mustHaveRefInput (porValidatorRef dexPORefs) - - cs <- validFillRangeConstraints poiStart poiEnd - return $ mconcat - [ mustHaveInput (partialOrderInfoToIn oi (PartialFill $ toInteger amt) di) - , mustHaveOutput o - , cs - , refScript - , mustHaveRefInput (porRefNftRef dexPORefs) - ] +fillMultiplePartialOrders eOrders = do + di <- ask + + -- This machinery is needed to accomodate the fact that MatchExecutionInfos may not have the PartialOrderInfo. In that case we must query it from the ref. + let separateOrders :: ([(GYTxOutRef, Natural)], [(PartialOrderInfo, Natural)]) + -> (Either GYTxOutRef PartialOrderInfo, Natural) + -> ([(GYTxOutRef, Natural)], [(PartialOrderInfo, Natural)]) + separateOrders (!refOrders, !poiOrders) (Left ref, n) = ((ref, n) : refOrders, poiOrders) + separateOrders (!refOrders, !poiOrders) (Right poi, n) = (refOrders, (poi, n) : poiOrders) + + (!ordersWithRefAndAmount, !ordersWithPoiAndAmount) = foldl' separateOrders ([],[]) eOrders + ordersWithRefAndAmount' = Map.fromList ordersWithRefAndAmount + queriedOrders <- getPartialOrdersInfos $ Map.keys ordersWithRefAndAmount' + -- Even though we use `dropMissing`, `getPartialOrdersInfos` verify that all entries are present. + let otherOrdersWithPoiAndAmount = Map.elems $ Map.merge Map.dropMissing Map.dropMissing (Map.zipWithMatched (\_ poi amt -> (poi, amt))) queriedOrders ordersWithRefAndAmount' + orders = otherOrdersWithPoiAndAmount ++ ordersWithPoiAndAmount + por = dexPORefs di + + (cfgRef, poci) <- fetchPartialOrderConfig (porRefAddr por) (porRefNft por) + + let buildWithFeeOutput = do + let (!feeOutputMap, !totalContainedFee, !maxTakerFee) = + foldl' + (\(!mapAcc, !feeAcc, !prevMaxTakerFee) (PartialOrderInfo {..}, amtToFill) -> + let curMaxTakerFee = max prevMaxTakerFee poiTakerLovelaceFlatFee in + if amtToFill == poiOfferedAmount then + let orderContainedFee = poiContainedFeeToValue poiContainedFee poiOfferedAsset poiAskedAsset + in (PlutusTx.unionWith (<>) mapAcc (PlutusTx.singleton (txOutRefToPlutus poiRef) (valueToPlutus orderContainedFee)), feeAcc <> orderContainedFee, curMaxTakerFee) + else (mapAcc, feeAcc, curMaxTakerFee) + ) + (PlutusTx.empty, mempty, 0) + orders + fee = totalContainedFee <> valueFromLovelace (fromIntegral maxTakerFee) + feeOutput + | fee == mempty = mempty + | otherwise = + mustHaveOutput $ mkGYTxOut (pociFeeAddr poci) fee $ datumFromPlutusData $ PartialOrderFeeOutput feeOutputMap mempty Nothing + foldlM + (\(!prevSkel) (poi@PartialOrderInfo {..}, amt) -> do + commonCheck amt poiOfferedAmount + cs <- validFillRangeConstraints poiStart poiEnd + let skel = + if amt == poiOfferedAmount then + + let expectedValueOut = expectedPaymentWithDeposit poi True + + in + mustHaveInput (partialOrderInfoToIn poi CompleteFill di) + <> mustHaveOutput (partialOrderInfoToPayment poi expectedValueOut) + <> mustMint (mintingScript di) nothingRedeemer poiNFT (-1) + <> cs + + else + + let price' = partialOrderPrice poi amt + od = partialOrderInfoToPartialOrderDatum poi + { poiOfferedAmount = poiOfferedAmount - amt + , poiPartialFills = poiPartialFills + 1 + , poiContainedPayment = poiContainedPayment + fromIntegral (valueAssetClass price' poiAskedAsset) + } + + expectedValueOut = poiUTxOValue <> price' `valueMinus` valueSingleton poiOfferedAsset (toInteger amt) + o = mkGYTxOut poiUTxOAddr expectedValueOut (datumFromPlutusData od) + + in + mustHaveInput (partialOrderInfoToIn poi (PartialFill $ toInteger amt) di) + <> mustHaveOutput o + <> cs + + pure $! prevSkel <> skel + ) + (mustHaveRefInput cfgRef <> feeOutput) + orders + + + let buildWithoutFeeOutput = do + let maxTakerFee = foldl' (\prevMaxTakerFee (PartialOrderInfo {..}, _) -> max prevMaxTakerFee poiTakerLovelaceFlatFee) 0 orders + foldlM + (\(!prevSkel) (idx, (poi@PartialOrderInfo {..}, amt)) -> do + commonCheck amt poiOfferedAmount + let price' = partialOrderPrice poi amt + tf = if idx == 1 then mempty { poifLovelaces = fromIntegral maxTakerFee } else mempty + od = partialOrderInfoToPartialOrderDatum poi + { poiOfferedAmount = poiOfferedAmount - amt + , poiPartialFills = poiPartialFills + 1 + , poiContainedFee = poiContainedFee <> tf + , poiContainedPayment = poiContainedPayment + fromIntegral (valueAssetClass price' poiAskedAsset) + } + + expectedValueOut = poiUTxOValue <> price' <> poiContainedFeeToValue tf poiOfferedAsset poiAskedAsset `valueMinus` valueSingleton poiOfferedAsset (toInteger amt) + o = mkGYTxOut poiUTxOAddr expectedValueOut (datumFromPlutusData od) + + cs <- validFillRangeConstraints poiStart poiEnd + + pure $! + prevSkel + <> mustHaveInput (partialOrderInfoToIn poi (PartialFill $ toInteger amt) di) + <> mustHaveOutput o + <> cs + ) + (mustHaveRefInput cfgRef) + (zip [(1 :: Natural).. ] orders) + + if isJust $ find (\(PartialOrderInfo {..}, amt) -> amt == poiOfferedAmount) orders then buildWithFeeOutput + else buildWithoutFeeOutput + where + commonCheck amt poiOfferedAmount = do + when (amt == 0) . throwAppError $ PodNonPositiveAmount $ toInteger amt + when (amt > poiOfferedAmount) . throwAppError $ PodRequestedAmountGreaterThanOfferedAmount amt poiOfferedAmount ------------------------------------------------------------------------------- -- Utilities ------------------------------------------------------------------------------- +partialOrderInfoToPartialOrderDatum :: PartialOrderInfo -> PartialOrderDatum +partialOrderInfoToPartialOrderDatum PartialOrderInfo {..} = PartialOrderDatum + { podOwnerKey = pubKeyHashToPlutus poiOwnerKey + , podOwnerAddr = addressToPlutus poiOwnerAddr + , podOfferedAsset = assetClassToPlutus poiOfferedAsset + , podOfferedOriginalAmount = fromIntegral poiOfferedOriginalAmount + , podOfferedAmount = fromIntegral poiOfferedAmount + , podAskedAsset = assetClassToPlutus poiAskedAsset + , podPrice = PlutusTx.fromGHC $ toRational poiPrice + , podNFT = tokenNameToPlutus poiNFT + , podStart = timeToPlutus <$> poiStart + , podEnd = timeToPlutus <$> poiEnd + , podPartialFills = fromIntegral poiPartialFills + , podMakerLovelaceFlatFee = fromIntegral poiMakerLovelaceFlatFee + , podTakerLovelaceFlatFee = toInteger poiTakerLovelaceFlatFee + , podContainedFee = poiContainedFeeToPlutus poiContainedFee + , podContainedPayment = toInteger poiContainedPayment + } + +poiGetContainedFeeValue :: PartialOrderInfo -> GYValue +poiGetContainedFeeValue PartialOrderInfo {..} = poiContainedFeeToValue poiContainedFee poiOfferedAsset poiAskedAsset + +poiContainedFeeToValue :: POIContainedFee -> GYAssetClass -> GYAssetClass -> GYValue +poiContainedFeeToValue POIContainedFee {..} offAC askAC = + valueSingleton GYLovelace (fromIntegral poifLovelaces) + <> valueSingleton offAC (fromIntegral poifOfferedTokens) + <> valueSingleton askAC (fromIntegral poifAskedTokens) + -- | Builds an input consuming the given order for a particular action. -partialOrderInfoToIn - :: PartialOrderInfo - -> PartialOrderAction - -> DEXInfo - -> GYTxIn PlutusV2 -partialOrderInfoToIn oi@PartialOrderInfo {..} oa DEXInfo {..} = - GYTxIn +partialOrderInfoToIn :: PartialOrderInfo + -> PartialOrderAction + -> DEXInfo + -> GYTxIn PlutusV2 +partialOrderInfoToIn oi@PartialOrderInfo {..} oa DEXInfo {..} = GYTxIn { gyTxInTxOutRef = poiRef - , gyTxInWitness = GYTxInWitnessScript - script - (datumFromPlutusData $ partialOrderInfoToPartialOrderDatum oi) - $ redeemerFromPlutusData oa + , gyTxInWitness = GYTxInWitnessScript + script + (datumFromPlutusData $ partialOrderInfoToPartialOrderDatum oi) + $ redeemerFromPlutusData oa } where script = case porValidatorRef dexPORefs of Nothing -> GYInScript dexPartialOrderValidator Just ref -> GYInReference ref (validatorToScript dexPartialOrderValidator) + +mintingScript :: DEXInfo -> GYMintScript PlutusV2 +mintingScript DEXInfo{dexNftPolicy, dexPORefs} = case porNftPolicyRef dexPORefs of + Nothing -> GYMintScript dexNftPolicy + Just ref -> GYMintReference ref (mintingPolicyToScript dexNftPolicy) + -- | Builds an output paying some value to the order owner, also adds the UTxO -- reference of the order to the datum. -partialOrderInfoToPayment :: PartialOrderInfo -> GYValue -> GYTxOut PlutusV2 -partialOrderInfoToPayment oi v = - mkGYTxOut (poiOwnerAddr oi) v - (datumFromPlutusData $ txOutRefToPlutus $ poiRef oi) - --- | Given a UTxO reference of an order, returns the complete information. -getPartialOrderInfo :: GYApiQueryMonad m => GYTxOutRef -> m PartialOrderInfo -getPartialOrderInfo oref = do - utxo <- utxoAtTxOutRef' oref - vod <- utxoDatum' utxo - runExceptT (makePartialOrderInfo oref vod) >>= liftEither +partialOrderInfoToPayment :: PartialOrderInfo -> GYValue -> GYTxOut 'PlutusV2 +partialOrderInfoToPayment oi v = mkGYTxOut (poiOwnerAddr oi) v (datumFromPlutusData $ txOutRefToPlutus $ poiRef oi) -- | Given an order and the bought amount from that order, returns the total -- price. partialOrderPrice :: PartialOrderInfo -> Natural -> GYValue -partialOrderPrice PartialOrderInfo {..} amt = - valueSingleton poiAskedAsset $ - ceiling $ rationalToGHC poiPrice * toRational amt - -mintingScript :: DEXInfo -> GYMintScript PlutusV2 -mintingScript DEXInfo{dexNftPolicy, dexPORefs} = - case porNftPolicyRef dexPORefs of - Nothing -> GYMintScript dexNftPolicy - Just ref -> GYMintReference ref (mintingPolicyToScript dexNftPolicy) +partialOrderPrice PartialOrderInfo {..} amt = valueSingleton poiAskedAsset $ ceiling $ rationalToGHC poiPrice * toRational amt + +{- | Note that at any moment, an order UTxO contains:- + * An NFT. + * Remaining offered tokens. + * Payment for tokens consumed. + * Initial deposit. + * Collected fees. +-} +expectedPaymentWithDeposit :: PartialOrderInfo -> Bool -> GYValue +expectedPaymentWithDeposit poi@PartialOrderInfo {..} isCompleteFill = + let toSubtract = valueSingleton (GYToken poiNFTCS poiNFT) 1 <> valueSingleton poiOfferedAsset (toInteger poiOfferedAmount) <> poiGetContainedFeeValue poi + toAdd = if isCompleteFill then partialOrderPrice poi poiOfferedAmount else mempty + in poiUTxOValue <> toAdd `valueMinus` toSubtract -partialOrderInfoToPartialOrderDatum :: PartialOrderInfo -> PartialOrderDatum -partialOrderInfoToPartialOrderDatum PartialOrderInfo {..} = - PartialOrderDatum - { podOwnerKey = pubKeyHashToPlutus poiOwnerKey - , podOwnerAddr = addressToPlutus poiOwnerAddr - , podOfferedAsset = assetClassToPlutus poiOfferedAsset - , podOfferedOriginalAmount = fromIntegral poiOfferedOriginalAmount - , podOfferedAmount = fromIntegral poiOfferedAmount - , podAskedAsset = assetClassToPlutus poiAskedAsset - , podPrice = PlutusTx.fromGHC $ toRational poiPrice - , podNFT = tokenNameToPlutus poiNFT - , podStart = timeToPlutus <$> poiStart - , podEnd = timeToPlutus <$> poiEnd - , podPartialFills = fromIntegral poiPartialFills - } +-- | Given a UTxO reference of an order, returns the complete information. +getPartialOrderInfo :: GYApiQueryMonad m + => GYTxOutRef + -> m PartialOrderInfo +getPartialOrderInfo orderRef = do + utxoWithDatum <- utxoAtTxOutRefWithDatum' orderRef + vod <- utxoDatumPure' utxoWithDatum + + runExceptT (makePartialOrderInfo orderRef vod) >>= liftEither + +getPartialOrdersInfos :: GYApiQueryMonad m + => [GYTxOutRef] + -> m (Map.Map GYTxOutRef PartialOrderInfo) +getPartialOrdersInfos orderRefs = do + utxosWithDatums <- utxosAtTxOutRefsWithDatums orderRefs + let vod = utxosDatumsPure utxosWithDatums + when (Map.size vod /= length orderRefs) $ throwAppError $ PodNotAllOrderRefsPresent $ Set.fromList orderRefs `Set.difference` Map.keysSet vod + runExceptT (Map.traverseWithKey makePartialOrderInfo vod) >>= liftEither -- | Given the UTxO reference of an order, returns the complete information. -- Checking the validity of the order. -makePartialOrderInfo - :: GYApiQueryMonad m - => GYTxOutRef - -> (GYAddress, GYValue, PartialOrderDatum) - -> ExceptT GYTxMonadException m PartialOrderInfo -makePartialOrderInfo orderRef (_, v, PartialOrderDatum {..}) = do +makePartialOrderInfo :: GYApiQueryMonad m + => GYTxOutRef + -> (GYAddress, GYValue, PartialOrderDatum) + -> ExceptT GYTxMonadException m PartialOrderInfo +makePartialOrderInfo orderRef (utxoAddr, v, PartialOrderDatum {..}) = do DEXInfo{dexNftPolicy} <- ask addr <- addressFromPlutus' podOwnerAddr @@ -327,29 +570,29 @@ makePartialOrderInfo orderRef (_, v, PartialOrderDatum {..}) = do nft <- tokenNameFromPlutus' podNFT askedAsset <- assetClassFromPlutus' podAskedAsset - let price = rationalFromPlutus podPrice - - when (price <= 0) $ - throwAppError (PodNonPositivePrice price) - when (valueAssetClass v (GYToken (mintingPolicyId dexNftPolicy) nft) /= 1) $ throwAppError PodNftNotAvailable return PartialOrderInfo - { poiRef = orderRef - , poiOwnerKey = key - , poiOwnerAddr = addr - , poiOfferedAsset = offeredAsset - , poiOfferedOriginalAmount = fromInteger podOfferedOriginalAmount - , poiOfferedAmount = fromInteger podOfferedAmount - , poiAskedAsset = askedAsset - , poiPrice = price - , poiNFT = nft - , poiStart = timeFromPlutus <$> podStart - , poiEnd = timeFromPlutus <$> podEnd - , poiPartialFills = fromInteger podPartialFills - , poiUTxOValue = v - , poiNFTCS = mintingPolicyId dexNftPolicy + { poiRef = orderRef + , poiOwnerKey = key + , poiOwnerAddr = addr + , poiOfferedAsset = offeredAsset + , poiOfferedOriginalAmount = fromInteger podOfferedOriginalAmount + , poiOfferedAmount = fromInteger podOfferedAmount + , poiAskedAsset = askedAsset + , poiPrice = rationalFromPlutus podPrice + , poiNFT = nft + , poiStart = timeFromPlutus <$> podStart + , poiEnd = timeFromPlutus <$> podEnd + , poiPartialFills = fromInteger podPartialFills + , poiMakerLovelaceFlatFee = fromIntegral podMakerLovelaceFlatFee + , poiTakerLovelaceFlatFee = fromInteger podTakerLovelaceFlatFee + , poiContainedFee = poiContainedFeeFromPlutus podContainedFee + , poiContainedPayment = fromInteger podContainedPayment + , poiUTxOValue = v + , poiUTxOAddr = utxoAddr + , poiNFTCS = mintingPolicyId dexNftPolicy } validFillRangeConstraints @@ -378,12 +621,3 @@ validFillRangeConstraints mstart mend = do if now <= endSlot then return $ isInvalidAfter $ min endSlot $ unsafeAdvanceSlot now 120 else throwAppError $ TooLateFill {foeEnd = endSlot, foeNow = now} - -expectedValueOut :: PartialOrderInfo -> Natural -> GYValue -expectedValueOut poi@PartialOrderInfo {..} amnt = - poiUTxOValue - <> partialOrderPrice poi amnt `valueMinus` ( valueSingleton poiOfferedAsset (toInteger amnt) - <> if poiOfferedAmount == amnt - then valueSingleton (GYToken poiNFTCS poiNFT) 1 - else mempty - ) diff --git a/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrderConfig.hs b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrderConfig.hs new file mode 100644 index 0000000..9be50f4 --- /dev/null +++ b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrderConfig.hs @@ -0,0 +1,126 @@ +{-# LANGUAGE TemplateHaskell #-} +{-| +Module : GeniusYield.DEX.Api.PartialOrderConfig +Copyright : (c) 2023 GYELD GMBH +License : Apache 2.0 +Maintainer : support@geniusyield.co +Stability : develop + +-} + +module GeniusYield.DEX.Api.PartialOrderConfig + ( PocdException (..) + , PartialOrderConfigInfoF (..) + , PartialOrderConfigInfo + , fetchPartialOrderConfig + ) where + +import qualified Cardano.Api as Api +import Data.Text (pack) +import Network.HTTP.Types (status400) + +import GeniusYield.HTTP.Errors (GYApiError (..), IsGYApiError (..)) +import GeniusYield.Imports +import GeniusYield.TxBuilder (GYTxQueryMonad (utxosAtAddressWithDatums), + addressFromPlutus', throwAppError, + utxoDatumPure') +import GeniusYield.Types +import qualified PlutusLedgerApi.V1 as Plutus +import PlutusTx (BuiltinData, + FromData (fromBuiltinData)) +import qualified PlutusTx +import PlutusTx.Builtins.Internal (BuiltinByteString (..)) +import PlutusTx.Ratio as PlutusTx (Rational) + +data PartialOrderConfigDatum = PartialOrderConfigDatum + { pocdSignatories :: [Plutus.PubKeyHash] + -- ^ Public key hashes of the potential signatories. + , pocdReqSignatories :: Integer + -- ^ Number of required signatures. + , pocdNftSymbol :: Plutus.CurrencySymbol + -- ^ Currency symbol of the partial order Nft. + , pocdFeeAddr :: Plutus.Address + -- ^ Address to which fees are paid. + , pocdMakerFeeFlat :: Integer + -- ^ Flat fee (in lovelace) paid by the maker. + , pocdMakerFeeRatio :: PlutusTx.Rational + -- ^ Proportional fee (in the offered token) paid by the maker. + , pocdTakerFee :: Integer + -- ^ Flat fee (in lovelace) paid by the taker. + , pocdMinDeposit :: Integer + -- ^ Minimum required deposit (in lovelace). + } deriving stock (Generic, Show) + +PlutusTx.unstableMakeIsData ''PartialOrderConfigDatum + +data PartialOrderConfigInfoF addr = PartialOrderConfigInfo + { pociSignatories :: ![GYPubKeyHash] + -- ^ Public key hashes of the potential signatories. + , pociReqSignatories :: !Integer + -- ^ Number of required signatures. + , pociNftSymbol :: !GYMintingPolicyId + -- ^ Minting Policy Id of the partial order Nft. + , pociFeeAddr :: !addr + -- ^ Address to which fees are paid. + , pociMakerFeeFlat :: !Integer + -- ^ Flat fee (in lovelace) paid by the maker. + , pociMakerFeeRatio :: !GYRational + -- ^ Proportional fee (in the offered token) paid by the maker. + , pociTakerFee :: !Integer + -- ^ Flat fee (in lovelace) paid by the taker. + , pociMinDeposit :: !Integer + -- ^ Minimum required deposit (in lovelace). + } deriving stock (Show, Generic, Functor) + +type PartialOrderConfigInfo = PartialOrderConfigInfoF GYAddress + +instance FromData (PartialOrderConfigInfoF Plutus.Address) where + fromBuiltinData :: BuiltinData -> Maybe (PartialOrderConfigInfoF Plutus.Address) + fromBuiltinData d = do + PartialOrderConfigDatum{..} <- fromBuiltinData d + signatories <- fromEither $ mapM pubKeyHashFromPlutus pocdSignatories + nftSymbol <- fromEither $ mintingPolicyIdFromCurrencySymbol pocdNftSymbol + pure PartialOrderConfigInfo + { pociSignatories = signatories + , pociReqSignatories = pocdReqSignatories + , pociNftSymbol = nftSymbol + , pociFeeAddr = pocdFeeAddr + , pociMakerFeeFlat = pocdMakerFeeFlat + , pociMakerFeeRatio = rationalFromPlutus pocdMakerFeeRatio + , pociTakerFee = pocdTakerFee + , pociMinDeposit = pocdMinDeposit + } + where + fromEither :: Either e a -> Maybe a + fromEither = either (const Nothing) Just + +newtype PocdException = PocdException GYAssetClass + deriving stock Show + deriving anyclass Exception + +instance IsGYApiError PocdException where + toApiError (PocdException nftToken) = GYApiError + { gaeErrorCode = "PARTIAL_ORDER_CONFIG_NOT_FOUND" + , gaeHttpStatus = status400 + , gaeMsg = pack $ printf "Partial order config not found for NFT: %s" nftToken + } + +fetchPartialOrderConfig :: GYTxQueryMonad m => GYAddress -> GYAssetClass -> m (GYTxOutRef, PartialOrderConfigInfo) +fetchPartialOrderConfig addr nftToken = do + utxos <- utxosAtAddressWithDatums addr $ Just nftToken + case utxos of + [p@(utxo, Just _)] -> do + (_, _, d') <- utxoDatumPure' p + feeAddr <- addressFromPlutus' $ pociFeeAddr d' + pure (utxoRef utxo, feeAddr <$ d') + _ -> throwAppError $ PocdException nftToken + +mintingPolicyIdFromCurrencySymbol :: Plutus.CurrencySymbol -> Either PlutusToCardanoError GYMintingPolicyId +mintingPolicyIdFromCurrencySymbol cs = + let + BuiltinByteString bs = Plutus.unCurrencySymbol cs + in + case Api.deserialiseFromRawBytes Api.AsPolicyId bs of + Left e -> Left $ DeserialiseRawBytesError $ pack $ + "mintingPolicyIdFromCurrencySymbol: " <> show cs <> ", error: " <> show e + Right pid -> Right $ mintingPolicyIdFromApi pid diff --git a/geniusyield-dex-api/src/GeniusYield/DEX/Api/Types.hs b/geniusyield-dex-api/src/GeniusYield/DEX/Api/Types.hs index ba63a6e..904d6b3 100644 --- a/geniusyield-dex-api/src/GeniusYield/DEX/Api/Types.hs +++ b/geniusyield-dex-api/src/GeniusYield/DEX/Api/Types.hs @@ -16,23 +16,24 @@ module GeniusYield.DEX.Api.Types , mkPORefs ) where -import Control.Monad.Reader ( MonadReader ) +import Control.Monad.Reader (MonadReader) -import Ply ( TypedScript, ScriptRole (..) ) -import Ply.Core.Apply ( (#) ) -import PlutusLedgerApi.V1 ( Address ) -import PlutusLedgerApi.V1.Scripts ( ScriptHash ) -import PlutusLedgerApi.V1.Value ( AssetClass ) +import PlutusLedgerApi.V1 (Address) +import PlutusLedgerApi.V1.Scripts (ScriptHash) +import PlutusLedgerApi.V1.Value (AssetClass) +import Ply (ScriptRole (..), TypedScript) +import Ply.Core.Apply ((#)) -import GeniusYield.DEX.Api.Constants ( minDeposit ) -import GeniusYield.DEX.Api.Utils ( validatorFromPly, mintingPolicyFromPly ) -import GeniusYield.Types ( GYValidator, GYMintingPolicy - , GYAddress, GYAssetClass - , PlutusVersion(PlutusV2) - , GYTxOutRef, scriptPlutusHash - , validatorToScript, assetClassToPlutus - ) -import GeniusYield.TxBuilder.Class ( GYTxMonad, GYTxQueryMonad ) +import GeniusYield.DEX.Api.Utils (mintingPolicyFromPly, + validatorFromPly) +import GeniusYield.TxBuilder.Class (GYTxMonad, GYTxQueryMonad) +import GeniusYield.Types (GYAddress, GYAssetClass, + GYMintingPolicy, GYTxOutRef, + GYValidator, + PlutusVersion (PlutusV2), + assetClassToPlutus, + scriptPlutusHash, + validatorToScript) type GYApiQueryMonad m = (MonadReader DEXInfo m, GYTxQueryMonad m) @@ -51,8 +52,6 @@ data PORefs = PORefs -- ^ The address where the reference NFT will be placed. , porRefNft :: !GYAssetClass -- ^ The reference NFT. - , porRefNftRef :: !GYTxOutRef - -- ^ The location of the reference NFT. , porValidatorRef :: !(Maybe GYTxOutRef) -- ^ The reference for the partial order validator. , porNftPolicyRef :: !(Maybe GYTxOutRef) @@ -62,12 +61,16 @@ data PORefs = PORefs -- Smart Constructors mkDEXMintingPolicy - :: TypedScript 'MintingPolicyRole '[ScriptHash, Integer] + :: TypedScript 'MintingPolicyRole '[ScriptHash, Address, AssetClass] -> GYValidator PlutusV2 + -> Address + -> GYAssetClass -> GYMintingPolicy PlutusV2 -mkDEXMintingPolicy mintingPolicyRaw v = mintingPolicyFromPly $ mintingPolicyRaw - # scriptPlutusHash (validatorToScript v) - # toInteger minDeposit +mkDEXMintingPolicy mintingPolicyRaw v addr ac = + mintingPolicyFromPly $ mintingPolicyRaw + # scriptPlutusHash (validatorToScript v) + # addr + # assetClassToPlutus ac mkDEXValidator :: TypedScript 'ValidatorRole '[Address, AssetClass] @@ -81,15 +84,13 @@ mkDEXValidator validatorRaw addr ac = validatorFromPly $ validatorRaw mkPORefs :: GYAddress -> GYAssetClass - -> GYTxOutRef -> Maybe GYTxOutRef -> Maybe GYTxOutRef -> PORefs -mkPORefs porAddr porAC porRef mVRef mNPRef = +mkPORefs porAddr porAC mVRef mNPRef = PORefs { porRefAddr = porAddr , porRefNft = porAC - , porRefNftRef = porRef , porValidatorRef = mVRef , porNftPolicyRef = mNPRef } From ad98a45b5bfb9769b42e53fc386e40b37160c560 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Sun, 10 Dec 2023 17:17:56 +0530 Subject: [PATCH 3/7] Feat #53: Update to bot config file --- config-files/bot-config.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/config-files/bot-config.json b/config-files/bot-config.json index f06c8aa..32ea631 100644 --- a/config-files/bot-config.json +++ b/config-files/bot-config.json @@ -3,16 +3,15 @@ "nftMintingPolicyFP": "compiled-scripts/minting-policy", "orderValidatorFP": "compiled-scripts/partial-order", "validatorRefs": { - "refAddr": "addr_test1wpgexmeunzsykesf42d4eqet5yvzeap6trjnflxqtkcf66g0kpnxt", - "refNftAC": "fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.6af3807634905a04be64a8dbe0ddb9da6ce52eed23cb428c7be5d6114eacc189", - "refNftUtxoRef": "aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#0", - "scriptRef": "aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#1", - "nftPolicyRef": "aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#0" + "refAddr": "addr_test1wrgvy8fermjrruaf7fnndtmpuw4xx4cnvfqjp5zqu8kscfcvh32qk", + "refNftAC": "fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.8309f9861928a55d37e84f6594b878941edce5e351f7904c2c63b559bde45c5c", + "scriptRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#2", + "nftPolicyRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#1" }, "strategy": "OneSellToManyBuy", "scanDelay": 40000000, "maxOrderMatches": 5, - "maxTxsPerIteration": 5, + "maxTxsPerIteration": 4, "randomizeMatchesFound": true, "scanTokens": [ { From 1525fe305d39ef69aebb171d74401889547456a4 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Sun, 10 Dec 2023 20:32:08 +0530 Subject: [PATCH 4/7] Feat #53: Updated SOR framework to work with new contracts --- .../lib-common/GeniusYield/OrderBot/Types.hs | 34 ++--- .../GeniusYield/OrderBot/DataSource.hsig | 5 +- .../src/GeniusYield/OrderBot.hs | 142 +++++++++--------- .../GeniusYield/OrderBot/MatchingStrategy.hs | 58 +++---- geniusyield-orderbot/src/OrderBotConfig.hs | 10 +- .../OrderBot/DataSource/Providers.hs | 30 ++-- 6 files changed, 137 insertions(+), 142 deletions(-) diff --git a/geniusyield-orderbot-framework/lib-common/GeniusYield/OrderBot/Types.hs b/geniusyield-orderbot-framework/lib-common/GeniusYield/OrderBot/Types.hs index 9fb2759..0deb22f 100644 --- a/geniusyield-orderbot-framework/lib-common/GeniusYield/OrderBot/Types.hs +++ b/geniusyield-orderbot-framework/lib-common/GeniusYield/OrderBot/Types.hs @@ -22,17 +22,17 @@ module GeniusYield.OrderBot.Types , mkEquivalentAssetPair ) where -import Data.Aeson (ToJSON, (.=)) -import qualified Data.Aeson as Aeson -import Data.Kind (Type) -import Data.Ratio (denominator, numerator, (%)) -import Numeric.Natural (Natural) +import Data.Aeson (ToJSON, (.=)) +import qualified Data.Aeson as Aeson +import Data.Kind (Type) +import Data.Ratio (denominator, numerator, (%)) +import Numeric.Natural (Natural) -import GeniusYield.Types.TxOutRef (GYTxOutRef) -import GeniusYield.Types.Value (GYAssetClass (..)) +import GeniusYield.Types.TxOutRef (GYTxOutRef) +import GeniusYield.Types.Value (GYAssetClass (..)) import GeniusYield.DEX.Api.PartialOrder (PartialOrderInfo (..)) -import GeniusYield.Types (rationalToGHC) +import GeniusYield.Types (rationalToGHC) ------------------------------------------------------------------------------- -- Information on DEX orders relevant to a matching strategy @@ -53,14 +53,14 @@ See: 'mkOrderInfo'. -} type OrderInfo :: OrderType -> Type data OrderInfo t = OrderInfo - { orderRef :: !GYTxOutRef + { orderRef :: !GYTxOutRef , orderType :: !(SOrderType t) , assetInfo :: !OrderAssetPair - , volume :: !Volume + , volume :: !Volume -- ^ Volume of the 'commodityAsset', either being bought or sold. - , price :: !Price + , price :: !Price -- ^ Price of each 'commodityAsset', in 'currencyAsset'. - , mPoi :: !(Maybe PartialOrderInfo) + , mPoi :: !(Maybe PartialOrderInfo) -- ^ The complete PartialOrderInfo. To avoid quering it again when filling the order } deriving stock (Eq, Show) @@ -123,11 +123,11 @@ mkOrderInfo oap poi@PartialOrderInfo{..} = case orderType of isSellOrder :: OrderInfo t -> Bool isSellOrder OrderInfo { orderType = SSellOrder} = True -isSellOrder _ = False +isSellOrder _ = False isBuyOrder :: OrderInfo t -> Bool isBuyOrder OrderInfo { orderType = SBuyOrder} = True -isBuyOrder _ = False +isBuyOrder _ = False ------------------------------------------------------------------------------- -- Order classification components. @@ -149,11 +149,11 @@ deriving stock instance Show (SOrderType t) {- | The amount of the commodity asset (being brought or sold), represented as a closed interval. -Although the contract now permits fills as low a 1 indivisible token, -the volumeMin field is still needed, because Buy orders are normalized and you +Although the contract permits fills as low a 1 indivisible token, +the @volumeMin@ field is still needed, because Buy orders are normalized and you can't always fill it for 1. The amount depends on the price of the order. -volumeMin should always be <= volumeMax. Users are responsible for maintaining +@volumeMin@ should always be @<= volumeMax@. Users are responsible for maintaining this invariant. -} data Volume = Volume diff --git a/geniusyield-orderbot-framework/lib-datasource/GeniusYield/OrderBot/DataSource.hsig b/geniusyield-orderbot-framework/lib-datasource/GeniusYield/OrderBot/DataSource.hsig index 73f0977..4b49ca2 100644 --- a/geniusyield-orderbot-framework/lib-datasource/GeniusYield/OrderBot/DataSource.hsig +++ b/geniusyield-orderbot-framework/lib-datasource/GeniusYield/OrderBot/DataSource.hsig @@ -57,10 +57,7 @@ mkDEX -- ^ Script Ref for the Partial Orders Validator -> Maybe GYTxOutRef -- ^ Script Ref for the NFT minting policy - -> (GYAddress, GYAssetClass, GYTxOutRef) - {- ^ Triplet representing the UTxO, address and value, where the NFT minting - policy of the orders is placed. - -} + -> (GYAddress, GYAssetClass) -> DEX {- | Fetch all unique DEX order asset pairings, and for each such asset pair, fetch all buy and sell orders. diff --git a/geniusyield-orderbot-framework/src/GeniusYield/OrderBot.hs b/geniusyield-orderbot-framework/src/GeniusYield/OrderBot.hs index b9df130..af8be63 100644 --- a/geniusyield-orderbot-framework/src/GeniusYield/OrderBot.hs +++ b/geniusyield-orderbot-framework/src/GeniusYield/OrderBot.hs @@ -11,96 +11,92 @@ module GeniusYield.OrderBot ( OrderBot (..) , runOrderBot ) where -import Control.Arrow ((&&&), second) -import Control.Concurrent (threadDelay) -import Control.Exception ( SomeException - , AsyncException( UserInterrupt ) - , fromException, bracket, handle - ) -import Control.Monad (forever, unless, filterM) -import Control.Monad.Reader (runReaderT) -import Data.Foldable (fold, toList) -import Data.Functor ((<&>)) -import Data.Aeson (ToJSON, encode) -import Data.Functor.Identity (runIdentity) -import Data.Maybe (mapMaybe) -import Data.List (find) - -import System.Exit ( exitSuccess ) - -import qualified Data.Map as M -import qualified Data.List.NonEmpty as NE (toList) -import qualified Data.ByteString.Char8 as B -import qualified Data.ByteString.Lazy as BL -import qualified Data.Text as Txt - -import GeniusYield.Providers.Common (SubmitTxException) -import GeniusYield.GYConfig ( GYCoreConfig (cfgNetworkId) - , withCfgProviders - , coreConfigIO - ) -import GeniusYield.OrderBot.DataSource ( closeDB, connectDB, mkDEX ) -import GeniusYield.OrderBot.MatchingStrategy ( IndependentStrategy - , MatchResult - , MatchExecutionInfo (..) - , executionSkeleton - , matchExecutionInfoUtxoRef - ) -import GeniusYield.OrderBot.OrderBook ( OrderBook - , buyOrders, sellOrders - , foldrOrders - , populateOrderBook - , withEachAsset - , maOrderBookToList - ) -import GeniusYield.OrderBot.Types ( OrderAssetPair(..), assetInfo ) -import GeniusYield.TxBuilder ( GYTxBuildResult(..) - , GYTxSkeleton - , GYTxMonadNode - , utxosAtTxOutRefs - , runGYTxQueryMonadNode - ) -import GeniusYield.TxBuilder.Node ( runGYTxMonadNodeParallelWithStrategy ) -import GeniusYield.Types - -import GeniusYield.DEX.Api.Types ( DEXInfo (..) - , PORefs (..) - , dexNftPolicy - , dexPartialOrderValidator - ) -import GeniusYield.Transaction ( BuildTxException - , GYCoinSelectionStrategy(GYRandomImproveMultiAsset) - ) +import Control.Arrow (second, (&&&)) +import Control.Concurrent (threadDelay) +import Control.Exception (AsyncException (UserInterrupt), + SomeException, bracket, + fromException, handle) +import Control.Monad (filterM, forever, + unless) +import Control.Monad.Reader (runReaderT) +import Data.Aeson (ToJSON, encode) +import Data.Foldable (foldl', toList) +import Data.Functor ((<&>)) +import Data.Functor.Identity (runIdentity) +import Data.List (find) +import Data.Maybe (mapMaybe) + +import System.Exit (exitSuccess) + +import qualified Data.ByteString.Char8 as B +import qualified Data.ByteString.Lazy as BL +import qualified Data.List.NonEmpty as NE (toList) +import qualified Data.Map as M +import qualified Data.Text as Txt + +import GeniusYield.GYConfig (GYCoreConfig (cfgNetworkId), + coreConfigIO, + withCfgProviders) +import GeniusYield.OrderBot.DataSource (closeDB, connectDB, + mkDEX) +import GeniusYield.OrderBot.MatchingStrategy (IndependentStrategy, + MatchExecutionInfo (..), + MatchResult, + executionSkeleton, + matchExecutionInfoUtxoRef) +import GeniusYield.OrderBot.OrderBook (OrderBook, buyOrders, + foldrOrders, + maOrderBookToList, + populateOrderBook, + sellOrders, + withEachAsset) +import GeniusYield.OrderBot.Types (OrderAssetPair (..), + assetInfo) +import GeniusYield.Providers.Common (SubmitTxException) +import GeniusYield.TxBuilder (GYTxBuildResult (..), + GYTxMonadNode, + GYTxSkeleton, + runGYTxQueryMonadNode, + utxosAtTxOutRefs) +import GeniusYield.TxBuilder.Node (runGYTxMonadNodeParallelWithStrategy) +import GeniusYield.Types + +import GeniusYield.DEX.Api.Types (DEXInfo (..), + PORefs (..), + dexNftPolicy, + dexPartialOrderValidator) +import GeniusYield.Transaction (BuildTxException, + GYCoinSelectionStrategy (GYLegacy)) -- | The order bot is product type between bot info and "execution strategies". data OrderBot = OrderBot - { botSkey :: !GYPaymentSigningKey + { botSkey :: !GYPaymentSigningKey -- ^ Signing key of the bot. - , botCollateral :: !(Maybe (GYTxOutRef, Bool)) + , botCollateral :: !(Maybe (GYTxOutRef, Bool)) {- ^ UTxO ref of the collateral UTxO in the bot's wallet. NOTE: If collateral is Nothing, then Atlas will choose some UTxO to - function as collateral. If a TxOutRef is given, the bool indicates wheter + function as collateral. If a TxOutRef is given, the bool indicates whether the collateral can be spent in the tx. -} - , botExecutionStrat :: !ExecutionStrategy + , botExecutionStrat :: !ExecutionStrategy -- ^ The execution strategy, which includes and governs the matching strategy. , botAssetPairFilter :: [OrderAssetPair] {- ^ List that can be used to filter out uninteresting orders/pools. The multiasset order book is created only with the existing pairs on the list. -} - , botRescanDelay :: Int + , botRescanDelay :: Int {- ^ How many microseconds to wait after a tx submission before rescanning the chain for orders. -} - , botTakeMatches :: [MatchResult] -> IO [MatchResult] + , botTakeMatches :: [MatchResult] -> IO [MatchResult] {- ^ How and how many matching results do the bot takes to build, sign and submit every iteration. -} } -{- | Currently, we only have the parallel execution strategy: MultiAssetTraverse, +{- | Currently, we only have the parallel execution strategy: @MultiAssetTraverse@, where each order book for each unique asset pair (see: "GeniusYield.OrderBot.Types.equivalentAssetPair") is processed independently. -} @@ -139,7 +135,7 @@ runOrderBot (dexPartialOrderValidator di) (porNftPolicyRef por) (porValidatorRef por) - (porRefAddr por, porRefNft por, porRefNftRef por) + (porRefAddr por, porRefNft por) logInfo $ unlines [ "" @@ -160,7 +156,7 @@ runOrderBot logInfo "Rescanning for orders..." -- First we populate the multi asset orderbook, using the provided - -- 'populateOrderBook'. + -- @populateOrderBook@. book <- populateOrderBook conn dex botAssetPairFilter let bookList = maOrderBookToList book @@ -259,7 +255,7 @@ buildTransactions matchesToExecute di netId providers botAddr botCollateral = handle handlerBuildTx $ do res <- runGYTxMonadNodeParallelWithStrategy - GYRandomImproveMultiAsset + GYLegacy netId providers [botAddr] botAddr botCollateral $ traverse resultToSkeleton matchesToExecute @@ -283,7 +279,7 @@ buildTransactions matchesToExecute di netId getBodies = NE.toList . runIdentity . sequence resultToSkeleton :: MatchResult -> GYTxMonadNode (GYTxSkeleton 'PlutusV2) - resultToSkeleton mResult = fold <$> traverse (flip runReaderT di . executionSkeleton) mResult + resultToSkeleton mResult = runReaderT (executionSkeleton mResult) di handlerBuildTx :: BuildTxException -> IO [(GYTxBody, MatchResult)] handlerBuildTx ex = logWarn (unwords ["BuildTxException:", show ex]) @@ -372,8 +368,8 @@ totalBuyOrders :: OrderBook -> Int totalBuyOrders = foldrOrders (const (+1)) 0 . buyOrders matchingsPerOrderAssetPair :: [OrderAssetPair] -> [MatchResult] -> M.Map OrderAssetPair Int -matchingsPerOrderAssetPair oaps = foldl succOAP (M.fromList $ map (,0) oaps) +matchingsPerOrderAssetPair oaps = foldl' succOAP (M.fromList $ map (, 0) oaps) where succOAP :: M.Map OrderAssetPair Int -> MatchResult -> M.Map OrderAssetPair Int - succOAP m (OrderExecutionInfo _ oi:_) = M.insertWith (+) (assetInfo oi) 1 m + succOAP m (OrderExecutionInfo _ oi : _) = M.insertWith (+) (assetInfo oi) 1 m succOAP m _ = m diff --git a/geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs b/geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs index 0303668..ffbbe15 100644 --- a/geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs +++ b/geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs @@ -17,22 +17,20 @@ module GeniusYield.OrderBot.MatchingStrategy , matchExecutionInfoUtxoRef ) where -import Data.Aeson (ToJSON (toJSON), (.=)) -import qualified Data.Aeson as Aeson -import Data.Ratio ((%)) -import Data.Text (Text) -import Numeric.Natural (Natural) - -import GeniusYield.DEX.Api.PartialOrder ( completelyFillPartialOrder - , partiallyFillPartialOrder - , PartialOrderInfo - ) -import GeniusYield.DEX.Api.Types (GYApiMonad) -import GeniusYield.OrderBot.OrderBook (OrderBook) -import GeniusYield.OrderBot.Types -import GeniusYield.TxBuilder (GYTxSkeleton) -import GeniusYield.Types.TxOutRef (showTxOutRef, GYTxOutRef) -import GeniusYield.Types.PlutusVersion (PlutusVersion(PlutusV2)) +import Data.Aeson (ToJSON (toJSON), (.=)) +import qualified Data.Aeson as Aeson +import Data.Maybe (fromJust) +import Data.Text (Text) +import Numeric.Natural (Natural) + +import GeniusYield.DEX.Api.PartialOrder (PartialOrderInfo (poiOfferedAmount), + fillMultiplePartialOrders) +import GeniusYield.DEX.Api.Types (GYApiMonad) +import GeniusYield.OrderBot.OrderBook (OrderBook) +import GeniusYield.OrderBot.Types +import GeniusYield.TxBuilder (GYTxSkeleton) +import GeniusYield.Types.PlutusVersion (PlutusVersion (PlutusV2)) +import GeniusYield.Types.TxOutRef (GYTxOutRef, showTxOutRef) {- | A matching strategy has access to the 'OrderBook' for a single asset pair, alongside all its relevant query functions. It must produce a 'MatchResult' which @@ -67,7 +65,7 @@ instance ToJSON MatchExecutionInfo where ] where prettySOrderType :: SOrderType t -> Text - prettySOrderType SBuyOrder = "Buy" + prettySOrderType SBuyOrder = "Buy" prettySOrderType SSellOrder = "Sell" {- | The result of order matching - should contain information to perform execute order and LP transactions. @@ -98,14 +96,22 @@ must be paid by the order. data FillType = CompleteFill | PartialFill Natural deriving stock (Eq, Show) executionSkeleton - :: GYApiMonad m - => MatchExecutionInfo - -> m (GYTxSkeleton PlutusV2) -executionSkeleton (OrderExecutionInfo CompleteFill oi) = completelyFillPartialOrder $ poiSource oi -executionSkeleton (OrderExecutionInfo (PartialFill n) oi@OrderInfo {orderType = SSellOrder}) = - partiallyFillPartialOrder (poiSource oi) n -executionSkeleton (OrderExecutionInfo (PartialFill n) oi@OrderInfo {orderType = SBuyOrder, price}) = - partiallyFillPartialOrder (poiSource oi) . floor $ (toInteger n % 1) * getPrice price + :: GYApiMonad m + => MatchResult + -> m (GYTxSkeleton 'PlutusV2) +executionSkeleton mr = fillMultiplePartialOrders $ map f mr + where + f (OrderExecutionInfo ft o) = + (poiSource o + , case ft of + CompleteFill -> poiOfferedAmount $ fromJust $ mPoi o + PartialFill n -> + if isBuyOrder o then + floor $ fromIntegral n * getPrice (price o) + else + n + ) + matchExecutionInfoUtxoRef :: MatchExecutionInfo -> GYTxOutRef matchExecutionInfoUtxoRef (OrderExecutionInfo CompleteFill OrderInfo {orderRef}) = orderRef @@ -114,4 +120,4 @@ matchExecutionInfoUtxoRef (OrderExecutionInfo (PartialFill _) OrderInfo {orderRe -- | If the order contains the PartialOrderInfo, return it. If not, return the ref poiSource :: forall t. OrderInfo t -> Either GYTxOutRef PartialOrderInfo poiSource OrderInfo {orderRef, mPoi = Nothing} = Left orderRef -poiSource OrderInfo {mPoi = Just poi} = Right poi +poiSource OrderInfo {mPoi = Just poi} = Right poi diff --git a/geniusyield-orderbot/src/OrderBotConfig.hs b/geniusyield-orderbot/src/OrderBotConfig.hs index 6bd1012..b1d5d05 100644 --- a/geniusyield-orderbot/src/OrderBotConfig.hs +++ b/geniusyield-orderbot/src/OrderBotConfig.hs @@ -26,7 +26,6 @@ import Data.Random ( shuffle, sample ) import qualified Data.Vector as V import Data.List ( nub ) import GHC.Generics ( Generic ) -import GHC.Natural ( naturalToInteger ) import System.Envy ( FromEnv (fromEnv), Var, Parser, envMaybe, env , decodeEnv ) @@ -162,7 +161,6 @@ data PORConfig = PORConfig { botCRefAddr :: GYAddress , botCRefNft :: GYAssetClass - , botCRefNftRef :: GYTxOutRef , botCScriptRef :: Maybe GYTxOutRef , botCNftPolicyRef :: Maybe GYTxOutRef } @@ -173,7 +171,6 @@ instance FromJSON PORConfig where PORConfig <$> (addressFromBech32 <$> obj .: "refAddr") <*> obj .: "refNftAC" - <*> obj .: "refNftUtxoRef" <*> obj .:? "scriptRef" <*> obj .:? "nftPolicyRef" parseJSON _ = fail "Expecting object value" @@ -225,7 +222,7 @@ intToNatural _ i | i > 0 = return $ fromInteger $ toInteger i intToNatural msg _ = throwIO $ userError $ msg ++ " is negative or zero" takeMatches :: Bool -> Natural -> [MatchResult] -> IO [MatchResult] -takeMatches r (fromIntegral . naturalToInteger -> maxTxPerIter) matches = +takeMatches r (fromIntegral -> maxTxPerIter) matches = take maxTxPerIter <$> if r then shuffleList matches else return matches shuffleList :: [a] -> IO [a] @@ -245,10 +242,9 @@ getDexInfo OrderBotConfig{ botCFPNftPolicy let partialOrderValidator = mkDEXValidator dexValidatorRaw (addressToPlutus $ botCRefAddr botCPORConfig) (botCRefNft botCPORConfig) - nftPolicy = mkDEXMintingPolicy dexPolicyRaw partialOrderValidator + nftPolicy = mkDEXMintingPolicy dexPolicyRaw partialOrderValidator (addressToPlutus $ botCRefAddr botCPORConfig) (botCRefNft botCPORConfig) porefs = PORefs { porRefAddr = botCRefAddr botCPORConfig , porRefNft = botCRefNft botCPORConfig - , porRefNftRef = botCRefNftRef botCPORConfig , porValidatorRef = botCScriptRef botCPORConfig , porNftPolicyRef = botCNftPolicyRef botCPORConfig } @@ -260,7 +256,7 @@ getDexInfo OrderBotConfig{ botCFPNftPolicy where readNftPolicy - :: IO (TypedScript 'MintingPolicyRole '[ScriptHash, Integer]) + :: IO (TypedScript 'MintingPolicyRole '[ScriptHash, Address, AssetClass]) readNftPolicy = readTypedScript botCFPNftPolicy readOrderValidator diff --git a/impl/datasource-providers/GeniusYield/OrderBot/DataSource/Providers.hs b/impl/datasource-providers/GeniusYield/OrderBot/DataSource/Providers.hs index d08998c..6a1e795 100644 --- a/impl/datasource-providers/GeniusYield/OrderBot/DataSource/Providers.hs +++ b/impl/datasource-providers/GeniusYield/OrderBot/DataSource/Providers.hs @@ -15,16 +15,16 @@ module GeniusYield.OrderBot.DataSource.Providers , withEachAssetOrders ) where -import Data.List (foldl') -import Data.Map.Strict (Map) -import qualified Data.Map.Strict as Map +import Data.List (foldl') +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map -import GeniusYield.DEX.Api.PartialOrder -import GeniusYield.OrderBot.Types -import GeniusYield.TxBuilder -import GeniusYield.Types -import GeniusYield.DEX.Api.Types (DEXInfo(..), mkPORefs) -import Control.Monad.Reader (ReaderT(runReaderT)) +import Control.Monad.Reader (ReaderT (runReaderT)) +import GeniusYield.DEX.Api.PartialOrder +import GeniusYield.DEX.Api.Types (DEXInfo (..), mkPORefs) +import GeniusYield.OrderBot.Types +import GeniusYield.TxBuilder +import GeniusYield.Types data Connection = Connection !GYNetworkId {-# UNPACK #-} !GYProviders @@ -42,12 +42,12 @@ mkDEX :: GYMintingPolicy PlutusV2 -> GYValidator PlutusV2 -> Maybe GYTxOutRef -> Maybe GYTxOutRef - -> (GYAddress, GYAssetClass, GYTxOutRef) + -> (GYAddress, GYAssetClass) -> DEX -mkDEX nft partialOrder mVRef mNPRef (porAddr, porAC, porRef) = +mkDEX nft partialOrder mVRef mNPRef (porAddr, porAC) = DEXInfo { dexNftPolicy = nft , dexPartialOrderValidator = partialOrder - , dexPORefs = mkPORefs porAddr porAC porRef mVRef mNPRef + , dexPORefs = mkPORefs porAddr porAC mVRef mNPRef } withEachAssetOrders @@ -65,7 +65,7 @@ withEachAssetOrders c dex assetFilter f acc = do let (buys, sells) = foldl' ( \(!buys, !sells) (SomeOrderInfo oInf@OrderInfo {orderType}) -> case orderType of - SBuyOrder -> (oInf : buys, sells) + SBuyOrder -> (oInf : buys, sells) SSellOrder -> (buys, oInf : sells) ) ([], []) @@ -117,7 +117,7 @@ partialOrderInfoToOrderInfo :: (OrderAssetPair, PartialOrderInfo) -> SomeOrderIn partialOrderInfoToOrderInfo = uncurry mkOrderInfo isAfterStart :: GYTime -> Maybe GYTime -> Bool -isAfterStart current = maybe True (current >) +isAfterStart current = maybe True (current >=) isBeforeEnd :: GYTime -> Maybe GYTime -> Bool -isBeforeEnd current = maybe True (current <) +isBeforeEnd current = maybe True (current <=) From fca8de917fa5de74fa60600ffdf92ebe3e495c77 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Sun, 10 Dec 2023 21:05:21 +0530 Subject: [PATCH 5/7] Feat #53: Removed deprecated functions --- .../src/GeniusYield/DEX/Api/PartialOrder.hs | 80 ------------------- 1 file changed, 80 deletions(-) diff --git a/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs index acc16e8..ff7d6a1 100644 --- a/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs +++ b/geniusyield-dex-api/src/GeniusYield/DEX/Api/PartialOrder.hs @@ -12,8 +12,6 @@ module GeniusYield.DEX.Api.PartialOrder , PartialOrderAction (..) , PartialOrderInfo (..) , partialOrders - , completelyFillPartialOrder - , partiallyFillPartialOrder , fillMultiplePartialOrders , getPartialOrderInfo , getPartialOrdersInfos @@ -263,84 +261,6 @@ partialOrders pOrderPredicate = do -- Tx building ------------------------------------------------------------------------------- --- | Completely fill a partially-fillable order. -completelyFillPartialOrder :: - (HasCallStack, GYApiMonad m) => - -- | The order reference. - Either GYTxOutRef PartialOrderInfo -> - m (GYTxSkeleton PlutusV2) -completelyFillPartialOrder poiSource = do - di@DEXInfo{dexPORefs} <- ask - - oi@PartialOrderInfo {..} <- case poiSource of - Left orderRef -> getPartialOrderInfo orderRef - Right poi -> return poi - - (cfgRef, poci) <- fetchPartialOrderConfig (porRefAddr dexPORefs) (porRefNft dexPORefs) - - let containedFee = poiGetContainedFeeValue oi - fee = containedFee <> valueFromLovelace (fromIntegral poiTakerLovelaceFlatFee) - feeOutput - | fee == mempty = mempty - | otherwise = mustHaveOutput $ mkGYTxOut - (pociFeeAddr poci) - fee - (datumFromPlutusData $ - PartialOrderFeeOutput - { pofdMentionedFees = PlutusTx.singleton (txOutRefToPlutus poiRef) (valueToPlutus containedFee) - , pofdReservedValue = mempty - , pofdSpentUTxORef = Nothing - } - ) - expectedValueOut = expectedPaymentWithDeposit oi True - cs <- validFillRangeConstraints poiStart poiEnd - - return $ - mustHaveInput (partialOrderInfoToIn oi CompleteFill di) - <> mustHaveOutput (partialOrderInfoToPayment oi expectedValueOut) - <> mustMint (mintingScript di) nothingRedeemer poiNFT (-1) - <> feeOutput - <> cs - <> mustHaveRefInput cfgRef - --- | Partially fill a partially-fillable order. -partiallyFillPartialOrder :: - (HasCallStack, GYApiMonad m) => - -- | The order reference. - Either GYTxOutRef PartialOrderInfo -> - -- | The amount of offered tokens to buy. - Natural -> - m (GYTxSkeleton PlutusV2) -partiallyFillPartialOrder poiSource amt = do - di@DEXInfo{dexPORefs} <- ask - - oi@PartialOrderInfo {..} <- case poiSource of - Left orderRef -> getPartialOrderInfo orderRef - Right poi -> return poi - - when (amt == 0) . throwAppError $ PodNonPositiveAmount $ toInteger amt - when (amt >= poiOfferedAmount) . throwAppError $ PodRequestedAmountGreaterOrEqualToOfferedAmount amt poiOfferedAmount - - (cfgRef, _pocd) <- fetchPartialOrderConfig (porRefAddr dexPORefs) (porRefNft dexPORefs) - - let price' = partialOrderPrice oi amt - od = partialOrderInfoToPartialOrderDatum oi - { poiOfferedAmount = poiOfferedAmount - amt - , poiPartialFills = poiPartialFills + 1 - , poiContainedFee = poiContainedFee <> mempty { poifLovelaces = fromIntegral poiTakerLovelaceFlatFee } - , poiContainedPayment = poiContainedPayment + fromIntegral (valueAssetClass price' poiAskedAsset) - } - - expectedValueOut = poiUTxOValue <> price' <> valueFromLovelace (fromIntegral poiTakerLovelaceFlatFee) `valueMinus` valueSingleton poiOfferedAsset (toInteger amt) - o = mkGYTxOut poiUTxOAddr expectedValueOut (datumFromPlutusData od) - - cs <- validFillRangeConstraints poiStart poiEnd - return $ - mustHaveInput (partialOrderInfoToIn oi (PartialFill $ toInteger amt) di) - <> mustHaveOutput o - <> cs - <> mustHaveRefInput cfgRef - {- | Fills multiple orders. If the provided amount of offered tokens to buy in an order is equal to the offered amount, then we completely fill the order. Otherwise, it gets partially filled. -} fillMultiplePartialOrders From 00c6adb8437c5de324ffc27784a20040d4eff280 Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Mon, 11 Dec 2023 14:58:55 +0530 Subject: [PATCH 6/7] Feat #53: Updated README --- .gitignore | 3 + Dockerfile | 2 +- README.md | 91 +++++++++++------------ config-files/atlas-config-blockfrost.json | 2 +- config-files/atlas-config-kupo.json | 2 +- config-files/atlas-config-maestro.json | 2 +- docker-compose.yml | 2 +- scripts/kupo-preprod.sh | 20 +++++ 8 files changed, 73 insertions(+), 51 deletions(-) create mode 100755 scripts/kupo-preprod.sh diff --git a/.gitignore b/.gitignore index de0aa30..598c6e7 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ cabal.project.local .DS_Store config-files/* *.skey +*.vkey +*.addr +scripts/kupo-mainnet.sh diff --git a/Dockerfile b/Dockerfile index 829eb91..6e32a46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -70,6 +70,6 @@ ENV BOTC_MAX_ORDERS_MATCHES='5' ENV BOTC_MAX_TXS_PER_ITERATION='4' ENV BOTC_RANDOMIZE_MATCHES_FOUND='True' ENV BOTC_ASSET_FILTER='[{"commodityAsset":"c6e65ba7878b2f8ea0ad39287d3e2fd256dc5c4160fc19bdf4c4d87e.7447454e53","currencyAsset":"lovelace"},{"commodityAsset":"0254a6ffa78edb03ea8933dbd4ca078758dbfc0fc6bb0d28b7a9c89f.4c454e4649","currencyAsset":"lovelace"},{"commodityAsset":"8cafc9b387c9f6519cacdce48a8448c062670c810d8da4b232e56313.6d4e5458","currencyAsset":"lovelace"},{"commodityAsset":"171163f05e4f30b6be3c22668c37978e7d508b84f83558e523133cdf.74454d50","currencyAsset":"lovelace"}]' -ENV BOTC_POREFS='{"refAddr":"addr_test1wpgexmeunzsykesf42d4eqet5yvzeap6trjnflxqtkcf66g0kpnxt","refNftAC":"fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.e6a295bb83d06f53fcf91151f54acec0a63fbd6f0d924206d5d012e6da3b72af","refNftUtxoRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#0","scriptRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#1","nftPolicyRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#0"}' +ENV BOTC_POREFS='{"refAddr":"addr_test1wrgvy8fermjrruaf7fnndtmpuw4xx4cnvfqjp5zqu8kscfcvh32qk","refNftAC":"fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.8309f9861928a55d37e84f6594b878941edce5e351f7904c2c63b559bde45c5c","scriptRef":"be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#2","nftPolicyRef":"be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#1"}' ENTRYPOINT ["/bin/bash", "./start.sh"] diff --git a/README.md b/README.md index e59eab8..fb8376a 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,10 @@ Let's start with a concrete and short overview of the GY DEX Orders, so the cont of the SOR for using, modifying, and improving with new custom strategies is properly established. A complete description can be found in the [GY whitepaper](https://www.geniusyield.co/whitepaper.pdf?lng=en). -Given a pair of tokens, an order will contain the number of tokens it offers, the price -of one unit of those offered, and the minimal amount we are forced to buy from the order. +Given a pair of tokens, an order will contain the number of tokens it offers and the price of one unit of offered token in terms of asked tokens. Besides that, the order will have some life timeline and, of course, a notion of ownership related to the one that created it. For example, we could create an order offering of `10 tokenA`, -with a unit price of `2 tokenB`, that is, we expect to receive `2 tokenB` per `1 tokenA`. Also, we -want the minimal amount to be bought be `5 tokenA`. Clearly, the owners of this order will be +with a unit price of `2 tokenB`, that is, we expect to receive `2 tokenB` per `1 tokenA`. Clearly, the owners of this order will be us and it's important to mention that all this information is **mandatory**, but we can avoid setting the life timeline, meaning the order will always be available. Once we create an order, the offered tokens will be locked on the order. @@ -66,9 +64,7 @@ Given an order, two interesting "actions" can be performed over it. The owner ca it and get back the locked tokens. Or anyone can _fill_ it, filling an order is just paying the correct amount of tokens the owner of the order expects to receive related to the amount of tokens we want to buy from that order. Following the previous example, anyone -could fill that order by buying from it `6 tokenA` and paying the owner `12 tokenB`. But, it -isn't possible to buy, for instance, `3 tokenA` from the order because the minimal amount -was setup to `5`, except the amount of offered tokens is less than that. +could fill that order by buying from it `6 tokenA` and paying `12 tokenB`. One important thing to mention that is transparent for any end user, is that there are two kinds of fills: _complete_ and _partial_. A complete fill will buy all the offered @@ -82,9 +78,9 @@ There shouldn't be any surprise if we mention that each action is performed by a Now, let's suppose, besides the previous order, we have another one offering of `20 tokenB`, with a unit price of `0.4 tokenA`. We could earn some tokens by “combining” the two orders -and take advantage of the price difference. Following the example, given we bought `6 tokenA` -using `12 tokenB`, we now can use these `6 tokenA` to buy back `15 tokenB` from this other -order, earning `3 tokenB`. These two fills can be combined into a single transaction, in +and take advantage of the price difference. Following the example, given we bought `8 tokenA` +using `16 tokenB`, we now can use these `8 tokenA` to buy back `20 tokenB` from this other +order, earning `4 tokenB`. These two fills can be combined into a single transaction, in fact, we could combine more than two orders. The SOR has the ability to build these transactions matching orders programmatically, @@ -119,22 +115,18 @@ Using the previous example we could have two cases: -If we want our earnings to be in `tokenB`, then the commodity must be `tokenA`. We can buy from -the sell order, `6 tokenA` using `12 tokenB`, then using these `6 tokenA` we buy back `15 tokenB` from -the buy order, earning `3 tokenB`. However, if we want our earnings to be in `tokenA`, then the -commodity must be `tokenB`. So we can buy from the sell order, `18 tokenB` using `7 tokenA`, then -using these `18 tokenB` we buy back `9 tokenA` from the buy order, earning `2 tokenA`. +If we want our earnings to be in `tokenA` then the +commodity must be `tokenB`. So we can buy from the sell order, `20 tokenB` using `8 tokenA`, then +using these `20 tokenB` we can get `10 tokenA` from the buy order, earning `2 tokenA`. ## Building and running > [!NOTE] -> The Genius Yield DEX is in the public testnet phase at the moment. -> > In order to run Smart Order Router instances for the public testnet, please use the preprod testnet as in the examples below. ### Docker -A ready-to-run, containerized version of the Smart Order Router is availabe via the [GitHub Container Registry](ghcr.io/geniusyield/smart-order-router:latest). +A ready-to-run, containerized version of the Smart Order Router is available via the [GitHub Container Registry](ghcr.io/geniusyield/smart-order-router:latest). A Smart Order Router container instance using the Maestro backend can be started by using the following snippet: @@ -145,7 +137,7 @@ A Smart Order Router container instance using the Maestro backend can be started PAYMENT_SIGNING_KEY_CBOR_HEX=5820d682e237a04d43ad011fdecd141acd485f6d3d634466692d58f6d75250f39134 COLLATERAL_UTXO_REF=7cc7b044d26981d3fc73ae72994f289d99ba113ceefb5b83f4d7643bfb12682a#1 MAESTRO_API_KEY=some_api_key -CARDANO_NETWORK=testnet-preprod +CARDANO_NETWORK=preprod docker run -it \ -e BOTC_SKEY="{\"cborHex\": \"$PAYMENT_SIGNING_KEY_CBOR_HEX\", \"type\": \"PaymentSigningKeyShelley_ed25519\", \"description\": \"Payment Signing Key\"}" \ @@ -160,6 +152,9 @@ Alternatively the Blockfrost or the Kupo backend could be used. This can be accomplished for Blockfrost by using the following commands: +> [!NOTE] +> Few of the optimisations that we make use of such as querying UTxOs and their datums in a single request, aren't available for Blockfrost, thus, this provider is expected to run slow compared to other providers. + ``` bash # SMART ORDER ROUTER INSTANCE USING BLOCKFROST # ============================================ @@ -167,7 +162,7 @@ This can be accomplished for Blockfrost by using the following commands: PAYMENT_SIGNING_KEY_CBOR_HEX=5820d682e237a04d43ad011fdecd141acd485f6d3d634466692d58f6d75250f39134 COLLATERAL_UTXO_REF=7cc7b044d26981d3fc73ae72994f289d99ba113ceefb5b83f4d7643bfb12682a#1 BLOCKFROST_API_KEY=some_api_key -CARDANO_NETWORK=testnet-preprod +CARDANO_NETWORK=preprod docker run -it \ -e BOTC_SKEY="{\"cborHex\": \"$PAYMENT_SIGNING_KEY_CBOR_HEX\", \"type\": \"PaymentSigningKeyShelley_ed25519\", \"description\": \"Payment Signing Key\"}" \ @@ -178,6 +173,12 @@ docker run -it \ And the following commands can be used to start a Kupo backed instance, if you want to use an existing Kupo instance: + > **ⓘ How to run Kupo efficiently?** + > + > Firstly, Kupo requires a node running, note that node itself maintains efficient access to information such as current protocol parameters, current set of pool ids, etc. but it doesn't efficiently provide us with UTxOs when say queried by a particular address. Kupo helps in covering this gap and gives us efficient lookup tables to query for UTxOs. For our use case, we are only interested in our own bot's UTxOs, order UTxOs and the required reference scripts / reference inputs. So we'll run Kupo to keep track of only those UTxOs, note that if we instead run Kupo by matching against star (`*`) pattern, then as Kupo does many disk writes, we would quickly burn out our SSDs TBW limit. + > + > Please see the scripts, [`kupo-preprod.sh`](./scripts/kupo-preprod.sh) for pre-production network and `kupo-mainnet.sh` (to be created) for mainnet network to see how this can be achieved. Note that these two scripts take as an argument the match pattern for bot's UTxOs, you may very well give the bech32 address of bot as value of this argument. To understand what all the script does, please see Kupo's [documentation](https://cardanosolutions.github.io/kupo/#section/Getting-started). + ``` bash # SMART ORDER ROUTER INSTANCE USING KUPO (existing Kupo instance) # =============================================================== @@ -186,7 +187,7 @@ PAYMENT_SIGNING_KEY_CBOR_HEX=5820d682e237a04d43ad011fdecd141acd485f6d3d634466692 COLLATERAL_UTXO_REF=7cc7b044d26981d3fc73ae72994f289d99ba113ceefb5b83f4d7643bfb12682a#1 KUPO_URL=http://some.url.to.your.kupo.instance:1442 CARDANO_NODE_SOCKET_PATH=/cardano/node/socket -CARDANO_NETWORK=testnet-preprod +CARDANO_NETWORK=preprod docker run -it \ -e BOTC_SKEY="{\"cborHex\": \"$PAYMENT_SIGNING_KEY_CBOR_HEX\", \"type\": \"PaymentSigningKeyShelley_ed25519\", \"description\": \"Payment Signing Key\"}" \ @@ -246,25 +247,24 @@ file. The complete bot configuration looks like this: ```json { - "signingKeyFP":"bot.skey", - "nftMintingPolicyFP":"compiled-scripts/minting-policy", - "orderValidatorFP":"compiled-scripts/partial-order", - "validatorRefs":{ - "refAddr":"addr_test1wpgexmeunzsykesf42d4eqet5yvzeap6trjnflxqtkcf66g0kpnxt", - "refNftAC":"fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.e6a295bb83d06f53fcf91151f54acec0a63fbd6f0d924206d5d012e6da3b72af", - "refNftUtxoRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#0", - "scriptRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#1", - "nftPolicyRef":"39f987a6beb9cc4c45bba149a21c28068f640f3593f15f8157f0b6022b431977#0" + "signingKeyFP": "bot.skey", + "nftMintingPolicyFP": "compiled-scripts/minting-policy", + "orderValidatorFP": "compiled-scripts/partial-order", + "validatorRefs": { + "refAddr": "addr_test1wrgvy8fermjrruaf7fnndtmpuw4xx4cnvfqjp5zqu8kscfcvh32qk", + "refNftAC": "fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.8309f9861928a55d37e84f6594b878941edce5e351f7904c2c63b559bde45c5c", + "scriptRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#2", + "nftPolicyRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#1" }, - "strategy":"OneSellToManyBuy", - "scanDelay":40000000, - "maxOrderMatches":5, - "maxTxsPerIteration":5, - "randomizeMatchesFound":true, - "scanTokens":[ + "strategy": "OneSellToManyBuy", + "scanDelay": 40000000, + "maxOrderMatches": 5, + "maxTxsPerIteration": 4, + "randomizeMatchesFound": true, + "scanTokens": [ { - "commodityAsset":"c6e65ba7878b2f8ea0ad39287d3e2fd256dc5c4160fc19bdf4c4d87e.7447454e53", - "currencyAsset":"lovelace" + "commodityAsset": "c6e65ba7878b2f8ea0ad39287d3e2fd256dc5c4160fc19bdf4c4d87e.7447454e53", + "currencyAsset": "lovelace" } ] } @@ -322,7 +322,7 @@ the private signing key, the verification key, and the wallet address on the preprod testnet. You can claim some **preprod** lovelaces using the [faucet](https://docs.cardano.org/cardano-testnet/tools/faucet/). -It's **recomended** to create and setup a `collateral`. A UTxO with 5 ADAs will +It's **recommended** to create and setup a `collateral`. A UTxO with 5 ADAs will do the work. But as we mentioned the `collateral` config field is optional. #### Deployed Contract @@ -334,12 +334,11 @@ that is completely placed on the blockchain. That is the validator and minting p ##### Preprod ```json { - "validatorRefs":{ - "refAddr":"addr_test1wpgexmeunzsykesf42d4eqet5yvzeap6trjnflxqtkcf66g0kpnxt", - "refNftAC":"fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.6af3807634905a04be64a8dbe0ddb9da6ce52eed23cb428c7be5d6114eacc189", - "refNftUtxoRef":"aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#0", - "scriptRef":"aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#1", - "nftPolicyRef":"aaaae7e568aab31db6f74faaf550867d58b2361868324567470862ecaaac7646#0" + "validatorRefs": { + "refAddr": "addr_test1wrgvy8fermjrruaf7fnndtmpuw4xx4cnvfqjp5zqu8kscfcvh32qk", + "refNftAC": "fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.8309f9861928a55d37e84f6594b878941edce5e351f7904c2c63b559bde45c5c", + "scriptRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#2", + "nftPolicyRef": "be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050#1" } } ``` @@ -489,7 +488,7 @@ different SOR instances? does not return proper order matches and there aren't enough tokens in the transaction bucket to pay an order. -- `GYTxMonadException "partiallyFillPartialOrder: amount x must be smaller than offered amount x`, +- `GYTxMonadException "... amount x must be smaller than offered amount x ...`, you are trying to partially fill an order, but the partial fill amount is the max volume of the order. Use [`CompleteFill`](./geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs#L98C17-L98C29) instead. See [GeniusYield.OrderBot.MatchingStrategy](./geniusyield-orderbot-framework/src/GeniusYield/OrderBot/MatchingStrategy.hs#L98) for more information. diff --git a/config-files/atlas-config-blockfrost.json b/config-files/atlas-config-blockfrost.json index eb7aa95..d7f6b22 100644 --- a/config-files/atlas-config-blockfrost.json +++ b/config-files/atlas-config-blockfrost.json @@ -2,7 +2,7 @@ "coreProvider": { "blockfrostKey": "<>" }, - "networkId": "testnet-preprod", + "networkId": "preprod", "logging": [ { "type": { diff --git a/config-files/atlas-config-kupo.json b/config-files/atlas-config-kupo.json index acd3367..358b3cd 100644 --- a/config-files/atlas-config-kupo.json +++ b/config-files/atlas-config-kupo.json @@ -3,7 +3,7 @@ "socketPath": "<>", "kupoUrl": "<>" }, - "networkId": "testnet-preprod", + "networkId": "preprod", "logging": [ { "type": { diff --git a/config-files/atlas-config-maestro.json b/config-files/atlas-config-maestro.json index bd87428..bf37d4b 100644 --- a/config-files/atlas-config-maestro.json +++ b/config-files/atlas-config-maestro.json @@ -2,7 +2,7 @@ "coreProvider": { "maestroToken": "<>" }, - "networkId": "testnet-preprod", + "networkId": "preprod", "logging": [ { "type": { diff --git a/docker-compose.yml b/docker-compose.yml index daf237b..355768f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: {"cborHex": "$PAYMENT_SIGNING_KEY_CBOR_HEX", "type": "PaymentSigningKeyShelley_ed25519", "description": "Payment Signing Key"} BOTC_COLLATERAL: "$COLLATERAL_UTXO_REF" BOTC_CONFIG: | - {"coreProvider": { "socketPath": "/ipc/node.socket", "kupoUrl": "kupo:1442" }, "networkId": "testnet-preprod", "logging": [{ "type": { "tag": "stderr" }, "severity": "Info", "verbosity": "V2" }]} + {"coreProvider": { "socketPath": "/ipc/node.socket", "kupoUrl": "kupo:1442" }, "networkId": "preprod", "logging": [{ "type": { "tag": "stderr" }, "severity": "Info", "verbosity": "V2" }]} restart: always volumes: [node-ipc:/ipc] depends_on: diff --git a/scripts/kupo-preprod.sh b/scripts/kupo-preprod.sh new file mode 100755 index 0000000..601861e --- /dev/null +++ b/scripts/kupo-preprod.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +FROM_BABBAGE=3542390.f93e682d5b91a94d8660e748aef229c19cb285bfb9830db48941d6a78183d81f +MATCH_ORDERS=158f42b49e0841301b45358b87744167f43359cc3785eab8d30893e1.* +MATCH_BOT=$1 +MATCH_MINTING_POLICY_REF=1@be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050 +MATCH_VALIDATOR_REF=2@be6f8dc16d4e8d5aad566ff6b5ffefdda574817a60d503e2a0ea95f773175050 +MATCH_CONFIG_ADDR=addr_test1wrgvy8fermjrruaf7fnndtmpuw4xx4cnvfqjp5zqu8kscfcvh32qk + +kupo \ + --node-socket $NODE_PREPROD/db/node.socket \ + --node-config $NODE_PREPROD/config.json \ + --since $FROM_BABBAGE \ + --match $MATCH_ORDERS \ + --match $MATCH_BOT \ + --match $MATCH_MINTING_POLICY_REF \ + --match $MATCH_VALIDATOR_REF \ + --match $MATCH_CONFIG_ADDR \ + --prune-utxo \ + --workdir $NODE_PREPROD/kupo/sor/db From 51fef2b3d20389ff12daa157ae6f0d9d0e1813bc Mon Sep 17 00:00:00 2001 From: sourabhxyz Date: Thu, 14 Dec 2023 20:08:28 +0530 Subject: [PATCH 7/7] Feat #53: Added mainnet config details --- .gitignore | 1 - README.md | 14 +++++--------- scripts/kupo-mainnet.sh | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100755 scripts/kupo-mainnet.sh diff --git a/.gitignore b/.gitignore index 598c6e7..9047e92 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,3 @@ config-files/* *.skey *.vkey *.addr -scripts/kupo-mainnet.sh diff --git a/README.md b/README.md index 2304224..0c74231 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ And the following commands can be used to start a Kupo backed instance, if you w > > Firstly, Kupo requires a node running, note that node itself maintains efficient access to information such as current protocol parameters, current set of pool ids, etc. but it doesn't efficiently provide us with UTxOs when say queried by a particular address. Kupo helps in covering this gap and gives us efficient lookup tables to query for UTxOs. For our use case, we are only interested in our own bot's UTxOs, order UTxOs and the required reference scripts / reference inputs. So we'll run Kupo to keep track of only those UTxOs, note that if we instead run Kupo by matching against star (`*`) pattern, then as Kupo does many disk writes, we would quickly burn out our SSDs TBW limit. > - > Please see the scripts, [`kupo-preprod.sh`](./scripts/kupo-preprod.sh) for pre-production network and `kupo-mainnet.sh` (to be created) for mainnet network to see how this can be achieved. Note that these two scripts take as an argument the match pattern for bot's UTxOs, you may very well give the bech32 address of bot as value of this argument. To understand what all the script does, please see Kupo's [documentation](https://cardanosolutions.github.io/kupo/#section/Getting-started). + > Please see the scripts, [`kupo-preprod.sh`](./scripts/kupo-preprod.sh) for pre-production network and [`kupo-mainnet.sh`](./scripts/kupo-mainnet.sh) for mainnet network to see how this can be achieved. Note that these two scripts take as an argument the match pattern for bot's UTxOs, you may very well give the bech32 address of bot as value of this argument. To understand what all the script does, please see Kupo's [documentation](https://cardanosolutions.github.io/kupo/#section/Getting-started). ``` bash # SMART ORDER ROUTER INSTANCE USING KUPO (existing Kupo instance) @@ -374,17 +374,13 @@ that is completely placed on the blockchain. That is the validator and the minti ##### Mainnet -> [!NOTE] -> The Smart Order Router configuration for the Cardano Mainnet is going to be available as we approach the Mainnet launch date. - ```json { "validatorRefs":{ - "refAddr":"", - "refNftAC":"", - "refNftUtxoRef":"", - "scriptRef":"", - "nftPolicyRef":"" + "refAddr": "addr1w9zr09hgj7z6vz3d7wnxw0u4x30arsp5k8avlcm84utptls8uqd0z", + "refNftAC": "fae686ea8f21d567841d703dea4d4221c2af071a6f2b433ff07c0af2.4aff78908ef2dce98bfe435fb3fd2529747b1c4564dff5adebedf4e46d0fc63d", + "scriptRef": "062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea#2", + "nftPolicyRef": "062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea#1" } } ``` diff --git a/scripts/kupo-mainnet.sh b/scripts/kupo-mainnet.sh new file mode 100755 index 0000000..a653c06 --- /dev/null +++ b/scripts/kupo-mainnet.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +FROM_BABBAGE=72316796.c58a24ba8203e7629422a24d9dc68ce2ed495420bf40d9dab124373655161a20 +MATCH_ORDERS=22f6999d4effc0ade05f6e1a70b702c65d6b3cdf0e301e4a8267f585.* +MATCH_BOT=$1 +MATCH_MINTING_POLICY_REF=1@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea +MATCH_VALIDATOR_REF=2@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea +MATCH_CONFIG_ADDR=addr1w9zr09hgj7z6vz3d7wnxw0u4x30arsp5k8avlcm84utptls8uqd0z + +kupo \ + --node-socket $NODE_MAINNET/db/node.socket \ + --node-config $NODE_MAINNET/config.json \ + --since $FROM_BABBAGE \ + --match $MATCH_ORDERS \ + --match $MATCH_BOT \ + --match $MATCH_MINTING_POLICY_REF \ + --match $MATCH_VALIDATOR_REF \ + --match $MATCH_CONFIG_ADDR \ + --prune-utxo \ + --workdir $NODE_MAINNET/kupo/sor/db