tx · 46yv6uQ4T326oMZV2cvv4KdAjfKR9MQNGh3dZ7nGhYR7

3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE:  -0.02000000 Waves

2023.09.21 14:38 [2765087] smart account 3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE > SELF 0.00000000 Waves

{ "type": 13, "id": "46yv6uQ4T326oMZV2cvv4KdAjfKR9MQNGh3dZ7nGhYR7", "fee": 2000000, "feeAssetId": null, "timestamp": 1695296348342, "version": 2, "chainId": 84, "sender": "3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE", "senderPublicKey": "G349Uq3FTox7dRNLeAfAQeoACvwZ9iEnVSaHcEYn6j8J", "proofs": [ "4SJvetwzuhJQAYa9KkUi7E5d3hArYAgF5ZeytuZt91AswbnngwjqBjNAQnp5Z6etaPje5YVzX5AsSoyey3tGo5P2" ], "script": "base64:BgKMHQgCEgYKBAEYEQESBAoCCAESABIDCgEBEgASABIAEgMKAQgSAwoBCBIDCgEIEgUKAwEBARIFCgMBAQESABIDCgEIEgcKBQgICAgIEgQKAhgREgASAwoBCCIDU0VQIgVTQ0FMRSIFTVVMVDgiCnplcm9CaWdJbnQiFHByb2Nlc3NpbmdTdGFnZVRvdGFsIhVwcm9jZXNzaW5nU3RhZ2VTaGFyZXMiC3dhdmVzU3RyaW5nIg5nZXROdW1iZXJCeUtleSIDa2V5Ig9nZXROdW1iZXJPckZhaWwiDmdldFN0cmluZ0J5S2V5Ig9nZXRTdHJpbmdPckZhaWwiDHBhcnNlQXNzZXRJZCIFaW5wdXQiB3dyYXBFcnIiA21zZyIIdGhyb3dFcnIiA2FicyIDdmFsIglhYnNCaWdJbnQiC2tleU1heERlcHRoIg9tYXhEZXB0aERlZmF1bHQiCG1heERlcHRoIhFrZXlGYWN0b3J5QWRkcmVzcyIRZmFjdG9yeUFkZHJlc3NTdHIiD2ZhY3RvcnlDb250cmFjdCISa2V5RW1pc3Npb25BZGRyZXNzIhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0IhNrZXlOdW1Ub1VzZXJNYXBwaW5nIgNudW0iFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUiGnJlZmVycmFsUHJvZ3JhbU5hbWVEZWZhdWx0IhNyZWZlcnJhbFByb2dyYW1OYW1lIhdrZXlSZWZlcnJhbE1pbkdXeEFtb3VudCIbcmVmZXJyYWxNaW5HV3hBbW91bnREZWZhdWx0IhRyZWZlcnJhbE1pbkdXeEFtb3VudCIZa2V5UmVmZXJyZXJSZXdhcmRQZXJtaWxsZSIdcmVmZXJyZXJSZXdhcmRQZXJtaWxsZURlZmF1bHQiFnJlZmVycmVyUmV3YXJkUGVybWlsbGUiGWtleVJlZmVycmFsUmV3YXJkUGVybWlsbGUiHXJlZmVycmFsUmV3YXJkUGVybWlsbGVEZWZhdWx0IhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlIgtrZXlSZWZlcnJlciIPcmVmZXJyYWxBZGRyZXNzIhRrZXlVbmNsYWltZWRSZWZlcnJhbCILcHJvZ3JhbU5hbWUiDmNsYWltZXJBZGRyZXNzIhJlbWlzc2lvbkFkZHJlc3NTdHIiEGVtaXNzaW9uQ29udHJhY3QiDUlkeENmZ0Fzc2V0SWQiFklkeENmZ1BhY2VtYWtlckFkZHJlc3MiFklkeENmZ0Jvb3N0aW5nQ29udHJhY3QiDklkeENmZ01heERlcHRoIglrZXlDb25maWciEmdldEVtaXNzaW9uQWRkcmVzcyIPZW1pc3Npb25BZGRyZXNzIgx3eEFzc2V0SWRTdHIiCXd4QXNzZXRJZCIVcmVhZENvbmZpZ0FycmF5T3JGYWlsIgxmb3JtYXRDb25maWciGm1hdGNoZXJQYWNlbWFrZXJBZGRyZXNzU3RyIhpib29zdGluZ0NvbnRyYWN0QWRkcmVzc1N0ciIWYm9vc3RpbmdDb250cmFjdE9yRmFpbCIIY2ZnQXJyYXkiH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQiDWtleVVzZXJzQ291bnQiFmtleVJhdGVQZXJCbG9ja0N1cnJlbnQiGmtleUd3eEhvbGRlcnNSZXdhcmRDdXJyZW50IhdrZXlHd3hIb2xkZXJzUmV3YXJkTmV4dCIUa2V5UG9vbFdlaWdodFZpcnR1YWwiFGtleU5leHRQcm9jZXNzZWRVc2VyIg9rZXlMYXRlc3RQZXJpb2QiDWtleU5leHRQZXJpb2QiEmtleVByb2Nlc3NpbmdTdGFnZSIWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZCIQa2V5VXNlclVuY2xhaW1lZCIJdXNlckluZGV4IhtrZXlOZXh0VW5sYWltZWRQZXJpb2RPZlVzZXIiHGtleUxhc3RQcm9jZXNzZWRQZXJpb2RPZlVzZXIiEmtleUhlaWdodEZvclBlcmlvZCIGcGVyaW9kIh1rZXlBdXhFbWlzc2lvblJld2FyZEZvclBlcmlvZCIXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QiEWtleUxhc3RQYXlvdXRJbmZvIhBQZXJpb2RQYXlvdXRJbmZvIg1tYXRjaGVyUmV3YXJkIg5lbWlzc2lvblJld2FyZCIUa2V5UGF5b3V0SGlzdG9yeUluZm8iF2tleVRvdGFsV2VpZ2h0Rm9yUGVyaW9kIhZrZXlVc2VyS1ZhbHVlRm9yUGVyaW9kIhZrZXlVc2VyQlZhbHVlRm9yUGVyaW9kIhZrZXlVc2VyV2VpZ2h0Rm9yUGVyaW9kIhtrZXlSZWZlcnJhbHNDb250cmFjdEFkZHJlc3MiHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbCIXa2V5VHJhZGluZ1Jld2FyZEhpc3RvcnkiBHVzZXIiAWkiEGtleVRyYWRpbmdSZXdhcmQiC3VzZXJBZGRyZXNzIhBrZXlNYXhSZWNpcGllbnRzIgxIaXN0b3J5RW50cnkiBHR5cGUiBmFtb3VudCIKaGlzdG9yeUtFWSILaGlzdG9yeURBVEEiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMiByRtYXRjaDAiAXMiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiC211c3RNYW5hZ2VyIgJwZCICcGsiDmNhbGNVc2VyV2VpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIPaGVpZ2h0Rm9yUGVyaW9kIgVrTGFzdCIEa0tleSIEa1JhdyILa1VzZXJXZWlnaHQiAWsiAWIiAXciAXAiAnB2IhZjYWxjVXNlcldlaWdodEZvckNsYWltIhB1c2VyV2VpZ2h0T3JVbml0IhVnZXRVc2VySW5kZXhCeUFkZHJlc3MiCm5leHRQZXJpb2QiEWNvbW1vbkNsYWltUmV3YXJkIgd1c2VySWR4IhN1c2VyVW5jbGFpbWVkT3B0aW9uIgF1IhBnZXRUcmFkaW5nUmV3YXJkIhVwYXltZW50QW1vdW50TGVmdE92ZXIiDXVzZXJBZGRyZXNzZXMiB3Jld2FyZHMiC2N1cnJlbnRJdGVyIgZjaGVja3MiE3RyYWRlUmV3YXJkSW50ZXJuYWwiF3RyYWRpbmdSZXdhcmRIaXN0b3J5S2V5Ig5nV3hBbW91bnRTdGFydCIIcmVmZXJyZXIiEWFjdGl2ZVJlZmVycmFsSW52Ig9wcm9jZXNzaW5nU3RhZ2UiDWN1cnJlbnRQZXJpb2QiC2N1cnJlbnRVc2VyIgxsYXRlc3RQZXJpb2QiCnVzZXJzQ291bnQiDnRvdGFsV2VpZ2h0S2V5Igt0b3RhbFdlaWdodCINJHQwMTQ1MTAxNDYyNiIKdXNlcldlaWdodCILdXNlckFjdGlvbnMiDnRvdGFsV2VpZ2h0TmV3IhFwcm9jZXNzaW5nQWN0aW9ucyIadXNlckFtb3VudE1hdGNoZXJGb3JQZXJpb2QiG3VzZXJBbW91bnRFbWlzc2lvbkZvclBlcmlvZCIPdXNlclRvdGFsQW1vdW50IgtyZWZlcnJhbEludiIOcmVmZXJyZXJSZXdhcmQiDnJlZmVycmFsUmV3YXJkIhB1bmNsYWltZWRBY3Rpb25zIgdjb3VudGVyIgZyZXN1bHQiAUAiC2NoZWNrQ2FsbGVyIgZkZWx0YUgiDGVtaXNzaW9uUmF0ZSIXZ3d4SG9sZGVyc1Jld2FyZEN1cnJlbnQiCWF1eEFtb3VudCICZW0iC21hdGNoZXJQYXJ0IgpwYXlvdXRJbmZvIhdnd3hIb2xkZXJzUmV3YXJkVXBkYXRlZCILdG90YWxSZXdhcmQiB2FjdGlvbnMiB2FkZHJlc3MiDSR0MDE5ODE1MTk4NjUiC2NoZWNrQW1vdW50IhJhbW91bnRGcm9tRW1pc3Npb24iD2NsYWltZWRSZWZlcnJhbCILdG90YWxBbW91bnQiDSR0MDIwNDM4MjA0ODgiEXJlZmVycmFsVW5jbGFpbWVkIg5nd3hBbW91bnRTdGFydCIPbG9ja1N0YXJ0SGVpZ2h0IhJsb2NrRHVyYXRpb25CbG9ja3MiDWxvY2tFbmRIZWlnaHQiDHNjYWxlOFBhcmFtSyIMc2NhbGU4UGFyYW1CIgx3eExvY2tBbW91bnQiDGxvY2tEdXJhdGlvbiIPbWF4TG9ja0R1cmF0aW9uIgdjb2VmZlg4Igt4MUJpZ0ludFN0ciILeDJCaWdJbnRTdHIiDGFtcEJpZ0ludFN0ciITYVByZWNpc2lvbkJpZ0ludFN0ciIYdGFyZ2V0UHJlY2lzaW9uQmlnSW50U3RyIgZuQ29pbnMiCmFQcmVjaXNpb24iD3RhcmdldFByZWNpc2lvbiICeDEiAngyIgNhbXAiA2FubiIDYXJyIgRjYWxjIgNhY2MiA2N1ciINJHQwMjMxMjEyMzE0OCIBZCIFZFByZXYiBWZvdW5kIgJkcCIFZE5leHQiBWREaWZmIg0kdDAyMzc0NjIzODA5IgIkbCICJHMiBSRhY2MwIgUkZjBfMSICJGEiAiRpIgUkZjBfMiIOYXJnc0NvbXBhcmlzb24iDW1heFJlY2lwaWVudHMiB3BheW1lbnQiDnBheW1lbnRBc3NldElkIg1wYXltZW50QW1vdW50IhF1c2VyQWRkcmVzc1N0cmluZyIGcmV3YXJkIgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXlfAAFhAgJfXwABYgDoBwABYwCAwtcvAAFkCQC2AgEAAAABZQAAAAFmAAEAAWcCBVdBVkVTAQFoAQFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWkAAAEBagEBaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAWkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAWkCDyBpcyBub3QgZGVmaW5lZAEBawEBaQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFpAgABAWwBAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQFpCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQFpAg8gaXMgbm90IGRlZmluZWQBAW0BAW4DCQAAAgUBbgUBZwUEdW5pdAkA2QQBBQFuAQFvAQFwCQC5CQIJAMwIAgIQZ3d4X3Jld2FyZC5yaWRlOgkAzAgCBQFwBQNuaWwCASABAXEBAXAJAAIBCQEBbwEFAXABAXIBAXMDCQBmAgAABQFzCQEBLQEFAXMFAXMBAXQBAXMDCQC/AgIFAWQFAXMJAL4CAQUBcwUBcwABdQIMJXNfX21heERlcHRoAAF2AB4AAXcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBdQUBdgEBeAACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAAXkJAQFsAQkBAXgAAAF6CQERQGV4dHJOYXRpdmUoMTA2MikBBQF5AQFBAAIdJXMlc19fY29uZmlnX19lbWlzc2lvbkFkZHJlc3MBAUIACQC5CQIJAMwIAgICJXMJAMwIAgIWdm90aW5nRW1pc3Npb25Db250cmFjdAUDbmlsBQFhAAFDCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQF6CQEBQgABAUQBAUUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIHbWFwcGluZwkAzAgCAghudW0ydXNlcgkAzAgCCQCkAwEFAUUFA25pbAUBYQABRgkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgILcHJvZ3JhbU5hbWUFA25pbAUBYQABRwIGd3hsb2NrAAFICQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAUYFAUcAAUkJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICDG1pbkdXeEFtb3VudAUDbmlsBQFhAAFKCQBoAgD0AwUBYwABSwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFJBQFKAAFMCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJlclJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAU0AMgABTgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFMBQFNAAFPCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAVAAMgABUQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFPBQFQAQFSAQFTCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICCHJlZmVycmVyCQDMCAIFAUgJAMwIAgUBUwUDbmlsBQFhAQFUAgFVAVYJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIRdW5jbGFpbWVkUmVmZXJyYWwJAMwIAgUBVQkAzAgCBQFWBQNuaWwFAWEAAVcJAQFsAQkBAUEAAAFYCQERQGV4dHJOYXRpdmUoMTA2MikBBQFXAAFZAAEAAVoAAgACYWEAAwACYWIABAECYWMAAgolc19fY29uZmlnAQJhZAAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQEBQQAJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4JAQFBAAIPIGlzIG5vdCBkZWZpbmVkAAJhZQkBAmFkAAACYWYJAJEDAgkAtQkCCQEFdmFsdWUBCQCdCAIFAmFlCQECYWMABQFhAAEAAmFnCQDZBAEFAmFmAQJhaAAJALUJAgkBAWwBCQECYWMABQFhAQJhaQQCYWYCYWoCYWsBdwkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAIFAmFmCQDMCAIFAmFqCQDMCAIFAmFrCQDMCAIJAKQDAQUBdwUDbmlsBQFhAQJhbAAEAmFtCQECYWgACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJhbQUCYWECKGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MgaXMgbm90IGRlZmluZWQBAmFuAAIoJXMlc19fZ3d4UmV3YXJkRW1pc3Npb25QYXJ0X19zdGFydEhlaWdodAECYW8AAg8lc19fbmV4dFVzZXJOdW0BAmFwAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhcQACHyVzJXNfX2d3eEhvbGRlcnNSZXdhcmRfX2N1cnJlbnQBAmFyAAIcJXMlc19fZ3d4SG9sZGVyc1Jld2FyZF9fbmV4dAECYXMAAiAlcyVzX19wb29sV2VpZ2h0X19HV1h2aXJ0dWFsUE9PTAECYXQAAhUlc19fbmV4dFByb2Nlc3NlZFVzZXIBAmF1AAIQJXNfX2xhdGVzdFBlcmlvZAECYXYAAg4lc19fbmV4dFBlcmlvZAECYXcAAhMlc19fcHJvY2Vzc2luZ1N0YWdlAQJheAACFyVzX19uZXh0UHJvY2Vzc2VkUGVyaW9kAQJheQECYXoJALkJAgkAzAgCAgQlcyVkCQDMCAICDXVzZXJVbmNsYWltZWQJAMwIAgkApAMBBQJhegUDbmlsBQFhAQJhQQECYXoJALkJAgkAzAgCAhclcyVkX19uZXh0Q2xhaW1lZFBlcmlvZAkAzAgCCQCkAwEFAmF6BQNuaWwFAWEBAmFCAQJhegkAuQkCCQDMCAICGSVzJWRfX2xhc3RQcm9jZXNzZWRQZXJpb2QJAMwIAgkApAMBBQJhegUDbmlsBQFhAQJhQwECYUQJALkJAgkAzAgCAholcyVkX19zdGFydEhlaWdodEZvclBlcmlvZAkAzAgCCQCkAwEFAmFEBQNuaWwFAWEBAmFFAQJhRAkAuQkCCQDMCAICFyVzJWRfX2F1eEVtaXNzaW9uUmV3YXJkCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYUYBAmFECQC5CQIJAMwIAgIaJXMlZF9fdG90YWxBbW91bnRGb3JQZXJpb2QJAMwIAgkApAMBBQJhRAUDbmlsBQFhAQJhRwACEiVzX19sYXN0UGF5b3V0SW5mbwECYUgDAmFEAmFJAmFKCQC5CQIJAMwIAgIGJWQlZCVkCQDMCAIJAKQDAQUCYUQJAMwIAgkApAMBBQJhSQkAzAgCCQCkAwEFAmFKBQNuaWwFAWEBAmFLAQJhRAkAuQkCCQDMCAICGCVzJXMlZF9fcGF5b3V0c19faGlzdG9yeQkAzAgCCQCkAwEFAmFEBQNuaWwFAWEBAmFMAQJhRAkAuQkCCQDMCAICGiVzJWRfX3RvdGFsV2VpZ2h0Rm9yUGVyaW9kCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU0CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgFrCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU4CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgFiCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU8CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgZ3ZWlnaHQJAMwIAgkApAMBBQJhRAUDbmlsBQFhAQJhUAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBmNvbmZpZwkAzAgCAhhyZWZlcnJhbHNDb250cmFjdEFkZHJlc3MFA25pbAUBYQACYVEJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQFsAQkBAmFQAAECYVICAmFTAmFUCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgINdHJhZGluZ1Jld2FyZAkAzAgCAgdoaXN0b3J5CQDMCAIFAmFTCQDMCAIJANgEAQgFAmFUDXRyYW5zYWN0aW9uSWQFA25pbAUBYQECYVUBAmFWCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg10cmFkaW5nUmV3YXJkCQDMCAIFAmFWBQNuaWwFAWEBAmFXAAkAuQkCCQDMCAICAiVzCQDMCAICDW1heFJlY2lwaWVudHMFA25pbAUBYQECYVgEAmFZAmFTAmFaAmFUBAJiYQkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFAmFZCQDMCAIFAmFTCQDMCAIJANgEAQgFAmFUDXRyYW5zYWN0aW9uSWQFA25pbAUBYQQCYmIJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUCYVoFA25pbAUBYQkBC1N0cmluZ0VudHJ5AgUCYmEFAmJiAQJiYwACFCVzX19tYW5hZ2VyUHVibGljS2V5AQJiZAACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQJiZQAEAmJmCQCiCAEJAQJiZAADCQABAgUCYmYCBlN0cmluZwQCYmcFAmJmCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiZwUEdGhpcwECYmgABAJiaQkBAmJlAAQCYmYJAJ0IAgUCYmkJAQJiYwADCQABAgUCYmYCBlN0cmluZwQCYmcFAmJmCQDZBAEFAmJnAwkAAQIFAmJmAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmJqAQJhVAQCYmsJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQCYmYJAQJiaAADCQABAgUCYmYCCkJ5dGVWZWN0b3IEAmJsBQJiZgMJAAACCAUCYVQPY2FsbGVyUHVibGljS2V5BQJibAYFAmJrAwkAAQIFAmJmAgRVbml0AwkAAAIIBQJhVAZjYWxsZXIFBHRoaXMGBQJiawkAAgECC01hdGNoIGVycm9yAQJibQQCYm4CYm8CYUQCYXoEAmJwCQECYUIBBQJhegQCYnEJAQJhTQIFAmFEBQJhegQCYnIJAJoIAgUCYm4FAmJxBAJicwkBAmFPAgUCYUQFAmF6AwkBCWlzRGVmaW5lZAEFAmJyBAJidAkBBXZhbHVlAQUCYnIEAmJ1CQEFdmFsdWUBCQCaCAIFAmJuCQECYU4CBQJhRAUCYXoEAmJ2CQBkAgkAaAIFAmJ0BQJibwUCYnUDCQBmAgUCYnYAAAkAlAoCCQBpAgUCYnYFAWIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJwBQJhRAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYnMFAmJ2BQNuaWwJAJQKAgAABQNuaWwEAmJ3CQCaCAIFBHRoaXMFAmJwAwMJAQlpc0RlZmluZWQBBQJidwkAZwIFAmFECQEFdmFsdWUBBQJidwcEAmJ4CQEFdmFsdWUBBQJidwQCYnQJAQV2YWx1ZQEJAJoIAgUCYm4JAQJhTQIFAmJ4BQJhegQCYnUJAQV2YWx1ZQEJAJoIAgUCYm4JAQJhTgIFAmJ4BQJhegQCYnYJAGQCCQBoAgUCYnQFAmJvBQJidQMJAGYCBQJidgAACQCUCgIJAGkCBQJidgUBYgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYnMFAmJ2BQNuaWwJAJQKAgAABQNuaWwJAJQKAgAABQNuaWwBAmJ5BAJibgJibwJhRAJhegQCYnMJAQJhTwIFAmFEBQJhegQCYnoJAJ8IAQUCYnMEAmJmBQJiegMJAAECBQJiZgIEVW5pdAAAAwkAAQIFAmJmAgNJbnQEAmJ2BQJiZgkAaQIFAmJ2BQFiCQACAQILTWF0Y2ggZXJyb3IBAmJBAgJhawJhVgQBaQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgdtYXBwaW5nCQDMCAICCHVzZXIybnVtCQDMCAIFAmFWBQNuaWwFAWEJAQ1wYXJzZUludFZhbHVlAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQdBZGRyZXNzAQkA2QQBBQJhawUBaQkArAICCQCsAgIJAKwCAgINVXNlciBhZGRyZXNzIAUCYVYCLSBpcyBub3QgZm91bmQgaW4gYm9vc3RpbmcgY29udHJhY3QgZGF0YSwga2V5PQUBaQECYkIACQEBaAEJAQJhdgABAmJDAQJhVgQCYW0JAQJhaAAEAmJECQECYkECCQCRAwIFAmFtBQJhYQUCYVYEAmJFCQCfCAEJAQJheQEFAmJEBAJiZgUCYkUDCQABAgUCYmYCBFVuaXQJAJQKAgAABQNuaWwDCQABAgUCYmYCA0ludAQCYkYFAmJmCQCUCgIFAmJGCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXkBBQJiRAAABQNuaWwJAAIBAgtNYXRjaCBlcnJvcgECYkcBAmFWCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhVQEFAmFWAAASAmFUARN0cmFkZVJld2FyZEludGVybmFsBAJiSAJiSQJiSgJiSwMJAAACBQJiSwkAkAMBBQJiSQUDbmlsBAJiTAkAzAgCAwkAAAIIBQJhVAZjYWxsZXIFBHRoaXMGCQEBcQECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIDCQBnAgUCYkgJAJEDAgUCYkoFAmJLBgkBAXEBAhxpbnN1ZmZpY2llbnQgcGF5bWVudCBhc3NldElkBQNuaWwDCQAAAgUCYkwFAmJMBAJiTQkA/AcEBQR0aGlzAhN0cmFkZVJld2FyZEludGVybmFsCQDMCAIJAGUCBQJiSAkAkQMCBQJiSgUCYksJAMwIAgUCYkkJAMwIAgUCYkoJAMwIAgkAZAIFAmJLAAEFA25pbAUDbmlsAwkAAAIFAmJNBQJiTQQCYk4JAQJhUgIJAJEDAgUCYkkFAmJLBQJhVAQCYVYJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYkkFAmJLCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJOCQCRAwIFAmJKBQJiSwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFVAQkAkQMCBQJiSQUCYksJAJEDAgUCYkoFAmJLBQNuaWwFAmJNCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUARZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5AgJhVgJiTwQCYlAJAJ0IAgUCYVEJAQFSAQUCYVYEAmJRAwkAAAIFAmJQBQR1bml0BQR1bml0CQD8BwQFAmFRAhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIFAUgJAMwIAgUCYVYJAMwIAgkAZwIFAmJPBQFLBQNuaWwFA25pbAMJAAACBQJiUQUCYlEJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUAQ5maW5hbGl6ZUhlbHBlcgAEAmJSCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhdwAFAWUEAmJTCQEBaAEJAQJheAAEAmJUCQEBaAEJAQJhdAAEAmJVCQEBaAEJAQJhdQAEAmJWCQELdmFsdWVPckVsc2UCCQCaCAIJAQJhbAAJAQJhbwAAAAQCYlcJAQJhTAEFAmJTBAJiWAkBAWgBCQECYUwBBQJiUwQCYm8JAQFoAQkBAmFDAQUCYlMDCQBmAgUCYlMFAmJVCQCUCgIFA25pbAcDCQAAAgUCYlIFAWUEAmJZCQECYm0ECQECYWwABQJibwUCYlMFAmJUBAJiWggFAmJZAl8xBAJjYQgFAmJZAl8yBAJjYgkAZAIFAmJYBQJiWgQCY2MDCQBmAgkAZQIFAmJWAAEFAmJUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXQACQBkAgUCYlQAAQUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXcABQFmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXQAAAAFA25pbAkAlAoCCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYlcFAmNiBQNuaWwFAmNjBQJjYQYDCQAAAgUCYlIFAWYEAmJaCQECYnkECQECYWwABQJibwUCYlMFAmJUBAJjZAkAawMJAQFoAQkBAmFGAQUCYlMFAmJaBQJiWAQCY2UJAGsDCQEBaAEJAQJhRQEFAmJTBQJiWgUCYlgEAmNmCQBkAgUCY2UFAmNkBAJiRQkAnwgBCQECYXkBBQJiVAQCYVYJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQJhbAAJAQFEAQUCYlQEAmJQCQCdCAIFAmFRCQEBUgEFAmFWBAJiUQMJAAACBQJiUAUEdW5pdAUEdW5pdAkA/AcEBQJhUQIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCBQFICQDMCAIFAmFWCQDMCAIJAGcCBQJiWgUBSwUDbmlsBQNuaWwDCQAAAgUCYlEFAmJRBAJjZwMDCQAAAgUCYlAFBHVuaXQGCQBmAgUBSwUCYloFBHVuaXQEAmNoCQBrAwUCY2YFAU4FAWIEAmNpCQBrAwUCY2YFAVEFAWIJAPwHBAUCYVECDGluY1VuY2xhaW1lZAkAzAgCBQFICQDMCAIFAmFWCQDMCAIFAmNoCQDMCAIFAmNpBQNuaWwFA25pbAMJAAACBQJjZwUCY2cEAmNqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXkBBQJiVAkAZAIJAQt2YWx1ZU9yRWxzZQIFAmJFAAAFAmNmBQNuaWwEAmNjAwkAZgIJAGUCBQJiVgABBQJiVAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF0AAkAZAIFAmJUAAEFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF4AAkAZAIFAmJTAAEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhdAAAAAkAzAgCCQELRGVsZXRlRW50cnkBCQECYXcABQNuaWwJAJQKAgkAzggCBQJjagUCY2MGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIYaW52YWxpZCBwcm9jZXNzaW5nIHN0YWdlAmFUAQ9maW5hbGl6ZVdyYXBwZXIBAmNrBAJjbAoAAmNtCQD8BwQFBHRoaXMCDmZpbmFsaXplSGVscGVyBQNuaWwFA25pbAMJAAECBQJjbQIHQm9vbGVhbgUCY20JAAIBCQCsAgIJAAMBBQJjbQIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjbAUCY2wDCQEBIQEFAmNsAwkAAAIFAmNrBQF3CQACAQISTm90aGluZyB0byBwcm9jZXNzCQCUCgIFA25pbAUEdW5pdAMJAGYCBQJjawAACQCUCgIFA25pbAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgkAZQIFAmNrAAEFA25pbAUDbmlsCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAEdcHJvY2Vzc1BlbmRpbmdQZXJpb2RzQW5kVXNlcnMACQCUCgIFA25pbAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgUBdwUDbmlsBQNuaWwCYVQBB2RlcG9zaXQABAJjbgMJAAACCAUCYVQGY2FsbGVyBQFDBgkBAmJqAQUCYVQDCQAAAgUCY24FAmNuBAJhRAkBAmJCAAQCY28JAGUCBQZoZWlnaHQJAQFqAQkBAmFuAAQCY3AJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFYCQECYXAACQCsAgIJAKwCAgIcbWFuZGF0b3J5IGVtaXNzaW9uX2NvbnRyYWN0LgkBAmFwAAIPIGlzIG5vdCBkZWZpbmVkBAJjcQkBC3ZhbHVlT3JFbHNlAgkAmggCBQFYCQECYXEAAAADCQAAAgUCY3EFAmNxBAJjcgkAawMJAGgCBQJjbwUCY3EFAmNwBQFjBAJjcwMJAGYCBQJjcgAACQD8BwQFAVgCBGVtaXQJAMwIAgUCY3IFA25pbAUDbmlsBQR1bml0AwkAAAIFAmNzBQJjcwQCY3QAAAQCY3UJAQJhSAMFAmFEBQJjdAUCY3IEAmN2CgACY20JAPwHBAUBWAIWZ3d4SG9sZGVyc1Jld2FyZFVwZGF0ZQUDbmlsBQNuaWwDCQABAgUCY20CB0Jvb2xlYW4FAmNtCQACAQkArAICCQADAQUCY20CHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3YFAmN2BAJjdwkAZAIFAmN0BQJjcgQCY3gDAwkAAAIFAmN3AAAJAQEhAQUCY3YHBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhdQAFAmFECQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUMBBQJhRAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUUBBQJhRAUCY3IJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbgAFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFGAQUCYUQFAmN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXYACQBkAgUCYUQAAQkAzAgCCQELU3RyaW5nRW50cnkCCQECYUcABQJjdQkAzAgCCQELU3RyaW5nRW50cnkCCQECYUsBBQJhRAUCY3UFA25pbAkAlAoCBQJjeAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAELY2xhaW1SZXdhcmQABAJhbQkBAmFoAAQCY3kJAKUIAQgFAmFUBmNhbGxlcgQCY3oJAQJiQwEFAmN5BAJhWggFAmN6Al8xBAJjeAgFAmN6Al8yBAJjQQMJAGYCBQJhWgAABgkAAgECEE5vdGhpbmcgdG8gY2xhaW0DCQAAAgUCY0EFAmNBBAJjQgAABAJjQwoAAmNtCQD8BwQFAmFRAgVjbGFpbQkAzAgCBQFIBQNuaWwFA25pbAMJAAECBQJjbQIDSW50BQJjbQkAAgEJAKwCAgkAAwEFAmNtAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmNECQBkAgUCYVoFAmNDCQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCYVQGY2FsbGVyBQJjRAkA2QQBCQCRAwIFAmFtBQFZCQDMCAIJAQJhWAQCBWNsYWltBQJjeQUCYVoFAmFUBQNuaWwFAmN4CQDMCAIFAmNECQDMCAIFAmNCBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBE2NsYWltUmV3YXJkUkVBRE9OTFkBAmN5BAJjRQkBAmJDAQUCY3kEAmFaCAUCY0UCXzEEAmN4CAUCY0UCXzIEAmNGCQELdmFsdWVPckVsc2UCCQCaCAIFAmFRCQEBVAIFAUgFAmN5AAAEAmNECQBkAgUCYVoFAmNGCQCUCgIFA25pbAUCY0QCYVQBHWxhdGVzdEZpbmFsaXplZFBlcmlvZFJFQURPTkxZAQJjeQkAlAoCBQNuaWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmF1AAD///////////8BAmFUASFsYXRlc3RGaW5hbGl6ZWRQZXJpb2RJbmZvUkVBRE9OTFkBAmN5CQCUCgIFA25pbAkBAWsBCQECYUcAAmFUARVjYWxjR3d4UGFyYW1zUkVBRE9OTFkDAmNHAmNIAmNJBAJjSgkAZAIFAmNIBQJjSQQCY0sJAQEtAQkAawMFAmNHBQFiBQJjSQQCY0wJAGgCCQBrAwUCY0cFAWIFAmNJBQJjSgkAlAoCBQNuaWwJAMwIAgUCY0sJAMwIAgUCY0wJAMwIAgkBAmJCAAUDbmlsAmFUARpjYWxjR3d4QW1vdW50U3RhcnRSRUFET05MWQMCY00CY04CY08EAmNQCQBrAwUCY04FAWMFAmNPBAJiTwkAawMFAmNNBQJjUAUBYwkAlAoCBQNuaWwJAMwIAgUCYk8FA25pbAJhVAEVb25FbWlzc2lvbkZvckd3eFN0YXJ0AAMJAQIhPQIIBQJhVAZjYWxsZXIFAXoJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbgAFBmhlaWdodAUDbmlsAmFUASNsYXRlc3RQZXJpb2RFbWlzc2lvblJld2FyZHNSRUFET05MWQECY3kEAmFECQECYkIACQCUCgIFA25pbAkAzAgCCQEBaAEJAQJhRQEFAmFEBQNuaWwCYVQBBWNhbGNEBQJjUQJjUgJjUwJjVAJjVQQCY1YJALYCAQACBAJjVwkApwMBBQJjVAQCY1gJAKcDAQUCY1UEAmNZCQCnAwEFAmNRBAJjWgkApwMBBQJjUgQCZGEJALkCAgkApwMBBQJjUwUCY1cEAmJnCQC3AgIFAmNZBQJjWgMJAAACBQJiZwUBZAkAlAoCBQNuaWwJAKYDAQUBZAQCZGIJALkCAgUCZGEFAmNWBAJkYwkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYFA25pbAoBAmRkAgJkZQJkZgQCZGcFAmRlBAJkaAgFAmRnAl8xBAJkaQgFAmRnAl8yBAJkaggFAmRnAl8zAwkBAiE9AgUCZGoFBHVuaXQFAmRlBAJkawkAugICCQC5AgIJALkCAgUCZGgFAmRoBQJkaAkAuQICCQC5AgIJALkCAgUCY1kFAmNaBQJjVgUCY1YEAmRsCQC6AgIJALkCAgkAtwICCQC6AgIJALkCAgUCZGIFAmJnBQJjVwkAuQICBQJkawUCY1YFAmRoCQC3AgIJALoCAgkAuQICCQC4AgIFAmRiBQJjVwUCZGgFAmNXCQC5AgIJALcCAgUCY1YJALYCAQABBQJkawQCZG0JAQF0AQkAuAICBQJkbAkBBXZhbHVlAQUCZGgDCQDAAgIFAmNYBQJkbQkAlQoDBQJkbAUCZGgFAmRmCQCVCgMFAmRsBQJkaAUEdW5pdAQCZG4KAAJkbwUCZGMKAAJkcAkAkAMBBQJkbwoAAmRxCQCVCgMFAmJnBQR1bml0BQR1bml0CgECZHICAmRzAmR0AwkAZwIFAmR0BQJkcAUCZHMJAQJkZAIFAmRzCQCRAwIFAmRvBQJkdAoBAmR1AgJkcwJkdAMJAGcCBQJkdAUCZHAFAmRzCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNwkBAmR1AgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgUCZHEAAAABAAIAAwAEAAUABgAHBAJkbAgFAmRuAl8xBAJkaQgFAmRuAl8yBAJkaggFAmRuAl8zAwkBAiE9AgUCZGoFBHVuaXQJAJQKAgUDbmlsCQCmAwEFAmRsBAJkbQkBAXQBCQC4AgIFAmRsCQEFdmFsdWUBBQJkaQkAAgEJAKwCAgIdRCBjYWxjdWxhdGlvbiBlcnJvciwgZERpZmYgPSAJAKYDAQUCZG0CYVQBC3RyYWRlUmV3YXJkAgJiSQJiSgQCZHYJAAACCQCQAwEFAmJJCQCQAwEFAmJKBAJkdwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYVcAAAAEAmR4CQCRAwIIBQJhVAhwYXltZW50cwAABAJkeQgFAmR4B2Fzc2V0SWQEAmR6CAUCZHgGYW1vdW50BAJiTAkAzAgCAwkAZwIFAmR3CQCQAwEFAmJJBgkBAXEBAhNUb28gbWFueSByZWNpcGllbnRzCQDMCAIDBQJkdgYJAQFxAQIXQXJndW1lbnRzIHNpemUgbWlzbWF0Y2gJAMwIAgMJAAACBQJkeQUCYWcGCQEBcQECE1dyb25nIGFzc2V0IHBheW1lbnQFA25pbAMJAAACBQJiTAUCYkwEAmJNCQD8BwQFBHRoaXMCE3RyYWRlUmV3YXJkSW50ZXJuYWwJAMwIAgUCZHoJAMwIAgUCYkkJAMwIAgUCYkoJAMwIAgAABQNuaWwFA25pbAMJAAACBQJiTQUCYk0JAJQKAgUDbmlsBQJiTQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAESY2xhaW1UcmFkaW5nUmV3YXJkAAQCYVYIBQJhVAZjYWxsZXIEAmRBCQClCAEFAmFWBAJkQgkBAmJHAQUCZEEDCQBmAgUCZEIAAAkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFWBQJkQgUCYWcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhVQEFAmRBAAAFA25pbAUCZEIJAQFxAQIQbm90aGluZyB0byBjbGFpbQJhVAEaY2xhaW1UcmFkaW5nUmV3YXJkUkVBRE9OTFkBAmFWCQCUCgIFA25pbAkBAmJHAQUCYVYBAmRDAQJkRAAEAmRFBAJiZgkBAmJoAAMJAAECBQJiZgIKQnl0ZVZlY3RvcgQCYmwFAmJmBQJibAMJAAECBQJiZgIEVW5pdAgFAmRDD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJkQwlib2R5Qnl0ZXMJAJEDAggFAmRDBnByb29mcwAABQJkReC5ky4=", "height": 2765087, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: D2pxJxcYEhJxxbt4AsasHmgTGpcAJvxVodqyJx2TZXBD Next: none Diff:
OldNewDifferences
77
88 let MULT8 = 100000000
99
10-let MULT8BI = toBigInt(MULT8)
11-
1210 let zeroBigInt = toBigInt(0)
1311
1412 let processingStageTotal = 0
1513
1614 let processingStageShares = 1
1715
18-let MULT18 = 1000000000000000000
16+let wavesString = "WAVES"
1917
20-let MULT18BI = toBigInt(MULT18)
18+func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
2119
22-let wavesString = "WAVES"
20+
21+func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
22+
23+
24+func getStringByKey (key) = valueOrElse(getString(this, key), "")
25+
26+
27+func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
28+
29+
30+func parseAssetId (input) = if ((input == wavesString))
31+ then unit
32+ else fromBase58String(input)
33+
2334
2435 func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
2536
2637
2738 func throwErr (msg) = throw(wrapErr(msg))
28-
29-
30-func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
31-
32-
33-func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
34-
35-
36-func getStringByKey (key) = valueOrElse(getString(this, key), "")
37-
38-
39-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
40-
41-
42-func parseAssetId (input) = if ((input == wavesString))
43- then unit
44- else fromBase58String(input)
4539
4640
4741 func abs (val) = if ((0 > val))
144138 }
145139
146140
147-let keySuspension = "%s__suspension"
148-
149-let isSuspended = valueOrElse(getBoolean(this, keySuspension), false)
150-
151-func throwIfSuspended () = if (!(isSuspended))
152- then true
153- else throwErr("suspended")
154-
155-
156141 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
157142
158143
159144 func keyUsersCount () = "%s__nextUserNum"
160-
161-
162-func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", toString(userAddress)], SEP)
163145
164146
165147 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
174156 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
175157
176158
159+func keyNextProcessedUser () = "%s__nextProcessedUser"
160+
161+
162+func keyLatestPeriod () = "%s__latestPeriod"
163+
164+
165+func keyNextPeriod () = "%s__nextPeriod"
166+
167+
168+func keyProcessingStage () = "%s__processingStage"
169+
170+
171+func keyNextProcessedPeriod () = "%s__nextProcessedPeriod"
172+
173+
177174 func keyUserUnclaimed (userIndex) = makeString(["%s%d", "userUnclaimed", toString(userIndex)], SEP)
175+
176+
177+func keyNextUnlaimedPeriodOfUser (userIndex) = makeString(["%s%d__nextClaimedPeriod", toString(userIndex)], SEP)
178+
179+
180+func keyLastProcessedPeriodOfUser (userIndex) = makeString(["%s%d__lastProcessedPeriod", toString(userIndex)], SEP)
181+
182+
183+func keyHeightForPeriod (period) = makeString(["%s%d__startHeightForPeriod", toString(period)], SEP)
184+
185+
186+func keyAuxEmissionRewardForPeriod (period) = makeString(["%s%d__auxEmissionReward", toString(period)], SEP)
187+
188+
189+func keyTotalAmountForPeriod (period) = makeString(["%s%d__totalAmountForPeriod", toString(period)], SEP)
190+
191+
192+func keyLastPayoutInfo () = "%s__lastPayoutInfo"
193+
194+
195+func PeriodPayoutInfo (period,matcherReward,emissionReward) = makeString(["%d%d%d", toString(period), toString(matcherReward), toString(emissionReward)], SEP)
196+
197+
198+func keyPayoutHistoryInfo (period) = makeString(["%s%s%d__payouts__history", toString(period)], SEP)
199+
200+
201+func keyTotalWeightForPeriod (period) = makeString(["%s%d__totalWeightForPeriod", toString(period)], SEP)
202+
203+
204+func keyUserKValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "k", toString(period)], SEP)
205+
206+
207+func keyUserBValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "b", toString(period)], SEP)
208+
209+
210+func keyUserWeightForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "weight", toString(period)], SEP)
178211
179212
180213 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
242275 }
243276
244277
278+func calcUserWeight (boostingContractAddress,heightForPeriod,period,userIndex) = {
279+ let kLast = keyLastProcessedPeriodOfUser(userIndex)
280+ let kKey = keyUserKValueForPeriod(period, userIndex)
281+ let kRaw = getInteger(boostingContractAddress, kKey)
282+ let kUserWeight = keyUserWeightForPeriod(period, userIndex)
283+ if (isDefined(kRaw))
284+ then {
285+ let k = value(kRaw)
286+ let b = value(getInteger(boostingContractAddress, keyUserBValueForPeriod(period, userIndex)))
287+ let w = ((k * heightForPeriod) + b)
288+ if ((w > 0))
289+ then $Tuple2((w / SCALE), [IntegerEntry(kLast, period), IntegerEntry(kUserWeight, w)])
290+ else $Tuple2(0, nil)
291+ }
292+ else {
293+ let p = getInteger(this, kLast)
294+ if (if (isDefined(p))
295+ then (period >= value(p))
296+ else false)
297+ then {
298+ let pv = value(p)
299+ let k = value(getInteger(boostingContractAddress, keyUserKValueForPeriod(pv, userIndex)))
300+ let b = value(getInteger(boostingContractAddress, keyUserBValueForPeriod(pv, userIndex)))
301+ let w = ((k * heightForPeriod) + b)
302+ if ((w > 0))
303+ then $Tuple2((w / SCALE), [IntegerEntry(kUserWeight, w)])
304+ else $Tuple2(0, nil)
305+ }
306+ else $Tuple2(0, nil)
307+ }
308+ }
309+
310+
311+func calcUserWeightForClaim (boostingContractAddress,heightForPeriod,period,userIndex) = {
312+ let kUserWeight = keyUserWeightForPeriod(period, userIndex)
313+ let userWeightOrUnit = getInteger(kUserWeight)
314+ match userWeightOrUnit {
315+ case _: Unit =>
316+ 0
317+ case w: Int =>
318+ (w / SCALE)
319+ case _ =>
320+ throw("Match error")
321+ }
322+ }
323+
324+
245325 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
246326 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
247327 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
248328 }
249329
250330
331+func nextPeriod () = getNumberByKey(keyNextPeriod())
332+
333+
334+func commonClaimReward (userAddress) = {
335+ let cfgArray = readConfigArrayOrFail()
336+ let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337+ let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338+ match userUnclaimedOption {
339+ case _: Unit =>
340+ $Tuple2(0, nil)
341+ case u: Int =>
342+ $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
343+ case _ =>
344+ throw("Match error")
345+ }
346+ }
347+
348+
251349 func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
252350
253351
254-func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
352+@Callable(i)
353+func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = if ((currentIter == size(userAddresses)))
354+ then nil
355+ else {
356+ let checks = [if ((i.caller == this))
357+ then true
358+ else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
359+ then true
360+ else throwErr("insufficient payment assetId")]
361+ if ((checks == checks))
362+ then {
363+ let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
364+ if ((tradeRewardInternal == tradeRewardInternal))
365+ then {
366+ let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
367+ let userAddress = addressFromStringValue(userAddresses[currentIter])
368+ $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
369+ }
370+ else throw("Strict value is not equal to itself.")
371+ }
372+ else throw("Strict value is not equal to itself.")
373+ }
255374
256-
257-func getGwxAmountTotalOption () = {
258- let keyGwxTotal = "%s%s__gwx__total"
259- getInteger(boostingContractOrFail(), keyGwxTotal)
260- }
261-
262-
263-func getUserGwxAmountTotalOption (userAddress) = {
264- func keyUserGwxAmountTotal (userAddress) = makeString(["%s%s__gwxAmountTotal", toString(userAddress)], SEP)
265-
266- getInteger(boostingContractOrFail(), keyUserGwxAmountTotal(userAddress))
267- }
268-
269-
270-func _refreshRewardPerGwxIntegral () = {
271- let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
272- case s: String =>
273- parseBigInt(s)
274- case _: Unit =>
275- unit
276- case _ =>
277- throw("Match error")
278- }, zeroBigInt)
279- let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
280- let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
281- let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
282- let gwxAmountTotal = valueOrElse(getGwxAmountTotalOption(), 0)
283- let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
284- let gwxAmountTotalBI = toBigInt(gwxAmountTotal)
285- let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + (if ((gwxAmountTotalBI == zeroBigInt))
286- then zeroBigInt
287- else fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), (gwxAmountTotalBI * MULT8BI))))
288- $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
289- }
290-
291-
292-func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
293-
294-
295-func _refreshUserReward (userAddress,userNum) = {
296- let $t01029210380 = _refreshRewardPerGwxIntegral()
297- let rewardPerGwxIntegralActions = $t01029210380._1
298- let rewardPerGwxIntegral = $t01029210380._2
299- let rewardPerGwxIntegralUserLast = match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
300- case s: String =>
301- valueOrErrorMessage(parseBigInt(s), wrapErr("invalid user last integral"))
302- case _: Unit =>
303- rewardPerGwxIntegral
304- case _ =>
305- throw("Match error")
306- }
307- let userIdxOption = getString(boostingContractOrFail(), keyUser2NumMapping(userAddress))
308- let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userNum)), 0)
309- let userGwxAmount = valueOrElse(getUserGwxAmountTotalOption(userAddress), 0)
310- let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
311- $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
312- }
313-
314-
315-func commonClaimReward (userAddressStr) = {
316- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
317- let cfgArray = readConfigArrayOrFail()
318- let userNum = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddressStr)
319- let $t01167111735 = _refreshUserReward(userAddress, userNum)
320- let actions = $t01167111735._1
321- let reward = $t01167111735._2
322- $Tuple2(reward, ([IntegerEntry(keyUserUnclaimed(userNum), 0)] ++ actions))
323- }
324375
325376
326377 @Callable(i)
327-func refreshUserReward (userAddressBytes,userNum) = {
328- let suspensionCheck = throwIfSuspended()
329- if ((suspensionCheck == suspensionCheck))
330- then {
331- let checkCaller = if ((i.caller == boostingContractOrFail()))
332- then true
333- else throwErr("permission denied")
334- if ((checkCaller == checkCaller))
335- then {
336- let $t01206112139 = _refreshUserReward(Address(userAddressBytes), userNum)
337- let actions = $t01206112139._1
338- let reward = $t01206112139._2
339- $Tuple2(([IntegerEntry(keyUserUnclaimed(userNum), reward)] ++ actions), reward)
340- }
341- else throw("Strict value is not equal to itself.")
342- }
378+func updateReferralActivity (userAddress,gWxAmountStart) = {
379+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
380+ let activeReferralInv = if ((referrer == unit))
381+ then unit
382+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
383+ if ((activeReferralInv == activeReferralInv))
384+ then $Tuple2(nil, unit)
343385 else throw("Strict value is not equal to itself.")
344386 }
345387
346388
347389
348390 @Callable(i)
349-func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = {
350- let suspensionCheck = throwIfSuspended()
351- if ((suspensionCheck == suspensionCheck))
352- then if ((currentIter == size(userAddresses)))
353- then nil
354- else {
355- let checks = [if ((i.caller == this))
356- then true
357- else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
358- then true
359- else throwErr("insufficient payment assetId")]
360- if ((checks == checks))
361- then {
362- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
363- if ((tradeRewardInternal == tradeRewardInternal))
364- then {
365- let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
366- let userAddress = addressFromStringValue(userAddresses[currentIter])
367- $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
368- }
369- else throw("Strict value is not equal to itself.")
370- }
371- else throw("Strict value is not equal to itself.")
391+func finalizeHelper () = {
392+ let processingStage = valueOrElse(getInteger(keyProcessingStage()), processingStageTotal)
393+ let currentPeriod = getNumberByKey(keyNextProcessedPeriod())
394+ let currentUser = getNumberByKey(keyNextProcessedUser())
395+ let latestPeriod = getNumberByKey(keyLatestPeriod())
396+ let usersCount = valueOrElse(getInteger(boostingContractOrFail(), keyUsersCount()), 0)
397+ let totalWeightKey = keyTotalWeightForPeriod(currentPeriod)
398+ let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
399+ let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
400+ if ((currentPeriod > latestPeriod))
401+ then $Tuple2(nil, false)
402+ else if ((processingStage == processingStageTotal))
403+ then {
404+ let $t01451014626 = calcUserWeight(boostingContractOrFail(), heightForPeriod, currentPeriod, currentUser)
405+ let userWeight = $t01451014626._1
406+ let userActions = $t01451014626._2
407+ let totalWeightNew = (totalWeight + userWeight)
408+ let processingActions = if (((usersCount - 1) > currentUser))
409+ then [IntegerEntry(keyNextProcessedUser(), (currentUser + 1))]
410+ else [IntegerEntry(keyProcessingStage(), processingStageShares), IntegerEntry(keyNextProcessedUser(), 0)]
411+ $Tuple2((([IntegerEntry(totalWeightKey, totalWeightNew)] ++ processingActions) ++ userActions), true)
372412 }
413+ else if ((processingStage == processingStageShares))
414+ then {
415+ let userWeight = calcUserWeightForClaim(boostingContractOrFail(), heightForPeriod, currentPeriod, currentUser)
416+ let userAmountMatcherForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod)), userWeight, totalWeight)
417+ let userAmountEmissionForPeriod = fraction(getNumberByKey(keyAuxEmissionRewardForPeriod(currentPeriod)), userWeight, totalWeight)
418+ let userTotalAmount = (userAmountEmissionForPeriod + userAmountMatcherForPeriod)
419+ let userUnclaimedOption = getInteger(keyUserUnclaimed(currentUser))
420+ let userAddress = getStringValue(boostingContractOrFail(), keyNumToUserMapping(currentUser))
421+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
422+ let activeReferralInv = if ((referrer == unit))
423+ then unit
424+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userWeight >= referralMinGWxAmount)], nil)
425+ if ((activeReferralInv == activeReferralInv))
426+ then {
427+ let referralInv = if (if ((referrer == unit))
428+ then true
429+ else (referralMinGWxAmount > userWeight))
430+ then unit
431+ else {
432+ let referrerReward = fraction(userTotalAmount, referrerRewardPermille, SCALE)
433+ let referralReward = fraction(userTotalAmount, referralRewardPermille, SCALE)
434+ invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
435+ }
436+ if ((referralInv == referralInv))
437+ then {
438+ let unclaimedActions = [IntegerEntry(keyUserUnclaimed(currentUser), (valueOrElse(userUnclaimedOption, 0) + userTotalAmount))]
439+ let processingActions = if (((usersCount - 1) > currentUser))
440+ then [IntegerEntry(keyNextProcessedUser(), (currentUser + 1))]
441+ else [IntegerEntry(keyNextProcessedPeriod(), (currentPeriod + 1)), IntegerEntry(keyNextProcessedUser(), 0), DeleteEntry(keyProcessingStage())]
442+ $Tuple2((unclaimedActions ++ processingActions), true)
443+ }
444+ else throw("Strict value is not equal to itself.")
445+ }
446+ else throw("Strict value is not equal to itself.")
447+ }
448+ else throw("invalid processing stage")
449+ }
450+
451+
452+
453+@Callable(i)
454+func finalizeWrapper (counter) = {
455+ let result = {
456+ let @ = invoke(this, "finalizeHelper", nil, nil)
457+ if ($isInstanceOf(@, "Boolean"))
458+ then @
459+ else throw(($getType(@) + " couldn't be cast to Boolean"))
460+ }
461+ if ((result == result))
462+ then if (!(result))
463+ then if ((counter == maxDepth))
464+ then throw("Nothing to process")
465+ else $Tuple2(nil, unit)
466+ else if ((counter > 0))
467+ then $Tuple2(nil, invoke(this, "finalizeWrapper", [(counter - 1)], nil))
468+ else $Tuple2(nil, unit)
373469 else throw("Strict value is not equal to itself.")
374470 }
375471
376472
377473
378474 @Callable(i)
379-func updateReferralActivity (userAddress,gWxAmountStart) = {
380- let suspensionCheck = throwIfSuspended()
381- if ((suspensionCheck == suspensionCheck))
382- then {
383- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
384- let activeReferralInv = if ((referrer == unit))
385- then unit
386- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
387- if ((activeReferralInv == activeReferralInv))
388- then $Tuple2(nil, unit)
389- else throw("Strict value is not equal to itself.")
390- }
391- else throw("Strict value is not equal to itself.")
392- }
475+func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
393476
394477
395478
396479 @Callable(i)
397-func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
398-
399-
400-
401-@Callable(i)
402-func claimReward () = {
403- let suspensionCheck = throwIfSuspended()
404- if ((suspensionCheck == suspensionCheck))
480+func deposit () = {
481+ let checkCaller = if ((i.caller == votingEmissionContract))
482+ then true
483+ else mustManager(i)
484+ if ((checkCaller == checkCaller))
405485 then {
406- let cfgArray = readConfigArrayOrFail()
407- let userAddress = i.caller
408- let userAddressStr = toString(userAddress)
409- let $t01400914066 = commonClaimReward(userAddressStr)
410- let amount = $t01400914066._1
411- let actions = $t01400914066._2
412- let checkAmount = if ((amount > 0))
413- then true
414- else throw("nothing to claim")
415- if ((checkAmount == checkAmount))
486+ let period = nextPeriod()
487+ let deltaH = (height - getNumberOrFail(keyGwxRewardEmissionStartHeight()))
488+ let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), (("mandatory emission_contract." + keyRatePerBlockCurrent()) + " is not defined"))
489+ let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
490+ if ((gwxHoldersRewardCurrent == gwxHoldersRewardCurrent))
416491 then {
417- let userGwxAmount = {
418- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
419- if ($isInstanceOf(@, "Int"))
420- then @
421- else throw(($getType(@) + " couldn't be cast to Int"))
422- }
423- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
424- let activeReferralInv = if ((referrer == unit))
425- then unit
426- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
427- if ((activeReferralInv == activeReferralInv))
492+ let auxAmount = fraction((deltaH * gwxHoldersRewardCurrent), emissionRate, MULT8)
493+ let em = if ((auxAmount > 0))
494+ then invoke(emissionContract, "emit", [auxAmount], nil)
495+ else unit
496+ if ((em == em))
428497 then {
429- let referralInv = if (if ((referrer == unit))
430- then true
431- else (referralMinGWxAmount > userGwxAmount))
432- then unit
433- else {
434- let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
435- let referralReward = fraction(amount, referralRewardPermille, SCALE)
436- invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
437- }
438- if ((referralInv == referralInv))
498+ let matcherPart = 0
499+ let payoutInfo = PeriodPayoutInfo(period, matcherPart, auxAmount)
500+ let gwxHoldersRewardUpdated = {
501+ let @ = invoke(emissionContract, "gwxHoldersRewardUpdate", nil, nil)
502+ if ($isInstanceOf(@, "Boolean"))
503+ then @
504+ else throw(($getType(@) + " couldn't be cast to Boolean"))
505+ }
506+ if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
439507 then {
440- let emit = invoke(emissionContract, "emit", [amount], nil)
441- if ((emit == emit))
442- then {
443- let claimedReferral = {
444- let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
445- if ($isInstanceOf(@, "Int"))
446- then @
447- else throw(($getType(@) + " couldn't be cast to Int"))
448- }
449- if ((claimedReferral == claimedReferral))
450- then {
451- let totalAmount = (amount + claimedReferral)
452- $Tuple2(([ScriptTransfer(i.caller, amount, wxAssetId), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
453- }
454- else throw("Strict value is not equal to itself.")
455- }
456- else throw("Strict value is not equal to itself.")
508+ let totalReward = (matcherPart + auxAmount)
509+ let actions = if (if ((totalReward == 0))
510+ then !(gwxHoldersRewardUpdated)
511+ else false)
512+ then nil
513+ else [IntegerEntry(keyLatestPeriod(), period), IntegerEntry(keyHeightForPeriod(period), height), IntegerEntry(keyAuxEmissionRewardForPeriod(period), auxAmount), IntegerEntry(keyGwxRewardEmissionStartHeight(), height), IntegerEntry(keyTotalAmountForPeriod(period), matcherPart), IntegerEntry(keyNextPeriod(), (period + 1)), StringEntry(keyLastPayoutInfo(), payoutInfo), StringEntry(keyPayoutHistoryInfo(period), payoutInfo)]
514+ $Tuple2(actions, unit)
457515 }
458516 else throw("Strict value is not equal to itself.")
459517 }
467525
468526
469527 @Callable(i)
528+func claimReward () = {
529+ let cfgArray = readConfigArrayOrFail()
530+ let address = toString(i.caller)
531+ let $t01981519865 = commonClaimReward(address)
532+ let amount = $t01981519865._1
533+ let actions = $t01981519865._2
534+ let checkAmount = if ((amount > 0))
535+ then true
536+ else throw("Nothing to claim")
537+ if ((checkAmount == checkAmount))
538+ then {
539+ let amountFromEmission = 0
540+ let claimedReferral = {
541+ let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
542+ if ($isInstanceOf(@, "Int"))
543+ then @
544+ else throw(($getType(@) + " couldn't be cast to Int"))
545+ }
546+ let totalAmount = (amount + claimedReferral)
547+ $Tuple2(([ScriptTransfer(i.caller, totalAmount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", address, amount, i)] ++ actions), [totalAmount, amountFromEmission])
548+ }
549+ else throw("Strict value is not equal to itself.")
550+ }
551+
552+
553+
554+@Callable(i)
470555 func claimRewardREADONLY (address) = {
471- let $t01542315473 = commonClaimReward(address)
472- let amount = $t01542315473._1
473- let actions = $t01542315473._2
556+ let $t02043820488 = commonClaimReward(address)
557+ let amount = $t02043820488._1
558+ let actions = $t02043820488._2
474559 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
475560 let totalAmount = (amount + referralUnclaimed)
476561 $Tuple2(nil, totalAmount)
479564
480565
481566 @Callable(i)
482-func onEmissionForGwxStart () = {
483- let suspensionCheck = throwIfSuspended()
484- if ((suspensionCheck == suspensionCheck))
485- then if ((i.caller != factoryContract))
486- then throw("permissions denied")
487- else [IntegerEntry(keyGwxRewardEmissionStartHeight(), height)]
488- else throw("Strict value is not equal to itself.")
567+func latestFinalizedPeriodREADONLY (address) = $Tuple2(nil, valueOrElse(getInteger(this, keyLatestPeriod()), -1))
568+
569+
570+
571+@Callable(i)
572+func latestFinalizedPeriodInfoREADONLY (address) = $Tuple2(nil, getStringByKey(keyLastPayoutInfo()))
573+
574+
575+
576+@Callable(i)
577+func calcGwxParamsREADONLY (gwxAmountStart,lockStartHeight,lockDurationBlocks) = {
578+ let lockEndHeight = (lockStartHeight + lockDurationBlocks)
579+ let scale8ParamK = -(fraction(gwxAmountStart, SCALE, lockDurationBlocks))
580+ let scale8ParamB = (fraction(gwxAmountStart, SCALE, lockDurationBlocks) * lockEndHeight)
581+ $Tuple2(nil, [scale8ParamK, scale8ParamB, nextPeriod()])
582+ }
583+
584+
585+
586+@Callable(i)
587+func calcGwxAmountStartREADONLY (wxLockAmount,lockDuration,maxLockDuration) = {
588+ let coeffX8 = fraction(lockDuration, MULT8, maxLockDuration)
589+ let gWxAmountStart = fraction(wxLockAmount, coeffX8, MULT8)
590+ $Tuple2(nil, [gWxAmountStart])
591+ }
592+
593+
594+
595+@Callable(i)
596+func onEmissionForGwxStart () = if ((i.caller != factoryContract))
597+ then throw("permissions denied")
598+ else [IntegerEntry(keyGwxRewardEmissionStartHeight(), height)]
599+
600+
601+
602+@Callable(i)
603+func latestPeriodEmissionRewardsREADONLY (address) = {
604+ let period = nextPeriod()
605+ $Tuple2(nil, [getNumberByKey(keyAuxEmissionRewardForPeriod(period))])
606+ }
607+
608+
609+
610+@Callable(i)
611+func calcD (x1BigIntStr,x2BigIntStr,ampBigIntStr,aPrecisionBigIntStr,targetPrecisionBigIntStr) = {
612+ let nCoins = toBigInt(2)
613+ let aPrecision = parseBigIntValue(aPrecisionBigIntStr)
614+ let targetPrecision = parseBigIntValue(targetPrecisionBigIntStr)
615+ let x1 = parseBigIntValue(x1BigIntStr)
616+ let x2 = parseBigIntValue(x2BigIntStr)
617+ let amp = (parseBigIntValue(ampBigIntStr) * aPrecision)
618+ let s = (x1 + x2)
619+ if ((s == zeroBigInt))
620+ then $Tuple2(nil, toString(zeroBigInt))
621+ else {
622+ let ann = (amp * nCoins)
623+ let arr = [0, 1, 2, 3, 4, 5, 6]
624+ func calc (acc,cur) = {
625+ let $t02312123148 = acc
626+ let d = $t02312123148._1
627+ let dPrev = $t02312123148._2
628+ let found = $t02312123148._3
629+ if ((found != unit))
630+ then acc
631+ else {
632+ let dp = (((d * d) * d) / (((x1 * x2) * nCoins) * nCoins))
633+ let dNext = (((((ann * s) / aPrecision) + (dp * nCoins)) * d) / ((((ann - aPrecision) * d) / aPrecision) + ((nCoins + toBigInt(1)) * dp)))
634+ let dDiff = absBigInt((dNext - value(d)))
635+ if ((targetPrecision >= dDiff))
636+ then $Tuple3(dNext, d, cur)
637+ else $Tuple3(dNext, d, unit)
638+ }
639+ }
640+
641+ let $t02374623809 = {
642+ let $l = arr
643+ let $s = size($l)
644+ let $acc0 = $Tuple3(s, unit, unit)
645+ func $f0_1 ($a,$i) = if (($i >= $s))
646+ then $a
647+ else calc($a, $l[$i])
648+
649+ func $f0_2 ($a,$i) = if (($i >= $s))
650+ then $a
651+ else throw("List size exceeds 7")
652+
653+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
654+ }
655+ let dNext = $t02374623809._1
656+ let dPrev = $t02374623809._2
657+ let found = $t02374623809._3
658+ if ((found != unit))
659+ then $Tuple2(nil, toString(dNext))
660+ else {
661+ let dDiff = absBigInt((dNext - value(dPrev)))
662+ throw(("D calculation error, dDiff = " + toString(dDiff)))
663+ }
664+ }
489665 }
490666
491667
492668
493669 @Callable(i)
494670 func tradeReward (userAddresses,rewards) = {
495- let suspensionCheck = throwIfSuspended()
496- if ((suspensionCheck == suspensionCheck))
671+ let argsComparison = (size(userAddresses) == size(rewards))
672+ let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
673+ let payment = i.payments[0]
674+ let paymentAssetId = payment.assetId
675+ let paymentAmount = payment.amount
676+ let checks = [if ((maxRecipients >= size(userAddresses)))
677+ then true
678+ else throwErr("Too many recipients"), if (argsComparison)
679+ then true
680+ else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
681+ then true
682+ else throwErr("Wrong asset payment")]
683+ if ((checks == checks))
497684 then {
498- let argsComparison = (size(userAddresses) == size(rewards))
499- let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
500- let payment = i.payments[0]
501- let paymentAssetId = payment.assetId
502- let paymentAmount = payment.amount
503- let checks = [if ((maxRecipients >= size(userAddresses)))
504- then true
505- else throwErr("Too many recipients"), if (argsComparison)
506- then true
507- else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
508- then true
509- else throwErr("Wrong asset payment")]
510- if ((checks == checks))
511- then {
512- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
513- if ((tradeRewardInternal == tradeRewardInternal))
514- then $Tuple2(nil, tradeRewardInternal)
515- else throw("Strict value is not equal to itself.")
516- }
685+ let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
686+ if ((tradeRewardInternal == tradeRewardInternal))
687+ then $Tuple2(nil, tradeRewardInternal)
517688 else throw("Strict value is not equal to itself.")
518689 }
519690 else throw("Strict value is not equal to itself.")
523694
524695 @Callable(i)
525696 func claimTradingReward () = {
526- let suspensionCheck = throwIfSuspended()
527- if ((suspensionCheck == suspensionCheck))
528- then {
529- let userAddress = i.caller
530- let userAddressString = toString(userAddress)
531- let reward = getTradingReward(userAddressString)
532- if ((reward > 0))
533- then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
534- else throwErr("nothing to claim")
535- }
536- else throw("Strict value is not equal to itself.")
697+ let userAddress = i.caller
698+ let userAddressString = toString(userAddress)
699+ let reward = getTradingReward(userAddressString)
700+ if ((reward > 0))
701+ then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
702+ else throwErr("nothing to claim")
537703 }
538704
539705
540706
541707 @Callable(i)
542708 func claimTradingRewardREADONLY (userAddress) = $Tuple2(nil, getTradingReward(userAddress))
543-
544-
545-
546-@Callable(i)
547-func suspend (v) = {
548- let checkCaller = mustManager(i)
549- if ((checkCaller == checkCaller))
550- then $Tuple2([BooleanEntry(keySuspension, v)], v)
551- else throw("Strict value is not equal to itself.")
552- }
553709
554710
555711 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let SCALE = 1000
77
88 let MULT8 = 100000000
99
10-let MULT8BI = toBigInt(MULT8)
11-
1210 let zeroBigInt = toBigInt(0)
1311
1412 let processingStageTotal = 0
1513
1614 let processingStageShares = 1
1715
18-let MULT18 = 1000000000000000000
16+let wavesString = "WAVES"
1917
20-let MULT18BI = toBigInt(MULT18)
18+func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
2119
22-let wavesString = "WAVES"
20+
21+func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
22+
23+
24+func getStringByKey (key) = valueOrElse(getString(this, key), "")
25+
26+
27+func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
28+
29+
30+func parseAssetId (input) = if ((input == wavesString))
31+ then unit
32+ else fromBase58String(input)
33+
2334
2435 func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
2536
2637
2738 func throwErr (msg) = throw(wrapErr(msg))
28-
29-
30-func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
31-
32-
33-func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
34-
35-
36-func getStringByKey (key) = valueOrElse(getString(this, key), "")
37-
38-
39-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
40-
41-
42-func parseAssetId (input) = if ((input == wavesString))
43- then unit
44- else fromBase58String(input)
4539
4640
4741 func abs (val) = if ((0 > val))
4842 then -(val)
4943 else val
5044
5145
5246 func absBigInt (val) = if ((zeroBigInt > val))
5347 then -(val)
5448 else val
5549
5650
5751 let keyMaxDepth = "%s__maxDepth"
5852
5953 let maxDepthDefault = 30
6054
6155 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
6256
6357 func keyFactoryAddress () = "%s%s__config__factoryAddress"
6458
6559
6660 let factoryAddressStr = getStringOrFail(keyFactoryAddress())
6761
6862 let factoryContract = addressFromStringValue(factoryAddressStr)
6963
7064 func keyEmissionAddress () = "%s%s__config__emissionAddress"
7165
7266
7367 func keyVotingEmissionContract () = makeString(["%s", "votingEmissionContract"], SEP)
7468
7569
7670 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract()))
7771
7872 func keyNumToUserMapping (num) = makeString(["%s%s%s", "mapping", "num2user", toString(num)], SEP)
7973
8074
8175 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
8276
8377 let referralProgramNameDefault = "wxlock"
8478
8579 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
8680
8781 let keyReferralMinGWxAmount = makeString(["%s%s", "referral", "minGWxAmount"], SEP)
8882
8983 let referralMinGWxAmountDefault = (500 * MULT8)
9084
9185 let referralMinGWxAmount = valueOrElse(getInteger(this, keyReferralMinGWxAmount), referralMinGWxAmountDefault)
9286
9387 let keyReferrerRewardPermille = makeString(["%s%s", "referral", "referrerRewardPermille"], SEP)
9488
9589 let referrerRewardPermilleDefault = 50
9690
9791 let referrerRewardPermille = valueOrElse(getInteger(this, keyReferrerRewardPermille), referrerRewardPermilleDefault)
9892
9993 let keyReferralRewardPermille = makeString(["%s%s", "referral", "referralRewardPermille"], SEP)
10094
10195 let referralRewardPermilleDefault = 50
10296
10397 let referralRewardPermille = valueOrElse(getInteger(this, keyReferralRewardPermille), referralRewardPermilleDefault)
10498
10599 func keyReferrer (referralAddress) = makeString(["%s%s%s", "referrer", referralProgramName, referralAddress], SEP)
106100
107101
108102 func keyUnclaimedReferral (programName,claimerAddress) = makeString(["%s%s%s", "unclaimedReferral", programName, claimerAddress], SEP)
109103
110104
111105 let emissionAddressStr = getStringOrFail(keyEmissionAddress())
112106
113107 let emissionContract = addressFromStringValue(emissionAddressStr)
114108
115109 let IdxCfgAssetId = 1
116110
117111 let IdxCfgPacemakerAddress = 2
118112
119113 let IdxCfgBoostingContract = 3
120114
121115 let IdxCfgMaxDepth = 4
122116
123117 func keyConfig () = "%s__config"
124118
125119
126120 func getEmissionAddress () = addressFromStringValue(valueOrErrorMessage(getString(this, keyEmissionAddress()), (("mandatory this." + keyEmissionAddress()) + " is not defined")))
127121
128122
129123 let emissionAddress = getEmissionAddress()
130124
131125 let wxAssetIdStr = split(value(getString(emissionAddress, keyConfig())), SEP)[1]
132126
133127 let wxAssetId = fromBase58String(wxAssetIdStr)
134128
135129 func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP)
136130
137131
138132 func formatConfig (wxAssetIdStr,matcherPacemakerAddressStr,boostingContractAddressStr,maxDepth) = makeString(["%s%s%s%d", wxAssetIdStr, matcherPacemakerAddressStr, boostingContractAddressStr, toString(maxDepth)], SEP)
139133
140134
141135 func boostingContractOrFail () = {
142136 let cfgArray = readConfigArrayOrFail()
143137 valueOrErrorMessage(addressFromString(cfgArray[IdxCfgBoostingContract]), "boosting contract address is not defined")
144138 }
145139
146140
147-let keySuspension = "%s__suspension"
148-
149-let isSuspended = valueOrElse(getBoolean(this, keySuspension), false)
150-
151-func throwIfSuspended () = if (!(isSuspended))
152- then true
153- else throwErr("suspended")
154-
155-
156141 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
157142
158143
159144 func keyUsersCount () = "%s__nextUserNum"
160-
161-
162-func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", toString(userAddress)], SEP)
163145
164146
165147 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
166148
167149
168150 func keyGwxHoldersRewardCurrent () = "%s%s__gwxHoldersReward__current"
169151
170152
171153 func keyGwxHoldersRewardNext () = "%s%s__gwxHoldersReward__next"
172154
173155
174156 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
175157
176158
159+func keyNextProcessedUser () = "%s__nextProcessedUser"
160+
161+
162+func keyLatestPeriod () = "%s__latestPeriod"
163+
164+
165+func keyNextPeriod () = "%s__nextPeriod"
166+
167+
168+func keyProcessingStage () = "%s__processingStage"
169+
170+
171+func keyNextProcessedPeriod () = "%s__nextProcessedPeriod"
172+
173+
177174 func keyUserUnclaimed (userIndex) = makeString(["%s%d", "userUnclaimed", toString(userIndex)], SEP)
175+
176+
177+func keyNextUnlaimedPeriodOfUser (userIndex) = makeString(["%s%d__nextClaimedPeriod", toString(userIndex)], SEP)
178+
179+
180+func keyLastProcessedPeriodOfUser (userIndex) = makeString(["%s%d__lastProcessedPeriod", toString(userIndex)], SEP)
181+
182+
183+func keyHeightForPeriod (period) = makeString(["%s%d__startHeightForPeriod", toString(period)], SEP)
184+
185+
186+func keyAuxEmissionRewardForPeriod (period) = makeString(["%s%d__auxEmissionReward", toString(period)], SEP)
187+
188+
189+func keyTotalAmountForPeriod (period) = makeString(["%s%d__totalAmountForPeriod", toString(period)], SEP)
190+
191+
192+func keyLastPayoutInfo () = "%s__lastPayoutInfo"
193+
194+
195+func PeriodPayoutInfo (period,matcherReward,emissionReward) = makeString(["%d%d%d", toString(period), toString(matcherReward), toString(emissionReward)], SEP)
196+
197+
198+func keyPayoutHistoryInfo (period) = makeString(["%s%s%d__payouts__history", toString(period)], SEP)
199+
200+
201+func keyTotalWeightForPeriod (period) = makeString(["%s%d__totalWeightForPeriod", toString(period)], SEP)
202+
203+
204+func keyUserKValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "k", toString(period)], SEP)
205+
206+
207+func keyUserBValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "b", toString(period)], SEP)
208+
209+
210+func keyUserWeightForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "weight", toString(period)], SEP)
178211
179212
180213 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
181214
182215
183216 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(keyReferralsContractAddress()))
184217
185218 func keyTradingRewardHistory (user,i) = makeString(["%s%s%s%s", "tradingReward", "history", user, toBase58String(i.transactionId)], SEP)
186219
187220
188221 func keyTradingReward (userAddress) = makeString(["%s%s", "tradingReward", userAddress], SEP)
189222
190223
191224 func keyMaxRecipients () = makeString(["%s", "maxRecipients"], SEP)
192225
193226
194227 func HistoryEntry (type,user,amount,i) = {
195228 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
196229 let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount)], SEP)
197230 StringEntry(historyKEY, historyDATA)
198231 }
199232
200233
201234 func keyManagerPublicKey () = "%s__managerPublicKey"
202235
203236
204237 func keyManagerVaultAddress () = "%s__managerVaultAddress"
205238
206239
207240 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
208241 case s: String =>
209242 addressFromStringValue(s)
210243 case _ =>
211244 this
212245 }
213246
214247
215248 func managerPublicKeyOrUnit () = {
216249 let managerVaultAddress = getManagerVaultAddressOrThis()
217250 match getString(managerVaultAddress, keyManagerPublicKey()) {
218251 case s: String =>
219252 fromBase58String(s)
220253 case _: Unit =>
221254 unit
222255 case _ =>
223256 throw("Match error")
224257 }
225258 }
226259
227260
228261 func mustManager (i) = {
229262 let pd = throw("Permission denied")
230263 match managerPublicKeyOrUnit() {
231264 case pk: ByteVector =>
232265 if ((i.callerPublicKey == pk))
233266 then true
234267 else pd
235268 case _: Unit =>
236269 if ((i.caller == this))
237270 then true
238271 else pd
239272 case _ =>
240273 throw("Match error")
241274 }
242275 }
243276
244277
278+func calcUserWeight (boostingContractAddress,heightForPeriod,period,userIndex) = {
279+ let kLast = keyLastProcessedPeriodOfUser(userIndex)
280+ let kKey = keyUserKValueForPeriod(period, userIndex)
281+ let kRaw = getInteger(boostingContractAddress, kKey)
282+ let kUserWeight = keyUserWeightForPeriod(period, userIndex)
283+ if (isDefined(kRaw))
284+ then {
285+ let k = value(kRaw)
286+ let b = value(getInteger(boostingContractAddress, keyUserBValueForPeriod(period, userIndex)))
287+ let w = ((k * heightForPeriod) + b)
288+ if ((w > 0))
289+ then $Tuple2((w / SCALE), [IntegerEntry(kLast, period), IntegerEntry(kUserWeight, w)])
290+ else $Tuple2(0, nil)
291+ }
292+ else {
293+ let p = getInteger(this, kLast)
294+ if (if (isDefined(p))
295+ then (period >= value(p))
296+ else false)
297+ then {
298+ let pv = value(p)
299+ let k = value(getInteger(boostingContractAddress, keyUserKValueForPeriod(pv, userIndex)))
300+ let b = value(getInteger(boostingContractAddress, keyUserBValueForPeriod(pv, userIndex)))
301+ let w = ((k * heightForPeriod) + b)
302+ if ((w > 0))
303+ then $Tuple2((w / SCALE), [IntegerEntry(kUserWeight, w)])
304+ else $Tuple2(0, nil)
305+ }
306+ else $Tuple2(0, nil)
307+ }
308+ }
309+
310+
311+func calcUserWeightForClaim (boostingContractAddress,heightForPeriod,period,userIndex) = {
312+ let kUserWeight = keyUserWeightForPeriod(period, userIndex)
313+ let userWeightOrUnit = getInteger(kUserWeight)
314+ match userWeightOrUnit {
315+ case _: Unit =>
316+ 0
317+ case w: Int =>
318+ (w / SCALE)
319+ case _ =>
320+ throw("Match error")
321+ }
322+ }
323+
324+
245325 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
246326 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
247327 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
248328 }
249329
250330
331+func nextPeriod () = getNumberByKey(keyNextPeriod())
332+
333+
334+func commonClaimReward (userAddress) = {
335+ let cfgArray = readConfigArrayOrFail()
336+ let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337+ let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338+ match userUnclaimedOption {
339+ case _: Unit =>
340+ $Tuple2(0, nil)
341+ case u: Int =>
342+ $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
343+ case _ =>
344+ throw("Match error")
345+ }
346+ }
347+
348+
251349 func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
252350
253351
254-func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
352+@Callable(i)
353+func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = if ((currentIter == size(userAddresses)))
354+ then nil
355+ else {
356+ let checks = [if ((i.caller == this))
357+ then true
358+ else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
359+ then true
360+ else throwErr("insufficient payment assetId")]
361+ if ((checks == checks))
362+ then {
363+ let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
364+ if ((tradeRewardInternal == tradeRewardInternal))
365+ then {
366+ let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
367+ let userAddress = addressFromStringValue(userAddresses[currentIter])
368+ $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
369+ }
370+ else throw("Strict value is not equal to itself.")
371+ }
372+ else throw("Strict value is not equal to itself.")
373+ }
255374
256-
257-func getGwxAmountTotalOption () = {
258- let keyGwxTotal = "%s%s__gwx__total"
259- getInteger(boostingContractOrFail(), keyGwxTotal)
260- }
261-
262-
263-func getUserGwxAmountTotalOption (userAddress) = {
264- func keyUserGwxAmountTotal (userAddress) = makeString(["%s%s__gwxAmountTotal", toString(userAddress)], SEP)
265-
266- getInteger(boostingContractOrFail(), keyUserGwxAmountTotal(userAddress))
267- }
268-
269-
270-func _refreshRewardPerGwxIntegral () = {
271- let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
272- case s: String =>
273- parseBigInt(s)
274- case _: Unit =>
275- unit
276- case _ =>
277- throw("Match error")
278- }, zeroBigInt)
279- let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
280- let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
281- let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
282- let gwxAmountTotal = valueOrElse(getGwxAmountTotalOption(), 0)
283- let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
284- let gwxAmountTotalBI = toBigInt(gwxAmountTotal)
285- let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + (if ((gwxAmountTotalBI == zeroBigInt))
286- then zeroBigInt
287- else fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), (gwxAmountTotalBI * MULT8BI))))
288- $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
289- }
290-
291-
292-func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
293-
294-
295-func _refreshUserReward (userAddress,userNum) = {
296- let $t01029210380 = _refreshRewardPerGwxIntegral()
297- let rewardPerGwxIntegralActions = $t01029210380._1
298- let rewardPerGwxIntegral = $t01029210380._2
299- let rewardPerGwxIntegralUserLast = match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
300- case s: String =>
301- valueOrErrorMessage(parseBigInt(s), wrapErr("invalid user last integral"))
302- case _: Unit =>
303- rewardPerGwxIntegral
304- case _ =>
305- throw("Match error")
306- }
307- let userIdxOption = getString(boostingContractOrFail(), keyUser2NumMapping(userAddress))
308- let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userNum)), 0)
309- let userGwxAmount = valueOrElse(getUserGwxAmountTotalOption(userAddress), 0)
310- let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
311- $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
312- }
313-
314-
315-func commonClaimReward (userAddressStr) = {
316- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
317- let cfgArray = readConfigArrayOrFail()
318- let userNum = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddressStr)
319- let $t01167111735 = _refreshUserReward(userAddress, userNum)
320- let actions = $t01167111735._1
321- let reward = $t01167111735._2
322- $Tuple2(reward, ([IntegerEntry(keyUserUnclaimed(userNum), 0)] ++ actions))
323- }
324375
325376
326377 @Callable(i)
327-func refreshUserReward (userAddressBytes,userNum) = {
328- let suspensionCheck = throwIfSuspended()
329- if ((suspensionCheck == suspensionCheck))
330- then {
331- let checkCaller = if ((i.caller == boostingContractOrFail()))
332- then true
333- else throwErr("permission denied")
334- if ((checkCaller == checkCaller))
335- then {
336- let $t01206112139 = _refreshUserReward(Address(userAddressBytes), userNum)
337- let actions = $t01206112139._1
338- let reward = $t01206112139._2
339- $Tuple2(([IntegerEntry(keyUserUnclaimed(userNum), reward)] ++ actions), reward)
340- }
341- else throw("Strict value is not equal to itself.")
342- }
378+func updateReferralActivity (userAddress,gWxAmountStart) = {
379+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
380+ let activeReferralInv = if ((referrer == unit))
381+ then unit
382+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
383+ if ((activeReferralInv == activeReferralInv))
384+ then $Tuple2(nil, unit)
343385 else throw("Strict value is not equal to itself.")
344386 }
345387
346388
347389
348390 @Callable(i)
349-func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = {
350- let suspensionCheck = throwIfSuspended()
351- if ((suspensionCheck == suspensionCheck))
352- then if ((currentIter == size(userAddresses)))
353- then nil
354- else {
355- let checks = [if ((i.caller == this))
356- then true
357- else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
358- then true
359- else throwErr("insufficient payment assetId")]
360- if ((checks == checks))
361- then {
362- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
363- if ((tradeRewardInternal == tradeRewardInternal))
364- then {
365- let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
366- let userAddress = addressFromStringValue(userAddresses[currentIter])
367- $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
368- }
369- else throw("Strict value is not equal to itself.")
370- }
371- else throw("Strict value is not equal to itself.")
391+func finalizeHelper () = {
392+ let processingStage = valueOrElse(getInteger(keyProcessingStage()), processingStageTotal)
393+ let currentPeriod = getNumberByKey(keyNextProcessedPeriod())
394+ let currentUser = getNumberByKey(keyNextProcessedUser())
395+ let latestPeriod = getNumberByKey(keyLatestPeriod())
396+ let usersCount = valueOrElse(getInteger(boostingContractOrFail(), keyUsersCount()), 0)
397+ let totalWeightKey = keyTotalWeightForPeriod(currentPeriod)
398+ let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
399+ let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
400+ if ((currentPeriod > latestPeriod))
401+ then $Tuple2(nil, false)
402+ else if ((processingStage == processingStageTotal))
403+ then {
404+ let $t01451014626 = calcUserWeight(boostingContractOrFail(), heightForPeriod, currentPeriod, currentUser)
405+ let userWeight = $t01451014626._1
406+ let userActions = $t01451014626._2
407+ let totalWeightNew = (totalWeight + userWeight)
408+ let processingActions = if (((usersCount - 1) > currentUser))
409+ then [IntegerEntry(keyNextProcessedUser(), (currentUser + 1))]
410+ else [IntegerEntry(keyProcessingStage(), processingStageShares), IntegerEntry(keyNextProcessedUser(), 0)]
411+ $Tuple2((([IntegerEntry(totalWeightKey, totalWeightNew)] ++ processingActions) ++ userActions), true)
372412 }
413+ else if ((processingStage == processingStageShares))
414+ then {
415+ let userWeight = calcUserWeightForClaim(boostingContractOrFail(), heightForPeriod, currentPeriod, currentUser)
416+ let userAmountMatcherForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod)), userWeight, totalWeight)
417+ let userAmountEmissionForPeriod = fraction(getNumberByKey(keyAuxEmissionRewardForPeriod(currentPeriod)), userWeight, totalWeight)
418+ let userTotalAmount = (userAmountEmissionForPeriod + userAmountMatcherForPeriod)
419+ let userUnclaimedOption = getInteger(keyUserUnclaimed(currentUser))
420+ let userAddress = getStringValue(boostingContractOrFail(), keyNumToUserMapping(currentUser))
421+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
422+ let activeReferralInv = if ((referrer == unit))
423+ then unit
424+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userWeight >= referralMinGWxAmount)], nil)
425+ if ((activeReferralInv == activeReferralInv))
426+ then {
427+ let referralInv = if (if ((referrer == unit))
428+ then true
429+ else (referralMinGWxAmount > userWeight))
430+ then unit
431+ else {
432+ let referrerReward = fraction(userTotalAmount, referrerRewardPermille, SCALE)
433+ let referralReward = fraction(userTotalAmount, referralRewardPermille, SCALE)
434+ invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
435+ }
436+ if ((referralInv == referralInv))
437+ then {
438+ let unclaimedActions = [IntegerEntry(keyUserUnclaimed(currentUser), (valueOrElse(userUnclaimedOption, 0) + userTotalAmount))]
439+ let processingActions = if (((usersCount - 1) > currentUser))
440+ then [IntegerEntry(keyNextProcessedUser(), (currentUser + 1))]
441+ else [IntegerEntry(keyNextProcessedPeriod(), (currentPeriod + 1)), IntegerEntry(keyNextProcessedUser(), 0), DeleteEntry(keyProcessingStage())]
442+ $Tuple2((unclaimedActions ++ processingActions), true)
443+ }
444+ else throw("Strict value is not equal to itself.")
445+ }
446+ else throw("Strict value is not equal to itself.")
447+ }
448+ else throw("invalid processing stage")
449+ }
450+
451+
452+
453+@Callable(i)
454+func finalizeWrapper (counter) = {
455+ let result = {
456+ let @ = invoke(this, "finalizeHelper", nil, nil)
457+ if ($isInstanceOf(@, "Boolean"))
458+ then @
459+ else throw(($getType(@) + " couldn't be cast to Boolean"))
460+ }
461+ if ((result == result))
462+ then if (!(result))
463+ then if ((counter == maxDepth))
464+ then throw("Nothing to process")
465+ else $Tuple2(nil, unit)
466+ else if ((counter > 0))
467+ then $Tuple2(nil, invoke(this, "finalizeWrapper", [(counter - 1)], nil))
468+ else $Tuple2(nil, unit)
373469 else throw("Strict value is not equal to itself.")
374470 }
375471
376472
377473
378474 @Callable(i)
379-func updateReferralActivity (userAddress,gWxAmountStart) = {
380- let suspensionCheck = throwIfSuspended()
381- if ((suspensionCheck == suspensionCheck))
382- then {
383- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
384- let activeReferralInv = if ((referrer == unit))
385- then unit
386- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
387- if ((activeReferralInv == activeReferralInv))
388- then $Tuple2(nil, unit)
389- else throw("Strict value is not equal to itself.")
390- }
391- else throw("Strict value is not equal to itself.")
392- }
475+func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
393476
394477
395478
396479 @Callable(i)
397-func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
398-
399-
400-
401-@Callable(i)
402-func claimReward () = {
403- let suspensionCheck = throwIfSuspended()
404- if ((suspensionCheck == suspensionCheck))
480+func deposit () = {
481+ let checkCaller = if ((i.caller == votingEmissionContract))
482+ then true
483+ else mustManager(i)
484+ if ((checkCaller == checkCaller))
405485 then {
406- let cfgArray = readConfigArrayOrFail()
407- let userAddress = i.caller
408- let userAddressStr = toString(userAddress)
409- let $t01400914066 = commonClaimReward(userAddressStr)
410- let amount = $t01400914066._1
411- let actions = $t01400914066._2
412- let checkAmount = if ((amount > 0))
413- then true
414- else throw("nothing to claim")
415- if ((checkAmount == checkAmount))
486+ let period = nextPeriod()
487+ let deltaH = (height - getNumberOrFail(keyGwxRewardEmissionStartHeight()))
488+ let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), (("mandatory emission_contract." + keyRatePerBlockCurrent()) + " is not defined"))
489+ let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
490+ if ((gwxHoldersRewardCurrent == gwxHoldersRewardCurrent))
416491 then {
417- let userGwxAmount = {
418- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
419- if ($isInstanceOf(@, "Int"))
420- then @
421- else throw(($getType(@) + " couldn't be cast to Int"))
422- }
423- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
424- let activeReferralInv = if ((referrer == unit))
425- then unit
426- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
427- if ((activeReferralInv == activeReferralInv))
492+ let auxAmount = fraction((deltaH * gwxHoldersRewardCurrent), emissionRate, MULT8)
493+ let em = if ((auxAmount > 0))
494+ then invoke(emissionContract, "emit", [auxAmount], nil)
495+ else unit
496+ if ((em == em))
428497 then {
429- let referralInv = if (if ((referrer == unit))
430- then true
431- else (referralMinGWxAmount > userGwxAmount))
432- then unit
433- else {
434- let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
435- let referralReward = fraction(amount, referralRewardPermille, SCALE)
436- invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
437- }
438- if ((referralInv == referralInv))
498+ let matcherPart = 0
499+ let payoutInfo = PeriodPayoutInfo(period, matcherPart, auxAmount)
500+ let gwxHoldersRewardUpdated = {
501+ let @ = invoke(emissionContract, "gwxHoldersRewardUpdate", nil, nil)
502+ if ($isInstanceOf(@, "Boolean"))
503+ then @
504+ else throw(($getType(@) + " couldn't be cast to Boolean"))
505+ }
506+ if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
439507 then {
440- let emit = invoke(emissionContract, "emit", [amount], nil)
441- if ((emit == emit))
442- then {
443- let claimedReferral = {
444- let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
445- if ($isInstanceOf(@, "Int"))
446- then @
447- else throw(($getType(@) + " couldn't be cast to Int"))
448- }
449- if ((claimedReferral == claimedReferral))
450- then {
451- let totalAmount = (amount + claimedReferral)
452- $Tuple2(([ScriptTransfer(i.caller, amount, wxAssetId), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
453- }
454- else throw("Strict value is not equal to itself.")
455- }
456- else throw("Strict value is not equal to itself.")
508+ let totalReward = (matcherPart + auxAmount)
509+ let actions = if (if ((totalReward == 0))
510+ then !(gwxHoldersRewardUpdated)
511+ else false)
512+ then nil
513+ else [IntegerEntry(keyLatestPeriod(), period), IntegerEntry(keyHeightForPeriod(period), height), IntegerEntry(keyAuxEmissionRewardForPeriod(period), auxAmount), IntegerEntry(keyGwxRewardEmissionStartHeight(), height), IntegerEntry(keyTotalAmountForPeriod(period), matcherPart), IntegerEntry(keyNextPeriod(), (period + 1)), StringEntry(keyLastPayoutInfo(), payoutInfo), StringEntry(keyPayoutHistoryInfo(period), payoutInfo)]
514+ $Tuple2(actions, unit)
457515 }
458516 else throw("Strict value is not equal to itself.")
459517 }
460518 else throw("Strict value is not equal to itself.")
461519 }
462520 else throw("Strict value is not equal to itself.")
463521 }
464522 else throw("Strict value is not equal to itself.")
465523 }
466524
467525
468526
469527 @Callable(i)
528+func claimReward () = {
529+ let cfgArray = readConfigArrayOrFail()
530+ let address = toString(i.caller)
531+ let $t01981519865 = commonClaimReward(address)
532+ let amount = $t01981519865._1
533+ let actions = $t01981519865._2
534+ let checkAmount = if ((amount > 0))
535+ then true
536+ else throw("Nothing to claim")
537+ if ((checkAmount == checkAmount))
538+ then {
539+ let amountFromEmission = 0
540+ let claimedReferral = {
541+ let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
542+ if ($isInstanceOf(@, "Int"))
543+ then @
544+ else throw(($getType(@) + " couldn't be cast to Int"))
545+ }
546+ let totalAmount = (amount + claimedReferral)
547+ $Tuple2(([ScriptTransfer(i.caller, totalAmount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", address, amount, i)] ++ actions), [totalAmount, amountFromEmission])
548+ }
549+ else throw("Strict value is not equal to itself.")
550+ }
551+
552+
553+
554+@Callable(i)
470555 func claimRewardREADONLY (address) = {
471- let $t01542315473 = commonClaimReward(address)
472- let amount = $t01542315473._1
473- let actions = $t01542315473._2
556+ let $t02043820488 = commonClaimReward(address)
557+ let amount = $t02043820488._1
558+ let actions = $t02043820488._2
474559 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
475560 let totalAmount = (amount + referralUnclaimed)
476561 $Tuple2(nil, totalAmount)
477562 }
478563
479564
480565
481566 @Callable(i)
482-func onEmissionForGwxStart () = {
483- let suspensionCheck = throwIfSuspended()
484- if ((suspensionCheck == suspensionCheck))
485- then if ((i.caller != factoryContract))
486- then throw("permissions denied")
487- else [IntegerEntry(keyGwxRewardEmissionStartHeight(), height)]
488- else throw("Strict value is not equal to itself.")
567+func latestFinalizedPeriodREADONLY (address) = $Tuple2(nil, valueOrElse(getInteger(this, keyLatestPeriod()), -1))
568+
569+
570+
571+@Callable(i)
572+func latestFinalizedPeriodInfoREADONLY (address) = $Tuple2(nil, getStringByKey(keyLastPayoutInfo()))
573+
574+
575+
576+@Callable(i)
577+func calcGwxParamsREADONLY (gwxAmountStart,lockStartHeight,lockDurationBlocks) = {
578+ let lockEndHeight = (lockStartHeight + lockDurationBlocks)
579+ let scale8ParamK = -(fraction(gwxAmountStart, SCALE, lockDurationBlocks))
580+ let scale8ParamB = (fraction(gwxAmountStart, SCALE, lockDurationBlocks) * lockEndHeight)
581+ $Tuple2(nil, [scale8ParamK, scale8ParamB, nextPeriod()])
582+ }
583+
584+
585+
586+@Callable(i)
587+func calcGwxAmountStartREADONLY (wxLockAmount,lockDuration,maxLockDuration) = {
588+ let coeffX8 = fraction(lockDuration, MULT8, maxLockDuration)
589+ let gWxAmountStart = fraction(wxLockAmount, coeffX8, MULT8)
590+ $Tuple2(nil, [gWxAmountStart])
591+ }
592+
593+
594+
595+@Callable(i)
596+func onEmissionForGwxStart () = if ((i.caller != factoryContract))
597+ then throw("permissions denied")
598+ else [IntegerEntry(keyGwxRewardEmissionStartHeight(), height)]
599+
600+
601+
602+@Callable(i)
603+func latestPeriodEmissionRewardsREADONLY (address) = {
604+ let period = nextPeriod()
605+ $Tuple2(nil, [getNumberByKey(keyAuxEmissionRewardForPeriod(period))])
606+ }
607+
608+
609+
610+@Callable(i)
611+func calcD (x1BigIntStr,x2BigIntStr,ampBigIntStr,aPrecisionBigIntStr,targetPrecisionBigIntStr) = {
612+ let nCoins = toBigInt(2)
613+ let aPrecision = parseBigIntValue(aPrecisionBigIntStr)
614+ let targetPrecision = parseBigIntValue(targetPrecisionBigIntStr)
615+ let x1 = parseBigIntValue(x1BigIntStr)
616+ let x2 = parseBigIntValue(x2BigIntStr)
617+ let amp = (parseBigIntValue(ampBigIntStr) * aPrecision)
618+ let s = (x1 + x2)
619+ if ((s == zeroBigInt))
620+ then $Tuple2(nil, toString(zeroBigInt))
621+ else {
622+ let ann = (amp * nCoins)
623+ let arr = [0, 1, 2, 3, 4, 5, 6]
624+ func calc (acc,cur) = {
625+ let $t02312123148 = acc
626+ let d = $t02312123148._1
627+ let dPrev = $t02312123148._2
628+ let found = $t02312123148._3
629+ if ((found != unit))
630+ then acc
631+ else {
632+ let dp = (((d * d) * d) / (((x1 * x2) * nCoins) * nCoins))
633+ let dNext = (((((ann * s) / aPrecision) + (dp * nCoins)) * d) / ((((ann - aPrecision) * d) / aPrecision) + ((nCoins + toBigInt(1)) * dp)))
634+ let dDiff = absBigInt((dNext - value(d)))
635+ if ((targetPrecision >= dDiff))
636+ then $Tuple3(dNext, d, cur)
637+ else $Tuple3(dNext, d, unit)
638+ }
639+ }
640+
641+ let $t02374623809 = {
642+ let $l = arr
643+ let $s = size($l)
644+ let $acc0 = $Tuple3(s, unit, unit)
645+ func $f0_1 ($a,$i) = if (($i >= $s))
646+ then $a
647+ else calc($a, $l[$i])
648+
649+ func $f0_2 ($a,$i) = if (($i >= $s))
650+ then $a
651+ else throw("List size exceeds 7")
652+
653+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
654+ }
655+ let dNext = $t02374623809._1
656+ let dPrev = $t02374623809._2
657+ let found = $t02374623809._3
658+ if ((found != unit))
659+ then $Tuple2(nil, toString(dNext))
660+ else {
661+ let dDiff = absBigInt((dNext - value(dPrev)))
662+ throw(("D calculation error, dDiff = " + toString(dDiff)))
663+ }
664+ }
489665 }
490666
491667
492668
493669 @Callable(i)
494670 func tradeReward (userAddresses,rewards) = {
495- let suspensionCheck = throwIfSuspended()
496- if ((suspensionCheck == suspensionCheck))
671+ let argsComparison = (size(userAddresses) == size(rewards))
672+ let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
673+ let payment = i.payments[0]
674+ let paymentAssetId = payment.assetId
675+ let paymentAmount = payment.amount
676+ let checks = [if ((maxRecipients >= size(userAddresses)))
677+ then true
678+ else throwErr("Too many recipients"), if (argsComparison)
679+ then true
680+ else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
681+ then true
682+ else throwErr("Wrong asset payment")]
683+ if ((checks == checks))
497684 then {
498- let argsComparison = (size(userAddresses) == size(rewards))
499- let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
500- let payment = i.payments[0]
501- let paymentAssetId = payment.assetId
502- let paymentAmount = payment.amount
503- let checks = [if ((maxRecipients >= size(userAddresses)))
504- then true
505- else throwErr("Too many recipients"), if (argsComparison)
506- then true
507- else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
508- then true
509- else throwErr("Wrong asset payment")]
510- if ((checks == checks))
511- then {
512- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
513- if ((tradeRewardInternal == tradeRewardInternal))
514- then $Tuple2(nil, tradeRewardInternal)
515- else throw("Strict value is not equal to itself.")
516- }
685+ let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
686+ if ((tradeRewardInternal == tradeRewardInternal))
687+ then $Tuple2(nil, tradeRewardInternal)
517688 else throw("Strict value is not equal to itself.")
518689 }
519690 else throw("Strict value is not equal to itself.")
520691 }
521692
522693
523694
524695 @Callable(i)
525696 func claimTradingReward () = {
526- let suspensionCheck = throwIfSuspended()
527- if ((suspensionCheck == suspensionCheck))
528- then {
529- let userAddress = i.caller
530- let userAddressString = toString(userAddress)
531- let reward = getTradingReward(userAddressString)
532- if ((reward > 0))
533- then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
534- else throwErr("nothing to claim")
535- }
536- else throw("Strict value is not equal to itself.")
697+ let userAddress = i.caller
698+ let userAddressString = toString(userAddress)
699+ let reward = getTradingReward(userAddressString)
700+ if ((reward > 0))
701+ then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
702+ else throwErr("nothing to claim")
537703 }
538704
539705
540706
541707 @Callable(i)
542708 func claimTradingRewardREADONLY (userAddress) = $Tuple2(nil, getTradingReward(userAddress))
543-
544-
545-
546-@Callable(i)
547-func suspend (v) = {
548- let checkCaller = mustManager(i)
549- if ((checkCaller == checkCaller))
550- then $Tuple2([BooleanEntry(keySuspension, v)], v)
551- else throw("Strict value is not equal to itself.")
552- }
553709
554710
555711 @Verifier(tx)
556712 func verify () = {
557713 let targetPublicKey = match managerPublicKeyOrUnit() {
558714 case pk: ByteVector =>
559715 pk
560716 case _: Unit =>
561717 tx.senderPublicKey
562718 case _ =>
563719 throw("Match error")
564720 }
565721 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
566722 }
567723

github/deemru/w8io/026f985 
88.07 ms