tx · FZgfsXSZoD4pgdTG3uhsugAHj3wz7KkbcJaShrzk8MAc

3N1Ay1K9wSK3yUNTdufdMuEV9fwY29TD7eb:  -0.03000000 Waves

2022.12.08 13:08 [2351224] smart account 3N1Ay1K9wSK3yUNTdufdMuEV9fwY29TD7eb > SELF 0.00000000 Waves

{ "type": 13, "id": "FZgfsXSZoD4pgdTG3uhsugAHj3wz7KkbcJaShrzk8MAc", "fee": 3000000, "feeAssetId": null, "timestamp": 1670494089424, "version": 2, "chainId": 84, "sender": "3N1Ay1K9wSK3yUNTdufdMuEV9fwY29TD7eb", "senderPublicKey": "4e5NoCiw1XuuVDogdELe1ovfZxz1DQLRijc5YBGeLXoG", "proofs": [ "L4dzMMAGRdUk8s4dkVKkDMxXaPTcaZFCeXvKXLeYCPPBCCiHzrCyoXVy2KvqAEiYK1CkLFzLdiKSs7LjDpbi4y7" ], "script": "base64:BgI+CAISBQoDAQgIEgMKAQgSABIAEgMKAQESABIAEgASAwoBCBIECgIIARIAEgQKAggBEgASBAoCAQgSBAoCAQhoAAtyZXZpc2lvbk51bQIAAANTRVACAl9fAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ABk1VTFRYNgkAtgIBBQVNVUxUNgAGTVVMVFg4CQC2AgEFBU1VTFQ4AAdNVUxUWDE4CQC2AgEAgICQu7rWrfANAApXQVZFU0lEU1RSAgVXQVZFUwAHV0FWRVNJRAkA2QQBBQpXQVZFU0lEU1RSAAlEQVlNSUxMSVMAgLiZKQAZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAABABhJZHhDb250cm9sQ2ZnQXVjdGlvbkRhcHAAAgAUSWR4Q29udHJvbENmZ1JwZERhcHAAAwAVSWR4Q29udHJvbENmZ01hdGhEYXBwAAQAHElkeENvbnRyb2xDZmdMaXF1aWRhdGlvbkRhcHAABQAVSWR4Q29udHJvbENmZ1Jlc3REYXBwAAYAHUlkeENvbnRyb2xDZmdOb2RlUmVnaXN0cnlEYXBwAAcAHElkeENvbnRyb2xDZmdOc2J0U3Rha2luZ0RhcHAACAAZSWR4Q29udHJvbENmZ01lZGlhdG9yRGFwcAAJABxJZHhDb250cm9sQ2ZnU3VyZlN0YWtpbmdEYXBwAAoAIElkeENvbnRyb2xDZmdHbnNidENvbnRyb2xsZXJEYXBwAAsBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICCQCsAgIJAKwCAgIKbWFuZGF0b3J5IAkApQgBBQdhZGRyZXNzAgEuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEMZ2V0SW50T3JGYWlsAQNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQNrZXkJAKwCAgkArAICAg9NYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAQxnZXRTdHJPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAEQa2V5TWluTG9ja0Ftb3VudAACESVzX19taW5Mb2NrQW1vdW50ARBrZXlTdGFrZWRBc3NldElkAAIRJXNfX3N0YWtlZEFzc2V0SWQBEWtleUNvbnRyb2xBZGRyZXNzAAIcJXMlc19fY29uZmlnX19jb250cm9sQWRkcmVzcwENa2V5Q29udHJvbENmZwACESVzX19jb250cm9sQ29uZmlnARhrZXlTdXBwb3J0ZWRSZXdhcmRBc3NldHMAAhVzdXBwb3J0ZWRSZXdhcmRBc3NldHMBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQdjb250cm9sCQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQdjb250cm9sCQENa2V5Q29udHJvbENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgpjb250cm9sQ2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKY29udHJvbENmZwUDaWR4CQCsAgICLUNvbnRyb2wgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgAD2NvbnRyb2xDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQERa2V5Q29udHJvbEFkZHJlc3MAAiMzUDVCZmQ1OFBQZk52Qk0ySHk4UWZiY0RxTWVOdHpnN0tmUAAKY29udHJvbENmZwkBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQUPY29udHJvbENvbnRyYWN0AAxtYXRoQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRVJZHhDb250cm9sQ2ZnTWF0aERhcHAAEG5ldXRyaW5vQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRlJZHhDb250cm9sQ2ZnTmV1dHJpbm9EYXBwAA9hdWN0aW9uQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRhJZHhDb250cm9sQ2ZnQXVjdGlvbkRhcHAAEHN0YWtlZEFzc2V0SWRTdHIJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQEQa2V5U3Rha2VkQXNzZXRJZAAADXN0YWtlZEFzc2V0SWQJANkEAQUQc3Rha2VkQXNzZXRJZFN0cgANbWluTG9ja0Ftb3VudAkBDGdldEludE9yRmFpbAEJARBrZXlNaW5Mb2NrQW1vdW50AAASc3VwcG9ydGVkQXNzZXRzU3RyCQEMZ2V0U3RyT3JFbHNlAgkBGGtleVN1cHBvcnRlZFJld2FyZEFzc2V0cwACAAATc3VwcG9ydGVkQXNzZXRzTGlzdAkAtQkCBRJzdXBwb3J0ZWRBc3NldHNTdHICAV8BFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBmFtb3VudAUDbmlsBQNTRVABFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBXN0YXJ0BQNuaWwFA1NFUAEQa2V5SGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwR0eElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgIHaGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJANgEAQUEdHhJZAUDbmlsBQNTRVABF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAkAuQkCCQDMCAICBCVzJXMJAMwIAgIFc3RhdHMJAMwIAgIRYWN0aXZlVG90YWxMb2NrZWQFA25pbAUDU0VQARJrZXlTdGF0c0xvY2tzQ291bnQACQC5CQIJAMwIAgIEJXMlcwkAzAgCAgVzdGF0cwkAzAgCAgpsb2Nrc0NvdW50BQNuaWwFA1NFUAESa2V5U3RhdHNVc2Vyc0NvdW50AAkAuQkCCQDMCAICBCVzJXMJAMwIAgIFc3RhdHMJAMwIAgIQYWN0aXZlVXNlcnNDb3VudAUDbmlsBQNTRVABF2tleVN0YXRzRGVwb3NpdEFtdEJ5RGF5AQl0aW1lc3RhbXAJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIFc3RhdHMJAMwIAgIPZGVwb3NpdEFtdEJ5RGF5CQDMCAIJAKQDAQUJdGltZXN0YW1wBQNuaWwFA1NFUAEYa2V5U3RhdHNEZXBvc2l0QW10VG90YWxzAAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgVzdGF0cwkAzAgCAhBkZXBvc2l0QW10VG90YWxzBQNuaWwFA1NFUAENa2V5TmV4dFBlcmlvZAACDiVzX19uZXh0UGVyaW9kARFrZXlEZXBvc2l0TnVtTGFzdAAJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIDZGVwCQDMCAICB2xhc3ROdW0FA25pbAUDU0VQARtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0BC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICEXVzZXJSd2RGcm9tRGVwTnVtCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgpkZXBvc2l0TnVtA3RrbgkAuQkCCQDMCAICBCVzJWQJAMwIAgIVcndkUGVyTnNidFN1bUJ5RGVwTnVtCQDMCAIJAKQDAQUKZGVwb3NpdE51bQkAzAgCBQN0a24FA25pbAUDU0VQAQlrZXlSZXdhcmQCC3VzZXJBZGRyZXNzA3RrbgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgNyd2QJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUDdGtuBQNuaWwFA1NFUAEKa2V5Q2xhaW1lZAILdXNlckFkZHJlc3MDdGtuCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICA2NsbQkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQN0a24FA25pbAUDU0VQARdrZXlOb3REaXN0cmlidXRlZFJld2FyZAEDdGtuCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg5ub3REaXN0cmlidXRlZAkAzAgCBQN0a24FA25pbAUDU0VQARRrZXlMZWdhY3lVc2VyQmFsYW5jZQIIdXNlckFkZHIDdGtuCQC5CQIJAMwIAgILcnBkX2JhbGFuY2UJAMwIAgUDdGtuCQDMCAIFCHVzZXJBZGRyBQNuaWwCAV8BFWtleUxlZ2FjeVRvdGFsQmFsYW5jZQEDdGtuCQC5CQIJAMwIAgILcnBkX2JhbGFuY2UJAMwIAgUDdGtuBQNuaWwCAV8BBXRvWDE4AgdvcmlnVmFsCG9yaWdNdWx0CQC8AgMJALYCAQUHb3JpZ1ZhbAUHTVVMVFgxOAUIb3JpZ011bHQBDGdldEludE9yWmVybwEDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQAAAQxnZXRJbnRPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAEPdG9BZGRyZXNzT3JGYWlsAQphZGRyZXNzU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUKYWRkcmVzc1N0cgkArAICAiFjb3VsZG4ndCBwYXJzZSBwYXNzZWQgYWRkcmVzc1N0cj0FCmFkZHJlc3NTdHIBC3RvQXNzZXRWZWN0AQhhc3NldFN0cgMJAAACBQhhc3NldFN0cgUKV0FWRVNJRFNUUgUEdW5pdAkA2QQBBQhhc3NldFN0cgEFYXNJbnQBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACA0ludAQGdmFsSW50BQckbWF0Y2gwBQZ2YWxJbnQJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBEmFzU3dhcFBhcmFtc1NUUlVDVAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAiMoSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50KQQGc3RydWN0BQckbWF0Y2gwBQZzdHJ1Y3QJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBE2Zvcm1hdEhpc3RvcnlSZWNvcmQDC3VzZXJBZGRyZXNzCW9sZEFtb3VudAluZXdBbW91bnQJALkJAgkAzAgCAgolcyVkJWQlZCVkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFCW9sZEFtb3VudAkAzAgCCQCkAwEFCW5ld0Ftb3VudAUDbmlsBQNTRVABGGZvcm1hdENsYWltSGlzdG9yeVJlY29yZAILdXNlckFkZHJlc3MOY2xhaW1lZFJld2FyZHMJALkJAgkAzAgCAgglcyVkJWQlcwkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgUOY2xhaW1lZFJld2FyZHMFA25pbAUDU0VQARJIaXN0b3J5UmVjb3JkRW50cnkFBHR5cGULdXNlckFkZHJlc3MEdHhJZAlvbGRBbW91bnQJbmV3QW1vdW50CQELU3RyaW5nRW50cnkCCQEQa2V5SGlzdG9yeVJlY29yZAMFBHR5cGUFC3VzZXJBZGRyZXNzBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAMFC3VzZXJBZGRyZXNzBQlvbGRBbW91bnQFCW5ld0Ftb3VudAERQ2xhaW1IaXN0b3J5RW50cnkDC3VzZXJBZGRyZXNzBHR4SWQOY2xhaW1lZFJld2FyZHMJAQtTdHJpbmdFbnRyeQIJARBrZXlIaXN0b3J5UmVjb3JkAwIFY2xhaW0FC3VzZXJBZGRyZXNzBQR0eElkCQEYZm9ybWF0Q2xhaW1IaXN0b3J5UmVjb3JkAgULdXNlckFkZHJlc3MFDmNsYWltZWRSZXdhcmRzAQtTdGF0c1Jlc3VsdAQOdG90YWxMb2NrZWRJbmMMbG9ja0NvdW50SW5jDXVzZXJzQ291bnRJbmMLaXNNaWdyYXRpb24ECmxvY2tzQ291bnQJAQxnZXRJbnRPclplcm8BCQESa2V5U3RhdHNMb2Nrc0NvdW50AAQKdXNlcnNDb3VudAkBDGdldEludE9yWmVybwEJARJrZXlTdGF0c1VzZXJzQ291bnQABAt0b3RhbEFtb3VudAkBDGdldEludE9yWmVybwEJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEDnRvdGFsQW1vdW50TmV3CQBkAgULdG90YWxBbW91bnQFDnRvdGFsTG9ja2VkSW5jCQCVCgMJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleVN0YXRzTG9ja3NDb3VudAAJAGQCBQpsb2Nrc0NvdW50BQxsb2NrQ291bnRJbmMJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlTdGF0c1VzZXJzQ291bnQACQBkAgUKdXNlcnNDb3VudAUNdXNlcnNDb3VudEluYwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAUOdG90YWxBbW91bnROZXcFA25pbAMFC2lzTWlncmF0aW9uBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJARVrZXlMZWdhY3lUb3RhbEJhbGFuY2UBBRBzdGFrZWRBc3NldElkU3RyBQ50b3RhbEFtb3VudE5ldwUDbmlsBQt0b3RhbEFtb3VudAUOdG90YWxBbW91bnROZXcBD0xvY2tQYXJhbXNFbnRyeQQLdXNlckFkZHJlc3MGYW1vdW50EnN0YWtpbmdTdGFydEhlaWdodAtpc01pZ3JhdGlvbgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFC3VzZXJBZGRyZXNzBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQULdXNlckFkZHJlc3MFEnN0YWtpbmdTdGFydEhlaWdodAUDbmlsAwULaXNNaWdyYXRpb24FA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleUxlZ2FjeVVzZXJCYWxhbmNlAgULdXNlckFkZHJlc3MFEHN0YWtlZEFzc2V0SWRTdHIFBmFtb3VudAUDbmlsAQ9nZXRQYXJhbXNPckZhaWwACQCUCgIJANkEAQkBD2dldFN0cmluZ09yRmFpbAIFBHRoaXMJARBrZXlTdGFrZWRBc3NldElkAAkBDGdldEludE9yRmFpbAEJARBrZXlNaW5Mb2NrQW1vdW50AAEMaXNBY3RpdmVVc2VyAQt1c2VyQWRkcmVzcwkAZgIJAQxnZXRJbnRPckVsc2UCCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFC3VzZXJBZGRyZXNzAAAAAAETZ2V0VXNlclBhcmFtc09yVW5pdAELdXNlckFkZHJlc3MDCQEMaXNBY3RpdmVVc2VyAQULdXNlckFkZHJlc3MJAJUKAwcJAQxnZXRJbnRPckZhaWwBCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFC3VzZXJBZGRyZXNzCQEMZ2V0SW50T3JGYWlsAQkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQt1c2VyQWRkcmVzcwUEdW5pdAETZ2V0VXNlclBhcmFtc09yRmFpbAELdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkBE2dldFVzZXJQYXJhbXNPclVuaXQBBQt1c2VyQWRkcmVzcwkArAICCQCsAgICBVVzZXIgBQt1c2VyQWRkcmVzcwIPIGlzIG5vdCBkZWZpbmVkAQpjYWxjUmV3YXJkBQt1c2VyQWRkcmVzcwdhc3NldElkDXN0YWtlZEFtb3VudFgOZGVwb3NpdE51bVVzZXIOZGVwb3NpdE51bUxhc3QEF3Jld2FyZFBlck5zYnRTdW1MYXN0S0VZCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUOZGVwb3NpdE51bUxhc3QFB2Fzc2V0SWQECnN1bUxhc3RYMTgJAKcDAQkBDGdldFN0ck9yRWxzZQIJARVrZXlSZXdhcmRQZXJOc2J0U3VtQXQCBQ5kZXBvc2l0TnVtTGFzdAUHYXNzZXRJZAIBMAQKc3VtVXNlclgxOAkApwMBCQEMZ2V0U3RyT3JFbHNlAgkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1Vc2VyBQdhc3NldElkAgEwBBFyZXdhcmREeW5hbWljUGFydAkAoAMBCQC8AgMJALgCAgUKc3VtTGFzdFgxOAUKc3VtVXNlclgxOAUNc3Rha2VkQW1vdW50WAUHTVVMVFgxOAQTcmV3YXJkQ2FjaGVkUGFydEtFWQkBCWtleVJld2FyZAIFC3VzZXJBZGRyZXNzBQdhc3NldElkBBByZXdhcmRDYWNoZWRQYXJ0CQEMZ2V0SW50T3JFbHNlAgUTcmV3YXJkQ2FjaGVkUGFydEtFWQAACQCWCgQJAGQCBRByZXdhcmRDYWNoZWRQYXJ0BRFyZXdhcmREeW5hbWljUGFydAUQcmV3YXJkQ2FjaGVkUGFydAURcmV3YXJkRHluYW1pY1BhcnQFE3Jld2FyZENhY2hlZFBhcnRLRVkBDHRvU3RhcnRPZkRheQEJdGltZXN0YW1wCQBoAgkAaQIFCXRpbWVzdGFtcAUJREFZTUlMTElTBQlEQVlNSUxMSVMBE2ZpbmRFbGVtZW50UG9zaXRpb24DA3NyYwdlbGVtZW50A3NlcAQMZWxlbWVudFN0YXJ0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJALMJAgUDc3JjBQdlbGVtZW50CQCsAgIJAKwCAgkArAICAhZ0aGVyZSBpcyBubyBzdWJzdHJpbmcgBQdlbGVtZW50AgQgaW4gBQNzcmMDCQAAAgUMZWxlbWVudFN0YXJ0AAAAAAQEbGVmdAkArwICBQNzcmMFDGVsZW1lbnRTdGFydAkAZQIJAJADAQkAtQkCBQRsZWZ0BQNzZXAAAQATRGVwb3NpdFRvdGFsc1BSRUZJWAIEJWQlZAETdXBkYXRlRGVwb3NpdFRvdGFscwMHY3VyclZhbAtpZHhUb1VwZGF0ZQhkZWx0YUFtdAQHY3VyckFycgkAtQkCBQdjdXJyVmFsBQNTRVAKAQ51cGREZXBUb3RCeUlkeAEDaWR4AwkBAiE9AgUDaWR4BQtpZHhUb1VwZGF0ZQkAkQMCBQdjdXJyQXJyBQNpZHgJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdjdXJyQXJyBQNpZHgFCGRlbHRhQW10CQC5CQIJAMwIAgUTRGVwb3NpdFRvdGFsc1BSRUZJWAkAzAgCCQEOdXBkRGVwVG90QnlJZHgBAAEJAMwIAgkBDnVwZERlcFRvdEJ5SWR4AQACBQNuaWwFA1NFUAEVRGVwb3NpdHNUb3RhbHNFbnRyaWVzAg1kZXBvc2l0QW1vdW50CmFzc2V0SWRTdHIECnN0YXJ0T2ZEYXkJAQx0b1N0YXJ0T2ZEYXkBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQIYnlEYXlLRVkJARdrZXlTdGF0c0RlcG9zaXRBbXRCeURheQEFCnN0YXJ0T2ZEYXkECXRvdGFsc0tFWQkBGGtleVN0YXRzRGVwb3NpdEFtdFRvdGFscwAECHBvc2l0aW9uCQETZmluZEVsZW1lbnRQb3NpdGlvbgMFEnN1cHBvcnRlZEFzc2V0c1N0cgUKYXNzZXRJZFN0cgIBXwQLZGVmYXVsdERBVEEJAKwCAgUTRGVwb3NpdFRvdGFsc1BSRUZJWAIGX18wX18wBA5jdXJyVG90YWxzREFUQQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQl0b3RhbHNLRVkFC2RlZmF1bHREQVRBBA1uZXdUb3RhbHNEQVRBCQETdXBkYXRlRGVwb3NpdFRvdGFscwMFDmN1cnJUb3RhbHNEQVRBCQBkAgUIcG9zaXRpb24AAQUNZGVwb3NpdEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCBQl0b3RhbHNLRVkFDW5ld1RvdGFsc0RBVEEJAMwIAgkBC1N0cmluZ0VudHJ5AgUIYnlEYXlLRVkFDW5ld1RvdGFsc0RBVEEFA25pbAENUmV3YXJkRW50cmllcwMJaXNOZXdVc2VyC3VzZXJBZGRyZXNzDHN0YWtlZEFtb3VudAQNc3Rha2VkQW1vdW50WAkAtgIBBQxzdGFrZWRBbW91bnQEG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQkBG2tleVVzZXJSZXdhcmRGcm9tRGVwb3NpdE51bQEFC3VzZXJBZGRyZXNzBA5kZXBvc2l0TnVtVXNlcgkBDGdldEludE9yRWxzZQIFG3VzZXJSZXdhcmRGcm9tRGVwb3NpdE51bUtFWQD///////////8BBA5kZXBvc2l0TnVtTGFzdAkBDGdldEludE9yRWxzZQIJARFrZXlEZXBvc2l0TnVtTGFzdAAA////////////AQoBG2ZvckVhY2hBc3NldENhY2hlVXNlclJld2FyZAIFYWNjdW0FYXNzZXQEDSR0MDEwNzI1MTA4NjAJAQpjYWxjUmV3YXJkBQULdXNlckFkZHJlc3MFBWFzc2V0BQ1zdGFrZWRBbW91bnRYBQ5kZXBvc2l0TnVtVXNlcgUOZGVwb3NpdE51bUxhc3QEC3Jld2FyZFRvdGFsCAUNJHQwMTA3MjUxMDg2MAJfMQQGY2FjaGVkCAUNJHQwMTA3MjUxMDg2MAJfMgQHZHluYW1pYwgFDSR0MDEwNzI1MTA4NjACXzMEE3Jld2FyZENhY2hlZFBhcnRLRVkIBQ0kdDAxMDcyNTEwODYwAl80CQDNCAIFBWFjY3VtCQEMSW50ZWdlckVudHJ5AgUTcmV3YXJkQ2FjaGVkUGFydEtFWQULcmV3YXJkVG90YWwDAwkAAAIFDmRlcG9zaXROdW1MYXN0AP///////////wEJAAACBQ5kZXBvc2l0TnVtVXNlcgD///////////8BBwUDbmlsAwMJAAACBQ5kZXBvc2l0TnVtTGFzdAD///////////8BCQBmAgUOZGVwb3NpdE51bVVzZXIA////////////AQcJAAIBAi9pbnZhbGlkIGRlcG9zaXROdW1MYXN0IGFuZCBkZXBvc2l0TnVtVXNlciBzdGF0ZQMDCQBmAgUOZGVwb3NpdE51bUxhc3QA////////////AQkAZwIFDmRlcG9zaXROdW1Vc2VyAP///////////wEHAwUJaXNOZXdVc2VyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkFDmRlcG9zaXROdW1MYXN0BQNuaWwJAM0IAgoAAiRsBRNzdXBwb3J0ZWRBc3NldHNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARtmb3JFYWNoQXNzZXRDYWNoZVVzZXJSZXdhcmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDIJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAkAAgEJAKwCAgkArAICCQCsAgICJHVuY292ZXJlZCBjb25kaXRpb246IGRlcG9zaXROdW1MYXN0PQkApAMBBQ5kZXBvc2l0TnVtTGFzdAIQIGRlcG9zaXROdW1Vc2VyPQkApAMBBQ5kZXBvc2l0TnVtVXNlcgEiSW5jcmVtZW50Tm90RGlzdHJpYnV0ZWRSZXdhcmRFbnRyeQIDdGtuCWFtb3VudEluYwQXbm90RGlzdHJpYnV0ZWRSZXdhcmRLRVkJARdrZXlOb3REaXN0cmlidXRlZFJld2FyZAEFA3RrbgQUbm90RGlzdHJpYnV0ZWRSZXdhcmQJAQxnZXRJbnRPckVsc2UCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdub3REaXN0cmlidXRlZFJld2FyZEtFWQkAZAIFFG5vdERpc3RyaWJ1dGVkUmV3YXJkBQlhbW91bnRJbmMFA25pbAEKbWVyZ2VTdGFrZQILdXNlckFkZHJlc3MLYW1vdW50VG9BZGQEDSR0MDEzNjg0MTM4MDAJAQt2YWx1ZU9yRWxzZQIJARNnZXRVc2VyUGFyYW1zT3JVbml0AQULdXNlckFkZHJlc3MJAJUKAwYAAAUGaGVpZ2h0BAlpc05ld1VzZXIIBQ0kdDAxMzY4NDEzODAwAl8xBAxzdGFrZWRBbW91bnQIBQ0kdDAxMzY4NDEzODAwAl8yBBJzdGFraW5nU3RhcnRIZWlnaHQIBQ0kdDAxMzY4NDEzODAwAl8zBA9zdGFrZWRBbW91bnRORVcDBQlpc05ld1VzZXIFC2Ftb3VudFRvQWRkCQBkAgULYW1vdW50VG9BZGQFDHN0YWtlZEFtb3VudAkAlgoEBQlpc05ld1VzZXIFDHN0YWtlZEFtb3VudAUSc3Rha2luZ1N0YXJ0SGVpZ2h0BQ9zdGFrZWRBbW91bnRORVcBGmlzVXNkblN0YWtpbmdNaWdyYXRpb25Eb25lAAQSbGVnYWN5VG90YWxCYWxhbmNlCQEMZ2V0SW50T3JFbHNlAgkBFWtleUxlZ2FjeVRvdGFsQmFsYW5jZQEFEHN0YWtlZEFzc2V0SWRTdHIAAAQMdG90YWxCYWxhbmNlCQEMZ2V0SW50T3JFbHNlAgkBF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAACQAAAgUSbGVnYWN5VG90YWxCYWxhbmNlBQx0b3RhbEJhbGFuY2UBGmZhaWxJZlVzZG5NaWdyYXRpb25Ob3REb25lAAMJARppc1VzZG5TdGFraW5nTWlncmF0aW9uRG9uZQAGCQACAQJOVVNETiBzdGFraW5nIG1pZ3JhdGlvbiBpcyBJTiBQUk9HUkVTUy4gQWxsIG9wZXJhdGlvbnMgYXJlIHRlbXBvcmFyeSBzdXNwZW5kZWQuAQtjb21tb25TdGFrZQMLdXNlckFkZHJlc3MBaQtpc01pZ3JhdGlvbgQIbWlnQ2hlY2sDCQEBIQEFC2lzTWlncmF0aW9uCQEaZmFpbElmVXNkbk1pZ3JhdGlvbk5vdERvbmUABgMJAAACBQhtaWdDaGVjawUIbWlnQ2hlY2sDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhVJbnZhbGlkIHBheW1lbnRzIHNpemUEB3BheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQGYW1vdW50CAUHcGF5bWVudAZhbW91bnQEE2ludmFsaWRBc3NldE1lc3NhZ2UJAKwCAgkArAICAg9JbnZhbGlkIGFzc2V0LiAJANgEAQUNc3Rha2VkQXNzZXRJZAIMIGlzIGV4cGVjdGVkBAdhc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIIBQdwYXltZW50B2Fzc2V0SWQFE2ludmFsaWRBc3NldE1lc3NhZ2UDCQECIT0CBQdhc3NldElkBQ1zdGFrZWRBc3NldElkCQACAQUTaW52YWxpZEFzc2V0TWVzc2FnZQQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MECm1lcmdlZERhdGEJAQptZXJnZVN0YWtlAgUOdXNlckFkZHJlc3NTdHIFBmFtb3VudAQJaXNOZXdVc2VyCAUKbWVyZ2VkRGF0YQJfMQQMc3Rha2VkQW1vdW50CAUKbWVyZ2VkRGF0YQJfMgQSc3Rha2luZ1N0YXJ0SGVpZ2h0CAUKbWVyZ2VkRGF0YQJfMwQPc3Rha2VkQW1vdW50TkVXCAUKbWVyZ2VkRGF0YQJfNAMJAGYCBQ1taW5Mb2NrQW1vdW50BQ9zdGFrZWRBbW91bnRORVcJAAIBCQCsAgICE01pbiBsb2NrIGFtb3VudCBpcyAJAKQDAQUNbWluTG9ja0Ftb3VudAQNJHQwMTUyODMxNTM5OAkBC1N0YXRzUmVzdWx0BAUGYW1vdW50AAEDBQlpc05ld1VzZXIAAQAABQtpc01pZ3JhdGlvbgQMc3RhdHNFbnRyaWVzCAUNJHQwMTUyODMxNTM5OAJfMQQLdG90YWxTdGFrZWQIBQ0kdDAxNTI4MzE1Mzk4Al8yBA50b3RhbFN0YWtlZE5ldwgFDSR0MDE1MjgzMTUzOTgCXzMJAM4IAgkAzggCCQDOCAIJAMwIAgkBEkhpc3RvcnlSZWNvcmRFbnRyeQUCBXN0YWtlBQ51c2VyQWRkcmVzc1N0cggFAWkNdHJhbnNhY3Rpb25JZAUMc3Rha2VkQW1vdW50BQ9zdGFrZWRBbW91bnRORVcFA25pbAkBDVJld2FyZEVudHJpZXMDBQlpc05ld1VzZXIFDnVzZXJBZGRyZXNzU3RyBQxzdGFrZWRBbW91bnQJAQ9Mb2NrUGFyYW1zRW50cnkEBQ51c2VyQWRkcmVzc1N0cgUPc3Rha2VkQW1vdW50TkVXBRJzdGFraW5nU3RhcnRIZWlnaHQFC2lzTWlncmF0aW9uBQxzdGF0c0VudHJpZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDWNvbW1vblVuc3Rha2UDBmFtb3VudAFpC2lzTWlncmF0aW9uBA5taWdyYXRpb25DaGVjawkBGmZhaWxJZlVzZG5NaWdyYXRpb25Ob3REb25lAAMJAAACBQ5taWdyYXRpb25DaGVjawUObWlncmF0aW9uQ2hlY2sDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAiN1bnN0YWtlIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudAQLdXNlckFkZHJlc3MIBQFpBmNhbGxlcgQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MEDSR0MDE1OTYzMTYwNTEJARNnZXRVc2VyUGFyYW1zT3JGYWlsAQUOdXNlckFkZHJlc3NTdHIECWlzTmV3VXNlcggFDSR0MDE1OTYzMTYwNTECXzEEDHN0YWtlZEFtb3VudAgFDSR0MDE1OTYzMTYwNTECXzIEEnN0YWtpbmdTdGFydEhlaWdodAgFDSR0MDE1OTYzMTYwNTECXzMDCQBnAgAABQxzdGFrZWRBbW91bnQJAAIBAhJOb3RoaW5nIHRvIHVuc3Rha2UDCQBmAgUGYW1vdW50BQxzdGFrZWRBbW91bnQJAAIBCQCsAgIJAKwCAgkArAICAgpSZXF1ZXN0ZWQgCQCkAwEFBmFtb3VudAISLCBidXQgc3Rha2VkIG9ubHkgCQCkAwEFDHN0YWtlZEFtb3VudAQPc3Rha2VkQW1vdW50TkVXCQBlAgUMc3Rha2VkQW1vdW50BQZhbW91bnQEDSR0MDE2MjkzMTY0NjQJAQtTdGF0c1Jlc3VsdAQJAQEtAQUGYW1vdW50AwkAAAIFBmFtb3VudAUMc3Rha2VkQW1vdW50AP///////////wEAAAMJAAACBQZhbW91bnQFDHN0YWtlZEFtb3VudAD///////////8BAAAFC2lzTWlncmF0aW9uBAxzdGF0c0VudHJpZXMIBQ0kdDAxNjI5MzE2NDY0Al8xBAt0b3RhbFN0YWtlZAgFDSR0MDE2MjkzMTY0NjQCXzIEDnRvdGFsU3Rha2VkTmV3CAUNJHQwMTYyOTMxNjQ2NAJfMwkAzggCCQDOCAIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUGYW1vdW50BQ1zdGFrZWRBc3NldElkCQDMCAIJARJIaXN0b3J5UmVjb3JkRW50cnkFAgd1bnN0YWtlBQ51c2VyQWRkcmVzc1N0cggFAWkNdHJhbnNhY3Rpb25JZAUMc3Rha2VkQW1vdW50BQ9zdGFrZWRBbW91bnRORVcFA25pbAkBDVJld2FyZEVudHJpZXMDBwUOdXNlckFkZHJlc3NTdHIFDHN0YWtlZEFtb3VudAkBD0xvY2tQYXJhbXNFbnRyeQQFDnVzZXJBZGRyZXNzU3RyBQ9zdGFrZWRBbW91bnRORVcFEnN0YWtpbmdTdGFydEhlaWdodAULaXNNaWdyYXRpb24FDHN0YXRzRW50cmllcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgELY29tbW9uQ2xhaW0CC3VzZXJBZGRyZXNzAWkEDm1pZ3JhdGlvbkNoZWNrCQEaZmFpbElmVXNkbk1pZ3JhdGlvbk5vdERvbmUAAwkAAAIFDm1pZ3JhdGlvbkNoZWNrBQ5taWdyYXRpb25DaGVjawQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MDCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIZcGF5bWVudHMgYXJlIG5vdCBhY2NlcHRlZAQNJHQwMTcwMjgxNzEzNgkBC3ZhbHVlT3JFbHNlAgkBE2dldFVzZXJQYXJhbXNPclVuaXQBBQ51c2VyQWRkcmVzc1N0cgkAlQoDBgAAAAAECWlzTmV3VXNlcggFDSR0MDE3MDI4MTcxMzYCXzEEDHN0YWtlZEFtb3VudAgFDSR0MDE3MDI4MTcxMzYCXzIEDHN0YWtpbmdTdGFydAgFDSR0MDE3MDI4MTcxMzYCXzMEDXN0YWtlZEFtb3VudFgJALYCAQUMc3Rha2VkQW1vdW50BBt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJARtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0BBQ51c2VyQWRkcmVzc1N0cgQOZGVwb3NpdE51bVVzZXIJAQxnZXRJbnRPckVsc2UCBRt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA////////////AQQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCCQERa2V5RGVwb3NpdE51bUxhc3QAAP///////////wEKAR9mb3JFYWNoQXNzZXRDYWxjVW5jbGFpbWVkUmV3YXJkAgVhY2N1bQVhc3NldAQNJHQwMTc1MDcxNzY0NQkBCmNhbGNSZXdhcmQFBQ51c2VyQWRkcmVzc1N0cgUFYXNzZXQFDXN0YWtlZEFtb3VudFgFDmRlcG9zaXROdW1Vc2VyBQ5kZXBvc2l0TnVtTGFzdAQLcmV3YXJkVG90YWwIBQ0kdDAxNzUwNzE3NjQ1Al8xBAZjYWNoZWQIBQ0kdDAxNzUwNzE3NjQ1Al8yBAdkeW5hbWljCAUNJHQwMTc1MDcxNzY0NQJfMwQTcmV3YXJkQ2FjaGVkUGFydEtFWQgFDSR0MDE3NTA3MTc2NDUCXzQECmNsYWltZWRLRVkJAQprZXlDbGFpbWVkAgUOdXNlckFkZHJlc3NTdHIFBWFzc2V0BA0kdDAxNzcwNTE3NzQyBQVhY2N1bQQEZGF0YQgFDSR0MDE3NzA1MTc3NDICXzEEEWNsYWltZWRBbXRCeUFzc2V0CAUNJHQwMTc3MDUxNzc0MgJfMgQHbmV3UGFydAkAuQkCCQDMCAIFBWFzc2V0CQDMCAIJAKQDAQULcmV3YXJkVG90YWwFA25pbAIBOgQUY2xhaW1lZEFtdEJ5QXNzZXROZXcJALkJAgkAzAgCBRFjbGFpbWVkQW10QnlBc3NldAkAzAgCBQduZXdQYXJ0BQNuaWwCAV8DCQBnAgAABQtyZXdhcmRUb3RhbAkAlAoCBQRkYXRhBRRjbGFpbWVkQW10QnlBc3NldE5ldwkAlAoCCQDNCAIJAM0IAgkAzQgCBQRkYXRhCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwULcmV3YXJkVG90YWwJAQt0b0Fzc2V0VmVjdAEFBWFzc2V0CQEMSW50ZWdlckVudHJ5AgUKY2xhaW1lZEtFWQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUKY2xhaW1lZEtFWQAABQtyZXdhcmRUb3RhbAkBDEludGVnZXJFbnRyeQIFE3Jld2FyZENhY2hlZFBhcnRLRVkAAAUUY2xhaW1lZEFtdEJ5QXNzZXROZXcEDSR0MDE4MjAyMTgzMTUKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBH2ZvckVhY2hBc3NldENhbGNVbmNsYWltZWRSZXdhcmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDIJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACBAl0cmFuc2ZlcnMIBQ0kdDAxODIwMjE4MzE1Al8xBBdjbGFpbWVkQW10QnlBc3NldFJlc3VsdAgFDSR0MDE4MjAyMTgzMTUCXzIDCQBnAgAACQCQAwEFCXRyYW5zZmVycwkAlAoCBQNuaWwAAAkAlAoCCQDNCAIJAM0IAgUJdHJhbnNmZXJzCQEMSW50ZWdlckVudHJ5AgUbdXNlclJld2FyZEZyb21EZXBvc2l0TnVtS0VZBQ5kZXBvc2l0TnVtTGFzdAkBEUNsYWltSGlzdG9yeUVudHJ5AwUOdXNlckFkZHJlc3NTdHIIBQFpDXRyYW5zYWN0aW9uSWQJALACAgUXY2xhaW1lZEFtdEJ5QXNzZXRSZXN1bHQAAQkAkAMBBQl0cmFuc2ZlcnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ACFVTRE5UWVBFAgRVU0ROAAhOU0JUVFlQRQIETlNCVAASTmV1dHJpbm9Bc3NldElkS2V5AhFuZXV0cmlub19hc3NldF9pZAATTmV1dHJpbm9Db250cmFjdEtleQIRbmV1dHJpbm9fY29udHJhY3QADk5zYnRBc3NldElkS2V5Ag1ib25kX2Fzc2V0X2lkAApCYWxhbmNlS2V5AgtycGRfYmFsYW5jZQAPbmV1dHJpbm9Bc3NldElkCQDZBAEJAQ9nZXRTdHJpbmdPckZhaWwCBRBuZXV0cmlub0NvbnRyYWN0BRJOZXV0cmlub0Fzc2V0SWRLZXkADm5zYnRBc3NldElkU3RyCQEPZ2V0U3RyaW5nT3JGYWlsAgUQbmV1dHJpbm9Db250cmFjdAUOTnNidEFzc2V0SWRLZXkAC25zYnRBc3NldElkCQDZBAEFDm5zYnRBc3NldElkU3RyARFnZXRVc2VyQmFsYW5jZUtleQIFb3duZXIHYXNzZXRJZAkAuQkCCQDMCAIFCkJhbGFuY2VLZXkJAMwIAgUHYXNzZXRJZAkAzAgCBQVvd25lcgUDbmlsAgFfARVnZXRDb250cmFjdEJhbGFuY2VLZXkBB2Fzc2V0SWQJAKwCAgkArAICBQpCYWxhbmNlS2V5AgFfBQdhc3NldElkARJnZXRDb250cmFjdEJhbGFuY2UBB2Fzc2V0SWQJAQxnZXRJbnRPckVsc2UCCQEVZ2V0Q29udHJhY3RCYWxhbmNlS2V5AQUHYXNzZXRJZAAAAQ5nZXRVc2VyQmFsYW5jZQIFb3duZXIHYXNzZXRJZAkBDGdldEludE9yRWxzZQIJARFnZXRVc2VyQmFsYW5jZUtleQIFBW93bmVyBQdhc3NldElkAAABGmdldFZhbGlkU3Rha2luZ0Fzc2V0T3JGYWlsAgtzdGFraW5nVHlwZQdhc3NldElkAwMJAAACBQtzdGFraW5nVHlwZQUIVVNETlRZUEUJAQIhPQIFB2Fzc2V0SWQFD25ldXRyaW5vQXNzZXRJZAcJAAIBAhFjYW4gdXNlIFVTRE4gb25seQMDCQAAAgULc3Rha2luZ1R5cGUFCE5TQlRUWVBFCQECIT0CBQdhc3NldElkBQtuc2J0QXNzZXRJZAcJAAIBAhFjYW4gdXNlIE5TQlQgb25seQMDCQECIT0CBQtzdGFraW5nVHlwZQUIVVNETlRZUEUJAQIhPQIFC3N0YWtpbmdUeXBlBQhOU0JUVFlQRQcJAAIBCQCsAgICGXVuc3VwcG9ydGVkIHN0YWtpbmcgdHlwZSAFC3N0YWtpbmdUeXBlBQdhc3NldElkAQ5pbnRlcm5hbFVubG9jawQLc3Rha2luZ1R5cGUBaQx1bmxvY2tBbW91bnQMYXNzZXRJZFBhcmFtBAdhY2NvdW50CQClCAEIBQFpBmNhbGxlcgQHYXNzZXRJZAkBGmdldFZhbGlkU3Rha2luZ0Fzc2V0T3JGYWlsAgULc3Rha2luZ1R5cGUJANkEAQUMYXNzZXRJZFBhcmFtBA1hc3NldElkU3RyaW5nCQDYBAEFB2Fzc2V0SWQEB2JhbGFuY2UJAGUCCQEOZ2V0VXNlckJhbGFuY2UCBQdhY2NvdW50BQ1hc3NldElkU3RyaW5nBQx1bmxvY2tBbW91bnQDCQBmAgAABQdiYWxhbmNlCQACAQIOaW52YWxpZCBhbW91bnQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFWdldENvbnRyYWN0QmFsYW5jZUtleQEFDWFzc2V0SWRTdHJpbmcJAGUCCQESZ2V0Q29udHJhY3RCYWxhbmNlAQUNYXNzZXRJZFN0cmluZwUMdW5sb2NrQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQERZ2V0VXNlckJhbGFuY2VLZXkCBQdhY2NvdW50BQ1hc3NldElkU3RyaW5nBQdiYWxhbmNlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB2FjY291bnQFDHVubG9ja0Ftb3VudAUHYXNzZXRJZAUDbmlsBQR1bml0DwFpAQtjb25zdHJ1Y3RvcgMNbWluTG9ja0Ftb3VudBVzdXBwb3J0ZWRSZXdhcmRBc3NldHMOcFN0YWtlZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEGtleU1pbkxvY2tBbW91bnQABQ1taW5Mb2NrQW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARhrZXlTdXBwb3J0ZWRSZXdhcmRBc3NldHMABRVzdXBwb3J0ZWRSZXdhcmRBc3NldHMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVN0YWtlZEFzc2V0SWQABQ5wU3Rha2VkQXNzZXRJZAUDbmlsAWkBEm1pZ3JhdGVVc2RuU3Rha2luZwEOdXNlckFkZHJlc3NTdHIEB21uZ1B1YlMJAQt2YWx1ZU9yRWxzZQIJAKIIAQIcJXMlc19fY2ZnX19sZWFzaW5nTWFuYWdlclB1YgIsN0FVTVg1NHVrWU1ZdlBtbWE3eW9GZjVOalpoczRCdTVuejNFejlFVjhzdXIEBm1uZ1B1YgkA2QQBBQdtbmdQdWJTAwkBAiE9AggFAWkPY2FsbGVyUHVibGljS2V5BQZtbmdQdWIJAAIBAiFtaWdyYXRlVXNkblN0YWtpbmcgbm90IGF1dGhvcml6ZWQDCQEaaXNVc2RuU3Rha2luZ01pZ3JhdGlvbkRvbmUACQACAQIXbWlncmF0aW9uIGhhcyBiZWVuIGRvbmUDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhhwYXltZW50cyBhcmUgbm90IGFsbG93ZWQDCQECIT0CCAUBaQpmZWVBc3NldElkBQR1bml0CQACAQIcZmVlIGluIFdBVkVTIGlzIGFsbG93ZWQgb25seQMJAQIhPQIIBQFpA2ZlZQCgwh4JAAIBAh8wLjAwNSBXQVZFUyBmZWUgaXMgYWxsb3dlZCBvbmx5BBFsZWdhY3lVc2VyQmFsYW5jZQkBDGdldEludE9yRWxzZQIJARRrZXlMZWdhY3lVc2VyQmFsYW5jZQIFDnVzZXJBZGRyZXNzU3RyBRBzdGFrZWRBc3NldElkU3RyAAADCQAAAgURbGVnYWN5VXNlckJhbGFuY2UAAAkAAgEJAKwCAgIYbm8gbmVlZCB0byBtaWdyYXRlIHVzZXIgBQ51c2VyQWRkcmVzc1N0cgMJAQxpc0FjdGl2ZVVzZXIBBQ51c2VyQWRkcmVzc1N0cgkAAgEJAKwCAgIWYWxyZWFkeSBtaWdyYXRlZCB1c2VyIAUOdXNlckFkZHJlc3NTdHIEC3VzZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ51c2VyQWRkcmVzc1N0cgQJZW1wdHlWZWN0CQDZBAECAAkBC2NvbW1vblN0YWtlAwULdXNlckFkZHJlc3MJAQpJbnZvY2F0aW9uCAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUNc3Rha2VkQXNzZXRJZAURbGVnYWN5VXNlckJhbGFuY2UFA25pbAULdXNlckFkZHJlc3MFCWVtcHR5VmVjdAgFAWkNdHJhbnNhY3Rpb25JZAAABQR1bml0BQt1c2VyQWRkcmVzcwUJZW1wdHlWZWN0BgFpAQVzdGFrZQAJAQtjb21tb25TdGFrZQMIBQFpBmNhbGxlcgUBaQcBaQETc3Rha2VCeU9yaWdpbkNhbGxlcgAJAQtjb21tb25TdGFrZQMIBQFpDG9yaWdpbkNhbGxlcgUBaQcBaQEHdW5zdGFrZQEGYW1vdW50CQENY29tbW9uVW5zdGFrZQMFBmFtb3VudAUBaQcBaQEHZGVwb3NpdAAEDm1pZ3JhdGlvbkNoZWNrCQEaZmFpbElmVXNkbk1pZ3JhdGlvbk5vdERvbmUAAwkAAAIFDm1pZ3JhdGlvbkNoZWNrBQ5taWdyYXRpb25DaGVjawMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECH2V4YWN0IDEgcGF5bWVudCBpcyBhbGxvd2VkIG9ubHkEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAZhbW91bnQIBQNwbXQGYW1vdW50BApwbXRBc3NldElkCQELdmFsdWVPckVsc2UCCAUDcG10B2Fzc2V0SWQFB1dBVkVTSUQEDXBtdEFzc2V0SWRTdHIJANgEAQUKcG10QXNzZXRJZAQIcG10TXVsdFgDCQAAAgUKcG10QXNzZXRJZAUHV0FWRVNJRAUGTVVMVFg4BQZNVUxUWDYEB2Ftb3VudFgJALYCAQUGYW1vdW50BAt0b3RhbFN0YWtlZAkBDGdldEludE9yRWxzZQIJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAAAAQMdG90YWxTdGFrZWRYCQC2AgEFC3RvdGFsU3Rha2VkAwkAZgIAAAULdG90YWxTdGFrZWQJAAIBAhtUT0RPOiBjYXNlIGlzIG5vdCBzdXBwb3J0ZWQDCQAAAgULdG90YWxTdGFrZWQAAAkBIkluY3JlbWVudE5vdERpc3RyaWJ1dGVkUmV3YXJkRW50cnkCBQ1wbXRBc3NldElkU3RyBQZhbW91bnQEEHJld2FyZFBlck5zYnRYMTgJALwCAwUHYW1vdW50WAUHTVVMVFgxOAUMdG90YWxTdGFrZWRYBBFkZXBvc2l0TnVtTGFzdEtFWQkBEWtleURlcG9zaXROdW1MYXN0AAQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCBRFkZXBvc2l0TnVtTGFzdEtFWQD///////////8BBA1kZXBvc2l0TnVtTmV3CQBkAgUOZGVwb3NpdE51bUxhc3QAAQMJAQEhAQkBCGNvbnRhaW5zAgUSc3VwcG9ydGVkQXNzZXRzU3RyBQ1wbXRBc3NldElkU3RyCQACAQkArAICCQCsAgIFEnN1cHBvcnRlZEFzc2V0c1N0cgIRIGRvZXNuJ3QgY29udGFpbiAFDXBtdEFzc2V0SWRTdHIKARdyZWZyZXNoUmV3YXJkUGVyTnNidFNVTQIFYWNjdW0JbmV4dEFzc2V0BBZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZCQEVa2V5UmV3YXJkUGVyTnNidFN1bUF0AgUNZGVwb3NpdE51bU5ldwUJbmV4dEFzc2V0BApzdW1MYXN0U3RyCQEMZ2V0U3RyT3JFbHNlAgkBFWtleVJld2FyZFBlck5zYnRTdW1BdAIFDmRlcG9zaXROdW1MYXN0BQluZXh0QXNzZXQCATAJAM0IAgUFYWNjdW0DCQAAAgUJbmV4dEFzc2V0BQ1wbXRBc3NldElkU3RyCQELU3RyaW5nRW50cnkCBRZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZCQCmAwEJALcCAgkApwMBBQpzdW1MYXN0U3RyBRByZXdhcmRQZXJOc2J0WDE4CQELU3RyaW5nRW50cnkCBRZyZXdhcmRQZXJOc2J0U3VtTmV3S0VZBQpzdW1MYXN0U3RyCQDOCAIJAM0IAgoAAiRsBRNzdXBwb3J0ZWRBc3NldHNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARdyZWZyZXNoUmV3YXJkUGVyTnNidFNVTQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIJAQxJbnRlZ2VyRW50cnkCBRFkZXBvc2l0TnVtTGFzdEtFWQUNZGVwb3NpdE51bU5ldwkBFURlcG9zaXRzVG90YWxzRW50cmllcwIFBmFtb3VudAUNcG10QXNzZXRJZFN0cgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQxjbGFpbVJld2FyZHMACQELY29tbW9uQ2xhaW0CCAUBaQZjYWxsZXIFAWkBaQEaY2xhaW1SZXdhcmRzQnlPcmlnaW5DYWxsZXIACQELY29tbW9uQ2xhaW0CCAUBaQxvcmlnaW5DYWxsZXIFAWkBaQEYdW5jbGFpbWVkUmV3YXJkc1JFQURPTkxZAQ51c2VyQWRkcmVzc1N0cgoBFmZvckVhY2hBc3NldFplcm9SZXdhcmQCBWFjY3VtBWFzc2V0CQCsAgIJAKwCAgUFYWNjdW0JALkJAgkAzAgCBQVhc3NldAkAzAgCAgEwCQDMCAICATAFA25pbAIBOgIBXwQSdW5jbGFpbWVkUmV3YXJkU3RyAwkAAAIFDnVzZXJBZGRyZXNzU3RyAgAKAAIkbAUTc3VwcG9ydGVkQXNzZXRzTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWZm9yRWFjaEFzc2V0WmVyb1Jld2FyZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIEC3VzZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ51c2VyQWRkcmVzc1N0cgQNJHQwMjQ2NDYyNDc2MAkBC3ZhbHVlT3JFbHNlAgkBE2dldFVzZXJQYXJhbXNPclVuaXQBBQ51c2VyQWRkcmVzc1N0cgkAlQoDBgAAAAAECWlzTmV3VXNlcggFDSR0MDI0NjQ2MjQ3NjACXzEEDHN0YWtlZEFtb3VudAgFDSR0MDI0NjQ2MjQ3NjACXzIEEnN0YWtpbmdTdGFydEhlaWdodAgFDSR0MDI0NjQ2MjQ3NjACXzMEDXN0YWtlZEFtb3VudFgJALYCAQUMc3Rha2VkQW1vdW50BBt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkJARtrZXlVc2VyUmV3YXJkRnJvbURlcG9zaXROdW0BBQ51c2VyQWRkcmVzc1N0cgQOZGVwb3NpdE51bVVzZXIJAQxnZXRJbnRPckVsc2UCBRt1c2VyUmV3YXJkRnJvbURlcG9zaXROdW1LRVkA////////////AQQOZGVwb3NpdE51bUxhc3QJAQxnZXRJbnRPckVsc2UCCQERa2V5RGVwb3NpdE51bUxhc3QAAP///////////wEKAR9mb3JFYWNoQXNzZXRDYWxjVW5jbGFpbWVkUmV3YXJkAgVhY2N1bQVhc3NldAQNJHQwMjUxMDYyNTI0NAkBCmNhbGNSZXdhcmQFBQ51c2VyQWRkcmVzc1N0cgUFYXNzZXQFDXN0YWtlZEFtb3VudFgFDmRlcG9zaXROdW1Vc2VyBQ5kZXBvc2l0TnVtTGFzdAQLcmV3YXJkVG90YWwIBQ0kdDAyNTEwNjI1MjQ0Al8xBAZjYWNoZWQIBQ0kdDAyNTEwNjI1MjQ0Al8yBAdkeW5hbWljCAUNJHQwMjUxMDYyNTI0NAJfMwQTcmV3YXJkQ2FjaGVkUGFydEtFWQgFDSR0MDI1MTA2MjUyNDQCXzQEB2NsYWltZWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBCmtleUNsYWltZWQCBQ51c2VyQWRkcmVzc1N0cgUFYXNzZXQAAAkArAICCQCsAgIFBWFjY3VtCQC5CQIJAMwIAgUFYXNzZXQJAMwIAgkApAMBBQtyZXdhcmRUb3RhbAkAzAgCCQCkAwEFB2NsYWltZWQFA25pbAIBOgIBXwoAAiRsBRNzdXBwb3J0ZWRBc3NldHNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAIACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAR9mb3JFYWNoQXNzZXRDYWxjVW5jbGFpbWVkUmV3YXJkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgkAlAoCBQNuaWwJALMCAgUSdW5jbGFpbWVkUmV3YXJkU3RyAAEBaQEWdXNkblN0YWtpbmdTWVNSRUFET05MWQIVdXNlckFkZHJlc3NTdHJPckVtcHR5CHVzZG5EaWZmBBJ1c2RuVG90YWxBbXRTdGFrZWQJAQxnZXRJbnRPckVsc2UCCQEXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQAAAADCQAAAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5AgAJAJQKAgUDbmlsCQDMCAIAAAkAzAgCBRJ1c2RuVG90YWxBbXRTdGFrZWQJAMwIAgAABQNuaWwEC3VzZXJBZGRyZXNzCQEPdG9BZGRyZXNzT3JGYWlsAQUVdXNlckFkZHJlc3NTdHJPckVtcHR5BAptZXJnZWREYXRhCQEKbWVyZ2VTdGFrZQIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQUIdXNkbkRpZmYECWlzTmV3VXNlcggFCm1lcmdlZERhdGECXzEEEHVzZG5TdGFrZWRCeVVzZXIIBQptZXJnZWREYXRhAl8yBBJzdGFraW5nU3RhcnRIZWlnaHQIBQptZXJnZWREYXRhAl8zBA9zdGFrZWRBbW91bnRORVcIBQptZXJnZWREYXRhAl80CQCUCgIFA25pbAkAzAgCBRB1c2RuU3Rha2VkQnlVc2VyCQDMCAIFEnVzZG5Ub3RhbEFtdFN0YWtlZAUDbmlsAWkBEWNvbmZpZ1NZU1JFQURPTkxZAAQKbWluTG9ja0FtdAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBEGtleU1pbkxvY2tBbW91bnQACQCUCgIFA25pbAkAzAgCBQptaW5Mb2NrQW10BQNuaWwBaQEObG9ja05ldXRyaW5vU1ACCHJlY2VpdmVyBXNoYXJlCQELY29tbW9uU3Rha2UDCAUBaQZjYWxsZXIFAWkHAWkBDGxvY2tOZXV0cmlubwAJAQtjb21tb25TdGFrZQMIBQFpBmNhbGxlcgUBaQcBaQEOdW5sb2NrTmV1dHJpbm8CDHVubG9ja0Ftb3VudA1hc3NldElkU3RyaW5nCQENY29tbW9uVW5zdGFrZQMFDHVubG9ja0Ftb3VudAUBaQcBaQEKdW5sb2NrTnNidAIMdW5sb2NrQW1vdW50DWFzc2V0SWRTdHJpbmcJAQ5pbnRlcm5hbFVubG9jawQFCE5TQlRUWVBFBQFpBQx1bmxvY2tBbW91bnQFDWFzc2V0SWRTdHJpbmcBAnR4AQZ2ZXJpZnkABBNwdWJLZXlBZG1pbnNMaXN0U3RyCQC5CQIJAMwIAgIsR0ZtS1oybmFaRlJvQ3ZOYndLQVFWR21MYjF1QmVXR0RnRmFiZEdCdVppdXkJAMwIAgIsR21KWFJ5aFJBNzlnOHlVR2dLQkFWZG5GZlFGRE1qUUc5OGIxTW1MRGg1a2sJAMwIAgIsQ0ZoYlY2aDQxaFZqYkdIdWRHdFMzZllVdjdRQUtSeEZRektOdHg0QjVQcVAJAMwIAgIrS243TnB6YUcxMmRMWmdjSGYyaXBVZnRVNmhiSnlnbXJoRnFRWUU0QjdaSwUDbmlsBQNTRVAEEHB1YktleUFkbWluc0xpc3QJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9jb250cm9sQ29udHJhY3QCDCVzX19tdWx0aXNpZwUTcHViS2V5QWRtaW5zTGlzdFN0cgUDU0VQBAVjb3VudAkAZAIJAGQCCQBkAgMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAJANkEAQkAkQMCBRBwdWJLZXlBZG1pbnNMaXN0AAAAAQAAAwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAQkA2QQBCQCRAwIFEHB1YktleUFkbWluc0xpc3QAAQABAAADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwACCQDZBAEJAJEDAgUQcHViS2V5QWRtaW5zTGlzdAACAAEAAAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAMJANkEAQkAkQMCBRBwdWJLZXlBZG1pbnNMaXN0AAMAAgAACQBnAgUFY291bnQAA0c+swo=", "height": 2351224, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let revisionNum = ""
5+
6+let SEP = "__"
7+
8+let MULT6 = 1000000
9+
10+let MULT8 = 100000000
11+
12+let MULTX6 = toBigInt(MULT6)
13+
14+let MULTX8 = toBigInt(MULT8)
15+
16+let MULTX18 = toBigInt(1000000000000000000)
17+
18+let WAVESIDSTR = "WAVES"
19+
20+let WAVESID = fromBase58String(WAVESIDSTR)
21+
22+let DAYMILLIS = 86400000
23+
24+let IdxControlCfgNeutrinoDapp = 1
25+
26+let IdxControlCfgAuctionDapp = 2
27+
28+let IdxControlCfgRpdDapp = 3
29+
30+let IdxControlCfgMathDapp = 4
31+
32+let IdxControlCfgLiquidationDapp = 5
33+
34+let IdxControlCfgRestDapp = 6
35+
36+let IdxControlCfgNodeRegistryDapp = 7
37+
38+let IdxControlCfgNsbtStakingDapp = 8
39+
40+let IdxControlCfgMediatorDapp = 9
41+
42+let IdxControlCfgSurfStakingDapp = 10
43+
44+let IdxControlCfgGnsbtControllerDapp = 11
45+
46+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
47+
48+
49+func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
50+
51+
52+func getStrOrElse (key,defaultVal) = valueOrElse(getString(this, key), defaultVal)
53+
54+
55+func keyMinLockAmount () = "%s__minLockAmount"
56+
57+
58+func keyStakedAssetId () = "%s__stakedAssetId"
59+
60+
61+func keyControlAddress () = "%s%s__config__controlAddress"
62+
63+
64+func keyControlCfg () = "%s__controlConfig"
65+
66+
67+func keySupportedRewardAssets () = "supportedRewardAssets"
68+
69+
70+func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
71+
72+
73+func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
74+
75+
76+let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
77+
78+let controlCfg = readControlCfgOrFail(controlContract)
79+
80+let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
81+
82+let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
83+
84+let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
85+
86+let stakedAssetIdStr = getStringOrFail(this, keyStakedAssetId())
87+
88+let stakedAssetId = fromBase58String(stakedAssetIdStr)
89+
90+let minLockAmount = getIntOrFail(keyMinLockAmount())
91+
92+let supportedAssetsStr = getStrOrElse(keySupportedRewardAssets(), "")
93+
94+let supportedAssetsList = split(supportedAssetsStr, "_")
95+
96+func keyLockParamUserAmount (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "amount"], SEP)
97+
98+
99+func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
100+
101+
102+func keyHistoryRecord (type,userAddress,txId) = makeString(["%s%s%s%s", "history", type, userAddress, toBase58String(txId)], SEP)
103+
104+
105+func keyLockParamTotalAmount () = makeString(["%s%s", "stats", "activeTotalLocked"], SEP)
106+
107+
108+func keyStatsLocksCount () = makeString(["%s%s", "stats", "locksCount"], SEP)
109+
110+
111+func keyStatsUsersCount () = makeString(["%s%s", "stats", "activeUsersCount"], SEP)
112+
113+
114+func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], SEP)
115+
116+
117+func keyStatsDepositAmtTotals () = makeString(["%s%s%d", "stats", "depositAmtTotals"], SEP)
118+
119+
120+func keyNextPeriod () = "%s__nextPeriod"
121+
122+
123+func keyDepositNumLast () = makeString(["%s%s%s", "dep", "lastNum"], SEP)
124+
125+
126+func keyUserRewardFromDepositNum (userAddress) = makeString(["%s%s%s", "userRwdFromDepNum", userAddress], SEP)
127+
128+
129+func keyRewardPerNsbtSumAt (depositNum,tkn) = makeString(["%s%d", "rwdPerNsbtSumByDepNum", toString(depositNum), tkn], SEP)
130+
131+
132+func keyReward (userAddress,tkn) = makeString(["%s%s%s", "rwd", userAddress, tkn], SEP)
133+
134+
135+func keyClaimed (userAddress,tkn) = makeString(["%s%s%s", "clm", userAddress, tkn], SEP)
136+
137+
138+func keyNotDistributedReward (tkn) = makeString(["%s%s", "notDistributed", tkn], SEP)
139+
140+
141+func keyLegacyUserBalance (userAddr,tkn) = makeString(["rpd_balance", tkn, userAddr], "_")
142+
143+
144+func keyLegacyTotalBalance (tkn) = makeString(["rpd_balance", tkn], "_")
145+
146+
147+func toX18 (origVal,origMult) = fraction(toBigInt(origVal), MULTX18, origMult)
148+
149+
150+func getIntOrZero (key) = valueOrElse(getInteger(this, key), 0)
151+
152+
153+func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
154+
155+
156+func toAddressOrFail (addressStr) = valueOrErrorMessage(addressFromString(addressStr), ("couldn't parse passed addressStr=" + addressStr))
157+
158+
159+func toAssetVect (assetStr) = if ((assetStr == WAVESIDSTR))
160+ then unit
161+ else fromBase58String(assetStr)
162+
163+
164+func asInt (val) = match val {
165+ case valInt: Int =>
166+ valInt
167+ case _ =>
168+ throw("fail to cast into Int")
169+}
170+
171+
172+func asSwapParamsSTRUCT (v) = match v {
173+ case struct: (Int, Int, Int, Int, Int, Int, Int) =>
174+ struct
175+ case _ =>
176+ throw("fail to cast into Int")
177+}
178+
179+
180+func formatHistoryRecord (userAddress,oldAmount,newAmount) = makeString(["%s%d%d%d%d", userAddress, toString(lastBlock.height), toString(lastBlock.timestamp), toString(oldAmount), toString(newAmount)], SEP)
181+
182+
183+func formatClaimHistoryRecord (userAddress,claimedRewards) = makeString(["%s%d%d%s", userAddress, toString(lastBlock.height), toString(lastBlock.timestamp), claimedRewards], SEP)
184+
185+
186+func HistoryRecordEntry (type,userAddress,txId,oldAmount,newAmount) = StringEntry(keyHistoryRecord(type, userAddress, txId), formatHistoryRecord(userAddress, oldAmount, newAmount))
187+
188+
189+func ClaimHistoryEntry (userAddress,txId,claimedRewards) = StringEntry(keyHistoryRecord("claim", userAddress, txId), formatClaimHistoryRecord(userAddress, claimedRewards))
190+
191+
192+func StatsResult (totalLockedInc,lockCountInc,usersCountInc,isMigration) = {
193+ let locksCount = getIntOrZero(keyStatsLocksCount())
194+ let usersCount = getIntOrZero(keyStatsUsersCount())
195+ let totalAmount = getIntOrZero(keyLockParamTotalAmount())
196+ let totalAmountNew = (totalAmount + totalLockedInc)
197+ $Tuple3(([IntegerEntry(keyStatsLocksCount(), (locksCount + lockCountInc)), IntegerEntry(keyStatsUsersCount(), (usersCount + usersCountInc)), IntegerEntry(keyLockParamTotalAmount(), totalAmountNew)] ++ (if (isMigration)
198+ then nil
199+ else [IntegerEntry(keyLegacyTotalBalance(stakedAssetIdStr), totalAmountNew)])), totalAmount, totalAmountNew)
200+ }
201+
202+
203+func LockParamsEntry (userAddress,amount,stakingStartHeight,isMigration) = ([IntegerEntry(keyLockParamUserAmount(userAddress), amount), IntegerEntry(keyLockParamStartBlock(userAddress), stakingStartHeight)] ++ (if (isMigration)
204+ then nil
205+ else [IntegerEntry(keyLegacyUserBalance(userAddress, stakedAssetIdStr), amount)]))
206+
207+
208+func getParamsOrFail () = $Tuple2(fromBase58String(getStringOrFail(this, keyStakedAssetId())), getIntOrFail(keyMinLockAmount()))
209+
210+
211+func isActiveUser (userAddress) = (getIntOrElse(keyLockParamUserAmount(userAddress), 0) > 0)
212+
213+
214+func getUserParamsOrUnit (userAddress) = if (isActiveUser(userAddress))
215+ then $Tuple3(false, getIntOrFail(keyLockParamUserAmount(userAddress)), getIntOrFail(keyLockParamStartBlock(userAddress)))
216+ else unit
217+
218+
219+func getUserParamsOrFail (userAddress) = valueOrErrorMessage(getUserParamsOrUnit(userAddress), (("User " + userAddress) + " is not defined"))
220+
221+
222+func calcReward (userAddress,assetId,stakedAmountX,depositNumUser,depositNumLast) = {
223+ let rewardPerNsbtSumLastKEY = keyRewardPerNsbtSumAt(depositNumLast, assetId)
224+ let sumLastX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, assetId), "0"))
225+ let sumUserX18 = parseBigIntValue(getStrOrElse(keyRewardPerNsbtSumAt(depositNumUser, assetId), "0"))
226+ let rewardDynamicPart = toInt(fraction((sumLastX18 - sumUserX18), stakedAmountX, MULTX18))
227+ let rewardCachedPartKEY = keyReward(userAddress, assetId)
228+ let rewardCachedPart = getIntOrElse(rewardCachedPartKEY, 0)
229+ $Tuple4((rewardCachedPart + rewardDynamicPart), rewardCachedPart, rewardDynamicPart, rewardCachedPartKEY)
230+ }
231+
232+
233+func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
234+
235+
236+func findElementPosition (src,element,sep) = {
237+ let elementStart = valueOrErrorMessage(indexOf(src, element), ((("there is no substring " + element) + " in ") + src))
238+ if ((elementStart == 0))
239+ then 0
240+ else {
241+ let left = take(src, elementStart)
242+ (size(split(left, sep)) - 1)
243+ }
244+ }
245+
246+
247+let DepositTotalsPREFIX = "%d%d"
248+
249+func updateDepositTotals (currVal,idxToUpdate,deltaAmt) = {
250+ let currArr = split(currVal, SEP)
251+ func updDepTotByIdx (idx) = if ((idx != idxToUpdate))
252+ then currArr[idx]
253+ else toString((parseIntValue(currArr[idx]) + deltaAmt))
254+
255+ makeString([DepositTotalsPREFIX, updDepTotByIdx(1), updDepTotByIdx(2)], SEP)
256+ }
257+
258+
259+func DepositsTotalsEntries (depositAmount,assetIdStr) = {
260+ let startOfDay = toStartOfDay(lastBlock.timestamp)
261+ let byDayKEY = keyStatsDepositAmtByDay(startOfDay)
262+ let totalsKEY = keyStatsDepositAmtTotals()
263+ let position = findElementPosition(supportedAssetsStr, assetIdStr, "_")
264+ let defaultDATA = (DepositTotalsPREFIX + "__0__0")
265+ let currTotalsDATA = valueOrElse(getString(this, totalsKEY), defaultDATA)
266+ let newTotalsDATA = updateDepositTotals(currTotalsDATA, (position + 1), depositAmount)
267+[StringEntry(totalsKEY, newTotalsDATA), StringEntry(byDayKEY, newTotalsDATA)]
268+ }
269+
270+
271+func RewardEntries (isNewUser,userAddress,stakedAmount) = {
272+ let stakedAmountX = toBigInt(stakedAmount)
273+ let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddress)
274+ let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
275+ let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
276+ func forEachAssetCacheUserReward (accum,asset) = {
277+ let $t01072510860 = calcReward(userAddress, asset, stakedAmountX, depositNumUser, depositNumLast)
278+ let rewardTotal = $t01072510860._1
279+ let cached = $t01072510860._2
280+ let dynamic = $t01072510860._3
281+ let rewardCachedPartKEY = $t01072510860._4
282+ (accum :+ IntegerEntry(rewardCachedPartKEY, rewardTotal))
283+ }
284+
285+ if (if ((depositNumLast == -1))
286+ then (depositNumUser == -1)
287+ else false)
288+ then nil
289+ else if (if ((depositNumLast == -1))
290+ then (depositNumUser > -1)
291+ else false)
292+ then throw("invalid depositNumLast and depositNumUser state")
293+ else if (if ((depositNumLast > -1))
294+ then (depositNumUser >= -1)
295+ else false)
296+ then if (isNewUser)
297+ then [IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)]
298+ else ({
299+ let $l = supportedAssetsList
300+ let $s = size($l)
301+ let $acc0 = nil
302+ func $f0_1 ($a,$i) = if (($i >= $s))
303+ then $a
304+ else forEachAssetCacheUserReward($a, $l[$i])
305+
306+ func $f0_2 ($a,$i) = if (($i >= $s))
307+ then $a
308+ else throw("List size exceeds 2")
309+
310+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
311+ } :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast))
312+ else throw(((("uncovered condition: depositNumLast=" + toString(depositNumLast)) + " depositNumUser=") + toString(depositNumUser)))
313+ }
314+
315+
316+func IncrementNotDistributedRewardEntry (tkn,amountInc) = {
317+ let notDistributedRewardKEY = keyNotDistributedReward(tkn)
318+ let notDistributedReward = getIntOrElse(notDistributedRewardKEY, 0)
319+[IntegerEntry(notDistributedRewardKEY, (notDistributedReward + amountInc))]
320+ }
321+
322+
323+func mergeStake (userAddress,amountToAdd) = {
324+ let $t01368413800 = valueOrElse(getUserParamsOrUnit(userAddress), $Tuple3(true, 0, height))
325+ let isNewUser = $t01368413800._1
326+ let stakedAmount = $t01368413800._2
327+ let stakingStartHeight = $t01368413800._3
328+ let stakedAmountNEW = if (isNewUser)
329+ then amountToAdd
330+ else (amountToAdd + stakedAmount)
331+ $Tuple4(isNewUser, stakedAmount, stakingStartHeight, stakedAmountNEW)
332+ }
333+
334+
335+func isUsdnStakingMigrationDone () = {
336+ let legacyTotalBalance = getIntOrElse(keyLegacyTotalBalance(stakedAssetIdStr), 0)
337+ let totalBalance = getIntOrElse(keyLockParamTotalAmount(), 0)
338+ (legacyTotalBalance == totalBalance)
339+ }
340+
341+
342+func failIfUsdnMigrationNotDone () = if (isUsdnStakingMigrationDone())
343+ then true
344+ else throw("USDN staking migration is IN PROGRESS. All operations are temporary suspended.")
345+
346+
347+func commonStake (userAddress,i,isMigration) = {
348+ let migCheck = if (!(isMigration))
349+ then failIfUsdnMigrationNotDone()
350+ else true
351+ if ((migCheck == migCheck))
352+ then if ((size(i.payments) != 1))
353+ then throw("Invalid payments size")
354+ else {
355+ let payment = i.payments[0]
356+ let amount = payment.amount
357+ let invalidAssetMessage = (("Invalid asset. " + toBase58String(stakedAssetId)) + " is expected")
358+ let assetId = valueOrErrorMessage(payment.assetId, invalidAssetMessage)
359+ if ((assetId != stakedAssetId))
360+ then throw(invalidAssetMessage)
361+ else {
362+ let userAddressStr = toString(userAddress)
363+ let mergedData = mergeStake(userAddressStr, amount)
364+ let isNewUser = mergedData._1
365+ let stakedAmount = mergedData._2
366+ let stakingStartHeight = mergedData._3
367+ let stakedAmountNEW = mergedData._4
368+ if ((minLockAmount > stakedAmountNEW))
369+ then throw(("Min lock amount is " + toString(minLockAmount)))
370+ else {
371+ let $t01528315398 = StatsResult(amount, 1, if (isNewUser)
372+ then 1
373+ else 0, isMigration)
374+ let statsEntries = $t01528315398._1
375+ let totalStaked = $t01528315398._2
376+ let totalStakedNew = $t01528315398._3
377+ ((([HistoryRecordEntry("stake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(isNewUser, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight, isMigration)) ++ statsEntries)
378+ }
379+ }
380+ }
381+ else throw("Strict value is not equal to itself.")
382+ }
383+
384+
385+func commonUnstake (amount,i,isMigration) = {
386+ let migrationCheck = failIfUsdnMigrationNotDone()
387+ if ((migrationCheck == migrationCheck))
388+ then if ((size(i.payments) != 0))
389+ then throw("unstake doesn't require any payment")
390+ else {
391+ let userAddress = i.caller
392+ let userAddressStr = toString(userAddress)
393+ let $t01596316051 = getUserParamsOrFail(userAddressStr)
394+ let isNewUser = $t01596316051._1
395+ let stakedAmount = $t01596316051._2
396+ let stakingStartHeight = $t01596316051._3
397+ if ((0 >= stakedAmount))
398+ then throw("Nothing to unstake")
399+ else if ((amount > stakedAmount))
400+ then throw(((("Requested " + toString(amount)) + ", but staked only ") + toString(stakedAmount)))
401+ else {
402+ let stakedAmountNEW = (stakedAmount - amount)
403+ let $t01629316464 = StatsResult(-(amount), if ((amount == stakedAmount))
404+ then -1
405+ else 0, if ((amount == stakedAmount))
406+ then -1
407+ else 0, isMigration)
408+ let statsEntries = $t01629316464._1
409+ let totalStaked = $t01629316464._2
410+ let totalStakedNew = $t01629316464._3
411+ ((([ScriptTransfer(userAddress, amount, stakedAssetId), HistoryRecordEntry("unstake", userAddressStr, i.transactionId, stakedAmount, stakedAmountNEW)] ++ RewardEntries(false, userAddressStr, stakedAmount)) ++ LockParamsEntry(userAddressStr, stakedAmountNEW, stakingStartHeight, isMigration)) ++ statsEntries)
412+ }
413+ }
414+ else throw("Strict value is not equal to itself.")
415+ }
416+
417+
418+func commonClaim (userAddress,i) = {
419+ let migrationCheck = failIfUsdnMigrationNotDone()
420+ if ((migrationCheck == migrationCheck))
421+ then {
422+ let userAddressStr = toString(userAddress)
423+ if ((size(i.payments) > 0))
424+ then throw("payments are not accepted")
425+ else {
426+ let $t01702817136 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
427+ let isNewUser = $t01702817136._1
428+ let stakedAmount = $t01702817136._2
429+ let stakingStart = $t01702817136._3
430+ let stakedAmountX = toBigInt(stakedAmount)
431+ let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
432+ let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
433+ let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
434+ func forEachAssetCalcUnclaimedReward (accum,asset) = {
435+ let $t01750717645 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
436+ let rewardTotal = $t01750717645._1
437+ let cached = $t01750717645._2
438+ let dynamic = $t01750717645._3
439+ let rewardCachedPartKEY = $t01750717645._4
440+ let claimedKEY = keyClaimed(userAddressStr, asset)
441+ let $t01770517742 = accum
442+ let data = $t01770517742._1
443+ let claimedAmtByAsset = $t01770517742._2
444+ let newPart = makeString([asset, toString(rewardTotal)], ":")
445+ let claimedAmtByAssetNew = makeString([claimedAmtByAsset, newPart], "_")
446+ if ((0 >= rewardTotal))
447+ then $Tuple2(data, claimedAmtByAssetNew)
448+ else $Tuple2((((data :+ ScriptTransfer(userAddress, rewardTotal, toAssetVect(asset))) :+ IntegerEntry(claimedKEY, (valueOrElse(getInteger(claimedKEY), 0) + rewardTotal))) :+ IntegerEntry(rewardCachedPartKEY, 0)), claimedAmtByAssetNew)
449+ }
450+
451+ let $t01820218315 = {
452+ let $l = supportedAssetsList
453+ let $s = size($l)
454+ let $acc0 = $Tuple2(nil, "")
455+ func $f0_1 ($a,$i) = if (($i >= $s))
456+ then $a
457+ else forEachAssetCalcUnclaimedReward($a, $l[$i])
458+
459+ func $f0_2 ($a,$i) = if (($i >= $s))
460+ then $a
461+ else throw("List size exceeds 2")
462+
463+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
464+ }
465+ let transfers = $t01820218315._1
466+ let claimedAmtByAssetResult = $t01820218315._2
467+ if ((0 >= size(transfers)))
468+ then $Tuple2(nil, 0)
469+ else $Tuple2(((transfers :+ IntegerEntry(userRewardFromDepositNumKEY, depositNumLast)) :+ ClaimHistoryEntry(userAddressStr, i.transactionId, drop(claimedAmtByAssetResult, 1))), size(transfers))
470+ }
471+ }
472+ else throw("Strict value is not equal to itself.")
473+ }
474+
475+
476+let USDNTYPE = "USDN"
477+
478+let NSBTTYPE = "NSBT"
479+
480+let NeutrinoAssetIdKey = "neutrino_asset_id"
481+
482+let NeutrinoContractKey = "neutrino_contract"
483+
484+let NsbtAssetIdKey = "bond_asset_id"
485+
486+let BalanceKey = "rpd_balance"
487+
488+let neutrinoAssetId = fromBase58String(getStringOrFail(neutrinoContract, NeutrinoAssetIdKey))
489+
490+let nsbtAssetIdStr = getStringOrFail(neutrinoContract, NsbtAssetIdKey)
491+
492+let nsbtAssetId = fromBase58String(nsbtAssetIdStr)
493+
494+func getUserBalanceKey (owner,assetId) = makeString([BalanceKey, assetId, owner], "_")
495+
496+
497+func getContractBalanceKey (assetId) = ((BalanceKey + "_") + assetId)
498+
499+
500+func getContractBalance (assetId) = getIntOrElse(getContractBalanceKey(assetId), 0)
501+
502+
503+func getUserBalance (owner,assetId) = getIntOrElse(getUserBalanceKey(owner, assetId), 0)
504+
505+
506+func getValidStakingAssetOrFail (stakingType,assetId) = if (if ((stakingType == USDNTYPE))
507+ then (assetId != neutrinoAssetId)
508+ else false)
509+ then throw("can use USDN only")
510+ else if (if ((stakingType == NSBTTYPE))
511+ then (assetId != nsbtAssetId)
512+ else false)
513+ then throw("can use NSBT only")
514+ else if (if ((stakingType != USDNTYPE))
515+ then (stakingType != NSBTTYPE)
516+ else false)
517+ then throw(("unsupported staking type " + stakingType))
518+ else assetId
519+
520+
521+func internalUnlock (stakingType,i,unlockAmount,assetIdParam) = {
522+ let account = toString(i.caller)
523+ let assetId = getValidStakingAssetOrFail(stakingType, fromBase58String(assetIdParam))
524+ let assetIdString = toBase58String(assetId)
525+ let balance = (getUserBalance(account, assetIdString) - unlockAmount)
526+ if ((0 > balance))
527+ then throw("invalid amount")
528+ else $Tuple2([IntegerEntry(getContractBalanceKey(assetIdString), (getContractBalance(assetIdString) - unlockAmount)), IntegerEntry(getUserBalanceKey(account, assetIdString), balance), ScriptTransfer(addressFromStringValue(account), unlockAmount, assetId)], unit)
529+ }
530+
531+
532+@Callable(i)
533+func constructor (minLockAmount,supportedRewardAssets,pStakedAssetId) = if ((i.caller != this))
534+ then throw("Permission denied")
535+ else [IntegerEntry(keyMinLockAmount(), minLockAmount), StringEntry(keySupportedRewardAssets(), supportedRewardAssets), StringEntry(keyStakedAssetId(), pStakedAssetId)]
536+
537+
538+
539+@Callable(i)
540+func migrateUsdnStaking (userAddressStr) = {
541+ let mngPubS = valueOrElse(getString("%s%s__cfg__leasingManagerPub"), "7AUMX54ukYMYvPmma7yoFf5NjZhs4Bu5nz3Ez9EV8sur")
542+ let mngPub = fromBase58String(mngPubS)
543+ if ((i.callerPublicKey != mngPub))
544+ then throw("migrateUsdnStaking not authorized")
545+ else if (isUsdnStakingMigrationDone())
546+ then throw("migration has been done")
547+ else if ((size(i.payments) != 0))
548+ then throw("payments are not allowed")
549+ else if ((i.feeAssetId != unit))
550+ then throw("fee in WAVES is allowed only")
551+ else if ((i.fee != 500000))
552+ then throw("0.005 WAVES fee is allowed only")
553+ else {
554+ let legacyUserBalance = getIntOrElse(keyLegacyUserBalance(userAddressStr, stakedAssetIdStr), 0)
555+ if ((legacyUserBalance == 0))
556+ then throw(("no need to migrate user " + userAddressStr))
557+ else if (isActiveUser(userAddressStr))
558+ then throw(("already migrated user " + userAddressStr))
559+ else {
560+ let userAddress = addressFromStringValue(userAddressStr)
561+ let emptyVect = fromBase58String("")
562+ commonStake(userAddress, Invocation([AttachedPayment(stakedAssetId, legacyUserBalance)], userAddress, emptyVect, i.transactionId, 0, unit, userAddress, emptyVect), true)
563+ }
564+ }
565+ }
566+
567+
568+
569+@Callable(i)
570+func stake () = commonStake(i.caller, i, false)
571+
572+
573+
574+@Callable(i)
575+func stakeByOriginCaller () = commonStake(i.originCaller, i, false)
576+
577+
578+
579+@Callable(i)
580+func unstake (amount) = commonUnstake(amount, i, false)
581+
582+
583+
584+@Callable(i)
585+func deposit () = {
586+ let migrationCheck = failIfUsdnMigrationNotDone()
587+ if ((migrationCheck == migrationCheck))
588+ then if ((size(i.payments) != 1))
589+ then throw("exact 1 payment is allowed only")
590+ else {
591+ let pmt = i.payments[0]
592+ let amount = pmt.amount
593+ let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
594+ let pmtAssetIdStr = toBase58String(pmtAssetId)
595+ let pmtMultX = if ((pmtAssetId == WAVESID))
596+ then MULTX8
597+ else MULTX6
598+ let amountX = toBigInt(amount)
599+ let totalStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
600+ let totalStakedX = toBigInt(totalStaked)
601+ if ((0 > totalStaked))
602+ then throw("TODO: case is not supported")
603+ else if ((totalStaked == 0))
604+ then IncrementNotDistributedRewardEntry(pmtAssetIdStr, amount)
605+ else {
606+ let rewardPerNsbtX18 = fraction(amountX, MULTX18, totalStakedX)
607+ let depositNumLastKEY = keyDepositNumLast()
608+ let depositNumLast = getIntOrElse(depositNumLastKEY, -1)
609+ let depositNumNew = (depositNumLast + 1)
610+ if (!(contains(supportedAssetsStr, pmtAssetIdStr)))
611+ then throw(((supportedAssetsStr + " doesn't contain ") + pmtAssetIdStr))
612+ else {
613+ func refreshRewardPerNsbtSUM (accum,nextAsset) = {
614+ let rewardPerNsbtSumNewKEY = keyRewardPerNsbtSumAt(depositNumNew, nextAsset)
615+ let sumLastStr = getStrOrElse(keyRewardPerNsbtSumAt(depositNumLast, nextAsset), "0")
616+ (accum :+ (if ((nextAsset == pmtAssetIdStr))
617+ then StringEntry(rewardPerNsbtSumNewKEY, toString((parseBigIntValue(sumLastStr) + rewardPerNsbtX18)))
618+ else StringEntry(rewardPerNsbtSumNewKEY, sumLastStr)))
619+ }
620+
621+ (({
622+ let $l = supportedAssetsList
623+ let $s = size($l)
624+ let $acc0 = nil
625+ func $f0_1 ($a,$i) = if (($i >= $s))
626+ then $a
627+ else refreshRewardPerNsbtSUM($a, $l[$i])
628+
629+ func $f0_2 ($a,$i) = if (($i >= $s))
630+ then $a
631+ else throw("List size exceeds 2")
632+
633+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
634+ } :+ IntegerEntry(depositNumLastKEY, depositNumNew)) ++ DepositsTotalsEntries(amount, pmtAssetIdStr))
635+ }
636+ }
637+ }
638+ else throw("Strict value is not equal to itself.")
639+ }
640+
641+
642+
643+@Callable(i)
644+func claimRewards () = commonClaim(i.caller, i)
645+
646+
647+
648+@Callable(i)
649+func claimRewardsByOriginCaller () = commonClaim(i.originCaller, i)
650+
651+
652+
653+@Callable(i)
654+func unclaimedRewardsREADONLY (userAddressStr) = {
655+ func forEachAssetZeroReward (accum,asset) = ((accum + makeString([asset, "0", "0"], ":")) + "_")
656+
657+ let unclaimedRewardStr = if ((userAddressStr == ""))
658+ then {
659+ let $l = supportedAssetsList
660+ let $s = size($l)
661+ let $acc0 = ""
662+ func $f0_1 ($a,$i) = if (($i >= $s))
663+ then $a
664+ else forEachAssetZeroReward($a, $l[$i])
665+
666+ func $f0_2 ($a,$i) = if (($i >= $s))
667+ then $a
668+ else throw("List size exceeds 2")
669+
670+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
671+ }
672+ else {
673+ let userAddress = addressFromStringValue(userAddressStr)
674+ let $t02464624760 = valueOrElse(getUserParamsOrUnit(userAddressStr), $Tuple3(true, 0, 0))
675+ let isNewUser = $t02464624760._1
676+ let stakedAmount = $t02464624760._2
677+ let stakingStartHeight = $t02464624760._3
678+ let stakedAmountX = toBigInt(stakedAmount)
679+ let userRewardFromDepositNumKEY = keyUserRewardFromDepositNum(userAddressStr)
680+ let depositNumUser = getIntOrElse(userRewardFromDepositNumKEY, -1)
681+ let depositNumLast = getIntOrElse(keyDepositNumLast(), -1)
682+ func forEachAssetCalcUnclaimedReward (accum,asset) = {
683+ let $t02510625244 = calcReward(userAddressStr, asset, stakedAmountX, depositNumUser, depositNumLast)
684+ let rewardTotal = $t02510625244._1
685+ let cached = $t02510625244._2
686+ let dynamic = $t02510625244._3
687+ let rewardCachedPartKEY = $t02510625244._4
688+ let claimed = valueOrElse(getInteger(keyClaimed(userAddressStr, asset)), 0)
689+ ((accum + makeString([asset, toString(rewardTotal), toString(claimed)], ":")) + "_")
690+ }
691+
692+ let $l = supportedAssetsList
693+ let $s = size($l)
694+ let $acc0 = ""
695+ func $f0_1 ($a,$i) = if (($i >= $s))
696+ then $a
697+ else forEachAssetCalcUnclaimedReward($a, $l[$i])
698+
699+ func $f0_2 ($a,$i) = if (($i >= $s))
700+ then $a
701+ else throw("List size exceeds 2")
702+
703+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
704+ }
705+ $Tuple2(nil, dropRight(unclaimedRewardStr, 1))
706+ }
707+
708+
709+
710+@Callable(i)
711+func usdnStakingSYSREADONLY (userAddressStrOrEmpty,usdnDiff) = {
712+ let usdnTotalAmtStaked = getIntOrElse(keyLockParamTotalAmount(), 0)
713+ if ((userAddressStrOrEmpty == ""))
714+ then $Tuple2(nil, [0, usdnTotalAmtStaked, 0])
715+ else {
716+ let userAddress = toAddressOrFail(userAddressStrOrEmpty)
717+ let mergedData = mergeStake(userAddressStrOrEmpty, usdnDiff)
718+ let isNewUser = mergedData._1
719+ let usdnStakedByUser = mergedData._2
720+ let stakingStartHeight = mergedData._3
721+ let stakedAmountNEW = mergedData._4
722+ $Tuple2(nil, [usdnStakedByUser, usdnTotalAmtStaked])
723+ }
724+ }
725+
726+
727+
728+@Callable(i)
729+func configSYSREADONLY () = {
730+ let minLockAmt = getIntegerValue(keyMinLockAmount())
731+ $Tuple2(nil, [minLockAmt])
732+ }
733+
734+
735+
736+@Callable(i)
737+func lockNeutrinoSP (receiver,share) = commonStake(i.caller, i, false)
738+
739+
740+
741+@Callable(i)
742+func lockNeutrino () = commonStake(i.caller, i, false)
743+
744+
745+
746+@Callable(i)
747+func unlockNeutrino (unlockAmount,assetIdString) = commonUnstake(unlockAmount, i, false)
748+
749+
750+
751+@Callable(i)
752+func unlockNsbt (unlockAmount,assetIdString) = internalUnlock(NSBTTYPE, i, unlockAmount, assetIdString)
753+
754+
755+@Verifier(tx)
756+func verify () = {
757+ let pubKeyAdminsListStr = makeString(["GFmKZ2naZFRoCvNbwKAQVGmLb1uBeWGDgFabdGBuZiuy", "GmJXRyhRA79g8yUGgKBAVdnFfQFDMjQG98b1MmLDh5kk", "CFhbV6h41hVjbGHudGtS3fYUv7QAKRxFQzKNtx4B5PqP", "Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK"], SEP)
758+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
759+ let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
760+ then 1
761+ else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
762+ then 1
763+ else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
764+ then 1
765+ else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
766+ then 2
767+ else 0))
768+ (count >= 3)
769+ }
770+

github/deemru/w8io/169f3d6 
41.27 ms