2022.08.09 20:59 [3242746] smart account 3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C > SELF 0.00000000 Waves

{ "type": 13, "id": "JC5Tc3eau8MEGK75s9k1iX3r49bHbb7XVXsSf6EDu6X5", "fee": 2400000, "feeAssetId": null, "timestamp": 1660069863279, "version": 1, "sender": "3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C", "senderPublicKey": "BYLtcNg4P4UcUd6tFdxeuhyRqgkYZujzyfwdEHNmo89c", "proofs": [ "5wnnVPMWmLC1cxDwXqoUBxAfzAzKpvVpSy1bY636gDkQkzzxq2mrQ5KkfNxoaq6e7iLzHqYA4fKmK56fBXcxN5LL" ], "script": "base64:BgIqCAISBQoDAQgIEgASABIDCgEBEgASABIAEgMKAQgSBAoCCAESAwoBARIAUQALcmV2aXNpb25OdW0CKDQ2N2Q2OWRiMGI2MGM2YWFjMDUwOGU2ODcyNDhjZDU4ODMzOGZiMzQACXNlcGFyYXRvcgICX18AA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAGTVVMVFg2CQC2AgEFBU1VTFQ2AAZNVUxUWDgJALYCAQUFTVVMVDgAB01VTFRYMTgJALYCAQCAgJC7utat8A0ACldBVkVTSURTVFICBVdBVkVTAAdXQVZFU0lECQDZBAEFCldBVkVTSURTVFIAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUHYWRkcmVzcwIBLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBEWtleUNvbnRyb2xBZGRyZXNzAAIcJXMlc19fY29uZmlnX19jb250cm9sQWRkcmVzcwENa2V5Q29udHJvbENmZwACESVzX19jb250cm9sQ29uZmlnARVrZXlHbnNidEZyb21TdXJmQ29lZmYAAh0lcyVzX19jZmdfX2duc2J0RnJvbVN1cmZDb2VmZgEUcmVhZENvbnRyb2xDZmdPckZhaWwBB2NvbnRyb2wJALUJAgkBD2dldFN0cmluZ09yRmFpbAIFB2NvbnRyb2wJAQ1rZXlDb250cm9sQ2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCCmNvbnRyb2xDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpjb250cm9sQ2ZnBQNpZHgJAKwCAgItQ29udHJvbCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAPY29udHJvbENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJARFrZXlDb250cm9sQWRkcmVzcwACIzNQNUJmZDU4UFBmTnZCTTJIeThRZmJjRHFNZU50emc3S2ZQAApjb250cm9sQ2ZnCQEUcmVhZENvbnRyb2xDZmdPckZhaWwBBQ9jb250cm9sQ29udHJhY3QADG1hdGhDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAQbmV1dHJpbm9Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAD2F1Y3Rpb25Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGElkeENvbnRyb2xDZmdBdWN0aW9uRGFwcAASZ25zYnRGcm9tU3VyZkNvZWZmCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARVrZXlHbnNidEZyb21TdXJmQ29lZmYAAKwCAQxrZXlCb25kQXNzZXQAAg1ib25kX2Fzc2V0X2lkARlrZXlBdWN0aW9uQ29udHJhY3RBZGRyZXNzAAIQYXVjdGlvbl9jb250cmFjdAEQa2V5TWluTG9ja0Ftb3VudAACESVzX19taW5Mb2NrQW1vdW50ARBrZXlTdGFrZWRBc3NldElkAAIRJXNfX3N0YWtlZEFzc2V0SWQBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgIGYW1vdW50BQNuaWwFCXNlcGFyYXRvcgEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawELdXNlckFkZHJlc3MJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgILcGFyYW1CeVVzZXIJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCAgVzdGFydAUDbmlsBQlzZXBhcmF0b3IBJmtleUxvY2tQYXJhbVZvdGluZ1Bvd2VyRWZmZWN0aXZlSGVpZ2h0AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgtwYXJhbUJ5VXNlcgkAzAgCCQClCAEFC3VzZXJBZGRyZXNzCQDMCAICEXZwRWZmZWN0aXZlSGVpZ2h0BQNuaWwFCXNlcGFyYXRvcgEQa2V5SGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwR0eElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgIHaGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgkA2AQBBQR0eElkBQNuaWwFCXNlcGFyYXRvcgEXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVzdGF0cwkAzAgCAhFhY3RpdmVUb3RhbExvY2tlZAUDbmlsBQlzZXBhcmF0b3IBEmtleVN0YXRzTG9ja3NDb3VudAAJALkJAgkAzAgCAgQlcyVzCQDMCAICBXN0YXRzCQDMCAICCmxvY2tzQ291bnQFA25pbAUJc2VwYXJhdG9yARJrZXlTdGF0c1VzZXJzQ291bnQACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVzdGF0cwkAzAgCAhBhY3RpdmVVc2Vyc0NvdW50BQNuaWwFCXNlcGFyYXRvcgENa2V5TmV4dFBlcmlvZAACDiVzX19uZXh0UGVyaW9kARhrZXlTdXBwb3J0ZWRSZXdhcmRBc3NldHMAAhVzdXBwb3J0ZWRSZXdhcmRBc3NldHMBEWtleURlcG9zaXROdW1MYXN0AAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgNkZXAJAMwIAgIHbGFzdE51bQUDbmlsBQlzZXBhcmF0b3IBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQELdXNlckFkZHJlc3MJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIRdXNlclJ3ZEZyb21EZXBOdW0JAMwIAgULdXNlckFkZHJlc3MFA25pbAUJc2VwYXJhdG9yARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCCmRlcG9zaXROdW0DdGtuCQC5CQIJAMwIAgIEJXMlZAkAzAgCAhVyd2RQZXJOc2J0U3VtQnlEZXBOdW0JAMwIAgkApAMBBQpkZXBvc2l0TnVtCQDMCAIFA3RrbgUDbmlsBQlzZXBhcmF0b3IBCWtleVJld2FyZAILdXNlckFkZHJlc3MDdGtuCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICA3J3ZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQN0a24FA25pbAUJc2VwYXJhdG9yAQprZXlDbGFpbWVkAgt1c2VyQWRkcmVzcwN0a24JALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIDY2xtCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFA3RrbgUDbmlsBQlzZXBhcmF0b3IBF2tleU5vdERpc3RyaWJ1dGVkUmV3YXJkAQN0a24JALkJAgkAzAgCAgQlcyVzCQDMCAICDm5vdERpc3RyaWJ1dGVkCQDMCAIFA3RrbgUDbmlsBQlzZXBhcmF0b3IBBXRvWDE4AgdvcmlnVmFsCG9yaWdNdWx0CQC8AgMJALYCAQUHb3JpZ1ZhbAUHTVVMVFgxOAUIb3JpZ011bHQBDGdldEludE9yWmVybwEDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQAAAQxnZXRJbnRPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAEMZ2V0SW50T3JGYWlsAQNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQNrZXkJAKwCAgkArAICAg9NYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAQxnZXRTdHJPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAEPdG9BZGRyZXNzT3JGYWlsAQphZGRyZXNzU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUKYWRkcmVzc1N0cgkArAICAiFjb3VsZG4ndCBwYXJzZSBwYXNzZWQgYWRkcmVzc1N0cj0FCmFkZHJlc3NTdHIBC3RvQXNzZXRWZWN0AQhhc3NldFN0cgMJAAACBQhhc3NldFN0cgUKV0FWRVNJRFNUUgUEdW5pdAkA2QQBBQhhc3NldFN0cgEFYXNJbnQBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACA0ludAQGdmFsSW50BQckbWF0Y2gwBQZ2YWxJbnQJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBEmFzU3dhcFBhcmFtc1NUUlVDVAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAhkoSW50LCBJbnQsIEludCwgSW50LCBJbnQpBAZzdHJ1Y3QFByRtYXRjaDAFBnN0cnVjdAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAETZm9ybWF0SGlzdG9yeVJlY29yZAQJb2xkQW1vdW50CG9sZFN0YXJ0CW5ld0Ftb3VudAhuZXdTdGFydAkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQlvbGRBbW91bnQJAMwIAgkApAMBBQhvbGRTdGFydAkAzAgCCQCkAwEFCW5ld0Ftb3VudAkAzAgCCQCkAwEFCG5ld1N0YXJ0BQNuaWwFCXNlcGFyYXRvcgEYZm9ybWF0Q2xhaW1IaXN0b3J5UmVjb3JkAgR1c2VyDmNsYWltZWRSZXdhcmRzCQC5CQIJAMwIAgIIJXMlZCVkJXMJAMwIAgUEdXNlcgkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgUOY2xhaW1lZFJld2FyZHMFA25pbAUJc2VwYXJhdG9yARJIaXN0b3J5UmVjb3JkRW50cnkHBHR5cGULdXNlckFkZHJlc3MEdHhJZAlvbGRBbW91bnQIb2xkU3RhcnQJbmV3QW1vdW50CG5ld1N0YXJ0CQELU3RyaW5nRW50cnkCCQEQa2V5SGlzdG9yeVJlY29yZAMFBHR5cGUFC3VzZXJBZGRyZXNzBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFCW9sZEFtb3VudAUIb2xkU3RhcnQFCW5ld0Ftb3VudAUIbmV3U3RhcnQBEUNsYWltSGlzdG9yeUVudHJ5Awt1c2VyQWRkcmVzcwR0eElkDmNsYWltZWRSZXdhcmRzCQELU3RyaW5nRW50cnkCCQEQa2V5SGlzdG9yeVJlY29yZAMCBWNsYWltBQt1c2VyQWRkcmVzcwUEdHhJZAkBGGZvcm1hdENsYWltSGlzdG9yeVJlY29yZAIJAKUIAQULdXNlckFkZHJlc3MFDmNsYWltZWRSZXdhcmRzAQtTdGF0c1Jlc3VsdAMOdG90YWxMb2NrZWRJbmMMbG9ja0NvdW50SW5jDXVzZXJzQ291bnRJbmMECmxvY2tzQ291bnQJAQxnZXRJbnRPclplcm8BCQESa2V5U3RhdHNMb2Nrc0NvdW50AAQKdXNlcnNDb3VudAkBDGdldEludE9yWmVybwEJARJrZXlTdGF0c1VzZXJzQ291bnQABAt0b3RhbEFtb3VudAkBDGdldEludE9yWmVybwEJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEDnRvdGFsQW1vdW50TmV3CQBkAgULdG90YWxBbW91bnQFDnRvdGFsTG9ja2VkSW5jCQCVCgMJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlTdGF0c0xvY2tzQ291bnQACQBkAgUKbG9ja3NDb3VudAUMbG9ja0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5U3RhdHNVc2Vyc0NvdW50AAkAZAIFCnVzZXJzQ291bnQFDXVzZXJzQ291bnRJbmMJAMwIAgkBDEludGVnZXJFbnRyeQIJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAFDnRvdGFsQW1vdW50TmV3BQNuaWwFC3RvdGFsQW1vdW50BQ50b3RhbEFtb3VudE5ldwEPTG9ja1BhcmFtc0VudHJ5Awt1c2VyQWRkcmVzcwZhbW91bnQadm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQULdXNlckFkZHJlc3MFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQt1c2VyQWRkcmVzcwUadm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQFA25pbAEPZ2V0UGFyYW1zT3JGYWlsAAkAlAoCCQDZBAEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQEQa2V5U3Rha2VkQXNzZXRJZAAJAQxnZXRJbnRPckZhaWwBCQEQa2V5TWluTG9ja0Ftb3VudAABDGlzQWN0aXZlVXNlcgELdXNlckFkZHJlc3MJAGYCCQEMZ2V0SW50T3JFbHNlAgkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwAAAAABE2dldFVzZXJQYXJhbXNPclVuaXQBC3VzZXJBZGRyZXNzAwkBDGlzQWN0aXZlVXNlcgEFC3VzZXJBZGRyZXNzCQCVCgMHCQEMZ2V0SW50T3JGYWlsAQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQt1c2VyQWRkcmVzcwkBDGdldEludE9yRmFpbAEJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQULdXNlckFkZHJlc3MFBHVuaXQBE2dldFVzZXJQYXJhbXNPckZhaWwBC3VzZXJBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQULdXNlckFkZHJlc3MJAKwCAgkArAICAgVVc2VyIAkApQgBBQt1c2VyQWRkcmVzcwIPIGlzIG5vdCBkZWZpbmVkABJzdXBwb3J0ZWRBc3NldHNTdHIJAQxnZXRTdHJPckVsc2UCCQEYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAIAABNzdXBwb3J0ZWRBc3NldHNMaXN0CQC1CQIFEnN1cHBvcnRlZEFzc2V0c1N0cgIBXwEKY2FsY1Jld2FyZAULdXNlckFkZHJlc3MHYXNzZXRJZA1zdGFrZWRBbW91bnRYDmRlcG9zaXROdW1Vc2VyDmRlcG9zaXROdW1MYXN0BBdyZXdhcmRQZXJOc2J0U3VtTGFzdEtFWQkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1MYXN0BQdhc3NldElkBApzdW1MYXN0WDE4CQCnAwEJAQxnZXRTdHJPckVsc2UCCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUOZGVwb3NpdE51bUxhc3QFB2Fzc2V0SWQCATAECnN1bVVzZXJYMTgJAKcDAQkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtVXNlcgUHYXNzZXRJZAIBMAQRcmV3YXJkRHluYW1pY1BhcnQJAKADAQkAvAIDCQC4AgIFCnN1bUxhc3RYMTgFCnN1bVVzZXJYMTgFDXN0YWtlZEFtb3VudFgFB01VTFRYMTgEE3Jld2FyZENhY2hlZFBhcnRLRVkJAQlrZXlSZXdhcmQCBQt1c2VyQWRkcmVzcwUHYXNzZXRJZAQQcmV3YXJkQ2FjaGVkUGFydAkBDGdldEludE9yRWxzZQIFE3Jld2FyZENhY2hlZFBhcnRLRVkAAAkAlgoECQBkAgUQcmV3YXJkQ2FjaGVkUGFydAURcmV3YXJkRHluYW1pY1BhcnQFEHJld2FyZENhY2hlZFBhcnQFEXJld2FyZER5bmFtaWNQYXJ0BRNyZXdhcmRDYWNoZWRQYXJ0S0VZAQ1SZXdhcmRFbnRyaWVzAwlpc05ld1VzZXILdXNlckFkZHJlc3MMc3Rha2VkQW1vdW50BA1zdGFrZWRBbW91bnRYCQC2AgEFDHN0YWtlZEFtb3VudAQbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZCQEba2V5VXNlclJld2FyZEZyb21EZXBvc2l0TnVtAQULdXNlckFkZHJlc3MEDmRlcG9zaXROdW1Vc2VyCQEMZ2V0SW50T3JFbHNlAgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZAP///////////wEEDmRlcG9zaXROdW1MYXN0CQEMZ2V0SW50T3JFbHNlAgkBEWtleURlcG9zaXROdW1MYXN0AAD///////////8BCgEbZm9yRWFjaEFzc2V0Q2FjaGVVc2VyUmV3YXJkAgVhY2N1bQVhc3NldAQLJHQwODk4MzkxMTgJAQpjYWxjUmV3YXJkBQULdXNlckFkZHJlc3MFBWFzc2V0BQ1zdGFrZWRBbW91bnRYBQ5kZXBvc2l0TnVtVXNlcgUOZGVwb3NpdE51bUxhc3QEC3Jld2FyZFRvdGFsCAULJHQwODk4MzkxMTgCXzEEBmNhY2hlZAgFCyR0MDg5ODM5MTE4Al8yBAdkeW5hbWljCAULJHQwODk4MzkxMTgCXzMEE3Jld2FyZENhY2hlZFBhcnRLRVkIBQskdDA4OTgzOTExOAJfNAkAzQgCBQVhY2N1bQkBDEludGVnZXJFbnRyeQIFE3Jld2FyZENhY2hlZFBhcnRLRVkFC3Jld2FyZFRvdGFsAwMJAAACBQ5kZXBvc2l0TnVtTGFzdAD///////////8BCQAAAgUOZGVwb3NpdE51bVVzZXIA////////////AQcFA25pbAMDCQAAAgUOZGVwb3NpdE51bUxhc3QA////////////AQkAZgIFDmRlcG9zaXROdW1Vc2VyAP///////////wEHCQACAQIvaW52YWxpZCBkZXBvc2l0TnVtTGFzdCBhbmQgZGVwb3NpdE51bVVzZXIgc3RhdGUDAwkAZgIFDmRlcG9zaXROdW1MYXN0AP///////////wEJAGcCBQ5kZXBvc2l0TnVtVXNlcgD///////////8BBwMFCWlzTmV3VXNlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAUDbmlsCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEbZm9yRWFjaEFzc2V0Q2FjaGVVc2VyUmV3YXJkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAkAAgEJAKwCAgkArAICCQCsAgICJHVuY292ZXJlZCBjb25kaXRpb246IGRlcG9zaXROdW1MYXN0PQkApAMBBQ5kZXBvc2l0TnVtTGFzdAIQIGRlcG9zaXROdW1Vc2VyPQkApAMBBQ5kZXBvc2l0TnVtVXNlcgEiSW5jcmVtZW50Tm90RGlzdHJpYnV0ZWRSZXdhcmRFbnRyeQIDdGtuCWFtb3VudEluYwQXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJARdrZXlOb3REaXN0cmlidXRlZFJld2FyZAEFA3RrbgQUbm90RGlzdHJpYnV0ZWRSZXdhcmQJAQxnZXRJbnRPckVsc2UCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQkAZAIFFG5vdERpc3RyaWJ1dGVkUmV3YXJkBQlhbW91bnRJbmMFA25pbAELc3VyZlRvR25zYnQBB3N1cmZBbXQJAGkCBQdzdXJmQW10BRJnbnNidEZyb21TdXJmQ29lZmYBH21lcmdlVm90aW5nUG93ZXJFZmZlY3RpdmVIZWlnaHQEEHF1YXJhbnRpbmVQZXJpb2QRdnBFZmZlY3RpdmVIZWlnaHQJc3Rha2VkQW10DHN0YWtlZEFtdE5FVwQPcmVtYWluaW5nVG9XYWl0CQBlAgURdnBFZmZlY3RpdmVIZWlnaHQFBmhlaWdodAMJAGcCAAAFD3JlbWFpbmluZ1RvV2FpdAkAZAIFBmhlaWdodAUQcXVhcmFudGluZVBlcmlvZAQNYWxyZWFkeVdhaXRlZAkAZQIFEHF1YXJhbnRpbmVQZXJpb2QFD3JlbWFpbmluZ1RvV2FpdAQDa1g4AwkBAiE9AgUMc3Rha2VkQW10TkVXAAAJAGsDBQlzdGFrZWRBbXQFBU1VTFQ4BQxzdGFrZWRBbXRORVcFEXZwRWZmZWN0aXZlSGVpZ2h0CQBlAgkAZAIFEHF1YXJhbnRpbmVQZXJpb2QFBmhlaWdodAkAawMFDWFscmVhZHlXYWl0ZWQFA2tYOAUFTVVMVDgBCm1lcmdlU3Rha2UCC3VzZXJBZGRyZXNzC2Ftb3VudFRvQWRkBA0kdDAxMjc3MTEyODgxCQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMTI3NzExMjg4MQJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTI3NzExMjg4MQJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQ0kdDAxMjc3MTEyODgxAl8zBA9zdGFrZWRBbW91bnRORVcDBQlpc05ld1VzZXIFC2Ftb3VudFRvQWRkCQBkAgULYW1vdW50VG9BZGQFDHN0YWtlZEFtb3VudAQQcXVhcmFudGluZVBlcmlvZAkAaAIAoAsADgQUdnBFZmZlY3RpdmVIZWlnaHRORVcDBQlpc05ld1VzZXIJAGQCBRBxdWFyYW50aW5lUGVyaW9kBQZoZWlnaHQJAR9tZXJnZVZvdGluZ1Bvd2VyRWZmZWN0aXZlSGVpZ2h0BAUQcXVhcmFudGluZVBlcmlvZAURdnBFZmZlY3RpdmVIZWlnaHQFDHN0YWtlZEFtb3VudAUPc3Rha2VkQW1vdW50TkVXCQCXCgUFCWlzTmV3VXNlcgUMc3Rha2VkQW1vdW50BRF2cEVmZmVjdGl2ZUhlaWdodAUPc3Rha2VkQW1vdW50TkVXBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwELY29tbW9uU3Rha2UCC3VzZXJBZGRyZXNzAWkEDSR0MDEzMzY3MTM0MjEJAQ9nZXRQYXJhbXNPckZhaWwABA1zdGFrZWRBc3NldElkCAUNJHQwMTMzNjcxMzQyMQJfMQQNbWluTG9ja0Ftb3VudAgFDSR0MDEzMzY3MTM0MjECXzIDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhVJbnZhbGlkIHBheW1lbnRzIHNpemUEB3BheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQGYW1vdW50CAUHcGF5bWVudAZhbW91bnQEE2ludmFsaWRBc3NldE1lc3NhZ2UJAKwCAgkArAICAg9JbnZhbGlkIGFzc2V0LiAJANgEAQUNc3Rha2VkQXNzZXRJZAIMIGlzIGV4cGVjdGVkBAdhc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIIBQdwYXltZW50B2Fzc2V0SWQFE2ludmFsaWRBc3NldE1lc3NhZ2UDCQECIT0CBQdhc3NldElkBQ1zdGFrZWRBc3NldElkCQACAQUTaW52YWxpZEFzc2V0TWVzc2FnZQQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MECm1lcmdlZERhdGEJAQptZXJnZVN0YWtlAgULdXNlckFkZHJlc3MFBmFtb3VudAQJaXNOZXdVc2VyCAUKbWVyZ2VkRGF0YQJfMQQMc3Rha2VkQW1vdW50CAUKbWVyZ2VkRGF0YQJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80BBR2cEVmZmVjdGl2ZUhlaWdodE5FVwgFCm1lcmdlZERhdGECXzUDCQBmAgUNbWluTG9ja0Ftb3VudAUPc3Rha2VkQW1vdW50TkVXCQACAQkArAICAhNNaW4gbG9jayBhbW91bnQgaXMgCQCkAwEFDW1pbkxvY2tBbW91bnQEDSR0MDE0MjIwMTQzMjIJAQtTdGF0c1Jlc3VsdAMFBmFtb3VudAABAwUJaXNOZXdVc2VyAAEAAAQMc3RhdHNFbnRyaWVzCAUNJHQwMTQyMjAxNDMyMgJfMQQLdG90YWxTdGFrZWQIBQ0kdDAxNDIyMDE0MzIyAl8yBA50b3RhbFN0YWtlZE5ldwgFDSR0MDE0MjIwMTQzMjICXzMJAM4IAgkAzggCCQDOCAIJAMwIAgkBEkhpc3RvcnlSZWNvcmRFbnRyeQcCBXN0YWtlBQt1c2VyQWRkcmVzcwgFAWkNdHJhbnNhY3Rpb25JZAUMc3Rha2VkQW1vdW50BRF2cEVmZmVjdGl2ZUhlaWdodAUPc3Rha2VkQW1vdW50TkVXBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwUDbmlsCQENUmV3YXJkRW50cmllcwMFCWlzTmV3VXNlcgUOdXNlckFkZHJlc3NTdHIFDHN0YWtlZEFtb3VudAkBD0xvY2tQYXJhbXNFbnRyeQMFC3VzZXJBZGRyZXNzBQ9zdGFrZWRBbW91bnRORVcFFHZwRWZmZWN0aXZlSGVpZ2h0TkVXBQxzdGF0c0VudHJpZXMBC2NvbW1vbkNsYWltAgt1c2VyQWRkcmVzcwFpBA51c2VyQWRkcmVzc1N0cgkApQgBBQt1c2VyQWRkcmVzcwMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhlwYXltZW50cyBhcmUgbm90IGFjY2VwdGVkBA0kdDAxNDgwMTE0OTA2CQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMTQ4MDExNDkwNgJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMTQ4MDExNDkwNgJfMgQMc3Rha2luZ1N0YXJ0CAUNJHQwMTQ4MDExNDkwNgJfMwQNc3Rha2VkQW1vdW50WAkAtgIBBQxzdGFrZWRBbW91bnQEG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQEFDnVzZXJBZGRyZXNzU3RyBA5kZXBvc2l0TnVtVXNlcgkBDGdldEludE9yRWxzZQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD///////////8BBA5kZXBvc2l0TnVtTGFzdAkBDGdldEludE9yRWxzZQIJARFrZXlEZXBvc2l0TnVtTGFzdAAA////////////AQoBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAxNTI3NzE1NDE1CQEKY2FsY1Jld2FyZAUFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDE1Mjc3MTU0MTUCXzEEBmNhY2hlZAgFDSR0MDE1Mjc3MTU0MTUCXzIEB2R5bmFtaWMIBQ0kdDAxNTI3NzE1NDE1Al8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMTUyNzcxNTQxNQJfNAQKY2xhaW1lZEtFWQkBCmtleUNsYWltZWQCBQ51c2VyQWRkcmVzc1N0cgUFYXNzZXQEDSR0MDE1NDc1MTU1MTIFBWFjY3VtBARkYXRhCAUNJHQwMTU0NzUxNTUxMgJfMQQRY2xhaW1lZEFtdEJ5QXNzZXQIBQ0kdDAxNTQ3NTE1NTEyAl8yBAduZXdQYXJ0CQC5CQIJAMwIAgUFYXNzZXQJAMwIAgkApAMBBQtyZXdhcmRUb3RhbAUDbmlsAgE6BBRjbGFpbWVkQW10QnlBc3NldE5ldwkAuQkCCQDMCAIFEWNsYWltZWRBbXRCeUFzc2V0CQDMCAIFB25ld1BhcnQFA25pbAIBXwMJAGcCAAAFC3Jld2FyZFRvdGFsCQCUCgIFBGRhdGEFFGNsYWltZWRBbXRCeUFzc2V0TmV3CQCUCgIJAM0IAgkAzQgCCQDNCAIFBGRhdGEJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQtyZXdhcmRUb3RhbAkBC3RvQXNzZXRWZWN0AQUFYXNzZXQJAQxJbnRlZ2VyRW50cnkCBQpjbGFpbWVkS0VZCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQpjbGFpbWVkS0VZAAAFC3Jld2FyZFRvdGFsCQEMSW50ZWdlckVudHJ5AgUTcmV3YXJkQ2FjaGVkUGFydEtFWQAABRRjbGFpbWVkQW10QnlBc3NldE5ldwQNJHQwMTU5NzIxNjA4NgoAAiRsBRNzdXBwb3J0ZWRBc3NldHNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwCAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEfZm9yRWFjaEFzc2V0Q2FsY1VuY2xhaW1lZFJld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQJdHJhbnNmZXJzCAUNJHQwMTU5NzIxNjA4NgJfMQQXY2xhaW1lZEFtdEJ5QXNzZXRSZXN1bHQIBQ0kdDAxNTk3MjE2MDg2Al8yAwkAZwIAAAkAkAMBBQl0cmFuc2ZlcnMFA25pbAkAzQgCCQDNCAIFCXRyYW5zZmVycwkBDEludGVnZXJFbnRyeQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQUOZGVwb3NpdE51bUxhc3QJARFDbGFpbUhpc3RvcnlFbnRyeQMFC3VzZXJBZGRyZXNzCAUBaQ10cmFuc2FjdGlvbklkCQCwAgIFF2NsYWltZWRBbXRCeUFzc2V0UmVzdWx0AAELAWkBC2NvbnN0cnVjdG9yAw1taW5Mb2NrQW1vdW50FXN1cHBvcnRlZFJld2FyZEFzc2V0cw1zdGFrZWRBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARBrZXlNaW5Mb2NrQW1vdW50AAUNbWluTG9ja0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEYa2V5U3VwcG9ydGVkUmV3YXJkQXNzZXRzAAUVc3VwcG9ydGVkUmV3YXJkQXNzZXRzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlTdGFrZWRBc3NldElkAAUNc3Rha2VkQXNzZXRJZAUDbmlsAWkBBXN0YWtlAAkBC2NvbW1vblN0YWtlAggFAWkGY2FsbGVyBQFpAWkBE3N0YWtlQnlPcmlnaW5DYWxsZXIACQELY29tbW9uU3Rha2UCCAUBaQxvcmlnaW5DYWxsZXIFAWkBaQEHdW5zdGFrZQEGYW1vdW50AwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIjdW5zdGFrZSBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnQEC3VzZXJBZGRyZXNzCAUBaQZjYWxsZXIEDnVzZXJBZGRyZXNzU3RyCQClCAEFC3VzZXJBZGRyZXNzBA0kdDAxNjk5NTE3MDQ5CQEPZ2V0UGFyYW1zT3JGYWlsAAQNc3Rha2VkQXNzZXRJZAgFDSR0MDE2OTk1MTcwNDkCXzEEDW1pbkxvY2tBbW91bnQIBQ0kdDAxNjk5NTE3MDQ5Al8yBA0kdDAxNzA1MjE3MTM2CQETZ2V0VXNlclBhcmFtc09yRmFpbAEFC3VzZXJBZGRyZXNzBAlpc05ld1VzZXIIBQ0kdDAxNzA1MjE3MTM2Al8xBAxzdGFrZWRBbW91bnQIBQ0kdDAxNzA1MjE3MTM2Al8yBBF2cEVmZmVjdGl2ZUhlaWdodAgFDSR0MDE3MDUyMTcxMzYCXzMEEHN3YXBQYXJhbXNTVFJVQ1QJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD9BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCAAAFA25pbAUDbmlsBAxzd2FwTGltaXRNYXgIBRBzd2FwUGFyYW1zU1RSVUNUAl8xBA5zd2FwTGltaXRTcGVudAgFEHN3YXBQYXJhbXNTVFJVQ1QCXzIEDmJsY2tzMkxtdFJlc2V0CAUQc3dhcFBhcmFtc1NUUlVDVAJfMwMJAGYCBQ5zd2FwTGltaXRTcGVudAAACQACAQkArAICCQCsAgICLVlvdSBoYXZlIGFscmVhZHkgbWFkZSBhIHN3YXAgb3BlcmF0aW9uLiBXYWl0IAkApAMBCQBkAgUGaGVpZ2h0BQ5ibGNrczJMbXRSZXNldAISIGhlaWdodCB0byB1bnN0YWtlAwkAZwIAAAUMc3Rha2VkQW1vdW50CQACAQISTm90aGluZyB0byB1bnN0YWtlAwkAZgIFBmFtb3VudAUMc3Rha2VkQW1vdW50CQACAQkArAICCQCsAgIJAKwCAgIKUmVxdWVzdGVkIAkApAMBBQZhbW91bnQCEiwgYnV0IHN0YWtlZCBvbmx5IAkApAMBBQxzdGFrZWRBbW91bnQED3N0YWtlZEFtb3VudE5FVwkAZQIFDHN0YWtlZEFtb3VudAUGYW1vdW50BA0kdDAxNzgwNjE3OTY0CQELU3RhdHNSZXN1bHQDCQEBLQEFBmFtb3VudAMJAAACBQZhbW91bnQFDHN0YWtlZEFtb3VudAD///////////8BAAADCQAAAgUGYW1vdW50BQxzdGFrZWRBbW91bnQA////////////AQAABAxzdGF0c0VudHJpZXMIBQ0kdDAxNzgwNjE3OTY0Al8xBAt0b3RhbFN0YWtlZAgFDSR0MDE3ODA2MTc5NjQCXzIEDnRvdGFsU3Rha2VkTmV3CAUNJHQwMTc4MDYxNzk2NAJfMwkAzggCCQDOCAIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUGYW1vdW50BQ1zdGFrZWRBc3NldElkCQDMCAIJARJIaXN0b3J5UmVjb3JkRW50cnkHAgd1bnN0YWtlBQt1c2VyQWRkcmVzcwgFAWkNdHJhbnNhY3Rpb25JZAUMc3Rha2VkQW1vdW50BRF2cEVmZmVjdGl2ZUhlaWdodAUPc3Rha2VkQW1vdW50TkVXBRF2cEVmZmVjdGl2ZUhlaWdodAUDbmlsCQENUmV3YXJkRW50cmllcwMHBQ51c2VyQWRkcmVzc1N0cgUMc3Rha2VkQW1vdW50CQEPTG9ja1BhcmFtc0VudHJ5AwULdXNlckFkZHJlc3MFD3N0YWtlZEFtb3VudE5FVwURdnBFZmZlY3RpdmVIZWlnaHQFDHN0YXRzRW50cmllcwFpAQdkZXBvc2l0AAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECH2V4YWN0IDEgcGF5bWVudCBpcyBhbGxvd2VkIG9ubHkEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAZhbW91bnQIBQNwbXQGYW1vdW50BApwbXRBc3NldElkCQELdmFsdWVPckVsc2UCCAUDcG10B2Fzc2V0SWQFB1dBVkVTSUQEDXBtdEFzc2V0SWRTdHIJANgEAQUKcG10QXNzZXRJZAQIcG10TXVsdFgDCQAAAgUKcG10QXNzZXRJZAUHV0FWRVNJRAUGTVVMVFg4BQZNVUxUWDYEB2Ftb3VudFgJALYCAQUGYW1vdW50BAt0b3RhbFN0YWtlZAkBDGdldEludE9yRWxzZQIJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAAAAQMdG90YWxTdGFrZWRYCQC2AgEFC3RvdGFsU3Rha2VkAwkAZgIAAAULdG90YWxTdGFrZWQJAAIBAhtUT0RPOiBjYXNlIGlzIG5vdCBzdXBwb3J0ZWQDCQAAAgULdG90YWxTdGFrZWQAAAkBIkluY3JlbWVudE5vdERpc3RyaWJ1dGVkUmV3YXJkRW50cnkCBQ1wbXRBc3NldElkU3RyBQZhbW91bnQEEHJld2FyZFBlck5zYnRYMTgJALwCAwUHYW1vdW50WAUHTVVMVFgxOAUMdG90YWxTdGFrZWRYBBFkZXBvc2l0TnVtTGFzdEtFWQkBEWtleURlcG9zaXROdW1MYXN0AAQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCBRFkZXBvc2l0TnVtTGFzdEtFWQD///////////8BBA1kZXBvc2l0TnVtTmV3CQBkAgUOZGVwb3NpdE51bUxhc3QAAQMJAQEhAQkBCGNvbnRhaW5zAgUSc3VwcG9ydGVkQXNzZXRzU3RyBQ1wbXRBc3NldElkU3RyCQACAQkArAICCQCsAgIFEnN1cHBvcnRlZEFzc2V0c1N0cgIRIGRvZXNuJ3QgY29udGFpbiAFDXBtdEFzc2V0SWRTdHIKARdyZWZyZXNoUmV3YXJkUGVyTnNidFNVTQIFYWNjdW0JbmV4dEFzc2V0BBZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUNZGVwb3NpdE51bU5ldwUJbmV4dEFzc2V0BApzdW1MYXN0U3RyCQEMZ2V0U3RyT3JFbHNlAgkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1MYXN0BQluZXh0QXNzZXQCATAJAM0IAgUFYWNjdW0DCQAAAgUJbmV4dEFzc2V0BQ1wbXRBc3NldElkU3RyCQELU3RyaW5nRW50cnkCBRZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZCQCmAwEJALcCAgkApwMBBQpzdW1MYXN0U3RyBRByZXdhcmRQZXJOc2J0WDE4CQELU3RyaW5nRW50cnkCBRZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZBQpzdW1MYXN0U3RyCQDNCAIKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEXcmVmcmVzaFJld2FyZFBlck5zYnRTVU0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAQxJbnRlZ2VyRW50cnkCBRFkZXBvc2l0TnVtTGFzdEtFWQUNZGVwb3NpdE51bU5ldwFpAQxjbGFpbVJld2FyZHMACQELY29tbW9uQ2xhaW0CCAUBaQZjYWxsZXIFAWkBaQEaY2xhaW1SZXdhcmRzQnlPcmlnaW5DYWxsZXIACQELY29tbW9uQ2xhaW0CCAUBaQxvcmlnaW5DYWxsZXIFAWkBaQEYdW5jbGFpbWVkUmV3YXJkc1JFQURPTkxZAQ51c2VyQWRkcmVzc1N0cgoBFmZvckVhY2hBc3NldFplcm9SZXdhcmQCBWFjY3VtBWFzc2V0CQCsAgIJAKwCAgUFYWNjdW0JALkJAgkAzAgCBQVhc3NldAkAzAgCAgEwCQDMCAICATAFA25pbAIBOgIBXwQSdW5jbGFpbWVkUmV3YXJkU3RyAwkAAAIFDnVzZXJBZGRyZXNzU3RyAgAKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWZm9yRWFjaEFzc2V0WmVyb1Jld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgQLdXNlckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDnVzZXJBZGRyZXNzU3RyBA0kdDAyMDUzODIwNjQzCQELdmFsdWVPckVsc2UCCQETZ2V0VXNlclBhcmFtc09yVW5pdAEFC3VzZXJBZGRyZXNzCQCVCgMGAAAAAAQJaXNOZXdVc2VyCAUNJHQwMjA1MzgyMDY0MwJfMQQMc3Rha2VkQW1vdW50CAUNJHQwMjA1MzgyMDY0MwJfMgQMc3Rha2luZ1N0YXJ0CAUNJHQwMjA1MzgyMDY0MwJfMwQNc3Rha2VkQW1vdW50WAkAtgIBBQxzdGFrZWRBbW91bnQEG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQEFDnVzZXJBZGRyZXNzU3RyBA5kZXBvc2l0TnVtVXNlcgkBDGdldEludE9yRWxzZQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD///////////8BBA5kZXBvc2l0TnVtTGFzdAkBDGdldEludE9yRWxzZQIJARFrZXlEZXBvc2l0TnVtTGFzdAAA////////////AQoBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBWFjY3VtBWFzc2V0BA0kdDAyMDk4OTIxMTI3CQEKY2FsY1Jld2FyZAUFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAUNc3Rha2VkQW1vdW50WAUOZGVwb3NpdE51bVVzZXIFDmRlcG9zaXROdW1MYXN0BAtyZXdhcmRUb3RhbAgFDSR0MDIwOTg5MjExMjcCXzEEBmNhY2hlZAgFDSR0MDIwOTg5MjExMjcCXzIEB2R5bmFtaWMIBQ0kdDAyMDk4OTIxMTI3Al8zBBNyZXdhcmRDYWNoZWRQYXJ0S0VZCAUNJHQwMjA5ODkyMTEyNwJfNAQHY2xhaW1lZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEKa2V5Q2xhaW1lZAIFDnVzZXJBZGRyZXNzU3RyBQVhc3NldAAACQCsAgIJAKwCAgUFYWNjdW0JALkJAgkAzAgCBQVhc3NldAkAzAgCCQCkAwEFC3Jld2FyZFRvdGFsCQDMCAIJAKQDAQUHY2xhaW1lZAUDbmlsAgE6AgFfCgACJGwFE3N1cHBvcnRlZEFzc2V0c0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAJQKAgUDbmlsCQCzAgIFEnVuY2xhaW1lZFJld2FyZFN0cgABAWkBFnN1cmZTdGFraW5nU1lTUkVBRE9OTFkCFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQhzdXJmRGlmZgQJc3VyZlRvdGFsCQEMZ2V0SW50T3JFbHNlAgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAABBJnbnNidEZyb21TdXJmVG90YWwJAQtzdXJmVG9HbnNidAEFCXN1cmZUb3RhbAMJAAACBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkCAAkAlAoCBQNuaWwJAMwIAgAACQDMCAIFCXN1cmZUb3RhbAkAzAgCAAAJAMwIAgUSZ25zYnRGcm9tU3VyZlRvdGFsCQDMCAIAAAkAzAgCBQZoZWlnaHQJAMwIAgUGaGVpZ2h0BQNuaWwEC3VzZXJBZGRyZXNzCQEPdG9BZGRyZXNzT3JGYWlsAQUVdXNlckFkZHJlc3NTdHJPckVtcHR5BAptZXJnZWREYXRhCQEKbWVyZ2VTdGFrZQIFC3VzZXJBZGRyZXNzBQhzdXJmRGlmZgQJaXNOZXdVc2VyCAUKbWVyZ2VkRGF0YQJfMQQMc3Rha2VkQW1vdW50CAUKbWVyZ2VkRGF0YQJfMgQRdnBFZmZlY3RpdmVIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80BBR2cEVmZmVjdGl2ZUhlaWdodE5FVwgFCm1lcmdlZERhdGECXzUECHN1cmZVc2VyBQxzdGFrZWRBbW91bnQEEWduc2J0RnJvbVN1cmZVc2VyCQELc3VyZlRvR25zYnQBBQhzdXJmVXNlcgkAlAoCBQNuaWwJAMwIAgUIc3VyZlVzZXIJAMwIAgUJc3VyZlRvdGFsCQDMCAIFEWduc2J0RnJvbVN1cmZVc2VyCQDMCAIFEmduc2J0RnJvbVN1cmZUb3RhbAkAzAgCBRF2cEVmZmVjdGl2ZUhlaWdodAkAzAgCBRR2cEVmZmVjdGl2ZUhlaWdodE5FVwUDbmlsAWkBGGduc2J0RnJvbVN1cmZTWVNSRUFET05MWQEHc3VyZkFtdAkAlAoCBQNuaWwJAQtzdXJmVG9HbnNidAEFB3N1cmZBbXQBaQERY29uZmlnU1lTUkVBRE9OTFkABAptaW5Mb2NrQW10CQERQGV4dHJOYXRpdmUoMTA1NSkBCQEQa2V5TWluTG9ja0Ftb3VudAAEIHN1cmZWb3RpbmdQb3dlclJlc3RyaWN0aXZlUGVyaW9kCQBoAgCgCwAOBBticlRvU3RhcnRTdXJmVHJhbnNmb3JtYXRpb24AsJhGCQCUCgIFA25pbAkAzAgCBQptaW5Mb2NrQW10CQDMCAIJAGgCBRJnbnNidEZyb21TdXJmQ29lZmYFBU1VTFQ2CQDMCAIFIHN1cmZWb3RpbmdQb3dlclJlc3RyaWN0aXZlUGVyaW9kCQDMCAIFG2JyVG9TdGFydFN1cmZUcmFuc2Zvcm1hdGlvbgUDbmlsAMyJJa0=", "chainId": 87, "height": 3242746, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2yZVVqyvpU9eAVijdxmzTnhiR2ygZ5WMFcSHxH6pue5V Next: 9PAfryBuDnVdE792YhSxTUKPZcX1n4S69ZQvwrpYxGK6 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "cbd0bdc8bbba91db64066b16a84913a4c965e23e"
4+let revisionNum = "467d69db0b60c6aac0508e687248cd588338fb34"
55
66 let separator = "__"
77
161161 }
162162
163163
164+func asSwapParamsSTRUCT (v) = match v {
165+ case struct: (Int, Int, Int, Int, Int) =>
166+ struct
167+ case _ =>
168+ throw("fail to cast into Int")
169+}
170+
171+
164172 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)
165173
166174
220228 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
221229 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
222230 func forEachAssetCacheUserReward (accum,asset) = {
223- let $t088308965 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
224- let rewardTotal = $t088308965._1
225- let cached = $t088308965._2
226- let dynamic = $t088308965._3
227- let rewardCachedPartKEY = $t088308965._4
231+ let $t089839118 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
232+ let rewardTotal = $t089839118._1
233+ let cached = $t089839118._2
234+ let dynamic = $t089839118._3
235+ let rewardCachedPartKEY = $t089839118._4
228236 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
229237 }
230238
284292
285293
286294 func mergeStake (userAddress,amountToAdd) = {
287- let $t01261812728 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
288- let isNewUser = $t01261812728._1
289- let stakedAmount = $t01261812728._2
290- let vpEffectiveHeight = $t01261812728._3
295+ let $t01277112881 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
296+ let isNewUser = $t01277112881._1
297+ let stakedAmount = $t01277112881._2
298+ let vpEffectiveHeight = $t01277112881._3
291299 let stakedAmountNEW = if (isNewUser)
292300 then amountToAdd
293301 else (amountToAdd + stakedAmount)
300308
301309
302310 func commonStake (userAddress,i) = {
303- let $t01321413268 = getParamsOrFail()
304- let stakedAssetId = $t01321413268._1
305- let minLockAmount = $t01321413268._2
311+ let $t01336713421 = getParamsOrFail()
312+ let stakedAssetId = $t01336713421._1
313+ let minLockAmount = $t01336713421._2
306314 if ((size(i.payments) != 1))
307315 then throw("Invalid payments size")
308316 else {
323331 if ((minLockAmount > stakedAmountNEW))
324332 then throw(("Min lock amount is " + toString(minLockAmount)))
325333 else {
326- let $t01406714169 = StatsResult(amount, 1, if (isNewUser)
334+ let $t01422014322 = StatsResult(amount, 1, if (isNewUser)
327335 then 1
328336 else 0)
329- let statsEntries = $t01406714169._1
330- let totalStaked = $t01406714169._2
331- let totalStakedNew = $t01406714169._3
337+ let statsEntries = $t01422014322._1
338+ let totalStaked = $t01422014322._2
339+ let totalStakedNew = $t01422014322._3
332340 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeightNEW)) ++ statsEntries)
333341 }
334342 }
341349 if ((size(i.payments) > 0))
342350 then throw("payments are not accepted")
343351 else {
344- let $t01464814753 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
345- let isNewUser = $t01464814753._1
346- let stakedAmount = $t01464814753._2
347- let stakingStart = $t01464814753._3
352+ let $t01480114906 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
353+ let isNewUser = $t01480114906._1
354+ let stakedAmount = $t01480114906._2
355+ let stakingStart = $t01480114906._3
348356 let stakedAmountX = toBigInt(stakedAmount)
349357 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
350358 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
351359 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
352360 func forEachAssetCalcUnclaimedReward (accum,asset) = {
353- let $t01512415262 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
354- let rewardTotal = $t01512415262._1
355- let cached = $t01512415262._2
356- let dynamic = $t01512415262._3
357- let rewardCachedPartKEY = $t01512415262._4
361+ let $t01527715415 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
362+ let rewardTotal = $t01527715415._1
363+ let cached = $t01527715415._2
364+ let dynamic = $t01527715415._3
365+ let rewardCachedPartKEY = $t01527715415._4
358366 let claimedKEY = keyClaimed(userAddressStr, asset)
359- let $t01532215359 = accum
360- let data = $t01532215359._1
361- let claimedAmtByAsset = $t01532215359._2
367+ let $t01547515512 = accum
368+ let data = $t01547515512._1
369+ let claimedAmtByAsset = $t01547515512._2
362370 let newPart = makeString([asset, toString(rewardTotal)], ":")
363371 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
364372 if ((0 >= rewardTotal))
366374 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
367375 }
368376
369- let $t01581915933 = {
377+ let $t01597216086 = {
370378 let $l = supportedAssetsList
371379 let $s = size($l)
372380 let $acc0 = $Tuple2(nil, "")
380388
381389 $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)
382390 }
383- let transfers = $t01581915933._1
384- let claimedAmtByAssetResult = $t01581915933._2
391+ let transfers = $t01597216086._1
392+ let claimedAmtByAssetResult = $t01597216086._2
385393 if ((0 >= size(transfers)))
386394 then nil
387395 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
412420 else {
413421 let userAddress = i.caller
414422 let userAddressStr = toString(userAddress)
415- let $t01684216896 = getParamsOrFail()
416- let stakedAssetId = $t01684216896._1
417- let minLockAmount = $t01684216896._2
418- let $t01689916983 = getUserParamsOrFail(userAddress)
419- let isNewUser = $t01689916983._1
420- let stakedAmount = $t01689916983._2
421- let vpEffectiveHeight = $t01689916983._3
422- if ((0 >= stakedAmount))
423- then throw("Nothing to unstake")
424- else if ((amount > stakedAmount))
425- then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
426- else {
427- let stakedAmountNEW = (stakedAmount - amount)
428- let $t01722517383 = StatsResult(-(amount), if ((amount == stakedAmount))
429- then -1
430- else 0, if ((amount == stakedAmount))
431- then -1
432- else 0)
433- let statsEntries = $t01722517383._1
434- let totalStaked = $t01722517383._2
435- let totalStakedNew = $t01722517383._3
436- ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
437- }
423+ let $t01699517049 = getParamsOrFail()
424+ let stakedAssetId = $t01699517049._1
425+ let minLockAmount = $t01699517049._2
426+ let $t01705217136 = getUserParamsOrFail(userAddress)
427+ let isNewUser = $t01705217136._1
428+ let stakedAmount = $t01705217136._2
429+ let vpEffectiveHeight = $t01705217136._3
430+ let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
431+ let swapLimitMax = swapParamsSTRUCT._1
432+ let swapLimitSpent = swapParamsSTRUCT._2
433+ let blcks2LmtReset = swapParamsSTRUCT._3
434+ if ((swapLimitSpent > 0))
435+ then throw((("You have already made a swap operation. Wait " + toString((height + blcks2LmtReset))) + " height to unstake"))
436+ else if ((0 >= stakedAmount))
437+ then throw("Nothing to unstake")
438+ else if ((amount > stakedAmount))
439+ then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
440+ else {
441+ let stakedAmountNEW = (stakedAmount - amount)
442+ let $t01780617964 = StatsResult(-(amount), if ((amount == stakedAmount))
443+ then -1
444+ else 0, if ((amount == stakedAmount))
445+ then -1
446+ else 0)
447+ let statsEntries = $t01780617964._1
448+ let totalStaked = $t01780617964._2
449+ let totalStakedNew = $t01780617964._3
450+ ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
451+ }
438452 }
439453
440454
524538 }
525539 else {
526540 let userAddress = addressFromStringValue(userAddressStr)
527- let $t01995720062 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
528- let isNewUser = $t01995720062._1
529- let stakedAmount = $t01995720062._2
530- let stakingStart = $t01995720062._3
541+ let $t02053820643 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
542+ let isNewUser = $t02053820643._1
543+ let stakedAmount = $t02053820643._2
544+ let stakingStart = $t02053820643._3
531545 let stakedAmountX = toBigInt(stakedAmount)
532546 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
533547 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
534548 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
535549 func forEachAssetCalcUnclaimedReward (accum,asset) = {
536- let $t02040820546 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
537- let rewardTotal = $t02040820546._1
538- let cached = $t02040820546._2
539- let dynamic = $t02040820546._3
540- let rewardCachedPartKEY = $t02040820546._4
550+ let $t02098921127 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
551+ let rewardTotal = $t02098921127._1
552+ let cached = $t02098921127._2
553+ let dynamic = $t02098921127._3
554+ let rewardCachedPartKEY = $t02098921127._4
541555 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
542556 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
543557 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "cbd0bdc8bbba91db64066b16a84913a4c965e23e"
4+let revisionNum = "467d69db0b60c6aac0508e687248cd588338fb34"
55
66 let separator = "__"
77
88 let SEP = "__"
99
1010 let MULT6 = 1000000
1111
1212 let MULT8 = 100000000
1313
1414 let MULTX6 = toBigInt(MULT6)
1515
1616 let MULTX8 = toBigInt(MULT8)
1717
1818 let MULTX18 = toBigInt(1000000000000000000)
1919
2020 let WAVESIDSTR = "WAVES"
2121
2222 let WAVESID = fromBase58String(WAVESIDSTR)
2323
2424 let IdxControlCfgNeutrinoDapp = 1
2525
2626 let IdxControlCfgAuctionDapp = 2
2727
2828 let IdxControlCfgRpdDapp = 3
2929
3030 let IdxControlCfgMathDapp = 4
3131
3232 let IdxControlCfgLiquidationDapp = 5
3333
3434 let IdxControlCfgRestDapp = 6
3535
3636 let IdxControlCfgNodeRegistryDapp = 7
3737
3838 let IdxControlCfgNsbtStakingDapp = 8
3939
4040 let IdxControlCfgMediatorDapp = 9
4141
4242 let IdxControlCfgSurfStakingDapp = 10
4343
4444 let IdxControlCfgGnsbtControllerDapp = 11
4545
4646 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
4747
4848
4949 func keyControlAddress () = "%s%s__config__controlAddress"
5050
5151
5252 func keyControlCfg () = "%s__controlConfig"
5353
5454
5555 func keyGnsbtFromSurfCoeff () = "%s%s__cfg__gnsbtFromSurfCoeff"
5656
5757
5858 func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
5959
6060
6161 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
6262
6363
6464 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
6565
6666 let controlCfg = readControlCfgOrFail(controlContract)
6767
6868 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
6969
7070 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
7171
7272 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
7373
7474 let gnsbtFromSurfCoeff = valueOrElse(getInteger(this, keyGnsbtFromSurfCoeff()), 300)
7575
7676 func keyBondAsset () = "bond_asset_id"
7777
7878
7979 func keyAuctionContractAddress () = "auction_contract"
8080
8181
8282 func keyMinLockAmount () = "%s__minLockAmount"
8383
8484
8585 func keyStakedAssetId () = "%s__stakedAssetId"
8686
8787
8888 func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "amount"], separator)
8989
9090
9191 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "start"], separator)
9292
9393
9494 func keyLockParamVotingPowerEffectiveHeight (userAddress) = makeString(["%s%s%s", "paramByUser", toString(userAddress), "vpEffectiveHeight"], separator)
9595
9696
9797 func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, toString(userAddress), toBase58String(txId)], separator)
9898
9999
100100 func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], separator)
101101
102102
103103 func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], separator)
104104
105105
106106 func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], separator)
107107
108108
109109 func keyNextPeriod () = "%s__nextPeriod"
110110
111111
112112 func keySupportedRewardAssets () = "supportedRewardAssets"
113113
114114
115115 func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], separator)
116116
117117
118118 func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], separator)
119119
120120
121121 func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], separator)
122122
123123
124124 func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], separator)
125125
126126
127127 func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], separator)
128128
129129
130130 func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], separator)
131131
132132
133133 func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
134134
135135
136136 func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
137137
138138
139139 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
140140
141141
142142 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
143143
144144
145145 func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
146146
147147
148148 func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
149149
150150
151151 func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
152152 then unit
153153 else fromBase58String(assetStr)
154154
155155
156156 func asInt (val) = match val {
157157 case valInt: Int =>
158158 valInt
159159 case _ =>
160160 throw("fail to cast into Int")
161161 }
162162
163163
164+func asSwapParamsSTRUCT (v) = match v {
165+ case struct: (Int, Int, Int, Int, Int) =>
166+ struct
167+ case _ =>
168+ throw("fail to cast into Int")
169+}
170+
171+
164172 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)
165173
166174
167175 func formatClaimHistoryRecord (user,claimedRewards) = makeString(["%s%d%d%s", user, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], separator)
168176
169177
170178 func HistoryRecordEntry (type,userAddress,txId,oldAmount,oldStart,newAmount,newStart) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(oldAmount, oldStart, newAmount, newStart))
171179
172180
173181 func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(toString(userAddress), claimedRewards))
174182
175183
176184 func StatsResult (totalLockedInc,lockCountInc,usersCountInc) = {
177185 let locksCount = getIntOrZero(keyStatsLocksCount())
178186 let usersCount = getIntOrZero(keyStatsUsersCount())
179187 let totalAmount = getIntOrZero(keyLockParamTotalAmount())
180188 let totalAmountNew = (totalAmount + totalLockedInc)
181189 $Tuple3([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew)], totalAmount, totalAmountNew)
182190 }
183191
184192
185193 func LockParamsEntry (userAddress,amount,votingPowerEffectiveHeight) = [IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), votingPowerEffectiveHeight)]
186194
187195
188196 func getParamsOrFail () = $Tuple2(fromBase58String(getStringOrFail(this, keyStakedAssetId())), getIntOrFail(keyMinLockAmount()))
189197
190198
191199 func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
192200
193201
194202 func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
195203 then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
196204 else unit
197205
198206
199207 func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + toString(userAddress)) + " is not defined"))
200208
201209
202210 let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
203211
204212 let supportedAssetsList = split(supportedAssetsStr, "_")
205213
206214 func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
207215 let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
208216 let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
209217 let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
210218 let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
211219 let rewardCachedPartKEY = keyReward(userAddress, assetId)
212220 let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
213221 $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
214222 }
215223
216224
217225 func RewardEntries (isNewUser,userAddress,stakedAmount) = {
218226 let stakedAmountX = toBigInt(stakedAmount)
219227 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
220228 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
221229 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
222230 func forEachAssetCacheUserReward (accum,asset) = {
223- let $t088308965 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
224- let rewardTotal = $t088308965._1
225- let cached = $t088308965._2
226- let dynamic = $t088308965._3
227- let rewardCachedPartKEY = $t088308965._4
231+ let $t089839118 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
232+ let rewardTotal = $t089839118._1
233+ let cached = $t089839118._2
234+ let dynamic = $t089839118._3
235+ let rewardCachedPartKEY = $t089839118._4
228236 (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
229237 }
230238
231239 if (if ((depositNumLast == -1))
232240 then (depositNumUser == -1)
233241 else false)
234242 then nil
235243 else if (if ((depositNumLast == -1))
236244 then (depositNumUser > -1)
237245 else false)
238246 then throw("invalid depositNumLast and depositNumUser state")
239247 else if (if ((depositNumLast > -1))
240248 then (depositNumUser >= -1)
241249 else false)
242250 then if (isNewUser)
243251 then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
244252 else ({
245253 let $l = supportedAssetsList
246254 let $s = size($l)
247255 let $acc0 = nil
248256 func $f0_1 ($a,$i) = if (($i >= $s))
249257 then $a
250258 else forEachAssetCacheUserReward($a, $l[$i])
251259
252260 func $f0_2 ($a,$i) = if (($i >= $s))
253261 then $a
254262 else throw("List size exceeds 10")
255263
256264 $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)
257265 } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
258266 else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
259267 }
260268
261269
262270 func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
263271 let notDistributedRewardKEY = keyNotDistributedReward(tkn)
264272 let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
265273 [IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
266274 }
267275
268276
269277 func surfToGnsbt (surfAmt) = (surfAmt / gnsbtFromSurfCoeff)
270278
271279
272280 func mergeVotingPowerEffectiveHeight (quarantinePeriod,vpEffectiveHeight,stakedAmt,stakedAmtNEW) = {
273281 let remainingToWait = (vpEffectiveHeight - height)
274282 if ((0 >= remainingToWait))
275283 then (height + quarantinePeriod)
276284 else {
277285 let alreadyWaited = (quarantinePeriod - remainingToWait)
278286 let kX8 = if ((stakedAmtNEW != 0))
279287 then fraction(stakedAmt, MULT8, stakedAmtNEW)
280288 else vpEffectiveHeight
281289 ((quarantinePeriod + height) - fraction(alreadyWaited, kX8, MULT8))
282290 }
283291 }
284292
285293
286294 func mergeStake (userAddress,amountToAdd) = {
287- let $t01261812728 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
288- let isNewUser = $t01261812728._1
289- let stakedAmount = $t01261812728._2
290- let vpEffectiveHeight = $t01261812728._3
295+ let $t01277112881 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
296+ let isNewUser = $t01277112881._1
297+ let stakedAmount = $t01277112881._2
298+ let vpEffectiveHeight = $t01277112881._3
291299 let stakedAmountNEW = if (isNewUser)
292300 then amountToAdd
293301 else (amountToAdd + stakedAmount)
294302 let quarantinePeriod = (1440 * 14)
295303 let vpEffectiveHeightNEW = if (isNewUser)
296304 then (quarantinePeriod + height)
297305 else mergeVotingPowerEffectiveHeight(quarantinePeriod, vpEffectiveHeight, stakedAmount, stakedAmountNEW)
298306 $Tuple5(isNewUser, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)
299307 }
300308
301309
302310 func commonStake (userAddress,i) = {
303- let $t01321413268 = getParamsOrFail()
304- let stakedAssetId = $t01321413268._1
305- let minLockAmount = $t01321413268._2
311+ let $t01336713421 = getParamsOrFail()
312+ let stakedAssetId = $t01336713421._1
313+ let minLockAmount = $t01336713421._2
306314 if ((size(i.payments) != 1))
307315 then throw("Invalid payments size")
308316 else {
309317 let payment = i.payments[0]
310318 let amount = payment.amount
311319 let invalidAssetMessage = (("Invalid asset. " + toBase58String(stakedAssetId)) + " is expected")
312320 let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
313321 if ((assetId != stakedAssetId))
314322 then throw(invalidAssetMessage)
315323 else {
316324 let userAddressStr = toString(userAddress)
317325 let mergedData = mergeStake(userAddress, amount)
318326 let isNewUser = mergedData._1
319327 let stakedAmount = mergedData._2
320328 let vpEffectiveHeight = mergedData._3
321329 let stakedAmountNEW = mergedData._4
322330 let vpEffectiveHeightNEW = mergedData._5
323331 if ((minLockAmount > stakedAmountNEW))
324332 then throw(("Min lock amount is " + toString(minLockAmount)))
325333 else {
326- let $t01406714169 = StatsResult(amount, 1, if (isNewUser)
334+ let $t01422014322 = StatsResult(amount, 1, if (isNewUser)
327335 then 1
328336 else 0)
329- let statsEntries = $t01406714169._1
330- let totalStaked = $t01406714169._2
331- let totalStakedNew = $t01406714169._3
337+ let statsEntries = $t01422014322._1
338+ let totalStaked = $t01422014322._2
339+ let totalStakedNew = $t01422014322._3
332340 ((([HistoryRecordEntry("stake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeightNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeightNEW)) ++ statsEntries)
333341 }
334342 }
335343 }
336344 }
337345
338346
339347 func commonClaim (userAddress,i) = {
340348 let userAddressStr = toString(userAddress)
341349 if ((size(i.payments) > 0))
342350 then throw("payments are not accepted")
343351 else {
344- let $t01464814753 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
345- let isNewUser = $t01464814753._1
346- let stakedAmount = $t01464814753._2
347- let stakingStart = $t01464814753._3
352+ let $t01480114906 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
353+ let isNewUser = $t01480114906._1
354+ let stakedAmount = $t01480114906._2
355+ let stakingStart = $t01480114906._3
348356 let stakedAmountX = toBigInt(stakedAmount)
349357 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
350358 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
351359 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
352360 func forEachAssetCalcUnclaimedReward (accum,asset) = {
353- let $t01512415262 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
354- let rewardTotal = $t01512415262._1
355- let cached = $t01512415262._2
356- let dynamic = $t01512415262._3
357- let rewardCachedPartKEY = $t01512415262._4
361+ let $t01527715415 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
362+ let rewardTotal = $t01527715415._1
363+ let cached = $t01527715415._2
364+ let dynamic = $t01527715415._3
365+ let rewardCachedPartKEY = $t01527715415._4
358366 let claimedKEY = keyClaimed(userAddressStr, asset)
359- let $t01532215359 = accum
360- let data = $t01532215359._1
361- let claimedAmtByAsset = $t01532215359._2
367+ let $t01547515512 = accum
368+ let data = $t01547515512._1
369+ let claimedAmtByAsset = $t01547515512._2
362370 let newPart = makeString([asset, toString(rewardTotal)], ":")
363371 let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
364372 if ((0 >= rewardTotal))
365373 then $Tuple2(data, claimedAmtByAssetNew)
366374 else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
367375 }
368376
369- let $t01581915933 = {
377+ let $t01597216086 = {
370378 let $l = supportedAssetsList
371379 let $s = size($l)
372380 let $acc0 = $Tuple2(nil, "")
373381 func $f0_1 ($a,$i) = if (($i >= $s))
374382 then $a
375383 else forEachAssetCalcUnclaimedReward($a, $l[$i])
376384
377385 func $f0_2 ($a,$i) = if (($i >= $s))
378386 then $a
379387 else throw("List size exceeds 10")
380388
381389 $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)
382390 }
383- let transfers = $t01581915933._1
384- let claimedAmtByAssetResult = $t01581915933._2
391+ let transfers = $t01597216086._1
392+ let claimedAmtByAssetResult = $t01597216086._2
385393 if ((0 >= size(transfers)))
386394 then nil
387395 else ((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddress, i.transactionId, drop(claimedAmtByAssetResult, 1)))
388396 }
389397 }
390398
391399
392400 @Callable(i)
393401 func constructor (minLockAmount,supportedRewardAssets,stakedAssetId) = if ((i.caller != this))
394402 then throw("Permission denied")
395403 else [IntegerEntry(keyMinLockAmount(), minLockAmount), StringEntry(keySupportedRewardAssets(), supportedRewardAssets), StringEntry(keyStakedAssetId(), stakedAssetId)]
396404
397405
398406
399407 @Callable(i)
400408 func stake () = commonStake(i.caller, i)
401409
402410
403411
404412 @Callable(i)
405413 func stakeByOriginCaller () = commonStake(i.originCaller, i)
406414
407415
408416
409417 @Callable(i)
410418 func unstake (amount) = if ((size(i.payments) != 0))
411419 then throw("unstake doesn't require any payment")
412420 else {
413421 let userAddress = i.caller
414422 let userAddressStr = toString(userAddress)
415- let $t01684216896 = getParamsOrFail()
416- let stakedAssetId = $t01684216896._1
417- let minLockAmount = $t01684216896._2
418- let $t01689916983 = getUserParamsOrFail(userAddress)
419- let isNewUser = $t01689916983._1
420- let stakedAmount = $t01689916983._2
421- let vpEffectiveHeight = $t01689916983._3
422- if ((0 >= stakedAmount))
423- then throw("Nothing to unstake")
424- else if ((amount > stakedAmount))
425- then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
426- else {
427- let stakedAmountNEW = (stakedAmount - amount)
428- let $t01722517383 = StatsResult(-(amount), if ((amount == stakedAmount))
429- then -1
430- else 0, if ((amount == stakedAmount))
431- then -1
432- else 0)
433- let statsEntries = $t01722517383._1
434- let totalStaked = $t01722517383._2
435- let totalStakedNew = $t01722517383._3
436- ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
437- }
423+ let $t01699517049 = getParamsOrFail()
424+ let stakedAssetId = $t01699517049._1
425+ let minLockAmount = $t01699517049._2
426+ let $t01705217136 = getUserParamsOrFail(userAddress)
427+ let isNewUser = $t01705217136._1
428+ let stakedAmount = $t01705217136._2
429+ let vpEffectiveHeight = $t01705217136._3
430+ let swapParamsSTRUCT = asSwapParamsSTRUCT(reentrantInvoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStr, 0], nil))
431+ let swapLimitMax = swapParamsSTRUCT._1
432+ let swapLimitSpent = swapParamsSTRUCT._2
433+ let blcks2LmtReset = swapParamsSTRUCT._3
434+ if ((swapLimitSpent > 0))
435+ then throw((("You have already made a swap operation. Wait " + toString((height + blcks2LmtReset))) + " height to unstake"))
436+ else if ((0 >= stakedAmount))
437+ then throw("Nothing to unstake")
438+ else if ((amount > stakedAmount))
439+ then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
440+ else {
441+ let stakedAmountNEW = (stakedAmount - amount)
442+ let $t01780617964 = StatsResult(-(amount), if ((amount == stakedAmount))
443+ then -1
444+ else 0, if ((amount == stakedAmount))
445+ then -1
446+ else 0)
447+ let statsEntries = $t01780617964._1
448+ let totalStaked = $t01780617964._2
449+ let totalStakedNew = $t01780617964._3
450+ ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddress, i.transactionId, stakedAmount, vpEffectiveHeight, stakedAmountNEW, vpEffectiveHeight)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddress, stakedAmountNEW, vpEffectiveHeight)) ++ statsEntries)
451+ }
438452 }
439453
440454
441455
442456 @Callable(i)
443457 func deposit () = if ((size(i.payments) != 1))
444458 then throw("exact 1 payment is allowed only")
445459 else {
446460 let pmt = i.payments[0]
447461 let amount = pmt.amount
448462 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
449463 let pmtAssetIdStr = toBase58String(pmtAssetId)
450464 let pmtMultX = if ((pmtAssetId == WAVESID))
451465 then MULTX8
452466 else MULTX6
453467 let amountX = toBigInt(amount)
454468 let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
455469 let totalStakedX = toBigInt(totalStaked)
456470 if ((0 > totalStaked))
457471 then throw("TODO: case is not supported")
458472 else if ((totalStaked == 0))
459473 then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
460474 else {
461475 let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
462476 let depositNumLastKEY = keyDepositNumLast()
463477 let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
464478 let depositNumNew = (depositNumLast + 1)
465479 if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
466480 then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
467481 else {
468482 func refreshRewardPerNsbtSUM (accum,nextAsset) = {
469483 let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
470484 let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
471485 (accum :+ (if ((nextAsset == pmtAssetIdStr))
472486 then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
473487 else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
474488 }
475489
476490 ({
477491 let $l = supportedAssetsList
478492 let $s = size($l)
479493 let $acc0 = nil
480494 func $f0_1 ($a,$i) = if (($i >= $s))
481495 then $a
482496 else refreshRewardPerNsbtSUM($a, $l[$i])
483497
484498 func $f0_2 ($a,$i) = if (($i >= $s))
485499 then $a
486500 else throw("List size exceeds 10")
487501
488502 $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)
489503 } :+ IntegerEntry(depositNumLastKEY, depositNumNew))
490504 }
491505 }
492506 }
493507
494508
495509
496510 @Callable(i)
497511 func claimRewards () = commonClaim(i.caller, i)
498512
499513
500514
501515 @Callable(i)
502516 func claimRewardsByOriginCaller () = commonClaim(i.originCaller, i)
503517
504518
505519
506520 @Callable(i)
507521 func unclaimedRewardsREADONLY (userAddressStr) = {
508522 func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
509523
510524 let unclaimedRewardStr = if ((userAddressStr == ""))
511525 then {
512526 let $l = supportedAssetsList
513527 let $s = size($l)
514528 let $acc0 = ""
515529 func $f0_1 ($a,$i) = if (($i >= $s))
516530 then $a
517531 else forEachAssetZeroReward($a, $l[$i])
518532
519533 func $f0_2 ($a,$i) = if (($i >= $s))
520534 then $a
521535 else throw("List size exceeds 10")
522536
523537 $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)
524538 }
525539 else {
526540 let userAddress = addressFromStringValue(userAddressStr)
527- let $t01995720062 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
528- let isNewUser = $t01995720062._1
529- let stakedAmount = $t01995720062._2
530- let stakingStart = $t01995720062._3
541+ let $t02053820643 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, 0))
542+ let isNewUser = $t02053820643._1
543+ let stakedAmount = $t02053820643._2
544+ let stakingStart = $t02053820643._3
531545 let stakedAmountX = toBigInt(stakedAmount)
532546 let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
533547 let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
534548 let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
535549 func forEachAssetCalcUnclaimedReward (accum,asset) = {
536- let $t02040820546 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
537- let rewardTotal = $t02040820546._1
538- let cached = $t02040820546._2
539- let dynamic = $t02040820546._3
540- let rewardCachedPartKEY = $t02040820546._4
550+ let $t02098921127 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
551+ let rewardTotal = $t02098921127._1
552+ let cached = $t02098921127._2
553+ let dynamic = $t02098921127._3
554+ let rewardCachedPartKEY = $t02098921127._4
541555 let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
542556 ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
543557 }
544558
545559 let $l = supportedAssetsList
546560 let $s = size($l)
547561 let $acc0 = ""
548562 func $f0_1 ($a,$i) = if (($i >= $s))
549563 then $a
550564 else forEachAssetCalcUnclaimedReward($a, $l[$i])
551565
552566 func $f0_2 ($a,$i) = if (($i >= $s))
553567 then $a
554568 else throw("List size exceeds 10")
555569
556570 $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)
557571 }
558572 $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
559573 }
560574
561575
562576
563577 @Callable(i)
564578 func surfStakingSYSREADONLY (userAddressStrOrEmpty,surfDiff) = {
565579 let surfTotal = getIntOrElse(keyLockParamTotalAmount(), 0)
566580 let gnsbtFromSurfTotal = surfToGnsbt(surfTotal)
567581 if ((userAddressStrOrEmpty == ""))
568582 then $Tuple2(nil, [0, surfTotal, 0, gnsbtFromSurfTotal, 0, height, height])
569583 else {
570584 let userAddress = toAddressOrFail(userAddressStrOrEmpty)
571585 let mergedData = mergeStake(userAddress, surfDiff)
572586 let isNewUser = mergedData._1
573587 let stakedAmount = mergedData._2
574588 let vpEffectiveHeight = mergedData._3
575589 let stakedAmountNEW = mergedData._4
576590 let vpEffectiveHeightNEW = mergedData._5
577591 let surfUser = stakedAmount
578592 let gnsbtFromSurfUser = surfToGnsbt(surfUser)
579593 $Tuple2(nil, [surfUser, surfTotal, gnsbtFromSurfUser, gnsbtFromSurfTotal, vpEffectiveHeight, vpEffectiveHeightNEW])
580594 }
581595 }
582596
583597
584598
585599 @Callable(i)
586600 func gnsbtFromSurfSYSREADONLY (surfAmt) = $Tuple2(nil, surfToGnsbt(surfAmt))
587601
588602
589603
590604 @Callable(i)
591605 func configSYSREADONLY () = {
592606 let minLockAmt = getIntegerValue(keyMinLockAmount())
593607 let surfVotingPowerRestrictivePeriod = (1440 * 14)
594608 let brToStartSurfTransformation = 1150000
595609 $Tuple2(nil, [minLockAmt, (gnsbtFromSurfCoeff * MULT6), surfVotingPowerRestrictivePeriod, brToStartSurfTransformation])
596610 }
597611
598612

github/deemru/w8io/786bc32 
78.58 ms