tx · D2pxJxcYEhJxxbt4AsasHmgTGpcAJvxVodqyJx2TZXBD

3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE:  -0.01600000 Waves

2023.09.07 12:25 [2744785] smart account 3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE > SELF 0.00000000 Waves

{ "type": 13, "id": "D2pxJxcYEhJxxbt4AsasHmgTGpcAJvxVodqyJx2TZXBD", "fee": 1600000, "feeAssetId": null, "timestamp": 1694078812478, "version": 2, "chainId": 84, "sender": "3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE", "senderPublicKey": "G349Uq3FTox7dRNLeAfAQeoACvwZ9iEnVSaHcEYn6j8J", "proofs": [ "3uxQKyizDEDPg1X3FktAVJ16dNAjZUTMbAYSF8RuokES6exmNpmUo1EXoniJ4HGYL8YmTSChEnAZzK1QSvPct6HF" ], "script": "base64:BgLZFggCEgQKAgIBEgYKBAEYEQESBAoCCAESABIAEgMKAQgSABIECgIYERIAEgMKAQgSAwoBBCIDU0VQIgVTQ0FMRSIFTVVMVDgiB01VTFQ4QkkiCnplcm9CaWdJbnQiFHByb2Nlc3NpbmdTdGFnZVRvdGFsIhVwcm9jZXNzaW5nU3RhZ2VTaGFyZXMiBk1VTFQxOCIITVVMVDE4QkkiC3dhdmVzU3RyaW5nIgd3cmFwRXJyIgNtc2ciCHRocm93RXJyIg5nZXROdW1iZXJCeUtleSIDa2V5Ig9nZXROdW1iZXJPckZhaWwiDmdldFN0cmluZ0J5S2V5Ig9nZXRTdHJpbmdPckZhaWwiDHBhcnNlQXNzZXRJZCIFaW5wdXQiA2FicyIDdmFsIglhYnNCaWdJbnQiC2tleU1heERlcHRoIg9tYXhEZXB0aERlZmF1bHQiCG1heERlcHRoIhFrZXlGYWN0b3J5QWRkcmVzcyIRZmFjdG9yeUFkZHJlc3NTdHIiD2ZhY3RvcnlDb250cmFjdCISa2V5RW1pc3Npb25BZGRyZXNzIhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0IhNrZXlOdW1Ub1VzZXJNYXBwaW5nIgNudW0iFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUiGnJlZmVycmFsUHJvZ3JhbU5hbWVEZWZhdWx0IhNyZWZlcnJhbFByb2dyYW1OYW1lIhdrZXlSZWZlcnJhbE1pbkdXeEFtb3VudCIbcmVmZXJyYWxNaW5HV3hBbW91bnREZWZhdWx0IhRyZWZlcnJhbE1pbkdXeEFtb3VudCIZa2V5UmVmZXJyZXJSZXdhcmRQZXJtaWxsZSIdcmVmZXJyZXJSZXdhcmRQZXJtaWxsZURlZmF1bHQiFnJlZmVycmVyUmV3YXJkUGVybWlsbGUiGWtleVJlZmVycmFsUmV3YXJkUGVybWlsbGUiHXJlZmVycmFsUmV3YXJkUGVybWlsbGVEZWZhdWx0IhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlIgtrZXlSZWZlcnJlciIPcmVmZXJyYWxBZGRyZXNzIhRrZXlVbmNsYWltZWRSZWZlcnJhbCILcHJvZ3JhbU5hbWUiDmNsYWltZXJBZGRyZXNzIhJlbWlzc2lvbkFkZHJlc3NTdHIiEGVtaXNzaW9uQ29udHJhY3QiDUlkeENmZ0Fzc2V0SWQiFklkeENmZ1BhY2VtYWtlckFkZHJlc3MiFklkeENmZ0Jvb3N0aW5nQ29udHJhY3QiDklkeENmZ01heERlcHRoIglrZXlDb25maWciEmdldEVtaXNzaW9uQWRkcmVzcyIPZW1pc3Npb25BZGRyZXNzIgx3eEFzc2V0SWRTdHIiCXd4QXNzZXRJZCIVcmVhZENvbmZpZ0FycmF5T3JGYWlsIgxmb3JtYXRDb25maWciGm1hdGNoZXJQYWNlbWFrZXJBZGRyZXNzU3RyIhpib29zdGluZ0NvbnRyYWN0QWRkcmVzc1N0ciIWYm9vc3RpbmdDb250cmFjdE9yRmFpbCIIY2ZnQXJyYXkiDWtleVN1c3BlbnNpb24iC2lzU3VzcGVuZGVkIhB0aHJvd0lmU3VzcGVuZGVkIh9rZXlHd3hSZXdhcmRFbWlzc2lvblN0YXJ0SGVpZ2h0Ig1rZXlVc2Vyc0NvdW50IhJrZXlVc2VyMk51bU1hcHBpbmciC3VzZXJBZGRyZXNzIhZrZXlSYXRlUGVyQmxvY2tDdXJyZW50IhprZXlHd3hIb2xkZXJzUmV3YXJkQ3VycmVudCIXa2V5R3d4SG9sZGVyc1Jld2FyZE5leHQiFGtleVBvb2xXZWlnaHRWaXJ0dWFsIhBrZXlVc2VyVW5jbGFpbWVkIgl1c2VySW5kZXgiG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcyIecmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzT3JGYWlsIhdrZXlUcmFkaW5nUmV3YXJkSGlzdG9yeSIEdXNlciIBaSIQa2V5VHJhZGluZ1Jld2FyZCIQa2V5TWF4UmVjaXBpZW50cyIMSGlzdG9yeUVudHJ5IgR0eXBlIgZhbW91bnQiCmhpc3RvcnlLRVkiC2hpc3RvcnlEQVRBIhNrZXlNYW5hZ2VyUHVibGljS2V5IhZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzIhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIgckbWF0Y2gwIgFzIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIgttdXN0TWFuYWdlciICcGQiAnBrIhVnZXRVc2VySW5kZXhCeUFkZHJlc3MiEGdldFRyYWRpbmdSZXdhcmQiF2tleVJld2FyZFBlckd3eEludGVncmFsIhdnZXRHd3hBbW91bnRUb3RhbE9wdGlvbiILa2V5R3d4VG90YWwiG2dldFVzZXJHd3hBbW91bnRUb3RhbE9wdGlvbiIVa2V5VXNlckd3eEFtb3VudFRvdGFsIhxfcmVmcmVzaFJld2FyZFBlckd3eEludGVncmFsIhxyZXdhcmRQZXJHd3hJbnRlZ3JhbFByZXZpb3VzIh5yZXdhcmRQZXJHd3hJbnRlZ3JhbExhc3RIZWlnaHQiDGVtaXNzaW9uUmF0ZSIXZ3d4SG9sZGVyc1Jld2FyZEN1cnJlbnQiDmd3eEFtb3VudFRvdGFsIgJkaCIQZ3d4QW1vdW50VG90YWxCSSIUcmV3YXJkUGVyR3d4SW50ZWdyYWwiH2tleVJld2FyZFBlckd3eEludGVncmFsVXNlckxhc3QiEl9yZWZyZXNoVXNlclJld2FyZCIHdXNlck51bSINJHQwMTAyOTIxMDM4MCIbcmV3YXJkUGVyR3d4SW50ZWdyYWxBY3Rpb25zIhxyZXdhcmRQZXJHd3hJbnRlZ3JhbFVzZXJMYXN0Ig11c2VySWR4T3B0aW9uIg11c2VyVW5jbGFpbWVkIg11c2VyR3d4QW1vdW50Igp1c2VyUmV3YXJkIhFjb21tb25DbGFpbVJld2FyZCIOdXNlckFkZHJlc3NTdHIiDSR0MDExNjcxMTE3MzUiB2FjdGlvbnMiBnJld2FyZCIQdXNlckFkZHJlc3NCeXRlcyIPc3VzcGVuc2lvbkNoZWNrIgtjaGVja0NhbGxlciINJHQwMTIwNjExMjEzOSIVcGF5bWVudEFtb3VudExlZnRPdmVyIg11c2VyQWRkcmVzc2VzIgdyZXdhcmRzIgtjdXJyZW50SXRlciIGY2hlY2tzIhN0cmFkZVJld2FyZEludGVybmFsIhd0cmFkaW5nUmV3YXJkSGlzdG9yeUtleSIOZ1d4QW1vdW50U3RhcnQiCHJlZmVycmVyIhFhY3RpdmVSZWZlcnJhbEludiINJHQwMTQwMDkxNDA2NiILY2hlY2tBbW91bnQiAUAiC3JlZmVycmFsSW52Ig5yZWZlcnJlclJld2FyZCIOcmVmZXJyYWxSZXdhcmQiBGVtaXQiD2NsYWltZWRSZWZlcnJhbCILdG90YWxBbW91bnQiB2FkZHJlc3MiDSR0MDE1NDIzMTU0NzMiEXJlZmVycmFsVW5jbGFpbWVkIg5hcmdzQ29tcGFyaXNvbiINbWF4UmVjaXBpZW50cyIHcGF5bWVudCIOcGF5bWVudEFzc2V0SWQiDXBheW1lbnRBbW91bnQiEXVzZXJBZGRyZXNzU3RyaW5nIgF2IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXlYAAFhAgJfXwABYgDoBwABYwCAwtcvAAFkCQC2AgEFAWMAAWUJALYCAQAAAAFmAAAAAWcAAQABaACAgJC7utat8A0AAWkJALYCAQUBaAABagIFV0FWRVMBAWsBAWwJALkJAgkAzAgCAhBnd3hfcmV3YXJkLnJpZGU6CQDMCAIFAWwFA25pbAIBIAEBbQEBbAkAAgEJAQFrAQUBbAEBbgEBbwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFvAAABAXABAW8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQFvCQEBawEJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAW8CDyBpcyBub3QgZGVmaW5lZAEBcQEBbwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFvAgABAXIBAW8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQFvCQEBawEJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAW8CDyBpcyBub3QgZGVmaW5lZAEBcwEBdAMJAAACBQF0BQFqBQR1bml0CQDZBAEFAXQBAXUBAXYDCQBmAgAABQF2CQEBLQEFAXYFAXYBAXcBAXYDCQC/AgIFAWUFAXYJAL4CAQUBdgUBdgABeAIMJXNfX21heERlcHRoAAF5AB4AAXoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBeAUBeQEBQQACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAAUIJAQFyAQkBAUEAAAFDCQERQGV4dHJOYXRpdmUoMTA2MikBBQFCAQFEAAIdJXMlc19fY29uZmlnX19lbWlzc2lvbkFkZHJlc3MBAUUACQC5CQIJAMwIAgICJXMJAMwIAgIWdm90aW5nRW1pc3Npb25Db250cmFjdAUDbmlsBQFhAAFGCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQFDCQEBRQABAUcBAUgJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIHbWFwcGluZwkAzAgCAghudW0ydXNlcgkAzAgCCQCkAwEFAUgFA25pbAUBYQABSQkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgILcHJvZ3JhbU5hbWUFA25pbAUBYQABSgIGd3hsb2NrAAFLCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAUkFAUoAAUwJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICDG1pbkdXeEFtb3VudAUDbmlsBQFhAAFNCQBoAgD0AwUBYwABTgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFMBQFNAAFPCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJlclJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAVAAMgABUQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFPBQFQAAFSCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlBQNuaWwFAWEAAVMAMgABVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFSBQFTAQFVAQFWCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICCHJlZmVycmVyCQDMCAIFAUsJAMwIAgUBVgUDbmlsBQFhAQFXAgFYAVkJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIRdW5jbGFpbWVkUmVmZXJyYWwJAMwIAgUBWAkAzAgCBQFZBQNuaWwFAWEAAVoJAQFyAQkBAUQAAAJhYQkBEUBleHRyTmF0aXZlKDEwNjIpAQUBWgACYWIAAQACYWMAAgACYWQAAwACYWUABAECYWYAAgolc19fY29uZmlnAQJhZwAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQEBRAAJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4JAQFEAAIPIGlzIG5vdCBkZWZpbmVkAAJhaAkBAmFnAAACYWkJAJEDAgkAtQkCCQEFdmFsdWUBCQCdCAIFAmFoCQECYWYABQFhAAEAAmFqCQDZBAEFAmFpAQJhawAJALUJAgkBAXIBCQECYWYABQFhAQJhbAQCYWkCYW0CYW4BegkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAIFAmFpCQDMCAIFAmFtCQDMCAIFAmFuCQDMCAIJAKQDAQUBegUDbmlsBQFhAQJhbwAEAmFwCQECYWsACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJhcAUCYWQCKGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MgaXMgbm90IGRlZmluZWQAAmFxAg4lc19fc3VzcGVuc2lvbgACYXIJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwUCYXEHAQJhcwADCQEBIQEFAmFyBgkBAW0BAglzdXNwZW5kZWQBAmF0AAIoJXMlc19fZ3d4UmV3YXJkRW1pc3Npb25QYXJ0X19zdGFydEhlaWdodAECYXUAAg8lc19fbmV4dFVzZXJOdW0BAmF2AQJhdwkAuQkCCQDMCAICGSVzJXMlc19fbWFwcGluZ19fdXNlcjJudW0JAMwIAgkApQgBBQJhdwUDbmlsBQFhAQJheAACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAECYXkAAh8lcyVzX19nd3hIb2xkZXJzUmV3YXJkX19jdXJyZW50AQJhegACHCVzJXNfX2d3eEhvbGRlcnNSZXdhcmRfX25leHQBAmFBAAIgJXMlc19fcG9vbFdlaWdodF9fR1dYdmlydHVhbFBPT0wBAmFCAQJhQwkAuQkCCQDMCAICBCVzJWQJAMwIAgINdXNlclVuY2xhaW1lZAkAzAgCCQCkAwEFAmFDBQNuaWwFAWEBAmFEAAkAuQkCCQDMCAICBCVzJXMJAMwIAgIGY29uZmlnCQDMCAICGHJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwUDbmlsBQFhAAJhRQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAXIBCQECYUQAAQJhRgICYUcCYUgJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCAg10cmFkaW5nUmV3YXJkCQDMCAICB2hpc3RvcnkJAMwIAgUCYUcJAMwIAgkA2AQBCAUCYUgNdHJhbnNhY3Rpb25JZAUDbmlsBQFhAQJhSQECYXcJALkJAgkAzAgCAgQlcyVzCQDMCAICDXRyYWRpbmdSZXdhcmQJAMwIAgUCYXcFA25pbAUBYQECYUoACQC5CQIJAMwIAgICJXMJAMwIAgINbWF4UmVjaXBpZW50cwUDbmlsBQFhAQJhSwQCYUwCYUcCYU0CYUgEAmFOCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCYUwJAMwIAgUCYUcJAMwIAgkA2AQBCAUCYUgNdHJhbnNhY3Rpb25JZAUDbmlsBQFhBAJhTwkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQJhTQUDbmlsBQFhCQELU3RyaW5nRW50cnkCBQJhTgUCYU8BAmFQAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAmFRAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAmFSAAQCYVMJAKIIAQkBAmFRAAMJAAECBQJhUwIGU3RyaW5nBAJhVAUCYVMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFUBQR0aGlzAQJhVQAEAmFWCQECYVIABAJhUwkAnQgCBQJhVgkBAmFQAAMJAAECBQJhUwIGU3RyaW5nBAJhVAUCYVMJANkEAQUCYVQDCQABAgUCYVMCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECYVcBAmFIBAJhWAkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJhUwkBAmFVAAMJAAECBQJhUwIKQnl0ZVZlY3RvcgQCYVkFAmFTAwkAAAIIBQJhSA9jYWxsZXJQdWJsaWNLZXkFAmFZBgUCYVgDCQABAgUCYVMCBFVuaXQDCQAAAggFAmFIBmNhbGxlcgUEdGhpcwYFAmFYCQACAQILTWF0Y2ggZXJyb3IBAmFaAgJhbgJhdwQBbwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgdtYXBwaW5nCQDMCAICCHVzZXIybnVtCQDMCAIFAmF3BQNuaWwFAWEJAQ1wYXJzZUludFZhbHVlAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQdBZGRyZXNzAQkA2QQBBQJhbgUBbwkArAICCQCsAgIJAKwCAgINVXNlciBhZGRyZXNzIAUCYXcCLSBpcyBub3QgZm91bmQgaW4gYm9vc3RpbmcgY29udHJhY3QgZGF0YSwga2V5PQUBbwECYmEBAmF3CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhSQEFAmF3AAABAmJiAAkAuQkCCQDMCAICAiVzCQDMCAICFHJld2FyZFBlckd3eEludGVncmFsBQNuaWwFAWEBAmJjAAQCYmQCECVzJXNfX2d3eF9fdG90YWwJAJoIAgkBAmFvAAUCYmQBAmJlAQJhdwoBAmJmAQJhdwkAuQkCCQDMCAICFCVzJXNfX2d3eEFtb3VudFRvdGFsCQDMCAIJAKUIAQUCYXcFA25pbAUBYQkAmggCCQECYW8ACQECYmYBBQJhdwECYmcABAJiaAkBC3ZhbHVlT3JFbHNlAgQCYVMJAJ0IAgUEdGhpcwkBAmJiAAMJAAECBQJhUwIGU3RyaW5nBAJhVAUCYVMJAKgDAQUCYVQDCQABAgUCYVMCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgUBZQQCYmkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzCQECYXQACQEBawEJAKwCAgIIaW52YWxpZCAJAQJhdAAEAmJqCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYWEJAQJheAAJAQFrAQkArAICAghpbnZhbGlkIAkBAmF4AAQCYmsJAQt2YWx1ZU9yRWxzZQIJAJoIAgUCYWEJAQJheQAAAAQCYmwJAQt2YWx1ZU9yRWxzZQIJAQJiYwAAAAQCYm0JALYCAQkAZQIFBmhlaWdodAUCYmkEAmJuCQC2AgEFAmJsBAJibwkAtwICBQJiaAMJAAACBQJibgUBZQUBZQkAvAIDBQJibQkAuQICCQC5AgIJALYCAQUCYmoJALYCAQUCYmsFAWkJALkCAgUCYm4FAWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF0AAUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiYgAJAKYDAQUCYm8FA25pbAUCYm8BAmJwAQJhdwkAuQkCCQDMCAICBCVzJXMJAMwIAgIccmV3YXJkUGVyR3d4SW50ZWdyYWxVc2VyTGFzdAkAzAgCCQClCAEFAmF3BQNuaWwFAWEBAmJxAgJhdwJicgQCYnMJAQJiZwAEAmJ0CAUCYnMCXzEEAmJvCAUCYnMCXzIEAmJ1BAJhUwkAnQgCBQR0aGlzCQECYnABBQJhdwMJAAECBQJhUwIGU3RyaW5nBAJhVAUCYVMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBBQJhVAkBAWsBAhppbnZhbGlkIHVzZXIgbGFzdCBpbnRlZ3JhbAMJAAECBQJhUwIEVW5pdAUCYm8JAAIBAgtNYXRjaCBlcnJvcgQCYnYJAJ0IAgkBAmFvAAkBAmF2AQUCYXcEAmJ3CQELdmFsdWVPckVsc2UCCQCfCAEJAQJhQgEFAmJyAAAEAmJ4CQELdmFsdWVPckVsc2UCCQECYmUBBQJhdwAABAJieQkAZAIJAKADAQkAvAIDCQC2AgEFAmJ4CQC4AgIFAmJvBQJidQUBaQUCYncJAJQKAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJicAEFAmF3CQCmAwEFAmJvBQNuaWwFAmJ0BQJieQECYnoBAmJBBAJhdwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmJBCQEBawECFGludmFsaWQgdXNlciBhZGRyZXNzBAJhcAkBAmFrAAQCYnIJAQJhWgIJAJEDAgUCYXAFAmFkBQJiQQQCYkIJAQJicQIFAmF3BQJicgQCYkMIBQJiQgJfMQQCYkQIBQJiQgJfMgkAlAoCBQJiRAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUIBBQJicgAABQNuaWwFAmJDCwJhSAERcmVmcmVzaFVzZXJSZXdhcmQCAmJFAmJyBAJiRgkBAmFzAAMJAAACBQJiRgUCYkYEAmJHAwkAAAIIBQJhSAZjYWxsZXIJAQJhbwAGCQEBbQECEXBlcm1pc3Npb24gZGVuaWVkAwkAAAIFAmJHBQJiRwQCYkgJAQJicQIJAQdBZGRyZXNzAQUCYkUFAmJyBAJiQwgFAmJIAl8xBAJiRAgFAmJIAl8yCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFCAQUCYnIFAmJEBQNuaWwFAmJDBQJiRAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhSAETdHJhZGVSZXdhcmRJbnRlcm5hbAQCYkkCYkoCYksCYkwEAmJGCQECYXMAAwkAAAIFAmJGBQJiRgMJAAACBQJiTAkAkAMBBQJiSgUDbmlsBAJiTQkAzAgCAwkAAAIIBQJhSAZjYWxsZXIFBHRoaXMGCQEBbQECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIDCQBnAgUCYkkJAJEDAgUCYksFAmJMBgkBAW0BAhxpbnN1ZmZpY2llbnQgcGF5bWVudCBhc3NldElkBQNuaWwDCQAAAgUCYk0FAmJNBAJiTgkA/AcEBQR0aGlzAhN0cmFkZVJld2FyZEludGVybmFsCQDMCAIJAGUCBQJiSQkAkQMCBQJiSwUCYkwJAMwIAgUCYkoJAMwIAgUCYksJAMwIAgkAZAIFAmJMAAEFA25pbAUDbmlsAwkAAAIFAmJOBQJiTgQCYk8JAQJhRgIJAJEDAgUCYkoFAmJMBQJhSAQCYXcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYkoFAmJMCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJPCQCRAwIFAmJLBQJiTAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFJAQkAkQMCBQJiSgUCYkwJAJEDAgUCYksFAmJMBQNuaWwFAmJOCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFIARZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5AgJhdwJiUAQCYkYJAQJhcwADCQAAAgUCYkYFAmJGBAJiUQkAnQgCBQJhRQkBAVUBBQJhdwQCYlIDCQAAAgUCYlEFBHVuaXQFBHVuaXQJAPwHBAUCYUUCFnVwZGF0ZVJlZmVycmFsQWN0aXZpdHkJAMwIAgUBSwkAzAgCBQJhdwkAzAgCCQBnAgUCYlAFAU4FA25pbAUDbmlsAwkAAAIFAmJSBQJiUgkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUgBHXByb2Nlc3NQZW5kaW5nUGVyaW9kc0FuZFVzZXJzAAkAlAoCBQNuaWwJAQFtAQIKZGVwcmVjYXRlZAJhSAELY2xhaW1SZXdhcmQABAJiRgkBAmFzAAMJAAACBQJiRgUCYkYEAmFwCQECYWsABAJhdwgFAmFIBmNhbGxlcgQCYkEJAKUIAQUCYXcEAmJTCQECYnoBBQJiQQQCYU0IBQJiUwJfMQQCYkMIBQJiUwJfMgQCYlQDCQBmAgUCYU0AAAYJAAIBAhBub3RoaW5nIHRvIGNsYWltAwkAAAIFAmJUBQJiVAQCYngKAAJiVQkA/AcECQECYW8AAhBnZXRVc2VyR3d4QW1vdW50CQDMCAIFAmJBBQNuaWwFA25pbAMJAAECBQJiVQIDSW50BQJiVQkAAgEJAKwCAgkAAwEFAmJVAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJRCQCdCAIFAmFFCQEBVQEFAmJBBAJiUgMJAAACBQJiUQUEdW5pdAUEdW5pdAkA/AcEBQJhRQIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCBQFLCQDMCAIFAmF3CQDMCAIJAGcCBQJieAUBTgUDbmlsBQNuaWwDCQAAAgUCYlIFAmJSBAJiVgMDCQAAAgUCYlEFBHVuaXQGCQBmAgUBTgUCYngFBHVuaXQEAmJXCQBrAwUCYU0FAVEFAWIEAmJYCQBrAwUCYU0FAVQFAWIJAPwHBAUCYUUCDGluY1VuY2xhaW1lZAkAzAgCBQFLCQDMCAIFAmF3CQDMCAIFAmJXCQDMCAIFAmJYBQNuaWwFA25pbAMJAAACBQJiVgUCYlYEAmJZCQD8BwQFAmFhAgRlbWl0CQDMCAIFAmFNBQNuaWwFA25pbAMJAAACBQJiWQUCYlkEAmJaCgACYlUJAPwHBAUCYUUCBWNsYWltCQDMCAIFAUsFA25pbAUDbmlsAwkAAQIFAmJVAgNJbnQFAmJVCQACAQkArAICCQADAQUCYlUCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAMJAAACBQJiWgUCYloEAmNhCQBkAgUCYU0FAmJaCQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCYUgGY2FsbGVyBQJhTQUCYWoJAMwIAgkBAmFLBAIFY2xhaW0FAmJBBQJjYQUCYUgFA25pbAUCYkMFAmNhCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFIARNjbGFpbVJld2FyZFJFQURPTkxZAQJjYgQCY2MJAQJiegEFAmNiBAJhTQgFAmNjAl8xBAJiQwgFAmNjAl8yBAJjZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQJhRQkBAVcCBQFLBQJjYgAABAJjYQkAZAIFAmFNBQJjZAkAlAoCBQNuaWwFAmNhAmFIARVvbkVtaXNzaW9uRm9yR3d4U3RhcnQABAJiRgkBAmFzAAMJAAACBQJiRgUCYkYDCQECIT0CCAUCYUgGY2FsbGVyBQFDCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXQABQZoZWlnaHQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhSAELdHJhZGVSZXdhcmQCAmJKAmJLBAJiRgkBAmFzAAMJAAACBQJiRgUCYkYEAmNlCQAAAgkAkAMBBQJiSgkAkAMBBQJiSwQCY2YJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmFKAAAABAJjZwkAkQMCCAUCYUgIcGF5bWVudHMAAAQCY2gIBQJjZwdhc3NldElkBAJjaQgFAmNnBmFtb3VudAQCYk0JAMwIAgMJAGcCBQJjZgkAkAMBBQJiSgYJAQFtAQITVG9vIG1hbnkgcmVjaXBpZW50cwkAzAgCAwUCY2UGCQEBbQECF0FyZ3VtZW50cyBzaXplIG1pc21hdGNoCQDMCAIDCQAAAgUCY2gFAmFqBgkBAW0BAhNXcm9uZyBhc3NldCBwYXltZW50BQNuaWwDCQAAAgUCYk0FAmJNBAJiTgkA/AcEBQR0aGlzAhN0cmFkZVJld2FyZEludGVybmFsCQDMCAIFAmNpCQDMCAIFAmJKCQDMCAIFAmJLCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUCYk4FAmJOCQCUCgIFA25pbAUCYk4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUgBEmNsYWltVHJhZGluZ1Jld2FyZAAEAmJGCQECYXMAAwkAAAIFAmJGBQJiRgQCYXcIBQJhSAZjYWxsZXIEAmNqCQClCAEFAmF3BAJiRAkBAmJhAQUCY2oDCQBmAgUCYkQAAAkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmF3BQJiRAUCYWoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhSQEFAmNqAAAFA25pbAUCYkQJAQFtAQIQbm90aGluZyB0byBjbGFpbQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhSAEaY2xhaW1UcmFkaW5nUmV3YXJkUkVBRE9OTFkBAmF3CQCUCgIFA25pbAkBAmJhAQUCYXcCYUgBB3N1c3BlbmQBAmNrBAJiRwkBAmFXAQUCYUgDCQAAAgUCYkcFAmJHCQCUCgIJAMwIAgkBDEJvb2xlYW5FbnRyeQIFAmFxBQJjawUDbmlsBQJjawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY2wBAmNtAAQCY24EAmFTCQECYVUAAwkAAQIFAmFTAgpCeXRlVmVjdG9yBAJhWQUCYVMFAmFZAwkAAQIFAmFTAgRVbml0CAUCY2wPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmNsCWJvZHlCeXRlcwkAkQMCCAUCY2wGcHJvb2ZzAAAFAmNuZJQbEQ==", "height": 2744785, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: F4PAPxf4h7YMvKLURBZ1CyHMnE6S2NX29goD5Cu16nES Next: 46yv6uQ4T326oMZV2cvv4KdAjfKR9MQNGh3dZ7nGhYR7 Diff:
OldNewDifferences
77
88 let MULT8 = 100000000
99
10+let MULT8BI = toBigInt(MULT8)
11+
1012 let zeroBigInt = toBigInt(0)
1113
1214 let processingStageTotal = 0
1315
1416 let processingStageShares = 1
1517
18+let MULT18 = 1000000000000000000
19+
20+let MULT18BI = toBigInt(MULT18)
21+
1622 let wavesString = "WAVES"
23+
24+func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
25+
26+
27+func throwErr (msg) = throw(wrapErr(msg))
28+
1729
1830 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
1931
2032
21-func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
33+func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
2234
2335
2436 func getStringByKey (key) = valueOrElse(getString(this, key), "")
2537
2638
27-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
39+func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
2840
2941
3042 func parseAssetId (input) = if ((input == wavesString))
3143 then unit
3244 else fromBase58String(input)
33-
34-
35-func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
36-
37-
38-func throwErr (msg) = throw(wrapErr(msg))
3945
4046
4147 func abs (val) = if ((0 > val))
138144 }
139145
140146
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+
141156 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
142157
143158
144159 func keyUsersCount () = "%s__nextUserNum"
160+
161+
162+func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", toString(userAddress)], SEP)
145163
146164
147165 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
156174 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
157175
158176
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-
174177 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)
211178
212179
213180 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
275242 }
276243
277244
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-
325245 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
326246 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
327247 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
328248 }
329249
330250
331-func nextPeriod () = getNumberByKey(keyNextPeriod())
251+func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
332252
333253
334-func commonClaimReward (userAddress) = {
335- let cfgArray = readConfigArrayOrFail()
336- let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337- let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338- match userUnclaimedOption {
254+func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
255+
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)
339274 case _: Unit =>
340- $Tuple2(0, nil)
341- case u: Int =>
342- $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
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
343304 case _ =>
344305 throw("Match error")
345306 }
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)
346312 }
347313
348314
349-func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
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+ }
350324
351325
352326 @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- }
374-
375-
376-
377-@Callable(i)
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)
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+ }
385343 else throw("Strict value is not equal to itself.")
386344 }
387345
388346
389347
390348 @Callable(i)
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)
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.")
412372 }
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)
469373 else throw("Strict value is not equal to itself.")
470374 }
471375
472376
473377
474378 @Callable(i)
475-func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
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+ }
476393
477394
478395
479396 @Callable(i)
480-func deposit () = {
481- let checkCaller = if ((i.caller == votingEmissionContract))
482- then true
483- else mustManager(i)
484- if ((checkCaller == checkCaller))
397+func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
398+
399+
400+
401+@Callable(i)
402+func claimReward () = {
403+ let suspensionCheck = throwIfSuspended()
404+ if ((suspensionCheck == suspensionCheck))
485405 then {
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))
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))
491416 then {
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))
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))
497428 then {
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))
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))
507439 then {
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)
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.")
515457 }
516458 else throw("Strict value is not equal to itself.")
517459 }
525467
526468
527469 @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)
555470 func claimRewardREADONLY (address) = {
556- let $t02043820488 = commonClaimReward(address)
557- let amount = $t02043820488._1
558- let actions = $t02043820488._2
471+ let $t01542315473 = commonClaimReward(address)
472+ let amount = $t01542315473._1
473+ let actions = $t01542315473._2
559474 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
560475 let totalAmount = (amount + referralUnclaimed)
561476 $Tuple2(nil, totalAmount)
564479
565480
566481 @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)
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- }
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.")
665489 }
666490
667491
668492
669493 @Callable(i)
670494 func tradeReward (userAddresses,rewards) = {
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))
495+ let suspensionCheck = throwIfSuspended()
496+ if ((suspensionCheck == suspensionCheck))
684497 then {
685- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
686- if ((tradeRewardInternal == tradeRewardInternal))
687- then $Tuple2(nil, tradeRewardInternal)
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+ }
688517 else throw("Strict value is not equal to itself.")
689518 }
690519 else throw("Strict value is not equal to itself.")
694523
695524 @Callable(i)
696525 func claimTradingReward () = {
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")
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.")
703537 }
704538
705539
706540
707541 @Callable(i)
708542 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+ }
709553
710554
711555 @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+
1012 let zeroBigInt = toBigInt(0)
1113
1214 let processingStageTotal = 0
1315
1416 let processingStageShares = 1
1517
18+let MULT18 = 1000000000000000000
19+
20+let MULT18BI = toBigInt(MULT18)
21+
1622 let wavesString = "WAVES"
23+
24+func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
25+
26+
27+func throwErr (msg) = throw(wrapErr(msg))
28+
1729
1830 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
1931
2032
21-func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
33+func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
2234
2335
2436 func getStringByKey (key) = valueOrElse(getString(this, key), "")
2537
2638
27-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
39+func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), wrapErr((("mandatory this." + key) + " is not defined")))
2840
2941
3042 func parseAssetId (input) = if ((input == wavesString))
3143 then unit
3244 else fromBase58String(input)
33-
34-
35-func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
36-
37-
38-func throwErr (msg) = throw(wrapErr(msg))
3945
4046
4147 func abs (val) = if ((0 > val))
4248 then -(val)
4349 else val
4450
4551
4652 func absBigInt (val) = if ((zeroBigInt > val))
4753 then -(val)
4854 else val
4955
5056
5157 let keyMaxDepth = "%s__maxDepth"
5258
5359 let maxDepthDefault = 30
5460
5561 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
5662
5763 func keyFactoryAddress () = "%s%s__config__factoryAddress"
5864
5965
6066 let factoryAddressStr = getStringOrFail(keyFactoryAddress())
6167
6268 let factoryContract = addressFromStringValue(factoryAddressStr)
6369
6470 func keyEmissionAddress () = "%s%s__config__emissionAddress"
6571
6672
6773 func keyVotingEmissionContract () = makeString(["%s", "votingEmissionContract"], SEP)
6874
6975
7076 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract()))
7177
7278 func keyNumToUserMapping (num) = makeString(["%s%s%s", "mapping", "num2user", toString(num)], SEP)
7379
7480
7581 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
7682
7783 let referralProgramNameDefault = "wxlock"
7884
7985 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
8086
8187 let keyReferralMinGWxAmount = makeString(["%s%s", "referral", "minGWxAmount"], SEP)
8288
8389 let referralMinGWxAmountDefault = (500 * MULT8)
8490
8591 let referralMinGWxAmount = valueOrElse(getInteger(this, keyReferralMinGWxAmount), referralMinGWxAmountDefault)
8692
8793 let keyReferrerRewardPermille = makeString(["%s%s", "referral", "referrerRewardPermille"], SEP)
8894
8995 let referrerRewardPermilleDefault = 50
9096
9197 let referrerRewardPermille = valueOrElse(getInteger(this, keyReferrerRewardPermille), referrerRewardPermilleDefault)
9298
9399 let keyReferralRewardPermille = makeString(["%s%s", "referral", "referralRewardPermille"], SEP)
94100
95101 let referralRewardPermilleDefault = 50
96102
97103 let referralRewardPermille = valueOrElse(getInteger(this, keyReferralRewardPermille), referralRewardPermilleDefault)
98104
99105 func keyReferrer (referralAddress) = makeString(["%s%s%s", "referrer", referralProgramName, referralAddress], SEP)
100106
101107
102108 func keyUnclaimedReferral (programName,claimerAddress) = makeString(["%s%s%s", "unclaimedReferral", programName, claimerAddress], SEP)
103109
104110
105111 let emissionAddressStr = getStringOrFail(keyEmissionAddress())
106112
107113 let emissionContract = addressFromStringValue(emissionAddressStr)
108114
109115 let IdxCfgAssetId = 1
110116
111117 let IdxCfgPacemakerAddress = 2
112118
113119 let IdxCfgBoostingContract = 3
114120
115121 let IdxCfgMaxDepth = 4
116122
117123 func keyConfig () = "%s__config"
118124
119125
120126 func getEmissionAddress () = addressFromStringValue(valueOrErrorMessage(getString(this, keyEmissionAddress()), (("mandatory this." + keyEmissionAddress()) + " is not defined")))
121127
122128
123129 let emissionAddress = getEmissionAddress()
124130
125131 let wxAssetIdStr = split(value(getString(emissionAddress, keyConfig())), SEP)[1]
126132
127133 let wxAssetId = fromBase58String(wxAssetIdStr)
128134
129135 func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP)
130136
131137
132138 func formatConfig (wxAssetIdStr,matcherPacemakerAddressStr,boostingContractAddressStr,maxDepth) = makeString(["%s%s%s%d", wxAssetIdStr, matcherPacemakerAddressStr, boostingContractAddressStr, toString(maxDepth)], SEP)
133139
134140
135141 func boostingContractOrFail () = {
136142 let cfgArray = readConfigArrayOrFail()
137143 valueOrErrorMessage(addressFromString(cfgArray[IdxCfgBoostingContract]), "boosting contract address is not defined")
138144 }
139145
140146
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+
141156 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
142157
143158
144159 func keyUsersCount () = "%s__nextUserNum"
160+
161+
162+func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", toString(userAddress)], SEP)
145163
146164
147165 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
148166
149167
150168 func keyGwxHoldersRewardCurrent () = "%s%s__gwxHoldersReward__current"
151169
152170
153171 func keyGwxHoldersRewardNext () = "%s%s__gwxHoldersReward__next"
154172
155173
156174 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
157175
158176
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-
174177 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)
211178
212179
213180 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
214181
215182
216183 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(keyReferralsContractAddress()))
217184
218185 func keyTradingRewardHistory (user,i) = makeString(["%s%s%s%s", "tradingReward", "history", user, toBase58String(i.transactionId)], SEP)
219186
220187
221188 func keyTradingReward (userAddress) = makeString(["%s%s", "tradingReward", userAddress], SEP)
222189
223190
224191 func keyMaxRecipients () = makeString(["%s", "maxRecipients"], SEP)
225192
226193
227194 func HistoryEntry (type,user,amount,i) = {
228195 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
229196 let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount)], SEP)
230197 StringEntry(historyKEY, historyDATA)
231198 }
232199
233200
234201 func keyManagerPublicKey () = "%s__managerPublicKey"
235202
236203
237204 func keyManagerVaultAddress () = "%s__managerVaultAddress"
238205
239206
240207 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
241208 case s: String =>
242209 addressFromStringValue(s)
243210 case _ =>
244211 this
245212 }
246213
247214
248215 func managerPublicKeyOrUnit () = {
249216 let managerVaultAddress = getManagerVaultAddressOrThis()
250217 match getString(managerVaultAddress, keyManagerPublicKey()) {
251218 case s: String =>
252219 fromBase58String(s)
253220 case _: Unit =>
254221 unit
255222 case _ =>
256223 throw("Match error")
257224 }
258225 }
259226
260227
261228 func mustManager (i) = {
262229 let pd = throw("Permission denied")
263230 match managerPublicKeyOrUnit() {
264231 case pk: ByteVector =>
265232 if ((i.callerPublicKey == pk))
266233 then true
267234 else pd
268235 case _: Unit =>
269236 if ((i.caller == this))
270237 then true
271238 else pd
272239 case _ =>
273240 throw("Match error")
274241 }
275242 }
276243
277244
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-
325245 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
326246 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
327247 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
328248 }
329249
330250
331-func nextPeriod () = getNumberByKey(keyNextPeriod())
251+func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
332252
333253
334-func commonClaimReward (userAddress) = {
335- let cfgArray = readConfigArrayOrFail()
336- let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337- let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338- match userUnclaimedOption {
254+func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
255+
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)
339274 case _: Unit =>
340- $Tuple2(0, nil)
341- case u: Int =>
342- $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
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
343304 case _ =>
344305 throw("Match error")
345306 }
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)
346312 }
347313
348314
349-func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
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+ }
350324
351325
352326 @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- }
374-
375-
376-
377-@Callable(i)
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)
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+ }
385343 else throw("Strict value is not equal to itself.")
386344 }
387345
388346
389347
390348 @Callable(i)
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)
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.")
412372 }
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)
469373 else throw("Strict value is not equal to itself.")
470374 }
471375
472376
473377
474378 @Callable(i)
475-func processPendingPeriodsAndUsers () = $Tuple2(nil, invoke(this, "finalizeWrapper", [maxDepth], nil))
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+ }
476393
477394
478395
479396 @Callable(i)
480-func deposit () = {
481- let checkCaller = if ((i.caller == votingEmissionContract))
482- then true
483- else mustManager(i)
484- if ((checkCaller == checkCaller))
397+func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
398+
399+
400+
401+@Callable(i)
402+func claimReward () = {
403+ let suspensionCheck = throwIfSuspended()
404+ if ((suspensionCheck == suspensionCheck))
485405 then {
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))
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))
491416 then {
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))
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))
497428 then {
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))
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))
507439 then {
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)
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.")
515457 }
516458 else throw("Strict value is not equal to itself.")
517459 }
518460 else throw("Strict value is not equal to itself.")
519461 }
520462 else throw("Strict value is not equal to itself.")
521463 }
522464 else throw("Strict value is not equal to itself.")
523465 }
524466
525467
526468
527469 @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)
555470 func claimRewardREADONLY (address) = {
556- let $t02043820488 = commonClaimReward(address)
557- let amount = $t02043820488._1
558- let actions = $t02043820488._2
471+ let $t01542315473 = commonClaimReward(address)
472+ let amount = $t01542315473._1
473+ let actions = $t01542315473._2
559474 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
560475 let totalAmount = (amount + referralUnclaimed)
561476 $Tuple2(nil, totalAmount)
562477 }
563478
564479
565480
566481 @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)
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- }
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.")
665489 }
666490
667491
668492
669493 @Callable(i)
670494 func tradeReward (userAddresses,rewards) = {
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))
495+ let suspensionCheck = throwIfSuspended()
496+ if ((suspensionCheck == suspensionCheck))
684497 then {
685- let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
686- if ((tradeRewardInternal == tradeRewardInternal))
687- then $Tuple2(nil, tradeRewardInternal)
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+ }
688517 else throw("Strict value is not equal to itself.")
689518 }
690519 else throw("Strict value is not equal to itself.")
691520 }
692521
693522
694523
695524 @Callable(i)
696525 func claimTradingReward () = {
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")
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.")
703537 }
704538
705539
706540
707541 @Callable(i)
708542 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+ }
709553
710554
711555 @Verifier(tx)
712556 func verify () = {
713557 let targetPublicKey = match managerPublicKeyOrUnit() {
714558 case pk: ByteVector =>
715559 pk
716560 case _: Unit =>
717561 tx.senderPublicKey
718562 case _ =>
719563 throw("Match error")
720564 }
721565 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
722566 }
723567

github/deemru/w8io/026f985 
76.08 ms