2022.09.21 22:09 [3304728] smart account 3PEhGDwvjrjVKRPv5kHkjfDLmBJK1dd2frT > SELF 0.00000000 Waves

{ "type": 13, "id": "95onnZmUbgcqgQqgYp9RmNQYL5WEqVaiELsJ7PUF5euo", "fee": 2400000, "feeAssetId": null, "timestamp": 1663787468669, "version": 2, "chainId": 87, "sender": "3PEhGDwvjrjVKRPv5kHkjfDLmBJK1dd2frT", "senderPublicKey": "BjDUSXyo3yUJSxVFdH2pYANz31E6xzH7rdyYLBMRvHE2", "proofs": [ "5duopf5NfHHrcubsX42suKHiJhvGKsqoi1kBGG4uWgNaZKdke3ssQUvtXB5bAGMYN4NHAsj2qmpbN8gUWH6AVb1o" ], "script": "base64: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ZXIAAAABCQABLAAAAAIJAAEsAAAAAgUAAAAHYWRkcmVzcwIAAAAKX3N1cHBsaWVkXwUAAAAKYXNzZXRJZFN0cgUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAICAAAAD3RvdGFsX3N1cHBsaWVkXwUAAAAKYXNzZXRJZFN0cgkAAGQAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgIAAAAPdG90YWxfc3VwcGxpZWRfBQAAAAphc3NldElkU3RyBQAAAAZhbW91bnQFAAAAA25pbAUAAAARcmF0ZXNSZWNhbGNSZXN1bHQAAAABaQEAAAAId2l0aGRyYXcAAAACAAAACmFzc2V0SWRTdHIAAAALYXNzZXRBbW91bnQEAAAACyR0MDU3ODM1ODUwCQEAAAANZ2V0QWN0dWFsUmF0ZQAAAAIFAAAACmFzc2V0SWRTdHICAAAABXNSYXRlBAAAAAVzUmF0ZQgFAAAACyR0MDU3ODM1ODUwAAAAAl8xBAAAABFyYXRlc1JlY2FsY1Jlc3VsdAgFAAAACyR0MDU3ODM1ODUwAAAAAl8yBAAAAAZhbW91bnQJAABrAAAAAwUAAAALYXNzZXRBbW91bnQFAAAAB1NjYWxlMTYFAAAABXNSYXRlBAAAAAdhZGRyZXNzCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAANYXNzZXRTdXBwbGllZAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAICAAAAD3RvdGFsX3N1cHBsaWVkXwUAAAAKYXNzZXRJZFN0cgQAAAANYXNzZXRCb3Jyb3dlZAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAICAAAAD3RvdGFsX2JvcnJvd2VkXwUAAAAKYXNzZXRJZFN0cgQAAAARdXNlckFzc2V0U3VwcGxpZWQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACCQABLAAAAAIFAAAAB2FkZHJlc3MCAAAACl9zdXBwbGllZF8FAAAACmFzc2V0SWRTdHIEAAAAEXVzZXJBc3NldEJvcnJvd2VkCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAphc3NldElkU3RyAwkBAAAAASEAAAABCQEAAAANdHJ5R2V0Qm9vbGVhbgAAAAECAAAADHNldHVwX2FjdGl2ZQkAAAIAAAABAgAAABFtYXJrZXQgaXMgc3RvcHBlZAMJAABmAAAAAgUAAAAGYW1vdW50CQAAZQAAAAIFAAAADWFzc2V0U3VwcGxpZWQFAAAADWFzc2V0Qm9ycm93ZWQJAAACAAAAAQIAAAAqdGhpcyBhbW91bnQgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgbWFya2V0AwkAAGYAAAACBQAAAAZhbW91bnQJAABlAAAAAgUAAAARdXNlckFzc2V0U3VwcGxpZWQFAAAAEXVzZXJBc3NldEJvcnJvd2VkCQAAAgAAAAECAAAAKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgZm9yIHRoaXMgdXNlcgkABE4AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIJAAEsAAAAAgUAAAAHYWRkcmVzcwIAAAAKX3N1cHBsaWVkXwUAAAAKYXNzZXRJZFN0cgkAAGUAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfc3VwcGxpZWRfBQAAAAphc3NldElkU3RyBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgIAAAAPdG90YWxfc3VwcGxpZWRfBQAAAAphc3NldElkU3RyCQAAZQAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACAgAAAA90b3RhbF9zdXBwbGllZF8FAAAACmFzc2V0SWRTdHIFAAAABmFtb3VudAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAABmFtb3VudAkBAAAADWdldEFzc2V0Qnl0ZXMAAAABBQAAAAphc3NldElkU3RyBQAAAANuaWwFAAAAEXJhdGVzUmVjYWxjUmVzdWx0AAAAAWkBAAAABmJvcnJvdwAAAAIAAAAKYXNzZXRJZFN0cgAAAAthc3NldEFtb3VudAQAAAAHYWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAACyR0MDY5OTU3MDYyCQEAAAANZ2V0QWN0dWFsUmF0ZQAAAAIFAAAACmFzc2V0SWRTdHICAAAABWJSYXRlBAAAAAViUmF0ZQgFAAAACyR0MDY5OTU3MDYyAAAAAl8xBAAAABFyYXRlc1JlY2FsY1Jlc3VsdAgFAAAACyR0MDY5OTU3MDYyAAAAAl8yBAAAAAZhbW91bnQJAABrAAAAAwUAAAALYXNzZXRBbW91bnQFAAAAB1NjYWxlMTYFAAAABWJSYXRlBAAAAAVwcmljZQgJAQAAAA1nZXRUb2tlblByaWNlAAAAAQUAAAAKYXNzZXRJZFN0cgAAAAJfMgQAAAAKYXNzZXRTY2FsZQkBAAAADmNhbGNBc3NldFNjYWxlAAAAAQUAAAAKYXNzZXRJZFN0cgQAAAANdXNkRXF1aXZhbGVudAkAAGsAAAADBQAAAAZhbW91bnQFAAAABXByaWNlBQAAAAphc3NldFNjYWxlBAAAABJjb2xsYXRlcmFsVmFsdWVJbnYJAAP8AAAABAUAAAAEdGhpcwIAAAARZ2V0VXNlckNvbGxhdGVyYWwJAARMAAAAAgcJAARMAAAAAgUAAAAHYWRkcmVzcwkABEwAAAACBgUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAEmNvbGxhdGVyYWxWYWx1ZUludgUAAAASY29sbGF0ZXJhbFZhbHVlSW52BAAAAA9jb2xsYXRlcmFsVmFsdWUEAAAAByRtYXRjaDAFAAAAEmNvbGxhdGVyYWxWYWx1ZUludgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4CQAAAgAAAAECAAAAH2Nhbid0IGdldCB1c2VyIGNvbGxhdGVyYWwgdmFsdWUDCQAAZgAAAAIFAAAADXVzZEVxdWl2YWxlbnQFAAAAD2NvbGxhdGVyYWxWYWx1ZQkAAAIAAAABAgAAACF5b3UgaGF2ZSB0byBzdXBwbHkgbW9yZSB0byBib3Jyb3cEAAAADWFzc2V0U3VwcGxpZWQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACAgAAAA90b3RhbF9zdXBwbGllZF8FAAAACmFzc2V0SWRTdHIEAAAADWFzc2V0Qm9ycm93ZWQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACAgAAAA90b3RhbF9ib3Jyb3dlZF8FAAAACmFzc2V0SWRTdHIEAAAAEXVzZXJBc3NldEJvcnJvd2VkCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAphc3NldElkU3RyAwkAAGYAAAACBQAAAAZhbW91bnQJAABlAAAAAgUAAAANYXNzZXRTdXBwbGllZAUAAAANYXNzZXRCb3Jyb3dlZAkAAAIAAAABAgAAABx0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlCQAETgAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAphc3NldElkU3RyCQAAZAAAAAIFAAAAEXVzZXJBc3NldEJvcnJvd2VkBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgIAAAAPdG90YWxfYm9ycm93ZWRfBQAAAAphc3NldElkU3RyCQAAZAAAAAIFAAAADWFzc2V0Qm9ycm93ZWQFAAAABmFtb3VudAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAABmFtb3VudAkBAAAADWdldEFzc2V0Qnl0ZXMAAAABBQAAAAphc3NldElkU3RyBQAAAANuaWwFAAAAEXJhdGVzUmVjYWxjUmVzdWx0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAVyZXBheQAAAAADCQEAAAABIQAAAAEJAQAAAA10cnlHZXRCb29sZWFuAAAAAQIAAAAMc2V0dXBfYWN0aXZlCQAAAgAAAAECAAAAEW1hcmtldCBpcyBzdG9wcGVkAwMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEGCQAAAAAAAAIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAAAAAAAAAAAAAkAAAIAAAABAgAAABwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAAAAAphc3NldElkU3RyCQEAAAAOZ2V0QXNzZXRTdHJpbmcAAAABCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAthc3NldEFtb3VudAgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50BAAAAAskdDA4NTA5ODU3NgkBAAAADWdldEFjdHVhbFJhdGUAAAACBQAAAAphc3NldElkU3RyAgAAAAViUmF0ZQQAAAAFYlJhdGUIBQAAAAskdDA4NTA5ODU3NgAAAAJfMQQAAAARcmF0ZXNSZWNhbGNSZXN1bHQIBQAAAAskdDA4NTA5ODU3NgAAAAJfMgQAAAAGYW1vdW50CQAAawAAAAMFAAAAC2Fzc2V0QW1vdW50BQAAAAdTY2FsZTE2BQAAAAViUmF0ZQQAAAAHYWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADWFzc2V0U3VwcGxpZWQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACAgAAAA90b3RhbF9zdXBwbGllZF8FAAAACmFzc2V0SWRTdHIEAAAADWFzc2V0Qm9ycm93ZWQJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACAgAAAA90b3RhbF9ib3Jyb3dlZF8FAAAACmFzc2V0SWRTdHIEAAAAEXVzZXJBc3NldEJvcnJvd2VkCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAphc3NldElkU3RyAwkAAAAAAAACCQAEswAAAAIJAQAAAAx0cnlHZXRTdHJpbmcAAAABAgAAAAxzZXR1cF90b2tlbnMFAAAACmFzc2V0SWRTdHIFAAAABHVuaXQJAAACAAAAAQIAAAApdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQDCQAAZgAAAAIFAAAABmFtb3VudAUAAAARdXNlckFzc2V0Qm9ycm93ZWQJAAAC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AQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACCQABLAAAAAIFAAAAB2FkZHJlc3MCAAAACl9zdXBwbGllZF8FAAAAC3NBc3NldElkU3RyBAAAABBjdXJyZW50QlBvc2l0aW9uCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAtiQXNzZXRJZFN0cgMJAABmAAAAAgUAAAAOdXNlckNvbGxhdGVyYWwAAAAAAAAAAAAJAAACAAAAAQIAAAAYdXNlciBjYW4ndCBiZSBsaXF1aWRhdGVkAwkAAGYAAAACBQAAAAxzQXNzZXRBbW91bnQFAAAAEGN1cnJlbnRTUG9zaXRpb24JAAACAAAAAQIAAAAycG9zaXRpb24gdG8gbGlxdWlkYXRlIGlzIGJpZ2dlciB0aGFuIHVzZXIncyBzdXBwbHkEAAAAEWFnZ3JlZ2F0b3JBZGRyZXNzCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFXnQyqxhNRqW7LgPdjfcFkeOLvck2oDLrTBAAAAA5iYWxhbmNlMEJlZm9yZQkBAAAACmdldEJhbGFuY2UAAAABBQAAAAtzQXNzZXRJZFN0cgMJAAAAAAAAAgUAAAAOYmFsYW5jZTBCZWZvcmUFAAAADmJhbGFuY2UwQmVmb3JlBAAAAA5iYWxhbmNlMUJlZm9yZQkBAAAACmdldEJhbGFuY2UAAAABBQAAAAtiQXNzZXRJZFN0cgMJAAAAAAAAAgUAAAAOYmFsYW5jZTFCZWZvcmUFAAAADmJhbGFuY2UxQmVmb3JlBAAAAA5leGNoYW5nZUludm9rZQkAA/wAAAAEBQAAABFhZ2dyZWdhdG9yQWRkcmVzcwIAAAAEc3dhcAkABEwAAAACBQAAAAhyb3V0ZVN0cgkABEwAAAACAAAAAAAAAAAABQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAQAAAA1nZXRBc3NldEJ5dGVzAAAAAQUAAAALc0Fzc2V0SWRTdHIFAAAAC2Fzc2V0QW1vdW50BQAAAANuaWwDCQAAAAAAAAIFAAAADmV4Y2hhbmdlSW52b2tlBQAAAA5leGNoYW5nZUludm9rZQQAAAAKYXNzZXQwU29sZAkAAGUAAAACBQAAAA5iYWxhbmNlMEJlZm9yZQkBAAAACmdldEJhbGFuY2UAAAABBQAAAAtzQXNzZXRJZFN0cgMJAAAAAAAAAgUAAAAKYXNzZXQwU29sZAUAAAAKYXNzZXQwU29sZAQAAAAMYXNzZXQxQm91Z2h0CQAAZQAAAAIJAQAAAApnZXRCYWxhbmNlAAAAAQUAAAALYkFzc2V0SWRTdHIFAAAADmJhbGFuY2UxQmVmb3JlAwkAAAAAAAACBQAAAAxhc3NldDFCb3VnaHQFAAAADGFzc2V0MUJvdWdodAQAAAALYXNzZXQwUHJpY2UICQEAAAANZ2V0VG9rZW5QcmljZQAAAAEFAAAAC3NBc3NldElkU3RyAAAAAl8yBAAAAAthc3NldDBTY2FsZQkBAAAADmNhbGNBc3NldFNjYWxlAAAAAQUAAAALc0Fzc2V0SWRTdHIEAAAACWFzc2V0MFVzZAkAAGsAAAADBQAAAAphc3NldDBTb2xkBQAAAAthc3NldDBQcmljZQUAAAALYXNzZXQwU2NhbGUEAAAAC2Fzc2V0MVByaWNlCAkBAAAADWdldFRva2VuUHJpY2UAAAABBQAAAAtiQXNzZXRJZFN0cgAAAAJfMQQAAAALYXNzZXQxU2NhbGUJAQAAAA5jYWxjQXNzZXRTY2FsZQAAAAEFAAAAC2JBc3NldElkU3RyBAAAAAlhc3NldDFVc2QJAABrAAAAAwUAAAAMYXNzZXQxQm91Z2h0BQAAAAthc3NldDFQcmljZQUAAAALYXNzZXQxU2NhbGUEAAAAB3BlbmFsdHkJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACCQAEtQAAAAIJAQAAAAx0cnlHZXRTdHJpbmcAAAABAgAAAA9zZXR1cF9wZW5hbHRpZXMCAAAAASwJAQAAAAV2YWx1ZQAAAAEJAARPAAAAAgkBAAAAD2dldE1hcmtldEFzc2V0cwAAAAAFAAAAC2JBc3NldElkU3RyBAAAABFsaXF1aWRhdGlvblByb2ZpdAkAAGUAAAACBQAAAAlhc3NldDFVc2QJAABrAAAAAwUAAAAJYXNzZXQwVXNkCQAAZQAAAAIFAAAABlNjYWxlOAUAAAAHcGVuYWx0eQUAAAAGU2NhbGU4BAAAAAxzQXNzZXRDaGFuZ2UJAABrAAAAAwUAAAAKYXNzZXQwU29sZAUAAAAHU2NhbGUxNgUAAAAFc1JhdGUEAAAADGJBc3NldENoYW5nZQkAAGsAAAADBQAAAAxhc3NldDFCb3VnaHQFAAAAB1NjYWxlMTYFAAAABWJSYXRlAwkAAGYAAAACBQAAAAphc3NldDBTb2xkBQAAAAthc3NldEFtb3VudAkAAAIAAAABAgAAACNtb3JlIGFzc2V0cyBleGNoYW5nZWQgdGhhbiBleHBlY3RlZAMJAABmAAAAAgAAAAAAAAAAAAUAAAARbGlxdWlkYXRpb25Qcm9maXQJAAACAAAAAQIAAAAvcHJpY2UgaW1wYWN0IGlzIGJpZ2dlciB0aGFuIGxpcXVpZGF0aW9uIHBlbmFsdHkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfc3VwcGxpZWRfBQAAAAtzQXNzZXRJZFN0cgkAAGUAAAACBQAAABBjdXJyZW50U1Bvc2l0aW9uBQAAAAxzQXNzZXRDaGFuZ2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAdhZGRyZXNzAgAAAApfYm9ycm93ZWRfBQAAAAtiQXNzZXRJZFN0cgkAAGUAAAACBQAAABBjdXJyZW50QlBvc2l0aW9uBQAAAAxiQXNzZXRDaGFuZ2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgIAAAAPdG90YWxfc3VwcGxpZWRfBQAAAAtzQXNzZXRJZFN0cgkAAGUAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgIAAAAPdG90YWxfc3VwcGxpZWRfBQAAAAtzQXNzZXRJZFN0cgUAAAAMc0Fzc2V0Q2hhbmdlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAICAAAAD3RvdGFsX2JvcnJvd2VkXwUAAAALYkFzc2V0SWRTdHIJAABlAAAAAgkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAICAAAAD3RvdGFsX2JvcnJvd2VkXwUAAAALYkFzc2V0SWRTdHIFAAAADGJBc3NldENoYW5nZQkABEwAAAAC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", "height": 3304728, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: GWoszeizZzbB46BwzBybGu5JPGNtRYsTt2pKVZaQGVgD Next: 657uHgMGi2iki8pkoBtKqrbvMe14xejdB4CfJ5SvZV9M Diff:
OldNewDifferences
124124 }
125125
126126
127-func getTokenPrice (assetIdStr) = {
128- let inv = invoke(addressFromStringValue("3P5BTtdj32Sd1Dyh1Mdw33xQAAckSfMfnKf"), "getTWAP60", [assetIdStr, false], nil)
129- if ((inv == inv))
130- then match inv {
131- case x: (Int, Int) =>
132- x
133- case _ =>
134- throw("error of price oracle")
135- }
127+func getTokenPrice (assetIdStr) = if ((assetIdStr == "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS"))
128+ then $Tuple2(15000000, 15000000)
129+ else if ((assetIdStr == "WAVES"))
130+ then $Tuple2(5000000, 5000000)
131+ else if ((assetIdStr == "Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5"))
132+ then $Tuple2(2000000, 2000000)
133+ else if ((assetIdStr == "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"))
134+ then $Tuple2(1000000, 1000000)
135+ else if ((assetIdStr == "6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ"))
136+ then $Tuple2(1000000, 1000000)
137+ else $Tuple2(950000, 950000)
138+
139+
140+func calcAssetScale (assetIdStr) = {
141+ let decimals = if ((assetIdStr == "WAVES"))
142+ then 8
143+ else value(assetInfo(fromBase58String(assetIdStr))).decimals
144+ pow(10, 0, decimals, 0, 0, DOWN)
145+ }
146+
147+
148+func calcUserCollateral (address) = {
149+ let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true], nil)
150+ if ((userCollateralInvoke == userCollateralInvoke))
151+ then {
152+ let userCollateralValue = match userCollateralInvoke {
153+ case x: Int =>
154+ x
155+ case _ =>
156+ throw("issue while doing in-dapp invocation")
157+ }
158+ if ((userCollateralValue == userCollateralValue))
159+ then userCollateralValue
160+ else throw("Strict value is not equal to itself.")
161+ }
136162 else throw("Strict value is not equal to itself.")
137163 }
138164
139165
140166 @Callable(i)
141-func preInit (tokens,ltvs,dailyPercent) = {
167+func preInit (tokens,ltvs,lts,penalties,dailyPercent) = {
142168 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
143169
144170 let rates = {
155181
156182 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
157183 }
158- ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), IntegerEntry("setup_interest", dailyPercent), BooleanEntry("setup_active", true)] ++ rates)
184+ ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), IntegerEntry("setup_interest", dailyPercent), BooleanEntry("setup_active", true)] ++ rates)
159185 }
160186
161187
170196 else {
171197 let assetIdStr = getAssetString(i.payments[0].assetId)
172198 let assetAmount = i.payments[0].amount
173- let $t045084575 = getActualRate(assetIdStr, "sRate")
174- let sRate = $t045084575._1
175- let ratesRecalcResult = $t045084575._2
199+ let $t051525219 = getActualRate(assetIdStr, "sRate")
200+ let sRate = $t051525219._1
201+ let ratesRecalcResult = $t051525219._2
176202 let amount = fraction(assetAmount, Scale16, sRate)
177203 let address = toString(i.caller)
178204 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
184210
185211 @Callable(i)
186212 func withdraw (assetIdStr,assetAmount) = {
187- let $t051395206 = getActualRate(assetIdStr, "sRate")
188- let sRate = $t051395206._1
189- let ratesRecalcResult = $t051395206._2
213+ let $t057835850 = getActualRate(assetIdStr, "sRate")
214+ let sRate = $t057835850._1
215+ let ratesRecalcResult = $t057835850._2
190216 let amount = fraction(assetAmount, Scale16, sRate)
191217 let address = toString(i.caller)
192218 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
207233 @Callable(i)
208234 func borrow (assetIdStr,assetAmount) = {
209235 let address = toString(i.caller)
210- let $t063516418 = getActualRate(assetIdStr, "bRate")
211- let bRate = $t063516418._1
212- let ratesRecalcResult = $t063516418._2
236+ let $t069957062 = getActualRate(assetIdStr, "bRate")
237+ let bRate = $t069957062._1
238+ let ratesRecalcResult = $t069957062._2
213239 let amount = fraction(assetAmount, Scale16, bRate)
214240 let price = getTokenPrice(assetIdStr)._2
215- let decimals = if ((assetIdStr == "WAVES"))
216- then 8
217- else value(assetInfo(fromBase58String(assetIdStr))).decimals
218- let assetScale = pow(10, 0, decimals, 0, 0, DOWN)
241+ let assetScale = calcAssetScale(assetIdStr)
219242 let usdEquivalent = fraction(amount, price, assetScale)
220243 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true], nil)
221244 if ((collateralValueInv == collateralValueInv))
252275 else {
253276 let assetIdStr = getAssetString(i.payments[0].assetId)
254277 let assetAmount = i.payments[0].amount
255- let $t079898056 = getActualRate(assetIdStr, "bRate")
256- let bRate = $t079898056._1
257- let ratesRecalcResult = $t079898056._2
278+ let $t085098576 = getActualRate(assetIdStr, "bRate")
279+ let bRate = $t085098576._1
280+ let ratesRecalcResult = $t085098576._2
258281 let amount = fraction(assetAmount, Scale16, bRate)
259282 let address = toString(i.caller)
260283 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
310333
311334 @Callable(i)
312335 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = {
313- let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true], nil)
314- if ((userCollateralInvoke == userCollateralInvoke))
336+ let userCollateral = calcUserCollateral(address)
337+ if ((userCollateral == userCollateral))
315338 then {
316- let userCollateralValue = match userCollateralInvoke {
317- case x: Int =>
318- x
319- case _ =>
320- throw("issue while doing in-dapp invocation")
321- }
322- if ((userCollateralValue == userCollateralValue))
323- then {
324- let $t01037110440 = getActualRate(sAssetIdStr, "sRate")
325- let sRate = $t01037110440._1
326- let ratesRecalcResult1 = $t01037110440._2
327- let $t01044310512 = getActualRate(bAssetIdStr, "bRate")
328- let bRate = $t01044310512._1
329- let ratesRecalcResult2 = $t01044310512._2
330- let sAssetAmount = fraction(assetAmount, Scale16, sRate)
331- let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
332- let currentBPosition = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
333- if ((userCollateralValue > 0))
334- then throw("user can't be liquidated")
335- else if ((sAssetAmount > currentSPosition))
336- then throw("position to liquidate is bigger than user's supply")
337- else {
338- let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
339- let balance0Before = getBalance(sAssetIdStr)
340- if ((balance0Before == balance0Before))
339+ let $t01070610775 = getActualRate(sAssetIdStr, "sRate")
340+ let sRate = $t01070610775._1
341+ let ratesRecalcResult1 = $t01070610775._2
342+ let $t01077810847 = getActualRate(bAssetIdStr, "bRate")
343+ let bRate = $t01077810847._1
344+ let ratesRecalcResult2 = $t01077810847._2
345+ let sAssetAmount = fraction(assetAmount, Scale16, sRate)
346+ let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
347+ let currentBPosition = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
348+ if ((userCollateral > 0))
349+ then throw("user can't be liquidated")
350+ else if ((sAssetAmount > currentSPosition))
351+ then throw("position to liquidate is bigger than user's supply")
352+ else {
353+ let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
354+ let balance0Before = getBalance(sAssetIdStr)
355+ if ((balance0Before == balance0Before))
356+ then {
357+ let balance1Before = getBalance(bAssetIdStr)
358+ if ((balance1Before == balance1Before))
341359 then {
342- let balance1Before = getBalance(bAssetIdStr)
343- if ((balance1Before == balance1Before))
360+ let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
361+ if ((exchangeInvoke == exchangeInvoke))
344362 then {
345- let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
346- if ((exchangeInvoke == exchangeInvoke))
363+ let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
364+ if ((asset0Sold == asset0Sold))
347365 then {
348- let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
349- if ((asset0Sold == asset0Sold))
366+ let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
367+ if ((asset1Bought == asset1Bought))
350368 then {
351- let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
352- if ((asset1Bought == asset1Bought))
353- then {
354- let sAssetChange = fraction(asset0Sold, Scale16, sRate)
355- let bAssetChange = fraction(asset1Bought, Scale16, bRate)
356- if ((asset0Sold > assetAmount))
357- then throw("more assets exchanged than expected")
358- else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange))]
359- }
360- else throw("Strict value is not equal to itself.")
369+ let asset0Price = getTokenPrice(sAssetIdStr)._2
370+ let asset0Scale = calcAssetScale(sAssetIdStr)
371+ let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
372+ let asset1Price = getTokenPrice(bAssetIdStr)._1
373+ let asset1Scale = calcAssetScale(bAssetIdStr)
374+ let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
375+ let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
376+ let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
377+ let sAssetChange = fraction(asset0Sold, Scale16, sRate)
378+ let bAssetChange = fraction(asset1Bought, Scale16, bRate)
379+ if ((asset0Sold > assetAmount))
380+ then throw("more assets exchanged than expected")
381+ else if ((0 > liquidationProfit))
382+ then throw("price impact is bigger than liquidation penalty")
383+ else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange)), ScriptTransfer(i.caller, liquidationProfit, getAssetBytes(bAssetIdStr))]
361384 }
362385 else throw("Strict value is not equal to itself.")
363386 }
367390 }
368391 else throw("Strict value is not equal to itself.")
369392 }
370- }
371- else throw("Strict value is not equal to itself.")
393+ else throw("Strict value is not equal to itself.")
394+ }
372395 }
373396 else throw("Strict value is not equal to itself.")
374397 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let Scale8 = 100000000
55
66 let Scale10 = 10000000000
77
88 let Scale16 = (Scale8 * Scale8)
99
1010 let dayBlocks = 1440
1111
1212 func tryGetInteger (key) = match getInteger(this, key) {
1313 case b: Int =>
1414 b
1515 case _ =>
1616 0
1717 }
1818
1919
2020 func tryGetBoolean (key) = match getBoolean(this, key) {
2121 case b: Boolean =>
2222 b
2323 case _ =>
2424 false
2525 }
2626
2727
2828 func tryGetString (key) = match getString(this, key) {
2929 case b: String =>
3030 b
3131 case _ =>
3232 ""
3333 }
3434
3535
3636 func getAssetString (assetId) = match assetId {
3737 case b: ByteVector =>
3838 toBase58String(b)
3939 case _ =>
4040 "WAVES"
4141 }
4242
4343
4444 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
4545 then unit
4646 else fromBase58String(assetIdStr)
4747
4848
4949 func getBalance (assetIdStr) = if ((assetIdStr == "WAVES"))
5050 then wavesBalance(this).available
5151 else assetBalance(this, fromBase58String(assetIdStr))
5252
5353
5454 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
5555
5656
5757 func getUr (assetIdStr) = {
5858 let down = max([fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16), Scale8])
5959 fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down)
6060 }
6161
6262
6363 func getInterest (assetIdStr) = {
6464 let ur = getUr(assetIdStr)
6565 let dailyInterest = if ((80000000 >= ur))
6666 then fraction(ur, 54794, 80000000)
6767 else (54794 + fraction((ur - 80000000), 54794, 20000000))
6868 max([(fraction(dailyInterest, ur, dayBlocks) / Scale8), 1])
6969 }
7070
7171
7272 func tokenRatesRecalc (assetIdStr) = {
7373 let interest = getInterest(assetIdStr)
7474 let ur = getUr(assetIdStr)
7575 let lastRecalcHeight = tryGetInteger("lastRateHeight")
7676 let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16])
7777 let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest))
7878 let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16])
7979 let newSRate = (lastSRate + ((height - lastRecalcHeight) * fraction(interest, ur, Scale8)))
8080 [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)]
8181 }
8282
8383
8484 func getActualRate (assetIdStr,rateType) = {
8585 func f (accum,token) = {
8686 let recalc = tokenRatesRecalc(token)
8787 $Tuple2(if ((token != assetIdStr))
8888 then accum._1
8989 else if ((rateType == "sRate"))
9090 then recalc[0].value
9191 else recalc[1].value, (accum._2 ++ recalc))
9292 }
9393
9494 let $l = getMarketAssets()
9595 let $s = size($l)
9696 let $acc0 = $Tuple2(0, nil)
9797 func $f0_1 ($a,$i) = if (($i >= $s))
9898 then $a
9999 else f($a, $l[$i])
100100
101101 func $f0_2 ($a,$i) = if (($i >= $s))
102102 then $a
103103 else throw("List size exceeds 6")
104104
105105 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
106106 }
107107
108108
109109 func ratesRecalc () = {
110110 func f (accum,token) = (accum ++ tokenRatesRecalc(token))
111111
112112 let $l = getMarketAssets()
113113 let $s = size($l)
114114 let $acc0 = nil
115115 func $f0_1 ($a,$i) = if (($i >= $s))
116116 then $a
117117 else f($a, $l[$i])
118118
119119 func $f0_2 ($a,$i) = if (($i >= $s))
120120 then $a
121121 else throw("List size exceeds 6")
122122
123123 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
124124 }
125125
126126
127-func getTokenPrice (assetIdStr) = {
128- let inv = invoke(addressFromStringValue("3P5BTtdj32Sd1Dyh1Mdw33xQAAckSfMfnKf"), "getTWAP60", [assetIdStr, false], nil)
129- if ((inv == inv))
130- then match inv {
131- case x: (Int, Int) =>
132- x
133- case _ =>
134- throw("error of price oracle")
135- }
127+func getTokenPrice (assetIdStr) = if ((assetIdStr == "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS"))
128+ then $Tuple2(15000000, 15000000)
129+ else if ((assetIdStr == "WAVES"))
130+ then $Tuple2(5000000, 5000000)
131+ else if ((assetIdStr == "Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5"))
132+ then $Tuple2(2000000, 2000000)
133+ else if ((assetIdStr == "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"))
134+ then $Tuple2(1000000, 1000000)
135+ else if ((assetIdStr == "6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ"))
136+ then $Tuple2(1000000, 1000000)
137+ else $Tuple2(950000, 950000)
138+
139+
140+func calcAssetScale (assetIdStr) = {
141+ let decimals = if ((assetIdStr == "WAVES"))
142+ then 8
143+ else value(assetInfo(fromBase58String(assetIdStr))).decimals
144+ pow(10, 0, decimals, 0, 0, DOWN)
145+ }
146+
147+
148+func calcUserCollateral (address) = {
149+ let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true], nil)
150+ if ((userCollateralInvoke == userCollateralInvoke))
151+ then {
152+ let userCollateralValue = match userCollateralInvoke {
153+ case x: Int =>
154+ x
155+ case _ =>
156+ throw("issue while doing in-dapp invocation")
157+ }
158+ if ((userCollateralValue == userCollateralValue))
159+ then userCollateralValue
160+ else throw("Strict value is not equal to itself.")
161+ }
136162 else throw("Strict value is not equal to itself.")
137163 }
138164
139165
140166 @Callable(i)
141-func preInit (tokens,ltvs,dailyPercent) = {
167+func preInit (tokens,ltvs,lts,penalties,dailyPercent) = {
142168 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
143169
144170 let rates = {
145171 let $l = split(tokens, ",")
146172 let $s = size($l)
147173 let $acc0 = nil
148174 func $f0_1 ($a,$i) = if (($i >= $s))
149175 then $a
150176 else f($a, $l[$i])
151177
152178 func $f0_2 ($a,$i) = if (($i >= $s))
153179 then $a
154180 else throw("List size exceeds 6")
155181
156182 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
157183 }
158- ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), IntegerEntry("setup_interest", dailyPercent), BooleanEntry("setup_active", true)] ++ rates)
184+ ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), IntegerEntry("setup_interest", dailyPercent), BooleanEntry("setup_active", true)] ++ rates)
159185 }
160186
161187
162188
163189 @Callable(i)
164190 func supply () = if (!(tryGetBoolean("setup_active")))
165191 then throw("market is stopped")
166192 else if (if ((size(i.payments) != 1))
167193 then true
168194 else (i.payments[0].amount == 0))
169195 then throw("1 payment has to be attached")
170196 else {
171197 let assetIdStr = getAssetString(i.payments[0].assetId)
172198 let assetAmount = i.payments[0].amount
173- let $t045084575 = getActualRate(assetIdStr, "sRate")
174- let sRate = $t045084575._1
175- let ratesRecalcResult = $t045084575._2
199+ let $t051525219 = getActualRate(assetIdStr, "sRate")
200+ let sRate = $t051525219._1
201+ let ratesRecalcResult = $t051525219._2
176202 let amount = fraction(assetAmount, Scale16, sRate)
177203 let address = toString(i.caller)
178204 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
179205 then throw("this asset is not supported by the market")
180206 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
181207 }
182208
183209
184210
185211 @Callable(i)
186212 func withdraw (assetIdStr,assetAmount) = {
187- let $t051395206 = getActualRate(assetIdStr, "sRate")
188- let sRate = $t051395206._1
189- let ratesRecalcResult = $t051395206._2
213+ let $t057835850 = getActualRate(assetIdStr, "sRate")
214+ let sRate = $t057835850._1
215+ let ratesRecalcResult = $t057835850._2
190216 let amount = fraction(assetAmount, Scale16, sRate)
191217 let address = toString(i.caller)
192218 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
193219 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
194220 let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
195221 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
196222 if (!(tryGetBoolean("setup_active")))
197223 then throw("market is stopped")
198224 else if ((amount > (assetSupplied - assetBorrowed)))
199225 then throw("this amount is not available on the market")
200226 else if ((amount > (userAssetSupplied - userAssetBorrowed)))
201227 then throw("this amount is not available for this user")
202228 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) - amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) - amount)), ScriptTransfer(i.caller, amount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
203229 }
204230
205231
206232
207233 @Callable(i)
208234 func borrow (assetIdStr,assetAmount) = {
209235 let address = toString(i.caller)
210- let $t063516418 = getActualRate(assetIdStr, "bRate")
211- let bRate = $t063516418._1
212- let ratesRecalcResult = $t063516418._2
236+ let $t069957062 = getActualRate(assetIdStr, "bRate")
237+ let bRate = $t069957062._1
238+ let ratesRecalcResult = $t069957062._2
213239 let amount = fraction(assetAmount, Scale16, bRate)
214240 let price = getTokenPrice(assetIdStr)._2
215- let decimals = if ((assetIdStr == "WAVES"))
216- then 8
217- else value(assetInfo(fromBase58String(assetIdStr))).decimals
218- let assetScale = pow(10, 0, decimals, 0, 0, DOWN)
241+ let assetScale = calcAssetScale(assetIdStr)
219242 let usdEquivalent = fraction(amount, price, assetScale)
220243 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true], nil)
221244 if ((collateralValueInv == collateralValueInv))
222245 then {
223246 let collateralValue = match collateralValueInv {
224247 case x: Int =>
225248 x
226249 case _ =>
227250 throw("can't get user collateral value")
228251 }
229252 if ((usdEquivalent > collateralValue))
230253 then throw("you have to supply more to borrow")
231254 else {
232255 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
233256 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
234257 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
235258 if ((amount > (assetSupplied - assetBorrowed)))
236259 then throw("this amount is not available")
237260 else ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, amount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
238261 }
239262 }
240263 else throw("Strict value is not equal to itself.")
241264 }
242265
243266
244267
245268 @Callable(i)
246269 func repay () = if (!(tryGetBoolean("setup_active")))
247270 then throw("market is stopped")
248271 else if (if ((size(i.payments) != 1))
249272 then true
250273 else (i.payments[0].amount == 0))
251274 then throw("1 payment has to be attached")
252275 else {
253276 let assetIdStr = getAssetString(i.payments[0].assetId)
254277 let assetAmount = i.payments[0].amount
255- let $t079898056 = getActualRate(assetIdStr, "bRate")
256- let bRate = $t079898056._1
257- let ratesRecalcResult = $t079898056._2
278+ let $t085098576 = getActualRate(assetIdStr, "bRate")
279+ let bRate = $t085098576._1
280+ let ratesRecalcResult = $t085098576._2
258281 let amount = fraction(assetAmount, Scale16, bRate)
259282 let address = toString(i.caller)
260283 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
261284 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
262285 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
263286 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
264287 then throw("this asset is not supported by the market")
265288 else if ((amount > userAssetBorrowed))
266289 then throw("payed amount is bigger than user's borrowed amount")
267290 else ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - amount))] ++ ratesRecalcResult)
268291 }
269292
270293
271294
272295 @Callable(i)
273296 func getUserCollateral (debug,address,minusBorrowed) = {
274297 let assets = getMarketAssets()
275298 let ltvs = split(tryGetString("setup_ltvs"), ",")
276299 let rates = getActualRate(assets[0], "sRate")._2
277300 func f (accum,next) = if ((next >= size(assets)))
278301 then accum
279302 else {
280303 let decimals = if ((assets[next] == "WAVES"))
281304 then 8
282305 else value(assetInfo(fromBase58String(assets[next]))).decimals
283306 let assetScale = pow(10, 0, decimals, 0, 0, DOWN)
284307 let assetPrice = getTokenPrice(assets[next])
285308 ((accum + fraction(fraction(fraction(tryGetInteger(((address + "_supplied_") + assets[next])), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
286309 then fraction(fraction(tryGetInteger(((address + "_borrowed_") + assets[next])), rates[((next * 3) + 1)].value, Scale16), assetPrice._2, assetScale)
287310 else 0))
288311 }
289312
290313 let result = {
291314 let $l = [0, 1, 2, 3, 4, 5]
292315 let $s = size($l)
293316 let $acc0 = 0
294317 func $f0_1 ($a,$i) = if (($i >= $s))
295318 then $a
296319 else f($a, $l[$i])
297320
298321 func $f0_2 ($a,$i) = if (($i >= $s))
299322 then $a
300323 else throw("List size exceeds 6")
301324
302325 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
303326 }
304327 if (debug)
305328 then throw(toString(result))
306329 else $Tuple2(rates, result)
307330 }
308331
309332
310333
311334 @Callable(i)
312335 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = {
313- let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true], nil)
314- if ((userCollateralInvoke == userCollateralInvoke))
336+ let userCollateral = calcUserCollateral(address)
337+ if ((userCollateral == userCollateral))
315338 then {
316- let userCollateralValue = match userCollateralInvoke {
317- case x: Int =>
318- x
319- case _ =>
320- throw("issue while doing in-dapp invocation")
321- }
322- if ((userCollateralValue == userCollateralValue))
323- then {
324- let $t01037110440 = getActualRate(sAssetIdStr, "sRate")
325- let sRate = $t01037110440._1
326- let ratesRecalcResult1 = $t01037110440._2
327- let $t01044310512 = getActualRate(bAssetIdStr, "bRate")
328- let bRate = $t01044310512._1
329- let ratesRecalcResult2 = $t01044310512._2
330- let sAssetAmount = fraction(assetAmount, Scale16, sRate)
331- let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
332- let currentBPosition = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
333- if ((userCollateralValue > 0))
334- then throw("user can't be liquidated")
335- else if ((sAssetAmount > currentSPosition))
336- then throw("position to liquidate is bigger than user's supply")
337- else {
338- let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
339- let balance0Before = getBalance(sAssetIdStr)
340- if ((balance0Before == balance0Before))
339+ let $t01070610775 = getActualRate(sAssetIdStr, "sRate")
340+ let sRate = $t01070610775._1
341+ let ratesRecalcResult1 = $t01070610775._2
342+ let $t01077810847 = getActualRate(bAssetIdStr, "bRate")
343+ let bRate = $t01077810847._1
344+ let ratesRecalcResult2 = $t01077810847._2
345+ let sAssetAmount = fraction(assetAmount, Scale16, sRate)
346+ let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
347+ let currentBPosition = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
348+ if ((userCollateral > 0))
349+ then throw("user can't be liquidated")
350+ else if ((sAssetAmount > currentSPosition))
351+ then throw("position to liquidate is bigger than user's supply")
352+ else {
353+ let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
354+ let balance0Before = getBalance(sAssetIdStr)
355+ if ((balance0Before == balance0Before))
356+ then {
357+ let balance1Before = getBalance(bAssetIdStr)
358+ if ((balance1Before == balance1Before))
341359 then {
342- let balance1Before = getBalance(bAssetIdStr)
343- if ((balance1Before == balance1Before))
360+ let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
361+ if ((exchangeInvoke == exchangeInvoke))
344362 then {
345- let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
346- if ((exchangeInvoke == exchangeInvoke))
363+ let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
364+ if ((asset0Sold == asset0Sold))
347365 then {
348- let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
349- if ((asset0Sold == asset0Sold))
366+ let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
367+ if ((asset1Bought == asset1Bought))
350368 then {
351- let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
352- if ((asset1Bought == asset1Bought))
353- then {
354- let sAssetChange = fraction(asset0Sold, Scale16, sRate)
355- let bAssetChange = fraction(asset1Bought, Scale16, bRate)
356- if ((asset0Sold > assetAmount))
357- then throw("more assets exchanged than expected")
358- else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange))]
359- }
360- else throw("Strict value is not equal to itself.")
369+ let asset0Price = getTokenPrice(sAssetIdStr)._2
370+ let asset0Scale = calcAssetScale(sAssetIdStr)
371+ let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
372+ let asset1Price = getTokenPrice(bAssetIdStr)._1
373+ let asset1Scale = calcAssetScale(bAssetIdStr)
374+ let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
375+ let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
376+ let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
377+ let sAssetChange = fraction(asset0Sold, Scale16, sRate)
378+ let bAssetChange = fraction(asset1Bought, Scale16, bRate)
379+ if ((asset0Sold > assetAmount))
380+ then throw("more assets exchanged than expected")
381+ else if ((0 > liquidationProfit))
382+ then throw("price impact is bigger than liquidation penalty")
383+ else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange)), ScriptTransfer(i.caller, liquidationProfit, getAssetBytes(bAssetIdStr))]
361384 }
362385 else throw("Strict value is not equal to itself.")
363386 }
364387 else throw("Strict value is not equal to itself.")
365388 }
366389 else throw("Strict value is not equal to itself.")
367390 }
368391 else throw("Strict value is not equal to itself.")
369392 }
370- }
371- else throw("Strict value is not equal to itself.")
393+ else throw("Strict value is not equal to itself.")
394+ }
372395 }
373396 else throw("Strict value is not equal to itself.")
374397 }
375398
376399
377400
378401 @Callable(i)
379402 func getPrices (debug) = {
380403 let assets = getMarketAssets()
381404 func f (accum,next) = if ((next >= size(assets)))
382405 then accum
383406 else {
384407 let assetPrice = getTokenPrice(assets[next])
385408 ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|")
386409 }
387410
388411 let result = {
389412 let $l = [0, 1, 2, 3, 4, 5]
390413 let $s = size($l)
391414 let $acc0 = ""
392415 func $f0_1 ($a,$i) = if (($i >= $s))
393416 then $a
394417 else f($a, $l[$i])
395418
396419 func $f0_2 ($a,$i) = if (($i >= $s))
397420 then $a
398421 else throw("List size exceeds 6")
399422
400423 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
401424 }
402425 if (debug)
403426 then throw(result)
404427 else $Tuple2(nil, result)
405428 }
406429
407430
408431
409432 @Callable(i)
410433 func calculateUtilizationRatio (assetIdStr,debug) = if (debug)
411434 then throw(toString(getUr(assetIdStr)))
412435 else $Tuple2(nil, getUr(assetIdStr))
413436
414437
415438
416439 @Callable(i)
417440 func calculateTokenRates (debug) = {
418441 func f (accum,assetIdStr) = {
419442 let rates = tokenRatesRecalc(assetIdStr)
420443 ((((accum + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ",")
421444 }
422445
423446 let parameter = {
424447 let $l = getMarketAssets()
425448 let $s = size($l)
426449 let $acc0 = ""
427450 func $f0_1 ($a,$i) = if (($i >= $s))
428451 then $a
429452 else f($a, $l[$i])
430453
431454 func $f0_2 ($a,$i) = if (($i >= $s))
432455 then $a
433456 else throw("List size exceeds 6")
434457
435458 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
436459 }
437460 if (debug)
438461 then throw(parameter)
439462 else $Tuple2(nil, parameter)
440463 }
441464
442465
443466
444467 @Callable(i)
445468 func calculateTokensInterest (debug) = {
446469 let dailyInterest = tryGetInteger("setup_interest")
447470 func f (accum,assetIdStr) = {
448471 let ur = getUr(assetIdStr)
449472 let rate = max([fraction(dailyInterest, ur, Scale8), dayBlocks])
450473 ((accum + toString(rate)) + ",")
451474 }
452475
453476 let parameter = {
454477 let $l = getMarketAssets()
455478 let $s = size($l)
456479 let $acc0 = ""
457480 func $f0_1 ($a,$i) = if (($i >= $s))
458481 then $a
459482 else f($a, $l[$i])
460483
461484 func $f0_2 ($a,$i) = if (($i >= $s))
462485 then $a
463486 else throw("List size exceeds 6")
464487
465488 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
466489 }
467490 if (debug)
468491 then throw(parameter)
469492 else $Tuple2(nil, parameter)
470493 }
471494
472495
473496 @Verifier(tx)
474497 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
475498

github/deemru/w8io/786bc32 
82.28 ms