tx · 6hFUb23ozNADNPXnkBa7yHVUErQHMvUYSyCvxMB2AZP3 3MrrZRV6F9ywSejcyd9foJV5ZWXRhiDD6yo: -0.03700000 Waves 2023.03.04 14:23 [2475242] smart account 3MrrZRV6F9ywSejcyd9foJV5ZWXRhiDD6yo > SELF 0.00000000 Waves
{ "type": 13, "id": "6hFUb23ozNADNPXnkBa7yHVUErQHMvUYSyCvxMB2AZP3", "fee": 3700000, "feeAssetId": null, "timestamp": 1677929014946, "version": 2, "chainId": 84, "sender": "3MrrZRV6F9ywSejcyd9foJV5ZWXRhiDD6yo", "senderPublicKey": "AzkmMXb1TBA8jfijtZ5hFHMEC6p5hm3e5prwCk1cTVCh", "proofs": [ "CN1PmrTqagZEDHQBi95oGxo9GqJZSBHkjBMvEgy4eFG37ypzZP5MVWZLjUnSmoQycup4qFm1ZYEKRh9zU6YaaVQ" ], "script": "base64:BgIXCAISAwoBCBIAEgMKAQESABIAEgMKAQg2AA1rX3RvdGFsU3VwcGx5Ag1rX3RvdGFsU3VwcGx5AA9rX3Jld2FyZEJhbGFuY2UCD2tfcmV3YXJkQmFsYW5jZQAOa19zd2FwX2FkZHJlc3MCDmtfc3dhcF9hZGRyZXNzABBrX2xhc3RVcGRhdGVUaW1lAhBrX2xhc3RVcGRhdGVUaW1lABZrX3Jld2FyZFBlclRva2VuU3RvcmVkAhZrX3Jld2FyZFBlclRva2VuU3RvcmVkAAxrX3Jld2FyZFJhdGUCDGtfcmV3YXJkUmF0ZQAOa19wZXJpb2RGaW5pc2gCDmtfcGVyaW9kRmluaXNoAAlrX2JhbGFuY2UCCWtfYmFsYW5jZQAUa191c2VyUmV3YXJkUGVyVG9rZW4CFGtfdXNlclJld2FyZFBlclRva2VuAAxrX3VzZXJSZXdhcmQCDGtfdXNlclJld2FyZAANa19pbml0aWFsaXplZAINa19pbml0aWFsaXplZAAUa19jb29yZGluYXRvckFkZHJlc3MCFGtfY29vcmRpbmF0b3JBZGRyZXNzABFrX3N0YWtpbmdfYWRkcmVzcwIRa19zdGFraW5nX2FkZHJlc3MAEmtfZ292ZXJuYW5jZV9hc3NldAILa19nb3ZfYXNzZXQADmtfcmV3YXJkX2Fzc2V0Ag5rX3Jld2FyZF9hc3NldAAPa19hZG1pbl9hZGRyZXNzAg9rX2FkbWluX2FkZHJlc3MBC2Nvb3JkaW5hdG9yAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwIbQ29vcmRpbmF0b3Igbm90IHNldCBGYXJtaW5nAhtDb29yZGluYXRvciBhZGRyZXNzIGludmFsaWQBDGFkbWluQWRkcmVzcwAJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQtjb29yZGluYXRvcgAFD2tfYWRtaW5fYWRkcmVzcwIVQWRtaW4gYWRkcmVzcyBub3Qgc2V0AQ9nb3Zlcm5hbmNlQXNzZXQACQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCCQELY29vcmRpbmF0b3IABRJrX2dvdmVybmFuY2VfYXNzZXQCGEdvdmVybmFuY2UgYXNzZXQgbm90IHNldAELcmV3YXJkQXNzZXQACQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCCQELY29vcmRpbmF0b3IABQ5rX3Jld2FyZF9hc3NldAIUUmV3YXJkIGFzc2V0IG5vdCBzZXQBDnN0YWtpbmdBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCCQELY29vcmRpbmF0b3IABRFrX3N0YWtpbmdfYWRkcmVzcwIXU3Rha2luZyBhZGRyZXNzIG5vdCBzZXQCF1N0YWtpbmcgYWRkcmVzcyBpbnZhbGlkAQtzd2FwQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBC2Nvb3JkaW5hdG9yAAUOa19zd2FwX2FkZHJlc3MCFFN3YXAgYWRkcmVzcyBub3Qgc2V0AhRTd2FwIGFkZHJlc3MgaW52YWxpZAAMREVDSU1BTF9VTklUCQBoAgABCQBoAgkAaAIJAGgCCQBoAgkAaAIJAGgCCQBoAgAKAAoACgAKAAoACgAKAAoACERVUkFUSU9OCQBoAgkAaAIAPAA8ABgACk5PX0FERFJFU1MCAAAJTk9fU1RBS0VSAAABBGRpdmQCAl94Al95CQBuBAUCX3gFDERFQ0lNQUxfVU5JVAUCX3kFCEhBTEZFVkVOAQRtdWxkAgJfeAJfeQkAbgQFAl94BQJfeQUMREVDSU1BTF9VTklUBQhIQUxGRVZFTgEDYWJzAQJfeAMJAGYCBQJfeAAABQJfeAkBAS0BBQJfeAEEbWludgICX3gCX3kDCQBmAgUCX3gFAl95BQJfeQUCX3gBDnRvQ29tcG9zaXRlS2V5AgRfa2V5CF9hZGRyZXNzCQCsAgIJAKwCAgUEX2tleQIBXwUIX2FkZHJlc3MBA2ludAEBawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAWsJAKwCAgINbm8gdmFsdWUgZm9yIAUBawEEaW50MAEBawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrAAABC3RvdGFsU3VwcGx5AAkBBGludDABBQ1rX3RvdGFsU3VwcGx5ARRyZXdhcmRQZXJUb2tlblN0b3JlZAAJAQRpbnQwAQUWa19yZXdhcmRQZXJUb2tlblN0b3JlZAEObGFzdFVwZGF0ZVRpbWUACQEEaW50MAEFEGtfbGFzdFVwZGF0ZVRpbWUBCnJld2FyZFJhdGUACQEEaW50MAEFDGtfcmV3YXJkUmF0ZQEMcGVyaW9kRmluaXNoAAkBBGludDABBQ5rX3BlcmlvZEZpbmlzaAENcmV3YXJkQmFsYW5jZQAJAQRpbnQwAQUPa19yZXdhcmRCYWxhbmNlAQdyZXdhcmRzAQdfc3Rha2VyCQEEaW50MAEJAQ50b0NvbXBvc2l0ZUtleQIFDGtfdXNlclJld2FyZAUHX3N0YWtlcgEWdXNlclJld2FyZFBlclRva2VuUGFpZAEHX3N0YWtlcgkBBGludDABCQEOdG9Db21wb3NpdGVLZXkCBRRrX3VzZXJSZXdhcmRQZXJUb2tlbgUHX3N0YWtlcgEJYmFsYW5jZU9mAQdfc3Rha2VyCQEEaW50MAEJAQ50b0NvbXBvc2l0ZUtleQIFCWtfYmFsYW5jZQUHX3N0YWtlcgELaW5pdGlhbGl6ZWQACQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFDWtfaW5pdGlhbGl6ZWQHARN1cGRhdGVSZXdhcmRCYWxhbmNlAQZfZGVsdGEJAMwIAgkBDEludGVnZXJFbnRyeQIFD2tfcmV3YXJkQmFsYW5jZQkAZAIJAQ1yZXdhcmRCYWxhbmNlAAUGX2RlbHRhBQNuaWwBEHVwZGF0ZVJld2FyZFJhdGUBC19yZXdhcmRSYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQxrX3Jld2FyZFJhdGUFC19yZXdhcmRSYXRlBQNuaWwBCnVwZGF0ZVRpbWUCD19sYXN0VXBkYXRlVGltZQ1fcGVyaW9kRmluaXNoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX2xhc3RVcGRhdGVUaW1lBQ9fbGFzdFVwZGF0ZVRpbWUJAMwIAgkBDEludGVnZXJFbnRyeQIFDmtfcGVyaW9kRmluaXNoBQ1fcGVyaW9kRmluaXNoBQNuaWwBGnVwZGF0ZVJld2FyZFBlclRva2VuU3RvcmVkARVfcmV3YXJkUGVyVG9rZW5TdG9yZWQJAMwIAgkBDEludGVnZXJFbnRyeQIFFmtfcmV3YXJkUGVyVG9rZW5TdG9yZWQFFV9yZXdhcmRQZXJUb2tlblN0b3JlZAUDbmlsARF1cGRhdGVVc2VyUmV3YXJkcwMHX3N0YWtlcgdfcmV3YXJkE191c2VyUmV3YXJkUGVyVG9rZW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFDGtfdXNlclJld2FyZAUHX3N0YWtlcgUHX3Jld2FyZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUUa191c2VyUmV3YXJkUGVyVG9rZW4FB19zdGFrZXIFE191c2VyUmV3YXJkUGVyVG9rZW4FA25pbAENdXBkYXRlQmFsYW5jZQIHX3N0YWtlcgZfZGVsdGEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFCWtfYmFsYW5jZQUHX3N0YWtlcgkAZAIJAQliYWxhbmNlT2YBBQdfc3Rha2VyBQZfZGVsdGEJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtfdG90YWxTdXBwbHkJAGQCCQELdG90YWxTdXBwbHkABQZfZGVsdGEFA25pbAETY3VycmVudFRpbWVzdGFtcFNlYwAJAGkCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcADoBwEYbGFzdFRpbWVSZXdhcmRBcHBsaWNhYmxlAAkBBG1pbnYCCQETY3VycmVudFRpbWVzdGFtcFNlYwAJAQxwZXJpb2RGaW5pc2gAAQ5yZXdhcmRQZXJUb2tlbgENX2JhbGFuY2VEZWx0YQMJAAACCQBkAgkBC3RvdGFsU3VwcGx5AAUNX2JhbGFuY2VEZWx0YQAACQEUcmV3YXJkUGVyVG9rZW5TdG9yZWQABAx0aW1lSW50ZXJ2YWwJAGUCCQEYbGFzdFRpbWVSZXdhcmRBcHBsaWNhYmxlAAkBDmxhc3RVcGRhdGVUaW1lAAQSYWN0dWFsVGltZUludGVydmFsAwkAZgIAAAUMdGltZUludGVydmFsAAAFDHRpbWVJbnRlcnZhbAQEZGlmZgkBBGRpdmQCCQBoAgkBCnJld2FyZFJhdGUABRJhY3R1YWxUaW1lSW50ZXJ2YWwJAGQCCQELdG90YWxTdXBwbHkABQ1fYmFsYW5jZURlbHRhCQBkAgkBFHJld2FyZFBlclRva2VuU3RvcmVkAAUEZGlmZgEGZWFybmVkAgdfc3Rha2VyDV9iYWxhbmNlRGVsdGEEC3Jld2FyZERlbHRhCQBlAgkBDnJld2FyZFBlclRva2VuAQUNX2JhbGFuY2VEZWx0YQkBFnVzZXJSZXdhcmRQZXJUb2tlblBhaWQBBQdfc3Rha2VyCQBkAgkBBG11bGQCCQBkAgkBCWJhbGFuY2VPZgEFB19zdGFrZXIFDV9iYWxhbmNlRGVsdGEFC3Jld2FyZERlbHRhCQEHcmV3YXJkcwEFB19zdGFrZXIBDHVwZGF0ZVJld2FyZAIHX3N0YWtlcg1fYmFsYW5jZURlbHRhBBduZXdSZXdhcmRQZXJUb2tlblN0b3JlZAkBDnJld2FyZFBlclRva2VuAQUNX2JhbGFuY2VEZWx0YQQRbmV3TGFzdFVwZGF0ZVRpbWUJARNjdXJyZW50VGltZXN0YW1wU2VjAAQLJHQwNTMwODU1MDADCQECIT0CBQdfc3Rha2VyAgAJAJQKAgkBBmVhcm5lZAIFB19zdGFrZXIFDV9iYWxhbmNlRGVsdGEFF25ld1Jld2FyZFBlclRva2VuU3RvcmVkCQCUCgIAAAAABAxzdGFrZXJFYXJuZWQIBQskdDA1MzA4NTUwMAJfMQQYc3Rha2VyUmV3YXJkUGVyVG9rZW5QYWlkCAULJHQwNTMwODU1MDACXzIJAJYKBAUXbmV3UmV3YXJkUGVyVG9rZW5TdG9yZWQFEW5ld0xhc3RVcGRhdGVUaW1lBQxzdGFrZXJFYXJuZWQFGHN0YWtlclJld2FyZFBlclRva2VuUGFpZAYBaQEKaW5pdGlhbGl6ZQEMX2Nvb3JkaW5hdG9yAwMJAQtpbml0aWFsaXplZAAGCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhRVbmFibGUgdG8gaW5pdGlhbGl6ZQkAzAgCCQELU3RyaW5nRW50cnkCBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwkApQgBCQERQGV4dHJOYXRpdmUoMTA2MikBBQxfY29vcmRpbmF0b3IJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDWtfaW5pdGlhbGl6ZWQGBQNuaWwBaQEFc3Rha2UABAdfc3Rha2VyCQClCAEIBQFpBmNhbGxlcgQHX2Ftb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQDAwkBAiE9AggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCQEPZ292ZXJuYW5jZUFzc2V0AAYJAQEhAQkBC2luaXRpYWxpemVkAAkAAgECFkludmFsaWQgY2FsbCB0byAgc3Rha2UECyR0MDYyMTI2Mzc3CQEMdXBkYXRlUmV3YXJkAgUHX3N0YWtlcgAABBduZXdSZXdhcmRQZXJUb2tlblN0b3JlZAgFCyR0MDYyMTI2Mzc3Al8xBBFuZXdMYXN0VXBkYXRlVGltZQgFCyR0MDYyMTI2Mzc3Al8yBAxzdGFrZXJFYXJuZWQIBQskdDA2MjEyNjM3NwJfMwQYc3Rha2VyUmV3YXJkUGVyVG9rZW5QYWlkCAULJHQwNjIxMjYzNzcCXzQEB2RvU3Rha2UJAPwHBAkBDnN0YWtpbmdBZGRyZXNzAAIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBD2dvdmVybmFuY2VBc3NldAAFB19hbW91bnQFA25pbAMJAAACBQdkb1N0YWtlBQdkb1N0YWtlCQDOCAIJAM4IAgkAzggCCQERdXBkYXRlVXNlclJld2FyZHMDBQdfc3Rha2VyBQxzdGFrZXJFYXJuZWQFGHN0YWtlclJld2FyZFBlclRva2VuUGFpZAkBGnVwZGF0ZVJld2FyZFBlclRva2VuU3RvcmVkAQUXbmV3UmV3YXJkUGVyVG9rZW5TdG9yZWQJAQp1cGRhdGVUaW1lAgURbmV3TGFzdFVwZGF0ZVRpbWUJAQxwZXJpb2RGaW5pc2gACQENdXBkYXRlQmFsYW5jZQIFB19zdGFrZXIFB19hbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHdW5TdGFrZQEHX2Ftb3VudAQMZG9BY2tSZXdhcmRzCQD8BwQFBHRoaXMCCmFja1Jld2FyZHMFA25pbAUDbmlsAwkAAAIFDGRvQWNrUmV3YXJkcwUMZG9BY2tSZXdhcmRzBAdfc3Rha2VyCQClCAEIBQFpBmNhbGxlcgMDCQECIT0CCAUBaQhwYXltZW50cwUDbmlsBgkBASEBCQELaW5pdGlhbGl6ZWQACQACAQIaSW52YWxpZCB1blN0YWtlIHBhcmFtZXRlcnMECyR0MDcxMjM3Mjg4CQEMdXBkYXRlUmV3YXJkAgUHX3N0YWtlcgAABBduZXdSZXdhcmRQZXJUb2tlblN0b3JlZAgFCyR0MDcxMjM3Mjg4Al8xBBFuZXdMYXN0VXBkYXRlVGltZQgFCyR0MDcxMjM3Mjg4Al8yBAxzdGFrZXJFYXJuZWQIBQskdDA3MTIzNzI4OAJfMwQYc3Rha2VyUmV3YXJkUGVyVG9rZW5QYWlkCAULJHQwNzEyMzcyODgCXzQDCQBmAgUHX2Ftb3VudAkAZAIJAQliYWxhbmNlT2YBBQdfc3Rha2VyBQxzdGFrZXJFYXJuZWQJAAIBAhpJbnZhbGlkIHVuU3Rha2UgcGFyYW1ldGVycwQJZG9VblN0YWtlCQD8BwQJAQ5zdGFraW5nQWRkcmVzcwACB3VuU3Rha2UJAMwIAgUHX2Ftb3VudAUDbmlsBQNuaWwDCQAAAgUJZG9VblN0YWtlBQlkb1VuU3Rha2UEDHJld2FyZENoYW5nZQMJAGcCCQEJYmFsYW5jZU9mAQUHX3N0YWtlcgUHX2Ftb3VudAAACQBlAgUHX2Ftb3VudAkBCWJhbGFuY2VPZgEFB19zdGFrZXIEDWJhbGFuY2VDaGFuZ2UDCQBnAgkBCWJhbGFuY2VPZgEFB19zdGFrZXIFB19hbW91bnQFB19hbW91bnQJAQliYWxhbmNlT2YBBQdfc3Rha2VyCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkBEXVwZGF0ZVVzZXJSZXdhcmRzAwUHX3N0YWtlcgkAZQIFDHN0YWtlckVhcm5lZAUMcmV3YXJkQ2hhbmdlBRhzdGFrZXJSZXdhcmRQZXJUb2tlblBhaWQJARp1cGRhdGVSZXdhcmRQZXJUb2tlblN0b3JlZAEFF25ld1Jld2FyZFBlclRva2VuU3RvcmVkCQEKdXBkYXRlVGltZQIFEW5ld0xhc3RVcGRhdGVUaW1lCQEMcGVyaW9kRmluaXNoAAkBDXVwZGF0ZUJhbGFuY2UCBQdfc3Rha2VyCQEBLQEFDWJhbGFuY2VDaGFuZ2UJARN1cGRhdGVSZXdhcmRCYWxhbmNlAQkBAS0BBQxyZXdhcmRDaGFuZ2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQdfYW1vdW50CQEPZ292ZXJuYW5jZUFzc2V0AAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBD3dpdGhkcmF3UmV3YXJkcwAEDGRvQWNrUmV3YXJkcwkA/AcEBQR0aGlzAgphY2tSZXdhcmRzBQNuaWwFA25pbAMJAAACBQxkb0Fja1Jld2FyZHMFDGRvQWNrUmV3YXJkcwQHX3N0YWtlcgkApQgBCAUBaQZjYWxsZXIECyR0MDg2MjY4NzcxCQEMdXBkYXRlUmV3YXJkAgUHX3N0YWtlcgAABBduZXdSZXdhcmRQZXJUb2tlblN0b3JlZAgFCyR0MDg2MjY4NzcxAl8xBBFuZXdMYXN0VXBkYXRlVGltZQgFCyR0MDg2MjY4NzcxAl8yBAxzdGFrZXJFYXJuZWQIBQskdDA4NjI2ODc3MQJfMwQYc3Rha2VyUmV3YXJkUGVyVG9rZW5QYWlkCAULJHQwODYyNjg3NzECXzQDAwkAZwIAAAUMc3Rha2VyRWFybmVkBgkBASEBCQELaW5pdGlhbGl6ZWQACQACAQIRTm8gZmFybWluZyByZXdhcmQECWRvVW5TdGFrZQkA/AcECQEOc3Rha2luZ0FkZHJlc3MAAgd1blN0YWtlCQDMCAIFDHN0YWtlckVhcm5lZAUDbmlsBQNuaWwDCQAAAgUJZG9VblN0YWtlBQlkb1VuU3Rha2UJAM4IAgkAzggCCQDOCAIJAM4IAgkBEXVwZGF0ZVVzZXJSZXdhcmRzAwUHX3N0YWtlcgAABRhzdGFrZXJSZXdhcmRQZXJUb2tlblBhaWQJARp1cGRhdGVSZXdhcmRQZXJUb2tlblN0b3JlZAEFF25ld1Jld2FyZFBlclRva2VuU3RvcmVkCQEKdXBkYXRlVGltZQIFEW5ld0xhc3RVcGRhdGVUaW1lCQEMcGVyaW9kRmluaXNoAAkBE3VwZGF0ZVJld2FyZEJhbGFuY2UBCQEBLQEFDHN0YWtlckVhcm5lZAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFDHN0YWtlckVhcm5lZAkBD2dvdmVybmFuY2VBc3NldAAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQphY2tSZXdhcmRzAAQNX3Jld2FyZEFtb3VudAkA/AcECQEOc3Rha2luZ0FkZHJlc3MAAg1jb21wdXRlUmV3YXJkCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQAAAgUNX3Jld2FyZEFtb3VudAUNX3Jld2FyZEFtb3VudAQMcmV3YXJkQW1vdW50BAckbWF0Y2gwBQ1fcmV3YXJkQW1vdW50AwkAAQIFByRtYXRjaDACA0ludAQBdAUHJG1hdGNoMAUBdAkAAgECGlJld2FyZCBhbW91bnQgbm90IGEgbnVtYmVyAwkAZgIJAGgCAAEFDERFQ0lNQUxfVU5JVAUMcmV3YXJkQW1vdW50BQNuaWwEDmRvQ2xhaW1SZXdhcmRzCQD8BwQJAQ5zdGFraW5nQWRkcmVzcwACD3dpdGhkcmF3UmV3YXJkcwUDbmlsBQNuaWwDCQAAAgUOZG9DbGFpbVJld2FyZHMFDmRvQ2xhaW1SZXdhcmRzBA1yZXdhcmRzQW1vdW50CQDwBwIFBHRoaXMJAQtyZXdhcmRBc3NldAAEBmRvU3dhcAkA/AcECQELc3dhcEFkZHJlc3MAAgRzd2FwCQDMCAIJANgEAQkBD2dvdmVybmFuY2VBc3NldAAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQtyZXdhcmRBc3NldAAFDXJld2FyZHNBbW91bnQFA25pbAMJAAACBQZkb1N3YXAFBmRvU3dhcAQLcmV3YXJkRGVsdGEJAPAHAgUEdGhpcwkBD2dvdmVybmFuY2VBc3NldAADCQAAAgULcmV3YXJkRGVsdGEFC3Jld2FyZERlbHRhAwkAZwIAAAULcmV3YXJkRGVsdGEJAAIBAhlJbnZhbGlkIGFja1Jld2FyZHMgcGFyYW1zBAdfcmV3YXJkBQtyZXdhcmREZWx0YQQXbmV3UmV3YXJkUGVyVG9rZW5TdG9yZWQICQEMdXBkYXRlUmV3YXJkAgUKTk9fQUREUkVTUwUJTk9fU1RBS0VSAl8xBAl0aW1lc3RhbXAJARNjdXJyZW50VGltZXN0YW1wU2VjAAQNbmV3UmV3YXJkUmF0ZQMJAGYCBQl0aW1lc3RhbXAJAQxwZXJpb2RGaW5pc2gACQBpAgUHX3Jld2FyZAUIRFVSQVRJT04EDXJlbWFpbmluZ1RpbWUJAGUCCQEMcGVyaW9kRmluaXNoAAUJdGltZXN0YW1wBAhsZWZ0b3ZlcgkAaAIJAQpyZXdhcmRSYXRlAAUNcmVtYWluaW5nVGltZQkAaQIJAGQCBQdfcmV3YXJkBQhsZWZ0b3ZlcgUIRFVSQVRJT04EB2RvU3Rha2UJAPwHBAkBDnN0YWtpbmdBZGRyZXNzAAIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBD2dvdmVybmFuY2VBc3NldAAFC3Jld2FyZERlbHRhBQNuaWwDCQAAAgUHZG9TdGFrZQUHZG9TdGFrZQkAzggCCQDOCAIJAM4IAgkBEHVwZGF0ZVJld2FyZFJhdGUBBQ1uZXdSZXdhcmRSYXRlCQEadXBkYXRlUmV3YXJkUGVyVG9rZW5TdG9yZWQBBRduZXdSZXdhcmRQZXJUb2tlblN0b3JlZAkBE3VwZGF0ZVJld2FyZEJhbGFuY2UBBQdfcmV3YXJkCQEKdXBkYXRlVGltZQIFCXRpbWVzdGFtcAkAZAIFCXRpbWVzdGFtcAUIRFVSQVRJT04JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELdmlld19yZXdhcmQBB19zdGFrZXIEDHN0YWtlckVhcm5lZAgJAQx1cGRhdGVSZXdhcmQCBQdfc3Rha2VyAAACXzMJAAIBCQCkAwEFDHN0YWtlckVhcm5lZAECdHgBBnZlcmlmeQAEDmNvb3JkaW5hdG9yU3RyCQCdCAIFBHRoaXMFFGtfY29vcmRpbmF0b3JBZGRyZXNzAwkBCWlzRGVmaW5lZAEFDmNvb3JkaW5hdG9yU3RyBAVhZG1pbgkAnQgCCQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBBQ5jb29yZGluYXRvclN0cgUPa19hZG1pbl9hZGRyZXNzAwkBCWlzRGVmaW5lZAEFBWFkbWluCQELdmFsdWVPckVsc2UCCQCbCAIJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQV2YWx1ZQEFBWFkbWluCQCsAgIJAKwCAgkArAICAgdzdGF0dXNfCQClCAEFBHRoaXMCAV8JANgEAQgFAnR4AmlkBwkAAgECLnVuYWJsZSB0byB2ZXJpZnk6IGFkbWluIG5vdCBzZXQgaW4gY29vcmRpbmF0b3IJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXnydWbP", "height": 2475242, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: FARS8CStsiJ5UHkhXxGtM5poXeby4YJHo2K5aAVahN9Y Next: none Diff:
Old | New | Differences | |
---|---|---|---|
5 | 5 | ||
6 | 6 | let k_rewardBalance = "k_rewardBalance" | |
7 | 7 | ||
8 | - | let k_ | |
8 | + | let k_swap_address = "k_swap_address" | |
9 | 9 | ||
10 | 10 | let k_lastUpdateTime = "k_lastUpdateTime" | |
11 | 11 | ||
29 | 29 | ||
30 | 30 | let k_governance_asset = "k_gov_asset" | |
31 | 31 | ||
32 | - | let k_quote_asset = "k_quote_asset" | |
33 | - | ||
34 | - | let k_admin_public_key = "k_admin_public_key" | |
32 | + | let k_reward_asset = "k_reward_asset" | |
35 | 33 | ||
36 | 34 | let k_admin_address = "k_admin_address" | |
37 | 35 | ||
38 | - | func coordinator () = valueOrErrorMessage(addressFromString( | |
36 | + | func coordinator () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, k_coordinatorAddress), "Coordinator not set Farming")), "Coordinator address invalid") | |
39 | 37 | ||
40 | 38 | ||
41 | - | func adminAddress () = addressFromString( | |
39 | + | func adminAddress () = addressFromString(valueOrErrorMessage(getString(coordinator(), k_admin_address), "Admin address not set")) | |
42 | 40 | ||
43 | 41 | ||
44 | - | func | |
42 | + | func governanceAsset () = fromBase58String(valueOrErrorMessage(getString(coordinator(), k_governance_asset), "Governance asset not set")) | |
45 | 43 | ||
46 | 44 | ||
47 | - | func | |
45 | + | func rewardAsset () = fromBase58String(valueOrErrorMessage(getString(coordinator(), k_reward_asset), "Reward asset not set")) | |
48 | 46 | ||
49 | 47 | ||
50 | - | func | |
48 | + | func stakingAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_staking_address), "Staking address not set")), "Staking address invalid") | |
51 | 49 | ||
52 | 50 | ||
53 | - | func | |
51 | + | func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_swap_address), "Swap address not set")), "Swap address invalid") | |
54 | 52 | ||
55 | 53 | ||
56 | 54 | let DECIMAL_UNIT = (1 * (((((((10 * 10) * 10) * 10) * 10) * 10) * 10) * 10)) | |
102 | 100 | ||
103 | 101 | ||
104 | 102 | func rewardBalance () = int0(k_rewardBalance) | |
105 | - | ||
106 | - | ||
107 | - | func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, k_swapAddress), "Now swap address")), "Invalid swap address") | |
108 | 103 | ||
109 | 104 | ||
110 | 105 | func rewards (_staker) = int0(toCompositeKey(k_userReward, _staker)) | |
164 | 159 | func updateReward (_staker,_balanceDelta) = { | |
165 | 160 | let newRewardPerTokenStored = rewardPerToken(_balanceDelta) | |
166 | 161 | let newLastUpdateTime = currentTimestampSec() | |
167 | - | let $ | |
162 | + | let $t053085500 = if ((_staker != "")) | |
168 | 163 | then $Tuple2(earned(_staker, _balanceDelta), newRewardPerTokenStored) | |
169 | 164 | else $Tuple2(0, 0) | |
170 | - | let stakerEarned = $ | |
171 | - | let stakerRewardPerTokenPaid = $ | |
165 | + | let stakerEarned = $t053085500._1 | |
166 | + | let stakerRewardPerTokenPaid = $t053085500._2 | |
172 | 167 | $Tuple4(newRewardPerTokenStored, newLastUpdateTime, stakerEarned, stakerRewardPerTokenPaid) | |
173 | 168 | } | |
174 | 169 | ||
175 | 170 | ||
176 | 171 | @Callable(i) | |
177 | - | func initialize (_coordinator,_swapAddress) = if (initialized()) | |
178 | - | then throw("Already initialized") | |
179 | - | else [StringEntry(k_coordinatorAddress, _coordinator), StringEntry(k_swapAddress, _swapAddress), BooleanEntry(k_initialized, true)] | |
180 | - | ||
181 | - | ||
182 | - | ||
183 | - | @Callable(i) | |
184 | - | func setSwap (_swapAddress) = if ((i.caller != adminAddress())) | |
185 | - | then throw("Invalid setSwap params") | |
186 | - | else [StringEntry(k_swapAddress, _swapAddress)] | |
172 | + | func initialize (_coordinator) = if (if (initialized()) | |
173 | + | then true | |
174 | + | else (i.caller != this)) | |
175 | + | then throw("Unable to initialize") | |
176 | + | else [StringEntry(k_coordinatorAddress, toString(addressFromStringValue(_coordinator))), BooleanEntry(k_initialized, true)] | |
187 | 177 | ||
188 | 178 | ||
189 | 179 | ||
196 | 186 | else !(initialized())) | |
197 | 187 | then throw("Invalid call to stake") | |
198 | 188 | else { | |
199 | - | let $ | |
200 | - | let newRewardPerTokenStored = $ | |
201 | - | let newLastUpdateTime = $ | |
202 | - | let stakerEarned = $ | |
203 | - | let stakerRewardPerTokenPaid = $ | |
189 | + | let $t062126377 = updateReward(_staker, 0) | |
190 | + | let newRewardPerTokenStored = $t062126377._1 | |
191 | + | let newLastUpdateTime = $t062126377._2 | |
192 | + | let stakerEarned = $t062126377._3 | |
193 | + | let stakerRewardPerTokenPaid = $t062126377._4 | |
204 | 194 | let doStake = invoke(stakingAddress(), "stake", nil, [AttachedPayment(governanceAsset(), _amount)]) | |
205 | 195 | if ((doStake == doStake)) | |
206 | 196 | then (((updateUserRewards(_staker, stakerEarned, stakerRewardPerTokenPaid) ++ updateRewardPerTokenStored(newRewardPerTokenStored)) ++ updateTime(newLastUpdateTime, periodFinish())) ++ updateBalance(_staker, _amount)) | |
221 | 211 | else !(initialized())) | |
222 | 212 | then throw("Invalid unStake parameters") | |
223 | 213 | else { | |
224 | - | let $ | |
225 | - | let newRewardPerTokenStored = $ | |
226 | - | let newLastUpdateTime = $ | |
227 | - | let stakerEarned = $ | |
228 | - | let stakerRewardPerTokenPaid = $ | |
214 | + | let $t071237288 = updateReward(_staker, 0) | |
215 | + | let newRewardPerTokenStored = $t071237288._1 | |
216 | + | let newLastUpdateTime = $t071237288._2 | |
217 | + | let stakerEarned = $t071237288._3 | |
218 | + | let stakerRewardPerTokenPaid = $t071237288._4 | |
229 | 219 | if ((_amount > (balanceOf(_staker) + stakerEarned))) | |
230 | 220 | then throw("Invalid unStake parameters") | |
231 | 221 | else { | |
255 | 245 | if ((doAckRewards == doAckRewards)) | |
256 | 246 | then { | |
257 | 247 | let _staker = toString(i.caller) | |
258 | - | let $ | |
259 | - | let newRewardPerTokenStored = $ | |
260 | - | let newLastUpdateTime = $ | |
261 | - | let stakerEarned = $ | |
262 | - | let stakerRewardPerTokenPaid = $ | |
248 | + | let $t086268771 = updateReward(_staker, 0) | |
249 | + | let newRewardPerTokenStored = $t086268771._1 | |
250 | + | let newLastUpdateTime = $t086268771._2 | |
251 | + | let stakerEarned = $t086268771._3 | |
252 | + | let stakerRewardPerTokenPaid = $t086268771._4 | |
263 | 253 | if (if ((0 >= stakerEarned)) | |
264 | 254 | then true | |
265 | 255 | else !(initialized())) | |
293 | 283 | let doClaimRewards = invoke(stakingAddress(), "withdrawRewards", nil, nil) | |
294 | 284 | if ((doClaimRewards == doClaimRewards)) | |
295 | 285 | then { | |
296 | - | let rewardsAmount = assetBalance(this, | |
297 | - | let doSwap = invoke(swapAddress(), "swap", [toBase58String(governanceAsset()), 0], [AttachedPayment( | |
286 | + | let rewardsAmount = assetBalance(this, rewardAsset()) | |
287 | + | let doSwap = invoke(swapAddress(), "swap", [toBase58String(governanceAsset()), 0], [AttachedPayment(rewardAsset(), rewardsAmount)]) | |
298 | 288 | if ((doSwap == doSwap)) | |
299 | 289 | then { | |
300 | 290 | let rewardDelta = assetBalance(this, governanceAsset()) | |
337 | 327 | ||
338 | 328 | ||
339 | 329 | @Verifier(tx) | |
340 | - | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey()) | |
330 | + | func verify () = { | |
331 | + | let coordinatorStr = getString(this, k_coordinatorAddress) | |
332 | + | if (isDefined(coordinatorStr)) | |
333 | + | then { | |
334 | + | let admin = getString(addressFromStringValue(value(coordinatorStr)), k_admin_address) | |
335 | + | if (isDefined(admin)) | |
336 | + | then valueOrElse(getBoolean(addressFromStringValue(value(admin)), ((("status_" + toString(this)) + "_") + toBase58String(tx.id))), false) | |
337 | + | else throw("unable to verify: admin not set in coordinator") | |
338 | + | } | |
339 | + | else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
340 | + | } | |
341 | 341 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let k_totalSupply = "k_totalSupply" | |
5 | 5 | ||
6 | 6 | let k_rewardBalance = "k_rewardBalance" | |
7 | 7 | ||
8 | - | let k_ | |
8 | + | let k_swap_address = "k_swap_address" | |
9 | 9 | ||
10 | 10 | let k_lastUpdateTime = "k_lastUpdateTime" | |
11 | 11 | ||
12 | 12 | let k_rewardPerTokenStored = "k_rewardPerTokenStored" | |
13 | 13 | ||
14 | 14 | let k_rewardRate = "k_rewardRate" | |
15 | 15 | ||
16 | 16 | let k_periodFinish = "k_periodFinish" | |
17 | 17 | ||
18 | 18 | let k_balance = "k_balance" | |
19 | 19 | ||
20 | 20 | let k_userRewardPerToken = "k_userRewardPerToken" | |
21 | 21 | ||
22 | 22 | let k_userReward = "k_userReward" | |
23 | 23 | ||
24 | 24 | let k_initialized = "k_initialized" | |
25 | 25 | ||
26 | 26 | let k_coordinatorAddress = "k_coordinatorAddress" | |
27 | 27 | ||
28 | 28 | let k_staking_address = "k_staking_address" | |
29 | 29 | ||
30 | 30 | let k_governance_asset = "k_gov_asset" | |
31 | 31 | ||
32 | - | let k_quote_asset = "k_quote_asset" | |
33 | - | ||
34 | - | let k_admin_public_key = "k_admin_public_key" | |
32 | + | let k_reward_asset = "k_reward_asset" | |
35 | 33 | ||
36 | 34 | let k_admin_address = "k_admin_address" | |
37 | 35 | ||
38 | - | func coordinator () = valueOrErrorMessage(addressFromString( | |
36 | + | func coordinator () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, k_coordinatorAddress), "Coordinator not set Farming")), "Coordinator address invalid") | |
39 | 37 | ||
40 | 38 | ||
41 | - | func adminAddress () = addressFromString( | |
39 | + | func adminAddress () = addressFromString(valueOrErrorMessage(getString(coordinator(), k_admin_address), "Admin address not set")) | |
42 | 40 | ||
43 | 41 | ||
44 | - | func | |
42 | + | func governanceAsset () = fromBase58String(valueOrErrorMessage(getString(coordinator(), k_governance_asset), "Governance asset not set")) | |
45 | 43 | ||
46 | 44 | ||
47 | - | func | |
45 | + | func rewardAsset () = fromBase58String(valueOrErrorMessage(getString(coordinator(), k_reward_asset), "Reward asset not set")) | |
48 | 46 | ||
49 | 47 | ||
50 | - | func | |
48 | + | func stakingAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_staking_address), "Staking address not set")), "Staking address invalid") | |
51 | 49 | ||
52 | 50 | ||
53 | - | func | |
51 | + | func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_swap_address), "Swap address not set")), "Swap address invalid") | |
54 | 52 | ||
55 | 53 | ||
56 | 54 | let DECIMAL_UNIT = (1 * (((((((10 * 10) * 10) * 10) * 10) * 10) * 10) * 10)) | |
57 | 55 | ||
58 | 56 | let DURATION = ((60 * 60) * 24) | |
59 | 57 | ||
60 | 58 | let NO_ADDRESS = "" | |
61 | 59 | ||
62 | 60 | let NO_STAKER = 0 | |
63 | 61 | ||
64 | 62 | func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN) | |
65 | 63 | ||
66 | 64 | ||
67 | 65 | func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN) | |
68 | 66 | ||
69 | 67 | ||
70 | 68 | func abs (_x) = if ((_x > 0)) | |
71 | 69 | then _x | |
72 | 70 | else -(_x) | |
73 | 71 | ||
74 | 72 | ||
75 | 73 | func minv (_x,_y) = if ((_x > _y)) | |
76 | 74 | then _y | |
77 | 75 | else _x | |
78 | 76 | ||
79 | 77 | ||
80 | 78 | func toCompositeKey (_key,_address) = ((_key + "_") + _address) | |
81 | 79 | ||
82 | 80 | ||
83 | 81 | func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k)) | |
84 | 82 | ||
85 | 83 | ||
86 | 84 | func int0 (k) = valueOrElse(getInteger(this, k), 0) | |
87 | 85 | ||
88 | 86 | ||
89 | 87 | func totalSupply () = int0(k_totalSupply) | |
90 | 88 | ||
91 | 89 | ||
92 | 90 | func rewardPerTokenStored () = int0(k_rewardPerTokenStored) | |
93 | 91 | ||
94 | 92 | ||
95 | 93 | func lastUpdateTime () = int0(k_lastUpdateTime) | |
96 | 94 | ||
97 | 95 | ||
98 | 96 | func rewardRate () = int0(k_rewardRate) | |
99 | 97 | ||
100 | 98 | ||
101 | 99 | func periodFinish () = int0(k_periodFinish) | |
102 | 100 | ||
103 | 101 | ||
104 | 102 | func rewardBalance () = int0(k_rewardBalance) | |
105 | - | ||
106 | - | ||
107 | - | func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, k_swapAddress), "Now swap address")), "Invalid swap address") | |
108 | 103 | ||
109 | 104 | ||
110 | 105 | func rewards (_staker) = int0(toCompositeKey(k_userReward, _staker)) | |
111 | 106 | ||
112 | 107 | ||
113 | 108 | func userRewardPerTokenPaid (_staker) = int0(toCompositeKey(k_userRewardPerToken, _staker)) | |
114 | 109 | ||
115 | 110 | ||
116 | 111 | func balanceOf (_staker) = int0(toCompositeKey(k_balance, _staker)) | |
117 | 112 | ||
118 | 113 | ||
119 | 114 | func initialized () = valueOrElse(getBoolean(this, k_initialized), false) | |
120 | 115 | ||
121 | 116 | ||
122 | 117 | func updateRewardBalance (_delta) = [IntegerEntry(k_rewardBalance, (rewardBalance() + _delta))] | |
123 | 118 | ||
124 | 119 | ||
125 | 120 | func updateRewardRate (_rewardRate) = [IntegerEntry(k_rewardRate, _rewardRate)] | |
126 | 121 | ||
127 | 122 | ||
128 | 123 | func updateTime (_lastUpdateTime,_periodFinish) = [IntegerEntry(k_lastUpdateTime, _lastUpdateTime), IntegerEntry(k_periodFinish, _periodFinish)] | |
129 | 124 | ||
130 | 125 | ||
131 | 126 | func updateRewardPerTokenStored (_rewardPerTokenStored) = [IntegerEntry(k_rewardPerTokenStored, _rewardPerTokenStored)] | |
132 | 127 | ||
133 | 128 | ||
134 | 129 | func updateUserRewards (_staker,_reward,_userRewardPerToken) = [IntegerEntry(toCompositeKey(k_userReward, _staker), _reward), IntegerEntry(toCompositeKey(k_userRewardPerToken, _staker), _userRewardPerToken)] | |
135 | 130 | ||
136 | 131 | ||
137 | 132 | func updateBalance (_staker,_delta) = [IntegerEntry(toCompositeKey(k_balance, _staker), (balanceOf(_staker) + _delta)), IntegerEntry(k_totalSupply, (totalSupply() + _delta))] | |
138 | 133 | ||
139 | 134 | ||
140 | 135 | func currentTimestampSec () = (lastBlock.timestamp / 1000) | |
141 | 136 | ||
142 | 137 | ||
143 | 138 | func lastTimeRewardApplicable () = minv(currentTimestampSec(), periodFinish()) | |
144 | 139 | ||
145 | 140 | ||
146 | 141 | func rewardPerToken (_balanceDelta) = if (((totalSupply() + _balanceDelta) == 0)) | |
147 | 142 | then rewardPerTokenStored() | |
148 | 143 | else { | |
149 | 144 | let timeInterval = (lastTimeRewardApplicable() - lastUpdateTime()) | |
150 | 145 | let actualTimeInterval = if ((0 > timeInterval)) | |
151 | 146 | then 0 | |
152 | 147 | else timeInterval | |
153 | 148 | let diff = divd((rewardRate() * actualTimeInterval), (totalSupply() + _balanceDelta)) | |
154 | 149 | (rewardPerTokenStored() + diff) | |
155 | 150 | } | |
156 | 151 | ||
157 | 152 | ||
158 | 153 | func earned (_staker,_balanceDelta) = { | |
159 | 154 | let rewardDelta = (rewardPerToken(_balanceDelta) - userRewardPerTokenPaid(_staker)) | |
160 | 155 | (muld((balanceOf(_staker) + _balanceDelta), rewardDelta) + rewards(_staker)) | |
161 | 156 | } | |
162 | 157 | ||
163 | 158 | ||
164 | 159 | func updateReward (_staker,_balanceDelta) = { | |
165 | 160 | let newRewardPerTokenStored = rewardPerToken(_balanceDelta) | |
166 | 161 | let newLastUpdateTime = currentTimestampSec() | |
167 | - | let $ | |
162 | + | let $t053085500 = if ((_staker != "")) | |
168 | 163 | then $Tuple2(earned(_staker, _balanceDelta), newRewardPerTokenStored) | |
169 | 164 | else $Tuple2(0, 0) | |
170 | - | let stakerEarned = $ | |
171 | - | let stakerRewardPerTokenPaid = $ | |
165 | + | let stakerEarned = $t053085500._1 | |
166 | + | let stakerRewardPerTokenPaid = $t053085500._2 | |
172 | 167 | $Tuple4(newRewardPerTokenStored, newLastUpdateTime, stakerEarned, stakerRewardPerTokenPaid) | |
173 | 168 | } | |
174 | 169 | ||
175 | 170 | ||
176 | 171 | @Callable(i) | |
177 | - | func initialize (_coordinator,_swapAddress) = if (initialized()) | |
178 | - | then throw("Already initialized") | |
179 | - | else [StringEntry(k_coordinatorAddress, _coordinator), StringEntry(k_swapAddress, _swapAddress), BooleanEntry(k_initialized, true)] | |
180 | - | ||
181 | - | ||
182 | - | ||
183 | - | @Callable(i) | |
184 | - | func setSwap (_swapAddress) = if ((i.caller != adminAddress())) | |
185 | - | then throw("Invalid setSwap params") | |
186 | - | else [StringEntry(k_swapAddress, _swapAddress)] | |
172 | + | func initialize (_coordinator) = if (if (initialized()) | |
173 | + | then true | |
174 | + | else (i.caller != this)) | |
175 | + | then throw("Unable to initialize") | |
176 | + | else [StringEntry(k_coordinatorAddress, toString(addressFromStringValue(_coordinator))), BooleanEntry(k_initialized, true)] | |
187 | 177 | ||
188 | 178 | ||
189 | 179 | ||
190 | 180 | @Callable(i) | |
191 | 181 | func stake () = { | |
192 | 182 | let _staker = toString(i.caller) | |
193 | 183 | let _amount = i.payments[0].amount | |
194 | 184 | if (if ((i.payments[0].assetId != governanceAsset())) | |
195 | 185 | then true | |
196 | 186 | else !(initialized())) | |
197 | 187 | then throw("Invalid call to stake") | |
198 | 188 | else { | |
199 | - | let $ | |
200 | - | let newRewardPerTokenStored = $ | |
201 | - | let newLastUpdateTime = $ | |
202 | - | let stakerEarned = $ | |
203 | - | let stakerRewardPerTokenPaid = $ | |
189 | + | let $t062126377 = updateReward(_staker, 0) | |
190 | + | let newRewardPerTokenStored = $t062126377._1 | |
191 | + | let newLastUpdateTime = $t062126377._2 | |
192 | + | let stakerEarned = $t062126377._3 | |
193 | + | let stakerRewardPerTokenPaid = $t062126377._4 | |
204 | 194 | let doStake = invoke(stakingAddress(), "stake", nil, [AttachedPayment(governanceAsset(), _amount)]) | |
205 | 195 | if ((doStake == doStake)) | |
206 | 196 | then (((updateUserRewards(_staker, stakerEarned, stakerRewardPerTokenPaid) ++ updateRewardPerTokenStored(newRewardPerTokenStored)) ++ updateTime(newLastUpdateTime, periodFinish())) ++ updateBalance(_staker, _amount)) | |
207 | 197 | else throw("Strict value is not equal to itself.") | |
208 | 198 | } | |
209 | 199 | } | |
210 | 200 | ||
211 | 201 | ||
212 | 202 | ||
213 | 203 | @Callable(i) | |
214 | 204 | func unStake (_amount) = { | |
215 | 205 | let doAckRewards = invoke(this, "ackRewards", nil, nil) | |
216 | 206 | if ((doAckRewards == doAckRewards)) | |
217 | 207 | then { | |
218 | 208 | let _staker = toString(i.caller) | |
219 | 209 | if (if ((i.payments != nil)) | |
220 | 210 | then true | |
221 | 211 | else !(initialized())) | |
222 | 212 | then throw("Invalid unStake parameters") | |
223 | 213 | else { | |
224 | - | let $ | |
225 | - | let newRewardPerTokenStored = $ | |
226 | - | let newLastUpdateTime = $ | |
227 | - | let stakerEarned = $ | |
228 | - | let stakerRewardPerTokenPaid = $ | |
214 | + | let $t071237288 = updateReward(_staker, 0) | |
215 | + | let newRewardPerTokenStored = $t071237288._1 | |
216 | + | let newLastUpdateTime = $t071237288._2 | |
217 | + | let stakerEarned = $t071237288._3 | |
218 | + | let stakerRewardPerTokenPaid = $t071237288._4 | |
229 | 219 | if ((_amount > (balanceOf(_staker) + stakerEarned))) | |
230 | 220 | then throw("Invalid unStake parameters") | |
231 | 221 | else { | |
232 | 222 | let doUnStake = invoke(stakingAddress(), "unStake", [_amount], nil) | |
233 | 223 | if ((doUnStake == doUnStake)) | |
234 | 224 | then { | |
235 | 225 | let rewardChange = if ((balanceOf(_staker) >= _amount)) | |
236 | 226 | then 0 | |
237 | 227 | else (_amount - balanceOf(_staker)) | |
238 | 228 | let balanceChange = if ((balanceOf(_staker) >= _amount)) | |
239 | 229 | then _amount | |
240 | 230 | else balanceOf(_staker) | |
241 | 231 | (((((updateUserRewards(_staker, (stakerEarned - rewardChange), stakerRewardPerTokenPaid) ++ updateRewardPerTokenStored(newRewardPerTokenStored)) ++ updateTime(newLastUpdateTime, periodFinish())) ++ updateBalance(_staker, -(balanceChange))) ++ updateRewardBalance(-(rewardChange))) ++ [ScriptTransfer(i.caller, _amount, governanceAsset())]) | |
242 | 232 | } | |
243 | 233 | else throw("Strict value is not equal to itself.") | |
244 | 234 | } | |
245 | 235 | } | |
246 | 236 | } | |
247 | 237 | else throw("Strict value is not equal to itself.") | |
248 | 238 | } | |
249 | 239 | ||
250 | 240 | ||
251 | 241 | ||
252 | 242 | @Callable(i) | |
253 | 243 | func withdrawRewards () = { | |
254 | 244 | let doAckRewards = invoke(this, "ackRewards", nil, nil) | |
255 | 245 | if ((doAckRewards == doAckRewards)) | |
256 | 246 | then { | |
257 | 247 | let _staker = toString(i.caller) | |
258 | - | let $ | |
259 | - | let newRewardPerTokenStored = $ | |
260 | - | let newLastUpdateTime = $ | |
261 | - | let stakerEarned = $ | |
262 | - | let stakerRewardPerTokenPaid = $ | |
248 | + | let $t086268771 = updateReward(_staker, 0) | |
249 | + | let newRewardPerTokenStored = $t086268771._1 | |
250 | + | let newLastUpdateTime = $t086268771._2 | |
251 | + | let stakerEarned = $t086268771._3 | |
252 | + | let stakerRewardPerTokenPaid = $t086268771._4 | |
263 | 253 | if (if ((0 >= stakerEarned)) | |
264 | 254 | then true | |
265 | 255 | else !(initialized())) | |
266 | 256 | then throw("No farming reward") | |
267 | 257 | else { | |
268 | 258 | let doUnStake = invoke(stakingAddress(), "unStake", [stakerEarned], nil) | |
269 | 259 | if ((doUnStake == doUnStake)) | |
270 | 260 | then ((((updateUserRewards(_staker, 0, stakerRewardPerTokenPaid) ++ updateRewardPerTokenStored(newRewardPerTokenStored)) ++ updateTime(newLastUpdateTime, periodFinish())) ++ updateRewardBalance(-(stakerEarned))) ++ [ScriptTransfer(i.caller, stakerEarned, governanceAsset())]) | |
271 | 261 | else throw("Strict value is not equal to itself.") | |
272 | 262 | } | |
273 | 263 | } | |
274 | 264 | else throw("Strict value is not equal to itself.") | |
275 | 265 | } | |
276 | 266 | ||
277 | 267 | ||
278 | 268 | ||
279 | 269 | @Callable(i) | |
280 | 270 | func ackRewards () = { | |
281 | 271 | let _rewardAmount = invoke(stakingAddress(), "computeReward", [toString(this)], nil) | |
282 | 272 | if ((_rewardAmount == _rewardAmount)) | |
283 | 273 | then { | |
284 | 274 | let rewardAmount = match _rewardAmount { | |
285 | 275 | case t: Int => | |
286 | 276 | t | |
287 | 277 | case _ => | |
288 | 278 | throw("Reward amount not a number") | |
289 | 279 | } | |
290 | 280 | if (((1 * DECIMAL_UNIT) > rewardAmount)) | |
291 | 281 | then nil | |
292 | 282 | else { | |
293 | 283 | let doClaimRewards = invoke(stakingAddress(), "withdrawRewards", nil, nil) | |
294 | 284 | if ((doClaimRewards == doClaimRewards)) | |
295 | 285 | then { | |
296 | - | let rewardsAmount = assetBalance(this, | |
297 | - | let doSwap = invoke(swapAddress(), "swap", [toBase58String(governanceAsset()), 0], [AttachedPayment( | |
286 | + | let rewardsAmount = assetBalance(this, rewardAsset()) | |
287 | + | let doSwap = invoke(swapAddress(), "swap", [toBase58String(governanceAsset()), 0], [AttachedPayment(rewardAsset(), rewardsAmount)]) | |
298 | 288 | if ((doSwap == doSwap)) | |
299 | 289 | then { | |
300 | 290 | let rewardDelta = assetBalance(this, governanceAsset()) | |
301 | 291 | if ((rewardDelta == rewardDelta)) | |
302 | 292 | then if ((0 >= rewardDelta)) | |
303 | 293 | then throw("Invalid ackRewards params") | |
304 | 294 | else { | |
305 | 295 | let _reward = rewardDelta | |
306 | 296 | let newRewardPerTokenStored = updateReward(NO_ADDRESS, NO_STAKER)._1 | |
307 | 297 | let timestamp = currentTimestampSec() | |
308 | 298 | let newRewardRate = if ((timestamp > periodFinish())) | |
309 | 299 | then (_reward / DURATION) | |
310 | 300 | else { | |
311 | 301 | let remainingTime = (periodFinish() - timestamp) | |
312 | 302 | let leftover = (rewardRate() * remainingTime) | |
313 | 303 | ((_reward + leftover) / DURATION) | |
314 | 304 | } | |
315 | 305 | let doStake = invoke(stakingAddress(), "stake", nil, [AttachedPayment(governanceAsset(), rewardDelta)]) | |
316 | 306 | if ((doStake == doStake)) | |
317 | 307 | then (((updateRewardRate(newRewardRate) ++ updateRewardPerTokenStored(newRewardPerTokenStored)) ++ updateRewardBalance(_reward)) ++ updateTime(timestamp, (timestamp + DURATION))) | |
318 | 308 | else throw("Strict value is not equal to itself.") | |
319 | 309 | } | |
320 | 310 | else throw("Strict value is not equal to itself.") | |
321 | 311 | } | |
322 | 312 | else throw("Strict value is not equal to itself.") | |
323 | 313 | } | |
324 | 314 | else throw("Strict value is not equal to itself.") | |
325 | 315 | } | |
326 | 316 | } | |
327 | 317 | else throw("Strict value is not equal to itself.") | |
328 | 318 | } | |
329 | 319 | ||
330 | 320 | ||
331 | 321 | ||
332 | 322 | @Callable(i) | |
333 | 323 | func view_reward (_staker) = { | |
334 | 324 | let stakerEarned = updateReward(_staker, 0)._3 | |
335 | 325 | throw(toString(stakerEarned)) | |
336 | 326 | } | |
337 | 327 | ||
338 | 328 | ||
339 | 329 | @Verifier(tx) | |
340 | - | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey()) | |
330 | + | func verify () = { | |
331 | + | let coordinatorStr = getString(this, k_coordinatorAddress) | |
332 | + | if (isDefined(coordinatorStr)) | |
333 | + | then { | |
334 | + | let admin = getString(addressFromStringValue(value(coordinatorStr)), k_admin_address) | |
335 | + | if (isDefined(admin)) | |
336 | + | then valueOrElse(getBoolean(addressFromStringValue(value(admin)), ((("status_" + toString(this)) + "_") + toBase58String(tx.id))), false) | |
337 | + | else throw("unable to verify: admin not set in coordinator") | |
338 | + | } | |
339 | + | else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
340 | + | } | |
341 | 341 |
github/deemru/w8io/169f3d6 76.91 ms ◑