tx · CAAN3NneZKMijyNsLNjYRTHEqaQ9Akjswa6QTNiE2ksY

3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2:  -0.01000000 Waves

2022.01.31 13:16 [1902975] smart account 3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2 > SELF 0.00000000 Waves

{ "type": 13, "id": "CAAN3NneZKMijyNsLNjYRTHEqaQ9Akjswa6QTNiE2ksY", "fee": 1000000, "feeAssetId": null, "timestamp": 1643624235296, "version": 2, "chainId": 84, "sender": "3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2", "senderPublicKey": "5dTGvAkGC1ryvEkRCst923pqULtN3qWs6XXueerWos1D", "proofs": [ "4bxJtEwiXtjJ9FpJhwx38d8FpDRTFwd1itkJYfGMZQhQoP8Q4HD4pfpCJQifm5dcwGpKN98PHjLJRMkUVKqvd4Ev" ], "script": "base64:AAIFAAAAAAAAADMIAhIHCgUCAQEBARIAEgASCAoGAgEBAQEBEgASBQoDAQEBEgASABIDCgEBEgYKBAgIAQEAAAAoAAAAAAtyZXZpc2lvbk51bQIAAAAAAAAAAANTRVACAAAAAl9fAAAAAAhNQVhERVBUSAAAAAAAAAAAEQAAAAAJVVNFUkRFUFRIAAAAAAAAAAAaAAAAAAVTQ0FMRQAAAAAAAAAD6AEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAANrZXkAAAAAAAAAAAABAAAADmdldFN0cmluZ0J5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5AgAAAAABAAAAD2dldFN0cmluZ09yRmFpbAAAAAEAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQiAAAAAQUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgIAAAAPbWFuZGF0b3J5IHRoaXMuBQAAAANrZXkCAAAADyBpcyBub3QgZGVmaW5lZAAAAAAWSWR4Q2ZnTmV1dHJpbm9Db250cmFjdAAAAAAAAAAAAQAAAAAWSWR4Q2ZnTnNidExvY2tDb250cmFjdAAAAAAAAAAAAgAAAAAOSWR4Q2ZnTWF4RGVwdGgAAAAAAAAAAAMAAAAAEUlkeENmZ1BlcmlvZERlbGF5AAAAAAAAAAAEAQAAAAlrZXlDb25maWcAAAAAAgAAAAolc19fY29uZmlnAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAACQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABCQEAAAAJa2V5Q29uZmlnAAAAAAUAAAADU0VQAQAAAAxmb3JtYXRDb25maWcAAAAEAAAAGm5ldXRyaW5vQ29udHJhY3RBZGRyZXNzU3RyAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyAAAACG1heERlcHRoAAAAC3BlcmlvZERlbGF5CQAEuQAAAAIJAARMAAAAAgIAAAAIJXMlcyVkJWQJAARMAAAAAgUAAAAabmV1dHJpbm9Db250cmFjdEFkZHJlc3NTdHIJAARMAAAAAgUAAAAabnNidExvY2tDb250cmFjdEFkZHJlc3NTdHIJAARMAAAAAgkAAaQAAAABBQAAAAhtYXhEZXB0aAkABEwAAAACCQABpAAAAAEFAAAAC3BlcmlvZERlbGF5BQAAAANuaWwFAAAAA1NFUAEAAAANa2V5VXNlcnNDb3VudAAAAAACAAAADyVzX19uZXh0VXNlck51bQEAAAASa2V5TWF4TG9ja0R1cmF0aW9uAAAAAAIAAAATJXNfX21heExvY2tEdXJhdGlvbgEAAAAUa2V5TmV4dFByb2Nlc3NlZFVzZXIAAAAAAgAAABUlc19fbmV4dFByb2Nlc3NlZFVzZXIBAAAAD2tleUxhdGVzdFBlcmlvZAAAAAACAAAAECVzX19sYXRlc3RQZXJpb2QBAAAADWtleU5leHRQZXJpb2QAAAAAAgAAAA4lc19fbmV4dFBlcmlvZAEAAAAWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZAAAAAACAAAAFyVzX19uZXh0UHJvY2Vzc2VkUGVyaW9kAQAAABtrZXlOZXh0VW5sYWltZWRQZXJpb2RPZlVzZXIAAAABAAAACXVzZXJJbmRleAkABLkAAAACCQAETAAAAAICAAAAFyVzJWRfX25leHRDbGFpbWVkUGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAJdXNlckluZGV4BQAAAANuaWwFAAAAA1NFUAEAAAAca2V5TGFzdFByb2Nlc3NlZFBlcmlvZE9mVXNlcgAAAAEAAAAJdXNlckluZGV4CQAEuQAAAAIJAARMAAAAAgIAAAAZJXMlZF9fbGFzdFByb2Nlc3NlZFBlcmlvZAkABEwAAAACCQABpAAAAAEFAAAACXVzZXJJbmRleAUAAAADbmlsBQAAAANTRVABAAAAEmtleUhlaWdodEZvclBlcmlvZAAAAAEAAAAGcGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAAaJXMlZF9fc3RhcnRIZWlnaHRGb3JQZXJpb2QJAARMAAAAAgkAAaQAAAABBQAAAAZwZXJpb2QFAAAAA25pbAUAAAADU0VQAQAAABdrZXlUb3RhbEFtb3VudEZvclBlcmlvZAAAAAIAAAAGcGVyaW9kAAAAB2lzV2F2ZXMJAAS5AAAAAgkABEwAAAACAwUAAAAHaXNXYXZlcwIAAAAfJXMlZF9fdG90YWxXYXZlc0Ftb3VudEZvclBlcmlvZAIAAAAeJXMlZF9fdG90YWxVc2RuQW1vdW50Rm9yUGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kBQAAAANuaWwFAAAAA1NFUAEAAAAOa2V5VG90YWxBbW91bnQAAAABAAAAB2lzV2F2ZXMDBQAAAAdpc1dhdmVzAgAAABQlc19fdG90YWxXYXZlc0Ftb3VudAIAAAATJXNfX3RvdGFsVXNkbkFtb3VudAEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABAAAABnBlcmlvZAkABLkAAAACCQAETAAAAAICAAAAGiVzJWRfX3RvdGFsV2VpZ2h0Rm9yUGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kBQAAAANuaWwFAAAAA1NFUAEAAAAWa2V5VXNlcktWYWx1ZUZvclBlcmlvZAAAAAIAAAAGcGVyaW9kAAAACXVzZXJJbmRleAkABLkAAAACCQAETAAAAAICAAAAFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAJdXNlckluZGV4CQAETAAAAAICAAAAAWsJAARMAAAAAgkAAaQAAAABBQAAAAZwZXJpb2QFAAAAA25pbAUAAAADU0VQAQAAABZrZXlVc2VyQlZhbHVlRm9yUGVyaW9kAAAAAgAAAAZwZXJpb2QAAAAJdXNlckluZGV4CQAEuQAAAAIJAARMAAAAAgIAAAAXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAARMAAAAAgkAAaQAAAABBQAAAAl1c2VySW5kZXgJAARMAAAAAgIAAAABYgkABEwAAAACCQABpAAAAAEFAAAABnBlcmlvZAUAAAADbmlsBQAAAANTRVABAAAADEhpc3RvcnlFbnRyeQAAAAcAAAAEdHlwZQAAAAR1c2VyAAAACnVzZG5BbW91bnQAAAAMd2F2ZXNBYW1vdW50AAAADWN1cnJlbnRQZXJpb2QAAAAMbGF0ZXN0UGVyaW9kAAAAAWkEAAAACmhpc3RvcnlLRVkJAAS5AAAAAgkABEwAAAACAgAAABElcyVzJXMlc19faGlzdG9yeQkABEwAAAACBQAAAAR0eXBlCQAETAAAAAIFAAAABHVzZXIJAARMAAAAAgkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkBQAAAANuaWwFAAAAA1NFUAQAAAALaGlzdG9yeURBVEEJAAS5AAAAAgkABEwAAAACAgAAAAwlZCVkJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAABmhlaWdodAkABEwAAAACCQABpAAAAAEIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQAETAAAAAIJAAGkAAAAAQUAAAAKdXNkbkFtb3VudAkABEwAAAACCQABpAAAAAEFAAAADHdhdmVzQWFtb3VudAkABEwAAAACCQABpAAAAAEFAAAADWN1cnJlbnRQZXJpb2QJAARMAAAAAgkAAaQAAAABBQAAAAxsYXRlc3RQZXJpb2QFAAAAA25pbAUAAAADU0VQCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAApoaXN0b3J5S0VZBQAAAAtoaXN0b3J5REFUQQEAAAAOZ2V0VXNkbkFzc2V0SWQAAAABAAAAF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MCAAAAEW5ldXRyaW5vX2Fzc2V0X2lkAgAAAC5tYW5kYXRvcnkga2V5IG5ldXRyaW5vX2Fzc2V0X2lkIGlzIG5vdCBkZWZpbmVkAQAAAA5nZXROc2J0QXNzZXRJZAAAAAEAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwIAAAANYm9uZF9hc3NldF9pZAIAAAAqbWFuZGF0b3J5IGtleSBib25kX2Fzc2V0X2lkIGlzIG5vdCBkZWZpbmVkAQAAAA5jYWxjVXNlcldlaWdodAAAAAQAAAAXbnNidExvY2tDb250cmFjdEFkZHJlc3MAAAAPaGVpZ2h0Rm9yUGVyaW9kAAAABnBlcmlvZAAAAAl1c2VySW5kZXgEAAAABWtMYXN0CQEAAAAca2V5TGFzdFByb2Nlc3NlZFBlcmlvZE9mVXNlcgAA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ABBuc2J0TG9ja0NvbnRyYWN0BAAAAAxsYXRlc3RQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA9rZXlMYXRlc3RQZXJpb2QAAAAABAAAAAp1c2Vyc0NvdW50CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAAF25zYnRMb2NrQ29udHJhY3RBZGRyZXNzCQEAAAANa2V5VXNlcnNDb3VudAAAAAAAAAAAAAAAAAAEAAAADnRvdGFsV2VpZ2h0S2V5CQEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kBAAAAA9oZWlnaHRGb3JQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABJrZXlIZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kAwMJAABmAAAAAgUAAAAFZGVwdGgAAAAAAAAAAAAJAABnAAAAAgUAAAAMbGF0ZXN0UGVyaW9kBQAAAA1jdXJyZW50UGVyaW9kBwQAAAACdDAJAQAAAA5jYWxjVXNlcldlaWdodAAAAAQFAAAAF25zYnRMb2NrQ29udHJhY3RBZGRyZXNzBQAAAA9oZWlnaHRGb3JQZXJpb2QFAAAADWN1cnJlbnRQZXJpb2QFAAAAC2N1cnJlbnRVc2VyBAAAAAd3ZWlnaHQwCQAAZAAAAAIFAAAAC3RvdGFsV2VpZ2h0CAUAAAACdDAAAAACXzEDCQAAZgAAAAIFAAAACnVzZXJzQ291bnQJAABkAAAAAgUAAAALY3VycmVudFVzZXIAAAAAAAAAAAEEAAAAAnQxCQEAAAAOY2FsY1VzZXJXZWlnaHQAAAAEBQAAABduc2J0TG9ja0NvbnRyYWN0QWRkcmVzcwUAAAAPaGVpZ2h0Rm9yUGVyaW9kBQAAAA1jdXJyZW50UGVyaW9kCQAAZAAAAAIFAAAAC2N1cnJlbnRVc2VyAAAAAAAAAAABBAAAAAd3ZWlnaHQxCQAAZAAAAAIFAAAAB3dlaWdodDAIBQAAAAJ0MQAAAAJfMQMJAABmAAAAAgUAAAAKdXNlcnNDb3VudAkAAGQAAAACBQAAAAtjdXJyZW50VXNlcgAAAAAAAAAAAgQAAAACdDIJAQAAAA5jYWxjVXNlcldlaWdo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dExvY2tDb250cmFjdAAAAAZwZXJpb2QAAAAEdXNlcgAAAAVkZXB0aAAAAAl0b3RhbFVzZG4AAAAKdG90YWxXYXZlcwQAAAAGcmVzdWx0CQAD/AAAAAQFAAAABHRoaXMCAAAADmNsYWltTmV4dEJhdGNoCQAETAAAAAIFAAAAEG5zYnRMb2NrQ29udHJhY3QJAARMAAAAAgUAAAAGcGVyaW9kCQAETAAAAAIFAAAABHVzZXIJAARMAAAAAgUAAAAFZGVwdGgJAARMAAAAAgUAAAAJdG90YWxVc2RuCQAETAAAAAIFAAAACnRvdGFsV2F2ZXMFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAZyZXN1bHQFAAAABnJlc3VsdAQAAAAHJG1hdGNoMAUAAAAGcmVzdWx0AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAA8oSW50LCBJbnQsIEludCkEAAAAAXIFAAAAByRtYXRjaDAFAAAAAXIJAAACAAAAAQIAAAAXSW5jb3JyZWN0IGludm9rZSByZXN1bHQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQAAAA1jbGFpbUludGVybmFsAAAABgAAABBuc2J0TG9ja0NvbnRyYWN0AAAADWN1cnJlbnRQZXJpb2QAAAALY3VycmVudFVzZXIAAAAFZGVwdGgAAAATdXNlclVzZG5BY2N1bXVsYXRlZAAAABR1c2VyV2F2ZXNBY2N1bXVsYXRlZAQAAAAXbnNidExvY2tDb250cmFjdEFkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQUAAAAQbnNidExvY2tDb250cmFjdAQAAAAMbGF0ZXN0UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZAAAAAAEAAAAC3RvdGFsV2VpZ2h0CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kBAAAAA9oZWlnaHRGb3JQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABJrZXlIZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kBAAAAA0kdDAxMDk2MzExMDc1CQEAAAAOY2FsY1VzZXJXZWlnaHQAAAAEBQAAABduc2J0TG9ja0NvbnRyYWN0QWRkcmVzcwUAAAAPaGVpZ2h0Rm9yUGVyaW9kBQAAAA1jdXJyZW50UGVyaW9kBQAAAAtjdXJyZW50VXNlcgQAAAAKdXNlcldlaWdodAgFAAAADSR0MDEwOTYzMTEwNzUAAAACXzEEAAAAB2lnbm9yZWQIBQAAAA0kdDAxMDk2MzExMDc1AAAAAl8yBAAAABd1c2VyVXNkbkFtb3VudEZvclBlcmlvZAkAAGsAAAADCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QAAAACBQAAAA1jdXJyZW50UGVyaW9kBwUAAAAKdXNlcldlaWdodAUAAAALdG90YWxXZWlnaHQEAAAAGHVzZXJXYXZlc0Ftb3VudEZvclBlcmlvZAkAAGsAAAADCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QAAAACBQAAAA1jdXJyZW50UGVyaW9kBgUAAAAKdXNlcldlaWdodAUAAAALdG90YWxXZWlnaHQDAwkAAGcAAAACAAAAAAAAAAAABQAAAAVkZXB0aAYJAABnAAAAAgkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABBQAAAAxsYXRlc3RQZXJpb2QJAAUVAAAAAwkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABCQAAZAAAAAIFAAAAE3VzZXJVc2RuQWNjdW11bGF0ZWQFAAAAF3VzZXJVc2RuQW1vdW50Rm9yUGVyaW9kCQAAZAAAAAIFAAAAFHVzZXJXYXZlc0FjY3VtdWxhdGVkBQAAABh1c2VyV2F2ZXNBbW91bnRGb3JQZXJpb2QJAQAAAAtpbnZva2VDbGFpbQAAAAYFAAAAEG5zYnRMb2NrQ29udHJhY3QJAABkAAAAAgUAAAANY3VycmVudFBlcmlvZAAAAAAAAAAAAQUAAAALY3VycmVudFVzZXIJAABlAAAAAgUAAAAFZGVwdGgAAAAAAAAAAAEJAABkAAAAAgUAAAATdXNlclVzZG5BY2N1bXVsYXRlZAUAAAAXdXNlclVzZG5BbW91bnRGb3JQZXJpb2QJAABkAAAAAgUAAAAUdXNlcldhdmVzQWNjdW11bGF0ZWQFAAAAGHVzZXJXYXZlc0Ftb3VudEZvclBlcmlvZAAAAAoAAAABaQEAAAAQcHJvY2Vzc05leHRCYXRjaAAAAAUAAAAQbnNidExvY2tDb250cmFjdAAAAA1jdXJyZW50UGVyaW9kAAAAC2N1cnJlbnRVc2VyAAAABWRlcHRoAAAAC3RvdGFsV2VpZ2h0AwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAAR0aGlzCQAAAgAAAAECAAAAJFNob3VsZCBiZSBjYWxsZWQgYnkgdGhpcyBzY3JpcHQgb25seQQAAAADdHBsCQEAAAAYcHJvY2Vzc05leHRCYXRjaEludGVybmFsAAAABQUAAAAQbnNidExvY2tDb250cmFjdAUAAAANY3VycmVudFBlcmlvZAUAAAALY3VycmVudFVzZXIFAAAABWRlcHRoBQAAAAt0b3RhbFdlaWdodAkABRQAAAACCAUAAAADdHBsAAAAAl8xCQAFFQAAAAMIBQAAAAN0cGwAAAACXzIIBQAAAAN0cGwAAAACXzMIBQAAAAN0cGwAAAACXzQAAAABaQEAAAAdcHJvY2Vzc1BlbmRpbmdQZXJpb2RzQW5kVXNlcnMAAAAABAAAAA1jdXJyZW50UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZAAAAAADCQAAZgAAAAIFAAAADWN1cnJlbnRQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA9rZXlMYXRlc3RQZXJpb2QAAAAACQAAAgAAAAECAAAAEk5vdGhpbmcgdG8gcHJvY2VzcwQAAAAIY2ZnQXJyYXkJAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAABAAAAAVkZXB0aAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAAA5JZHhDZmdNYXhEZXB0aAMJAABmAAAAAgUAAAAFZGVwdGgFAAAACE1BWERFUFRICQAAAgAAAAECAAAAFkRlcHRoIGV4Y2VlZHMgTUFYREVQVEgEAAAAEG5zYnRMb2NrQ29udHJhY3QJAAJZAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAWSWR4Q2ZnTnNidExvY2tDb250cmFjdAQAAAALY3VycmVudFVzZXIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABRrZXlOZXh0UHJvY2Vzc2VkVXNlcgAAAAAEAAAAC3RvdGFsV2VpZ2h0CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kBAAAAAFyCQEAAAAYcHJvY2Vzc05leHRCYXRjaEludGVybmFsAAAABQUAAAAQbnNidExvY2tDb250cmFjdAUAAAANY3VycmVudFBlcmlvZAUAAAALY3VycmVudFVzZXIFAAAABWRlcHRoBQAAAAt0b3RhbFdlaWdodAkABE0AAAACCQAETQAAAAIIBQAAAAFyAAAAAl8xCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFmtleU5leHRQcm9jZXNzZWRQZXJpb2QAAAAACAUAAAABcgAAAAJfMgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABRrZXlOZXh0UHJvY2Vzc2VkVXNlcgAAAAAIBQAAAAFyAAAAAl8zAAAAAWkBAAAAB2RlcG9zaXQAAAAABAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOZXV0cmlub0NvbnRyYWN0AwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAABBuZXV0cmlub0NvbnRyYWN0CQAAAgAAAAECAAAAFFdyb25nIGNhbGxlciBhZGRyZXNzBAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAAB2Fzc2V0SWQIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAAGcGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAANa2V5TmV4dFBlcmlvZAAAAAAEAAAABGhSYXcJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEmtleUhlaWdodEZvclBlcmlvZAAAAAEFAAAABnBlcmlvZAQAAAAFZGVsYXkJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAARSWR4Q2ZnUGVyaW9kRGVsYXkDCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABBQAAAARoUmF3CQEAAAAMRGVwb3NpdEVudHJ5AAAAAwUAAAAGcGVyaW9kBQAAAANwbXQHAwkAAGcAAAACBQAAAAZoZWlnaHQJAABkAAAAAgkBAAAABXZhbHVlAAAAAQUAAAAEaFJhdwUAAAAFZGVsYXkJAQAAAAxEZXBvc2l0RW50cnkAAAADCQAAZAAAAAIFAAAABnBlcmlvZAAAAAAAAAAAAQUAAAADcG10BgQAAAAJa2V5QW1vdW50CQEAAAAXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QAAAACBQAAAAZwZXJpb2QJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEdW5pdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJa2V5QW1vdW50CQAAZAAAAAIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAACWtleUFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5rZXlUb3RhbEFtb3VudAAAAAEJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEdW5pdAkAAGQAAAACCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAOa2V5VG90YWxBbW91bnQAAAABCQAAAAAAAAIFAAAAB2Fzc2V0SWQFAAAABHVuaXQIBQAAAANwbXQAAAAGYW1vdW50BQAAAANuaWwAAAABaQEAAAAOY2xhaW1OZXh0QmF0Y2gAAAAGAAAAEG5zYnRMb2NrQ29udHJhY3QAAAANY3VycmVudFBlcmlvZAAAAAtjdXJyZW50VXNlcgAAAAVkZXB0aAAAAA91c2RuQWNjdW11bGF0ZWQAAAAQd2F2ZXNBY2N1bXVsYXRlZAMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAACRTaG91bGQgYmUgY2FsbGVkIGJ5IHRoaXMgc2NyaXB0IG9ubHkEAAAAD3BlcmlvZEFuZFRvdGFscwkBAAAADWNsYWltSW50ZXJuYWwAAAAGBQAAABBuc2J0TG9ja0NvbnRyYWN0BQAAAA1jdXJyZW50UGVyaW9kBQAAAAtjdXJyZW50VXNlcgUAAAAFZGVwdGgFAAAAD3VzZG5BY2N1bXVsYXRlZAUAAAAQd2F2ZXNBY2N1bXVsYXRlZAkABRQAAAACBQAAAANuaWwFAAAAD3BlcmlvZEFuZFRvdGFscwAAAAFpAQAAAAtjbGFpbVJld2FyZAAAAAAEAAAACGNmZ0FycmF5CQEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAQAAAAHYWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAB3VzZXJJZHgJAQAAABVnZXRVc2VySW5kZXhCeUFkZHJlc3MAAAACCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOc2J0TG9ja0NvbnRyYWN0BQAAAAdhZGRyZXNzBAAAAA1jdXJyZW50UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAba2V5TmV4dFVubGFpbWVkUGVyaW9kT2ZVc2VyAAAAAQUAAAAHdXNlcklkeAQAAAAMbGF0ZXN0UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZAAAAAADCQAAZwAAAAIFAAAADWN1cnJlbnRQZXJpb2QFAAAADGxhdGVzdFBlcmlvZAkAAAIAAAABAgAAABBOb3RoaW5nIHRvIGNsYWltBAAAABBuc2J0TG9ja0NvbnRyYWN0CQACWQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAFklkeENmZ05zYnRMb2NrQ29udHJhY3QEAAAADSR0MDE1NTg3MTU2OTkJAQAAAA1jbGFpbUludGVybmFsAAAABgUAAAAQbnNidExvY2tDb250cmFjdAUAAAANY3VycmVudFBlcmlvZAUAAAAHdXNlcklkeAUAAAAJVVNFUkRFUFRIAAAAAAAAAAAAAAAAAAAAAAAABAAAAAZwZXJpb2QIBQAAAA0kdDAxNTU4NzE1Njk5AAAAAl8xBAAAAAp1c2RuQW1vdW50CAUAAAANJHQwMTU1ODcxNTY5OQAAAAJfMgQAAAALd2F2ZXNBbW91bnQIBQAAAA0kdDAxNTU4NzE1Njk5AAAAAl8zAwMJAABnAAAAAgAAAAAAAAAAAAUAAAAKdXNkbkFtb3VudAkAAGcAAAACAAAAAAAAAAAABQAAAAt3YXZlc0Ftb3VudAcJAAACAAAAAQIAAAAUTm8gcGF5b3V0cyBhdmFpbGFibGUEAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOZXV0cmlub0NvbnRyYWN0CQAFFAAAAAIJAAROAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAG2tleU5leHRVbmxhaW1lZFBlcmlvZE9mVXNlcgAAAAEFAAAAB3VzZXJJZHgFAAAABnBlcmlvZAkABEwAAAACCQEAAAAMSGlzdG9yeUVudHJ5AAAABwIAAAALY2xhaW1SZXdhcmQFAAAAB2FkZHJlc3MFAAAACnVzZG5BbW91bnQFAAAAC3dhdmVzQW1vdW50BQAAAAZwZXJpb2QFAAAADGxhdGVzdFBlcmlvZAUAAAABaQUAAAADbmlsAwkAAGYAAAACBQAAAAp1c2RuQW1vdW50AAAAAAAAAAAACQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKdXNkbkFtb3VudAkAAlkAAAABCQEAAAAOZ2V0VXNkbkFzc2V0SWQAAAABBQAAABBuZXV0cmlub0NvbnRyYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOa2V5VG90YWxBbW91bnQAAAABBwkAAGUAAAACCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAOa2V5VG90YWxBbW91bnQAAAABBwUAAAAKdXNkbkFtb3VudAUAAAADbmlsCQAETgAAAAIFAAAAA25pbAMJAABmAAAAAgUAAAALd2F2ZXNBbW91bnQAAAAAAAAAAAAJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAt3YXZlc0Ftb3VudAUAAAAEdW5pdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVRvdGFsQW1vdW50AAAAAQYJAABlAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAADmtleVRvdGFsQW1vdW50AAAAAQYFAAAAC3dhdmVzQW1vdW50BQAAAANuaWwFAAAAA25pbAkABRQAAAACBQAAAAp1c2RuQW1vdW50BQAAAAt3YXZlc0Ftb3VudAAAAAFpAQAAABxjYWxjR292ZXJuYW5jZVBhcmFtc1JFQURPTkxZAAAAAwAAABBuc2J0TG9ja2VkQW1vdW50AAAAD2xvY2tTdGFydEhlaWdodAAAABJsb2NrRHVyYXRpb25CbG9ja3MEAAAACGNmZ0FycmF5CQEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAQAAAAQbnNidExvY2tDb250cmFjdAkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOc2J0TG9ja0NvbnRyYWN0BAAAAAttYXhEdXJhdGlvbgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgkBAAAAB0FkZHJlc3MAAAABBQAAABBuc2J0TG9ja0NvbnRyYWN0CQEAAAASa2V5TWF4TG9ja0R1cmF0aW9uAAAAAAQAAAANbG9ja0VuZEhlaWdodAkAAGQAAAACBQAAAA9sb2NrU3RhcnRIZWlnaHQFAAAAEmxvY2tEdXJhdGlvbkJsb2NrcwQAAAABawkBAAAAAS0AAAABCQAAawAAAAMFAAAAEG5zYnRMb2NrZWRBbW91bnQFAAAABVNDQUxFBQAAAAttYXhEdXJhdGlvbgQAAAABYgkAAGgAAAACCQEAAAABLQAAAAEFAAAAAWsFAAAADWxvY2tFbmRIZWlnaHQJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAAAWsJAARMAAAAAgUAAAABYgkABEwAAAACCQEAAAAKbmV4dFBlcmlvZAAAAAAFAAAAA25pbAAAAAFpAQAAABZnZXRUb3RhbFJld2FyZFJFQURPTkxZAAAAAAkABRQAAAACBQAAAANuaWwJAARMAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAADmtleVRvdGFsQW1vdW50AAAAAQcJAARMAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAADmtleVRvdGFsQW1vdW50AAAAAQYFAAAAA25pbAAAAAFpAQAAAA5wYXJhbXNSRUFET05MWQAAAAAEAAAACGNmZ0FycmF5CQEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAQAAAALcGVyaW9kRGVsYXkJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAARSWR4Q2ZnUGVyaW9kRGVsYXkJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAAC3BlcmlvZERlbGF5BQAAAANuaWwAAAABaQEAAAAgcmV3YXJkc1BlckdOc2J0Rm9yUGVyaW9kUkVBRE9OTFkAAAABAAAABnBlcmlvZAQAAAAMbGF0ZXN0UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAPa2V5TGF0ZXN0UGVyaW9kAAAAAAMDCQAAZgAAAAIAAAAAAAAAAAAFAAAABnBlcmlvZAYJAABmAAAAAgUAAAAGcGVyaW9kBQAAAAxsYXRlc3RQZXJpb2QJAAACAAAAAQIAAAAOSW52YWxpZCBwZXJpb2QEAAAAC3RvdGFsV2VpZ2h0CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABBQAAAAZwZXJpb2QEAAAADSR0MDE3NjczMTc5MTQDCQAAZgAAAAIFAAAAC3RvdGFsV2VpZ2h0AAAAAAAAAAAACQAFFAAAAAIJAABpAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAF2tleVRvdGFsQW1vdW50Rm9yUGVyaW9kAAAAAgUAAAAGcGVyaW9kBgUAAAALdG90YWxXZWlnaHQJAABpAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAF2tleVRvdGFsQW1vdW50Rm9yUGVyaW9kAAAAAgUAAAAGcGVyaW9kBwUAAAALdG90YWxXZWlnaHQJAAUUAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAQAAAANd2F2ZXNQZXJHTnNidAgFAAAADSR0MDE3NjczMTc5MTQAAAACXzEEAAAADHVzZG5QZXJHTnNidAgFAAAADSR0MDE3NjczMTc5MTQAAAACXzIJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAADXdhdmVzUGVyR05zYnQJAARMAAAAAgUAAAAMdXNkblBlckdOc2J0BQAAAANuaWwAAAABaQEAAAALY29uc3RydWN0b3IAAAAEAAAAGm5ldXRyaW5vQ29udHJhY3RBZGRyZXNzU3RyAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyAAAACG1heERlcHRoAAAAC3BlcmlvZERlbGF5AwkBAAAAAiE9AAAAAgUAAAAEdGhpcwgFAAAAAWkAAAAGY2FsbGVyCQAAAgAAAAECAAAADm5vdCBhdXRob3JpemVkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAlrZXlDb25maWcAAAAACQEAAAAMZm9ybWF0Q29uZmlnAAAABAUAAAAabmV1dHJpbm9Db250cmFjdEFkZHJlc3NTdHIFAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyBQAAAAhtYXhEZXB0aAUAAAALcGVyaW9kRGVsYXkFAAAAA25pbAAAAABiNwlu", "height": 1902975, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: GvKcfmg4N5vRs6KQWsrCE1WL1BS73bPidhfYeMHkMeyX Next: GjVctdxeMZEvRrm783dvzbK9MACnyfsz8d2bNdweL8L6 Diff:
OldNewDifferences
3838
3939
4040 func keyUsersCount () = "%s__nextUserNum"
41+
42+
43+func keyMaxLockDuration () = "%s__maxLockDuration"
4144
4245
4346 func keyNextProcessedUser () = "%s__nextProcessedUser"
9396 func getNsbtAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "bond_asset_id"), "mandatory key bond_asset_id is not defined")
9497
9598
96-func calcWeight (nsbtLockContractAddress,period,user,periodHeight,periods,users) = {
97- let k = value(getInteger(nsbtLockContractAddress, keyUserKValueForPeriod(period, user)))
98- let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, user)))
99- let w = ((k * periodHeight) + b)
100- if ((w > 0))
101- then $Tuple4((w / SCALE), nil, periods, users)
102- else $Tuple4(0, nil, periods, users)
103- }
104-
105-
106-func calcUserWeight (nsbtLockContractAddress,heightForPeriod,period,userIndex,periods,users) = {
99+func calcUserWeight (nsbtLockContractAddress,heightForPeriod,period,userIndex) = {
107100 let kLast = keyLastProcessedPeriodOfUser(userIndex)
108101 let kKey = keyUserKValueForPeriod(period, userIndex)
109102 let kRaw = getInteger(nsbtLockContractAddress, kKey)
113106 let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, userIndex)))
114107 let w = ((k * heightForPeriod) + b)
115108 if ((w > 0))
116- then {
117- let idx = indexOf(users, userIndex)
118- if (isDefined(idx))
119- then $Tuple4((w / SCALE), [IntegerEntry(kLast, period)], (removeByIndex(periods, value(idx)) :+ period), (removeByIndex(users, value(idx)) :+ userIndex))
120- else $Tuple4((w / SCALE), [IntegerEntry(kLast, period)], (periods :+ period), (users :+ userIndex))
121- }
122- else $Tuple4(0, nil, periods, users)
109+ then $Tuple2((w / SCALE), [IntegerEntry(kLast, period)])
110+ else $Tuple2(0, nil)
123111 }
124112 else {
125113 let p = getInteger(this, kLast)
126114 if (isDefined(p))
127- then calcWeight(nsbtLockContractAddress, value(p), userIndex, heightForPeriod, periods, users)
128- else {
129- let idx = indexOf(users, userIndex)
130- if (isDefined(idx))
131- then calcWeight(nsbtLockContractAddress, periods[value(idx)], userIndex, heightForPeriod, periods, users)
132- else $Tuple4(0, nil, periods, users)
115+ then {
116+ let pv = value(p)
117+ let k = value(getInteger(nsbtLockContractAddress, keyUserKValueForPeriod(pv, userIndex)))
118+ let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(pv, userIndex)))
119+ let w = ((k * heightForPeriod) + b)
120+ if ((w > 0))
121+ then $Tuple2((w / SCALE), nil)
122+ else $Tuple2(0, nil)
133123 }
124+ else $Tuple2(0, nil)
134125 }
135126 }
136127
149140 else -1), IntegerEntry(keyHeightForPeriod(period), height), IntegerEntry(keyTotalAmountForPeriod(period, (pmt.assetId == unit)), pmt.amount), IntegerEntry(keyTotalAmount((pmt.assetId == unit)), (getNumberByKey(keyTotalAmount((pmt.assetId == unit))) + pmt.amount)), IntegerEntry(keyNextPeriod(), period)]
150141
151142
152-func invokeProcess (nsbtLockContract,period,user,depth,weight,periods,users) = {
153- let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight, periods, users], nil)
143+func invokeProcess (nsbtLockContract,period,user,depth,weight) = {
144+ let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight], nil)
154145 if ((result == result))
155146 then match result {
156- case r: (Int, Int, List[Any], List[Any], Int) =>
147+ case r: (Int, Int, Int) =>
157148 r
158149 case _ =>
159150 throw("Incorrect invoke result")
162153 }
163154
164155
165-func checkLastPartOfPeriod (nsbtLockContract,currentPeriod,latestPeriod,depth,periods,users) = if ((latestPeriod >= (currentPeriod + 1)))
166- then invokeProcess(nsbtLockContract, (currentPeriod + 1), 0, (depth - 1), 0, periods, users)
167- else $Tuple5((currentPeriod + 1), 0, nil, nil, 0)
168-
169-
170-func processNextBatchInternal (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight,periods,users) = {
156+func processNextBatchInternal (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = {
171157 let nsbtLockContractAddress = Address(nsbtLockContract)
172158 let latestPeriod = getNumberByKey(keyLatestPeriod())
173159 let usersCount = valueOrElse(getInteger(nsbtLockContractAddress, keyUsersCount()), 0)
177163 then (latestPeriod >= currentPeriod)
178164 else false)
179165 then {
180- let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser, periods, users)
166+ let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
181167 let weight0 = (totalWeight + t0._1)
182168 if ((usersCount > (currentUser + 1)))
183169 then {
184- let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1), t0._3, t0._4)
170+ let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1))
185171 let weight1 = (weight0 + t1._1)
186172 if ((usersCount > (currentUser + 2)))
187173 then {
188- let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2), t1._3, t1._4)
174+ let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2))
189175 let weight2 = (weight1 + t2._1)
190176 if ((usersCount > (currentUser + 3)))
191177 then {
192- let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3), t2._3, t2._4)
178+ let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3))
193179 let weight3 = (weight2 + t3._1)
194180 if ((usersCount > (currentUser + 4)))
195181 then {
196- let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4), t3._3, t3._4)
182+ let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4))
197183 let weight4 = (weight3 + t4._1)
198184 if ((usersCount > (currentUser + 5)))
199185 then {
200- let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5), t4._3, t4._4)
186+ let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5))
201187 let weight5 = (weight4 + t5._1)
202188 if ((usersCount > (currentUser + 6)))
203189 then {
204- let r5 = invokeProcess(nsbtLockContract, currentPeriod, (currentUser + 6), (depth - 1), weight5, t5._3, t5._4)
205- $Tuple6((((((t0._2 ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3, r5._4, r5._5)
190+ let r5 = invokeProcess(nsbtLockContract, currentPeriod, (currentUser + 6), (depth - 1), weight5)
191+ $Tuple4((((((t0._2 ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3)
206192 }
207- else {
208- let r5 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t5._3, t5._4)
209- $Tuple6((((((([IntegerEntry(totalWeightKey, weight5)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3, r5._4, r5._5)
210- }
193+ else $Tuple4((((((([IntegerEntry(totalWeightKey, weight5)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), (currentPeriod + 1), 0, 0)
211194 }
212- else {
213- let r4 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t4._3, t4._4)
214- $Tuple6(((((([IntegerEntry(totalWeightKey, weight4)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2), r4._1, r4._2, r4._3, r4._4, r4._5)
215- }
195+ else $Tuple4(((((([IntegerEntry(totalWeightKey, weight4)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2), (currentPeriod + 1), 0, 0)
216196 }
217- else {
218- let r3 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t3._3, t3._4)
219- $Tuple6((((([IntegerEntry(totalWeightKey, weight3)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2), r3._1, r3._2, r3._3, r3._4, r3._5)
220- }
197+ else $Tuple4((((([IntegerEntry(totalWeightKey, weight3)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2), (currentPeriod + 1), 0, 0)
221198 }
222- else {
223- let r2 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t2._3, t2._4)
224- $Tuple6(((([IntegerEntry(totalWeightKey, weight2)] ++ t0._2) ++ t1._2) ++ t2._2), r2._1, r2._2, r2._3, r2._4, r2._5)
225- }
199+ else $Tuple4(((([IntegerEntry(totalWeightKey, weight2)] ++ t0._2) ++ t1._2) ++ t2._2), (currentPeriod + 1), 0, 0)
226200 }
227- else {
228- let r1 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t1._3, t1._4)
229- $Tuple6((([IntegerEntry(totalWeightKey, weight1)] ++ t0._2) ++ t1._2), r1._1, r1._2, r1._3, r1._4, r1._5)
230- }
201+ else $Tuple4((([IntegerEntry(totalWeightKey, weight1)] ++ t0._2) ++ t1._2), (currentPeriod + 1), 0, 0)
231202 }
232- else {
233- let r0 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t0._3, t0._4)
234- $Tuple6(([IntegerEntry(totalWeightKey, weight0)] ++ t0._2), r0._1, r0._2, r0._3, r0._4, r0._5)
235- }
203+ else $Tuple4(([IntegerEntry(totalWeightKey, weight0)] ++ t0._2), (currentPeriod + 1), 0, 0)
236204 }
237205 else if ((currentUser == 0))
238- then $Tuple6(nil, currentPeriod, 0, nil, nil, 0)
239- else $Tuple6([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, nil, nil, 0)
206+ then $Tuple4(nil, currentPeriod, 0, 0)
207+ else $Tuple4([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, 0)
240208 }
241209
242210
258226 let latestPeriod = getNumberByKey(keyNextProcessedPeriod())
259227 let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
260228 let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
261- let $t01342213542 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser, nil, nil)
262- let userWeight = $t01342213542._1
263- let ignored = $t01342213542._2
229+ let $t01096311075 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
230+ let userWeight = $t01096311075._1
231+ let ignored = $t01096311075._2
264232 let userUsdnAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, false)), userWeight, totalWeight)
265233 let userWavesAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, true)), userWeight, totalWeight)
266234 if (if ((0 >= depth))
272240
273241
274242 @Callable(i)
275-func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight,periods,users) = if ((i.caller != this))
243+func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = if ((i.caller != this))
276244 then throw("Should be called by this script only")
277245 else {
278- let tpl = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight, periods, users)
279- $Tuple2(tpl._1, $Tuple5(tpl._2, tpl._3, tpl._4, tpl._5, tpl._6))
246+ let tpl = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
247+ $Tuple2(tpl._1, $Tuple3(tpl._2, tpl._3, tpl._4))
280248 }
281249
282250
295263 let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
296264 let currentUser = getNumberByKey(keyNextProcessedUser())
297265 let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
298- let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight, nil, nil)
266+ let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
299267 ((r._1 :+ IntegerEntry(keyNextProcessedPeriod(), r._2)) :+ IntegerEntry(keyNextProcessedUser(), r._3))
300268 }
301269 }
349317 then throw("Nothing to claim")
350318 else {
351319 let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
352- let $t01808818200 = claimInternal(nsbtLockContract, currentPeriod, userIdx, USERDEPTH, 0, 0)
353- let period = $t01808818200._1
354- let usdnAmount = $t01808818200._2
355- let wavesAmount = $t01808818200._3
320+ let $t01558715699 = claimInternal(nsbtLockContract, currentPeriod, userIdx, USERDEPTH, 0, 0)
321+ let period = $t01558715699._1
322+ let usdnAmount = $t01558715699._2
323+ let wavesAmount = $t01558715699._3
356324 if (if ((0 >= usdnAmount))
357325 then (0 >= wavesAmount)
358326 else false)
371339
372340
373341 @Callable(i)
374-func calcGovernanceParamsREADONLY (nsbtAmount,lockStartHeight,lockDurationBlocks) = {
342+func calcGovernanceParamsREADONLY (nsbtLockedAmount,lockStartHeight,lockDurationBlocks) = {
343+ let cfgArray = readConfigArrayOrFail()
344+ let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
345+ let maxDuration = getIntegerValue(Address(nsbtLockContract), keyMaxLockDuration())
375346 let lockEndHeight = (lockStartHeight + lockDurationBlocks)
376- let scale8ParamK = -(fraction(nsbtAmount, SCALE, lockDurationBlocks))
377- let scale8ParamB = (fraction(nsbtAmount, SCALE, lockDurationBlocks) * lockEndHeight)
378- $Tuple2(nil, [scale8ParamK, scale8ParamB, nextPeriod()])
347+ let k = -(fraction(nsbtLockedAmount, SCALE, maxDuration))
348+ let b = (-(k) * lockEndHeight)
349+ $Tuple2(nil, [k, b, nextPeriod()])
379350 }
380351
381352
382353
383354 @Callable(i)
384355 func getTotalRewardREADONLY () = $Tuple2(nil, [getNumberByKey(keyTotalAmount(false)), getNumberByKey(keyTotalAmount(true))])
356+
357+
358+
359+@Callable(i)
360+func paramsREADONLY () = {
361+ let cfgArray = readConfigArrayOrFail()
362+ let periodDelay = parseIntValue(cfgArray[IdxCfgPeriodDelay])
363+ $Tuple2(nil, [periodDelay])
364+ }
365+
366+
367+
368+@Callable(i)
369+func rewardsPerGNsbtForPeriodREADONLY (period) = {
370+ let latestPeriod = getNumberByKey(keyLatestPeriod())
371+ if (if ((0 > period))
372+ then true
373+ else (period > latestPeriod))
374+ then throw("Invalid period")
375+ else {
376+ let totalWeight = getNumberByKey(keyTotalWeightForPeriod(period))
377+ let $t01767317914 = if ((totalWeight > 0))
378+ then $Tuple2((getNumberByKey(keyTotalAmountForPeriod(period, true)) / totalWeight), (getNumberByKey(keyTotalAmountForPeriod(period, false)) / totalWeight))
379+ else $Tuple2(0, 0)
380+ let wavesPerGNsbt = $t01767317914._1
381+ let usdnPerGNsbt = $t01767317914._2
382+ $Tuple2(nil, [wavesPerGNsbt, usdnPerGNsbt])
383+ }
384+ }
385385
386386
387387
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let revisionNum = ""
55
66 let SEP = "__"
77
88 let MAXDEPTH = 17
99
1010 let USERDEPTH = 26
1111
1212 let SCALE = 1000
1313
1414 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
1515
1616
1717 func getStringByKey (key) = valueOrElse(getString(this, key), "")
1818
1919
2020 func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
2121
2222
2323 let IdxCfgNeutrinoContract = 1
2424
2525 let IdxCfgNsbtLockContract = 2
2626
2727 let IdxCfgMaxDepth = 3
2828
2929 let IdxCfgPeriodDelay = 4
3030
3131 func keyConfig () = "%s__config"
3232
3333
3434 func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP)
3535
3636
3737 func formatConfig (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = makeString(["%s%s%d%d", neutrinoContractAddressStr, nsbtLockContractAddressStr, toString(maxDepth), toString(periodDelay)], SEP)
3838
3939
4040 func keyUsersCount () = "%s__nextUserNum"
41+
42+
43+func keyMaxLockDuration () = "%s__maxLockDuration"
4144
4245
4346 func keyNextProcessedUser () = "%s__nextProcessedUser"
4447
4548
4649 func keyLatestPeriod () = "%s__latestPeriod"
4750
4851
4952 func keyNextPeriod () = "%s__nextPeriod"
5053
5154
5255 func keyNextProcessedPeriod () = "%s__nextProcessedPeriod"
5356
5457
5558 func keyNextUnlaimedPeriodOfUser (userIndex) = makeString(["%s%d__nextClaimedPeriod", toString(userIndex)], SEP)
5659
5760
5861 func keyLastProcessedPeriodOfUser (userIndex) = makeString(["%s%d__lastProcessedPeriod", toString(userIndex)], SEP)
5962
6063
6164 func keyHeightForPeriod (period) = makeString(["%s%d__startHeightForPeriod", toString(period)], SEP)
6265
6366
6467 func keyTotalAmountForPeriod (period,isWaves) = makeString([if (isWaves)
6568 then "%s%d__totalWavesAmountForPeriod"
6669 else "%s%d__totalUsdnAmountForPeriod", toString(period)], SEP)
6770
6871
6972 func keyTotalAmount (isWaves) = if (isWaves)
7073 then "%s__totalWavesAmount"
7174 else "%s__totalUsdnAmount"
7275
7376
7477 func keyTotalWeightForPeriod (period) = makeString(["%s%d__totalWeightForPeriod", toString(period)], SEP)
7578
7679
7780 func keyUserKValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "k", toString(period)], SEP)
7881
7982
8083 func keyUserBValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "b", toString(period)], SEP)
8184
8285
8386 func HistoryEntry (type,user,usdnAmount,wavesAamount,currentPeriod,latestPeriod,i) = {
8487 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
8588 let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(usdnAmount), toString(wavesAamount), toString(currentPeriod), toString(latestPeriod)], SEP)
8689 StringEntry(historyKEY, historyDATA)
8790 }
8891
8992
9093 func getUsdnAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "neutrino_asset_id"), "mandatory key neutrino_asset_id is not defined")
9194
9295
9396 func getNsbtAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "bond_asset_id"), "mandatory key bond_asset_id is not defined")
9497
9598
96-func calcWeight (nsbtLockContractAddress,period,user,periodHeight,periods,users) = {
97- let k = value(getInteger(nsbtLockContractAddress, keyUserKValueForPeriod(period, user)))
98- let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, user)))
99- let w = ((k * periodHeight) + b)
100- if ((w > 0))
101- then $Tuple4((w / SCALE), nil, periods, users)
102- else $Tuple4(0, nil, periods, users)
103- }
104-
105-
106-func calcUserWeight (nsbtLockContractAddress,heightForPeriod,period,userIndex,periods,users) = {
99+func calcUserWeight (nsbtLockContractAddress,heightForPeriod,period,userIndex) = {
107100 let kLast = keyLastProcessedPeriodOfUser(userIndex)
108101 let kKey = keyUserKValueForPeriod(period, userIndex)
109102 let kRaw = getInteger(nsbtLockContractAddress, kKey)
110103 if (isDefined(kRaw))
111104 then {
112105 let k = value(kRaw)
113106 let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, userIndex)))
114107 let w = ((k * heightForPeriod) + b)
115108 if ((w > 0))
116- then {
117- let idx = indexOf(users, userIndex)
118- if (isDefined(idx))
119- then $Tuple4((w / SCALE), [IntegerEntry(kLast, period)], (removeByIndex(periods, value(idx)) :+ period), (removeByIndex(users, value(idx)) :+ userIndex))
120- else $Tuple4((w / SCALE), [IntegerEntry(kLast, period)], (periods :+ period), (users :+ userIndex))
121- }
122- else $Tuple4(0, nil, periods, users)
109+ then $Tuple2((w / SCALE), [IntegerEntry(kLast, period)])
110+ else $Tuple2(0, nil)
123111 }
124112 else {
125113 let p = getInteger(this, kLast)
126114 if (isDefined(p))
127- then calcWeight(nsbtLockContractAddress, value(p), userIndex, heightForPeriod, periods, users)
128- else {
129- let idx = indexOf(users, userIndex)
130- if (isDefined(idx))
131- then calcWeight(nsbtLockContractAddress, periods[value(idx)], userIndex, heightForPeriod, periods, users)
132- else $Tuple4(0, nil, periods, users)
115+ then {
116+ let pv = value(p)
117+ let k = value(getInteger(nsbtLockContractAddress, keyUserKValueForPeriod(pv, userIndex)))
118+ let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(pv, userIndex)))
119+ let w = ((k * heightForPeriod) + b)
120+ if ((w > 0))
121+ then $Tuple2((w / SCALE), nil)
122+ else $Tuple2(0, nil)
133123 }
124+ else $Tuple2(0, nil)
134125 }
135126 }
136127
137128
138129 func getUserIndexByAddress (nsbtLockContractAddressStr,userAddress) = {
139130 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
140131 valueOrErrorMessage(getInteger(Address(fromBase58String(nsbtLockContractAddressStr)), key), ((("User address " + userAddress) + " is not found in nsbtLock contract data, key=") + key))
141132 }
142133
143134
144135 func nextPeriod () = getNumberByKey(keyNextPeriod())
145136
146137
147138 func DepositEntry (period,pmt,finalize) = [IntegerEntry(keyLatestPeriod(), if (finalize)
148139 then (period - 1)
149140 else -1), IntegerEntry(keyHeightForPeriod(period), height), IntegerEntry(keyTotalAmountForPeriod(period, (pmt.assetId == unit)), pmt.amount), IntegerEntry(keyTotalAmount((pmt.assetId == unit)), (getNumberByKey(keyTotalAmount((pmt.assetId == unit))) + pmt.amount)), IntegerEntry(keyNextPeriod(), period)]
150141
151142
152-func invokeProcess (nsbtLockContract,period,user,depth,weight,periods,users) = {
153- let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight, periods, users], nil)
143+func invokeProcess (nsbtLockContract,period,user,depth,weight) = {
144+ let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight], nil)
154145 if ((result == result))
155146 then match result {
156- case r: (Int, Int, List[Any], List[Any], Int) =>
147+ case r: (Int, Int, Int) =>
157148 r
158149 case _ =>
159150 throw("Incorrect invoke result")
160151 }
161152 else throw("Strict value is not equal to itself.")
162153 }
163154
164155
165-func checkLastPartOfPeriod (nsbtLockContract,currentPeriod,latestPeriod,depth,periods,users) = if ((latestPeriod >= (currentPeriod + 1)))
166- then invokeProcess(nsbtLockContract, (currentPeriod + 1), 0, (depth - 1), 0, periods, users)
167- else $Tuple5((currentPeriod + 1), 0, nil, nil, 0)
168-
169-
170-func processNextBatchInternal (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight,periods,users) = {
156+func processNextBatchInternal (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = {
171157 let nsbtLockContractAddress = Address(nsbtLockContract)
172158 let latestPeriod = getNumberByKey(keyLatestPeriod())
173159 let usersCount = valueOrElse(getInteger(nsbtLockContractAddress, keyUsersCount()), 0)
174160 let totalWeightKey = keyTotalWeightForPeriod(currentPeriod)
175161 let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
176162 if (if ((depth > 0))
177163 then (latestPeriod >= currentPeriod)
178164 else false)
179165 then {
180- let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser, periods, users)
166+ let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
181167 let weight0 = (totalWeight + t0._1)
182168 if ((usersCount > (currentUser + 1)))
183169 then {
184- let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1), t0._3, t0._4)
170+ let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1))
185171 let weight1 = (weight0 + t1._1)
186172 if ((usersCount > (currentUser + 2)))
187173 then {
188- let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2), t1._3, t1._4)
174+ let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2))
189175 let weight2 = (weight1 + t2._1)
190176 if ((usersCount > (currentUser + 3)))
191177 then {
192- let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3), t2._3, t2._4)
178+ let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3))
193179 let weight3 = (weight2 + t3._1)
194180 if ((usersCount > (currentUser + 4)))
195181 then {
196- let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4), t3._3, t3._4)
182+ let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4))
197183 let weight4 = (weight3 + t4._1)
198184 if ((usersCount > (currentUser + 5)))
199185 then {
200- let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5), t4._3, t4._4)
186+ let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5))
201187 let weight5 = (weight4 + t5._1)
202188 if ((usersCount > (currentUser + 6)))
203189 then {
204- let r5 = invokeProcess(nsbtLockContract, currentPeriod, (currentUser + 6), (depth - 1), weight5, t5._3, t5._4)
205- $Tuple6((((((t0._2 ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3, r5._4, r5._5)
190+ let r5 = invokeProcess(nsbtLockContract, currentPeriod, (currentUser + 6), (depth - 1), weight5)
191+ $Tuple4((((((t0._2 ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3)
206192 }
207- else {
208- let r5 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t5._3, t5._4)
209- $Tuple6((((((([IntegerEntry(totalWeightKey, weight5)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3, r5._4, r5._5)
210- }
193+ else $Tuple4((((((([IntegerEntry(totalWeightKey, weight5)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), (currentPeriod + 1), 0, 0)
211194 }
212- else {
213- let r4 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t4._3, t4._4)
214- $Tuple6(((((([IntegerEntry(totalWeightKey, weight4)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2), r4._1, r4._2, r4._3, r4._4, r4._5)
215- }
195+ else $Tuple4(((((([IntegerEntry(totalWeightKey, weight4)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2), (currentPeriod + 1), 0, 0)
216196 }
217- else {
218- let r3 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t3._3, t3._4)
219- $Tuple6((((([IntegerEntry(totalWeightKey, weight3)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2), r3._1, r3._2, r3._3, r3._4, r3._5)
220- }
197+ else $Tuple4((((([IntegerEntry(totalWeightKey, weight3)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2), (currentPeriod + 1), 0, 0)
221198 }
222- else {
223- let r2 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t2._3, t2._4)
224- $Tuple6(((([IntegerEntry(totalWeightKey, weight2)] ++ t0._2) ++ t1._2) ++ t2._2), r2._1, r2._2, r2._3, r2._4, r2._5)
225- }
199+ else $Tuple4(((([IntegerEntry(totalWeightKey, weight2)] ++ t0._2) ++ t1._2) ++ t2._2), (currentPeriod + 1), 0, 0)
226200 }
227- else {
228- let r1 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t1._3, t1._4)
229- $Tuple6((([IntegerEntry(totalWeightKey, weight1)] ++ t0._2) ++ t1._2), r1._1, r1._2, r1._3, r1._4, r1._5)
230- }
201+ else $Tuple4((([IntegerEntry(totalWeightKey, weight1)] ++ t0._2) ++ t1._2), (currentPeriod + 1), 0, 0)
231202 }
232- else {
233- let r0 = checkLastPartOfPeriod(nsbtLockContract, currentPeriod, latestPeriod, depth, t0._3, t0._4)
234- $Tuple6(([IntegerEntry(totalWeightKey, weight0)] ++ t0._2), r0._1, r0._2, r0._3, r0._4, r0._5)
235- }
203+ else $Tuple4(([IntegerEntry(totalWeightKey, weight0)] ++ t0._2), (currentPeriod + 1), 0, 0)
236204 }
237205 else if ((currentUser == 0))
238- then $Tuple6(nil, currentPeriod, 0, nil, nil, 0)
239- else $Tuple6([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, nil, nil, 0)
206+ then $Tuple4(nil, currentPeriod, 0, 0)
207+ else $Tuple4([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, 0)
240208 }
241209
242210
243211 func invokeClaim (nsbtLockContract,period,user,depth,totalUsdn,totalWaves) = {
244212 let result = invoke(this, "claimNextBatch", [nsbtLockContract, period, user, depth, totalUsdn, totalWaves], nil)
245213 if ((result == result))
246214 then match result {
247215 case r: (Int, Int, Int) =>
248216 r
249217 case _ =>
250218 throw("Incorrect invoke result")
251219 }
252220 else throw("Strict value is not equal to itself.")
253221 }
254222
255223
256224 func claimInternal (nsbtLockContract,currentPeriod,currentUser,depth,userUsdnAccumulated,userWavesAccumulated) = {
257225 let nsbtLockContractAddress = Address(nsbtLockContract)
258226 let latestPeriod = getNumberByKey(keyNextProcessedPeriod())
259227 let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
260228 let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
261- let $t01342213542 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser, nil, nil)
262- let userWeight = $t01342213542._1
263- let ignored = $t01342213542._2
229+ let $t01096311075 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
230+ let userWeight = $t01096311075._1
231+ let ignored = $t01096311075._2
264232 let userUsdnAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, false)), userWeight, totalWeight)
265233 let userWavesAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, true)), userWeight, totalWeight)
266234 if (if ((0 >= depth))
267235 then true
268236 else ((currentPeriod + 1) >= latestPeriod))
269237 then $Tuple3((currentPeriod + 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod))
270238 else invokeClaim(nsbtLockContract, (currentPeriod + 1), currentUser, (depth - 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod))
271239 }
272240
273241
274242 @Callable(i)
275-func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight,periods,users) = if ((i.caller != this))
243+func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = if ((i.caller != this))
276244 then throw("Should be called by this script only")
277245 else {
278- let tpl = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight, periods, users)
279- $Tuple2(tpl._1, $Tuple5(tpl._2, tpl._3, tpl._4, tpl._5, tpl._6))
246+ let tpl = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
247+ $Tuple2(tpl._1, $Tuple3(tpl._2, tpl._3, tpl._4))
280248 }
281249
282250
283251
284252 @Callable(i)
285253 func processPendingPeriodsAndUsers () = {
286254 let currentPeriod = getNumberByKey(keyNextProcessedPeriod())
287255 if ((currentPeriod > getNumberByKey(keyLatestPeriod())))
288256 then throw("Nothing to process")
289257 else {
290258 let cfgArray = readConfigArrayOrFail()
291259 let depth = parseIntValue(cfgArray[IdxCfgMaxDepth])
292260 if ((depth > MAXDEPTH))
293261 then throw("Depth exceeds MAXDEPTH")
294262 else {
295263 let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
296264 let currentUser = getNumberByKey(keyNextProcessedUser())
297265 let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
298- let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight, nil, nil)
266+ let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
299267 ((r._1 :+ IntegerEntry(keyNextProcessedPeriod(), r._2)) :+ IntegerEntry(keyNextProcessedUser(), r._3))
300268 }
301269 }
302270 }
303271
304272
305273
306274 @Callable(i)
307275 func deposit () = {
308276 let cfgArray = readConfigArrayOrFail()
309277 let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract]))
310278 if ((i.caller != neutrinoContract))
311279 then throw("Wrong caller address")
312280 else {
313281 let pmt = value(i.payments[0])
314282 let assetId = pmt.assetId
315283 let period = getNumberByKey(keyNextPeriod())
316284 let hRaw = getInteger(this, keyHeightForPeriod(period))
317285 let delay = parseIntValue(cfgArray[IdxCfgPeriodDelay])
318286 if (!(isDefined(hRaw)))
319287 then DepositEntry(period, pmt, false)
320288 else if ((height >= (value(hRaw) + delay)))
321289 then DepositEntry((period + 1), pmt, true)
322290 else {
323291 let keyAmount = keyTotalAmountForPeriod(period, (assetId == unit))
324292 [IntegerEntry(keyAmount, (getNumberByKey(keyAmount) + pmt.amount)), IntegerEntry(keyTotalAmount((assetId == unit)), (getNumberByKey(keyTotalAmount((assetId == unit))) + pmt.amount))]
325293 }
326294 }
327295 }
328296
329297
330298
331299 @Callable(i)
332300 func claimNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,usdnAccumulated,wavesAccumulated) = if ((i.caller != this))
333301 then throw("Should be called by this script only")
334302 else {
335303 let periodAndTotals = claimInternal(nsbtLockContract, currentPeriod, currentUser, depth, usdnAccumulated, wavesAccumulated)
336304 $Tuple2(nil, periodAndTotals)
337305 }
338306
339307
340308
341309 @Callable(i)
342310 func claimReward () = {
343311 let cfgArray = readConfigArrayOrFail()
344312 let address = toString(i.caller)
345313 let userIdx = getUserIndexByAddress(cfgArray[IdxCfgNsbtLockContract], address)
346314 let currentPeriod = getNumberByKey(keyNextUnlaimedPeriodOfUser(userIdx))
347315 let latestPeriod = getNumberByKey(keyNextProcessedPeriod())
348316 if ((currentPeriod >= latestPeriod))
349317 then throw("Nothing to claim")
350318 else {
351319 let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
352- let $t01808818200 = claimInternal(nsbtLockContract, currentPeriod, userIdx, USERDEPTH, 0, 0)
353- let period = $t01808818200._1
354- let usdnAmount = $t01808818200._2
355- let wavesAmount = $t01808818200._3
320+ let $t01558715699 = claimInternal(nsbtLockContract, currentPeriod, userIdx, USERDEPTH, 0, 0)
321+ let period = $t01558715699._1
322+ let usdnAmount = $t01558715699._2
323+ let wavesAmount = $t01558715699._3
356324 if (if ((0 >= usdnAmount))
357325 then (0 >= wavesAmount)
358326 else false)
359327 then throw("No payouts available")
360328 else {
361329 let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract]))
362330 $Tuple2(([IntegerEntry(keyNextUnlaimedPeriodOfUser(userIdx), period), HistoryEntry("claimReward", address, usdnAmount, wavesAmount, period, latestPeriod, i)] ++ (if ((usdnAmount > 0))
363331 then [ScriptTransfer(i.caller, usdnAmount, fromBase58String(getUsdnAssetId(neutrinoContract))), IntegerEntry(keyTotalAmount(false), (getNumberByKey(keyTotalAmount(false)) - usdnAmount))]
364332 else (nil ++ (if ((wavesAmount > 0))
365333 then [ScriptTransfer(i.caller, wavesAmount, unit), IntegerEntry(keyTotalAmount(true), (getNumberByKey(keyTotalAmount(true)) - wavesAmount))]
366334 else nil)))), $Tuple2(usdnAmount, wavesAmount))
367335 }
368336 }
369337 }
370338
371339
372340
373341 @Callable(i)
374-func calcGovernanceParamsREADONLY (nsbtAmount,lockStartHeight,lockDurationBlocks) = {
342+func calcGovernanceParamsREADONLY (nsbtLockedAmount,lockStartHeight,lockDurationBlocks) = {
343+ let cfgArray = readConfigArrayOrFail()
344+ let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
345+ let maxDuration = getIntegerValue(Address(nsbtLockContract), keyMaxLockDuration())
375346 let lockEndHeight = (lockStartHeight + lockDurationBlocks)
376- let scale8ParamK = -(fraction(nsbtAmount, SCALE, lockDurationBlocks))
377- let scale8ParamB = (fraction(nsbtAmount, SCALE, lockDurationBlocks) * lockEndHeight)
378- $Tuple2(nil, [scale8ParamK, scale8ParamB, nextPeriod()])
347+ let k = -(fraction(nsbtLockedAmount, SCALE, maxDuration))
348+ let b = (-(k) * lockEndHeight)
349+ $Tuple2(nil, [k, b, nextPeriod()])
379350 }
380351
381352
382353
383354 @Callable(i)
384355 func getTotalRewardREADONLY () = $Tuple2(nil, [getNumberByKey(keyTotalAmount(false)), getNumberByKey(keyTotalAmount(true))])
356+
357+
358+
359+@Callable(i)
360+func paramsREADONLY () = {
361+ let cfgArray = readConfigArrayOrFail()
362+ let periodDelay = parseIntValue(cfgArray[IdxCfgPeriodDelay])
363+ $Tuple2(nil, [periodDelay])
364+ }
365+
366+
367+
368+@Callable(i)
369+func rewardsPerGNsbtForPeriodREADONLY (period) = {
370+ let latestPeriod = getNumberByKey(keyLatestPeriod())
371+ if (if ((0 > period))
372+ then true
373+ else (period > latestPeriod))
374+ then throw("Invalid period")
375+ else {
376+ let totalWeight = getNumberByKey(keyTotalWeightForPeriod(period))
377+ let $t01767317914 = if ((totalWeight > 0))
378+ then $Tuple2((getNumberByKey(keyTotalAmountForPeriod(period, true)) / totalWeight), (getNumberByKey(keyTotalAmountForPeriod(period, false)) / totalWeight))
379+ else $Tuple2(0, 0)
380+ let wavesPerGNsbt = $t01767317914._1
381+ let usdnPerGNsbt = $t01767317914._2
382+ $Tuple2(nil, [wavesPerGNsbt, usdnPerGNsbt])
383+ }
384+ }
385385
386386
387387
388388 @Callable(i)
389389 func constructor (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = if ((this != i.caller))
390390 then throw("not authorized")
391391 else [StringEntry(keyConfig(), formatConfig(neutrinoContractAddressStr, nsbtLockContractAddressStr, maxDepth, periodDelay))]
392392
393393

github/deemru/w8io/873ac7e 
144.39 ms