tx · Fc62ZY3vCzp7oKtUmhfxGcjScDeUYS4dB8cKmAHd8J9p

3PG2vMhK5CPqsCDodvLGzQ84QkoHXCJ3oNP:  -0.14000000 Waves

2020.07.16 12:19 [2153059] smart account 3PG2vMhK5CPqsCDodvLGzQ84QkoHXCJ3oNP > SELF 0.00000000 Waves

{ "type": 13, "id": "Fc62ZY3vCzp7oKtUmhfxGcjScDeUYS4dB8cKmAHd8J9p", "fee": 14000000, "feeAssetId": null, "timestamp": 1594887078061, "version": 1, "sender": "3PG2vMhK5CPqsCDodvLGzQ84QkoHXCJ3oNP", "senderPublicKey": "5RM3w4ysmDbtgfswnVNPx7DQkNwVAG3RoxNFHgt6ToNU", "proofs": [ "", "39kEHZeVzcBcMeLy6d8NaBHyBz3s5VvGSreCBzNQBfoxpDf6ZnH5bfBzWMaWoawY71RLieAu8NsfBBUFCy3Eyw5x", "", "2GJGF4KuQ69WWB6wdxGTg5bxPR28KL8YBxverSGcL6iiZ1SC8JXnSsQ6nq7xZR6DF5qXeNKiPaLgpmKa3Gu9Y7PU" ], "script": "base64:AAIDAAAAAAAAABQIARIDCgEBEgQKAgEIEgMKAQgSAAAAADcBAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAABAAAADmdldFN0cmluZ0J5S2V5AAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWECAAAAAAEAAAAWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkEAAAAByRtYXRjaDAJAAQbAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAdCb29sZWFuBAAAAAFhBQAAAAckbWF0Y2gwBQAAAAFhBwEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFhBQAAAAckbWF0Y2gwBQAAAAFhAAAAAAAAAAAAAAAAAAdXQVZFTEVUAAAAAAAF9eEAAAAAAAVQQVVMSQAAAAAAAA9CQAAAAAAIUFJJQ0VMRVQAAAAAAAAPQkAAAAAADU1JTk9SREVSVE9UQUwJAABoAAAAAgAAAAAAAAAACgUAAAAHV0FWRUxFVAAAAAAGTUFYUk9JAAAAAAAAAABfAAAAAAhDQU5DRUxFRAIAAAAIY2FuY2VsZWQAAAAAA05FVwIAAAADbmV3AAAAAAZGSUxMRUQCAAAABmZpbGxlZAAAAAAIUHJpY2VLZXkCAAAABXByaWNlAAAAAA5Cb25kQXNzZXRJZEtleQIAAAANYm9uZF9hc3NldF9pZAAAAAASTmV1dHJpbm9Bc3NldElkS2V5AgAAABFuZXV0cmlub19hc3NldF9pZAAAAAARQmFsYW5jZUxvY2tlZGtLZXkCAAAADWJhbGFuY2VfbG9ja18AAAAAFVdhdmVzTG9ja2VkQmFsYW5jZUtleQkAASwAAAACBQAAABFCYWxhbmNlTG9ja2Vka0tleQIAAAAFd2F2ZXMAAAAAGE5ldXRyaW5vTG9ja2VkQmFsYW5jZUtleQkAASwAAAACBQAAABFCYWxhbmNlTG9ja2Vka0tleQIAAAAIbmV1dHJpbm8AAAAADUZpcnN0T3JkZXJLZXkCAAAAC29yZGVyX2ZpcnN0AQAAABJnZXRSb2lCeU9yZGVySWRLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAAQZGVidWdfb3JkZXJfcm9pXwUAAAAHb3JkZXJJZAEAAAAQZ2V0T3JkZXJQcmljZUtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAAxvcmRlcl9wcmljZV8FAAAAB29yZGVySWQBAAAAEGdldE9yZGVyVG90YWxLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAAMb3JkZXJfdG90YWxfBQAAAAdvcmRlcklkAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAADG9yZGVyX293bmVyXwUAAAAHb3JkZXJJZAEAAAARZ2V0T3JkZXJIZWlnaHRLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAANb3JkZXJfaGVpZ2h0XwUAAAAHb3JkZXJJZAEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAANb3JkZXJfc3RhdHVzXwUAAAAHb3JkZXJJZAEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAABNvcmRlcl9maWxsZWRfdG90YWxfBQAAAAdvcmRlcklkAQAAAA9nZXRQcmV2T3JkZXJLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAALb3JkZXJfcHJldl8FAAAAB29yZGVySWQBAAAAD2dldE5leHRPcmRlcktleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAAtvcmRlcl9uZXh0XwUAAAAHb3JkZXJJZAEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAIAAAAGYW1vdW50AAAABXByaWNlCQAAawAAAAMJAABrAAAAAwUAAAAGYW1vdW50BQAAAAhQUklDRUxFVAUAAAAFcHJpY2UFAAAAB1dBVkVMRVQFAAAABVBBVUxJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgAAAAZhbW91bnQAAAAFcHJpY2UJAABrAAAAAwkAAGsAAAADBQAAAAZhbW91bnQFAAAABXByaWNlBQAAAAhQUklDRUxFVAUAAAAFUEFVTEkFAAAAB1dBVkVMRVQBAAAAEmNvbnZlcnRXYXZlc1RvQm9uZAAAAAIAAAAGYW1vdW50AAAABXByaWNlCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAABmFtb3VudAUAAAAFcHJpY2UBAAAAEmNvbnZlcnRCb25kVG9XYXZlcwAAAAIAAAAGYW1vdW50AAAABXByaWNlCQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAIFAAAABmFtb3VudAUAAAAFcHJpY2UAAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVdwBGKmR5vprVZolMvvhYwwgiAomggUlrIAAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAB0FkZHJlc3MAAAABAQAAABoBVyOzrRJck6TK7Dn+T0bWzVZNLfsQ+2OYegAAAAATbGlxdWlkYXRpb25Db250cmFjdAkBAAAAB0FkZHJlc3MAAAABAQAAABoBVxrqScv6Cn7KCH8o1Z+Vjgx7abWpOJEfSAAAAAAPbmV1dHJpbm9Bc3NldElkAQAAACC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QAAAAALYm9uZEFzc2V0SWQBAAAAIFXuw76qC/BQ6HHIG6pucJ6kscj+Si65wfHMxWsPeJdLAAAAAAlpc0Jsb2NrZWQJAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0AgAAAAppc19ibG9ja2VkAAAAAAxjdXJyZW50UHJpY2UJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAACFByaWNlS2V5AAAAABVuZXV0cmlub0xvY2tlZEJhbGFuY2UJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAABBuZXV0cmlub0NvbnRyYWN0BQAAABhOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkAAAAAB3Jlc2VydmUJAABlAAAAAgkBAAAADHdhdmVzQmFsYW5jZQAAAAEFAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAABBuZXV0cmlub0NvbnRyYWN0BQAAABVXYXZlc0xvY2tlZEJhbGFuY2VLZXkAAAAADm5ldXRyaW5vU3VwcGx5CQAAZQAAAAIJAABlAAAAAgkAAGQAAAACBQAAABVuZXV0cmlub0xvY2tlZEJhbGFuY2UICQEAAAAHZXh0cmFjdAAAAAEJAAPsAAAAAQUAAAAPbmV1dHJpbm9Bc3NldElkAAAACHF1YW50aXR5CQAD6wAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAAD25ldXRyaW5vQXNzZXRJZAkAA+sAAAACBQAAABNsaXF1aWRhdGlvbkNvbnRyYWN0BQAAAA9uZXV0cmlub0Fzc2V0SWQAAAAAB2RlZmljaXQJAABlAAAAAgUAAAAObmV1dHJpbm9TdXBwbHkJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAHcmVzZXJ2ZQUAAAAMY3VycmVudFByaWNlAAAAAApmaXJzdE9yZGVyCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA1GaXJzdE9yZGVyS2V5AQAAAA1nZXRPcmRlclByaWNlAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEGdldE9yZGVyUHJpY2VLZXkAAAABBQAAAAJpZAEAAAANZ2V0T3JkZXJUb3RhbAAAAAEAAAACaWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAACaWQBAAAADWdldE9yZGVyT3duZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEFAAAAAmlkAQAAAA5nZXRPcmRlclN0YXR1cwAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAAmlkAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABBQAAAAJpZAEAAAAMZ2V0UHJldk9yZGVyAAAAAQAAAAJpZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAD2dldFByZXZPcmRlcktleQAAAAEFAAAAAmlkAQAAAAxnZXROZXh0T3JkZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAPZ2V0TmV4dE9yZGVyS2V5AAAAAQUAAAACaWQBAAAACW9yZGVyRGF0YQAAAAYAAAAHb3JkZXJJZAAAAA10b3RhbFdhdmVsZXRzAAAABW93bmVyAAAABnN0YXR1cwAAAANyb2kAAAAFcHJpY2UJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABBnZXRPcmRlclByaWNlS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAAFcHJpY2UJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAANdG90YWxXYXZlbGV0cwkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAEGdldE9yZGVyT3duZXJLZXkAAAABBQAAAAdvcmRlcklkBQAAAAVvd25lcgkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAEWdldE9yZGVySGVpZ2h0S2V5AAAAAQUAAAAHb3JkZXJJZAUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAdvcmRlcklkBQAAAAZzdGF0dXMJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAAEsAAAAAgIAAAAZZGVidWdfb3JkZXJfY3VycmVudFByaWNlXwUAAAAHb3JkZXJJZAUAAAAMY3VycmVudFByaWNlCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAASZ2V0Um9pQnlPcmRlcklkS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAADcm9pBQAAAANuaWwBAAAAEGludGVybmFsU2VsbEJvbmQAAAAJAAAADWN1cnJlbnRNYXhSb2kAAAALcEZpcnN0T3JkZXIAAAAKcE5leHRPcmRlcgAAAAxwRmlsbGVkVG90YWwAAAAEcFJvaQAAAAZwUHJpY2UAAAAQcFBheW1lbnRXYXZlbGV0cwAAABFvcmRlck93bmVyQWRkcmVzcwAAAAxpbnN0YW50T3JkZXIEAAAAFXByaWNlV2F2ZXNCeUJvbmRDZW50cwkAAGsAAAADCQAAZAAAAAIAAAAAAAAAAGQFAAAABHBSb2kFAAAADGN1cnJlbnRQcmljZQAAAAAAAAAAZAQAAAANcmVtYWluZWRUb3RhbAkAAGUAAAACBQAAABBwUGF5bWVudFdhdmVsZXRzBQAAAAxwRmlsbGVkVG90YWwEAAAAE2ZpbGxhYmxlT3JkZXJBbW91bnQJAQAAABJjb252ZXJ0V2F2ZXNUb0JvbmQAAAACBQAAAA1yZW1haW5lZFRvdGFsBQAAABVwcmljZVdhdmVzQnlCb25kQ2VudHMEAAAAG3RvdGFsT3JkZXJXYXZlbGV0ZXNSZXF1aXJlZAkBAAAAEmNvbnZlcnRCb25kVG9XYXZlcwAAAAIFAAAAE2ZpbGxhYmxlT3JkZXJBbW91bnQFAAAAFXByaWNlV2F2ZXNCeUJvbmRDZW50cwQAAAAVbmJUb2tlbnNTZWxsQ29uZGl0aW9uCQAAZwAAAAIFAAAADWN1cnJlbnRNYXhSb2kFAAAABHBSb2kDCQEAAAABIQAAAAEFAAAAFW5iVG9rZW5zU2VsbENvbmRpdGlvbgkAAAIAAAABCQABLAAAAAICAAAAE2lubmFwcm9wcmlhdGUgcm9pOiAJAAGkAAAAAQUAAAAEcFJvaQMJAAAAAAAAAgUAAAAbdG90YWxPcmRlcldhdmVsZXRlc1JlcXVpcmVkAAAAAAAAAAAACQAAAgAAAAECAAAAH2Nhbm5vdCBmaWxsIG9yZGVyIGF0IHRoZSBtb21lbnQEAAAADmNoYW5nZVdhdmVsZXRzCQAAZQAAAAIFAAAADXJlbWFpbmVkVG90YWwFAAAAG3RvdGFsT3JkZXJXYXZlbGV0ZXNSZXF1aXJlZAQAAAAMd3JpdGVTZXREYXRhAwUAAAAMaW5zdGFudE9yZGVyCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAQZ2V0T3JkZXJQcmljZUtleQAAAAEFAAAAC3BGaXJzdE9yZGVyBQAAAAZwUHJpY2UJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAALcEZpcnN0T3JkZXIFAAAAEHBQYXltZW50V2F2ZWxldHMJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQUAAAALcEZpcnN0T3JkZXIJAAJYAAAAAQgFAAAAEW9yZGVyT3duZXJBZGRyZXNzAAAABWJ5dGVzCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJIZWlnaHRLZXkAAAABBQAAAAtwRmlyc3RPcmRlcgUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEFAAAAC3BGaXJzdE9yZGVyCQAAZAAAAAIFAAAADHBGaWxsZWRUb3RhbAUAAAAbdG90YWxPcmRlcldhdmVsZXRlc1JlcXVpcmVkCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAtwRmlyc3RPcmRlcgUAAAAGRklMTEVECQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQABLAAAAAICAAAAGWRlYnVnX29yZGVyX2N1cnJlbnRQcmljZV8FAAAAC3BGaXJzdE9yZGVyBQAAAAxjdXJyZW50UHJpY2UJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABJnZXRSb2lCeU9yZGVySWRLZXkAAAABBQAAAAtwRmlyc3RPcmRlcgUAAAAEcFJvaQUAAAADbmlsCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEFAAAAC3BGaXJzdE9yZGVyCQAAZAAAAAIFAAAADHBGaWxsZWRUb3RhbAUAAAAbdG90YWxPcmRlcldhdmVsZXRlc1JlcXVpcmVkCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAtwRmlyc3RPcmRlcgUAAAAGRklMTEVECQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAQZ2V0T3JkZXJUb3RhbEtleQAAAAEFAAAAC3BGaXJzdE9yZGVyBQAAABBwUGF5bWVudFdhdmVsZXRzCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0UHJldk9yZGVyS2V5AAAAAQUAAAAKcE5leHRPcmRlcgIAAAAACQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAA1GaXJzdE9yZGVyS2V5BQAAAApwTmV4dE9yZGVyBQAAAANuaWwJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABBQAAAAx3cml0ZVNldERhdGEJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAARb3JkZXJPd25lckFkZHJlc3MFAAAAE2ZpbGxhYmxlT3JkZXJBbW91bnQFAAAAC2JvbmRBc3NldElkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAAG3RvdGFsT3JkZXJXYXZlbGV0ZXNSZXF1aXJlZAUAAAAEdW5pdAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAABFvcmRlck93bmVyQWRkcmVzcwUAAAAOY2hhbmdlV2F2ZWxldHMFAAAABHVuaXQFAAAAA25pbAEAAAAXaW50ZXJuYWxBZGRCdXlCb25kT3JkZXIAAAAGAAAADWN1cnJlbnRNYXhSb2kAAAADcm9pAAAABXByaWNlAAAACXByZXZPcmRlcgAAAANpbnYAAAAMaW5zdGFudE9yZGVyBAAAAANwbXQJAQAAAAdleHRyYWN0AAAAAQgFAAAAA2ludgAAAAdwYXltZW50BAAAAApuZXdPcmRlcklkCQACWAAAAAEIBQAAAANpbnYAAAANdHJhbnNhY3Rpb25JZAMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFljb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwMJAABmAAAAAgUAAAANTUlOT1JERVJUT1RBTAgFAAAAA3BtdAAAAAZhbW91bnQJAAACAAAAAQkAASwAAAACAgAAABdtaW4gb3JkZXIgdG90YWwgZXF1YWxzIAkAAaQAAAABBQAAAA1NSU5PUkRFUlRPVEFMAwkAAGYAAAACBQAAAANyb2kFAAAABk1BWFJPSQkAAAIAAAABAgAAABdtYXggc2V0T3JkZXIgUk9JIGlzIDk1JQMDCQAAZgAAAAIFAAAAB2RlZmljaXQAAAAAAAAAAAAJAABmAAAAAgAAAAAAAAAAAAUAAAADcm9pBwkAAAIAAAABAgAAADJjYW4ndCBwbGFjZSBvcmRlciB3aXRoIG5lZ2F0aXZlIHJvaSBkdXJpbmcgZGVmaWNpdAMJAABmAAAAAgkBAAAAAS0AAAABBQAAAAZNQVhST0kFAAAAA3JvaQkAAAIAAAABAgAAABhtaW4gc2V0T3JkZXIgUk9JIGlzIC05NSUDCQAAAAAAAAIFAAAAA3JvaQAAAAAAAAAAAAkAAAIAAAABAgAAABxyb2kgc2hvdWxkIG5vdCBiZSBlcXVhbCB0byAwAwkBAAAACWlzRGVmaW5lZAAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAkAAAIAAAABAgAAABJjYW4gdXNlIHdhdmVzIG9ubHkDCQEAAAACIT0AAAACCQEAAAANZ2V0T3JkZXJPd25lcgAAAAEFAAAACm5ld09yZGVySWQCAAAAAAkAAAIAAAABAgAAAAxvcmRlciBleGlzdHMDAwkBAAAAAiE9AAAAAgUAAAAJcHJldk9yZGVyAgAAAAAJAQAAAAIhPQAAAAIJAQAAAA5nZXRPcmRlclN0YXR1cwAAAAEFAAAACXByZXZPcmRlcgUAAAADTkVXBwkAAAIAAAABAgAAABxwcmV2IG9yZGVyIHN0YXR1cyBpcyBub3QgbmV3BAAAABlpc05ld09yZGVyQXRGaXJzdFBvc2l0aW9uCQAAAAAAAAIFAAAACXByZXZPcmRlcgIAAAAABAAAAAVvd25lcgkABCUAAAABCAUAAAADaW52AAAABmNhbGxlcgQAAAAJbmV4dE9yZGVyAwUAAAAZaXNOZXdPcmRlckF0Rmlyc3RQb3NpdGlvbgUAAAAKZmlyc3RPcmRlcgkBAAAADGdldE5leHRPcmRlcgAAAAEFAAAACXByZXZPcmRlcgQAAAAMbmV4dE9yZGVyUm9pCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAASZ2V0Um9pQnlPcmRlcklkS2V5AAAAAQUAAAAJbmV4dE9yZGVyBAAAABBpc05leHRPcmRlckVycm9yAwMJAQAAAAIhPQAAAAIFAAAACW5leHRPcmRlcgIAAAAACQAAZwAAAAIFAAAAA3JvaQUAAAAMbmV4dE9yZGVyUm9pBwYHBAAAAAxwcmV2T3JkZXJSb2kJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABJnZXRSb2lCeU9yZGVySWRLZXkAAAABBQAAAAlwcmV2T3JkZXIEAAAAEGlzUHJldk9yZGVyRXJyb3IDAwkBAAAAAiE9AAAAAgUAAAAJcHJldk9yZGVyAgAAAAAJAABmAAAAAgUAAAAMcHJldk9yZGVyUm9pBQAAAANyb2kHBgcDAwUAAAAQaXNOZXh0T3JkZXJFcnJvcgYFAAAAEGlzUHJldk9yZGVyRXJyb3IJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAfaW52YWxpZCBvcmRlciBpc1ByZXZPcmRlckVycm9yOgkAAaUAAAABBQAAABBpc1ByZXZPcmRlckVycm9yAgAAABIgaXNOZXh0T3JkZXJFcnJvcjoJAAGlAAAAAQUAAAAQaXNOZXh0T3JkZXJFcnJvcgMDBQAAABlpc05ld09yZGVyQXRGaXJzdFBvc2l0aW9uCQAAZwAAAAIFAAAADWN1cnJlbnRNYXhSb2kFAAAAA3JvaQcJAQAAABBpbnRlcm5hbFNlbGxCb25kAAAACQUAAAANY3VycmVudE1heFJvaQUAAAAKbmV3T3JkZXJJZAUAAAAJbmV4dE9yZGVyAAAAAAAAAAAABQAAAANyb2kFAAAABXByaWNlCAUAAAADcG10AAAABmFtb3VudAgFAAAAA2ludgAAAAZjYWxsZXIGAwUAAAAMaW5zdGFudE9yZGVyCQAAAgAAAAECAAAAMkluc3RhbnQgb3JkZXIgY291bGRuJ3QgYmUgYWRkZWQgaW50byB3YWl0aW5nIHF1ZXVlCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0UHJldk9yZGVyS2V5AAAAAQUAAAAKbmV3T3JkZXJJZAUAAAAJcHJldk9yZGVyCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0TmV4dE9yZGVyS2V5AAAAAQUAAAAKbmV3T3JkZXJJZAUAAAAJbmV4dE9yZGVyCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0TmV4dE9yZGVyS2V5AAAAAQUAAAAJcHJldk9yZGVyAwkAAAAAAAACBQAAAAlwcmV2T3JkZXICAAAAAAIAAAAABQAAAApuZXdPcmRlcklkCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0UHJldk9yZGVyS2V5AAAAAQUAAAAJbmV4dE9yZGVyAwkAAAAAAAACBQAAAAluZXh0T3JkZXICAAAAAAIAAAAABQAAAApuZXdPcmRlcklkCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAA1GaXJzdE9yZGVyS2V5AwMJAAAAAAAAAgUAAAAKZmlyc3RPcmRlcgIAAAAABgkAAAAAAAACBQAAAApmaXJzdE9yZGVyBQAAAAluZXh0T3JkZXIFAAAACm5ld09yZGVySWQFAAAACmZpcnN0T3JkZXIJAQAAAAlvcmRlckRhdGEAAAAGBQAAAApuZXdPcmRlcklkCAUAAAADcG10AAAABmFtb3VudAUAAAAFb3duZXIFAAAAA05FVwUAAAADcm9pBQAAAAVwcmljZQAAAAQAAAABaQEAAAAUaW5zdGFudEJ1eU5zYnRPckZhaWwAAAABAAAADW5vTGVzc1RoZW5Sb2kEAAAAA3BtdAkBAAAAB2V4dHJhY3QAAAABCAUAAAABaQAAAAdwYXltZW50BAAAAA1jdXJyZW50TWF4Um9pCQAAawAAAAMFAAAAB2RlZmljaXQAAAAAAAAAAGQFAAAADm5ldXRyaW5vU3VwcGx5AwkAAGYAAAACBQAAAA1ub0xlc3NUaGVuUm9pBQAAAA1jdXJyZW50TWF4Um9pCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAD0N1cnJlbnQgbWF4Um9pPQkAAaQAAAABBQAAAA1jdXJyZW50TWF4Um9pAgAAAC0gaXMgbGVzcyB0aGVuIHBhc3NlZCBwYXJhbWV0ZXIgbm9MZXNzVGhlblJvaT0JAAGkAAAAAQUAAAANbm9MZXNzVGhlblJvaQQAAAAVcHJpY2VXYXZlc0J5Qm9uZENlbnRzCQAAawAAAAMJAABkAAAAAgAAAAAAAAAAZAUAAAANY3VycmVudE1heFJvaQUAAAAMY3VycmVudFByaWNlAAAAAAAAAABkCQEAAAAXaW50ZXJuYWxBZGRCdXlCb25kT3JkZXIAAAAGBQAAAA1jdXJyZW50TWF4Um9pBQAAAA1jdXJyZW50TWF4Um9pCQAAaQAAAAIJAABoAAAAAgUAAAAIUFJJQ0VMRVQFAAAACFBSSUNFTEVUBQAAABVwcmljZVdhdmVzQnlCb25kQ2VudHMCAAAAAAUAAAABaQYAAAABaQEAAAAPYWRkQnV5Qm9uZE9yZGVyAAAAAgAAAAVwcmljZQAAAAlwcmV2T3JkZXIEAAAAA3BtdAkBAAAAB2V4dHJhY3QAAAABCAUAAAABaQAAAAdwYXltZW50BAAAABVwcmljZVdhdmVzQnlCb25kQ2VudHMJAABrAAAAAwUAAAAIUFJJQ0VMRVQFAAAACFBSSUNFTEVUBQAAAAVwcmljZQMJAABnAAAAAgAAAAAAAAAAAAUAAAAFcHJpY2UJAAACAAAAAQIAAAAPcHJpY2UgbGVzcyB6ZXJvCQEAAAAXaW50ZXJuYWxBZGRCdXlCb25kT3JkZXIAAAAGCQAAawAAAAMFAAAAB2RlZmljaXQAAAAAAAAAAGQFAAAADm5ldXRyaW5vU3VwcGx5CQAAawAAAAMJAABlAAAAAgUAAAAVcHJpY2VXYXZlc0J5Qm9uZENlbnRzBQAAAAxjdXJyZW50UHJpY2UAAAAAAAAAAGQFAAAADGN1cnJlbnRQcmljZQUAAAAFcHJpY2UFAAAACXByZXZPcmRlcgUAAAABaQcAAAABaQEAAAALY2FuY2VsT3JkZXIAAAABAAAAB29yZGVySWQEAAAABW93bmVyCQEAAAANZ2V0T3JkZXJPd25lcgAAAAEFAAAAB29yZGVySWQEAAAABmFtb3VudAkAAGUAAAACCQEAAAANZ2V0T3JkZXJUb3RhbAAAAAEFAAAAB29yZGVySWQJAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQUAAAAHb3JkZXJJZAQAAAAGY2FsbGVyCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAJbmV4dE9yZGVyCQEAAAAMZ2V0TmV4dE9yZGVyAAAAAQUAAAAHb3JkZXJJZAQAAAAJcHJldk9yZGVyCQEAAAAMZ2V0UHJldk9yZGVyAAAAAQUAAAAHb3JkZXJJZAMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFljb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwMJAQAAAAIhPQAAAAIFAAAABW93bmVyBQAAAAZjYWxsZXIJAAACAAAAAQIAAAARcGVybWlzc2lvbiBkZW5pZWQDCQEAAAACIT0AAAACCQEAAAAOZ2V0T3JkZXJTdGF0dXMAAAABBQAAAAdvcmRlcklkBQAAAANORVcJAAACAAAAAQIAAAAUaW52YWxpZCBvcmRlciBzdGF0dXMJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAA1GaXJzdE9yZGVyS2V5AwkAAAAAAAACBQAAAApmaXJzdE9yZGVyBQAAAAdvcmRlcklkBQAAAAluZXh0T3JkZXIFAAAACmZpcnN0T3JkZXIJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA9nZXROZXh0T3JkZXJLZXkAAAABBQAAAAlwcmV2T3JkZXIFAAAACW5leHRPcmRlcgkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAD2dldFByZXZPcmRlcktleQAAAAEFAAAACW5leHRPcmRlcgUAAAAJcHJldk9yZGVyCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAdvcmRlcklkBQAAAAhDQU5DRUxFRAUAAAADbmlsCQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAGYW1vdW50BQAAAAR1bml0BQAAAANuaWwAAAABaQEAAAAIc2VsbEJvbmQAAAAAAwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAWWNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAwkAAAAAAAACBQAAAApmaXJzdE9yZGVyAgAAAAAJAAACAAAAAQIAAAAPZW1wdHkgb3JkZXJib29rBAAAAAluZXh0T3JkZXIJAQAAAAxnZXROZXh0T3JkZXIAAAABBQAAAApmaXJzdE9yZGVyBAAAAAtmaWxsZWRUb3RhbAkBAAAAE2dldE9yZGVyRmlsbGVkVG90YWwAAAABBQAAAApmaXJzdE9yZGVyBAAAAApvcmRlclByaWNlCQEAAAANZ2V0T3JkZXJQcmljZQAAAAEFAAAACmZpcnN0T3JkZXIEAAAAA3JvaQkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEmdldFJvaUJ5T3JkZXJJZEtleQAAAAEFAAAACmZpcnN0T3JkZXIEAAAAD3BheW1lbnRXYXZlbGV0cwkBAAAADWdldE9yZGVyVG90YWwAAAABBQAAAApmaXJzdE9yZGVyBAAAABFvcmRlck93bmVyQWRkcmVzcwkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAAA1nZXRPcmRlck93bmVyAAAAAQUAAAAKZmlyc3RPcmRlcgkBAAAAEGludGVybmFsU2VsbEJvbmQAAAAJCQAAawAAAAMFAAAAB2RlZmljaXQAAAAAAAAAAGQFAAAADm5ldXRyaW5vU3VwcGx5BQAAAApmaXJzdE9yZGVyBQAAAAluZXh0T3JkZXIFAAAAC2ZpbGxlZFRvdGFsBQAAAANyb2kFAAAACm9yZGVyUHJpY2UFAAAAD3BheW1lbnRXYXZlbGV0cwUAAAARb3JkZXJPd25lckFkZHJlc3MHAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAQAAAAQcHViS2V5QWRtaW5zTGlzdAkABEwAAAACAgAAACxCTEVvZ3V6UFZLVlRmWHh4VDNXN1JxZjhhVW0yZ2dDOVZlbWQyTVFhd00yRwkABEwAAAACAgAAACxGV1ZmZllyMkFMbUhNZWpabTNXcWVMejZTZHltM2dMRkd0Sm40S1R3eVU1eAkABEwAAAACAgAAACwzV2gyTGFXY2I1Z2c3SzJwUGNXM0VwNkVBdVJCellrQWdyZHB0NDNqVERGYQkABEwAAAACAgAAACw1V1JYRlNqd2NUYk5mS2NKczhacVhtU1NXWXNTVkpVdE12TXFaajVoSDROYwUAAAADbmlsBAAAAAVjb3VudAkAAGQAAAACCQAAZAAAAAIJAABkAAAAAgMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAgAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAADCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAwAAAAAAAAAAAgAAAAAAAAAAAAkAAGcAAAACBQAAAAVjb3VudAAAAAAAAAAAA08KEcA=", "chainId": 87, "height": 2153059, "spentComplexity": 0 } View: original | compacted Prev: 6Wi8nwXfJ8vWkHvV3S3wmx4MFEJvLMgQuhtRec2AxwR2 Next: YReb3nVQzjcYiopS5gLYPNrpnvGnqKw617PXEAVTtrT Diff:
OldNewDifferences
4545
4646 let PAULI = 1000000
4747
48+let PRICELET = 1000000
49+
4850 let MINORDERTOTAL = (10 * WAVELET)
4951
5052 let MAXROI = 95
5557
5658 let FILLED = "filled"
5759
58-let NeutrinoContractKey = "neutrino_contract"
59-
6060 let PriceKey = "price"
6161
6262 let BondAssetIdKey = "bond_asset_id"
6363
6464 let NeutrinoAssetIdKey = "neutrino_asset_id"
65-
66-let ControlContractKey = "control_contract"
6765
6866 let BalanceLockedkKey = "balance_lock_"
6967
7169
7270 let NeutrinoLockedBalanceKey = (BalanceLockedkKey + "neutrino")
7371
74-let LiquidationContractKey = "liquidation_contract"
75-
7672 let FirstOrderKey = "order_first"
7773
7874 func getRoiByOrderIdKey (orderId) = ("debug_order_roi_" + orderId)
7975
8076
8177 func getOrderPriceKey (orderId) = ("order_price_" + orderId)
82-
83-
84-func getDebugOrderPriceKey (orderId) = ("debug_order_currentPrice_" + orderId)
8578
8679
8780 func getOrderTotalKey (orderId) = ("order_total_" + orderId)
10598 func getNextOrderKey (orderId) = ("order_next_" + orderId)
10699
107100
108-func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, 100, price), WAVELET, PAULI)
101+func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
109102
110103
111-func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, 100), PAULI, WAVELET)
104+func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
112105
113106
114107 func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
144137 func getOrderPrice (id) = getNumberByKey(getOrderPriceKey(id))
145138
146139
147-func getDebugOrderPrice (id) = getNumberByKey(getDebugOrderPriceKey(id))
148-
149-
150140 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
151141
152142
165155 func getNextOrder (id) = getStringByKey(getNextOrderKey(id))
166156
167157
158+func orderData (orderId,totalWavelets,owner,status,roi,price) = [DataEntry(getOrderPriceKey(orderId), price), DataEntry(getOrderTotalKey(orderId), totalWavelets), DataEntry(getOrderOwnerKey(orderId), owner), DataEntry(getOrderHeightKey(orderId), height), DataEntry(getOrderStatusKey(orderId), status), DataEntry(("debug_order_currentPrice_" + orderId), currentPrice), DataEntry(getRoiByOrderIdKey(orderId), roi)]
159+
160+
161+func internalSellBond (currentMaxRoi,pFirstOrder,pNextOrder,pFilledTotal,pRoi,pPrice,pPaymentWavelets,orderOwnerAddress,instantOrder) = {
162+ let priceWavesByBondCents = fraction((100 + pRoi), currentPrice, 100)
163+ let remainedTotal = (pPaymentWavelets - pFilledTotal)
164+ let fillableOrderAmount = convertWavesToBond(remainedTotal, priceWavesByBondCents)
165+ let totalOrderWaveletesRequired = convertBondToWaves(fillableOrderAmount, priceWavesByBondCents)
166+ let nbTokensSellCondition = (currentMaxRoi >= pRoi)
167+ if (!(nbTokensSellCondition))
168+ then throw(("innapropriate roi: " + toString(pRoi)))
169+ else if ((totalOrderWaveletesRequired == 0))
170+ then throw("cannot fill order at the moment")
171+ else {
172+ let changeWavelets = (remainedTotal - totalOrderWaveletesRequired)
173+ let writeSetData = if (instantOrder)
174+ then [DataEntry(getOrderPriceKey(pFirstOrder), pPrice), DataEntry(getOrderTotalKey(pFirstOrder), pPaymentWavelets), DataEntry(getOrderOwnerKey(pFirstOrder), toBase58String(orderOwnerAddress.bytes)), DataEntry(getOrderHeightKey(pFirstOrder), height), DataEntry(getOrderFilledTotalKey(pFirstOrder), (pFilledTotal + totalOrderWaveletesRequired)), DataEntry(getOrderStatusKey(pFirstOrder), FILLED), DataEntry(("debug_order_currentPrice_" + pFirstOrder), currentPrice), DataEntry(getRoiByOrderIdKey(pFirstOrder), pRoi)]
175+ else [DataEntry(getOrderFilledTotalKey(pFirstOrder), (pFilledTotal + totalOrderWaveletesRequired)), DataEntry(getOrderStatusKey(pFirstOrder), FILLED), DataEntry(getOrderTotalKey(pFirstOrder), pPaymentWavelets), DataEntry(getPrevOrderKey(pNextOrder), ""), DataEntry(FirstOrderKey, pNextOrder)]
176+ ScriptResult(WriteSet(writeSetData), TransferSet([ScriptTransfer(orderOwnerAddress, fillableOrderAmount, bondAssetId), ScriptTransfer(neutrinoContract, totalOrderWaveletesRequired, unit), ScriptTransfer(orderOwnerAddress, changeWavelets, unit)]))
177+ }
178+ }
179+
180+
181+func internalAddBuyBondOrder (currentMaxRoi,roi,price,prevOrder,inv,instantOrder) = {
182+ let pmt = extract(inv.payment)
183+ let newOrderId = toBase58String(inv.transactionId)
184+ if (isBlocked)
185+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
186+ else if ((MINORDERTOTAL > pmt.amount))
187+ then throw(("min order total equals " + toString(MINORDERTOTAL)))
188+ else if ((roi > MAXROI))
189+ then throw("max setOrder ROI is 95%")
190+ else if (if ((deficit > 0))
191+ then (0 > roi)
192+ else false)
193+ then throw("can't place order with negative roi during deficit")
194+ else if ((-(MAXROI) > roi))
195+ then throw("min setOrder ROI is -95%")
196+ else if ((roi == 0))
197+ then throw("roi should not be equal to 0")
198+ else if (isDefined(pmt.assetId))
199+ then throw("can use waves only")
200+ else if ((getOrderOwner(newOrderId) != ""))
201+ then throw("order exists")
202+ else if (if ((prevOrder != ""))
203+ then (getOrderStatus(prevOrder) != NEW)
204+ else false)
205+ then throw("prev order status is not new")
206+ else {
207+ let isNewOrderAtFirstPosition = (prevOrder == "")
208+ let owner = toString(inv.caller)
209+ let nextOrder = if (isNewOrderAtFirstPosition)
210+ then firstOrder
211+ else getNextOrder(prevOrder)
212+ let nextOrderRoi = getNumberByKey(getRoiByOrderIdKey(nextOrder))
213+ let isNextOrderError = if (if ((nextOrder != ""))
214+ then (roi >= nextOrderRoi)
215+ else false)
216+ then true
217+ else false
218+ let prevOrderRoi = getNumberByKey(getRoiByOrderIdKey(prevOrder))
219+ let isPrevOrderError = if (if ((prevOrder != ""))
220+ then (prevOrderRoi > roi)
221+ else false)
222+ then true
223+ else false
224+ if (if (isNextOrderError)
225+ then true
226+ else isPrevOrderError)
227+ then throw(((("invalid order isPrevOrderError:" + toString(isPrevOrderError)) + " isNextOrderError:") + toString(isNextOrderError)))
228+ else if (if (isNewOrderAtFirstPosition)
229+ then (currentMaxRoi >= roi)
230+ else false)
231+ then internalSellBond(currentMaxRoi, newOrderId, nextOrder, 0, roi, price, pmt.amount, inv.caller, true)
232+ else if (instantOrder)
233+ then throw("Instant order couldn't be added into waiting queue")
234+ else WriteSet([DataEntry(getPrevOrderKey(newOrderId), prevOrder), DataEntry(getNextOrderKey(newOrderId), nextOrder), DataEntry(getNextOrderKey(prevOrder), if ((prevOrder == ""))
235+ then ""
236+ else newOrderId), DataEntry(getPrevOrderKey(nextOrder), if ((nextOrder == ""))
237+ then ""
238+ else newOrderId), DataEntry(FirstOrderKey, if (if ((firstOrder == ""))
239+ then true
240+ else (firstOrder == nextOrder))
241+ then newOrderId
242+ else firstOrder), orderData(newOrderId, pmt.amount, owner, NEW, roi, price)])
243+ }
244+ }
245+
246+
168247 @Callable(i)
169-func migrateOrderPrice () = {
170- let lastMigratedOrderKey = "migration_6decimals_lastMigratedOrderId"
171- let finalStatus = "migrated_to_6decimals"
172- let lastMigratedOrderId = getStringByKey(lastMigratedOrderKey)
173- let currentOrderId = if ((lastMigratedOrderId == ""))
174- then firstOrder
175- else getNextOrder(lastMigratedOrderId)
176- let orderMigrationStatusKey = ("migration_6decimals_status_" + currentOrderId)
177- let orderMigrationStatus = getStringByKey(orderMigrationStatusKey)
178- if ((orderMigrationStatus == finalStatus))
179- then throw("error: order has been already migrated")
180- else if ((currentOrderId == ""))
181- then throw("status ok: all orders have been already migrated or nothing to migrate")
182- else WriteSet([DataEntry(orderMigrationStatusKey, finalStatus), DataEntry(lastMigratedOrderKey, currentOrderId), DataEntry(getOrderPriceKey(currentOrderId), (getOrderPrice(currentOrderId) * 10000)), DataEntry(getDebugOrderPriceKey(currentOrderId), (getDebugOrderPrice(currentOrderId) * 10000))])
248+func instantBuyNsbtOrFail (noLessThenRoi) = {
249+ let pmt = extract(i.payment)
250+ let currentMaxRoi = fraction(deficit, 100, neutrinoSupply)
251+ if ((noLessThenRoi > currentMaxRoi))
252+ then throw(((("Current maxRoi=" + toString(currentMaxRoi)) + " is less then passed parameter noLessThenRoi=") + toString(noLessThenRoi)))
253+ else {
254+ let priceWavesByBondCents = fraction((100 + currentMaxRoi), currentPrice, 100)
255+ internalAddBuyBondOrder(currentMaxRoi, currentMaxRoi, ((PRICELET * PRICELET) / priceWavesByBondCents), "", i, true)
256+ }
183257 }
258+
259+
260+
261+@Callable(i)
262+func addBuyBondOrder (price,prevOrder) = {
263+ let pmt = extract(i.payment)
264+ let priceWavesByBondCents = fraction(PRICELET, PRICELET, price)
265+ if ((0 >= price))
266+ then throw("price less zero")
267+ else internalAddBuyBondOrder(fraction(deficit, 100, neutrinoSupply), fraction((priceWavesByBondCents - currentPrice), 100, currentPrice), price, prevOrder, i, false)
268+ }
269+
270+
271+
272+@Callable(i)
273+func cancelOrder (orderId) = {
274+ let owner = getOrderOwner(orderId)
275+ let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
276+ let caller = toString(i.caller)
277+ let nextOrder = getNextOrder(orderId)
278+ let prevOrder = getPrevOrder(orderId)
279+ if (isBlocked)
280+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
281+ else if ((owner != caller))
282+ then throw("permission denied")
283+ else if ((getOrderStatus(orderId) != NEW))
284+ then throw("invalid order status")
285+ else ScriptResult(WriteSet([DataEntry(FirstOrderKey, if ((firstOrder == orderId))
286+ then nextOrder
287+ else firstOrder), DataEntry(getNextOrderKey(prevOrder), nextOrder), DataEntry(getPrevOrderKey(nextOrder), prevOrder), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, unit)]))
288+ }
289+
290+
291+
292+@Callable(i)
293+func sellBond () = if (isBlocked)
294+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
295+ else if ((firstOrder == ""))
296+ then throw("empty orderbook")
297+ else {
298+ let nextOrder = getNextOrder(firstOrder)
299+ let filledTotal = getOrderFilledTotal(firstOrder)
300+ let orderPrice = getOrderPrice(firstOrder)
301+ let roi = getNumberByKey(getRoiByOrderIdKey(firstOrder))
302+ let paymentWavelets = getOrderTotal(firstOrder)
303+ let orderOwnerAddress = Address(fromBase58String(getOrderOwner(firstOrder)))
304+ internalSellBond(fraction(deficit, 100, neutrinoSupply), firstOrder, nextOrder, filledTotal, roi, orderPrice, paymentWavelets, orderOwnerAddress, false)
305+ }
184306
185307
186308 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = match getInteger(this, key) {
55 case a: Int =>
66 a
77 case _ =>
88 0
99 }
1010
1111
1212 func getStringByKey (key) = match getString(this, key) {
1313 case a: String =>
1414 a
1515 case _ =>
1616 ""
1717 }
1818
1919
2020 func getBoolByAddressAndKey (address,key) = match getBoolean(address, key) {
2121 case a: Boolean =>
2222 a
2323 case _ =>
2424 false
2525 }
2626
2727
2828 func getStringByAddressAndKey (address,key) = match getString(address, key) {
2929 case a: String =>
3030 a
3131 case _ =>
3232 ""
3333 }
3434
3535
3636 func getNumberByAddressAndKey (address,key) = match getInteger(address, key) {
3737 case a: Int =>
3838 a
3939 case _ =>
4040 0
4141 }
4242
4343
4444 let WAVELET = 100000000
4545
4646 let PAULI = 1000000
4747
48+let PRICELET = 1000000
49+
4850 let MINORDERTOTAL = (10 * WAVELET)
4951
5052 let MAXROI = 95
5153
5254 let CANCELED = "canceled"
5355
5456 let NEW = "new"
5557
5658 let FILLED = "filled"
5759
58-let NeutrinoContractKey = "neutrino_contract"
59-
6060 let PriceKey = "price"
6161
6262 let BondAssetIdKey = "bond_asset_id"
6363
6464 let NeutrinoAssetIdKey = "neutrino_asset_id"
65-
66-let ControlContractKey = "control_contract"
6765
6866 let BalanceLockedkKey = "balance_lock_"
6967
7068 let WavesLockedBalanceKey = (BalanceLockedkKey + "waves")
7169
7270 let NeutrinoLockedBalanceKey = (BalanceLockedkKey + "neutrino")
7371
74-let LiquidationContractKey = "liquidation_contract"
75-
7672 let FirstOrderKey = "order_first"
7773
7874 func getRoiByOrderIdKey (orderId) = ("debug_order_roi_" + orderId)
7975
8076
8177 func getOrderPriceKey (orderId) = ("order_price_" + orderId)
82-
83-
84-func getDebugOrderPriceKey (orderId) = ("debug_order_currentPrice_" + orderId)
8578
8679
8780 func getOrderTotalKey (orderId) = ("order_total_" + orderId)
8881
8982
9083 func getOrderOwnerKey (orderId) = ("order_owner_" + orderId)
9184
9285
9386 func getOrderHeightKey (orderId) = ("order_height_" + orderId)
9487
9588
9689 func getOrderStatusKey (orderId) = ("order_status_" + orderId)
9790
9891
9992 func getOrderFilledTotalKey (orderId) = ("order_filled_total_" + orderId)
10093
10194
10295 func getPrevOrderKey (orderId) = ("order_prev_" + orderId)
10396
10497
10598 func getNextOrderKey (orderId) = ("order_next_" + orderId)
10699
107100
108-func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, 100, price), WAVELET, PAULI)
101+func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
109102
110103
111-func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, 100), PAULI, WAVELET)
104+func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
112105
113106
114107 func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
115108
116109
117110 func convertBondToWaves (amount,price) = convertNeutrinoToWaves(amount, price)
118111
119112
120113 let neutrinoContract = Address(base58'3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo')
121114
122115 let controlContract = Address(base58'3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP')
123116
124117 let liquidationContract = Address(base58'3P4PCxsJqMzQBALo8zANHtBDZRRquobHQp7')
125118
126119 let neutrinoAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
127120
128121 let bondAssetId = base58'6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g'
129122
130123 let isBlocked = getBoolByAddressAndKey(controlContract, "is_blocked")
131124
132125 let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey)
133126
134127 let neutrinoLockedBalance = getNumberByAddressAndKey(neutrinoContract, NeutrinoLockedBalanceKey)
135128
136129 let reserve = (wavesBalance(neutrinoContract) - getNumberByAddressAndKey(neutrinoContract, WavesLockedBalanceKey))
137130
138131 let neutrinoSupply = (((neutrinoLockedBalance + extract(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(liquidationContract, neutrinoAssetId))
139132
140133 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice))
141134
142135 let firstOrder = getStringByKey(FirstOrderKey)
143136
144137 func getOrderPrice (id) = getNumberByKey(getOrderPriceKey(id))
145138
146139
147-func getDebugOrderPrice (id) = getNumberByKey(getDebugOrderPriceKey(id))
148-
149-
150140 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
151141
152142
153143 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
154144
155145
156146 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
157147
158148
159149 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
160150
161151
162152 func getPrevOrder (id) = getStringByKey(getPrevOrderKey(id))
163153
164154
165155 func getNextOrder (id) = getStringByKey(getNextOrderKey(id))
166156
167157
158+func orderData (orderId,totalWavelets,owner,status,roi,price) = [DataEntry(getOrderPriceKey(orderId), price), DataEntry(getOrderTotalKey(orderId), totalWavelets), DataEntry(getOrderOwnerKey(orderId), owner), DataEntry(getOrderHeightKey(orderId), height), DataEntry(getOrderStatusKey(orderId), status), DataEntry(("debug_order_currentPrice_" + orderId), currentPrice), DataEntry(getRoiByOrderIdKey(orderId), roi)]
159+
160+
161+func internalSellBond (currentMaxRoi,pFirstOrder,pNextOrder,pFilledTotal,pRoi,pPrice,pPaymentWavelets,orderOwnerAddress,instantOrder) = {
162+ let priceWavesByBondCents = fraction((100 + pRoi), currentPrice, 100)
163+ let remainedTotal = (pPaymentWavelets - pFilledTotal)
164+ let fillableOrderAmount = convertWavesToBond(remainedTotal, priceWavesByBondCents)
165+ let totalOrderWaveletesRequired = convertBondToWaves(fillableOrderAmount, priceWavesByBondCents)
166+ let nbTokensSellCondition = (currentMaxRoi >= pRoi)
167+ if (!(nbTokensSellCondition))
168+ then throw(("innapropriate roi: " + toString(pRoi)))
169+ else if ((totalOrderWaveletesRequired == 0))
170+ then throw("cannot fill order at the moment")
171+ else {
172+ let changeWavelets = (remainedTotal - totalOrderWaveletesRequired)
173+ let writeSetData = if (instantOrder)
174+ then [DataEntry(getOrderPriceKey(pFirstOrder), pPrice), DataEntry(getOrderTotalKey(pFirstOrder), pPaymentWavelets), DataEntry(getOrderOwnerKey(pFirstOrder), toBase58String(orderOwnerAddress.bytes)), DataEntry(getOrderHeightKey(pFirstOrder), height), DataEntry(getOrderFilledTotalKey(pFirstOrder), (pFilledTotal + totalOrderWaveletesRequired)), DataEntry(getOrderStatusKey(pFirstOrder), FILLED), DataEntry(("debug_order_currentPrice_" + pFirstOrder), currentPrice), DataEntry(getRoiByOrderIdKey(pFirstOrder), pRoi)]
175+ else [DataEntry(getOrderFilledTotalKey(pFirstOrder), (pFilledTotal + totalOrderWaveletesRequired)), DataEntry(getOrderStatusKey(pFirstOrder), FILLED), DataEntry(getOrderTotalKey(pFirstOrder), pPaymentWavelets), DataEntry(getPrevOrderKey(pNextOrder), ""), DataEntry(FirstOrderKey, pNextOrder)]
176+ ScriptResult(WriteSet(writeSetData), TransferSet([ScriptTransfer(orderOwnerAddress, fillableOrderAmount, bondAssetId), ScriptTransfer(neutrinoContract, totalOrderWaveletesRequired, unit), ScriptTransfer(orderOwnerAddress, changeWavelets, unit)]))
177+ }
178+ }
179+
180+
181+func internalAddBuyBondOrder (currentMaxRoi,roi,price,prevOrder,inv,instantOrder) = {
182+ let pmt = extract(inv.payment)
183+ let newOrderId = toBase58String(inv.transactionId)
184+ if (isBlocked)
185+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
186+ else if ((MINORDERTOTAL > pmt.amount))
187+ then throw(("min order total equals " + toString(MINORDERTOTAL)))
188+ else if ((roi > MAXROI))
189+ then throw("max setOrder ROI is 95%")
190+ else if (if ((deficit > 0))
191+ then (0 > roi)
192+ else false)
193+ then throw("can't place order with negative roi during deficit")
194+ else if ((-(MAXROI) > roi))
195+ then throw("min setOrder ROI is -95%")
196+ else if ((roi == 0))
197+ then throw("roi should not be equal to 0")
198+ else if (isDefined(pmt.assetId))
199+ then throw("can use waves only")
200+ else if ((getOrderOwner(newOrderId) != ""))
201+ then throw("order exists")
202+ else if (if ((prevOrder != ""))
203+ then (getOrderStatus(prevOrder) != NEW)
204+ else false)
205+ then throw("prev order status is not new")
206+ else {
207+ let isNewOrderAtFirstPosition = (prevOrder == "")
208+ let owner = toString(inv.caller)
209+ let nextOrder = if (isNewOrderAtFirstPosition)
210+ then firstOrder
211+ else getNextOrder(prevOrder)
212+ let nextOrderRoi = getNumberByKey(getRoiByOrderIdKey(nextOrder))
213+ let isNextOrderError = if (if ((nextOrder != ""))
214+ then (roi >= nextOrderRoi)
215+ else false)
216+ then true
217+ else false
218+ let prevOrderRoi = getNumberByKey(getRoiByOrderIdKey(prevOrder))
219+ let isPrevOrderError = if (if ((prevOrder != ""))
220+ then (prevOrderRoi > roi)
221+ else false)
222+ then true
223+ else false
224+ if (if (isNextOrderError)
225+ then true
226+ else isPrevOrderError)
227+ then throw(((("invalid order isPrevOrderError:" + toString(isPrevOrderError)) + " isNextOrderError:") + toString(isNextOrderError)))
228+ else if (if (isNewOrderAtFirstPosition)
229+ then (currentMaxRoi >= roi)
230+ else false)
231+ then internalSellBond(currentMaxRoi, newOrderId, nextOrder, 0, roi, price, pmt.amount, inv.caller, true)
232+ else if (instantOrder)
233+ then throw("Instant order couldn't be added into waiting queue")
234+ else WriteSet([DataEntry(getPrevOrderKey(newOrderId), prevOrder), DataEntry(getNextOrderKey(newOrderId), nextOrder), DataEntry(getNextOrderKey(prevOrder), if ((prevOrder == ""))
235+ then ""
236+ else newOrderId), DataEntry(getPrevOrderKey(nextOrder), if ((nextOrder == ""))
237+ then ""
238+ else newOrderId), DataEntry(FirstOrderKey, if (if ((firstOrder == ""))
239+ then true
240+ else (firstOrder == nextOrder))
241+ then newOrderId
242+ else firstOrder), orderData(newOrderId, pmt.amount, owner, NEW, roi, price)])
243+ }
244+ }
245+
246+
168247 @Callable(i)
169-func migrateOrderPrice () = {
170- let lastMigratedOrderKey = "migration_6decimals_lastMigratedOrderId"
171- let finalStatus = "migrated_to_6decimals"
172- let lastMigratedOrderId = getStringByKey(lastMigratedOrderKey)
173- let currentOrderId = if ((lastMigratedOrderId == ""))
174- then firstOrder
175- else getNextOrder(lastMigratedOrderId)
176- let orderMigrationStatusKey = ("migration_6decimals_status_" + currentOrderId)
177- let orderMigrationStatus = getStringByKey(orderMigrationStatusKey)
178- if ((orderMigrationStatus == finalStatus))
179- then throw("error: order has been already migrated")
180- else if ((currentOrderId == ""))
181- then throw("status ok: all orders have been already migrated or nothing to migrate")
182- else WriteSet([DataEntry(orderMigrationStatusKey, finalStatus), DataEntry(lastMigratedOrderKey, currentOrderId), DataEntry(getOrderPriceKey(currentOrderId), (getOrderPrice(currentOrderId) * 10000)), DataEntry(getDebugOrderPriceKey(currentOrderId), (getDebugOrderPrice(currentOrderId) * 10000))])
248+func instantBuyNsbtOrFail (noLessThenRoi) = {
249+ let pmt = extract(i.payment)
250+ let currentMaxRoi = fraction(deficit, 100, neutrinoSupply)
251+ if ((noLessThenRoi > currentMaxRoi))
252+ then throw(((("Current maxRoi=" + toString(currentMaxRoi)) + " is less then passed parameter noLessThenRoi=") + toString(noLessThenRoi)))
253+ else {
254+ let priceWavesByBondCents = fraction((100 + currentMaxRoi), currentPrice, 100)
255+ internalAddBuyBondOrder(currentMaxRoi, currentMaxRoi, ((PRICELET * PRICELET) / priceWavesByBondCents), "", i, true)
256+ }
183257 }
258+
259+
260+
261+@Callable(i)
262+func addBuyBondOrder (price,prevOrder) = {
263+ let pmt = extract(i.payment)
264+ let priceWavesByBondCents = fraction(PRICELET, PRICELET, price)
265+ if ((0 >= price))
266+ then throw("price less zero")
267+ else internalAddBuyBondOrder(fraction(deficit, 100, neutrinoSupply), fraction((priceWavesByBondCents - currentPrice), 100, currentPrice), price, prevOrder, i, false)
268+ }
269+
270+
271+
272+@Callable(i)
273+func cancelOrder (orderId) = {
274+ let owner = getOrderOwner(orderId)
275+ let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
276+ let caller = toString(i.caller)
277+ let nextOrder = getNextOrder(orderId)
278+ let prevOrder = getPrevOrder(orderId)
279+ if (isBlocked)
280+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
281+ else if ((owner != caller))
282+ then throw("permission denied")
283+ else if ((getOrderStatus(orderId) != NEW))
284+ then throw("invalid order status")
285+ else ScriptResult(WriteSet([DataEntry(FirstOrderKey, if ((firstOrder == orderId))
286+ then nextOrder
287+ else firstOrder), DataEntry(getNextOrderKey(prevOrder), nextOrder), DataEntry(getPrevOrderKey(nextOrder), prevOrder), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, unit)]))
288+ }
289+
290+
291+
292+@Callable(i)
293+func sellBond () = if (isBlocked)
294+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
295+ else if ((firstOrder == ""))
296+ then throw("empty orderbook")
297+ else {
298+ let nextOrder = getNextOrder(firstOrder)
299+ let filledTotal = getOrderFilledTotal(firstOrder)
300+ let orderPrice = getOrderPrice(firstOrder)
301+ let roi = getNumberByKey(getRoiByOrderIdKey(firstOrder))
302+ let paymentWavelets = getOrderTotal(firstOrder)
303+ let orderOwnerAddress = Address(fromBase58String(getOrderOwner(firstOrder)))
304+ internalSellBond(fraction(deficit, 100, neutrinoSupply), firstOrder, nextOrder, filledTotal, roi, orderPrice, paymentWavelets, orderOwnerAddress, false)
305+ }
184306
185307
186308 @Verifier(tx)
187309 func verify () = {
188310 let pubKeyAdminsList = ["BLEoguzPVKVTfXxxT3W7Rqf8aUm2ggC9Vemd2MQawM2G", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
189311 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
190312 then 1
191313 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
192314 then 1
193315 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
194316 then 1
195317 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
196318 then 2
197319 else 0))
198320 (count >= 3)
199321 }
200322

github/deemru/w8io/3ef1775 
73.83 ms