tx · GcXcsR7siWTtCajvNbGXAVcsTjmJabABAvguHapdjmGN

3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE:  -0.02000000 Waves

2023.08.14 17:40 [2710363] smart account 3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE > SELF 0.00000000 Waves

{ "type": 13, "id": "GcXcsR7siWTtCajvNbGXAVcsTjmJabABAvguHapdjmGN", "fee": 2000000, "feeAssetId": null, "timestamp": 1692024028141, "version": 2, "chainId": 84, "sender": "3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE", "senderPublicKey": "G349Uq3FTox7dRNLeAfAQeoACvwZ9iEnVSaHcEYn6j8J", "proofs": [ "5pzNi9EMWLVcgW4V66MV6Sp9FBkiys77u1QTwQAR2pHbC4tASinHWdSEz3A1bkppnDEtjvPvuqfyNprLdBEYZzx5" ], "script": "base64:BgKMHQgCEgYKBAEYEQESBAoCCAESABIDCgEBEgASABIAEgMKAQgSAwoBCBIDCgEIEgUKAwEBARIFCgMBAQESABIDCgEIEgcKBQgICAgIEgQKAhgREgASAwoBCCIDU0VQIgVTQ0FMRSIFTVVMVDgiCnplcm9CaWdJbnQiFHByb2Nlc3NpbmdTdGFnZVRvdGFsIhVwcm9jZXNzaW5nU3RhZ2VTaGFyZXMiC3dhdmVzU3RyaW5nIg5nZXROdW1iZXJCeUtleSIDa2V5Ig9nZXROdW1iZXJPckZhaWwiDmdldFN0cmluZ0J5S2V5Ig9nZXRTdHJpbmdPckZhaWwiDHBhcnNlQXNzZXRJZCIFaW5wdXQiB3dyYXBFcnIiA21zZyIIdGhyb3dFcnIiA2FicyIDdmFsIglhYnNCaWdJbnQiC2tleU1heERlcHRoIg9tYXhEZXB0aERlZmF1bHQiCG1heERlcHRoIhFrZXlGYWN0b3J5QWRkcmVzcyIRZmFjdG9yeUFkZHJlc3NTdHIiD2ZhY3RvcnlDb250cmFjdCISa2V5RW1pc3Npb25BZGRyZXNzIhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0IhNrZXlOdW1Ub1VzZXJNYXBwaW5nIgNudW0iFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUiGnJlZmVycmFsUHJvZ3JhbU5hbWVEZWZhdWx0IhNyZWZlcnJhbFByb2dyYW1OYW1lIhdrZXlSZWZlcnJhbE1pbkdXeEFtb3VudCIbcmVmZXJyYWxNaW5HV3hBbW91bnREZWZhdWx0IhRyZWZlcnJhbE1pbkdXeEFtb3VudCIZa2V5UmVmZXJyZXJSZXdhcmRQZXJtaWxsZSIdcmVmZXJyZXJSZXdhcmRQZXJtaWxsZURlZmF1bHQiFnJlZmVycmVyUmV3YXJkUGVybWlsbGUiGWtleVJlZmVycmFsUmV3YXJkUGVybWlsbGUiHXJlZmVycmFsUmV3YXJkUGVybWlsbGVEZWZhdWx0IhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlIgtrZXlSZWZlcnJlciIPcmVmZXJyYWxBZGRyZXNzIhRrZXlVbmNsYWltZWRSZWZlcnJhbCILcHJvZ3JhbU5hbWUiDmNsYWltZXJBZGRyZXNzIhJlbWlzc2lvbkFkZHJlc3NTdHIiEGVtaXNzaW9uQ29udHJhY3QiDUlkeENmZ0Fzc2V0SWQiFklkeENmZ1BhY2VtYWtlckFkZHJlc3MiFklkeENmZ0Jvb3N0aW5nQ29udHJhY3QiDklkeENmZ01heERlcHRoIglrZXlDb25maWciEmdldEVtaXNzaW9uQWRkcmVzcyIPZW1pc3Npb25BZGRyZXNzIgx3eEFzc2V0SWRTdHIiCXd4QXNzZXRJZCIVcmVhZENvbmZpZ0FycmF5T3JGYWlsIgxmb3JtYXRDb25maWciGm1hdGNoZXJQYWNlbWFrZXJBZGRyZXNzU3RyIhpib29zdGluZ0NvbnRyYWN0QWRkcmVzc1N0ciIWYm9vc3RpbmdDb250cmFjdE9yRmFpbCIIY2ZnQXJyYXkiH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQiDWtleVVzZXJzQ291bnQiFmtleVJhdGVQZXJCbG9ja0N1cnJlbnQiGmtleUd3eEhvbGRlcnNSZXdhcmRDdXJyZW50IhdrZXlHd3hIb2xkZXJzUmV3YXJkTmV4dCIUa2V5UG9vbFdlaWdodFZpcnR1YWwiFGtleU5leHRQcm9jZXNzZWRVc2VyIg9rZXlMYXRlc3RQZXJpb2QiDWtleU5leHRQZXJpb2QiEmtleVByb2Nlc3NpbmdTdGFnZSIWa2V5TmV4dFByb2Nlc3NlZFBlcmlvZCIQa2V5VXNlclVuY2xhaW1lZCIJdXNlckluZGV4IhtrZXlOZXh0VW5sYWltZWRQZXJpb2RPZlVzZXIiHGtleUxhc3RQcm9jZXNzZWRQZXJpb2RPZlVzZXIiEmtleUhlaWdodEZvclBlcmlvZCIGcGVyaW9kIh1rZXlBdXhFbWlzc2lvblJld2FyZEZvclBlcmlvZCIXa2V5VG90YWxBbW91bnRGb3JQZXJpb2QiEWtleUxhc3RQYXlvdXRJbmZvIhBQZXJpb2RQYXlvdXRJbmZvIg1tYXRjaGVyUmV3YXJkIg5lbWlzc2lvblJld2FyZCIUa2V5UGF5b3V0SGlzdG9yeUluZm8iF2tleVRvdGFsV2VpZ2h0Rm9yUGVyaW9kIhZrZXlVc2VyS1ZhbHVlRm9yUGVyaW9kIhZrZXlVc2VyQlZhbHVlRm9yUGVyaW9kIhZrZXlVc2VyV2VpZ2h0Rm9yUGVyaW9kIhtrZXlSZWZlcnJhbHNDb250cmFjdEFkZHJlc3MiHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbCIXa2V5VHJhZGluZ1Jld2FyZEhpc3RvcnkiBHVzZXIiAWkiEGtleVRyYWRpbmdSZXdhcmQiC3VzZXJBZGRyZXNzIhBrZXlNYXhSZWNpcGllbnRzIgxIaXN0b3J5RW50cnkiBHR5cGUiBmFtb3VudCIKaGlzdG9yeUtFWSILaGlzdG9yeURBVEEiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMiByRtYXRjaDAiAXMiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiC211c3RNYW5hZ2VyIgJwZCICcGsiDmNhbGNVc2VyV2VpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIPaGVpZ2h0Rm9yUGVyaW9kIgVrTGFzdCIEa0tleSIEa1JhdyILa1VzZXJXZWlnaHQiAWsiAWIiAXciAXAiAnB2IhZjYWxjVXNlcldlaWdodEZvckNsYWltIhB1c2VyV2VpZ2h0T3JVbml0IhVnZXRVc2VySW5kZXhCeUFkZHJlc3MiCm5leHRQZXJpb2QiEWNvbW1vbkNsYWltUmV3YXJkIgd1c2VySWR4IhN1c2VyVW5jbGFpbWVkT3B0aW9uIgF1IhBnZXRUcmFkaW5nUmV3YXJkIhVwYXltZW50QW1vdW50TGVmdE92ZXIiDXVzZXJBZGRyZXNzZXMiB3Jld2FyZHMiC2N1cnJlbnRJdGVyIgZjaGVja3MiE3RyYWRlUmV3YXJkSW50ZXJuYWwiF3RyYWRpbmdSZXdhcmRIaXN0b3J5S2V5Ig5nV3hBbW91bnRTdGFydCIIcmVmZXJyZXIiEWFjdGl2ZVJlZmVycmFsSW52Ig9wcm9jZXNzaW5nU3RhZ2UiDWN1cnJlbnRQZXJpb2QiC2N1cnJlbnRVc2VyIgxsYXRlc3RQZXJpb2QiCnVzZXJzQ291bnQiDnRvdGFsV2VpZ2h0S2V5Igt0b3RhbFdlaWdodCINJHQwMTQ1MTAxNDYyNiIKdXNlcldlaWdodCILdXNlckFjdGlvbnMiDnRvdGFsV2VpZ2h0TmV3IhFwcm9jZXNzaW5nQWN0aW9ucyIadXNlckFtb3VudE1hdGNoZXJGb3JQZXJpb2QiG3VzZXJBbW91bnRFbWlzc2lvbkZvclBlcmlvZCIPdXNlclRvdGFsQW1vdW50IgtyZWZlcnJhbEludiIOcmVmZXJyZXJSZXdhcmQiDnJlZmVycmFsUmV3YXJkIhB1bmNsYWltZWRBY3Rpb25zIgdjb3VudGVyIgZyZXN1bHQiAUAiC2NoZWNrQ2FsbGVyIgZkZWx0YUgiDGVtaXNzaW9uUmF0ZSIXZ3d4SG9sZGVyc1Jld2FyZEN1cnJlbnQiCWF1eEFtb3VudCICZW0iC21hdGNoZXJQYXJ0IgpwYXlvdXRJbmZvIhdnd3hIb2xkZXJzUmV3YXJkVXBkYXRlZCILdG90YWxSZXdhcmQiB2FjdGlvbnMiB2FkZHJlc3MiDSR0MDE5ODE1MTk4NjUiC2NoZWNrQW1vdW50IhJhbW91bnRGcm9tRW1pc3Npb24iD2NsYWltZWRSZWZlcnJhbCILdG90YWxBbW91bnQiDSR0MDIwNDM4MjA0ODgiEXJlZmVycmFsVW5jbGFpbWVkIg5nd3hBbW91bnRTdGFydCIPbG9ja1N0YXJ0SGVpZ2h0IhJsb2NrRHVyYXRpb25CbG9ja3MiDWxvY2tFbmRIZWlnaHQiDHNjYWxlOFBhcmFtSyIMc2NhbGU4UGFyYW1CIgx3eExvY2tBbW91bnQiDGxvY2tEdXJhdGlvbiIPbWF4TG9ja0R1cmF0aW9uIgdjb2VmZlg4Igt4MUJpZ0ludFN0ciILeDJCaWdJbnRTdHIiDGFtcEJpZ0ludFN0ciITYVByZWNpc2lvbkJpZ0ludFN0ciIYdGFyZ2V0UHJlY2lzaW9uQmlnSW50U3RyIgZuQ29pbnMiCmFQcmVjaXNpb24iD3RhcmdldFByZWNpc2lvbiICeDEiAngyIgNhbXAiA2FubiIDYXJyIgRjYWxjIgNhY2MiA2N1ciINJHQwMjMxMjEyMzE0OCIBZCIFZFByZXYiBWZvdW5kIgJkcCIFZE5leHQiBWREaWZmIg0kdDAyMzc0NjIzODA5IgIkbCICJHMiBSRhY2MwIgUkZjBfMSICJGEiAiRpIgUkZjBfMiIOYXJnc0NvbXBhcmlzb24iDW1heFJlY2lwaWVudHMiB3BheW1lbnQiDnBheW1lbnRBc3NldElkIg1wYXltZW50QW1vdW50IhF1c2VyQWRkcmVzc1N0cmluZyIGcmV3YXJkIgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXlfAAFhAgJfXwABYgDoBwABYwCAwtcvAAFkCQC2AgEAAAABZQAAAAFmAAEAAWcCBVdBVkVTAQFoAQFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWkAAAEBagEBaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAWkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAWkCDyBpcyBub3QgZGVmaW5lZAEBawEBaQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFpAgABAWwBAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQFpCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQFpAg8gaXMgbm90IGRlZmluZWQBAW0BAW4DCQAAAgUBbgUBZwUEdW5pdAkA2QQBBQFuAQFvAQFwCQC5CQIJAMwIAgIQZ3d4X3Jld2FyZC5yaWRlOgkAzAgCBQFwBQNuaWwCASABAXEBAXAJAAIBCQEBbwEFAXABAXIBAXMDCQBmAgAABQFzCQEBLQEFAXMFAXMBAXQBAXMDCQC/AgIFAWQFAXMJAL4CAQUBcwUBcwABdQIMJXNfX21heERlcHRoAAF2AB4AAXcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBdQUBdgEBeAACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAAXkJAQFsAQkBAXgAAAF6CQERQGV4dHJOYXRpdmUoMTA2MikBBQF5AQFBAAIdJXMlc19fY29uZmlnX19lbWlzc2lvbkFkZHJlc3MBAUIACQC5CQIJAMwIAgICJXMJAMwIAgIWdm90aW5nRW1pc3Npb25Db250cmFjdAUDbmlsBQFhAAFDCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQF6CQEBQgABAUQBAUUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIHbWFwcGluZwkAzAgCAghudW0ydXNlcgkAzAgCCQCkAwEFAUUFA25pbAUBYQABRgkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgILcHJvZ3JhbU5hbWUFA25pbAUBYQABRwIGd3hsb2NrAAFICQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAUYFAUcAAUkJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICDG1pbkdXeEFtb3VudAUDbmlsBQFhAAFKCQBoAgD0AwUBYwABSwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFJBQFKAAFMCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJlclJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAU0AMgABTgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFMBQFNAAFPCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAVAAMgABUQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFPBQFQAQFSAQFTCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICCHJlZmVycmVyCQDMCAIFAUgJAMwIAgUBUwUDbmlsBQFhAQFUAgFVAVYJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIRdW5jbGFpbWVkUmVmZXJyYWwJAMwIAgUBVQkAzAgCBQFWBQNuaWwFAWEAAVcJAQFsAQkBAUEAAAFYCQERQGV4dHJOYXRpdmUoMTA2MikBBQFXAAFZAAEAAVoAAgACYWEAAwACYWIABAECYWMAAgolc19fY29uZmlnAQJhZAAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQEBQQAJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4JAQFBAAIPIGlzIG5vdCBkZWZpbmVkAAJhZQkBAmFkAAACYWYJAJEDAgkAtQkCCQEFdmFsdWUBCQCdCAIFAmFlCQECYWMABQFhAAEAAmFnCQDZBAEFAmFmAQJhaAAJALUJAgkBAWwBCQECYWMABQFhAQJhaQQCYWYCYWoCYWsBdwkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAIFAmFmCQDMCAIFAmFqCQDMCAIFAmFrCQDMCAIJAKQDAQUBdwUDbmlsBQFhAQJhbAAEAmFtCQECYWgACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJhbQUCYWECKGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MgaXMgbm90IGRlZmluZWQBAmFuAAIoJXMlc19fZ3d4UmV3YXJkRW1pc3Npb25QYXJ0X19zdGFydEhlaWdodAECYW8AAg8lc19fbmV4dFVzZXJOdW0BAmFwAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhcQACHyVzJXNfX2d3eEhvbGRlcnNSZXdhcmRfX2N1cnJlbnQBAmFyAAIcJXMlc19fZ3d4SG9sZGVyc1Jld2FyZF9fbmV4dAECYXMAAiAlcyVzX19wb29sV2VpZ2h0X19HV1h2aXJ0dWFsUE9PTAECYXQAAhUlc19fbmV4dFByb2Nlc3NlZFVzZXIBAmF1AAIQJXNfX2xhdGVzdFBlcmlvZAECYXYAAg4lc19fbmV4dFBlcmlvZAECYXcAAhMlc19fcHJvY2Vzc2luZ1N0YWdlAQJheAACFyVzX19uZXh0UHJvY2Vzc2VkUGVyaW9kAQJheQECYXoJALkJAgkAzAgCAgQlcyVkCQDMCAICDXVzZXJVbmNsYWltZWQJAMwIAgkApAMBBQJhegUDbmlsBQFhAQJhQQECYXoJALkJAgkAzAgCAhclcyVkX19uZXh0Q2xhaW1lZFBlcmlvZAkAzAgCCQCkAwEFAmF6BQNuaWwFAWEBAmFCAQJhegkAuQkCCQDMCAICGSVzJWRfX2xhc3RQcm9jZXNzZWRQZXJpb2QJAMwIAgkApAMBBQJhegUDbmlsBQFhAQJhQwECYUQJALkJAgkAzAgCAholcyVkX19zdGFydEhlaWdodEZvclBlcmlvZAkAzAgCCQCkAwEFAmFEBQNuaWwFAWEBAmFFAQJhRAkAuQkCCQDMCAICFyVzJWRfX2F1eEVtaXNzaW9uUmV3YXJkCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYUYBAmFECQC5CQIJAMwIAgIaJXMlZF9fdG90YWxBbW91bnRGb3JQZXJpb2QJAMwIAgkApAMBBQJhRAUDbmlsBQFhAQJhRwACEiVzX19sYXN0UGF5b3V0SW5mbwECYUgDAmFEAmFJAmFKCQC5CQIJAMwIAgIGJWQlZCVkCQDMCAIJAKQDAQUCYUQJAMwIAgkApAMBBQJhSQkAzAgCCQCkAwEFAmFKBQNuaWwFAWEBAmFLAQJhRAkAuQkCCQDMCAICGCVzJXMlZF9fcGF5b3V0c19faGlzdG9yeQkAzAgCCQCkAwEFAmFEBQNuaWwFAWEBAmFMAQJhRAkAuQkCCQDMCAICGiVzJWRfX3RvdGFsV2VpZ2h0Rm9yUGVyaW9kCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU0CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgFrCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU4CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgFiCQDMCAIJAKQDAQUCYUQFA25pbAUBYQECYU8CAmFEAmF6CQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgkApAMBBQJhegkAzAgCAgZ3ZWlnaHQJAMwIAgkApAMBBQJhRAUDbmlsBQFhAQJhUAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBmNvbmZpZwkAzAgCAhhyZWZlcnJhbHNDb250cmFjdEFkZHJlc3MFA25pbAUBYQACYVEJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQFsAQkBAmFQAAECYVICAmFTAmFUCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgINdHJhZGluZ1Jld2FyZAkAzAgCAgdoaXN0b3J5CQDMCAIFAmFTCQDMCAIJANgEAQgFAmFUDXRyYW5zYWN0aW9uSWQFA25pbAUBYQECYVUBAmFWCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg10cmFkaW5nUmV3YXJkCQDMCAIFAmFWBQNuaWwFAWEBAmFXAAkAuQkCCQDMCAICAiVzCQDMCAICDW1heFJlY2lwaWVudHMFA25pbAUBYQECYVgEAmFZAmFTAmFaAmFUBAJiYQkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFAmFZCQDMCAIFAmFTCQDMCAIJANgEAQgFAmFUDXRyYW5zYWN0aW9uSWQFA25pbAUBYQQCYmIJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUCYVoFA25pbAUBYQkBC1N0cmluZ0VudHJ5AgUCYmEFAmJiAQJiYwACFCVzX19tYW5hZ2VyUHVibGljS2V5AQJiZAACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQJiZQAEAmJmCQCiCAEJAQJiZAADCQABAgUCYmYCBlN0cmluZwQCYmcFAmJmCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiZwUEdGhpcwECYmgABAJiaQkBAmJlAAQCYmYJAJ0IAgUCYmkJAQJiYwADCQABAgUCYmYCBlN0cmluZwQCYmcFAmJmCQDZBAEFAmJnAwkAAQIFAmJmAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmJqAQJhVAQCYmsJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQCYmYJAQJiaAADCQABAgUCYmYCCkJ5dGVWZWN0b3IEAmJsBQJiZgMJAAACCAUCYVQPY2FsbGVyUHVibGljS2V5BQJibAYFAmJrAwkAAQIFAmJmAgRVbml0AwkAAAIIBQJhVAZjYWxsZXIFBHRoaXMGBQJiawkAAgECC01hdGNoIGVycm9yAQJibQQCYm4CYm8CYUQCYXoEAmJwCQECYUIBBQJhegQCYnEJAQJhTQIFAmFEBQJhegQCYnIJAJoIAgUCYm4FAmJxBAJicwkBAmFPAgUCYUQFAmF6AwkBCWlzRGVmaW5lZAEFAmJyBAJidAkBBXZhbHVlAQUCYnIEAmJ1CQEFdmFsdWUBCQCaCAIFAmJuCQECYU4CBQJhRAUCYXoEAmJ2CQBkAgkAaAIFAmJ0BQJibwUCYnUDCQBmAgUCYnYAAAkAlAoCCQBpAgUCYnYFAWIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJwBQJhRAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYnMFAmJ2BQNuaWwJAJQKAgAABQNuaWwEAmJ3CQCaCAIFBHRoaXMFAmJwAwMJAQlpc0RlZmluZWQBBQJidwkAZwIFAmFECQEFdmFsdWUBBQJidwcEAmJ4CQEFdmFsdWUBBQJidwQCYnQJAQV2YWx1ZQEJAJoIAgUCYm4JAQJhTQIFAmJ4BQJhegQCYnUJAQV2YWx1ZQEJAJoIAgUCYm4JAQJhTgIFAmJ4BQJhegQCYnYJAGQCCQBoAgUCYnQFAmJvBQJidQMJAGYCBQJidgAACQCUCgIJAGkCBQJidgUBYgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYnMFAmJ2BQNuaWwJAJQKAgAABQNuaWwJAJQKAgAABQNuaWwBAmJ5BAJibgJibwJhRAJhegQCYnMJAQJhTwIFAmFEBQJhegQCYnoJAJ8IAQUCYnMEAmJmBQJiegMJAAECBQJiZgIEVW5pdAAAAwkAAQIFAmJmAgNJbnQEAmJ2BQJiZgkAaQIFAmJ2BQFiCQACAQILTWF0Y2ggZXJyb3IBAmJBAgJhawJhVgQBaQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgdtYXBwaW5nCQDMCAICCHVzZXIybnVtCQDMCAIFAmFWBQNuaWwFAWEJAQ1wYXJzZUludFZhbHVlAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQdBZGRyZXNzAQkA2QQBBQJhawUBaQkArAICCQCsAgIJAKwCAgINVXNlciBhZGRyZXNzIAUCYVYCLSBpcyBub3QgZm91bmQgaW4gYm9vc3RpbmcgY29udHJhY3QgZGF0YSwga2V5PQUBaQECYkIACQEBaAEJAQJhdgABAmJDAQJhVgQCYW0JAQJhaAAEAmJECQECYkECCQCRAwIFAmFtBQJhYQUCYVYEAmJFCQCfCAEJAQJheQEFAmJEBAJiZgUCYkUDCQABAgUCYmYCBFVuaXQJAJQKAgAABQNuaWwDCQABAgUCYmYCA0ludAQCYkYFAmJmCQCUCgIFAmJGCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXkBBQJiRAAABQNuaWwJAAIBAgtNYXRjaCBlcnJvcgECYkcBAmFWCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhVQEFAmFWAAASAmFUARN0cmFkZVJld2FyZEludGVybmFsBAJiSAJiSQJiSgJiSwMJAAACBQJiSwkAkAMBBQJiSQUDbmlsBAJiTAkAzAgCAwkAAAIIBQJhVAZjYWxsZXIFBHRoaXMGCQEBcQECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIDCQBnAgUCYkgJAJEDAgUCYkoFAmJLBgkBAXEBAhxpbnN1ZmZpY2llbnQgcGF5bWVudCBhc3NldElkBQNuaWwDCQAAAgUCYkwFAmJMBAJiTQkA/AcEBQR0aGlzAhN0cmFkZVJld2FyZEludGVybmFsCQDMCAIJAGUCBQJiSAkAkQMCBQJiSgUCYksJAMwIAgUCYkkJAMwIAgUCYkoJAMwIAgkAZAIFAmJLAAEFA25pbAUDbmlsAwkAAAIFAmJNBQJiTQQCYk4JAQJhUgIJAJEDAgUCYkkFAmJLBQJhVAQCYVYJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYkkFAmJLCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJOCQCRAwIFAmJKBQJiSwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFVAQkAkQMCBQJiSQUCYksJAJEDAgUCYkoFAmJLBQNuaWwFAmJNCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUARZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5AgJhVgJiTwQCYlAJAJ0IAgUCYVEJAQFSAQUCYVYEAmJRAwkAAAIFAmJQBQR1bml0BQR1bml0CQD8BwQFAmFRAhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIFAUgJAMwIAgUCYVYJAMwIAgkAZwIFAmJPBQFLBQNuaWwFA25pbAMJAAACBQJiUQUCYlEJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUAQ5maW5hbGl6ZUhlbHBlcgAEAmJSCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhdwAFAWUEAmJTCQEBaAEJAQJheAAEAmJUCQEBaAEJAQJhdAAEAmJVCQEBaAEJAQJhdQAEAmJWCQELdmFsdWVPckVsc2UCCQCaCAIJAQJhbAAJAQJhbwAAAAQCYlcJAQJhTAEFAmJTBAJiWAkBAWgBCQECYUwBBQJiUwQCYm8JAQFoAQkBAmFDAQUCYlMDCQBmAgUCYlMFAmJVCQCUCgIFA25pbAcDCQAAAgUCYlIFAWUEAmJZCQECYm0ECQECYWwABQJibwUCYlMFAmJUBAJiWggFAmJZAl8xBAJjYQgFAmJZAl8yBAJjYgkAZAIFAmJYBQJiWgQCY2MDCQBmAgkAZQIFAmJWAAEFAmJUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXQACQBkAgUCYlQAAQUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXcABQFmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXQAAAAFA25pbAkAlAoCCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYlcFAmNiBQNuaWwFAmNjBQJjYQYDCQAAAgUCYlIFAWYEAmJaCQECYnkECQECYWwABQJibwUCYlMFAmJUBAJjZAkAawMJAQFoAQkBAmFGAQUCYlMFAmJaBQJiWAQCY2UJAGsDCQEBaAEJAQJhRQEFAmJTBQJiWgUCYlgEAmNmCQBkAgUCY2UFAmNkBAJiRQkAnwgBCQECYXkBBQJiVAQCYVYJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQJhbAAJAQFEAQUCYlQEAmJQCQCdCAIFAmFRCQEBUgEFAmFWBAJiUQMJAAACBQJiUAUEdW5pdAUEdW5pdAkA/AcEBQJhUQIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCBQFICQDMCAIFAmFWCQDMCAIJAGcCBQJiWgUBSwUDbmlsBQNuaWwDCQAAAgUCYlEFAmJRBAJjZwMDCQAAAgUCYlAFBHVuaXQGCQBmAgUBSwUCYloFBHVuaXQEAmNoCQBrAwUCY2YFAU4FAWIEAmNpCQBrAwUCY2YFAVEFAWIJAPwHBAUCYVECDGluY1VuY2xhaW1lZAkAzAgCBQFICQDMCAIFAmFWCQDMCAIFAmNoCQDMCAIFAmNpBQNuaWwFA25pbAMJAAACBQJjZwUCY2cEAmNqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXkBBQJiVAkAZAIJAQt2YWx1ZU9yRWxzZQIFAmJFAAAFAmNmBQNuaWwEAmNjAwkAZgIJAGUCBQJiVgABBQJiVAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF0AAkAZAIFAmJUAAEFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF4AAkAZAIFAmJTAAEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhdAAAAAkAzAgCCQELRGVsZXRlRW50cnkBCQECYXcABQNuaWwJAJQKAgkAzggCBQJjagUCY2MGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIYaW52YWxpZCBwcm9jZXNzaW5nIHN0YWdlAmFUAQ9maW5hbGl6ZVdyYXBwZXIBAmNrBAJjbAoAAmNtCQD8BwQFBHRoaXMCDmZpbmFsaXplSGVscGVyBQNuaWwFA25pbAMJAAECBQJjbQIHQm9vbGVhbgUCY20JAAIBCQCsAgIJAAMBBQJjbQIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjbAUCY2wDCQEBIQEFAmNsAwkAAAIFAmNrBQF3CQACAQISTm90aGluZyB0byBwcm9jZXNzCQCUCgIFA25pbAUEdW5pdAMJAGYCBQJjawAACQCUCgIFA25pbAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgkAZQIFAmNrAAEFA25pbAUDbmlsCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAEdcHJvY2Vzc1BlbmRpbmdQZXJpb2RzQW5kVXNlcnMACQCUCgIFA25pbAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgUBdwUDbmlsBQNuaWwCYVQBB2RlcG9zaXQABAJjbgMJAAACCAUCYVQGY2FsbGVyBQFDBgkBAmJqAQUCYVQDCQAAAgUCY24FAmNuBAJhRAkBAmJCAAQCY28JAGUCBQZoZWlnaHQJAQFqAQkBAmFuAAQCY3AJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFYCQECYXAACQCsAgIJAKwCAgIcbWFuZGF0b3J5IGVtaXNzaW9uX2NvbnRyYWN0LgkBAmFwAAIPIGlzIG5vdCBkZWZpbmVkBAJjcQkBC3ZhbHVlT3JFbHNlAgkAmggCBQFYCQECYXEAAAADCQAAAgUCY3EFAmNxBAJjcgkAawMJAGgCBQJjbwUCY3EFAmNwBQFjBAJjcwMJAGYCBQJjcgAACQD8BwQFAVgCBGVtaXQJAMwIAgUCY3IFA25pbAUDbmlsBQR1bml0AwkAAAIFAmNzBQJjcwQCY3QAAAQCY3UJAQJhSAMFAmFEBQJjdAUCY3IEAmN2CgACY20JAPwHBAUBWAIWZ3d4SG9sZGVyc1Jld2FyZFVwZGF0ZQUDbmlsBQNuaWwDCQABAgUCY20CB0Jvb2xlYW4FAmNtCQACAQkArAICCQADAQUCY20CHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3YFAmN2BAJjdwkAZAIFAmN0BQJjcgQCY3gDAwkAAAIFAmN3AAAJAQEhAQUCY3YHBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhdQAFAmFECQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUMBBQJhRAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUUBBQJhRAUCY3IJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbgAFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFGAQUCYUQFAmN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXYACQBkAgUCYUQAAQkAzAgCCQELU3RyaW5nRW50cnkCCQECYUcABQJjdQkAzAgCCQELU3RyaW5nRW50cnkCCQECYUsBBQJhRAUCY3UFA25pbAkAlAoCBQJjeAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAELY2xhaW1SZXdhcmQABAJhbQkBAmFoAAQCY3kJAKUIAQgFAmFUBmNhbGxlcgQCY3oJAQJiQwEFAmN5BAJhWggFAmN6Al8xBAJjeAgFAmN6Al8yBAJjQQMJAGYCBQJhWgAABgkAAgECEE5vdGhpbmcgdG8gY2xhaW0DCQAAAgUCY0EFAmNBBAJjQgAABAJjQwoAAmNtCQD8BwQFAmFRAgVjbGFpbQkAzAgCBQFIBQNuaWwFA25pbAMJAAECBQJjbQIDSW50BQJjbQkAAgEJAKwCAgkAAwEFAmNtAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmNECQBkAgUCYVoFAmNDCQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCYVQGY2FsbGVyBQJjRAkA2QQBCQCRAwIFAmFtBQFZCQDMCAIJAQJhWAQCBWNsYWltBQJjeQUCYVoFAmFUBQNuaWwFAmN4CQDMCAIFAmNECQDMCAIFAmNCBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBE2NsYWltUmV3YXJkUkVBRE9OTFkBAmN5BAJjRQkBAmJDAQUCY3kEAmFaCAUCY0UCXzEEAmN4CAUCY0UCXzIEAmNGCQELdmFsdWVPckVsc2UCCQCaCAIFAmFRCQEBVAIFAUgFAmN5AAAEAmNECQBkAgUCYVoFAmNGCQCUCgIFA25pbAUCY0QCYVQBHWxhdGVzdEZpbmFsaXplZFBlcmlvZFJFQURPTkxZAQJjeQkAlAoCBQNuaWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmF1AAD///////////8BAmFUASFsYXRlc3RGaW5hbGl6ZWRQZXJpb2RJbmZvUkVBRE9OTFkBAmN5CQCUCgIFA25pbAkBAWsBCQECYUcAAmFUARVjYWxjR3d4UGFyYW1zUkVBRE9OTFkDAmNHAmNIAmNJBAJjSgkAZAIFAmNIBQJjSQQCY0sJAQEtAQkAawMFAmNHBQFiBQJjSQQCY0wJAGgCCQBrAwUCY0cFAWIFAmNJBQJjSgkAlAoCBQNuaWwJAMwIAgUCY0sJAMwIAgUCY0wJAMwIAgkBAmJCAAUDbmlsAmFUARpjYWxjR3d4QW1vdW50U3RhcnRSRUFET05MWQMCY00CY04CY08EAmNQCQBrAwUCY04FAWMFAmNPBAJiTwkAawMFAmNNBQJjUAUBYwkAlAoCBQNuaWwJAMwIAgUCYk8FA25pbAJhVAEVb25FbWlzc2lvbkZvckd3eFN0YXJ0AAMJAQIhPQIIBQJhVAZjYWxsZXIFAXoJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbgAFBmhlaWdodAUDbmlsAmFUASNsYXRlc3RQZXJpb2RFbWlzc2lvblJld2FyZHNSRUFET05MWQECY3kEAmFECQECYkIACQCUCgIFA25pbAkAzAgCCQEBaAEJAQJhRQEFAmFEBQNuaWwCYVQBBWNhbGNEBQJjUQJjUgJjUwJjVAJjVQQCY1YJALYCAQACBAJjVwkApwMBBQJjVAQCY1gJAKcDAQUCY1UEAmNZCQCnAwEFAmNRBAJjWgkApwMBBQJjUgQCZGEJALkCAgkApwMBBQJjUwUCY1cEAmJnCQC3AgIFAmNZBQJjWgMJAAACBQJiZwUBZAkAlAoCBQNuaWwJAKYDAQUBZAQCZGIJALkCAgUCZGEFAmNWBAJkYwkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYFA25pbAoBAmRkAgJkZQJkZgQCZGcFAmRlBAJkaAgFAmRnAl8xBAJkaQgFAmRnAl8yBAJkaggFAmRnAl8zAwkBAiE9AgUCZGoFBHVuaXQFAmRlBAJkawkAugICCQC5AgIJALkCAgUCZGgFAmRoBQJkaAkAuQICCQC5AgIJALkCAgUCY1kFAmNaBQJjVgUCY1YEAmRsCQC6AgIJALkCAgkAtwICCQC6AgIJALkCAgUCZGIFAmJnBQJjVwkAuQICBQJkawUCY1YFAmRoCQC3AgIJALoCAgkAuQICCQC4AgIFAmRiBQJjVwUCZGgFAmNXCQC5AgIJALcCAgUCY1YJALYCAQABBQJkawQCZG0JAQF0AQkAuAICBQJkbAkBBXZhbHVlAQUCZGgDCQDAAgIFAmNYBQJkbQkAlQoDBQJkbAUCZGgFAmRmCQCVCgMFAmRsBQJkaAUEdW5pdAQCZG4KAAJkbwUCZGMKAAJkcAkAkAMBBQJkbwoAAmRxCQCVCgMFAmJnBQR1bml0BQR1bml0CgECZHICAmRzAmR0AwkAZwIFAmR0BQJkcAUCZHMJAQJkZAIFAmRzCQCRAwIFAmRvBQJkdAoBAmR1AgJkcwJkdAMJAGcCBQJkdAUCZHAFAmRzCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNwkBAmR1AgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgkBAmRyAgUCZHEAAAABAAIAAwAEAAUABgAHBAJkbAgFAmRuAl8xBAJkaQgFAmRuAl8yBAJkaggFAmRuAl8zAwkBAiE9AgUCZGoFBHVuaXQJAJQKAgUDbmlsCQCmAwEFAmRsBAJkbQkBAXQBCQC4AgIFAmRsCQEFdmFsdWUBBQJkaQkAAgEJAKwCAgIdRCBjYWxjdWxhdGlvbiBlcnJvciwgZERpZmYgPSAJAKYDAQUCZG0CYVQBC3RyYWRlUmV3YXJkAgJiSQJiSgQCZHYJAAACCQCQAwEFAmJJCQCQAwEFAmJKBAJkdwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYVcAAAAEAmR4CQCRAwIIBQJhVAhwYXltZW50cwAABAJkeQgFAmR4B2Fzc2V0SWQEAmR6CAUCZHgGYW1vdW50BAJiTAkAzAgCAwkAZwIFAmR3CQCQAwEFAmJJBgkBAXEBAhNUb28gbWFueSByZWNpcGllbnRzCQDMCAIDBQJkdgYJAQFxAQIXQXJndW1lbnRzIHNpemUgbWlzbWF0Y2gJAMwIAgMJAAACBQJkeQUCYWcGCQEBcQECE1dyb25nIGFzc2V0IHBheW1lbnQFA25pbAMJAAACBQJiTAUCYkwEAmJNCQD8BwQFBHRoaXMCE3RyYWRlUmV3YXJkSW50ZXJuYWwJAMwIAgUCZHoJAMwIAgUCYkkJAMwIAgUCYkoJAMwIAgAABQNuaWwFA25pbAMJAAACBQJiTQUCYk0JAJQKAgUDbmlsBQJiTQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAESY2xhaW1UcmFkaW5nUmV3YXJkAAQCYVYIBQJhVAZjYWxsZXIEAmRBCQClCAEFAmFWBAJkQgkBAmJHAQUCZEEDCQBmAgUCZEIAAAkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFWBQJkQgUCYWcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhVQEFAmRBAAAFA25pbAUCZEIJAQFxAQIQbm90aGluZyB0byBjbGFpbQJhVAEaY2xhaW1UcmFkaW5nUmV3YXJkUkVBRE9OTFkBAmFWCQCUCgIFA25pbAkBAmJHAQUCYVYBAmRDAQJkRAAEAmRFBAJiZgkBAmJoAAMJAAECBQJiZgIKQnl0ZVZlY3RvcgQCYmwFAmJmBQJibAMJAAECBQJiZgIEVW5pdAgFAmRDD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJkQwlib2R5Qnl0ZXMJAJEDAggFAmRDBnByb29mcwAABQJkReC5ky4=", "height": 2710363, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 85d7pw2xtRmy3syv4UdMdrDwAAQ3PKRgFdVQoAgNTxDr Next: 2aiNXQCFqPkXCuya54TKGupVLi6ygKVcBXHrHZFW1asM 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
17-
18-let MULT18 = 1000000000000000000
19-
20-let MULT18BI = toBigInt(MULT18)
2115
2216 let wavesString = "WAVES"
2317
162156 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
163157
164158
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+
165174 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)
166211
167212
168213 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
230275 }
231276
232277
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+
233325 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
234326 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
235327 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
236328 }
237329
238330
239-func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
331+func nextPeriod () = getNumberByKey(keyNextPeriod())
240332
241333
242-func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
243-
244-
245-func _refreshRewardPerGwxIntegral () = {
246- let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
247- case s: String =>
248- parseBigInt(s)
334+func commonClaimReward (userAddress) = {
335+ let cfgArray = readConfigArrayOrFail()
336+ let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337+ let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338+ match userUnclaimedOption {
249339 case _: Unit =>
250- unit
340+ $Tuple2(0, nil)
341+ case u: Int =>
342+ $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
251343 case _ =>
252344 throw("Match error")
253- }, zeroBigInt)
254- let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
255- let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
256- let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
257- let gwxAmountTotal = {
258- let @ = invoke(boostingContractOrFail(), "getGwxTotalREADONLY", nil, nil)
259- if ($isInstanceOf(@, "Int"))
260- then @
261- else throw(($getType(@) + " couldn't be cast to Int"))
262- }
263- let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
264- let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), (toBigInt(gwxAmountTotal) * MULT8BI)))
265- $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
345+ }
266346 }
267347
268348
269-func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
270-
271-
272-func _refreshUserReward (userAddress) = {
273- let rewardPerGwxIntegralUserLast = valueOrElse( match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
274- case s: String =>
275- parseBigInt(s)
276- case _: Unit =>
277- unit
278- case _ =>
279- throw("Match error")
280- }, zeroBigInt)
281- let userIdxOrFail = getUserIndexByAddress(toString(boostingContractOrFail()), toString(userAddress))
282- let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userIdxOrFail)), 0)
283- let $t0992710144 = _refreshRewardPerGwxIntegral()
284- let rewardPerGwxIntegralActions = $t0992710144._1
285- let rewardPerGwxIntegral = $t0992710144._2
286- let userGwxAmount = {
287- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [toString(userAddress)], nil)
288- if ($isInstanceOf(@, "Int"))
289- then @
290- else throw(($getType(@) + " couldn't be cast to Int"))
291- }
292- let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
293- $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
294- }
295-
296-
297-func commonClaimReward (userAddressStr) = {
298- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
299- let cfgArray = readConfigArrayOrFail()
300- let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddressStr)
301- let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
302- let $t01098111036 = _refreshUserReward(userAddress)
303- let actions = $t01098111036._1
304- let reward = $t01098111036._2
305- $Tuple2(reward, ([IntegerEntry(keyUserUnclaimed(userIdx), 0)] ++ actions))
306- }
307-
308-
309-@Callable(i)
310-func refreshUserReward (userAddressBytes) = {
311- let checkCaller = if ((i.caller == boostingContractOrFail()))
312- then true
313- else throwErr("permission denied")
314- if ((checkCaller == checkCaller))
315- then _refreshUserReward(Address(userAddressBytes))
316- else throw("Strict value is not equal to itself.")
317- }
318-
349+func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
319350
320351
321352 @Callable(i)
357388
358389
359390 @Callable(i)
360-func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
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)
412+ }
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+ }
361450
362451
363452
364453 @Callable(i)
365-func claimReward () = {
366- let cfgArray = readConfigArrayOrFail()
367- let userAddress = i.caller
368- let userAddressStr = toString(userAddress)
369- let $t01299613053 = commonClaimReward(userAddressStr)
370- let amount = $t01299613053._1
371- let actions = $t01299613053._2
372- let checkAmount = if ((amount > 0))
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)
469+ else throw("Strict value is not equal to itself.")
470+ }
471+
472+
473+
474+@Callable(i)
475+func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
476+
477+
478+
479+@Callable(i)
480+func deposit () = {
481+ let checkCaller = if ((i.caller == votingEmissionContract))
373482 then true
374- else throw("nothing to claim")
375- if ((checkAmount == checkAmount))
483+ else mustManager(i)
484+ if ((checkCaller == checkCaller))
376485 then {
377- let userGwxAmount = {
378- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
379- if ($isInstanceOf(@, "Int"))
380- then @
381- else throw(($getType(@) + " couldn't be cast to Int"))
382- }
383- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
384- let activeReferralInv = if ((referrer == unit))
385- then unit
386- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
387- if ((activeReferralInv == activeReferralInv))
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))
388491 then {
389- let referralInv = if (if ((referrer == unit))
390- then true
391- else (referralMinGWxAmount > userGwxAmount))
392- then unit
393- else {
394- let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
395- let referralReward = fraction(amount, referralRewardPermille, SCALE)
396- invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
397- }
398- if ((referralInv == referralInv))
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))
399497 then {
400- let claimedReferral = {
401- let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
402- if ($isInstanceOf(@, "Int"))
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"))
403503 then @
404- else throw(($getType(@) + " couldn't be cast to Int"))
504+ else throw(($getType(@) + " couldn't be cast to Boolean"))
405505 }
406- if ((claimedReferral == claimedReferral))
506+ if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
407507 then {
408- let totalAmount = (amount + claimedReferral)
409- $Tuple2(([ScriptTransfer(i.caller, amount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
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)
410515 }
411516 else throw("Strict value is not equal to itself.")
412517 }
420525
421526
422527 @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)
423555 func claimRewardREADONLY (address) = {
424- let $t01438014430 = commonClaimReward(address)
425- let amount = $t01438014430._1
426- let actions = $t01438014430._2
556+ let $t02043820488 = commonClaimReward(address)
557+ let amount = $t02043820488._1
558+ let actions = $t02043820488._2
427559 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
428560 let totalAmount = (amount + referralUnclaimed)
429561 $Tuple2(nil, totalAmount)
432564
433565
434566 @Callable(i)
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)
435596 func onEmissionForGwxStart () = if ((i.caller != factoryContract))
436597 then throw("permissions denied")
437598 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+ }
665+ }
438666
439667
440668
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
17-
18-let MULT18 = 1000000000000000000
19-
20-let MULT18BI = toBigInt(MULT18)
2115
2216 let wavesString = "WAVES"
2317
2418 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
2519
2620
2721 func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
2822
2923
3024 func getStringByKey (key) = valueOrElse(getString(this, key), "")
3125
3226
3327 func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
3428
3529
3630 func parseAssetId (input) = if ((input == wavesString))
3731 then unit
3832 else fromBase58String(input)
3933
4034
4135 func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
4236
4337
4438 func throwErr (msg) = throw(wrapErr(msg))
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
147141 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
148142
149143
150144 func keyUsersCount () = "%s__nextUserNum"
151145
152146
153147 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
154148
155149
156150 func keyGwxHoldersRewardCurrent () = "%s%s__gwxHoldersReward__current"
157151
158152
159153 func keyGwxHoldersRewardNext () = "%s%s__gwxHoldersReward__next"
160154
161155
162156 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
163157
164158
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+
165174 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)
166211
167212
168213 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
169214
170215
171216 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(keyReferralsContractAddress()))
172217
173218 func keyTradingRewardHistory (user,i) = makeString(["%s%s%s%s", "tradingReward", "history", user, toBase58String(i.transactionId)], SEP)
174219
175220
176221 func keyTradingReward (userAddress) = makeString(["%s%s", "tradingReward", userAddress], SEP)
177222
178223
179224 func keyMaxRecipients () = makeString(["%s", "maxRecipients"], SEP)
180225
181226
182227 func HistoryEntry (type,user,amount,i) = {
183228 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
184229 let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount)], SEP)
185230 StringEntry(historyKEY, historyDATA)
186231 }
187232
188233
189234 func keyManagerPublicKey () = "%s__managerPublicKey"
190235
191236
192237 func keyManagerVaultAddress () = "%s__managerVaultAddress"
193238
194239
195240 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
196241 case s: String =>
197242 addressFromStringValue(s)
198243 case _ =>
199244 this
200245 }
201246
202247
203248 func managerPublicKeyOrUnit () = {
204249 let managerVaultAddress = getManagerVaultAddressOrThis()
205250 match getString(managerVaultAddress, keyManagerPublicKey()) {
206251 case s: String =>
207252 fromBase58String(s)
208253 case _: Unit =>
209254 unit
210255 case _ =>
211256 throw("Match error")
212257 }
213258 }
214259
215260
216261 func mustManager (i) = {
217262 let pd = throw("Permission denied")
218263 match managerPublicKeyOrUnit() {
219264 case pk: ByteVector =>
220265 if ((i.callerPublicKey == pk))
221266 then true
222267 else pd
223268 case _: Unit =>
224269 if ((i.caller == this))
225270 then true
226271 else pd
227272 case _ =>
228273 throw("Match error")
229274 }
230275 }
231276
232277
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+
233325 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
234326 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
235327 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
236328 }
237329
238330
239-func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
331+func nextPeriod () = getNumberByKey(keyNextPeriod())
240332
241333
242-func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
243-
244-
245-func _refreshRewardPerGwxIntegral () = {
246- let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
247- case s: String =>
248- parseBigInt(s)
334+func commonClaimReward (userAddress) = {
335+ let cfgArray = readConfigArrayOrFail()
336+ let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337+ let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338+ match userUnclaimedOption {
249339 case _: Unit =>
250- unit
340+ $Tuple2(0, nil)
341+ case u: Int =>
342+ $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
251343 case _ =>
252344 throw("Match error")
253- }, zeroBigInt)
254- let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
255- let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
256- let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
257- let gwxAmountTotal = {
258- let @ = invoke(boostingContractOrFail(), "getGwxTotalREADONLY", nil, nil)
259- if ($isInstanceOf(@, "Int"))
260- then @
261- else throw(($getType(@) + " couldn't be cast to Int"))
262- }
263- let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
264- let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), (toBigInt(gwxAmountTotal) * MULT8BI)))
265- $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
345+ }
266346 }
267347
268348
269-func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
270-
271-
272-func _refreshUserReward (userAddress) = {
273- let rewardPerGwxIntegralUserLast = valueOrElse( match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
274- case s: String =>
275- parseBigInt(s)
276- case _: Unit =>
277- unit
278- case _ =>
279- throw("Match error")
280- }, zeroBigInt)
281- let userIdxOrFail = getUserIndexByAddress(toString(boostingContractOrFail()), toString(userAddress))
282- let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userIdxOrFail)), 0)
283- let $t0992710144 = _refreshRewardPerGwxIntegral()
284- let rewardPerGwxIntegralActions = $t0992710144._1
285- let rewardPerGwxIntegral = $t0992710144._2
286- let userGwxAmount = {
287- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [toString(userAddress)], nil)
288- if ($isInstanceOf(@, "Int"))
289- then @
290- else throw(($getType(@) + " couldn't be cast to Int"))
291- }
292- let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
293- $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
294- }
295-
296-
297-func commonClaimReward (userAddressStr) = {
298- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
299- let cfgArray = readConfigArrayOrFail()
300- let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddressStr)
301- let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
302- let $t01098111036 = _refreshUserReward(userAddress)
303- let actions = $t01098111036._1
304- let reward = $t01098111036._2
305- $Tuple2(reward, ([IntegerEntry(keyUserUnclaimed(userIdx), 0)] ++ actions))
306- }
307-
308-
309-@Callable(i)
310-func refreshUserReward (userAddressBytes) = {
311- let checkCaller = if ((i.caller == boostingContractOrFail()))
312- then true
313- else throwErr("permission denied")
314- if ((checkCaller == checkCaller))
315- then _refreshUserReward(Address(userAddressBytes))
316- else throw("Strict value is not equal to itself.")
317- }
318-
349+func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
319350
320351
321352 @Callable(i)
322353 func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = if ((currentIter == size(userAddresses)))
323354 then nil
324355 else {
325356 let checks = [if ((i.caller == this))
326357 then true
327358 else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
328359 then true
329360 else throwErr("insufficient payment assetId")]
330361 if ((checks == checks))
331362 then {
332363 let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
333364 if ((tradeRewardInternal == tradeRewardInternal))
334365 then {
335366 let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
336367 let userAddress = addressFromStringValue(userAddresses[currentIter])
337368 $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
338369 }
339370 else throw("Strict value is not equal to itself.")
340371 }
341372 else throw("Strict value is not equal to itself.")
342373 }
343374
344375
345376
346377 @Callable(i)
347378 func updateReferralActivity (userAddress,gWxAmountStart) = {
348379 let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
349380 let activeReferralInv = if ((referrer == unit))
350381 then unit
351382 else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
352383 if ((activeReferralInv == activeReferralInv))
353384 then $Tuple2(nil, unit)
354385 else throw("Strict value is not equal to itself.")
355386 }
356387
357388
358389
359390 @Callable(i)
360-func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
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)
412+ }
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+ }
361450
362451
363452
364453 @Callable(i)
365-func claimReward () = {
366- let cfgArray = readConfigArrayOrFail()
367- let userAddress = i.caller
368- let userAddressStr = toString(userAddress)
369- let $t01299613053 = commonClaimReward(userAddressStr)
370- let amount = $t01299613053._1
371- let actions = $t01299613053._2
372- let checkAmount = if ((amount > 0))
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)
469+ else throw("Strict value is not equal to itself.")
470+ }
471+
472+
473+
474+@Callable(i)
475+func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
476+
477+
478+
479+@Callable(i)
480+func deposit () = {
481+ let checkCaller = if ((i.caller == votingEmissionContract))
373482 then true
374- else throw("nothing to claim")
375- if ((checkAmount == checkAmount))
483+ else mustManager(i)
484+ if ((checkCaller == checkCaller))
376485 then {
377- let userGwxAmount = {
378- let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
379- if ($isInstanceOf(@, "Int"))
380- then @
381- else throw(($getType(@) + " couldn't be cast to Int"))
382- }
383- let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
384- let activeReferralInv = if ((referrer == unit))
385- then unit
386- else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
387- if ((activeReferralInv == activeReferralInv))
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))
388491 then {
389- let referralInv = if (if ((referrer == unit))
390- then true
391- else (referralMinGWxAmount > userGwxAmount))
392- then unit
393- else {
394- let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
395- let referralReward = fraction(amount, referralRewardPermille, SCALE)
396- invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
397- }
398- if ((referralInv == referralInv))
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))
399497 then {
400- let claimedReferral = {
401- let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
402- if ($isInstanceOf(@, "Int"))
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"))
403503 then @
404- else throw(($getType(@) + " couldn't be cast to Int"))
504+ else throw(($getType(@) + " couldn't be cast to Boolean"))
405505 }
406- if ((claimedReferral == claimedReferral))
506+ if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
407507 then {
408- let totalAmount = (amount + claimedReferral)
409- $Tuple2(([ScriptTransfer(i.caller, amount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
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)
410515 }
411516 else throw("Strict value is not equal to itself.")
412517 }
413518 else throw("Strict value is not equal to itself.")
414519 }
415520 else throw("Strict value is not equal to itself.")
416521 }
417522 else throw("Strict value is not equal to itself.")
418523 }
419524
420525
421526
422527 @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)
423555 func claimRewardREADONLY (address) = {
424- let $t01438014430 = commonClaimReward(address)
425- let amount = $t01438014430._1
426- let actions = $t01438014430._2
556+ let $t02043820488 = commonClaimReward(address)
557+ let amount = $t02043820488._1
558+ let actions = $t02043820488._2
427559 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
428560 let totalAmount = (amount + referralUnclaimed)
429561 $Tuple2(nil, totalAmount)
430562 }
431563
432564
433565
434566 @Callable(i)
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)
435596 func onEmissionForGwxStart () = if ((i.caller != factoryContract))
436597 then throw("permissions denied")
437598 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+ }
665+ }
438666
439667
440668
441669 @Callable(i)
442670 func tradeReward (userAddresses,rewards) = {
443671 let argsComparison = (size(userAddresses) == size(rewards))
444672 let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
445673 let payment = i.payments[0]
446674 let paymentAssetId = payment.assetId
447675 let paymentAmount = payment.amount
448676 let checks = [if ((maxRecipients >= size(userAddresses)))
449677 then true
450678 else throwErr("Too many recipients"), if (argsComparison)
451679 then true
452680 else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
453681 then true
454682 else throwErr("Wrong asset payment")]
455683 if ((checks == checks))
456684 then {
457685 let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
458686 if ((tradeRewardInternal == tradeRewardInternal))
459687 then $Tuple2(nil, tradeRewardInternal)
460688 else throw("Strict value is not equal to itself.")
461689 }
462690 else throw("Strict value is not equal to itself.")
463691 }
464692
465693
466694
467695 @Callable(i)
468696 func claimTradingReward () = {
469697 let userAddress = i.caller
470698 let userAddressString = toString(userAddress)
471699 let reward = getTradingReward(userAddressString)
472700 if ((reward > 0))
473701 then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
474702 else throwErr("nothing to claim")
475703 }
476704
477705
478706
479707 @Callable(i)
480708 func claimTradingRewardREADONLY (userAddress) = $Tuple2(nil, getTradingReward(userAddress))
481709
482710
483711 @Verifier(tx)
484712 func verify () = {
485713 let targetPublicKey = match managerPublicKeyOrUnit() {
486714 case pk: ByteVector =>
487715 pk
488716 case _: Unit =>
489717 tx.senderPublicKey
490718 case _ =>
491719 throw("Match error")
492720 }
493721 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
494722 }
495723

github/deemru/w8io/169f3d6 
93.82 ms