tx · 9zo1J28X6gnXZXw5PmvdzWGFXxG6N2quZEoyMsQegPw2

3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE:  -0.01500000 Waves

2023.08.08 13:08 [2701486] smart account 3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE > SELF 0.00000000 Waves

{ "type": 13, "id": "9zo1J28X6gnXZXw5PmvdzWGFXxG6N2quZEoyMsQegPw2", "fee": 1500000, "feeAssetId": null, "timestamp": 1691489303319, "version": 2, "chainId": 84, "sender": "3Mp5kisFrqESzrXxAMEPk2k69zpeF41czEE", "senderPublicKey": "G349Uq3FTox7dRNLeAfAQeoACvwZ9iEnVSaHcEYn6j8J", "proofs": [ "5hbNWh7Jaepd3JdxxioD8f8TgGxkajKWZJM9AUP2aweHdxa8tqGCJPzkkkXjb59jgvdWqYFS1wwVWjym3kJpxdqj" ], "script": "base64:BgL8FAgCEgMKAQISBgoEARgRARIECgIIARIAEgASAwoBCBIAEgQKAhgREgASAwoBCCIDU0VQIgVTQ0FMRSIFTVVMVDgiCnplcm9CaWdJbnQiFHByb2Nlc3NpbmdTdGFnZVRvdGFsIhVwcm9jZXNzaW5nU3RhZ2VTaGFyZXMiBk1VTFQxOCIITVVMVDE4QkkiC3dhdmVzU3RyaW5nIg5nZXROdW1iZXJCeUtleSIDa2V5Ig9nZXROdW1iZXJPckZhaWwiDmdldFN0cmluZ0J5S2V5Ig9nZXRTdHJpbmdPckZhaWwiDHBhcnNlQXNzZXRJZCIFaW5wdXQiB3dyYXBFcnIiA21zZyIIdGhyb3dFcnIiA2FicyIDdmFsIglhYnNCaWdJbnQiC2tleU1heERlcHRoIg9tYXhEZXB0aERlZmF1bHQiCG1heERlcHRoIhFrZXlGYWN0b3J5QWRkcmVzcyIRZmFjdG9yeUFkZHJlc3NTdHIiD2ZhY3RvcnlDb250cmFjdCISa2V5RW1pc3Npb25BZGRyZXNzIhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0IhNrZXlOdW1Ub1VzZXJNYXBwaW5nIgNudW0iFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUiGnJlZmVycmFsUHJvZ3JhbU5hbWVEZWZhdWx0IhNyZWZlcnJhbFByb2dyYW1OYW1lIhdrZXlSZWZlcnJhbE1pbkdXeEFtb3VudCIbcmVmZXJyYWxNaW5HV3hBbW91bnREZWZhdWx0IhRyZWZlcnJhbE1pbkdXeEFtb3VudCIZa2V5UmVmZXJyZXJSZXdhcmRQZXJtaWxsZSIdcmVmZXJyZXJSZXdhcmRQZXJtaWxsZURlZmF1bHQiFnJlZmVycmVyUmV3YXJkUGVybWlsbGUiGWtleVJlZmVycmFsUmV3YXJkUGVybWlsbGUiHXJlZmVycmFsUmV3YXJkUGVybWlsbGVEZWZhdWx0IhZyZWZlcnJhbFJld2FyZFBlcm1pbGxlIgtrZXlSZWZlcnJlciIPcmVmZXJyYWxBZGRyZXNzIhRrZXlVbmNsYWltZWRSZWZlcnJhbCILcHJvZ3JhbU5hbWUiDmNsYWltZXJBZGRyZXNzIhJlbWlzc2lvbkFkZHJlc3NTdHIiEGVtaXNzaW9uQ29udHJhY3QiDUlkeENmZ0Fzc2V0SWQiFklkeENmZ1BhY2VtYWtlckFkZHJlc3MiFklkeENmZ0Jvb3N0aW5nQ29udHJhY3QiDklkeENmZ01heERlcHRoIglrZXlDb25maWciEmdldEVtaXNzaW9uQWRkcmVzcyIPZW1pc3Npb25BZGRyZXNzIgx3eEFzc2V0SWRTdHIiCXd4QXNzZXRJZCIVcmVhZENvbmZpZ0FycmF5T3JGYWlsIgxmb3JtYXRDb25maWciGm1hdGNoZXJQYWNlbWFrZXJBZGRyZXNzU3RyIhpib29zdGluZ0NvbnRyYWN0QWRkcmVzc1N0ciIWYm9vc3RpbmdDb250cmFjdE9yRmFpbCIIY2ZnQXJyYXkiH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQiDWtleVVzZXJzQ291bnQiFmtleVJhdGVQZXJCbG9ja0N1cnJlbnQiGmtleUd3eEhvbGRlcnNSZXdhcmRDdXJyZW50IhdrZXlHd3hIb2xkZXJzUmV3YXJkTmV4dCIUa2V5UG9vbFdlaWdodFZpcnR1YWwiEGtleVVzZXJVbmNsYWltZWQiCXVzZXJJbmRleCIba2V5UmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzIh5yZWZlcnJhbHNDb250cmFjdEFkZHJlc3NPckZhaWwiF2tleVRyYWRpbmdSZXdhcmRIaXN0b3J5IgR1c2VyIgFpIhBrZXlUcmFkaW5nUmV3YXJkIgt1c2VyQWRkcmVzcyIQa2V5TWF4UmVjaXBpZW50cyIMSGlzdG9yeUVudHJ5IgR0eXBlIgZhbW91bnQiCmhpc3RvcnlLRVkiC2hpc3RvcnlEQVRBIhNrZXlNYW5hZ2VyUHVibGljS2V5IhZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzIhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIgckbWF0Y2gwIgFzIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIgttdXN0TWFuYWdlciICcGQiAnBrIhVnZXRVc2VySW5kZXhCeUFkZHJlc3MiEWNvbW1vbkNsYWltUmV3YXJkIgd1c2VySWR4IhN1c2VyVW5jbGFpbWVkT3B0aW9uIgF1IhBnZXRUcmFkaW5nUmV3YXJkIhdrZXlSZXdhcmRQZXJHd3hJbnRlZ3JhbCIcX3JlZnJlc2hSZXdhcmRQZXJHd3hJbnRlZ3JhbCIccmV3YXJkUGVyR3d4SW50ZWdyYWxQcmV2aW91cyIecmV3YXJkUGVyR3d4SW50ZWdyYWxMYXN0SGVpZ2h0IgxlbWlzc2lvblJhdGUiF2d3eEhvbGRlcnNSZXdhcmRDdXJyZW50Ig5nd3hBbW91bnRUb3RhbCIBQCICZGgiFHJld2FyZFBlckd3eEludGVncmFsIh9rZXlSZXdhcmRQZXJHd3hJbnRlZ3JhbFVzZXJMYXN0IhJfcmVmcmVzaFVzZXJSZXdhcmQiHHJld2FyZFBlckd3eEludGVncmFsVXNlckxhc3QiDXVzZXJJZHhPckZhaWwiDXVzZXJVbmNsYWltZWQiDSR0MDEwMzA0MTA1MjEiG3Jld2FyZFBlckd3eEludGVncmFsQWN0aW9ucyINdXNlckd3eEFtb3VudCIKdXNlclJld2FyZCIQdXNlckFkZHJlc3NCeXRlcyILY2hlY2tDYWxsZXIiFXBheW1lbnRBbW91bnRMZWZ0T3ZlciINdXNlckFkZHJlc3NlcyIHcmV3YXJkcyILY3VycmVudEl0ZXIiBmNoZWNrcyITdHJhZGVSZXdhcmRJbnRlcm5hbCIXdHJhZGluZ1Jld2FyZEhpc3RvcnlLZXkiDmdXeEFtb3VudFN0YXJ0IghyZWZlcnJlciIRYWN0aXZlUmVmZXJyYWxJbnYiDnVzZXJBZGRyZXNzU3RyIg0kdDAxMjgzMjEyODg5IgdhY3Rpb25zIgtjaGVja0Ftb3VudCILcmVmZXJyYWxJbnYiDnJlZmVycmVyUmV3YXJkIg5yZWZlcnJhbFJld2FyZCIPY2xhaW1lZFJlZmVycmFsIgt0b3RhbEFtb3VudCIHYWRkcmVzcyINJHQwMTQyMTYxNDI2NiIRcmVmZXJyYWxVbmNsYWltZWQiDmFyZ3NDb21wYXJpc29uIg1tYXhSZWNpcGllbnRzIgdwYXltZW50Ig5wYXltZW50QXNzZXRJZCINcGF5bWVudEFtb3VudCIRdXNlckFkZHJlc3NTdHJpbmciBnJld2FyZCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5UQABYQICX18AAWIA6AcAAWMAgMLXLwABZAkAtgIBAAAAAWUAAAABZgABAAFnAICAkLu61q3wDQABaAkAtgIBBQFnAAFpAgVXQVZFUwEBagEBawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrAAABAWwBAWsJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQFrCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQFrAg8gaXMgbm90IGRlZmluZWQBAW0BAWsJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUBawIAAQFuAQFrCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUBawkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBawIPIGlzIG5vdCBkZWZpbmVkAQFvAQFwAwkAAAIFAXAFAWkFBHVuaXQJANkEAQUBcAEBcQEBcgkAuQkCCQDMCAICEGd3eF9yZXdhcmQucmlkZToJAMwIAgUBcgUDbmlsAgEgAQFzAQFyCQACAQkBAXEBBQFyAQF0AQF1AwkAZgIAAAUBdQkBAS0BBQF1BQF1AQF2AQF1AwkAvwICBQFkBQF1CQC+AgEFAXUFAXUAAXcCDCVzX19tYXhEZXB0aAABeAAeAAF5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAXcFAXgBAXoAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzAAFBCQEBbgEJAQF6AAABQgkBEUBleHRyTmF0aXZlKDEwNjIpAQUBQQEBQwACHSVzJXNfX2NvbmZpZ19fZW1pc3Npb25BZGRyZXNzAQFEAAkAuQkCCQDMCAICAiVzCQDMCAICFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QFA25pbAUBYQABRQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUBQgkBAUQAAQFGAQFHCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICB21hcHBpbmcJAMwIAgIIbnVtMnVzZXIJAMwIAgkApAMBBQFHBQNuaWwFAWEAAUgJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICC3Byb2dyYW1OYW1lBQNuaWwFAWEAAUkCBnd4bG9jawABSgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFIBQFJAAFLCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghyZWZlcnJhbAkAzAgCAgxtaW5HV3hBbW91bnQFA25pbAUBYQABTAkAaAIA9AMFAWMAAU0JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBSwUBTAABTgkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgIWcmVmZXJyZXJSZXdhcmRQZXJtaWxsZQUDbmlsBQFhAAFPADIAAVAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBTgUBTwABUQkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgIWcmVmZXJyYWxSZXdhcmRQZXJtaWxsZQUDbmlsBQFhAAFSADIAAVMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBUQUBUgEBVAEBVQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAghyZWZlcnJlcgkAzAgCBQFKCQDMCAIFAVUFA25pbAUBYQEBVgIBVwFYCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICEXVuY2xhaW1lZFJlZmVycmFsCQDMCAIFAVcJAMwIAgUBWAUDbmlsBQFhAAFZCQEBbgEJAQFDAAABWgkBEUBleHRyTmF0aXZlKDEwNjIpAQUBWQACYWEAAQACYWIAAgACYWMAAwACYWQABAECYWUAAgolc19fY29uZmlnAQJhZgAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQEBQwAJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4JAQFDAAIPIGlzIG5vdCBkZWZpbmVkAAJhZwkBAmFmAAACYWgJAJEDAgkAtQkCCQEFdmFsdWUBCQCdCAIFAmFnCQECYWUABQFhAAEAAmFpCQDZBAEFAmFoAQJhagAJALUJAgkBAW4BCQECYWUABQFhAQJhawQCYWgCYWwCYW0BeQkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAIFAmFoCQDMCAIFAmFsCQDMCAIFAmFtCQDMCAIJAKQDAQUBeQUDbmlsBQFhAQJhbgAEAmFvCQECYWoACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJhbwUCYWMCKGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MgaXMgbm90IGRlZmluZWQBAmFwAAIoJXMlc19fZ3d4UmV3YXJkRW1pc3Npb25QYXJ0X19zdGFydEhlaWdodAECYXEAAg8lc19fbmV4dFVzZXJOdW0BAmFyAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhcwACHyVzJXNfX2d3eEhvbGRlcnNSZXdhcmRfX2N1cnJlbnQBAmF0AAIcJXMlc19fZ3d4SG9sZGVyc1Jld2FyZF9fbmV4dAECYXUAAiAlcyVzX19wb29sV2VpZ2h0X19HV1h2aXJ0dWFsUE9PTAECYXYBAmF3CQC5CQIJAMwIAgIEJXMlZAkAzAgCAg11c2VyVW5jbGFpbWVkCQDMCAIJAKQDAQUCYXcFA25pbAUBYQECYXgACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgZjb25maWcJAMwIAgIYcmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzBQNuaWwFAWEAAmF5CQERQGV4dHJOYXRpdmUoMTA2MikBCQEBbgEJAQJheAABAmF6AgJhQQJhQgkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAICDXRyYWRpbmdSZXdhcmQJAMwIAgIHaGlzdG9yeQkAzAgCBQJhQQkAzAgCCQDYBAEIBQJhQg10cmFuc2FjdGlvbklkBQNuaWwFAWEBAmFDAQJhRAkAuQkCCQDMCAICBCVzJXMJAMwIAgINdHJhZGluZ1Jld2FyZAkAzAgCBQJhRAUDbmlsBQFhAQJhRQAJALkJAgkAzAgCAgIlcwkAzAgCAg1tYXhSZWNpcGllbnRzBQNuaWwFAWEBAmFGBAJhRwJhQQJhSAJhQgQCYUkJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQJhRwkAzAgCBQJhQQkAzAgCCQDYBAEIBQJhQg10cmFuc2FjdGlvbklkBQNuaWwFAWEEAmFKCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFAmFIBQNuaWwFAWEJAQtTdHJpbmdFbnRyeQIFAmFJBQJhSgECYUsAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYUwAAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwECYU0ABAJhTgkAoggBCQECYUwAAwkAAQIFAmFOAgZTdHJpbmcEAmFPBQJhTgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYU8FBHRoaXMBAmFQAAQCYVEJAQJhTQAEAmFOCQCdCAIFAmFRCQECYUsAAwkAAQIFAmFOAgZTdHJpbmcEAmFPBQJhTgkA2QQBBQJhTwMJAAECBQJhTgIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJhUgECYUIEAmFTCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmFOCQECYVAAAwkAAQIFAmFOAgpCeXRlVmVjdG9yBAJhVAUCYU4DCQAAAggFAmFCD2NhbGxlclB1YmxpY0tleQUCYVQGBQJhUwMJAAECBQJhTgIEVW5pdAMJAAACCAUCYUIGY2FsbGVyBQR0aGlzBgUCYVMJAAIBAgtNYXRjaCBlcnJvcgECYVUCAmFtAmFEBAFrCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICB21hcHBpbmcJAMwIAgIIdXNlcjJudW0JAMwIAgUCYUQFA25pbAUBYQkBDXBhcnNlSW50VmFsdWUBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBB0FkZHJlc3MBCQDZBAEFAmFtBQFrCQCsAgIJAKwCAgkArAICAg1Vc2VyIGFkZHJlc3MgBQJhRAItIGlzIG5vdCBmb3VuZCBpbiBib29zdGluZyBjb250cmFjdCBkYXRhLCBrZXk9BQFrAQJhVgECYUQEAmFvCQECYWoABAJhVwkBAmFVAgkAkQMCBQJhbwUCYWMFAmFEBAJhWAkAnwgBCQECYXYBBQJhVwQCYU4FAmFYAwkAAQIFAmFOAgRVbml0CQCUCgIAAAUDbmlsAwkAAQIFAmFOAgNJbnQEAmFZBQJhTgkAlAoCBQJhWQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF2AQUCYVcAAAUDbmlsCQACAQILTWF0Y2ggZXJyb3IBAmFaAQJhRAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYUMBBQJhRAAAAQJiYQAJALkJAgkAzAgCAgIlcwkAzAgCAhRyZXdhcmRQZXJHd3hJbnRlZ3JhbAUDbmlsBQFhAQJiYgAEAmJjCQELdmFsdWVPckVsc2UCBAJhTgkAnQgCBQR0aGlzCQECYmEAAwkAAQIFAmFOAgZTdHJpbmcEAmFPBQJhTgkAqAMBBQJhTwMJAAECBQJhTgIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yBQFkBAJiZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMJAQJhcAAJAQFxAQkArAICAghpbnZhbGlkIAkBAmFwAAQCYmUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFaCQECYXIACQEBcQEJAKwCAgIIaW52YWxpZCAJAQJhcgAEAmJmCQELdmFsdWVPckVsc2UCCQCaCAIFAVoJAQJhcwAAAAQCYmcKAAJiaAkA/AcECQECYW4AAhNnZXRHd3hUb3RhbFJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJiaAIDSW50BQJiaAkAAgEJAKwCAgkAAwEFAmJoAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJpCQC2AgEJAGUCBQZoZWlnaHQFAmJkBAJiagkAtwICBQJiYwkAvAIDBQJiaQkAuQICCQC5AgIJALYCAQUCYmUJALYCAQUCYmYFAWgJALYCAQUCYmcJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFwAAUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiYQAJAKYDAQUCYmoFA25pbAUCYmoBAmJrAQJhRAkAuQkCCQDMCAICBCVzJXMJAMwIAgIccmV3YXJkUGVyR3d4SW50ZWdyYWxVc2VyTGFzdAkAzAgCCQClCAEFAmFEBQNuaWwFAWEBAmJsAQJhRAQCYm0JAQt2YWx1ZU9yRWxzZQIEAmFOCQCdCAIFBHRoaXMJAQJiawEFAmFEAwkAAQIFAmFOAgZTdHJpbmcEAmFPBQJhTgkAqAMBBQJhTwMJAAECBQJhTgIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yBQFkBAJibgkBAmFVAgkApQgBCQECYW4ACQClCAEFAmFEBAJibwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXYBBQJibgAABAJicAkBAmJiAAQCYnEIBQJicAJfMQQCYmoIBQJicAJfMgQCYnIKAAJiaAkA/AcECQECYW4AAhBnZXRVc2VyR3d4QW1vdW50CQDMCAIJAKUIAQUCYUQFA25pbAUDbmlsAwkAAQIFAmJoAgNJbnQFAmJoCQACAQkArAICCQADAQUCYmgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYnMJAGQCCQCgAwEJALwCAwkAtgIBBQJicgkAuAICBQJiagUCYm0FAWgFAmJvCQCUCgIJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYmsBBQJhRAkApgMBBQJiagUDbmlsBQJicQUCYnMKAmFCARFyZWZyZXNoVXNlclJld2FyZAECYnQEAmJ1AwkAAAIIBQJhQgZjYWxsZXIJAQJhbgAGCQEBcwECEXBlcm1pc3Npb24gZGVuaWVkAwkAAAIFAmJ1BQJidQkBAmJsAQkBB0FkZHJlc3MBBQJidAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhQgETdHJhZGVSZXdhcmRJbnRlcm5hbAQCYnYCYncCYngCYnkDCQAAAgUCYnkJAJADAQUCYncFA25pbAQCYnoJAMwIAgMJAAACCAUCYUIGY2FsbGVyBQR0aGlzBgkBAXMBAhFQZXJtaXNzaW9uIGRlbmllZAkAzAgCAwkAZwIFAmJ2CQCRAwIFAmJ4BQJieQYJAQFzAQIcaW5zdWZmaWNpZW50IHBheW1lbnQgYXNzZXRJZAUDbmlsAwkAAAIFAmJ6BQJiegQCYkEJAPwHBAUEdGhpcwITdHJhZGVSZXdhcmRJbnRlcm5hbAkAzAgCCQBlAgUCYnYJAJEDAgUCYngFAmJ5CQDMCAIFAmJ3CQDMCAIFAmJ4CQDMCAIJAGQCBQJieQABBQNuaWwFA25pbAMJAAACBQJiQQUCYkEEAmJCCQECYXoCCQCRAwIFAmJ3BQJieQUCYUIEAmFECQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmJ3BQJieQkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJiQgkAkQMCBQJieAUCYnkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhQwEJAJEDAgUCYncFAmJ5CQCRAwIFAmJ4BQJieQUDbmlsBQJiQQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhQgEWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQICYUQCYkMEAmJECQCdCAIFAmF5CQEBVAEFAmFEBAJiRQMJAAACBQJiRAUEdW5pdAUEdW5pdAkA/AcEBQJheQIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCBQFKCQDMCAIFAmFECQDMCAIJAGcCBQJiQwUBTQUDbmlsBQNuaWwDCQAAAgUCYkUFAmJFCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhQgEdcHJvY2Vzc1BlbmRpbmdQZXJpb2RzQW5kVXNlcnMACQCUCgIFA25pbAkBAXMBAgpkZXByZWNhdGVkAmFCAQtjbGFpbVJld2FyZAAEAmFvCQECYWoABAJhRAgFAmFCBmNhbGxlcgQCYkYJAKUIAQUCYUQEAmJHCQECYVYBBQJiRgQCYUgIBQJiRwJfMQQCYkgIBQJiRwJfMgQCYkkDCQBmAgUCYUgAAAYJAAIBAhBub3RoaW5nIHRvIGNsYWltAwkAAAIFAmJJBQJiSQQCYnIKAAJiaAkA/AcECQECYW4AAhBnZXRVc2VyR3d4QW1vdW50CQDMCAIFAmJGBQNuaWwFA25pbAMJAAECBQJiaAIDSW50BQJiaAkAAgEJAKwCAgkAAwEFAmJoAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJECQCdCAIFAmF5CQEBVAEFAmJGBAJiRQMJAAACBQJiRAUEdW5pdAUEdW5pdAkA/AcEBQJheQIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCBQFKCQDMCAIFAmFECQDMCAIJAGcCBQJicgUBTQUDbmlsBQNuaWwDCQAAAgUCYkUFAmJFBAJiSgMDCQAAAgUCYkQFBHVuaXQGCQBmAgUBTQUCYnIFBHVuaXQEAmJLCQBrAwUCYUgFAVAFAWIEAmJMCQBrAwUCYUgFAVMFAWIJAPwHBAUCYXkCDGluY1VuY2xhaW1lZAkAzAgCBQFKCQDMCAIFAmFECQDMCAIFAmJLCQDMCAIFAmJMBQNuaWwFA25pbAMJAAACBQJiSgUCYkoEAmJNCgACYmgJAPwHBAUCYXkCBWNsYWltCQDMCAIFAUoFA25pbAUDbmlsAwkAAQIFAmJoAgNJbnQFAmJoCQACAQkArAICCQADAQUCYmgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAMJAAACBQJiTQUCYk0EAmJOCQBkAgUCYUgFAmJNCQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCYUIGY2FsbGVyBQJhSAkA2QQBCQCRAwIFAmFvBQJhYQkAzAgCCQECYUYEAgVjbGFpbQUCYkYFAmJOBQJhQgUDbmlsBQJiSAUCYk4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUIBE2NsYWltUmV3YXJkUkVBRE9OTFkBAmJPBAJiUAkBAmFWAQUCYk8EAmFICAUCYlACXzEEAmJICAUCYlACXzIEAmJRCQELdmFsdWVPckVsc2UCCQCaCAIFAmF5CQEBVgIFAUoFAmJPAAAEAmJOCQBkAgUCYUgFAmJRCQCUCgIFA25pbAUCYk4CYUIBFW9uRW1pc3Npb25Gb3JHd3hTdGFydAADCQECIT0CCAUCYUIGY2FsbGVyBQFCCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXAABQZoZWlnaHQFA25pbAJhQgELdHJhZGVSZXdhcmQCAmJ3AmJ4BAJiUgkAAAIJAJADAQUCYncJAJADAQUCYngEAmJTCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhRQAAAAQCYlQJAJEDAggFAmFCCHBheW1lbnRzAAAEAmJVCAUCYlQHYXNzZXRJZAQCYlYIBQJiVAZhbW91bnQEAmJ6CQDMCAIDCQBnAgUCYlMJAJADAQUCYncGCQEBcwECE1RvbyBtYW55IHJlY2lwaWVudHMJAMwIAgMFAmJSBgkBAXMBAhdBcmd1bWVudHMgc2l6ZSBtaXNtYXRjaAkAzAgCAwkAAAIFAmJVBQJhaQYJAQFzAQITV3JvbmcgYXNzZXQgcGF5bWVudAUDbmlsAwkAAAIFAmJ6BQJiegQCYkEJAPwHBAUEdGhpcwITdHJhZGVSZXdhcmRJbnRlcm5hbAkAzAgCBQJiVgkAzAgCBQJidwkAzAgCBQJieAkAzAgCAAAFA25pbAUDbmlsAwkAAAIFAmJBBQJiQQkAlAoCBQNuaWwFAmJBCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFCARJjbGFpbVRyYWRpbmdSZXdhcmQABAJhRAgFAmFCBmNhbGxlcgQCYlcJAKUIAQUCYUQEAmJYCQECYVoBBQJiVwMJAGYCBQJiWAAACQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUQFAmJYBQJhaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFDAQUCYlcAAAUDbmlsBQJiWAkBAXMBAhBub3RoaW5nIHRvIGNsYWltAmFCARpjbGFpbVRyYWRpbmdSZXdhcmRSRUFET05MWQECYUQJAJQKAgUDbmlsCQECYVoBBQJhRAECYlkBAmJaAAQCY2EEAmFOCQECYVAAAwkAAQIFAmFOAgpCeXRlVmVjdG9yBAJhVAUCYU4FAmFUAwkAAQIFAmFOAgRVbml0CAUCYlkPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmJZCWJvZHlCeXRlcwkAkQMCCAUCYlkGcHJvb2ZzAAAFAmNhEcgmdw==", "height": 2701486, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7RHViMziaZz32mSVDWqEhu9Rrq2NGb1ccG3BmG6B8Bbh Next: AM4CJw4MDMfKEh2A6QJx5BF8PwCGTvh2KuWNsEpvw2Zc Diff:
OldNewDifferences
1212 let processingStageTotal = 0
1313
1414 let processingStageShares = 1
15+
16+let MULT18 = 1000000000000000000
17+
18+let MULT18BI = toBigInt(MULT18)
1519
1620 let wavesString = "WAVES"
1721
156160 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
157161
158162
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-
174163 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)
211164
212165
213166 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
275228 }
276229
277230
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-
325231 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
326232 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
327233 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
328234 }
329-
330-
331-func nextPeriod () = getNumberByKey(keyNextPeriod())
332235
333236
334237 func commonClaimReward (userAddress) = {
347250
348251
349252 func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
253+
254+
255+func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
256+
257+
258+func _refreshRewardPerGwxIntegral () = {
259+ let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
260+ case s: String =>
261+ parseBigInt(s)
262+ case _: Unit =>
263+ unit
264+ case _ =>
265+ throw("Match error")
266+ }, zeroBigInt)
267+ let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
268+ let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
269+ let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
270+ let gwxAmountTotal = {
271+ let @ = invoke(boostingContractOrFail(), "getGwxTotalREADONLY", nil, nil)
272+ if ($isInstanceOf(@, "Int"))
273+ then @
274+ else throw(($getType(@) + " couldn't be cast to Int"))
275+ }
276+ let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
277+ let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), toBigInt(gwxAmountTotal)))
278+ $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
279+ }
280+
281+
282+func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
283+
284+
285+func _refreshUserReward (userAddress) = {
286+ let rewardPerGwxIntegralUserLast = valueOrElse( match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
287+ case s: String =>
288+ parseBigInt(s)
289+ case _: Unit =>
290+ unit
291+ case _ =>
292+ throw("Match error")
293+ }, zeroBigInt)
294+ let userIdxOrFail = getUserIndexByAddress(toString(boostingContractOrFail()), toString(userAddress))
295+ let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userIdxOrFail)), 0)
296+ let $t01030410521 = _refreshRewardPerGwxIntegral()
297+ let rewardPerGwxIntegralActions = $t01030410521._1
298+ let rewardPerGwxIntegral = $t01030410521._2
299+ let userGwxAmount = {
300+ let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [toString(userAddress)], nil)
301+ if ($isInstanceOf(@, "Int"))
302+ then @
303+ else throw(($getType(@) + " couldn't be cast to Int"))
304+ }
305+ let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
306+ $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
307+ }
308+
309+
310+@Callable(i)
311+func refreshUserReward (userAddressBytes) = {
312+ let checkCaller = if ((i.caller == boostingContractOrFail()))
313+ then true
314+ else throwErr("permission denied")
315+ if ((checkCaller == checkCaller))
316+ then _refreshUserReward(Address(userAddressBytes))
317+ else throw("Strict value is not equal to itself.")
318+ }
319+
350320
351321
352322 @Callable(i)
388358
389359
390360 @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)
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- }
361+func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
450362
451363
452364
453365 @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)
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))
366+func claimReward () = {
367+ let cfgArray = readConfigArrayOrFail()
368+ let userAddress = i.caller
369+ let userAddressStr = toString(userAddress)
370+ let $t01283212889 = commonClaimReward(userAddressStr)
371+ let amount = $t01283212889._1
372+ let actions = $t01283212889._2
373+ let checkAmount = if ((amount > 0))
482374 then true
483- else mustManager(i)
484- if ((checkCaller == checkCaller))
375+ else throw("nothing to claim")
376+ if ((checkAmount == checkAmount))
485377 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))
378+ let userGwxAmount = {
379+ let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
380+ if ($isInstanceOf(@, "Int"))
381+ then @
382+ else throw(($getType(@) + " couldn't be cast to Int"))
383+ }
384+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
385+ let activeReferralInv = if ((referrer == unit))
386+ then unit
387+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
388+ if ((activeReferralInv == activeReferralInv))
491389 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))
390+ let referralInv = if (if ((referrer == unit))
391+ then true
392+ else (referralMinGWxAmount > userGwxAmount))
393+ then unit
394+ else {
395+ let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
396+ let referralReward = fraction(amount, referralRewardPermille, SCALE)
397+ invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
398+ }
399+ if ((referralInv == referralInv))
497400 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"))
401+ let claimedReferral = {
402+ let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
403+ if ($isInstanceOf(@, "Int"))
503404 then @
504- else throw(($getType(@) + " couldn't be cast to Boolean"))
405+ else throw(($getType(@) + " couldn't be cast to Int"))
505406 }
506- if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
407+ if ((claimedReferral == claimedReferral))
507408 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)
409+ let totalAmount = (amount + claimedReferral)
410+ $Tuple2(([ScriptTransfer(i.caller, amount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
515411 }
516412 else throw("Strict value is not equal to itself.")
517413 }
525421
526422
527423 @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)
555424 func claimRewardREADONLY (address) = {
556- let $t02043820488 = commonClaimReward(address)
557- let amount = $t02043820488._1
558- let actions = $t02043820488._2
425+ let $t01421614266 = commonClaimReward(address)
426+ let amount = $t01421614266._1
427+ let actions = $t01421614266._2
559428 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
560429 let totalAmount = (amount + referralUnclaimed)
561430 $Tuple2(nil, totalAmount)
564433
565434
566435 @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)
596436 func onEmissionForGwxStart () = if ((i.caller != factoryContract))
597437 then throw("permissions denied")
598438 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- }
666439
667440
668441
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
1010 let zeroBigInt = toBigInt(0)
1111
1212 let processingStageTotal = 0
1313
1414 let processingStageShares = 1
15+
16+let MULT18 = 1000000000000000000
17+
18+let MULT18BI = toBigInt(MULT18)
1519
1620 let wavesString = "WAVES"
1721
1822 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
1923
2024
2125 func getNumberOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("mandatory this." + key) + " is not defined"))
2226
2327
2428 func getStringByKey (key) = valueOrElse(getString(this, key), "")
2529
2630
2731 func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (("mandatory this." + key) + " is not defined"))
2832
2933
3034 func parseAssetId (input) = if ((input == wavesString))
3135 then unit
3236 else fromBase58String(input)
3337
3438
3539 func wrapErr (msg) = makeString(["gwx_reward.ride:", msg], " ")
3640
3741
3842 func throwErr (msg) = throw(wrapErr(msg))
3943
4044
4145 func abs (val) = if ((0 > val))
4246 then -(val)
4347 else val
4448
4549
4650 func absBigInt (val) = if ((zeroBigInt > val))
4751 then -(val)
4852 else val
4953
5054
5155 let keyMaxDepth = "%s__maxDepth"
5256
5357 let maxDepthDefault = 30
5458
5559 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
5660
5761 func keyFactoryAddress () = "%s%s__config__factoryAddress"
5862
5963
6064 let factoryAddressStr = getStringOrFail(keyFactoryAddress())
6165
6266 let factoryContract = addressFromStringValue(factoryAddressStr)
6367
6468 func keyEmissionAddress () = "%s%s__config__emissionAddress"
6569
6670
6771 func keyVotingEmissionContract () = makeString(["%s", "votingEmissionContract"], SEP)
6872
6973
7074 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract()))
7175
7276 func keyNumToUserMapping (num) = makeString(["%s%s%s", "mapping", "num2user", toString(num)], SEP)
7377
7478
7579 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
7680
7781 let referralProgramNameDefault = "wxlock"
7882
7983 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
8084
8185 let keyReferralMinGWxAmount = makeString(["%s%s", "referral", "minGWxAmount"], SEP)
8286
8387 let referralMinGWxAmountDefault = (500 * MULT8)
8488
8589 let referralMinGWxAmount = valueOrElse(getInteger(this, keyReferralMinGWxAmount), referralMinGWxAmountDefault)
8690
8791 let keyReferrerRewardPermille = makeString(["%s%s", "referral", "referrerRewardPermille"], SEP)
8892
8993 let referrerRewardPermilleDefault = 50
9094
9195 let referrerRewardPermille = valueOrElse(getInteger(this, keyReferrerRewardPermille), referrerRewardPermilleDefault)
9296
9397 let keyReferralRewardPermille = makeString(["%s%s", "referral", "referralRewardPermille"], SEP)
9498
9599 let referralRewardPermilleDefault = 50
96100
97101 let referralRewardPermille = valueOrElse(getInteger(this, keyReferralRewardPermille), referralRewardPermilleDefault)
98102
99103 func keyReferrer (referralAddress) = makeString(["%s%s%s", "referrer", referralProgramName, referralAddress], SEP)
100104
101105
102106 func keyUnclaimedReferral (programName,claimerAddress) = makeString(["%s%s%s", "unclaimedReferral", programName, claimerAddress], SEP)
103107
104108
105109 let emissionAddressStr = getStringOrFail(keyEmissionAddress())
106110
107111 let emissionContract = addressFromStringValue(emissionAddressStr)
108112
109113 let IdxCfgAssetId = 1
110114
111115 let IdxCfgPacemakerAddress = 2
112116
113117 let IdxCfgBoostingContract = 3
114118
115119 let IdxCfgMaxDepth = 4
116120
117121 func keyConfig () = "%s__config"
118122
119123
120124 func getEmissionAddress () = addressFromStringValue(valueOrErrorMessage(getString(this, keyEmissionAddress()), (("mandatory this." + keyEmissionAddress()) + " is not defined")))
121125
122126
123127 let emissionAddress = getEmissionAddress()
124128
125129 let wxAssetIdStr = split(value(getString(emissionAddress, keyConfig())), SEP)[1]
126130
127131 let wxAssetId = fromBase58String(wxAssetIdStr)
128132
129133 func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP)
130134
131135
132136 func formatConfig (wxAssetIdStr,matcherPacemakerAddressStr,boostingContractAddressStr,maxDepth) = makeString(["%s%s%s%d", wxAssetIdStr, matcherPacemakerAddressStr, boostingContractAddressStr, toString(maxDepth)], SEP)
133137
134138
135139 func boostingContractOrFail () = {
136140 let cfgArray = readConfigArrayOrFail()
137141 valueOrErrorMessage(addressFromString(cfgArray[IdxCfgBoostingContract]), "boosting contract address is not defined")
138142 }
139143
140144
141145 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
142146
143147
144148 func keyUsersCount () = "%s__nextUserNum"
145149
146150
147151 func keyRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
148152
149153
150154 func keyGwxHoldersRewardCurrent () = "%s%s__gwxHoldersReward__current"
151155
152156
153157 func keyGwxHoldersRewardNext () = "%s%s__gwxHoldersReward__next"
154158
155159
156160 func keyPoolWeightVirtual () = "%s%s__poolWeight__GWXvirtualPOOL"
157161
158162
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-
174163 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)
211164
212165
213166 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
214167
215168
216169 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(keyReferralsContractAddress()))
217170
218171 func keyTradingRewardHistory (user,i) = makeString(["%s%s%s%s", "tradingReward", "history", user, toBase58String(i.transactionId)], SEP)
219172
220173
221174 func keyTradingReward (userAddress) = makeString(["%s%s", "tradingReward", userAddress], SEP)
222175
223176
224177 func keyMaxRecipients () = makeString(["%s", "maxRecipients"], SEP)
225178
226179
227180 func HistoryEntry (type,user,amount,i) = {
228181 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
229182 let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount)], SEP)
230183 StringEntry(historyKEY, historyDATA)
231184 }
232185
233186
234187 func keyManagerPublicKey () = "%s__managerPublicKey"
235188
236189
237190 func keyManagerVaultAddress () = "%s__managerVaultAddress"
238191
239192
240193 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
241194 case s: String =>
242195 addressFromStringValue(s)
243196 case _ =>
244197 this
245198 }
246199
247200
248201 func managerPublicKeyOrUnit () = {
249202 let managerVaultAddress = getManagerVaultAddressOrThis()
250203 match getString(managerVaultAddress, keyManagerPublicKey()) {
251204 case s: String =>
252205 fromBase58String(s)
253206 case _: Unit =>
254207 unit
255208 case _ =>
256209 throw("Match error")
257210 }
258211 }
259212
260213
261214 func mustManager (i) = {
262215 let pd = throw("Permission denied")
263216 match managerPublicKeyOrUnit() {
264217 case pk: ByteVector =>
265218 if ((i.callerPublicKey == pk))
266219 then true
267220 else pd
268221 case _: Unit =>
269222 if ((i.caller == this))
270223 then true
271224 else pd
272225 case _ =>
273226 throw("Match error")
274227 }
275228 }
276229
277230
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-
325231 func getUserIndexByAddress (boostingContractAddressStr,userAddress) = {
326232 let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
327233 parseIntValue(valueOrErrorMessage(getString(Address(fromBase58String(boostingContractAddressStr)), key), ((("User address " + userAddress) + " is not found in boosting contract data, key=") + key)))
328234 }
329-
330-
331-func nextPeriod () = getNumberByKey(keyNextPeriod())
332235
333236
334237 func commonClaimReward (userAddress) = {
335238 let cfgArray = readConfigArrayOrFail()
336239 let userIdx = getUserIndexByAddress(cfgArray[IdxCfgBoostingContract], userAddress)
337240 let userUnclaimedOption = getInteger(keyUserUnclaimed(userIdx))
338241 match userUnclaimedOption {
339242 case _: Unit =>
340243 $Tuple2(0, nil)
341244 case u: Int =>
342245 $Tuple2(u, [IntegerEntry(keyUserUnclaimed(userIdx), 0)])
343246 case _ =>
344247 throw("Match error")
345248 }
346249 }
347250
348251
349252 func getTradingReward (userAddress) = valueOrElse(getInteger(this, keyTradingReward(userAddress)), 0)
253+
254+
255+func keyRewardPerGwxIntegral () = makeString(["%s", "rewardPerGwxIntegral"], SEP)
256+
257+
258+func _refreshRewardPerGwxIntegral () = {
259+ let rewardPerGwxIntegralPrevious = valueOrElse( match getString(this, keyRewardPerGwxIntegral()) {
260+ case s: String =>
261+ parseBigInt(s)
262+ case _: Unit =>
263+ unit
264+ case _ =>
265+ throw("Match error")
266+ }, zeroBigInt)
267+ let rewardPerGwxIntegralLastHeight = valueOrErrorMessage(getInteger(this, keyGwxRewardEmissionStartHeight()), wrapErr(("invalid " + keyGwxRewardEmissionStartHeight())))
268+ let emissionRate = valueOrErrorMessage(getInteger(emissionContract, keyRatePerBlockCurrent()), wrapErr(("invalid " + keyRatePerBlockCurrent())))
269+ let gwxHoldersRewardCurrent = valueOrElse(getInteger(emissionContract, keyGwxHoldersRewardCurrent()), 0)
270+ let gwxAmountTotal = {
271+ let @ = invoke(boostingContractOrFail(), "getGwxTotalREADONLY", nil, nil)
272+ if ($isInstanceOf(@, "Int"))
273+ then @
274+ else throw(($getType(@) + " couldn't be cast to Int"))
275+ }
276+ let dh = toBigInt((height - rewardPerGwxIntegralLastHeight))
277+ let rewardPerGwxIntegral = (rewardPerGwxIntegralPrevious + fraction(dh, ((toBigInt(emissionRate) * toBigInt(gwxHoldersRewardCurrent)) * MULT18BI), toBigInt(gwxAmountTotal)))
278+ $Tuple2([IntegerEntry(keyGwxRewardEmissionStartHeight(), height), StringEntry(keyRewardPerGwxIntegral(), toString(rewardPerGwxIntegral))], rewardPerGwxIntegral)
279+ }
280+
281+
282+func keyRewardPerGwxIntegralUserLast (userAddress) = makeString(["%s%s", "rewardPerGwxIntegralUserLast", toString(userAddress)], SEP)
283+
284+
285+func _refreshUserReward (userAddress) = {
286+ let rewardPerGwxIntegralUserLast = valueOrElse( match getString(this, keyRewardPerGwxIntegralUserLast(userAddress)) {
287+ case s: String =>
288+ parseBigInt(s)
289+ case _: Unit =>
290+ unit
291+ case _ =>
292+ throw("Match error")
293+ }, zeroBigInt)
294+ let userIdxOrFail = getUserIndexByAddress(toString(boostingContractOrFail()), toString(userAddress))
295+ let userUnclaimed = valueOrElse(getInteger(keyUserUnclaimed(userIdxOrFail)), 0)
296+ let $t01030410521 = _refreshRewardPerGwxIntegral()
297+ let rewardPerGwxIntegralActions = $t01030410521._1
298+ let rewardPerGwxIntegral = $t01030410521._2
299+ let userGwxAmount = {
300+ let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [toString(userAddress)], nil)
301+ if ($isInstanceOf(@, "Int"))
302+ then @
303+ else throw(($getType(@) + " couldn't be cast to Int"))
304+ }
305+ let userReward = (toInt(fraction(toBigInt(userGwxAmount), (rewardPerGwxIntegral - rewardPerGwxIntegralUserLast), MULT18BI)) + userUnclaimed)
306+ $Tuple2(([StringEntry(keyRewardPerGwxIntegralUserLast(userAddress), toString(rewardPerGwxIntegral))] ++ rewardPerGwxIntegralActions), userReward)
307+ }
308+
309+
310+@Callable(i)
311+func refreshUserReward (userAddressBytes) = {
312+ let checkCaller = if ((i.caller == boostingContractOrFail()))
313+ then true
314+ else throwErr("permission denied")
315+ if ((checkCaller == checkCaller))
316+ then _refreshUserReward(Address(userAddressBytes))
317+ else throw("Strict value is not equal to itself.")
318+ }
319+
350320
351321
352322 @Callable(i)
353323 func tradeRewardInternal (paymentAmountLeftOver,userAddresses,rewards,currentIter) = if ((currentIter == size(userAddresses)))
354324 then nil
355325 else {
356326 let checks = [if ((i.caller == this))
357327 then true
358328 else throwErr("Permission denied"), if ((paymentAmountLeftOver >= rewards[currentIter]))
359329 then true
360330 else throwErr("insufficient payment assetId")]
361331 if ((checks == checks))
362332 then {
363333 let tradeRewardInternal = invoke(this, "tradeRewardInternal", [(paymentAmountLeftOver - rewards[currentIter]), userAddresses, rewards, (currentIter + 1)], nil)
364334 if ((tradeRewardInternal == tradeRewardInternal))
365335 then {
366336 let tradingRewardHistoryKey = keyTradingRewardHistory(userAddresses[currentIter], i)
367337 let userAddress = addressFromStringValue(userAddresses[currentIter])
368338 $Tuple2([IntegerEntry(tradingRewardHistoryKey, rewards[currentIter]), IntegerEntry(keyTradingReward(userAddresses[currentIter]), rewards[currentIter])], tradeRewardInternal)
369339 }
370340 else throw("Strict value is not equal to itself.")
371341 }
372342 else throw("Strict value is not equal to itself.")
373343 }
374344
375345
376346
377347 @Callable(i)
378348 func updateReferralActivity (userAddress,gWxAmountStart) = {
379349 let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddress))
380350 let activeReferralInv = if ((referrer == unit))
381351 then unit
382352 else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (gWxAmountStart >= referralMinGWxAmount)], nil)
383353 if ((activeReferralInv == activeReferralInv))
384354 then $Tuple2(nil, unit)
385355 else throw("Strict value is not equal to itself.")
386356 }
387357
388358
389359
390360 @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)
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- }
361+func processPendingPeriodsAndUsers () = $Tuple2(nil, throwErr("deprecated"))
450362
451363
452364
453365 @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)
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))
366+func claimReward () = {
367+ let cfgArray = readConfigArrayOrFail()
368+ let userAddress = i.caller
369+ let userAddressStr = toString(userAddress)
370+ let $t01283212889 = commonClaimReward(userAddressStr)
371+ let amount = $t01283212889._1
372+ let actions = $t01283212889._2
373+ let checkAmount = if ((amount > 0))
482374 then true
483- else mustManager(i)
484- if ((checkCaller == checkCaller))
375+ else throw("nothing to claim")
376+ if ((checkAmount == checkAmount))
485377 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))
378+ let userGwxAmount = {
379+ let @ = invoke(boostingContractOrFail(), "getUserGwxAmount", [userAddressStr], nil)
380+ if ($isInstanceOf(@, "Int"))
381+ then @
382+ else throw(($getType(@) + " couldn't be cast to Int"))
383+ }
384+ let referrer = getString(referralsContractAddressOrFail, keyReferrer(userAddressStr))
385+ let activeReferralInv = if ((referrer == unit))
386+ then unit
387+ else invoke(referralsContractAddressOrFail, "updateReferralActivity", [referralProgramName, userAddress, (userGwxAmount >= referralMinGWxAmount)], nil)
388+ if ((activeReferralInv == activeReferralInv))
491389 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))
390+ let referralInv = if (if ((referrer == unit))
391+ then true
392+ else (referralMinGWxAmount > userGwxAmount))
393+ then unit
394+ else {
395+ let referrerReward = fraction(amount, referrerRewardPermille, SCALE)
396+ let referralReward = fraction(amount, referralRewardPermille, SCALE)
397+ invoke(referralsContractAddressOrFail, "incUnclaimed", [referralProgramName, userAddress, referrerReward, referralReward], nil)
398+ }
399+ if ((referralInv == referralInv))
497400 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"))
401+ let claimedReferral = {
402+ let @ = invoke(referralsContractAddressOrFail, "claim", [referralProgramName], nil)
403+ if ($isInstanceOf(@, "Int"))
503404 then @
504- else throw(($getType(@) + " couldn't be cast to Boolean"))
405+ else throw(($getType(@) + " couldn't be cast to Int"))
505406 }
506- if ((gwxHoldersRewardUpdated == gwxHoldersRewardUpdated))
407+ if ((claimedReferral == claimedReferral))
507408 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)
409+ let totalAmount = (amount + claimedReferral)
410+ $Tuple2(([ScriptTransfer(i.caller, amount, fromBase58String(cfgArray[IdxCfgAssetId])), HistoryEntry("claim", userAddressStr, totalAmount, i)] ++ actions), totalAmount)
515411 }
516412 else throw("Strict value is not equal to itself.")
517413 }
518414 else throw("Strict value is not equal to itself.")
519415 }
520416 else throw("Strict value is not equal to itself.")
521417 }
522418 else throw("Strict value is not equal to itself.")
523419 }
524420
525421
526422
527423 @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)
555424 func claimRewardREADONLY (address) = {
556- let $t02043820488 = commonClaimReward(address)
557- let amount = $t02043820488._1
558- let actions = $t02043820488._2
425+ let $t01421614266 = commonClaimReward(address)
426+ let amount = $t01421614266._1
427+ let actions = $t01421614266._2
559428 let referralUnclaimed = valueOrElse(getInteger(referralsContractAddressOrFail, keyUnclaimedReferral(referralProgramName, address)), 0)
560429 let totalAmount = (amount + referralUnclaimed)
561430 $Tuple2(nil, totalAmount)
562431 }
563432
564433
565434
566435 @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)
596436 func onEmissionForGwxStart () = if ((i.caller != factoryContract))
597437 then throw("permissions denied")
598438 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- }
666439
667440
668441
669442 @Callable(i)
670443 func tradeReward (userAddresses,rewards) = {
671444 let argsComparison = (size(userAddresses) == size(rewards))
672445 let maxRecipients = valueOrElse(getInteger(keyMaxRecipients()), 0)
673446 let payment = i.payments[0]
674447 let paymentAssetId = payment.assetId
675448 let paymentAmount = payment.amount
676449 let checks = [if ((maxRecipients >= size(userAddresses)))
677450 then true
678451 else throwErr("Too many recipients"), if (argsComparison)
679452 then true
680453 else throwErr("Arguments size mismatch"), if ((paymentAssetId == wxAssetId))
681454 then true
682455 else throwErr("Wrong asset payment")]
683456 if ((checks == checks))
684457 then {
685458 let tradeRewardInternal = invoke(this, "tradeRewardInternal", [paymentAmount, userAddresses, rewards, 0], nil)
686459 if ((tradeRewardInternal == tradeRewardInternal))
687460 then $Tuple2(nil, tradeRewardInternal)
688461 else throw("Strict value is not equal to itself.")
689462 }
690463 else throw("Strict value is not equal to itself.")
691464 }
692465
693466
694467
695468 @Callable(i)
696469 func claimTradingReward () = {
697470 let userAddress = i.caller
698471 let userAddressString = toString(userAddress)
699472 let reward = getTradingReward(userAddressString)
700473 if ((reward > 0))
701474 then $Tuple2([ScriptTransfer(userAddress, reward, wxAssetId), IntegerEntry(keyTradingReward(userAddressString), 0)], reward)
702475 else throwErr("nothing to claim")
703476 }
704477
705478
706479
707480 @Callable(i)
708481 func claimTradingRewardREADONLY (userAddress) = $Tuple2(nil, getTradingReward(userAddress))
709482
710483
711484 @Verifier(tx)
712485 func verify () = {
713486 let targetPublicKey = match managerPublicKeyOrUnit() {
714487 case pk: ByteVector =>
715488 pk
716489 case _: Unit =>
717490 tx.senderPublicKey
718491 case _ =>
719492 throw("Match error")
720493 }
721494 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
722495 }
723496

github/deemru/w8io/169f3d6 
90.11 ms