tx · D3PVQH9UExw5C2NusxkZETYytjddhiEAZnHRQ1xrbhwi

3N5yarEiTQccnnuerogYT3BxM5Zc5bRgDZy:  -0.04000000 Waves

2022.10.13 12:13 [2270392] smart account 3N5yarEiTQccnnuerogYT3BxM5Zc5bRgDZy > SELF 0.00000000 Waves

{ "type": 13, "id": "D3PVQH9UExw5C2NusxkZETYytjddhiEAZnHRQ1xrbhwi", "fee": 4000000, "feeAssetId": null, "timestamp": 1665652465316, "version": 1, "sender": "3N5yarEiTQccnnuerogYT3BxM5Zc5bRgDZy", "senderPublicKey": "FK9j3YFWVChXKESTn33fMZz1JseCNMMqHhfB7smxJo4e", "proofs": [ "27vykrr6BGpRxcmXXbnSHJJHyLbTCSPzevoHEKjYiQv3ythTtGLokWpdjh1rmXLc2tfMK3f7R5zrxgDZz6CksnvQ" ], "script": "base64:BgIqCAISBQoDAQgIEgASABIDCgEBEgASABIAEgMKAQgSBAoCCAESAwoBARIAWAAJc2VwYXJhdG9yAgJfXwADU0VQAgJfXwAFTVVMVDYAwIQ9AAVNVUxUOACAwtcvAAZNVUxUWDYJALYCAQUFTVVMVDYABk1VTFRYOAkAtgIBBQVNVUxUOAAHTVVMVFgxOAkAtgIBAICAkLu61q3wDQAKV0FWRVNJRFNUUgIFV0FWRVMAB1dBVkVTSUQJANkEAQUKV0FWRVNJRFNUUgAJREFZTUlMTElTAIC4mSkAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUHYWRkcmVzcwIBLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBEWtleUNvbnRyb2xBZGRyZXNzAAIcJXMlc19fY29uZmlnX19jb250cm9sQWRkcmVzcwENa2V5Q29udHJvbENmZwACESVzX19jb250cm9sQ29uZmlnARVrZXlHbnNidEZyb21TdXJmQ29lZmYAAh0lcyVzX19jZmdfX2duc2J0RnJvbVN1cmZDb2VmZgEUcmVhZENvbnRyb2xDZmdPckZhaWwBB2NvbnRyb2wJALUJAgkBD2dldFN0cmluZ09yRmFpbAIFB2NvbnRyb2wJAQ1rZXlDb250cm9sQ2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCCmNvbnRyb2xDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpjb250cm9sQ2ZnBQNpZHgJAKwCAgItQ29udHJvbCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAPY29udHJvbENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJARFrZXlDb250cm9sQWRkcmVzcwACIzNONE5TN2Q0Sm85YTZGMTRMaUZVS0tZVmRVa2tmMmVQNFp4AApjb250cm9sQ2ZnCQEUcmVhZENvbnRyb2xDZmdPckZhaWwBBQ9jb250cm9sQ29udHJhY3QADG1hdGhDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAQbmV1dHJpbm9Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAD2F1Y3Rpb25Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGElkeENvbnRyb2xDZmdBdWN0aW9uRGFwcAASZ25zYnRGcm9tU3VyZkNvZWZmCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARVrZXlHbnNidEZyb21TdXJmQ29lZmYAAKwCAQxrZXlCb25kQXNzZXQAAg1ib25kX2Fzc2V0X2lkARlrZXlBdWN0aW9uQ29udHJhY3RBZGRyZXNzAAIQYXVjdGlvbl9jb250cmFjdAEQa2V5TWluTG9ja0Ftb3VudAACESVzX19taW5Mb2NrQW1vdW50ARBrZXlTdGFrZWRBc3NldElkAAIRJXNfX3N0YWtlZEFzc2V0SWQBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgIGYW1vdW50BQNuaWwFCXNlcGFyYXRvcgEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawELdXNlckFkZHJlc3MJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgILcGFyYW1CeVVzZXIJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCAgVzdGFydAUDbmlsBQlzZXBhcmF0b3IBJmtleUxvY2tQYXJhbVZvdGluZ1Bvd2VyRWZmZWN0aXZlSGVpZ2h0AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgtwYXJhbUJ5VXNlcgkAzAgCCQClCAEFC3VzZXJBZGRyZXNzCQDMCAICEXZwRWZmZWN0aXZlSGVpZ2h0BQNuaWwFCXNlcGFyYXRvcgEQa2V5SGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwR0eElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgIHaGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgkA2AQBBQR0eElkBQNuaWwFCXNlcGFyYXRvcgEXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVzdGF0cwkAzAgCAhFhY3RpdmVUb3RhbExvY2tlZAUDbmlsBQlzZXBhcmF0b3IBEmtleVN0YXRzTG9ja3NDb3VudAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBXN0YXRzCQDMCAICCmxvY2tzQ291bnQFA25pbAUJc2VwYXJhdG9yARJrZXlTdGF0c1VzZXJzQ291bnQACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVzdGF0cwkAzAgCAhBhY3RpdmVVc2Vyc0NvdW50BQNuaWwFCXNlcGFyYXRvcgEXa2V5U3RhdHNEZXBvc2l0QW10QnlEYXkBCXRpbWVzdGFtcAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgVzdGF0cwkAzAgCAg9kZXBvc2l0QW10QnlEYXkJAMwIAgkApAMBBQl0aW1lc3RhbXAFA25pbAUJc2VwYXJhdG9yARhrZXlTdGF0c0RlcG9zaXRBbXRUb3RhbHMACQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBXN0YXRzCQDMCAICEGRlcG9zaXRBbXRUb3RhbHMFA25pbAUJc2VwYXJhdG9yAQ1rZXlOZXh0UGVyaW9kAAIOJXNfX25leHRQZXJpb2QBGGtleVN1cHBvcnRlZFJld2FyZEFzc2V0cwACFXN1cHBvcnRlZFJld2FyZEFzc2V0cwERa2V5RGVwb3NpdE51bUxhc3QACQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICA2RlcAkAzAgCAgdsYXN0TnVtBQNuaWwFCXNlcGFyYXRvcgEba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAhF1c2VyUndkRnJvbURlcE51bQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQlzZXBhcmF0b3IBFWtleVJld2FyZFBlck5zYnRTdW1BdAIKZGVwb3NpdE51bQN0a24JALkJAgkAzAgCAgQlcyVkCQDMCAICFXJ3ZFBlck5zYnRTdW1CeURlcE51bQkAzAgCCQCkAwEFCmRlcG9zaXROdW0JAMwIAgUDdGtuBQNuaWwFCXNlcGFyYXRvcgEJa2V5UmV3YXJkAgt1c2VyQWRkcmVzcwN0a24JALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIDcndkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFA3RrbgUDbmlsBQlzZXBhcmF0b3IBCmtleUNsYWltZWQCC3VzZXJBZGRyZXNzA3RrbgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgNjbG0JAMwIAgULdXNlckFkZHJlc3MJAMwIAgUDdGtuBQNuaWwFCXNlcGFyYXRvcgEXa2V5Tm90RGlzdHJpYnV0ZWRSZXdhcmQBA3RrbgkAuQkCCQDMCAICBCVzJXMJAMwIAgIObm90RGlzdHJpYnV0ZWQJAMwIAgUDdGtuBQNuaWwFCXNlcGFyYXRvcgEFdG9YMTgCB29yaWdWYWwIb3JpZ011bHQJALwCAwkAtgIBBQdvcmlnVmFsBQdNVUxUWDE4BQhvcmlnTXVsdAEMZ2V0SW50T3JaZXJvAQNrZXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5AAABDGdldEludE9yRWxzZQIDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5BQpkZWZhdWx0VmFsAQxnZXRJbnRPckZhaWwBA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFA2tleQkArAICCQCsAgICD01hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBDGdldFN0ck9yRWxzZQIDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUDa2V5BQpkZWZhdWx0VmFsAQ90b0FkZHJlc3NPckZhaWwBCmFkZHJlc3NTdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQphZGRyZXNzU3RyCQCsAgICIWNvdWxkbid0IHBhcnNlIHBhc3NlZCBhZGRyZXNzU3RyPQUKYWRkcmVzc1N0cgELdG9Bc3NldFZlY3QBCGFzc2V0U3RyAwkAAAIFCGFzc2V0U3RyBQpXQVZFU0lEU1RSBQR1bml0CQDZBAEFCGFzc2V0U3RyAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAESYXNTd2FwUGFyYW1zU1RSVUNUAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACIyhJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQpBAZzdHJ1Y3QFByRtYXRjaDAFBnN0cnVjdAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAETZm9ybWF0SGlzdG9yeVJlY29yZAQJb2xkQW1vdW50CG9sZFN0YXJ0CW5ld0Ftb3VudAhuZXdTdGFydAkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQlvbGRBbW91bnQJAMwIAgkApAMBBQhvbGRTdGFydAkAzAgCCQCkAwEFCW5ld0Ftb3VudAkAzAgCCQCkAwEFCG5ld1N0YXJ0BQNuaWwFCXNlcGFyYXRvcgEYZm9ybWF0Q2xhaW1IaXN0b3J5UmVjb3JkAgR1c2VyDmNsYWltZWRSZXdhcmRzCQC5CQIJAMwIAgIIJXMlZCVkJXMJAMwIAgUEdXNlcgkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgUOY2xhaW1lZFJld2FyZHMFA25pbAUJc2VwYXJhdG9yARJIaXN0b3J5UmVjb3JkRW50cnkHBHR5cGULdXNlckFkZHJlc3MEdHhJZAlvbGRBbW91bnQIb2xkU3RhcnQJbmV3QW1vdW50CG5ld1N0YXJ0CQELU3RyaW5nRW50cnkCCQEQa2V5SGlzdG9yeVJlY29yZAMFBHR5cGUFC3VzZXJBZGRyZXNzBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFCW9sZEFtb3VudAUIb2xkU3RhcnQFCW5ld0Ftb3VudAUIbmV3U3RhcnQBEUNsYWltSGlzdG9yeUVudHJ5Awt1c2VyQWRkcmVzcwR0eElkDmNsYWltZWRSZXdhcmRzCQELU3RyaW5nRW50cnkCCQEQa2V5SGlzdG9yeVJlY29yZAMCBWNsYWltBQt1c2VyQWRkcmVzcwUEdHhJZAkBGGZvcm1hdENsYWltSGlzdG9yeVJlY29yZAIJAKUIAQULdXNlckFkZHJlc3MFDmNsYWltZWRSZXdhcmRzAQtTdGF0c1Jlc3VsdAMOdG90YWxMb2NrZWRJbmMMbG9ja0NvdW50SW5jDXVzZXJzQ291bnRJbmMECmxvY2tzQ291bnQJAQxnZXRJbnRPclplcm8BCQESa2V5U3RhdHNMb2Nrc0NvdW50AAQKdXNlcnNDb3VudAkBDGdldEludE9yWmVybwEJARJrZXlTdGF0c1VzZXJzQ291bnQABAt0b3RhbEFtb3VudAkBDGdldEludE9yWmVybwEJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEDnRvdGFsQW1vdW50TmV3CQBkAgULdG90YWxBbW91bnQFDnRvdGFsTG9ja2VkSW5jCQCVCgMJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlTdGF0c0xvY2tzQ291bnQACQBkAgUKbG9ja3NDb3VudAUMbG9ja0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5U3RhdHNVc2Vyc0NvdW50AAkAZAIFCnVzZXJzQ291bnQFDXVzZXJzQ291bnRJbmMJAMwIAgkBDEludGVnZXJFbnRyeQIJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAFDnRvdGFsQW1vdW50TmV3BQNuaWwFC3RvdGFsQW1vdW50BQ50b3RhbEFtb3VudE5ldwEPTG9ja1BhcmFtc0VudHJ5Awt1c2VyQWRkcmVzcwZhbW91bnQadm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQULdXNlckFkZHJlc3MFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQt1c2VyQWRkcmVzcwUadm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQFA25pbAEPZ2V0UGFyYW1zT3JGYWlsAAkAlAoCCQDZBAEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQEQa2V5U3Rha2VkQXNzZXRJZAAJAQxnZXRJbnRPckZhaWwBCQEQa2V5TWluTG9ja0Ftb3VudAABDGlzQWN0aXZlVXNlcgELdXNlckFkZHJlc3MJAGYCCQEMZ2V0SW50T3JFbHNlAgkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwAAAAABE2dldFVzZXJQYXJhbXNPclVuaXQBC3VzZXJBZGRyZXNzAwkBDGlzQWN0aXZlVXNlcgEFC3VzZXJBZGRyZXNzCQCVCgMHCQEMZ2V0SW50T3JGYWlsAQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwkBDGdldEludE9yRmFpbAEJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQULdXNlckFkZHJlc3MFBHVuaXQBE2dldFVzZXJQYXJhbXNPckZhaWwBC3VzZXJBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQULdXNlckFkZHJlc3MJAKwCAgkArAICAgVVc2VyIAkApQgBBQt1c2VyQWRkcmVzcwIPIGlzIG5vdCBkZWZpbmVkABJzdXBwb3J0ZWRBc3NldHNTdHIJAQxnZXRTdHJPckVsc2UCCQEYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAIAABNzdXBwb3J0ZWRBc3NldHNMaXN0CQC1CQIFEnN1cHBvcnRlZEFzc2V0c1N0cgIBXwEKY2FsY1Jld2FyZAULdXNlckFkZHJlc3MHYXNzZXRJZA1zdGFrZWRBbW91bnRYDmRlcG9zaXROdW1Vc2VyDmRlcG9zaXROdW1MYXN0BBdyZXdhcmRQZXJOc2J0U3VtTGFzdEtFWQkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1MYXN0BQdhc3NldElkBApzdW1MYXN0WDE4CQCnAwEJAQxnZXRTdHJPckVsc2UCCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUOZGVwb3NpdE51bUxhc3QFB2Fzc2V0SWQCATAECnN1bVVzZXJYMTgJAKcDAQkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtVXNlcgUHYXNzZXRJZAIBMAQRcmV3YXJkRHluYW1pY1BhcnQJAKADAQkAvAIDCQC4AgIFCnN1bUxhc3RYMTgFCnN1bVVzZXJYMTgFDXN0YWtlZEFtb3VudFgFB01VTFRYMTgEE3Jld2FyZENhY2hlZFBhcnRLRVkJAQlrZXlSZXdhcmQCBQt1c2VyQWRkcmVzcwUHYXNzZXRJZAQQcmV3YXJkQ2FjaGVkUGFydAkBDGdldEludE9yRWxzZQIFE3Jld2FyZENhY2hlZFBhcnRLRVkAAAkAlgoECQBkAgUQcmV3YXJkQ2FjaGVkUGFydAURcmV3YXJkRHluYW1pY1BhcnQFEHJld2FyZENhY2hlZFBhcnQFEXJld2FyZER5bmFtaWNQYXJ0BRNyZXdhcmRDYWNoZWRQYXJ0S0VZAQx0b1N0YXJ0T2ZEYXkBCXRpbWVzdGFtcAkAaAIJAGkCBQl0aW1lc3RhbXAFCURBWU1JTExJUwUJREFZTUlMTElTARNmaW5kRWxlbWVudFBvc2l0aW9uAwNzcmMHZWxlbWVudANzZXAEDGVsZW1lbnRTdGFydAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCzCQIFA3NyYwUHZWxlbWVudAkArAICCQCsAgIJAKwCAgIWdGhlcmUgaXMgbm8gc3Vic3RyaW5nIAUHZWxlbWVudAIEIGluIAUDc3JjAwkAAAIFDGVsZW1lbnRTdGFydAAAAAAEBGxlZnQJAK8CAgUDc3JjBQxlbGVtZW50U3RhcnQJAGUCCQCQAwEJALUJAgUEbGVmdAUDc2VwAAEAE0RlcG9zaXRUb3RhbHNQUkVGSVgCJCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZAETdXBkYXRlRGVwb3NpdFRvdGFscwMHY3VyclZhbAtpZHhUb1VwZGF0ZQhkZWx0YUFtdAQHY3VyckFycgkAtQkCBQdjdXJyVmFsBQNTRVAKAQ51cGREZXBUb3RCeUlkeAEDaWR4AwkBAiE9AgUDaWR4BQtpZHhUb1VwZGF0ZQkAkQMCBQdjdXJyQXJyBQNpZHgJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdjdXJyQXJyBQNpZHgFCGRlbHRhQW10CQC5CQIJAMwIAgUTRGVwb3NpdFRvdGFsc1BSRUZJWAkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAAEJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQACCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEAAwkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAAQJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQAFCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEABgkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAAcJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQAICQDMCAIJAQ51cGREZXBUb3RCeUlkeAEACQkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAAoJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQALCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEADAkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAA0JAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQAOCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEADwkAzAgCCQEOdXBkRGVwVG90QnlJZHgBABAJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQARCQDMCAIJAQ51cGREZXBUb3RCeUlkeAEAEgUDbmlsBQNTRVABFURlcG9zaXRzVG90YWxzRW50cmllcwINZGVwb3NpdEFtb3VudAphc3NldElkU3RyBApzdGFydE9mRGF5CQEMdG9TdGFydE9mRGF5AQgFCWxhc3RCbG9jawl0aW1lc3RhbXAECGJ5RGF5S0VZCQEXa2V5U3RhdHNEZXBvc2l0QW10QnlEYXkBBQpzdGFydE9mRGF5BAl0b3RhbHNLRVkJARhrZXlTdGF0c0RlcG9zaXRBbXRUb3RhbHMABAhwb3NpdGlvbgkBE2ZpbmRFbGVtZW50UG9zaXRpb24DBRJzdXBwb3J0ZWRBc3NldHNTdHIFCmFzc2V0SWRTdHICAV8EC2RlZmF1bHREQVRBCQCsAgIFE0RlcG9zaXRUb3RhbHNQUkVGSVgCNl9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMF9fMAQOY3VyclRvdGFsc0RBVEEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUJdG90YWxzS0VZBQtkZWZhdWx0REFUQQQNbmV3VG90YWxzREFUQQkBE3VwZGF0ZURlcG9zaXRUb3RhbHMDBQ5jdXJyVG90YWxzREFUQQkAZAIFCHBvc2l0aW9uAAEFDWRlcG9zaXRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUJdG90YWxzS0VZBQ1uZXdUb3RhbHNEQVRBCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGJ5RGF5S0VZBQ1uZXdUb3RhbHNEQVRBBQNuaWwBDVJld2FyZEVudHJpZXMDCWlzTmV3VXNlcgt1c2VyQWRkcmVzcwxzdGFrZWRBbW91bnQEDXN0YWtlZEFtb3VudFgJALYCAQUMc3Rha2VkQW1vdW50BBt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJARtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0BBQt1c2VyQWRkcmVzcwQOZGVwb3NpdE51bVVzZXIJAQxnZXRJbnRPckVsc2UCBRt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA////////////AQQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCCQERa2V5RGVwb3NpdE51bUxhc3QAAP///////////wEKARtmb3JFYWNoQXNzZXRDYWNoZVVzZXJSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAxMTEyMDExMjU1CQEKY2FsY1Jld2FyZAUFC3VzZXJBZGRyZXNzBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDExMTIwMTEyNTUCXzEEBmNhY2hlZAgFDSR0MDExMTIwMTEyNTUCXzIEB2R5bmFtaWMIBQ0kdDAxMTEyMDExMjU1Al8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMTExMjAxMTI1NQJfNAkAzQgCBQVhY2N1bQkBDEludGVnZXJFbnRyeQIFE3Jld2FyZENhY2hlZFBhcnRLRVkFC3Jld2FyZFRvdGFsAwMJAAACBQ5kZXBvc2l0TnVtTGFzdAD///////////8BCQAAAgUOZGVwb3NpdE51bVVzZXIA////////////AQcFA25pbAMDCQAAAgUOZGVwb3NpdE51bUxhc3QA////////////AQkAZgIFDmRlcG9zaXROdW1Vc2VyAP///////////wEHCQACAQIvaW52YWxpZCBkZXBvc2l0TnVtTGFzdCBhbmQgZGVwb3NpdE51bVVzZXIgc3RhdGUDAwkAZgIFDmRlcG9zaXROdW1MYXN0AP///////////wEJAGcCBQ5kZXBvc2l0TnVtVXNlcgD///////////8BBwMFCWlzTmV3VXNlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAUDbmlsCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEbZm9yRWFjaEFzc2V0Q2FjaGVVc2VyUmV3YXJkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA5CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAkAAgEJAKwCAgkArAICCQCsAgICJHVuY292ZXJlZCBjb25kaXRpb246IGRlcG9zaXROdW1MYXN0PQkApAMBBQ5kZXBvc2l0TnVtTGFzdAIQIGRlcG9zaXROdW1Vc2VyPQkApAMBBQ5kZXBvc2l0TnVtVXNlcgEiSW5jcmVtZW50Tm90RGlzdHJpYnV0ZWRSZXdhcmRFbnRyeQIDdGtuCWFtb3VudEluYwQXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJARdrZXlOb3REaXN0cmlidXRlZFJld2FyZAEFA3RrbgQUbm90RGlzdHJpYnV0ZWRSZXdhcmQJAQxnZXRJbnRPckVsc2UCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQkAZAIFFG5vdERpc3RyaWJ1dGVkUmV3YXJkBQlhbW91bnRJbmMFA25pbAELc3VyZlRvR25zYnQBB3N1cmZBbXQJAGkCBQdzdXJmQW10BRJnbnNidEZyb21TdXJmQ29lZmYBH21lcmdlVm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQEEHF1YXJhbnRpbmVQZXJpb2QRdnBFZmZlY3RpdmVIZWlnaHQJc3Rha2VkQW10DHN0YWtlZEFtdE5FVwQPcmVtYWluaW5nVG9XYWl0CQBlAgURdnBFZmZlY3RpdmVIZWlnaHQFBmhlaWdodAMJAGcCAAAFD3JlbWFpbmluZ1RvV2FpdAkAZAIFBmhlaWdodAUQcXVhcmFudGluZVBlcmlvZAQNYWxyZWFkeVdhaXRlZAkAZQIFEHF1YXJhbnRpbmVQZXJpb2QFD3JlbWFpbmluZ1RvV2FpdAQDa1g4AwkBAiE9AgUMc3Rha2VkQW10TkVXAAAJAGsDBQlzdGFrZWRBbXQFBU1VTFQ4BQxzdGFrZWRBbXRORVcFEXZwRWZmZWN0aXZlSGVpZ2h0CQBlAgkAZAIFEHF1YXJhbnRpbmVQZXJpb2QFBmhlaWdodAkAawMFDWFscmVhZHlXYWl0ZWQFA2tYOAUFTVVMVDgBCm1lcmdlU3Rha2UCC3VzZXJBZGRyZXNzC2Ftb3VudFRvQWRkBA0kdDAxNDkwNzE1MDE3CQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMTQ5MDcxNTAxNwJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTQ5MDcxNTAxNwJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQ0kdDAxNDkwNzE1MDE3Al8zBA9zdGFrZWRBbW91bnRORVcDBQlpc05ld1VzZXIFC2Ftb3VudFRvQWRkCQBkAgULYW1vdW50VG9BZGQFDHN0YWtlZEFtb3VudAQQcXVhcmFudGluZVBlcmlvZAkAaAIAoAsADgQUdnBFZmZlY3RpdmVIZWlnaHRORVcDBQlpc05ld1VzZXIJAGQCBRBxdWFyYW50aW5lUGVyaW9kBQZoZWlnaHQJAR9tZXJnZVZvdGluZ1Bvd2VyRWZmZWN0aXZlSGVpZ2h0BAUQcXVhcmFudGluZVBlcmlvZAURdnBFZmZlY3RpdmVIZWlnaHQFDHN0YWtlZEFtb3VudAUPc3Rha2VkQW1vdW50TkVXCQCXCgUFCWlzTmV3VXNlcgUMc3Rha2VkQW1vdW50BRF2cEVmZmVjdGl2ZUhlaWdodAUPc3Rha2VkQW1vdW50TkVXBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwELY29tbW9uU3Rha2UCC3VzZXJBZGRyZXNzAWkEDSR0MDE1NTAzMTU1NTcJAQ9nZXRQYXJhbXNPckZhaWwABA1zdGFrZWRBc3NldElkCAUNJHQwMTU1MDMxNTU1NwJfMQQNbWluTG9ja0Ftb3VudAgFDSR0MDE1NTAzMTU1NTcCXzIDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhVJbnZhbGlkIHBheW1lbnRzIHNpemUEB3BheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQGYW1vdW50CAUHcGF5bWVudAZhbW91bnQEE2ludmFsaWRBc3NldE1lc3NhZ2UJAKwCAgkArAICAg9JbnZhbGlkIGFzc2V0LiAJANgEAQUNc3Rha2VkQXNzZXRJZAIMIGlzIGV4cGVjdGVkBAdhc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIIBQdwYXltZW50B2Fzc2V0SWQFE2ludmFsaWRBc3NldE1lc3NhZ2UDCQECIT0CBQdhc3NldElkBQ1zdGFrZWRBc3NldElkCQACAQUTaW52YWxpZEFzc2V0TWVzc2FnZQQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MECm1lcmdlZERhdGEJAQptZXJnZVN0YWtlAgULdXNlckFkZHJlc3MFBmFtb3VudAQJaXNOZXdVc2VyCAUKbWVyZ2VkRGF0YQJfMQQMc3Rha2VkQW1vdW50CAUKbWVyZ2VkRGF0YQJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80BBR2cEVmZmVjdGl2ZUhlaWdodE5FVwgFCm1lcmdlZERhdGECXzUDCQBmAgUNbWluTG9ja0Ftb3VudAUPc3Rha2VkQW1vdW50TkVXCQACAQkArAICAhNNaW4gbG9jayBhbW91bnQgaXMgCQCkAwEFDW1pbkxvY2tBbW91bnQEDSR0MDE2MzU2MTY0NTgJAQtTdGF0c1Jlc3VsdAMFBmFtb3VudAABAwUJaXNOZXdVc2VyAAEAAAQMc3RhdHNFbnRyaWVzCAUNJHQwMTYzNTYxNjQ1OAJfMQQLdG90YWxTdGFrZWQIBQ0kdDAxNjM1NjE2NDU4Al8yBA50b3RhbFN0YWtlZE5ldwgFDSR0MDE2MzU2MTY0NTgCXzMJAM4IAgkAzggCCQDOCAIJAMwIAgkBEkhpc3RvcnlSZWNvcmRFbnRyeQcCBXN0YWtlBQt1c2VyQWRkcmVzcwgFAWkNdHJhbnNhY3Rpb25JZAUMc3Rha2VkQW1vdW50BRF2cEVmZmVjdGl2ZUhlaWdodAUPc3Rha2VkQW1vdW50TkVXBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwUDbmlsCQENUmV3YXJkRW50cmllcwMFCWlzTmV3VXNlcgUOdXNlckFkZHJlc3NTdHIFDHN0YWtlZEFtb3VudAkBD0xvY2tQYXJhbXNFbnRyeQMFC3VzZXJBZGRyZXNzBQ9zdGFrZWRBbW91bnRORVcFFHZwRWZmZWN0aXZlSGVpZ2h0TkVXBQxzdGF0c0VudHJpZXMBC2NvbW1vbkNsYWltAgt1c2VyQWRkcmVzcwFpBA51c2VyQWRkcmVzc1N0cgkApQgBBQt1c2VyQWRkcmVzcwMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhlwYXltZW50cyBhcmUgbm90IGFjY2VwdGVkBA0kdDAxNjkzNzE3MDQyCQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMTY5MzcxNzA0MgJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTY5MzcxNzA0MgJfMgQMc3Rha2luZ1N0YXJ0CAUNJHQwMTY5MzcxNzA0MgJfMwQNc3Rha2VkQW1vdW50WAkAtgIBBQxzdGFrZWRBbW91bnQEG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQEFDnVzZXJBZGRyZXNzU3RyBA5kZXBvc2l0TnVtVXNlcgkBDGdldEludE9yRWxzZQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD///////////8BBA5kZXBvc2l0TnVtTGFzdAkBDGdldEludE9yRWxzZQIJARFrZXlEZXBvc2l0TnVtTGFzdAAA////////////AQoBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAxNzQxMzE3NTUxCQEKY2FsY1Jld2FyZAUFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDE3NDEzMTc1NTECXzEEBmNhY2hlZAgFDSR0MDE3NDEzMTc1NTECXzIEB2R5bmFtaWMIBQ0kdDAxNzQxMzE3NTUxAl8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMTc0MTMxNzU1MQJfNAQKY2xhaW1lZEtFWQkBCmtleUNsYWltZWQCBQ51c2VyQWRkcmVzc1N0cgUFYXNzZXQEDSR0MDE3NjExMTc2NDgFBWFjY3VtBARkYXRhCAUNJHQwMTc2MTExNzY0OAJfMQQRY2xhaW1lZEFtdEJ5QXNzZXQIBQ0kdDAxNzYxMTE3NjQ4Al8yBAduZXdQYXJ0CQC5CQIJAMwIAgUFYXNzZXQJAMwIAgkApAMBBQtyZXdhcmRUb3RhbAUDbmlsAgE6BBRjbGFpbWVkQW10QnlBc3NldE5ldwkAuQkCCQDMCAIFEWNsYWltZWRBbXRCeUFzc2V0CQDMCAIFB25ld1BhcnQFA25pbAIBXwMJAGcCAAAFC3Jld2FyZFRvdGFsCQCUCgIFBGRhdGEFFGNsYWltZWRBbXRCeUFzc2V0TmV3CQCUCgIJAM0IAgkAzQgCCQDNCAIFBGRhdGEJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQtyZXdhcmRUb3RhbAkBC3RvQXNzZXRWZWN0AQUFYXNzZXQJAQxJbnRlZ2VyRW50cnkCBQpjbGFpbWVkS0VZCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQpjbGFpbWVkS0VZAAAFC3Jld2FyZFRvdGFsCQEMSW50ZWdlckVudHJ5AgUTcmV3YXJkQ2FjaGVkUGFydEtFWQAABRRjbGFpbWVkQW10QnlBc3NldE5ldwQNJHQwMTgxMDgxODIyMQoAAiRsBRNzdXBwb3J0ZWRBc3NldHNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwCAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgOQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQQJdHJhbnNmZXJzCAUNJHQwMTgxMDgxODIyMQJfMQQXY2xhaW1lZEFtdEJ5QXNzZXRSZXN1bHQIBQ0kdDAxODEwODE4MjIxAl8yAwkAZwIAAAkAkAMBBQl0cmFuc2ZlcnMJAJQKAgUDbmlsAAAJAJQKAgkAzQgCCQDNCAIFCXRyYW5zZmVycwkBDEludGVnZXJFbnRyeQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQUOZGVwb3NpdE51bUxhc3QJARFDbGFpbUhpc3RvcnlFbnRyeQMFC3VzZXJBZGRyZXNzCAUBaQ10cmFuc2FjdGlvbklkCQCwAgIFF2NsYWltZWRBbXRCeUFzc2V0UmVzdWx0AAEJAJADAQUJdHJhbnNmZXJzCwFpAQtjb25zdHJ1Y3RvcgMNbWluTG9ja0Ftb3VudBVzdXBwb3J0ZWRSZXdhcmRBc3NldHMNc3Rha2VkQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEQa2V5TWluTG9ja0Ftb3VudAAFDW1pbkxvY2tBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGGtleVN1cHBvcnRlZFJld2FyZEFzc2V0cwAFFXN1cHBvcnRlZFJld2FyZEFzc2V0cwkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U3Rha2VkQXNzZXRJZAAFDXN0YWtlZEFzc2V0SWQFA25pbAFpAQVzdGFrZQAJAQtjb21tb25TdGFrZQIIBQFpBmNhbGxlcgUBaQFpARNzdGFrZUJ5T3JpZ2luQ2FsbGVyAAkBC2NvbW1vblN0YWtlAggFAWkMb3JpZ2luQ2FsbGVyBQFpAWkBB3Vuc3Rha2UBBmFtb3VudAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECI3Vuc3Rha2UgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50BAt1c2VyQWRkcmVzcwgFAWkGY2FsbGVyBA51c2VyQWRkcmVzc1N0cgkApQgBBQt1c2VyQWRkcmVzcwQNJHQwMTkxNTUxOTIwOQkBD2dldFBhcmFtc09yRmFpbAAEDXN0YWtlZEFzc2V0SWQIBQ0kdDAxOTE1NTE5MjA5Al8xBA1taW5Mb2NrQW1vdW50CAUNJHQwMTkxNTUxOTIwOQJfMgQNJHQwMTkyMTIxOTI5NgkBE2dldFVzZXJQYXJhbXNPckZhaWwBBQt1c2VyQWRkcmVzcwQJaXNOZXdVc2VyCAUNJHQwMTkyMTIxOTI5NgJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTkyMTIxOTI5NgJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQ0kdDAxOTIxMjE5Mjk2Al8zBBBzd2FwUGFyYW1zU1RSVUNUCQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/QcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgAABQNuaWwFA25pbAQUc3dhcExpbWl0U3BlbnRJblVzZG4IBRBzd2FwUGFyYW1zU1RSVUNUAl8yBA5ibGNrczJMbXRSZXNldAgFEHN3YXBQYXJhbXNTVFJVQ1QCXzMDCQBmAgUUc3dhcExpbWl0U3BlbnRJblVzZG4AAAkAAgEJAKwCAgkArAICAi1Zb3UgaGF2ZSBhbHJlYWR5IG1hZGUgYSBzd2FwIG9wZXJhdGlvbi4gV2FpdCAJAKQDAQkAZAIFBmhlaWdodAUOYmxja3MyTG10UmVzZXQCEiBoZWlnaHQgdG8gdW5zdGFrZQMJAGcCAAAFDHN0YWtlZEFtb3VudAkAAgECEk5vdGhpbmcgdG8gdW5zdGFrZQMJAGYCBQZhbW91bnQFDHN0YWtlZEFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICClJlcXVlc3RlZCAJAKQDAQUGYW1vdW50AhIsIGJ1dCBzdGFrZWQgb25seSAJAKQDAQUMc3Rha2VkQW1vdW50BA9zdGFrZWRBbW91bnRORVcJAGUCBQxzdGFrZWRBbW91bnQFBmFtb3VudAQNJHQwMTk5MzQyMDA5MgkBC1N0YXRzUmVzdWx0AwkBAS0BBQZhbW91bnQDCQAAAgUGYW1vdW50BQxzdGFrZWRBbW91bnQA////////////AQAAAwkAAAIFBmFtb3VudAUMc3Rha2VkQW1vdW50AP///////////wEAAAQMc3RhdHNFbnRyaWVzCAUNJHQwMTk5MzQyMDA5MgJfMQQLdG90YWxTdGFrZWQIBQ0kdDAxOTkzNDIwMDkyAl8yBA50b3RhbFN0YWtlZE5ldwgFDSR0MDE5OTM0MjAwOTICXzMJAM4IAgkAzggCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFBmFtb3VudAUNc3Rha2VkQXNzZXRJZAkAzAgCCQESSGlzdG9yeVJlY29yZEVudHJ5BwIHdW5zdGFrZQULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQFDHN0YWtlZEFtb3VudAURdnBFZmZlY3RpdmVIZWlnaHQFD3N0YWtlZEFtb3VudE5FVwURdnBFZmZlY3RpdmVIZWlnaHQFA25pbAkBDVJld2FyZEVudHJpZXMDBwUOdXNlckFkZHJlc3NTdHIFDHN0YWtlZEFtb3VudAkBD0xvY2tQYXJhbXNFbnRyeQMFC3VzZXJBZGRyZXNzBQ9zdGFrZWRBbW91bnRORVcFEXZwRWZmZWN0aXZlSGVpZ2h0BQxzdGF0c0VudHJpZXMBaQEHZGVwb3NpdAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAh9leGFjdCAxIHBheW1lbnQgaXMgYWxsb3dlZCBvbmx5BANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQGYW1vdW50CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBC3ZhbHVlT3JFbHNlAggFA3BtdAdhc3NldElkBQdXQVZFU0lEBA1wbXRBc3NldElkU3RyCQDYBAEFCnBtdEFzc2V0SWQECHBtdE11bHRYAwkAAAIFCnBtdEFzc2V0SWQFB1dBVkVTSUQFBk1VTFRYOAUGTVVMVFg2BAdhbW91bnRYCQC2AgEFBmFtb3VudAQLdG90YWxTdGFrZWQJAQxnZXRJbnRPckVsc2UCCQEXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQAAAAEDHRvdGFsU3Rha2VkWAkAtgIBBQt0b3RhbFN0YWtlZAMJAGYCAAAFC3RvdGFsU3Rha2VkCQACAQIbVE9ETzogY2FzZSBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFC3RvdGFsU3Rha2VkAAAJASJJbmNyZW1lbnROb3REaXN0cmlidXRlZFJld2FyZEVudHJ5AgUNcG10QXNzZXRJZFN0cgUGYW1vdW50BBByZXdhcmRQZXJOc2J0WDE4CQC8AgMFB2Ftb3VudFgFB01VTFRYMTgFDHRvdGFsU3Rha2VkWAQRZGVwb3NpdE51bUxhc3RLRVkJARFrZXlEZXBvc2l0TnVtTGFzdAAEDmRlcG9zaXROdW1MYXN0CQEMZ2V0SW50T3JFbHNlAgURZGVwb3NpdE51bUxhc3RLRVkA////////////AQQNZGVwb3NpdE51bU5ldwkAZAIFDmRlcG9zaXROdW1MYXN0AAEDCQEBIQEJAQhjb250YWlucwIFEnN1cHBvcnRlZEFzc2V0c1N0cgUNcG10QXNzZXRJZFN0cgkAAgEJAKwCAgkArAICBRJzdXBwb3J0ZWRBc3NldHNTdHICESBkb2Vzbid0IGNvbnRhaW4gBQ1wbXRBc3NldElkU3RyCgEXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0CBWFjY3VtCW5leHRBc3NldAQWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDWRlcG9zaXROdW1OZXcFCW5leHRBc3NldAQKc3VtTGFzdFN0cgkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtTGFzdAUJbmV4dEFzc2V0AgEwCQDNCAIFBWFjY3VtAwkAAAIFCW5leHRBc3NldAUNcG10QXNzZXRJZFN0cgkBC1N0cmluZ0VudHJ5AgUWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQkApgMBCQC3AgIJAKcDAQUKc3VtTGFzdFN0cgUQcmV3YXJkUGVyTnNidFgxOAkBC1N0cmluZ0VudHJ5AgUWcmV3YXJkUGVyTnNidFN1bU5ld0tFWQUKc3VtTGFzdFN0cgkAzggCCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDkJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkJAQxJbnRlZ2VyRW50cnkCBRFkZXBvc2l0TnVtTGFzdEtFWQUNZGVwb3NpdE51bU5ldwkBFURlcG9zaXRzVG90YWxzRW50cmllcwIFBmFtb3VudAUNcG10QXNzZXRJZFN0cgFpAQxjbGFpbVJld2FyZHMACQELY29tbW9uQ2xhaW0CCAUBaQZjYWxsZXIFAWkBaQEaY2xhaW1SZXdhcmRzQnlPcmlnaW5DYWxsZXIACQELY29tbW9uQ2xhaW0CCAUBaQxvcmlnaW5DYWxsZXIFAWkBaQEYdW5jbGFpbWVkUmV3YXJkc1JFQURPTkxZAQ51c2VyQWRkcmVzc1N0cgoBFmZvckVhY2hBc3NldFplcm9SZXdhcmQCBWFjY3VtBWFzc2V0CQCsAgIJAKwCAgUFYWNjdW0JALkJAgkAzAgCBQVhc3NldAkAzAgCAgEwCQDMCAICATAFA25pbAIBOgIBXwQSdW5jbGFpbWVkUmV3YXJkU3RyAwkAAAIFDnVzZXJBZGRyZXNzU3RyAgAKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWZm9yRWFjaEFzc2V0WmVyb1Jld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgOQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQQLdXNlckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDnVzZXJBZGRyZXNzU3RyBA0kdDAyMjcxNjIyODIxCQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMjI3MTYyMjgyMQJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMjI3MTYyMjgyMQJfMgQMc3Rha2luZ1N0YXJ0CAUNJHQwMjI3MTYyMjgyMQJfMwQNc3Rha2VkQW1vdW50WAkAtgIBBQxzdGFrZWRBbW91bnQEG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQEFDnVzZXJBZGRyZXNzU3RyBA5kZXBvc2l0TnVtVXNlcgkBDGdldEludE9yRWxzZQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD///////////8BBA5kZXBvc2l0TnVtTGFzdAkBDGdldEludE9yRWxzZQIJARFrZXlEZXBvc2l0TnVtTGFzdAAA////////////AQoBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAyMzE2NzIzMzA1CQEKY2FsY1Jld2FyZAUFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDIzMTY3MjMzMDUCXzEEBmNhY2hlZAgFDSR0MDIzMTY3MjMzMDUCXzIEB2R5bmFtaWMIBQ0kdDAyMzE2NzIzMzA1Al8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMjMxNjcyMzMwNQJfNAQHY2xhaW1lZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEKa2V5Q2xhaW1lZAIFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAAACQCsAgIJAKwCAgUFYWNjdW0JALkJAgkAzAgCBQVhc3NldAkAzAgCCQCkAwEFC3Jld2FyZFRvdGFsCQDMCAIJAKQDAQUHY2xhaW1lZAUDbmlsAgE6AgFfCgACJGwFE3N1cHBvcnRlZEFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDkJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkJAJQKAgUDbmlsCQCzAgIFEnVuY2xhaW1lZFJld2FyZFN0cgABAWkBFnN1cmZTdGFraW5nU1lTUkVBRE9OTFkCFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQhzdXJmRGlmZgQJc3VyZlRvdGFsCQEMZ2V0SW50T3JFbHNlAgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAABBJnbnNidEZyb21TdXJmVG90YWwJAQtzdXJmVG9HbnNidAEFCXN1cmZUb3RhbAMJAAACBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkCAAkAlAoCBQNuaWwJAMwIAgAACQDMCAIFCXN1cmZUb3RhbAkAzAgCAAAJAMwIAgUSZ25zYnRGcm9tU3VyZlRvdGFsCQDMCAIAAAkAzAgCBQZoZWlnaHQJAMwIAgUGaGVpZ2h0BQNuaWwEC3VzZXJBZGRyZXNzCQEPdG9BZGRyZXNzT3JGYWlsAQUVdXNlckFkZHJlc3NTdHJPckVtcHR5BAptZXJnZWREYXRhCQEKbWVyZ2VTdGFrZQIFC3VzZXJBZGRyZXNzBQhzdXJmRGlmZgQJaXNOZXdVc2VyCAUKbWVyZ2VkRGF0YQJfMQQMc3Rha2VkQW1vdW50CAUKbWVyZ2VkRGF0YQJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80BBR2cEVmZmVjdGl2ZUhlaWdodE5FVwgFCm1lcmdlZERhdGECXzUECHN1cmZVc2VyBQxzdGFrZWRBbW91bnQEEWduc2J0RnJvbVN1cmZVc2VyCQELc3VyZlRvR25zYnQBBQhzdXJmVXNlcgkAlAoCBQNuaWwJAMwIAgUIc3VyZlVzZXIJAMwIAgUJc3VyZlRvdGFsCQDMCAIFEWduc2J0RnJvbVN1cmZVc2VyCQDMCAIFEmduc2J0RnJvbVN1cmZUb3RhbAkAzAgCBRF2cEVmZmVjdGl2ZUhlaWdodAkAzAgCBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwUDbmlsAWkBGGduc2J0RnJvbVN1cmZTWVNSRUFET05MWQEHc3VyZkFtdAkAlAoCBQNuaWwJAQtzdXJmVG9HbnNidAEFB3N1cmZBbXQBaQERY29uZmlnU1lTUkVBRE9OTFkABAptaW5Mb2NrQW10CQERQGV4dHJOYXRpdmUoMTA1NSkBCQEQa2V5TWluTG9ja0Ftb3VudAAEIHN1cmZWb3RpbmdQb3dlclJlc3RyaWN0aXZlUGVyaW9kCQBoAgCgCwAOBBticlRvU3RhcnRTdXJmVHJhbnNmb3JtYXRpb24AsJhGCQCUCgIFA25pbAkAzAgCBQptaW5Mb2NrQW10CQDMCAIJAGgCBRJnbnNidEZyb21TdXJmQ29lZmYFBU1VTFQ2CQDMCAIFIHN1cmZWb3RpbmdQb3dlclJlc3RyaWN0aXZlUGVyaW9kCQDMCAIFG2JyVG9TdGFydFN1cmZUcmFuc2Zvcm1hdGlvbgUDbmlsAOjaJWw=", "chainId": 84, "height": 2270392, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4baeR1NLQcGbhAvGVafwveABprDax3iCKbAwMLFjZ8Xb Next: 8jMpDxhfGn11M1m7QqTccXb6n7P8EDQju6YCe2kjdH2J Diff:
OldNewDifferences
1818 let WAVESIDSTR = "WAVES"
1919
2020 let WAVESID = fromBase58String(WAVESIDSTR)
21+
22+let DAYMILLIS = 86400000
2123
2224 let IdxControlCfgNeutrinoDapp = 1
2325
102104
103105
104106 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], separator)
107+
108+
109+func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], separator)
110+
111+
112+func keyStatsDepositAmtTotals () = makeString(["%s%s%d", "stats", "depositAmtTotals"], separator)
105113
106114
107115 func keyNextPeriod () = "%s__nextPeriod"
220228 }
221229
222230
231+func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
232+
233+
234+func findElementPosition (src,element,sep) = {
235+ let elementStart = valueOrErrorMessage(indexOf(src, element), ((("there is no substring " + element) + " in ") + src))
236+ if ((elementStart == 0))
237+ then 0
238+ else {
239+ let left = take(src, elementStart)
240+ (size(split(left, sep)) - 1)
241+ }
242+ }
243+
244+
245+let DepositTotalsPREFIX = "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
246+
247+func updateDepositTotals (currVal,idxToUpdate,deltaAmt) = {
248+ let currArr = split(currVal, SEP)
249+ func updDepTotByIdx (idx) = if ((idx != idxToUpdate))
250+ then currArr[idx]
251+ else toString((parseIntValue(currArr[idx]) + deltaAmt))
252+
253+ makeString([DepositTotalsPREFIX, updDepTotByIdx(1), updDepTotByIdx(2), updDepTotByIdx(3), updDepTotByIdx(4), updDepTotByIdx(5), updDepTotByIdx(6), updDepTotByIdx(7), updDepTotByIdx(8), updDepTotByIdx(9), updDepTotByIdx(10), updDepTotByIdx(11), updDepTotByIdx(12), updDepTotByIdx(13), updDepTotByIdx(14), updDepTotByIdx(15), updDepTotByIdx(16), updDepTotByIdx(17), updDepTotByIdx(18)], SEP)
254+ }
255+
256+
257+func DepositsTotalsEntries (depositAmount,assetIdStr) = {
258+ let startOfDay = toStartOfDay(lastBlock.timestamp)
259+ let byDayKEY = keyStatsDepositAmtByDay(startOfDay)
260+ let totalsKEY = keyStatsDepositAmtTotals()
261+ let position = findElementPosition(supportedAssetsStr, assetIdStr, "_")
262+ let defaultDATA = (DepositTotalsPREFIX + "__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0")
263+ let currTotalsDATA = valueOrElse(getString(this, totalsKEY), defaultDATA)
264+ let newTotalsDATA = updateDepositTotals(currTotalsDATA, (position + 1), depositAmount)
265+[StringEntry(totalsKEY, newTotalsDATA), StringEntry(byDayKEY, newTotalsDATA)]
266+ }
267+
268+
223269 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
224270 let stakedAmountX = toBigInt(stakedAmount)
225271 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
226272 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
227273 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
228274 func forEachAssetCacheUserReward (accum,asset) = {
229- let $t089529087 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
230- let rewardTotal = $t089529087._1
231- let cached = $t089529087._2
232- let dynamic = $t089529087._3
233- let rewardCachedPartKEY = $t089529087._4
275+ let $t01112011255 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
276+ let rewardTotal = $t01112011255._1
277+ let cached = $t01112011255._2
278+ let dynamic = $t01112011255._3
279+ let rewardCachedPartKEY = $t01112011255._4
234280 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
235281 }
236282
257303
258304 func $f0_2 ($a,$i) = if (($i >= $s))
259305 then $a
260- else throw("List size exceeds 10")
306+ else throw("List size exceeds 9")
261307
262- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
308+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
263309 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
264310 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
265311 }
290336
291337
292338 func mergeStake (userAddress,amountToAdd) = {
293- let $t01274012850 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
294- let isNewUser = $t01274012850._1
295- let stakedAmount = $t01274012850._2
296- let vpEffectiveHeight = $t01274012850._3
339+ let $t01490715017 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
340+ let isNewUser = $t01490715017._1
341+ let stakedAmount = $t01490715017._2
342+ let vpEffectiveHeight = $t01490715017._3
297343 let stakedAmountNEW = if (isNewUser)
298344 then amountToAdd
299345 else (amountToAdd + stakedAmount)
306352
307353
308354 func commonStake (userAddress,i) = {
309- let $t01333613390 = getParamsOrFail()
310- let stakedAssetId = $t01333613390._1
311- let minLockAmount = $t01333613390._2
355+ let $t01550315557 = getParamsOrFail()
356+ let stakedAssetId = $t01550315557._1
357+ let minLockAmount = $t01550315557._2
312358 if ((size(i.payments) != 1))
313359 then throw("Invalid payments size")
314360 else {
329375 if ((minLockAmount > stakedAmountNEW))
330376 then throw(("Min lock amount is " + toString(minLockAmount)))
331377 else {
332- let $t01418914291 = StatsResult(amount, 1, if (isNewUser)
378+ let $t01635616458 = StatsResult(amount, 1, if (isNewUser)
333379 then 1
334380 else 0)
335- let statsEntries = $t01418914291._1
336- let totalStaked = $t01418914291._2
337- let totalStakedNew = $t01418914291._3
381+ let statsEntries = $t01635616458._1
382+ let totalStaked = $t01635616458._2
383+ let totalStakedNew = $t01635616458._3
338384 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeightNEW)) ++ statsEntries)
339385 }
340386 }
347393 if ((size(i.payments) > 0))
348394 then throw("payments are not accepted")
349395 else {
350- let $t01477014875 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
351- let isNewUser = $t01477014875._1
352- let stakedAmount = $t01477014875._2
353- let stakingStart = $t01477014875._3
396+ let $t01693717042 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
397+ let isNewUser = $t01693717042._1
398+ let stakedAmount = $t01693717042._2
399+ let stakingStart = $t01693717042._3
354400 let stakedAmountX = toBigInt(stakedAmount)
355401 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
356402 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
357403 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
358404 func forEachAssetCalcUnclaimedReward (accum,asset) = {
359- let $t01524615384 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
360- let rewardTotal = $t01524615384._1
361- let cached = $t01524615384._2
362- let dynamic = $t01524615384._3
363- let rewardCachedPartKEY = $t01524615384._4
405+ let $t01741317551 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
406+ let rewardTotal = $t01741317551._1
407+ let cached = $t01741317551._2
408+ let dynamic = $t01741317551._3
409+ let rewardCachedPartKEY = $t01741317551._4
364410 let claimedKEY = keyClaimed(userAddressStr, asset)
365- let $t01544415481 = accum
366- let data = $t01544415481._1
367- let claimedAmtByAsset = $t01544415481._2
411+ let $t01761117648 = accum
412+ let data = $t01761117648._1
413+ let claimedAmtByAsset = $t01761117648._2
368414 let newPart = makeString([asset, toString(rewardTotal)], ":")
369415 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
370416 if ((0 >= rewardTotal))
372418 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
373419 }
374420
375- let $t01594116055 = {
421+ let $t01810818221 = {
376422 let $l = supportedAssetsList
377423 let $s = size($l)
378424 let $acc0 = $Tuple2(nil, "")
382428
383429 func $f0_2 ($a,$i) = if (($i >= $s))
384430 then $a
385- else throw("List size exceeds 10")
431+ else throw("List size exceeds 9")
386432
387- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
433+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
388434 }
389- let transfers = $t01594116055._1
390- let claimedAmtByAssetResult = $t01594116055._2
435+ let transfers = $t01810818221._1
436+ let claimedAmtByAssetResult = $t01810818221._2
391437 if ((0 >= size(transfers)))
392- then nil
393- else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
438+ then $Tuple2(nil, 0)
439+ else $Tuple2(((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1))), size(transfers))
394440 }
395441 }
396442
418464 else {
419465 let userAddress = i.caller
420466 let userAddressStr = toString(userAddress)
421- let $t01696417018 = getParamsOrFail()
422- let stakedAssetId = $t01696417018._1
423- let minLockAmount = $t01696417018._2
424- let $t01702117105 = getUserParamsOrFail(userAddress)
425- let isNewUser = $t01702117105._1
426- let stakedAmount = $t01702117105._2
427- let vpEffectiveHeight = $t01702117105._3
467+ let $t01915519209 = getParamsOrFail()
468+ let stakedAssetId = $t01915519209._1
469+ let minLockAmount = $t01915519209._2
470+ let $t01921219296 = getUserParamsOrFail(userAddress)
471+ let isNewUser = $t01921219296._1
472+ let stakedAmount = $t01921219296._2
473+ let vpEffectiveHeight = $t01921219296._3
428474 let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
429475 let swapLimitSpentInUsdn = swapParamsSTRUCT._2
430476 let blcks2LmtReset = swapParamsSTRUCT._3
436482 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
437483 else {
438484 let stakedAmountNEW = (stakedAmount - amount)
439- let $t01774317901 = StatsResult(-(amount), if ((amount == stakedAmount))
485+ let $t01993420092 = StatsResult(-(amount), if ((amount == stakedAmount))
440486 then -1
441487 else 0, if ((amount == stakedAmount))
442488 then -1
443489 else 0)
444- let statsEntries = $t01774317901._1
445- let totalStaked = $t01774317901._2
446- let totalStakedNew = $t01774317901._3
490+ let statsEntries = $t01993420092._1
491+ let totalStaked = $t01993420092._2
492+ let totalStakedNew = $t01993420092._3
447493 ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
448494 }
449495 }
484530 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
485531 }
486532
487- ({
533+ (({
488534 let $l = supportedAssetsList
489535 let $s = size($l)
490536 let $acc0 = nil
494540
495541 func $f0_2 ($a,$i) = if (($i >= $s))
496542 then $a
497- else throw("List size exceeds 10")
543+ else throw("List size exceeds 9")
498544
499- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
500- } :+ IntegerEntry(depositNumLastKEY, depositNumNew))
545+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
546+ } :+ IntegerEntry(depositNumLastKEY, depositNumNew)) ++ DepositsTotalsEntries(amount, pmtAssetIdStr))
501547 }
502548 }
503549 }
529575
530576 func $f0_2 ($a,$i) = if (($i >= $s))
531577 then $a
532- else throw("List size exceeds 10")
578+ else throw("List size exceeds 9")
533579
534- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
580+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
535581 }
536582 else {
537583 let userAddress = addressFromStringValue(userAddressStr)
538- let $t02047520580 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
539- let isNewUser = $t02047520580._1
540- let stakedAmount = $t02047520580._2
541- let stakingStart = $t02047520580._3
584+ let $t02271622821 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
585+ let isNewUser = $t02271622821._1
586+ let stakedAmount = $t02271622821._2
587+ let stakingStart = $t02271622821._3
542588 let stakedAmountX = toBigInt(stakedAmount)
543589 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
544590 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
545591 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
546592 func forEachAssetCalcUnclaimedReward (accum,asset) = {
547- let $t02092621064 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
548- let rewardTotal = $t02092621064._1
549- let cached = $t02092621064._2
550- let dynamic = $t02092621064._3
551- let rewardCachedPartKEY = $t02092621064._4
593+ let $t02316723305 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
594+ let rewardTotal = $t02316723305._1
595+ let cached = $t02316723305._2
596+ let dynamic = $t02316723305._3
597+ let rewardCachedPartKEY = $t02316723305._4
552598 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
553599 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
554600 }
562608
563609 func $f0_2 ($a,$i) = if (($i >= $s))
564610 then $a
565- else throw("List size exceeds 10")
611+ else throw("List size exceeds 9")
566612
567- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
613+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
568614 }
569615 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
570616 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let SEP = "__"
77
88 let MULT6 = 1000000
99
1010 let MULT8 = 100000000
1111
1212 let MULTX6 = toBigInt(MULT6)
1313
1414 let MULTX8 = toBigInt(MULT8)
1515
1616 let MULTX18 = toBigInt(1000000000000000000)
1717
1818 let WAVESIDSTR = "WAVES"
1919
2020 let WAVESID = fromBase58String(WAVESIDSTR)
21+
22+let DAYMILLIS = 86400000
2123
2224 let IdxControlCfgNeutrinoDapp = 1
2325
2426 let IdxControlCfgAuctionDapp = 2
2527
2628 let IdxControlCfgRpdDapp = 3
2729
2830 let IdxControlCfgMathDapp = 4
2931
3032 let IdxControlCfgLiquidationDapp = 5
3133
3234 let IdxControlCfgRestDapp = 6
3335
3436 let IdxControlCfgNodeRegistryDapp = 7
3537
3638 let IdxControlCfgNsbtStakingDapp = 8
3739
3840 let IdxControlCfgMediatorDapp = 9
3941
4042 let IdxControlCfgSurfStakingDapp = 10
4143
4244 let IdxControlCfgGnsbtControllerDapp = 11
4345
4446 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
4547
4648
4749 func keyControlAddress () = "%s%s__config__controlAddress"
4850
4951
5052 func keyControlCfg () = "%s__controlConfig"
5153
5254
5355 func keyGnsbtFromSurfCoeff () = "%s%s__cfg__gnsbtFromSurfCoeff"
5456
5557
5658 func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
5759
5860
5961 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
6062
6163
6264 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
6365
6466 let controlCfg = readControlCfgOrFail(controlContract)
6567
6668 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
6769
6870 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
6971
7072 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
7173
7274 let gnsbtFromSurfCoeff = valueOrElse(getInteger(this, keyGnsbtFromSurfCoeff()), 300)
7375
7476 func keyBondAsset () = "bond_asset_id"
7577
7678
7779 func keyAuctionContractAddress () = "auction_contract"
7880
7981
8082 func keyMinLockAmount () = "%s__minLockAmount"
8183
8284
8385 func keyStakedAssetId () = "%s__stakedAssetId"
8486
8587
8688 func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], separator)
8789
8890
8991 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], separator)
9092
9193
9294 func keyLockParamVotingPowerEffectiveHeight (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "vpEffectiveHeight"], separator)
9395
9496
9597 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, toString(userAddress), toBase58String(txId)], separator)
9698
9799
98100 func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], separator)
99101
100102
101103 func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], separator)
102104
103105
104106 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], separator)
107+
108+
109+func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], separator)
110+
111+
112+func keyStatsDepositAmtTotals () = makeString(["%s%s%d", "stats", "depositAmtTotals"], separator)
105113
106114
107115 func keyNextPeriod () = "%s__nextPeriod"
108116
109117
110118 func keySupportedRewardAssets () = "supportedRewardAssets"
111119
112120
113121 func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], separator)
114122
115123
116124 func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], separator)
117125
118126
119127 func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], separator)
120128
121129
122130 func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], separator)
123131
124132
125133 func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], separator)
126134
127135
128136 func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], separator)
129137
130138
131139 func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
132140
133141
134142 func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
135143
136144
137145 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
138146
139147
140148 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
141149
142150
143151 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
144152
145153
146154 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
147155
148156
149157 func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
150158 then unit
151159 else fromBase58String(assetStr)
152160
153161
154162 func asInt (val) = match val {
155163 case valInt: Int =>
156164 valInt
157165 case _ =>
158166 throw("fail to cast into Int")
159167 }
160168
161169
162170 func asSwapParamsSTRUCT (v) = match v {
163171 case struct: (Int, Int, Int, Int, Int, Int, Int) =>
164172 struct
165173 case _ =>
166174 throw("fail to cast into Int")
167175 }
168176
169177
170178 func formatHistoryRecord (oldAmount,oldStart,newAmount,newStart) = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(oldAmount), toString(oldStart), toString(newAmount), toString(newStart)], separator)
171179
172180
173181 func formatClaimHistoryRecord (user,claimedRewards) = makeString(["%s%d%d%s", user, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], separator)
174182
175183
176184 func HistoryRecordEntry (type,userAddress,txId,oldAmount,oldStart,newAmount,newStart) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(oldAmount, oldStart, newAmount, newStart))
177185
178186
179187 func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(toString(userAddress), claimedRewards))
180188
181189
182190 func StatsResult (totalLockedInc,lockCountInc,usersCountInc) = {
183191 let locksCount = getIntOrZero(keyStatsLocksCount())
184192 let usersCount = getIntOrZero(keyStatsUsersCount())
185193 let totalAmount = getIntOrZero(keyLockParamTotalAmount())
186194 let totalAmountNew = (totalAmount + totalLockedInc)
187195 $Tuple3([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew)], totalAmount, totalAmountNew)
188196 }
189197
190198
191199 func LockParamsEntry (userAddress,amount,votingPowerEffectiveHeight) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), votingPowerEffectiveHeight)]
192200
193201
194202 func getParamsOrFail () = $Tuple2(fromBase58String(getStringOrFail(this, keyStakedAssetId())), getIntOrFail(keyMinLockAmount()))
195203
196204
197205 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
198206
199207
200208 func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
201209 then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
202210 else unit
203211
204212
205213 func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
206214
207215
208216 let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
209217
210218 let supportedAssetsList = split(supportedAssetsStr, "_")
211219
212220 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
213221 let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
214222 let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
215223 let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
216224 let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
217225 let rewardCachedPartKEY = keyReward(userAddress, assetId)
218226 let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
219227 $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
220228 }
221229
222230
231+func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
232+
233+
234+func findElementPosition (src,element,sep) = {
235+ let elementStart = valueOrErrorMessage(indexOf(src, element), ((("there is no substring " + element) + " in ") + src))
236+ if ((elementStart == 0))
237+ then 0
238+ else {
239+ let left = take(src, elementStart)
240+ (size(split(left, sep)) - 1)
241+ }
242+ }
243+
244+
245+let DepositTotalsPREFIX = "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
246+
247+func updateDepositTotals (currVal,idxToUpdate,deltaAmt) = {
248+ let currArr = split(currVal, SEP)
249+ func updDepTotByIdx (idx) = if ((idx != idxToUpdate))
250+ then currArr[idx]
251+ else toString((parseIntValue(currArr[idx]) + deltaAmt))
252+
253+ makeString([DepositTotalsPREFIX, updDepTotByIdx(1), updDepTotByIdx(2), updDepTotByIdx(3), updDepTotByIdx(4), updDepTotByIdx(5), updDepTotByIdx(6), updDepTotByIdx(7), updDepTotByIdx(8), updDepTotByIdx(9), updDepTotByIdx(10), updDepTotByIdx(11), updDepTotByIdx(12), updDepTotByIdx(13), updDepTotByIdx(14), updDepTotByIdx(15), updDepTotByIdx(16), updDepTotByIdx(17), updDepTotByIdx(18)], SEP)
254+ }
255+
256+
257+func DepositsTotalsEntries (depositAmount,assetIdStr) = {
258+ let startOfDay = toStartOfDay(lastBlock.timestamp)
259+ let byDayKEY = keyStatsDepositAmtByDay(startOfDay)
260+ let totalsKEY = keyStatsDepositAmtTotals()
261+ let position = findElementPosition(supportedAssetsStr, assetIdStr, "_")
262+ let defaultDATA = (DepositTotalsPREFIX + "__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0__0")
263+ let currTotalsDATA = valueOrElse(getString(this, totalsKEY), defaultDATA)
264+ let newTotalsDATA = updateDepositTotals(currTotalsDATA, (position + 1), depositAmount)
265+[StringEntry(totalsKEY, newTotalsDATA), StringEntry(byDayKEY, newTotalsDATA)]
266+ }
267+
268+
223269 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
224270 let stakedAmountX = toBigInt(stakedAmount)
225271 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
226272 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
227273 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
228274 func forEachAssetCacheUserReward (accum,asset) = {
229- let $t089529087 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
230- let rewardTotal = $t089529087._1
231- let cached = $t089529087._2
232- let dynamic = $t089529087._3
233- let rewardCachedPartKEY = $t089529087._4
275+ let $t01112011255 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
276+ let rewardTotal = $t01112011255._1
277+ let cached = $t01112011255._2
278+ let dynamic = $t01112011255._3
279+ let rewardCachedPartKEY = $t01112011255._4
234280 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
235281 }
236282
237283 if (if ((depositNumLast == -1))
238284 then (depositNumUser == -1)
239285 else false)
240286 then nil
241287 else if (if ((depositNumLast == -1))
242288 then (depositNumUser > -1)
243289 else false)
244290 then throw("invalid depositNumLast and depositNumUser state")
245291 else if (if ((depositNumLast > -1))
246292 then (depositNumUser >= -1)
247293 else false)
248294 then if (isNewUser)
249295 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
250296 else ({
251297 let $l = supportedAssetsList
252298 let $s = size($l)
253299 let $acc0 = nil
254300 func $f0_1 ($a,$i) = if (($i >= $s))
255301 then $a
256302 else forEachAssetCacheUserReward($a, $l[$i])
257303
258304 func $f0_2 ($a,$i) = if (($i >= $s))
259305 then $a
260- else throw("List size exceeds 10")
306+ else throw("List size exceeds 9")
261307
262- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
308+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
263309 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
264310 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
265311 }
266312
267313
268314 func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
269315 let notDistributedRewardKEY = keyNotDistributedReward(tkn)
270316 let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
271317 [IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
272318 }
273319
274320
275321 func surfToGnsbt (surfAmt) = (surfAmt / gnsbtFromSurfCoeff)
276322
277323
278324 func mergeVotingPowerEffectiveHeight (quarantinePeriod,vpEffectiveHeight,stakedAmt,stakedAmtNEW) = {
279325 let remainingToWait = (vpEffectiveHeight - height)
280326 if ((0 >= remainingToWait))
281327 then (height + quarantinePeriod)
282328 else {
283329 let alreadyWaited = (quarantinePeriod - remainingToWait)
284330 let kX8 = if ((stakedAmtNEW != 0))
285331 then fraction(stakedAmt, MULT8, stakedAmtNEW)
286332 else vpEffectiveHeight
287333 ((quarantinePeriod + height) - fraction(alreadyWaited, kX8, MULT8))
288334 }
289335 }
290336
291337
292338 func mergeStake (userAddress,amountToAdd) = {
293- let $t01274012850 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
294- let isNewUser = $t01274012850._1
295- let stakedAmount = $t01274012850._2
296- let vpEffectiveHeight = $t01274012850._3
339+ let $t01490715017 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
340+ let isNewUser = $t01490715017._1
341+ let stakedAmount = $t01490715017._2
342+ let vpEffectiveHeight = $t01490715017._3
297343 let stakedAmountNEW = if (isNewUser)
298344 then amountToAdd
299345 else (amountToAdd + stakedAmount)
300346 let quarantinePeriod = (1440 * 14)
301347 let vpEffectiveHeightNEW = if (isNewUser)
302348 then (quarantinePeriod + height)
303349 else mergeVotingPowerEffectiveHeight(quarantinePeriod, vpEffectiveHeight, stakedAmount, stakedAmountNEW)
304350 $Tuple5(isNewUser, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)
305351 }
306352
307353
308354 func commonStake (userAddress,i) = {
309- let $t01333613390 = getParamsOrFail()
310- let stakedAssetId = $t01333613390._1
311- let minLockAmount = $t01333613390._2
355+ let $t01550315557 = getParamsOrFail()
356+ let stakedAssetId = $t01550315557._1
357+ let minLockAmount = $t01550315557._2
312358 if ((size(i.payments) != 1))
313359 then throw("Invalid payments size")
314360 else {
315361 let payment = i.payments[0]
316362 let amount = payment.amount
317363 let invalidAssetMessage = (("Invalid asset. " + toBase58String(stakedAssetId)) + " is expected")
318364 let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
319365 if ((assetId != stakedAssetId))
320366 then throw(invalidAssetMessage)
321367 else {
322368 let userAddressStr = toString(userAddress)
323369 let mergedData = mergeStake(userAddress, amount)
324370 let isNewUser = mergedData._1
325371 let stakedAmount = mergedData._2
326372 let vpEffectiveHeight = mergedData._3
327373 let stakedAmountNEW = mergedData._4
328374 let vpEffectiveHeightNEW = mergedData._5
329375 if ((minLockAmount > stakedAmountNEW))
330376 then throw(("Min lock amount is " + toString(minLockAmount)))
331377 else {
332- let $t01418914291 = StatsResult(amount, 1, if (isNewUser)
378+ let $t01635616458 = StatsResult(amount, 1, if (isNewUser)
333379 then 1
334380 else 0)
335- let statsEntries = $t01418914291._1
336- let totalStaked = $t01418914291._2
337- let totalStakedNew = $t01418914291._3
381+ let statsEntries = $t01635616458._1
382+ let totalStaked = $t01635616458._2
383+ let totalStakedNew = $t01635616458._3
338384 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeightNEW)) ++ statsEntries)
339385 }
340386 }
341387 }
342388 }
343389
344390
345391 func commonClaim (userAddress,i) = {
346392 let userAddressStr = toString(userAddress)
347393 if ((size(i.payments) > 0))
348394 then throw("payments are not accepted")
349395 else {
350- let $t01477014875 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
351- let isNewUser = $t01477014875._1
352- let stakedAmount = $t01477014875._2
353- let stakingStart = $t01477014875._3
396+ let $t01693717042 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
397+ let isNewUser = $t01693717042._1
398+ let stakedAmount = $t01693717042._2
399+ let stakingStart = $t01693717042._3
354400 let stakedAmountX = toBigInt(stakedAmount)
355401 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
356402 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
357403 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
358404 func forEachAssetCalcUnclaimedReward (accum,asset) = {
359- let $t01524615384 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
360- let rewardTotal = $t01524615384._1
361- let cached = $t01524615384._2
362- let dynamic = $t01524615384._3
363- let rewardCachedPartKEY = $t01524615384._4
405+ let $t01741317551 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
406+ let rewardTotal = $t01741317551._1
407+ let cached = $t01741317551._2
408+ let dynamic = $t01741317551._3
409+ let rewardCachedPartKEY = $t01741317551._4
364410 let claimedKEY = keyClaimed(userAddressStr, asset)
365- let $t01544415481 = accum
366- let data = $t01544415481._1
367- let claimedAmtByAsset = $t01544415481._2
411+ let $t01761117648 = accum
412+ let data = $t01761117648._1
413+ let claimedAmtByAsset = $t01761117648._2
368414 let newPart = makeString([asset, toString(rewardTotal)], ":")
369415 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
370416 if ((0 >= rewardTotal))
371417 then $Tuple2(data, claimedAmtByAssetNew)
372418 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
373419 }
374420
375- let $t01594116055 = {
421+ let $t01810818221 = {
376422 let $l = supportedAssetsList
377423 let $s = size($l)
378424 let $acc0 = $Tuple2(nil, "")
379425 func $f0_1 ($a,$i) = if (($i >= $s))
380426 then $a
381427 else forEachAssetCalcUnclaimedReward($a, $l[$i])
382428
383429 func $f0_2 ($a,$i) = if (($i >= $s))
384430 then $a
385- else throw("List size exceeds 10")
431+ else throw("List size exceeds 9")
386432
387- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
433+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
388434 }
389- let transfers = $t01594116055._1
390- let claimedAmtByAssetResult = $t01594116055._2
435+ let transfers = $t01810818221._1
436+ let claimedAmtByAssetResult = $t01810818221._2
391437 if ((0 >= size(transfers)))
392- then nil
393- else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
438+ then $Tuple2(nil, 0)
439+ else $Tuple2(((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1))), size(transfers))
394440 }
395441 }
396442
397443
398444 @Callable(i)
399445 func constructor (minLockAmount,supportedRewardAssets,stakedAssetId) = if ((i.caller != this))
400446 then throw("Permission denied")
401447 else [IntegerEntry(keyMinLockAmount(), minLockAmount), StringEntry(keySupportedRewardAssets(), supportedRewardAssets), StringEntry(keyStakedAssetId(), stakedAssetId)]
402448
403449
404450
405451 @Callable(i)
406452 func stake () = commonStake(i.caller, i)
407453
408454
409455
410456 @Callable(i)
411457 func stakeByOriginCaller () = commonStake(i.originCaller, i)
412458
413459
414460
415461 @Callable(i)
416462 func unstake (amount) = if ((size(i.payments) != 0))
417463 then throw("unstake doesn't require any payment")
418464 else {
419465 let userAddress = i.caller
420466 let userAddressStr = toString(userAddress)
421- let $t01696417018 = getParamsOrFail()
422- let stakedAssetId = $t01696417018._1
423- let minLockAmount = $t01696417018._2
424- let $t01702117105 = getUserParamsOrFail(userAddress)
425- let isNewUser = $t01702117105._1
426- let stakedAmount = $t01702117105._2
427- let vpEffectiveHeight = $t01702117105._3
467+ let $t01915519209 = getParamsOrFail()
468+ let stakedAssetId = $t01915519209._1
469+ let minLockAmount = $t01915519209._2
470+ let $t01921219296 = getUserParamsOrFail(userAddress)
471+ let isNewUser = $t01921219296._1
472+ let stakedAmount = $t01921219296._2
473+ let vpEffectiveHeight = $t01921219296._3
428474 let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
429475 let swapLimitSpentInUsdn = swapParamsSTRUCT._2
430476 let blcks2LmtReset = swapParamsSTRUCT._3
431477 if ((swapLimitSpentInUsdn > 0))
432478 then throw((("You have already made a swap operation. Wait " + toString((height + blcks2LmtReset))) + " height to unstake"))
433479 else if ((0 >= stakedAmount))
434480 then throw("Nothing to unstake")
435481 else if ((amount > stakedAmount))
436482 then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
437483 else {
438484 let stakedAmountNEW = (stakedAmount - amount)
439- let $t01774317901 = StatsResult(-(amount), if ((amount == stakedAmount))
485+ let $t01993420092 = StatsResult(-(amount), if ((amount == stakedAmount))
440486 then -1
441487 else 0, if ((amount == stakedAmount))
442488 then -1
443489 else 0)
444- let statsEntries = $t01774317901._1
445- let totalStaked = $t01774317901._2
446- let totalStakedNew = $t01774317901._3
490+ let statsEntries = $t01993420092._1
491+ let totalStaked = $t01993420092._2
492+ let totalStakedNew = $t01993420092._3
447493 ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
448494 }
449495 }
450496
451497
452498
453499 @Callable(i)
454500 func deposit () = if ((size(i.payments) != 1))
455501 then throw("exact 1 payment is allowed only")
456502 else {
457503 let pmt = i.payments[0]
458504 let amount = pmt.amount
459505 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
460506 let pmtAssetIdStr = toBase58String(pmtAssetId)
461507 let pmtMultX = if ((pmtAssetId == WAVESID))
462508 then MULTX8
463509 else MULTX6
464510 let amountX = toBigInt(amount)
465511 let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
466512 let totalStakedX = toBigInt(totalStaked)
467513 if ((0 > totalStaked))
468514 then throw("TODO: case is not supported")
469515 else if ((totalStaked == 0))
470516 then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
471517 else {
472518 let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
473519 let depositNumLastKEY = keyDepositNumLast()
474520 let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
475521 let depositNumNew = (depositNumLast + 1)
476522 if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
477523 then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
478524 else {
479525 func refreshRewardPerNsbtSUM (accum,nextAsset) = {
480526 let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
481527 let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
482528 (accum :+ (if ((nextAsset == pmtAssetIdStr))
483529 then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
484530 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
485531 }
486532
487- ({
533+ (({
488534 let $l = supportedAssetsList
489535 let $s = size($l)
490536 let $acc0 = nil
491537 func $f0_1 ($a,$i) = if (($i >= $s))
492538 then $a
493539 else refreshRewardPerNsbtSUM($a, $l[$i])
494540
495541 func $f0_2 ($a,$i) = if (($i >= $s))
496542 then $a
497- else throw("List size exceeds 10")
543+ else throw("List size exceeds 9")
498544
499- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
500- } :+ IntegerEntry(depositNumLastKEY, depositNumNew))
545+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
546+ } :+ IntegerEntry(depositNumLastKEY, depositNumNew)) ++ DepositsTotalsEntries(amount, pmtAssetIdStr))
501547 }
502548 }
503549 }
504550
505551
506552
507553 @Callable(i)
508554 func claimRewards () = commonClaim(i.caller, i)
509555
510556
511557
512558 @Callable(i)
513559 func claimRewardsByOriginCaller () = commonClaim(i.originCaller, i)
514560
515561
516562
517563 @Callable(i)
518564 func unclaimedRewardsREADONLY (userAddressStr) = {
519565 func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
520566
521567 let unclaimedRewardStr = if ((userAddressStr == ""))
522568 then {
523569 let $l = supportedAssetsList
524570 let $s = size($l)
525571 let $acc0 = ""
526572 func $f0_1 ($a,$i) = if (($i >= $s))
527573 then $a
528574 else forEachAssetZeroReward($a, $l[$i])
529575
530576 func $f0_2 ($a,$i) = if (($i >= $s))
531577 then $a
532- else throw("List size exceeds 10")
578+ else throw("List size exceeds 9")
533579
534- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
580+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
535581 }
536582 else {
537583 let userAddress = addressFromStringValue(userAddressStr)
538- let $t02047520580 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
539- let isNewUser = $t02047520580._1
540- let stakedAmount = $t02047520580._2
541- let stakingStart = $t02047520580._3
584+ let $t02271622821 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
585+ let isNewUser = $t02271622821._1
586+ let stakedAmount = $t02271622821._2
587+ let stakingStart = $t02271622821._3
542588 let stakedAmountX = toBigInt(stakedAmount)
543589 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
544590 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
545591 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
546592 func forEachAssetCalcUnclaimedReward (accum,asset) = {
547- let $t02092621064 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
548- let rewardTotal = $t02092621064._1
549- let cached = $t02092621064._2
550- let dynamic = $t02092621064._3
551- let rewardCachedPartKEY = $t02092621064._4
593+ let $t02316723305 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
594+ let rewardTotal = $t02316723305._1
595+ let cached = $t02316723305._2
596+ let dynamic = $t02316723305._3
597+ let rewardCachedPartKEY = $t02316723305._4
552598 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
553599 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
554600 }
555601
556602 let $l = supportedAssetsList
557603 let $s = size($l)
558604 let $acc0 = ""
559605 func $f0_1 ($a,$i) = if (($i >= $s))
560606 then $a
561607 else forEachAssetCalcUnclaimedReward($a, $l[$i])
562608
563609 func $f0_2 ($a,$i) = if (($i >= $s))
564610 then $a
565- else throw("List size exceeds 10")
611+ else throw("List size exceeds 9")
566612
567- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
613+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9)
568614 }
569615 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
570616 }
571617
572618
573619
574620 @Callable(i)
575621 func surfStakingSYSREADONLY (userAddressStrOrEmpty,surfDiff) = {
576622 let surfTotal = getIntOrElse(keyLockParamTotalAmount(), 0)
577623 let gnsbtFromSurfTotal = surfToGnsbt(surfTotal)
578624 if ((userAddressStrOrEmpty == ""))
579625 then $Tuple2(nil, [0, surfTotal, 0, gnsbtFromSurfTotal, 0, height, height])
580626 else {
581627 let userAddress = toAddressOrFail(userAddressStrOrEmpty)
582628 let mergedData = mergeStake(userAddress, surfDiff)
583629 let isNewUser = mergedData._1
584630 let stakedAmount = mergedData._2
585631 let vpEffectiveHeight = mergedData._3
586632 let stakedAmountNEW = mergedData._4
587633 let vpEffectiveHeightNEW = mergedData._5
588634 let surfUser = stakedAmount
589635 let gnsbtFromSurfUser = surfToGnsbt(surfUser)
590636 $Tuple2(nil, [surfUser, surfTotal, gnsbtFromSurfUser, gnsbtFromSurfTotal, vpEffectiveHeight, vpEffectiveHeightNEW])
591637 }
592638 }
593639
594640
595641
596642 @Callable(i)
597643 func gnsbtFromSurfSYSREADONLY (surfAmt) = $Tuple2(nil, surfToGnsbt(surfAmt))
598644
599645
600646
601647 @Callable(i)
602648 func configSYSREADONLY () = {
603649 let minLockAmt = getIntegerValue(keyMinLockAmount())
604650 let surfVotingPowerRestrictivePeriod = (1440 * 14)
605651 let brToStartSurfTransformation = 1150000
606652 $Tuple2(nil, [minLockAmt, (gnsbtFromSurfCoeff * MULT6), surfVotingPowerRestrictivePeriod, brToStartSurfTransformation])
607653 }
608654
609655

github/deemru/w8io/169f3d6 
118.11 ms