tx · 9jR4bFgiSYbqmqLn1rrPXR3WJiexqpJcFWUgYNbmWh3o 3N3GoRY8jrcttJ8MPUwKvo4B5ng3ovFnRDp: -0.01000000 Waves 2022.01.12 13:45 [1875634] smart account 3N3GoRY8jrcttJ8MPUwKvo4B5ng3ovFnRDp > SELF 0.00000000 Waves
{ "type": 13, "id": "9jR4bFgiSYbqmqLn1rrPXR3WJiexqpJcFWUgYNbmWh3o", "fee": 1000000, "feeAssetId": null, "timestamp": 1641984349513, "version": 2, "chainId": 84, "sender": "3N3GoRY8jrcttJ8MPUwKvo4B5ng3ovFnRDp", "senderPublicKey": "EaCtGGjVDPVdseZXSPyhxjMfa5vh67c3xxy6M4Kz5EeB", "proofs": [ "31WnUHzxq4eGEkUraVuJwjDT6Hes6HLDKm3NjCUveHi2YkDKSQjgcPc9BKZZjnhVwG6kjWkjx81gJeEYQ5XtZYri" ], "script": "base64:AAIFAAAAAAAAAC4IAhIJCgcCAQEBAREREgASABIICgYCAQEBAQESABIFCgMBAQESABIGCgQICAEBAAAAKQAAAAALcmV2aXNpb25OdW0CAAAAAAAAAAADU0VQAgAAAAJfXwAAAAAITUFYREVQVEgAAAAAAAAAABEAAAAACVVTRVJERVBUSAAAAAAAAAAAGgAAAAAFU0NBTEUAAAAAAAAAA+gBAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AAAAAAAAAAAAAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAA2tleQIAAAAAAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEIgAAAAEFAAAAA2tleQkAASwAAAACCQABLAAAAAICAAAAD21hbmRhdG9yeSB0aGlzLgUAAAADa2V5AgAAAA8gaXMgbm90IGRlZmluZWQAAAAAFklkeENmZ05ldXRyaW5vQ29udHJhY3QAAAAAAAAAAAEAAAAAFklkeENmZ05zYnRMb2NrQ29udHJhY3QAAAAAAAAAAAIAAAAADklkeENmZ01heERlcHRoAAAAAAAAAAADAAAAABFJZHhDZmdQZXJpb2REZWxheQAAAAAAAAAABAEAAAAJa2V5Q29uZmlnAAAAAAIAAAAKJXNfX2NvbmZpZwEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAkABLUAAAACCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQkBAAAACWtleUNvbmZpZwAAAAAFAAAAA1NFUAEAAAAMZm9ybWF0Q29uZmlnAAAABAAAABpuZXV0cmlub0NvbnRyYWN0QWRkcmVzc1N0cgAAABpuc2J0TG9ja0NvbnRyYWN0QWRkcmVzc1N0cgAAAAhtYXhEZXB0aAAAAAtwZXJpb2REZWxheQkABLkAAAACCQAETAAAAAICAAAACCVzJXMlZCVkCQAETAAAAAIFAAAAGm5ldXRyaW5vQ29udHJhY3RBZGRyZXNzU3RyCQAETAAAAAIFAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyCQAETAAAAAIJAAGkAAAAAQUAAAAIbWF4RGVwdGgJAARMAAAAAgkAAaQAAAABBQAAAAtwZXJpb2REZWxheQUAAAADbmlsBQAAAANTRVABAAAADWtleVVzZXJzQ291bnQAAAAAAgAAAA8lc19fbmV4dFVzZXJOdW0BAAAAFGtleU5leHRQcm9jZXNzZWRVc2VyAAAAAAIAAAAVJXNfX25leHRQcm9jZXNzZWRVc2VyAQAAAA9rZXlMYXRlc3RQZXJpb2QAAAAAAgAAABAlc19fbGF0ZXN0UGVyaW9kAQAAAA1rZXlOZXh0UGVyaW9kAAAAAAIAAAAOJXNfX25leHRQZXJpb2QBAAAAFmtleU5leHRQcm9jZXNzZWRQZXJpb2QAAAAAAgAAABclc19fbmV4dFByb2Nlc3NlZFBlcmlvZAEAAAAba2V5TmV4dFVubGFpbWVkUGVyaW9kT2ZVc2VyAAAAAQAAAAl1c2VySW5kZXgJAAS5AAAAAgkABEwAAAACAgAAABclcyVkX19uZXh0Q2xhaW1lZFBlcmlvZAkABEwAAAACCQABpAAAAAEFAAAACXVzZXJJbmRleAUAAAADbmlsBQAAAANTRVABAAAAHGtleUxhc3RQcm9jZXNzZWRQZXJpb2RPZlVzZXIAAAABAAAACXVzZXJJbmRleAkABLkAAAACCQAETAAAAAICAAAAGSVzJWRfX2xhc3RQcm9jZXNzZWRQZXJpb2QJAARMAAAAAgkAAaQAAAABBQAAAAl1c2VySW5kZXgFAAAAA25pbAUAAAADU0VQAQAAABJrZXlIZWlnaHRGb3JQZXJpb2QAAAABAAAABnBlcmlvZAkABLkAAAACCQAETAAAAAICAAAAGiVzJWRfX3N0YXJ0SGVpZ2h0Rm9yUGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kBQAAAANuaWwFAAAAA1NFUAEAAAAXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QAAAACAAAABnBlcmlvZAAAAAdpc1dhdmVzCQAEuQAAAAIJAARMAAAAAgMFAAAAB2lzV2F2ZXMCAAAAHyVzJWRfX3RvdGFsV2F2ZXNBbW91bnRGb3JQZXJpb2QCAAAAHiVzJWRfX3RvdGFsVXNkbkFtb3VudEZvclBlcmlvZAkABEwAAAACCQABpAAAAAEFAAAABnBlcmlvZAUAAAADbmlsBQAAAANTRVABAAAADmtleVRvdGFsQW1vdW50AAAAAQAAAAdpc1dhdmVzAwUAAAAHaXNXYXZlcwIAAAAUJXNfX3RvdGFsV2F2ZXNBbW91bnQCAAAAEyVzX190b3RhbFVzZG5BbW91bnQBAAAAF2tleVRvdGFsV2VpZ2h0Rm9yUGVyaW9kAAAAAQAAAAZwZXJpb2QJAAS5AAAAAgkABEwAAAACAgAAABolcyVkX190b3RhbFdlaWdodEZvclBlcmlvZAkABEwAAAACCQABpAAAAAEFAAAABnBlcmlvZAUAAAADbmlsBQAAAANTRVABAAAAFmtleVVzZXJLVmFsdWVGb3JQZXJpb2QAAAACAAAABnBlcmlvZAAAAAl1c2VySW5kZXgJAAS5AAAAAgkABEwAAAACAgAAABclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkABEwAAAACCQABpAAAAAEFAAAACXVzZXJJbmRleAkABEwAAAACAgAAAAFrCQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kBQAAAANuaWwFAAAAA1NFUAEAAAAWa2V5VXNlckJWYWx1ZUZvclBlcmlvZAAAAAIAAAAGcGVyaW9kAAAACXVzZXJJbmRleAkABLkAAAACCQAETAAAAAICAAAAFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAJdXNlckluZGV4CQAETAAAAAICAAAAAWIJAARMAAAAAgkAAaQAAAABBQAAAAZwZXJpb2QFAAAAA25pbAUAAAADU0VQAQAAAAxIaXN0b3J5RW50cnkAAAAHAAAABHR5cGUAAAAEdXNlcgAAAAp1c2RuQW1vdW50AAAADHdhdmVzQWFtb3VudAAAAA1jdXJyZW50UGVyaW9kAAAADGxhdGVzdFBlcmlvZAAAAAFpBAAAAApoaXN0b3J5S0VZCQAEuQAAAAIJAARMAAAAAgIAAAARJXMlcyVzJXNfX2hpc3RvcnkJAARMAAAAAgUAAAAEdHlwZQkABEwAAAACBQAAAAR1c2VyCQAETAAAAAIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAADbmlsBQAAAANTRVAEAAAAC2hpc3RvcnlEQVRBCQAEuQAAAAIJAARMAAAAAgIAAAAMJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAZoZWlnaHQJAARMAAAAAgkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAkABEwAAAACCQABpAAAAAEFAAAACnVzZG5BbW91bnQJAARMAAAAAgkAAaQAAAABBQAAAAx3YXZlc0FhbW91bnQJAARMAAAAAgkAAaQAAAABBQAAAA1jdXJyZW50UGVyaW9kCQAETAAAAAIJAAGkAAAAAQUAAAAMbGF0ZXN0UGVyaW9kBQAAAANuaWwFAAAAA1NFUAkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAKaGlzdG9yeUtFWQUAAAALaGlzdG9yeURBVEEBAAAADmdldFVzZG5Bc3NldElkAAAAAQAAABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzAgAAABFuZXV0cmlub19hc3NldF9pZAIAAAAubWFuZGF0b3J5IGtleSBuZXV0cmlub19hc3NldF9pZCBpcyBub3QgZGVmaW5lZAEAAAAOZ2V0TnNidEFzc2V0SWQAAAABAAAAF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MCAAAADWJvbmRfYXNzZXRfaWQCAAAAKm1hbmRhdG9yeSBrZXkgYm9uZF9hc3NldF9pZCBpcyBub3QgZGVmaW5lZAEAAAAKY2FsY1dlaWdodAAAAAYAAAAXbnNidExvY2tDb250cmFjdEFkZHJlc3MAAAAGcGVyaW9kAAAABHVzZXIAAAAMcGVyaW9kSGVpZ2h0AAAAB3BlcmlvZHMAAAAFdXNlcnMEAAAAAWsJAQAAAAV2YWx1ZQAAAAEJAAQaAAAAAgUAAAAXbnNidExvY2tDb250cmFjdEFkZHJlc3MJAQAAABZrZXlVc2VyS1ZhbHVlRm9yUGVyaW9kAAAAAgUAAAAG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AAEJAQAAAA1pbnZva2VQcm9jZXNzAAAABwUAAAAQbnNidExvY2tDb250cmFjdAkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABAAAAAAAAAAAACQAAZQAAAAIFAAAABWRlcHRoAAAAAAAAAAABAAAAAAAAAAAABQAAAAdwZXJpb2RzBQAAAAV1c2VycwkABRcAAAAFCQAAZAAAAAIFAAAADWN1cnJlbnRQZXJpb2QAAAAAAAAAAAEAAAAAAAAAAAAFAAAAA25pbAUAAAADbmlsAAAAAAAAAAAAAQAAABhwcm9jZXNzTmV4dEJhdGNoSW50ZXJuYWwAAAAHAAAAEG5zYnRMb2NrQ29udHJhY3QAAAANY3VycmVudFBlcmlvZAAAAAtjdXJyZW50VXNlcgAAAAVkZXB0aAAAAAt0b3RhbFdlaWdodAAAAAdwZXJpb2RzAAAABXVzZXJzBAAAABduc2J0TG9ja0NvbnRyYWN0QWRkcmVzcwkBAAAAB0FkZHJlc3MAAAABBQAAABBuc2J0TG9ja0NvbnRyYWN0BAAAAAxsYXRlc3RQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA9rZXlMYXRlc3RQZXJpb2QAAAAABAAAAAp1c2Vyc0NvdW50CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAAF25zYnRMb2NrQ29udHJhY3RBZGRyZXNzCQEAAAANa2V5VXNlcnNDb3VudAAAAAAAAAAAAAAAAAAEAAAADnRvdGFsV2VpZ2h0S2V5CQEAAAAXa2V5VG90YWxXZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kBAAAAA9oZWlnaHRGb3JQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABJrZXlIZWlnaHRGb3JQZXJpb2QAAAABBQAAAA1jdXJyZW50UGVyaW9kAwMJAABmAAAAAgUAAAAFZGVwdGgAAAAAAAAAAAAJAABnAAAAAgUAAAAMbGF0ZXN0UGVyaW9kBQAAAA1jdXJyZW50UGVyaW9kBwQAAAACdDAJAQAAAA5jYWxjVXNlcldlaWdodAAAAAYFAAAAF25zYnRMb2NrQ29udHJhY3RBZGRyZXNzBQAAAA9oZWlnaHRGb3JQZXJp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A25pbAMJAAAAAAAAAgUAAAAGcmVzdWx0BQAAAAZyZXN1bHQEAAAAByRtYXRjaDAFAAAABnJlc3VsdAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAPKEludCwgSW50LCBJbnQpBAAAAAFyBQAAAAckbWF0Y2gwBQAAAAFyCQAAAgAAAAECAAAAF0luY29ycmVjdCBpbnZva2UgcmVzdWx0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEAAAANY2xhaW1JbnRlcm5hbAAAAAYAAAAQbnNidExvY2tDb250cmFjdAAAAA1jdXJyZW50UGVyaW9kAAAAC2N1cnJlbnRVc2VyAAAABWRlcHRoAAAAE3VzZXJVc2RuQWNjdW11bGF0ZWQAAAAUdXNlcldhdmVzQWNjdW11bGF0ZWQEAAAAF25zYnRMb2NrQ29udHJhY3RBZGRyZXNzCQEAAAAHQWRkcmVzcwAAAAEFAAAAEG5zYnRMb2NrQ29udHJhY3QEAAAADGxhdGVzdFBlcmlvZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFmtleU5leHRQcm9jZXNzZWRQZXJpb2QAAAAABAAAAAt0b3RhbFdlaWdodAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAF2tleVRvdGFsV2VpZ2h0Rm9yUGVyaW9kAAAAAQUAAAANY3VycmVudFBlcmlvZAQAAAAPaGVpZ2h0Rm9yUGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAASa2V5SGVpZ2h0Rm9yUGVyaW9kAAAAAQUAAAANY3VycmVudFBlcmlvZAQAAAANJHQwMTM0MjIxMzU0MgkBAAAADmNhbGNVc2VyV2VpZ2h0AAAABgUAAAAXbnNidExvY2tDb250cmFjdEFkZHJlc3MFAAAAD2hlaWdodEZvclBlcmlvZAUAAAANY3VycmVudFBlcmlvZAUAAAALY3VycmVudFVzZXIFAAAAA25pbAUAAAADbmlsBAAAAAp1c2VyV2VpZ2h0CAUAAAANJHQwMTM0MjIxMzU0MgAAAAJfMQQAAAAHaWdub3JlZAgFAAAADSR0MDEzNDIyMTM1NDIAAAACXzIEAAAAF3VzZXJVc2RuQW1vdW50Rm9yUGVyaW9kCQAAawAAAAMJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABdrZXlUb3RhbEFtb3VudEZvclBlcmlvZAAAAAIFAAAADWN1cnJlbnRQZXJpb2QHBQAAAAp1c2VyV2VpZ2h0BQAAAAt0b3RhbFdlaWdodAQAAAAYdXNlcldhdmVzQW1vdW50Rm9yUGVyaW9kCQAAawAAAAMJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABdrZXlUb3RhbEFtb3VudEZvclBlcmlvZAAAAAIFAAAADWN1cnJlbnRQZXJpb2QGBQAAAAp1c2VyV2VpZ2h0BQAAAAt0b3RhbFdlaWdodAMDCQAAZwAAAAIAAAAAAAAAAAAFAAAABWRlcHRoBgkAAGcAAAACCQAAZAAAAAIFAAAADWN1cnJlbnRQZXJpb2QAAAAAAAAAAAEFAAAADGxhdGVzdFBlcmlvZAkABRUAAAADCQAAZAAAAAIFAAAADWN1cnJlbnRQZXJpb2QAAAAAAAAAAAEJAABkAAAAAgUAAAATdXNlclVzZG5BY2N1bXVsYXRlZAUAAAAXdXNlclVzZG5BbW91bnRGb3JQZXJpb2QJAABkAAAAAgUAAAAUdXNlcldhdmVzQWNjdW11bGF0ZWQFAAAAGHVzZXJXYXZlc0Ftb3VudEZvclBlcmlvZAkBAAAAC2ludm9rZUNsYWltAAAABgUAAAAQbnNidExvY2tDb250cmFjdAkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABBQAAAAtjdXJyZW50VXNlcgkAAGUAAAACBQAAAAVkZXB0aAAAAAAAAAAAAQkAAGQAAAACBQAAABN1c2VyVXNkbkFjY3VtdWxhdGVkBQAAABd1c2VyVXNkbkFtb3VudEZvclBlcmlvZAkAAGQAAAACBQAAABR1c2VyV2F2ZXNBY2N1bXVsYXRlZAUAAAAYdXNlcldhdmVzQW1vdW50Rm9yUGVyaW9kAAAACAAAAAFpAQAAABBwcm9jZXNzTmV4dEJhdGNoAAAABwAAABBuc2J0TG9ja0NvbnRyYWN0AAAADWN1cnJlbnRQZXJpb2QAAAALY3VycmVudFVzZXIAAAAFZGVwdGgAAAALdG90YWxXZWlnaHQAAAAHcGVyaW9kcwAAAAV1c2VycwMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAACRTaG91bGQgYmUgY2FsbGVkIGJ5IHRoaXMgc2NyaXB0IG9ubHkEAAAAA3RwbAkBAAAAGHByb2Nlc3NOZXh0QmF0Y2hJbnRlcm5hbAAAAAcFAAAAEG5zYnRMb2NrQ29udHJhY3QFAAAADWN1cnJlbnRQZXJpb2QFAAAAC2N1cnJlbnRVc2VyBQAAAAVkZXB0aAUAAAALdG90YWxXZWlnaHQFAAAAB3BlcmlvZHMFAAAABXVzZXJzCQAFFAAAAAIIBQAAAAN0cGwAAAACXzEJAAUXAAAABQgFAAAAA3RwbAAAAAJfMggFAAAAA3RwbAAAAAJfMwgFAAAAA3RwbAAAAAJfNAgFAAAAA3RwbAAAAAJfNQgFAAAAA3RwbAAAAAJfNgAAAAFpAQAAAB1wcm9jZXNzUGVuZGluZ1BlcmlvZHNBbmRVc2VycwAAAAAEAAAADWN1cnJlbnRQZXJpb2QJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABZrZXlOZXh0UHJvY2Vzc2VkUGVyaW9kAAAAAAMJAABmAAAAAgUAAAANY3VycmVudFBlcmlvZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAD2tleUxhdGVzdFBlcmlvZAAAAAAJAAACAAAAAQIAAAASTm90aGluZyB0byBwcm9jZXNzBAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAABWRlcHRoCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAADklkeENmZ01heERlcHRoAwkAAGYAAAACBQAAAAVkZXB0aAUAAAAITUFYREVQVEgJAAACAAAAAQIAAAAWRGVwdGggZXhjZWVkcyBNQVhERVBUSAQAAAAQbnNidExvY2tDb250cmFjdAkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOc2J0TG9ja0NvbnRyYWN0BAAAAAtjdXJyZW50VXNlcgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFGtleU5leHRQcm9jZXNzZWRVc2VyAAAAAAQAAAALdG90YWxXZWlnaHQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABdrZXlUb3RhbFdlaWdodEZvclBlcmlvZAAAAAEFAAAADWN1cnJlbnRQZXJpb2QEAAAAAXIJAQAAABhwcm9jZXNzTmV4dEJhdGNoSW50ZXJuYWwAAAAHBQAAABBuc2J0TG9ja0NvbnRyYWN0BQAAAA1jdXJyZW50UGVyaW9kBQAAAAtjdXJyZW50VXNlcgUAAAAFZGVwdGgFAAAAC3RvdGFsV2VpZ2h0BQAAAANuaWwFAAAAA25pbAkABE0AAAACCQAETQAAAAIIBQAAAAFyAAAAAl8xCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFmtleU5leHRQcm9jZXNzZWRQZXJpb2QAAAAACAUAAAABcgAAAAJfMgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABRrZXlOZXh0UHJvY2Vzc2VkVXNlcgAAAAAIBQAAAAFyAAAAAl8zAAAAAWkBAAAAB2RlcG9zaXQAAAAABAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOZXV0cmlub0NvbnRyYWN0AwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAABBuZXV0cmlub0NvbnRyYWN0CQAAAgAAAAECAAAAFFdyb25nIGNhbGxlciBhZGRyZXNzBAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAAB2Fzc2V0SWQIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAAGcGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAANa2V5TmV4dFBlcmlvZAAAAAAEAAAABGhSYXcJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEmtleUhlaWdodEZvclBlcmlvZAAAAAEFAAAABnBlcmlvZAQAAAAFZGVsYXkJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAARSWR4Q2ZnUGVyaW9kRGVsYXkDCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABBQAAAARoUmF3CQEAAAAMRGVwb3NpdEVudHJ5AAAAAwUAAAAGcGVyaW9kBQAAAANwbXQHAwkAAGcAAAACBQAAAAZoZWlnaHQJAABkAAAAAgkBAAAABXZhbHVlAAAAAQUAAAAEaFJhdwUAAAAFZGVsYXkJAQAAAAxEZXBvc2l0RW50cnkAAAADCQAAZAAAAAIFAAAABnBlcmlvZAAAAAAAAAAAAQUAAAADcG10BgQAAAAJa2V5QW1vdW50CQEAAAAXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QAAAACBQAAAAZwZXJpb2QJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEdW5pdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJa2V5QW1vdW50CQAAZAAAAAIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAACWtleUFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5rZXlUb3RhbEFtb3VudAAAAAEJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEdW5pdAkAAGQAAAACCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAOa2V5VG90YWxBbW91bnQAAAABCQAAAAAAAAIFAAAAB2Fzc2V0SWQFAAAABHVuaXQIBQAAAANwbXQAAAAGYW1vdW50BQAAAANuaWwAAAABaQEAAAAOY2xhaW1OZXh0QmF0Y2gAAAAGAAAAEG5zYnRMb2NrQ29udHJhY3QAAAANY3VycmVudFBlcmlvZAAAAAtjdXJyZW50VXNlcgAAAAVkZXB0aAAAAA91c2RuQWNjdW11bGF0ZWQAAAAQd2F2ZXNBY2N1bXVsYXRlZAMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAACRTaG91bGQgYmUgY2FsbGVkIGJ5IHRoaXMgc2NyaXB0IG9ubHkEAAAAD3BlcmlvZEFuZFRvdGFscwkBAAAADWNsYWltSW50ZXJuYWwAAAAGBQAAABBuc2J0TG9ja0NvbnRyYWN0BQAAAA1jdXJyZW50UGVyaW9kBQAAAAtjdXJyZW50VXNlcgUAAAAFZGVwdGgFAAAAD3VzZG5BY2N1bXVsYXRlZAUAAAAQd2F2ZXNBY2N1bXVsYXRlZAkABRQAAAACBQAAAANuaWwFAAAAD3BlcmlvZEFuZFRvdGFscwAAAAFpAQAAAAtjbGFpbVJld2FyZAAAAAAEAAAACGNmZ0FycmF5CQEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAQAAAAHYWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAB3VzZXJJZHgJAQAAABVnZXRVc2VySW5kZXhCeUFkZHJlc3MAAAACCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOc2J0TG9ja0NvbnRyYWN0BQAAAAdhZGRyZXNzBAAAAA1jdXJyZW50UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAba2V5TmV4dFVubGFpbWVkUGVyaW9kT2ZVc2VyAAAAAQUAAAAHdXNlcklkeAQAAAAMbGF0ZXN0UGVyaW9kCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZAAAAAADCQAAZwAAAAIFAAAADWN1cnJlbnRQZXJpb2QFAAAADGxhdGVzdFBlcmlvZAkAAAIAAAABAgAAABBOb3RoaW5nIHRvIGNsYWltBAAAABBuc2J0TG9ja0NvbnRyYWN0CQACWQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAFklkeENmZ05zYnRMb2NrQ29udHJhY3QEAAAADSR0MDE4MDg4MTgyMDAJAQAAAA1jbGFpbUludGVybmFsAAAABgUAAAAQbnNidExvY2tDb250cmFjdAUAAAANY3VycmVudFBlcmlvZAUAAAAHdXNlcklkeAUAAAAJVVNFUkRFUFRIAAAAAAAAAAAAAAAAAAAAAAAABAAAAAZwZXJpb2QIBQAAAA0kdDAxODA4ODE4MjAwAAAAAl8xBAAAAAp1c2RuQW1vdW50CAUAAAANJHQwMTgwODgxODIwMAAAAAJfMgQAAAALd2F2ZXNBbW91bnQIBQAAAA0kdDAxODA4ODE4MjAwAAAAAl8zAwMJAABnAAAAAgAAAAAAAAAAAAUAAAAKdXNkbkFtb3VudAkAAGcAAAACAAAAAAAAAAAABQAAAAt3YXZlc0Ftb3VudAcJAAACAAAAAQIAAAAUTm8gcGF5b3V0cyBhdmFpbGFibGUEAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABZJZHhDZmdOZXV0cmlub0NvbnRyYWN0CQAFFAAAAAIJAAROAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAG2tleU5leHRVbmxhaW1lZFBlcmlvZE9mVXNlcgAAAAEFAAAAB3VzZXJJZHgFAAAABnBlcmlvZAkABEwAAAACCQEAAAAMSGlzdG9yeUVudHJ5AAAABwIAAAALY2xhaW1SZXdhcmQFAAAAB2FkZHJlc3MFAAAACnVzZG5BbW91bnQFAAAAC3dhdmVzQW1vdW50BQAAAAZwZXJpb2QFAAAADGxhdGVzdFBlcmlvZAUAAAABaQUAAAADbmlsAwkAAGYAAAACBQAAAAp1c2RuQW1vdW50AAAAAAAAAAAACQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKdXNkbkFtb3VudAkAAlkAAAABCQEAAAAOZ2V0VXNkbkFzc2V0SWQAAAABBQAAABBuZXV0cmlub0NvbnRyYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOa2V5VG90YWxBbW91bnQAAAABBwkAAGUAAAACCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAOa2V5VG90YWxBbW91bnQAAAABBwUAAAAKdXNkbkFtb3VudAUAAAADbmlsCQAETgAAAAIFAAAAA25pbAMJAABmAAAAAgUAAAALd2F2ZXNBbW91bnQAAAAAAAAAAAAJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAt3YXZlc0Ftb3VudAUAAAAEdW5pdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVRvdGFsQW1vdW50AAAAAQYJAABlAAAAAgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAADmtleVRvdGFsQW1vdW50AAAAAQYFAAAAC3dhdmVzQW1vdW50BQAAAANuaWwFAAAAA25pbAkABRQAAAACBQAAAAp1c2RuQW1vdW50BQAAAAt3YXZlc0Ftb3VudAAAAAFpAQAAABxjYWxjR292ZXJuYW5jZVBhcmFtc1JFQURPTkxZAAAAAwAAAApuc2J0QW1vdW50AAAAD2xvY2tTdGFydEhlaWdodAAAABJsb2NrRHVyYXRpb25CbG9ja3MEAAAADWxvY2tFbmRIZWlnaHQJAABkAAAAAgUAAAAPbG9ja1N0YXJ0SGVpZ2h0BQAAABJsb2NrRHVyYXRpb25CbG9ja3MEAAAADHNjYWxlOFBhcmFtSwkBAAAAAS0AAAABCQAAawAAAAMFAAAACm5zYnRBbW91bnQFAAAABVNDQUxFBQAAABJsb2NrRHVyYXRpb25CbG9ja3MEAAAADHNjYWxlOFBhcmFtQgkAAGgAAAACCQAAawAAAAMFAAAACm5zYnRBbW91bnQFAAAABVNDQUxFBQAAABJsb2NrRHVyYXRpb25CbG9ja3MFAAAADWxvY2tFbmRIZWlnaHQJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAADHNjYWxlOFBhcmFtSwkABEwAAAACBQAAAAxzY2FsZThQYXJhbUIJAARMAAAAAgkBAAAACm5leHRQZXJpb2QAAAAABQAAAANuaWwAAAABaQEAAAAWZ2V0VG90YWxSZXdhcmRSRUFET05MWQAAAAAJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA5rZXlUb3RhbEFtb3VudAAAAAEHCQAETAAAAAIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA5rZXlUb3RhbEFtb3VudAAAAAEGBQAAAANuaWwAAAABaQEAAAALY29uc3RydWN0b3IAAAAEAAAAGm5ldXRyaW5vQ29udHJhY3RBZGRyZXNzU3RyAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyAAAACG1heERlcHRoAAAAC3BlcmlvZERlbGF5AwkBAAAAAiE9AAAAAgUAAAAEdGhpcwgFAAAAAWkAAAAGY2FsbGVyCQAAAgAAAAECAAAADm5vdCBhdXRob3JpemVkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAlrZXlDb25maWcAAAAACQEAAAAMZm9ybWF0Q29uZmlnAAAABAUAAAAabmV1dHJpbm9Db250cmFjdEFkZHJlc3NTdHIFAAAAGm5zYnRMb2NrQ29udHJhY3RBZGRyZXNzU3RyBQAAAAhtYXhEZXB0aAUAAAALcGVyaW9kRGVsYXkFAAAAA25pbAAAAADY2KcO", "height": 1875634, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 5 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let revisionNum = "" | |
5 | + | ||
6 | + | let SEP = "__" | |
7 | + | ||
8 | + | let MAXDEPTH = 17 | |
9 | + | ||
10 | + | let USERDEPTH = 26 | |
11 | + | ||
12 | + | let SCALE = 1000 | |
13 | + | ||
14 | + | func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0) | |
15 | + | ||
16 | + | ||
17 | + | func getStringByKey (key) = valueOrElse(getString(this, key), "") | |
18 | + | ||
19 | + | ||
20 | + | func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined")) | |
21 | + | ||
22 | + | ||
23 | + | let IdxCfgNeutrinoContract = 1 | |
24 | + | ||
25 | + | let IdxCfgNsbtLockContract = 2 | |
26 | + | ||
27 | + | let IdxCfgMaxDepth = 3 | |
28 | + | ||
29 | + | let IdxCfgPeriodDelay = 4 | |
30 | + | ||
31 | + | func keyConfig () = "%s__config" | |
32 | + | ||
33 | + | ||
34 | + | func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP) | |
35 | + | ||
36 | + | ||
37 | + | func formatConfig (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = makeString(["%s%s%d%d", neutrinoContractAddressStr, nsbtLockContractAddressStr, toString(maxDepth), toString(periodDelay)], SEP) | |
38 | + | ||
39 | + | ||
40 | + | func keyUsersCount () = "%s__nextUserNum" | |
41 | + | ||
42 | + | ||
43 | + | func keyNextProcessedUser () = "%s__nextProcessedUser" | |
44 | + | ||
45 | + | ||
46 | + | func keyLatestPeriod () = "%s__latestPeriod" | |
47 | + | ||
48 | + | ||
49 | + | func keyNextPeriod () = "%s__nextPeriod" | |
50 | + | ||
51 | + | ||
52 | + | func keyNextProcessedPeriod () = "%s__nextProcessedPeriod" | |
53 | + | ||
54 | + | ||
55 | + | func keyNextUnlaimedPeriodOfUser (userIndex) = makeString(["%s%d__nextClaimedPeriod", toString(userIndex)], SEP) | |
56 | + | ||
57 | + | ||
58 | + | func keyLastProcessedPeriodOfUser (userIndex) = makeString(["%s%d__lastProcessedPeriod", toString(userIndex)], SEP) | |
59 | + | ||
60 | + | ||
61 | + | func keyHeightForPeriod (period) = makeString(["%s%d__startHeightForPeriod", toString(period)], SEP) | |
62 | + | ||
63 | + | ||
64 | + | func keyTotalAmountForPeriod (period,isWaves) = makeString([if (isWaves) | |
65 | + | then "%s%d__totalWavesAmountForPeriod" | |
66 | + | else "%s%d__totalUsdnAmountForPeriod", toString(period)], SEP) | |
67 | + | ||
68 | + | ||
69 | + | func keyTotalAmount (isWaves) = if (isWaves) | |
70 | + | then "%s__totalWavesAmount" | |
71 | + | else "%s__totalUsdnAmount" | |
72 | + | ||
73 | + | ||
74 | + | func keyTotalWeightForPeriod (period) = makeString(["%s%d__totalWeightForPeriod", toString(period)], SEP) | |
75 | + | ||
76 | + | ||
77 | + | func keyUserKValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "k", toString(period)], SEP) | |
78 | + | ||
79 | + | ||
80 | + | func keyUserBValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "b", toString(period)], SEP) | |
81 | + | ||
82 | + | ||
83 | + | func HistoryEntry (type,user,usdnAmount,wavesAamount,currentPeriod,latestPeriod,i) = { | |
84 | + | let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP) | |
85 | + | let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(usdnAmount), toString(wavesAamount), toString(currentPeriod), toString(latestPeriod)], SEP) | |
86 | + | StringEntry(historyKEY, historyDATA) | |
87 | + | } | |
88 | + | ||
89 | + | ||
90 | + | func getUsdnAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "neutrino_asset_id"), "mandatory key neutrino_asset_id is not defined") | |
91 | + | ||
92 | + | ||
93 | + | func getNsbtAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "bond_asset_id"), "mandatory key bond_asset_id is not defined") | |
94 | + | ||
95 | + | ||
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) = { | |
107 | + | let kLast = keyLastProcessedPeriodOfUser(userIndex) | |
108 | + | let kKey = keyUserKValueForPeriod(period, userIndex) | |
109 | + | let kRaw = getInteger(nsbtLockContractAddress, kKey) | |
110 | + | if (isDefined(kRaw)) | |
111 | + | then { | |
112 | + | let k = value(kRaw) | |
113 | + | let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, userIndex))) | |
114 | + | let w = ((k * heightForPeriod) + b) | |
115 | + | 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) | |
123 | + | } | |
124 | + | else { | |
125 | + | let p = getInteger(this, kLast) | |
126 | + | 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) | |
133 | + | } | |
134 | + | } | |
135 | + | } | |
136 | + | ||
137 | + | ||
138 | + | func getUserIndexByAddress (nsbtLockContractAddressStr,userAddress) = { | |
139 | + | let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP) | |
140 | + | valueOrErrorMessage(getInteger(Address(fromBase58String(nsbtLockContractAddressStr)), key), ((("User address " + userAddress) + " is not found in nsbtLock contract data, key=") + key)) | |
141 | + | } | |
142 | + | ||
143 | + | ||
144 | + | func nextPeriod () = getNumberByKey(keyNextPeriod()) | |
145 | + | ||
146 | + | ||
147 | + | func DepositEntry (period,pmt,finalize) = [IntegerEntry(keyLatestPeriod(), if (finalize) | |
148 | + | then (period - 1) | |
149 | + | 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)] | |
150 | + | ||
151 | + | ||
152 | + | func invokeProcess (nsbtLockContract,period,user,depth,weight,periods,users) = { | |
153 | + | let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight, periods, users], nil) | |
154 | + | if ((result == result)) | |
155 | + | then match result { | |
156 | + | case r: (Int, Int, List[Any], List[Any], Int) => | |
157 | + | r | |
158 | + | case _ => | |
159 | + | throw("Incorrect invoke result") | |
160 | + | } | |
161 | + | else throw("Strict value is not equal to itself.") | |
162 | + | } | |
163 | + | ||
164 | + | ||
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) = { | |
171 | + | let nsbtLockContractAddress = Address(nsbtLockContract) | |
172 | + | let latestPeriod = getNumberByKey(keyLatestPeriod()) | |
173 | + | let usersCount = valueOrElse(getInteger(nsbtLockContractAddress, keyUsersCount()), 0) | |
174 | + | let totalWeightKey = keyTotalWeightForPeriod(currentPeriod) | |
175 | + | let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod)) | |
176 | + | if (if ((depth > 0)) | |
177 | + | then (latestPeriod >= currentPeriod) | |
178 | + | else false) | |
179 | + | then { | |
180 | + | let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser, periods, users) | |
181 | + | let weight0 = (totalWeight + t0._1) | |
182 | + | if ((usersCount > (currentUser + 1))) | |
183 | + | then { | |
184 | + | let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1), t0._3, t0._4) | |
185 | + | let weight1 = (weight0 + t1._1) | |
186 | + | if ((usersCount > (currentUser + 2))) | |
187 | + | then { | |
188 | + | let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2), t1._3, t1._4) | |
189 | + | let weight2 = (weight1 + t2._1) | |
190 | + | if ((usersCount > (currentUser + 3))) | |
191 | + | then { | |
192 | + | let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3), t2._3, t2._4) | |
193 | + | let weight3 = (weight2 + t3._1) | |
194 | + | if ((usersCount > (currentUser + 4))) | |
195 | + | then { | |
196 | + | let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4), t3._3, t3._4) | |
197 | + | let weight4 = (weight3 + t4._1) | |
198 | + | if ((usersCount > (currentUser + 5))) | |
199 | + | then { | |
200 | + | let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5), t4._3, t4._4) | |
201 | + | let weight5 = (weight4 + t5._1) | |
202 | + | if ((usersCount > (currentUser + 6))) | |
203 | + | 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) | |
206 | + | } | |
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 | + | } | |
211 | + | } | |
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 | + | } | |
216 | + | } | |
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 | + | } | |
221 | + | } | |
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 | + | } | |
226 | + | } | |
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 | + | } | |
231 | + | } | |
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 | + | } | |
236 | + | } | |
237 | + | else if ((currentUser == 0)) | |
238 | + | then $Tuple6(nil, currentPeriod, 0, nil, nil, 0) | |
239 | + | else $Tuple6([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, nil, nil, 0) | |
240 | + | } | |
241 | + | ||
242 | + | ||
243 | + | func invokeClaim (nsbtLockContract,period,user,depth,totalUsdn,totalWaves) = { | |
244 | + | let result = invoke(this, "claimNextBatch", [nsbtLockContract, period, user, depth, totalUsdn, totalWaves], nil) | |
245 | + | if ((result == result)) | |
246 | + | then match result { | |
247 | + | case r: (Int, Int, Int) => | |
248 | + | r | |
249 | + | case _ => | |
250 | + | throw("Incorrect invoke result") | |
251 | + | } | |
252 | + | else throw("Strict value is not equal to itself.") | |
253 | + | } | |
254 | + | ||
255 | + | ||
256 | + | func claimInternal (nsbtLockContract,currentPeriod,currentUser,depth,userUsdnAccumulated,userWavesAccumulated) = { | |
257 | + | let nsbtLockContractAddress = Address(nsbtLockContract) | |
258 | + | let latestPeriod = getNumberByKey(keyNextProcessedPeriod()) | |
259 | + | let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod)) | |
260 | + | 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 | |
264 | + | let userUsdnAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, false)), userWeight, totalWeight) | |
265 | + | let userWavesAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, true)), userWeight, totalWeight) | |
266 | + | if (if ((0 >= depth)) | |
267 | + | then true | |
268 | + | else ((currentPeriod + 1) >= latestPeriod)) | |
269 | + | then $Tuple3((currentPeriod + 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod)) | |
270 | + | else invokeClaim(nsbtLockContract, (currentPeriod + 1), currentUser, (depth - 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod)) | |
271 | + | } | |
272 | + | ||
273 | + | ||
274 | + | @Callable(i) | |
275 | + | func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight,periods,users) = if ((i.caller != this)) | |
276 | + | then throw("Should be called by this script only") | |
277 | + | 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)) | |
280 | + | } | |
281 | + | ||
282 | + | ||
283 | + | ||
284 | + | @Callable(i) | |
285 | + | func processPendingPeriodsAndUsers () = { | |
286 | + | let currentPeriod = getNumberByKey(keyNextProcessedPeriod()) | |
287 | + | if ((currentPeriod > getNumberByKey(keyLatestPeriod()))) | |
288 | + | then throw("Nothing to process") | |
289 | + | else { | |
290 | + | let cfgArray = readConfigArrayOrFail() | |
291 | + | let depth = parseIntValue(cfgArray[IdxCfgMaxDepth]) | |
292 | + | if ((depth > MAXDEPTH)) | |
293 | + | then throw("Depth exceeds MAXDEPTH") | |
294 | + | else { | |
295 | + | let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract]) | |
296 | + | let currentUser = getNumberByKey(keyNextProcessedUser()) | |
297 | + | let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod)) | |
298 | + | let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight, nil, nil) | |
299 | + | ((r._1 :+ IntegerEntry(keyNextProcessedPeriod(), r._2)) :+ IntegerEntry(keyNextProcessedUser(), r._3)) | |
300 | + | } | |
301 | + | } | |
302 | + | } | |
303 | + | ||
304 | + | ||
305 | + | ||
306 | + | @Callable(i) | |
307 | + | func deposit () = { | |
308 | + | let cfgArray = readConfigArrayOrFail() | |
309 | + | let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract])) | |
310 | + | if ((i.caller != neutrinoContract)) | |
311 | + | then throw("Wrong caller address") | |
312 | + | else { | |
313 | + | let pmt = value(i.payments[0]) | |
314 | + | let assetId = pmt.assetId | |
315 | + | let period = getNumberByKey(keyNextPeriod()) | |
316 | + | let hRaw = getInteger(this, keyHeightForPeriod(period)) | |
317 | + | let delay = parseIntValue(cfgArray[IdxCfgPeriodDelay]) | |
318 | + | if (!(isDefined(hRaw))) | |
319 | + | then DepositEntry(period, pmt, false) | |
320 | + | else if ((height >= (value(hRaw) + delay))) | |
321 | + | then DepositEntry((period + 1), pmt, true) | |
322 | + | else { | |
323 | + | let keyAmount = keyTotalAmountForPeriod(period, (assetId == unit)) | |
324 | + | [IntegerEntry(keyAmount, (getNumberByKey(keyAmount) + pmt.amount)), IntegerEntry(keyTotalAmount((assetId == unit)), (getNumberByKey(keyTotalAmount((assetId == unit))) + pmt.amount))] | |
325 | + | } | |
326 | + | } | |
327 | + | } | |
328 | + | ||
329 | + | ||
330 | + | ||
331 | + | @Callable(i) | |
332 | + | func claimNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,usdnAccumulated,wavesAccumulated) = if ((i.caller != this)) | |
333 | + | then throw("Should be called by this script only") | |
334 | + | else { | |
335 | + | let periodAndTotals = claimInternal(nsbtLockContract, currentPeriod, currentUser, depth, usdnAccumulated, wavesAccumulated) | |
336 | + | $Tuple2(nil, periodAndTotals) | |
337 | + | } | |
338 | + | ||
339 | + | ||
340 | + | ||
341 | + | @Callable(i) | |
342 | + | func claimReward () = { | |
343 | + | let cfgArray = readConfigArrayOrFail() | |
344 | + | let address = toString(i.caller) | |
345 | + | let userIdx = getUserIndexByAddress(cfgArray[IdxCfgNsbtLockContract], address) | |
346 | + | let currentPeriod = getNumberByKey(keyNextUnlaimedPeriodOfUser(userIdx)) | |
347 | + | let latestPeriod = getNumberByKey(keyNextProcessedPeriod()) | |
348 | + | if ((currentPeriod >= latestPeriod)) | |
349 | + | then throw("Nothing to claim") | |
350 | + | else { | |
351 | + | 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 | |
356 | + | if (if ((0 >= usdnAmount)) | |
357 | + | then (0 >= wavesAmount) | |
358 | + | else false) | |
359 | + | then throw("No payouts available") | |
360 | + | else { | |
361 | + | let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract])) | |
362 | + | $Tuple2(([IntegerEntry(keyNextUnlaimedPeriodOfUser(userIdx), period), HistoryEntry("claimReward", address, usdnAmount, wavesAmount, period, latestPeriod, i)] ++ (if ((usdnAmount > 0)) | |
363 | + | then [ScriptTransfer(i.caller, usdnAmount, fromBase58String(getUsdnAssetId(neutrinoContract))), IntegerEntry(keyTotalAmount(false), (getNumberByKey(keyTotalAmount(false)) - usdnAmount))] | |
364 | + | else (nil ++ (if ((wavesAmount > 0)) | |
365 | + | then [ScriptTransfer(i.caller, wavesAmount, unit), IntegerEntry(keyTotalAmount(true), (getNumberByKey(keyTotalAmount(true)) - wavesAmount))] | |
366 | + | else nil)))), $Tuple2(usdnAmount, wavesAmount)) | |
367 | + | } | |
368 | + | } | |
369 | + | } | |
370 | + | ||
371 | + | ||
372 | + | ||
373 | + | @Callable(i) | |
374 | + | func calcGovernanceParamsREADONLY (nsbtAmount,lockStartHeight,lockDurationBlocks) = { | |
375 | + | 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()]) | |
379 | + | } | |
380 | + | ||
381 | + | ||
382 | + | ||
383 | + | @Callable(i) | |
384 | + | func getTotalRewardREADONLY () = $Tuple2(nil, [getNumberByKey(keyTotalAmount(false)), getNumberByKey(keyTotalAmount(true))]) | |
385 | + | ||
386 | + | ||
387 | + | ||
388 | + | @Callable(i) | |
389 | + | func constructor (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = if ((this != i.caller)) | |
390 | + | then throw("not authorized") | |
391 | + | else [StringEntry(keyConfig(), formatConfig(neutrinoContractAddressStr, nsbtLockContractAddressStr, maxDepth, periodDelay))] | |
392 | + | ||
393 | + |
github/deemru/w8io/169f3d6 50.24 ms ◑