tx · HWRVNKksKRyErxvrkwAf8rVMTEMyGvCfkRPvFeVdmHKA

3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE:  -0.02300000 Waves

2023.10.16 12:15 [2800981] smart account 3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE > SELF 0.00000000 Waves

{ "type": 13, "id": "HWRVNKksKRyErxvrkwAf8rVMTEMyGvCfkRPvFeVdmHKA", "fee": 2300000, "feeAssetId": null, "timestamp": 1697447754702, "version": 2, "chainId": 84, "sender": "3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE", "senderPublicKey": "6t3vrhP1jCmG7CeKBmL8hUibtdP3cMXGC2XtPYEPPC5w", "proofs": [ "U5T56zL6BAxvLQNEXPPYXHiQiJ8Fn3nVu8J9PeS43gGWY6qg3wpVPKiYXxnAMe6r5V4VkWjifGNjiC4FMGxyurL" ], "script": "base64:BgIrCAISBQoDCAEIEgMKAQgSBAoCCAQSAwoBCBIDCgEIEgUKAwgBCBIECgIIATYACXNlcGFyYXRvcgICX18ABU1VTFQ4AIDC1y8AC3dhdmVzU3RyaW5nAgVXQVZFUwAQc3RhdHVzSW5Qcm9ncmVzcwIKaW5Qcm9ncmVzcwAOc3RhdHVzQWNjZXB0ZWQCCGFjY2VwdGVkAA5zdGF0dXNSZWplY3RlZAIIcmVqZWN0ZWQBB3dyYXBFcnIBA21zZwkAuQkCCQDMCAICGHZvdGluZ192ZXJpZmllZF92Mi5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIdGhyb3dFcnIBA21zZwkAAgEJAQd3cmFwRXJyAQUDbXNnAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECG0ZhaWxlZCB0byBjYXN0IGludG8gSW50ZWdlcgEMcGFyc2VBc3NldElkAQVpbnB1dAMJAAACBQVpbnB1dAULd2F2ZXNTdHJpbmcFBHVuaXQJANkEAQUFaW5wdXQBD2Fzc2V0SWRUb1N0cmluZwEFaW5wdXQDCQAAAgUFaW5wdXQFBHVuaXQFC3dhdmVzU3RyaW5nCQDYBAEJAQV2YWx1ZQEFBWlucHV0ARBnZXRJbnRlZ2VyT3JaZXJvAgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEQZ2V0SW50ZWdlck9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEQZ2V0U3RyaW5nT3JFbXB0eQIHYWRkcmVzcwNrZXkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUHYWRkcmVzcwUDa2V5AgABD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAATa2V5Qm9vc3RpbmdDb250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUJc2VwYXJhdG9yABNrZXlFbWlzc2lvbkNvbnRyYWN0CQC5CQIJAMwIAgICJXMJAMwIAgIQZW1pc3Npb25Db250cmFjdAUDbmlsBQlzZXBhcmF0b3IAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QJALkJAgkAzAgCAgIlcwkAzAgCAhNhc3NldHNTdG9yZUNvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgAQYm9vc3RpbmdDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5Qm9vc3RpbmdDb250cmFjdAAQZW1pc3Npb25Db250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5RW1pc3Npb25Db250cmFjdAATYXNzZXRzU3RvcmVDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUWa2V5QXNzZXRzU3RvcmVDb250cmFjdAARa2V5RW1pc3Npb25Db25maWcJALkJAgkAzAgCAgIlcwkAzAgCAgZjb25maWcFA25pbAUJc2VwYXJhdG9yAAx3eEFzc2V0SWRTdHIJAJEDAgkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAURa2V5RW1pc3Npb25Db25maWcFCXNlcGFyYXRvcgABAAl3eEFzc2V0SWQJANkEAQUMd3hBc3NldElkU3RyABVrZXlWb3RpbmdUaHJlc2hvbGRBZGQJALkJAgkAzAgCAgQlcyVzCQDMCAICD3ZvdGluZ1RocmVzaG9sZAkAzAgCAgNhZGQFA25pbAUJc2VwYXJhdG9yABhrZXlWb3RpbmdUaHJlc2hvbGRSZW1vdmUJALkJAgkAzAgCAgQlcyVzCQDMCAICD3ZvdGluZ1RocmVzaG9sZAkAzAgCAgZyZW1vdmUFA25pbAUJc2VwYXJhdG9yABVrZXlQZXJpb2RMZW5ndGhSZW1vdmUJALkJAgkAzAgCAgIlcwkAzAgCAhJwZXJpb2RMZW5ndGhSZW1vdmUFA25pbAUJc2VwYXJhdG9yABJrZXlNYXhQZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAg9tYXhQZXJpb2RMZW5ndGgFA25pbAUJc2VwYXJhdG9yABJrZXlNaW5QZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAg9taW5QZXJpb2RMZW5ndGgFA25pbAUJc2VwYXJhdG9yARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICE3ZvdGluZ1Jld2FyZEFzc2V0SWQJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEPa2V5Vm90aW5nUmV3YXJkAwt1c2VyQWRkcmVzcwdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmV3YXJkCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEUa2V5VG90YWxWb3RpbmdSZXdhcmQCB2Fzc2V0SWQFaW5kZXgJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIRdG90YWxWb3RpbmdSZXdhcmQJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgAba2V5RmluYWxpemVDYWxsUmV3YXJkQW1vdW50CQC5CQIJAMwIAgICJXMJAMwIAgIYZmluYWxpemVDYWxsUmV3YXJkQW1vdW50BQNuaWwFCXNlcGFyYXRvcgAaa2V5TWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UJALkJAgkAzAgCAgIlcwkAzAgCAhdtaW5TdWdnZXN0UmVtb3ZlQmFsYW5jZQUDbmlsBQlzZXBhcmF0b3IBD2tleUN1cnJlbnRJbmRleAEHYXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIMY3VycmVudEluZGV4CQDMCAIFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yAQdrZXlWb3RlAwdhc3NldElkBWluZGV4BmNhbGxlcgkAuQkCCQDMCAICCCVzJXMlZCVzCQDMCAICBHZvdGUJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4CQDMCAIJAKUIAQUGY2FsbGVyBQNuaWwFCXNlcGFyYXRvcgEJdm90ZVZhbHVlAgdpbkZhdm9yCWd3eEFtb3VudAkAuQkCCQDMCAICBCVzJWQJAMwIAgkApQMBBQdpbkZhdm9yCQDMCAIJAKQDAQUJZ3d4QW1vdW50BQNuaWwFCXNlcGFyYXRvcgEQa2V5U3VnZ2VzdElzc3VlcgIHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAg1zdWdnZXN0SXNzdWVyCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQVpbmRleAUDbmlsBQlzZXBhcmF0b3IBD2tleUNsYWltSGlzdG9yeQMLdXNlckFkZHJlc3MHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICB2hpc3RvcnkJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgFA25pbAUJc2VwYXJhdG9yAA5rZXlGZWVQZXJCbG9jawkAuQkCCQDMCAICAiVzCQDMCAICC2ZlZVBlckJsb2NrBQNuaWwFCXNlcGFyYXRvcgALZmVlUGVyQmxvY2sJARBnZXRJbnRlZ2VyT3JGYWlsAgUEdGhpcwUOa2V5RmVlUGVyQmxvY2sAJmtleU1pbld4TWluRm9yU3VnZ2VzdEFkZEFtb3VudFJlcXVpcmVkCQC5CQIJAMwIAgICJXMJAMwIAgIgd3hNaW5Gb3JTdWdnZXN0QWRkQW1vdW50UmVxdWlyZWQFA25pbAUJc2VwYXJhdG9yACNrZXlXeEZvclN1Z2dlc3RSZW1vdmVBbW91bnRSZXF1aXJlZAkAuQkCCQDMCAICAiVzCQDMCAICIHd4Rm9yU3VnZ2VzdFJlbW92ZUFtb3VudFJlcXVpcmVkBQNuaWwFCXNlcGFyYXRvcgENa2V5Vm90aW5nSW5mbwIHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgp2b3RpbmdJbmZvCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQVpbmRleAUDbmlsBQlzZXBhcmF0b3IBD3ZvdGluZ0luZm9WYWx1ZQoNaXNSZXdhcmRFeGlzdA1yZXdhcmRBc3NldElkDHJld2FyZEFtb3VudAp2b3RpbmdUeXBlBnN0YXR1cxF2b3RpbmdTdGFydEhlaWdodA92b3RpbmdFbmRIZWlnaHQLdm90ZXNRdW9ydW0Idm90ZXNGb3IMdm90ZXNBZ2FpbnN0CQC5CQIJAMwIAgIUJXMlcyVkJXMlcyVkJWQlZCVkJWQJAMwIAgkApQMBBQ1pc1Jld2FyZEV4aXN0CQDMCAIFDXJld2FyZEFzc2V0SWQJAMwIAgkApAMBBQxyZXdhcmRBbW91bnQJAMwIAgUKdm90aW5nVHlwZQkAzAgCBQZzdGF0dXMJAMwIAgkApAMBBRF2b3RpbmdTdGFydEhlaWdodAkAzAgCCQCkAwEFD3ZvdGluZ0VuZEhlaWdodAkAzAgCCQCkAwEFC3ZvdGVzUXVvcnVtCQDMCAIJAKQDAQUIdm90ZXNGb3IJAMwIAgkApAMBBQx2b3Rlc0FnYWluc3QFA25pbAUJc2VwYXJhdG9yAQ1rZXlBc3NldEltYWdlAQdhc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgphc3NldEltYWdlCQDMCAIFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yARhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQJZ3d4QW1vdW50CQD8BwQFEGJvb3N0aW5nQ29udHJhY3QCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFDHRhcmdldEhlaWdodAUDbmlsBQNuaWwJAQVhc0ludAEFCWd3eEFtb3VudAEWa2V5TWFuYWdlclZhdWx0QWRkcmVzcwACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzARNrZXlNYW5hZ2VyUHVibGljS2V5AAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMABAckbWF0Y2gwCQCiCAEJARZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAXMFBHRoaXMBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABBNtYW5hZ2VyVmF1bHRBZGRyZXNzCQEcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcwAEByRtYXRjaDAJAJ0IAgUTbWFuYWdlclZhdWx0QWRkcmVzcwkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgESZ2V0Vm90aW5nSW5mb1BhcnRzAQp2b3RpbmdJbmZvBA92b3RpbmdJbmZvUGFydHMJALUJAgUKdm90aW5nSW5mbwUJc2VwYXJhdG9yBBBpc1Jld2FyZEV4aXN0U3RyCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwABBA1pc1Jld2FyZEV4aXN0AwkAAAIFEGlzUmV3YXJkRXhpc3RTdHICBHRydWUGBwQNcmV3YXJkQXNzZXRJZAkAkQMCBQ92b3RpbmdJbmZvUGFydHMAAgQMcmV3YXJkQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAMECnZvdGluZ1R5cGUJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAQEBnN0YXR1cwkAkQMCBQ92b3RpbmdJbmZvUGFydHMABQQRdm90aW5nU3RhcnRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMABgQPdm90aW5nRW5kSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAcEC3ZvdGVzUXVvcnVtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAgECHZvdGVzRm9yCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAkEDHZvdGVzQWdhaW5zdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwAKCQCcCgoFDWlzUmV3YXJkRXhpc3QFDXJld2FyZEFzc2V0SWQFDHJld2FyZEFtb3VudAUKdm90aW5nVHlwZQUGc3RhdHVzBRF2b3RpbmdTdGFydEhlaWdodAUPdm90aW5nRW5kSGVpZ2h0BQt2b3Rlc1F1b3J1bQUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAERdm90aW5nRXhpc3RDaGVja3MCB2Fzc2V0SWQMY3VycmVudEluZGV4BAp2b3RpbmdJbmZvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgJAQd3cmFwRXJyAQIVdm90aW5nIGluZm8gbm90IGZvdW5kBA92b3RpbmdJbmZvQXJyYXkJALUJAgUKdm90aW5nSW5mbwUJc2VwYXJhdG9yBAZzdGF0dXMJAJEDAgUPdm90aW5nSW5mb0FycmF5AAUED3ZvdGluZ0VuZEhlaWdodAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb0FycmF5AAcJAQd3cmFwRXJyAQIddm90aW5nIHN0YXJ0IGhlaWdodCBub3QgZm91bmQEDXN1Z2dlc3RJc3N1ZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhd2b3RpbmcgaXNzdWVyIG5vdCBmb3VuZAQGY2hlY2tzCQDMCAIDCQAAAgUGc3RhdHVzBRBzdGF0dXNJblByb2dyZXNzBgkBCHRocm93RXJyAQIVbm8gdm90aW5nIGluIHByb2dyZXNzCQDMCAIDCQBmAgUPdm90aW5nRW5kSGVpZ2h0BQZoZWlnaHQGCQEIdGhyb3dFcnIBAg52b3RpbmcgZXhwaXJlZAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzCQCVCgMFBnN0YXR1cwUPdm90aW5nRW5kSGVpZ2h0BQ1zdWdnZXN0SXNzdWVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9jYWxjdWxhdGVSZXdhcmQDBXZvdGVyB2Fzc2V0SWQFaW5kZXgEB3ZvdGVLZXkJAQdrZXlWb3RlAwUHYXNzZXRJZAUFaW5kZXgFBXZvdGVyBAhsYXN0Vm90ZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEFB3ZvdGVLZXkJAQd3cmFwRXJyAQISeW91IGhhdmUgbm90IHZvdGVkBA1sYXN0Vm90ZVBhcnRzCQC1CQIFCGxhc3RWb3RlBQlzZXBhcmF0b3IECWd3eEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDWxhc3RWb3RlUGFydHMAAgQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUFaW5kZXgJAQd3cmFwRXJyAQIVdm90aW5nIGluZm8gbm90IGZvdW5kBAt2b3RpbmdQYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIEBnN0YXR1cwgFC3ZvdGluZ1BhcnRzAl81BAh2b3Rlc0ZvcggFC3ZvdGluZ1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQt2b3RpbmdQYXJ0cwNfMTAEFXBhcnRPZlRoZVRvdGFsVm90ZXNYOAkAawMFCWd3eEFtb3VudAUFTVVMVDgJAGQCBQh2b3Rlc0ZvcgUMdm90ZXNBZ2FpbnN0BBF0b3RhbFZvdGluZ1Jld2FyZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQVpbmRleAAABBF2b3RlclJld2FyZEFtb3VudAkAbgQFFXBhcnRPZlRoZVRvdGFsVm90ZXNYOAURdG90YWxWb3RpbmdSZXdhcmQFBU1VTFQ4BQVGTE9PUgQIY2FuQ2xhaW0DCQAAAgUGc3RhdHVzBQ5zdGF0dXNBY2NlcHRlZAkAZgIFEXZvdGVyUmV3YXJkQW1vdW50AAAHCQCUCgIFEXZvdGVyUmV3YXJkQW1vdW50BQhjYW5DbGFpbQcBaQEKc3VnZ2VzdEFkZAMHYXNzZXRJZAxwZXJpb2RMZW5ndGgKYXNzZXRJbWFnZQQJd3hQYXltZW50CQCRAwIIBQFpCHBheW1lbnRzAAAEEHd4UGF5bWVudEFzc2V0SWQJAQV2YWx1ZQEIBQl3eFBheW1lbnQHYXNzZXRJZAQPd3hQYXltZW50QW1vdW50CQEFdmFsdWUBCAUJd3hQYXltZW50BmFtb3VudAQPbWluUGVyaW9kTGVuZ3RoCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJrZXlNaW5QZXJpb2RMZW5ndGgED21heFBlcmlvZExlbmd0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQUSa2V5TWF4UGVyaW9kTGVuZ3RoBA90b2tlbklzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQUBQAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQGY2hlY2tzCQDMCAIDAwkAZwIFDHBlcmlvZExlbmd0aAUPbWluUGVyaW9kTGVuZ3RoCQBnAgUPbWF4UGVyaW9kTGVuZ3RoBQxwZXJpb2RMZW5ndGgHBgkBCHRocm93RXJyAQIUaW52YWxpZCBwZXJpb2RMZW5ndGgJAMwIAgMJAAACBQ90b2tlbklzVmVyaWZpZWQHBgkBCHRocm93RXJyAQIWdG9rZW4gYWxyZWFkeSB2ZXJpZmllZAkAzAgCAwkAZwIFD3d4UGF5bWVudEFtb3VudAkAaAIFDHBlcmlvZExlbmd0aAULZmVlUGVyQmxvY2sGCQEIdGhyb3dFcnIBAh5ub3QgZW5vdWdoIHd4IGZvciBnaXZlbiBwZXJpb2QJAMwIAgMJAGcCBQ93eFBheW1lbnRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFJmtleU1pbld4TWluRm9yU3VnZ2VzdEFkZEFtb3VudFJlcXVpcmVkBgkBCHRocm93RXJyAQIhcGF5bWVudCBsZXNzIHRoZW4gbWluIGZvciBzdWdnZXN0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MED2N1cnJlbnRJbmRleEtleQkBD2tleUN1cnJlbnRJbmRleAEFB2Fzc2V0SWQEDGN1cnJlbnRJbmRleAkAnwgBBQ9jdXJyZW50SW5kZXhLZXkECG5ld0luZGV4AwkBCWlzRGVmaW5lZAEFDGN1cnJlbnRJbmRleAkAZAIJAQV2YWx1ZQEFDGN1cnJlbnRJbmRleAABAAAECyR0MDkyNTk5ODk5AwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAQQTdm90aW5nUmV3YXJkUGF5bWVudAkAkQMCCAUBaQhwYXltZW50cwABBBp2b3RpbmdSZXdhcmRQYXltZW50QXNzZXRJZAkA2AQBCQEFdmFsdWUBCAUTdm90aW5nUmV3YXJkUGF5bWVudAdhc3NldElkBBl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQEFdmFsdWUBCAUTdm90aW5nUmV3YXJkUGF5bWVudAZhbW91bnQJAJYKBAYFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkBRl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgUHYXNzZXRJZAUIbmV3SW5kZXgFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQhuZXdJbmRleAUZdm90aW5nUmV3YXJkUGF5bWVudEFtb3VudAUDbmlsCQCWCgQHAgVFTVBUWQAABQNuaWwEDWlzUmV3YXJkRXhpc3QIBQskdDA5MjU5OTg5OQJfMQQNcmV3YXJkQXNzZXRJZAgFCyR0MDkyNTk5ODk5Al8yBAxyZXdhcmRBbW91bnQIBQskdDA5MjU5OTg5OQJfMwQTdm90aW5nUmV3YXJkQWN0aW9ucwgFCyR0MDkyNTk5ODk5Al80BAt2b3Rlc1F1b3J1bQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFFWtleVZvdGluZ1RocmVzaG9sZEFkZAkBB3dyYXBFcnIBAhp2b3RpbmdUaHJlc2hvbGRBZGQgbm90IHNldAQKdm90aW5nSW5mbwkBD3ZvdGluZ0luZm9WYWx1ZQoFDWlzUmV3YXJkRXhpc3QFDXJld2FyZEFzc2V0SWQFDHJld2FyZEFtb3VudAIMdmVyaWZpY2F0aW9uBRBzdGF0dXNJblByb2dyZXNzBQZoZWlnaHQJAGQCBQZoZWlnaHQFDHBlcmlvZExlbmd0aAULdm90ZXNRdW9ydW0AAAAABBhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFG2tleUZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAQMYnVybld4QW1vdW50CQBlAgUPd3hQYXltZW50QW1vdW50BRhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPY3VycmVudEluZGV4S2V5BQhuZXdJbmRleAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFCG5ld0luZGV4CQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFCG5ld0luZGV4BQp2b3RpbmdJbmZvCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1rZXlBc3NldEltYWdlAQUHYXNzZXRJZAUKYXNzZXRJbWFnZQkAzAgCCQEEQnVybgIFEHd4UGF5bWVudEFzc2V0SWQFDGJ1cm5XeEFtb3VudAUDbmlsBRN2b3RpbmdSZXdhcmRBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN1Z2dlc3RSZW1vdmUBB2Fzc2V0SWQEDmd3eEFtb3VudEF0Tm93CQEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgkApQgBCAUBaQZjYWxsZXIFBmhlaWdodAQXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UJARFAZXh0ck5hdGl2ZSgxMDU1KQEFGmtleU1pblN1Z2dlc3RSZW1vdmVCYWxhbmNlBAl3eFBheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQQd3hQYXltZW50QXNzZXRJZAkBBXZhbHVlAQgFCXd4UGF5bWVudAdhc3NldElkBA93eFBheW1lbnRBbW91bnQJAQV2YWx1ZQEIBQl3eFBheW1lbnQGYW1vdW50BA90b2tlbklzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQUBQAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQGY2hlY2tzCQDMCAIDBQ90b2tlbklzVmVyaWZpZWQGCQEIdGhyb3dFcnIBAhJ0b2tlbiBub3QgdmVyaWZpZWQJAMwIAgMJAGcCBQ5nd3hBbW91bnRBdE5vdwUXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UGCQEIdGhyb3dFcnIBAhBub3QgZW5vdWdoIGdXWGVzCQDMCAIDCQBnAgUPd3hQYXltZW50QW1vdW50CQERQGV4dHJOYXRpdmUoMTA1NSkBBSNrZXlXeEZvclN1Z2dlc3RSZW1vdmVBbW91bnRSZXF1aXJlZAYJAQh0aHJvd0VycgECIXBheW1lbnQgbGVzcyB0aGVuIG1pbiBmb3Igc3VnZ2VzdAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA9jdXJyZW50SW5kZXhLZXkJAQ9rZXlDdXJyZW50SW5kZXgBBQdhc3NldElkBAxjdXJyZW50SW5kZXgJAJ8IAQUPY3VycmVudEluZGV4S2V5BAhuZXdJbmRleAMJAQlpc0RlZmluZWQBBQxjdXJyZW50SW5kZXgJAGQCCQEFdmFsdWUBBQxjdXJyZW50SW5kZXgAAQAABAxwZXJpb2RMZW5ndGgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRVrZXlQZXJpb2RMZW5ndGhSZW1vdmUJAQd3cmFwRXJyAQIacGVyaW9kTGVuZ3RoUmVtb3ZlIG5vdCBzZXQED3ZvdGluZ0VuZEhlaWdodAkAZAIFBmhlaWdodAUMcGVyaW9kTGVuZ3RoBAt2b3Rlc1F1b3J1bQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFGGtleVZvdGluZ1RocmVzaG9sZFJlbW92ZQkBB3dyYXBFcnIBAh12b3RpbmdUaHJlc2hvbGRSZW1vdmUgbm90IHNldAQKdm90aW5nSW5mbwkBD3ZvdGluZ0luZm9WYWx1ZQoHAgVFTVBUWQAAAg5kZXZlcmlmaWNhdGlvbgUQc3RhdHVzSW5Qcm9ncmVzcwUGaGVpZ2h0CQBkAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgFC3ZvdGVzUXVvcnVtAAAAAAQTc2V0QXNzZXRJbWFnZUFjdGlvbgQHJG1hdGNoMAkAoggBCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQNuaWwDCQABAgUHJG1hdGNoMAIEVW5pdAQVYXNzZXRzU3RvcmVBc3NldEltYWdlCgABQAkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0AhRnZXRBc3NldExvZ29SRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleUFzc2V0SW1hZ2UBBQdhc3NldElkBRVhc3NldHNTdG9yZUFzc2V0SW1hZ2UFA25pbAkAAgECC01hdGNoIGVycm9yCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFD2N1cnJlbnRJbmRleEtleQUIbmV3SW5kZXgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVN1Z2dlc3RJc3N1ZXICBQdhc3NldElkBQhuZXdJbmRleAkApQgBCAUBaQZjYWxsZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQhuZXdJbmRleAUKdm90aW5nSW5mbwUDbmlsBRNzZXRBc3NldEltYWdlQWN0aW9uCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBHZvdGUCB2Fzc2V0SWQHaW5GYXZvcgQPY3VycmVudEluZGV4S2V5CQEPa2V5Q3VycmVudEluZGV4AQUHYXNzZXRJZAQMY3VycmVudEluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUPY3VycmVudEluZGV4S2V5CQEHd3JhcEVycgECFXZvdGluZyBkb2VzIG5vdCBleGlzdAQKdm90aW5nSW5mbwkBEXZvdGluZ0V4aXN0Q2hlY2tzAgUHYXNzZXRJZAUMY3VycmVudEluZGV4AwkAAAIFCnZvdGluZ0luZm8FCnZvdGluZ0luZm8EFmN1cnJlbnRWb3RpbmdFbmRIZWlnaHQIBQp2b3RpbmdJbmZvAl8yBA5nd3hBbW91bnRBdEVuZAkBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAIJAKUIAQgFAWkGY2FsbGVyBRZjdXJyZW50Vm90aW5nRW5kSGVpZ2h0BAd2b3RlS2V5CQEHa2V5Vm90ZQMFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAgFAWkGY2FsbGVyBAZjaGVja3MJAMwIAgMJAAACCQCiCAEFB3ZvdGVLZXkFBHVuaXQGCQEIdGhyb3dFcnIBAhZZb3UgaGF2ZSBhbHJlYWR5IHZvdGVkCQDMCAIDCQBmAgUOZ3d4QW1vdW50QXRFbmQAAAYJAAIBAihZb3UnbGwgbm90IGhhdmUgZ1dYIGF0IHRoZSBlbmQgb2Ygdm90aW5nBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDXZvdGluZ0luZm9TdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQED3ZvdGluZ0luZm9QYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIECHZvdGVzRm9yCAUPdm90aW5nSW5mb1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQ92b3RpbmdJbmZvUGFydHMDXzEwBA0kdDAxMzU2MzEzNzI0AwUHaW5GYXZvcgkAlAoCCQBkAgUIdm90ZXNGb3IFDmd3eEFtb3VudEF0RW5kBQx2b3Rlc0FnYWluc3QJAJQKAgUIdm90ZXNGb3IJAGQCBQx2b3Rlc0FnYWluc3QFDmd3eEFtb3VudEF0RW5kBAtuZXdWb3Rlc0ZvcggFDSR0MDEzNTYzMTM3MjQCXzEED25ld1ZvdGVzQWdhaW5zdAgFDSR0MDEzNTYzMTM3MjQCXzIEEm5ld1ZvdGluZ0luZm9WYWx1ZQkBD3ZvdGluZ0luZm9WYWx1ZQoIBQ92b3RpbmdJbmZvUGFydHMCXzEIBQ92b3RpbmdJbmZvUGFydHMCXzIIBQ92b3RpbmdJbmZvUGFydHMCXzMIBQ92b3RpbmdJbmZvUGFydHMCXzQIBQ92b3RpbmdJbmZvUGFydHMCXzUIBQ92b3RpbmdJbmZvUGFydHMCXzYIBQ92b3RpbmdJbmZvUGFydHMCXzcIBQ92b3RpbmdJbmZvUGFydHMCXzgFC25ld1ZvdGVzRm9yBQ9uZXdWb3Rlc0FnYWluc3QEEnZvdGluZ1Jld2FyZEFjdGlvbgQHJG1hdGNoMAkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAnBrBQckbWF0Y2gwCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlWb3RpbmdSZXdhcmQDCAUBaQZjYWxsZXIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBCXZvdGVWYWx1ZQIFB2luRmF2b3IFDmd3eEFtb3VudEF0RW5kBQNuaWwDCQABAgUHJG1hdGNoMAIEVW5pdAUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQd2b3RlS2V5CQEJdm90ZVZhbHVlAgUHaW5GYXZvcgUOZ3d4QW1vdW50QXRFbmQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgFEm5ld1ZvdGluZ0luZm9WYWx1ZQUDbmlsBRJ2b3RpbmdSZXdhcmRBY3Rpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKY2FuY2VsVm90ZQEHYXNzZXRJZAQPY3VycmVudEluZGV4S2V5CQEPa2V5Q3VycmVudEluZGV4AQUHYXNzZXRJZAQMY3VycmVudEluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUPY3VycmVudEluZGV4S2V5CQEHd3JhcEVycgECFXZvdGluZyBkb2VzIG5vdCBleGlzdAQHdm90ZUtleQkBB2tleVZvdGUDBQdhc3NldElkBQxjdXJyZW50SW5kZXgIBQFpBmNhbGxlcgQIbGFzdFZvdGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBBQd2b3RlS2V5CQEHd3JhcEVycgECEnlvdSBoYXZlIG5vdCB2b3RlZAQNbGFzdFZvdGVQYXJ0cwkAtQkCBQhsYXN0Vm90ZQUJc2VwYXJhdG9yBAdpbkZhdm9yCQCRAwIFDWxhc3RWb3RlUGFydHMAAQQJZ3d4QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNbGFzdFZvdGVQYXJ0cwACBAp2b3RpbmdJbmZvCQERdm90aW5nRXhpc3RDaGVja3MCBQdhc3NldElkBQxjdXJyZW50SW5kZXgDCQAAAgUKdm90aW5nSW5mbwUKdm90aW5nSW5mbwQGY2hlY2tzCQDMCAIDAwkAAAIFB2luRmF2b3ICBHRydWUGCQAAAgUHaW5GYXZvcgIFZmFsc2UGCQEIdGhyb3dFcnIBAgxpbnZhbGlkIHZvdGUFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEHd3JhcEVycgECFXZvdGluZyBpbmZvIG5vdCBmb3VuZAQPdm90aW5nSW5mb1BhcnRzCQESZ2V0Vm90aW5nSW5mb1BhcnRzAQUNdm90aW5nSW5mb1N0cgQIdm90ZXNGb3IIBQ92b3RpbmdJbmZvUGFydHMCXzkEDHZvdGVzQWdhaW5zdAgFD3ZvdGluZ0luZm9QYXJ0cwNfMTAEDSR0MDE1MzQ5MTU1MTADCQAAAgUHaW5GYXZvcgIEdHJ1ZQkAlAoCCQBlAgUIdm90ZXNGb3IFCWd3eEFtb3VudAUMdm90ZXNBZ2FpbnN0CQCUCgIFCHZvdGVzRm9yCQBlAgUMdm90ZXNBZ2FpbnN0BQlnd3hBbW91bnQEC25ld1ZvdGVzRm9yCAUNJHQwMTUzNDkxNTUxMAJfMQQPbmV3Vm90ZXNBZ2FpbnN0CAUNJHQwMTUzNDkxNTUxMAJfMgQSbmV3Vm90aW5nSW5mb1ZhbHVlCQEPdm90aW5nSW5mb1ZhbHVlCggFD3ZvdGluZ0luZm9QYXJ0cwJfMQgFD3ZvdGluZ0luZm9QYXJ0cwJfMggFD3ZvdGluZ0luZm9QYXJ0cwJfMwgFD3ZvdGluZ0luZm9QYXJ0cwJfNAgFD3ZvdGluZ0luZm9QYXJ0cwJfNQgFD3ZvdGluZ0luZm9QYXJ0cwJfNggFD3ZvdGluZ0luZm9QYXJ0cwJfNwgFD3ZvdGluZ0luZm9QYXJ0cwJfOAULbmV3Vm90ZXNGb3IFD25ld1ZvdGVzQWdhaW5zdAkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAUSbmV3Vm90aW5nSW5mb1ZhbHVlCQDMCAIJAQtEZWxldGVFbnRyeQEFB3ZvdGVLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBD2tleVZvdGluZ1Jld2FyZAMIBQFpBmNhbGxlcgUHYXNzZXRJZAUMY3VycmVudEluZGV4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIZmluYWxpemUBB2Fzc2V0SWQED2N1cnJlbnRJbmRleEtleQkBD2tleUN1cnJlbnRJbmRleAEFB2Fzc2V0SWQEDGN1cnJlbnRJbmRleAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9jdXJyZW50SW5kZXhLZXkAAAQSdm90aW5nVGhyZXNob2xkQWRkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUVa2V5Vm90aW5nVGhyZXNob2xkQWRkCQEHd3JhcEVycgECGnZvdGluZ1RocmVzaG9sZEFkZCBub3Qgc2V0BBV2b3RpbmdUaHJlc2hvbGRSZW1vdmUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRhrZXlWb3RpbmdUaHJlc2hvbGRSZW1vdmUJAQd3cmFwRXJyAQIddm90aW5nVGhyZXNob2xkUmVtb3ZlIG5vdCBzZXQEDXZvdGluZ0luZm9TdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQED3ZvdGluZ0luZm9QYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIECnZvdGluZ1R5cGUIBQ92b3RpbmdJbmZvUGFydHMCXzQEBnN0YXR1cwgFD3ZvdGluZ0luZm9QYXJ0cwJfNQQPdm90aW5nRW5kSGVpZ2h0CAUPdm90aW5nSW5mb1BhcnRzAl83BAx2b3RpbmdRdW9ydW0IBQ92b3RpbmdJbmZvUGFydHMCXzgECHZvdGVzRm9yCAUPdm90aW5nSW5mb1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQ92b3RpbmdJbmZvUGFydHMDXzEwBAZjaGVja3MJAMwIAgMJAAACBQZzdGF0dXMFEHN0YXR1c0luUHJvZ3Jlc3MGCQEIdGhyb3dFcnIBAhZ2b3Rpbmcgbm90IGluIHByb2dyZXNzCQDMCAIDCQBnAgUGaGVpZ2h0BQ92b3RpbmdFbmRIZWlnaHQGCQEIdGhyb3dFcnIBAhN2b3Rpbmcgbm90IGZpbmlzaGVkCQDMCAIDCQEJaXNEZWZpbmVkAQkAoggBCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQGCQEIdGhyb3dFcnIBAhNhc3NldCBpbWFnZSBub3Qgc2V0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDnZvdGluZ0FjY2VwdGVkAwMJAGcCCQBkAgUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAUMdm90aW5nUXVvcnVtCQBmAgUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAcGBwQJbmV3U3RhdHVzAwUOdm90aW5nQWNjZXB0ZWQFDnN0YXR1c0FjY2VwdGVkBQ5zdGF0dXNSZWplY3RlZAQKYXNzZXRJbWFnZQkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDWtleUFzc2V0SW1hZ2UBBQdhc3NldElkBBBpc1ZvdGluZ0FjY2VwdGVkAwUOdm90aW5nQWNjZXB0ZWQEFXZvdGluZ0FjY2VwdGVkSW52b2tlcwMJAAACBQp2b3RpbmdUeXBlAgx2ZXJpZmljYXRpb24JAPwHBAUTYXNzZXRzU3RvcmVDb250cmFjdAIOY3JlYXRlT3JVcGRhdGUJAMwIAgUHYXNzZXRJZAkAzAgCBQphc3NldEltYWdlCQDMCAIGBQNuaWwFA25pbAkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0AgtzZXRWZXJpZmllZAkAzAgCBQdhc3NldElkCQDMCAIHBQNuaWwFA25pbAUVdm90aW5nQWNjZXB0ZWRJbnZva2VzBQNuaWwDCQAAAgUQaXNWb3RpbmdBY2NlcHRlZAUQaXNWb3RpbmdBY2NlcHRlZAQSbmV3Vm90aW5nSW5mb1ZhbHVlCQEPdm90aW5nSW5mb1ZhbHVlCggFD3ZvdGluZ0luZm9QYXJ0cwJfMQgFD3ZvdGluZ0luZm9QYXJ0cwJfMggFD3ZvdGluZ0luZm9QYXJ0cwJfMwgFD3ZvdGluZ0luZm9QYXJ0cwJfNAUJbmV3U3RhdHVzCAUPdm90aW5nSW5mb1BhcnRzAl82CAUPdm90aW5nSW5mb1BhcnRzAl83CAUPdm90aW5nSW5mb1BhcnRzAl84CAUPdm90aW5nSW5mb1BhcnRzAl85CAUPdm90aW5nSW5mb1BhcnRzA18xMAQYZmluYWxpemVDYWxsUmV3YXJkQW1vdW50CQERQGV4dHJOYXRpdmUoMTA1NSkBBRtrZXlGaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQEFHN1Z2dlc3RJc3N1ZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAQZdm90aW5nUmV3YXJkQXNzZXRJZE9wdGlvbgkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAQXdG90YWxWb3RpbmdSZXdhcmRPcHRpb24JAJ8IAQkBFGtleVRvdGFsVm90aW5nUmV3YXJkAgUHYXNzZXRJZAUMY3VycmVudEluZGV4BBNyZXR1cm5SZXdhcmRBY3Rpb25zAwMDBQ52b3RpbmdBY2NlcHRlZAYJAAACBRl2b3RpbmdSZXdhcmRBc3NldElkT3B0aW9uBQR1bml0BgkAAAIFF3RvdGFsVm90aW5nUmV3YXJkT3B0aW9uBQR1bml0BQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUUc3VnZ2VzdElzc3VlckFkZHJlc3MJAQV2YWx1ZQEFF3RvdGFsVm90aW5nUmV3YXJkT3B0aW9uCQEMcGFyc2VBc3NldElkAQkBBXZhbHVlAQUZdm90aW5nUmV3YXJkQXNzZXRJZE9wdGlvbgUDbmlsCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgFEm5ld1ZvdGluZ0luZm9WYWx1ZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFGGZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAUJd3hBc3NldElkBQNuaWwFE3JldHVyblJld2FyZEFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENY2xhaW1SRUFET05MWQMHYXNzZXRJZAVpbmRleA51c2VyQWRkcmVzc1N0cgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgkBB3dyYXBFcnIBAg9pbnZhbGlkIGFkZHJlc3MEFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIJAKIIAQkBFmtleVZvdGluZ1Jld2FyZEFzc2V0SWQCBQdhc3NldElkBQVpbmRleAQMcmV3YXJkQW1vdW50AwkBCWlzRGVmaW5lZAEFFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIICQEPY2FsY3VsYXRlUmV3YXJkAwULdXNlckFkZHJlc3MFB2Fzc2V0SWQFBWluZGV4Al8xAAAJAJQKAgUDbmlsBQxyZXdhcmRBbW91bnQBaQEFY2xhaW0CB2Fzc2V0SWQFaW5kZXgEDWNhbGxlckFkZHJlc3MIBQFpBmNhbGxlcgQPY2xhaW1IaXN0b3J5S2V5CQEPa2V5Q2xhaW1IaXN0b3J5AwUNY2FsbGVyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgEDGNsYWltSGlzdG9yeQkAnwgBBQ9jbGFpbUhpc3RvcnlLZXkEBmNoZWNrcwkAzAgCAwkAAAIFDGNsYWltSGlzdG9yeQUEdW5pdAYJAQh0aHJvd0VycgECD2FscmVhZHkgY2xhaW1lZAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA0kdDAxOTUxNjE5NTkzCQEPY2FsY3VsYXRlUmV3YXJkAwUNY2FsbGVyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgEDHJld2FyZEFtb3VudAgFDSR0MDE5NTE2MTk1OTMCXzEECGNhbkNsYWltCAUNJHQwMTk1MTYxOTU5MwJfMgMJAQEhAQUIY2FuQ2xhaW0JAQh0aHJvd0VycgECEG5vdGhpbmcgdG8gY2xhaW0EFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIJAKIIAQkBFmtleVZvdGluZ1Jld2FyZEFzc2V0SWQCBQdhc3NldElkBQVpbmRleAQMcmV3YXJkQWN0aW9uAwkBCWlzRGVmaW5lZAEFFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIEE3ZvdGluZ1Jld2FyZEFzc2V0SWQJANkEAQkBBXZhbHVlAQUWdm90aW5nUmV3YXJkQXNzZXRJZFN0cgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ1jYWxsZXJBZGRyZXNzBQxyZXdhcmRBbW91bnQFE3ZvdGluZ1Jld2FyZEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIFD2NsYWltSGlzdG9yeUtleQUMcmV3YXJkQW1vdW50CQDMCAIJAQtEZWxldGVFbnRyeQEJAQ9rZXlWb3RpbmdSZXdhcmQDBQ1jYWxsZXJBZGRyZXNzBQdhc3NldElkBQVpbmRleAUDbmlsCQEIdGhyb3dFcnIBAhBub3RoaW5nIHRvIGNsYWltBQxyZXdhcmRBY3Rpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXl5AB8a", "height": 2800981, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5D7QNGD8KMTn2YpYQXCsmKEKgdxrpZMNfdvNsRzs6oHy Next: AD1yy84NgB3UNpyKryCJTDD6pqGyKCm22BovMbXr8F5j Diff:
OldNewDifferences
44 let separator = "__"
55
66 let MULT8 = 100000000
7+
8+let wavesString = "WAVES"
9+
10+let statusInProgress = "inProgress"
11+
12+let statusAccepted = "accepted"
13+
14+let statusRejected = "rejected"
715
816 func wrapErr (msg) = makeString(["voting_verified_v2.ride:", msg], " ")
917
1725 case _ =>
1826 throw("Failed to cast into Integer")
1927 }
28+
29+
30+func parseAssetId (input) = if ((input == wavesString))
31+ then unit
32+ else fromBase58String(input)
33+
34+
35+func assetIdToString (input) = if ((input == unit))
36+ then wavesString
37+ else toBase58String(value(input))
2038
2139
2240 func getIntegerOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
162180 let status = votingInfoArray[5]
163181 let votingEndHeight = valueOrErrorMessage(parseIntValue(votingInfoArray[7]), wrapErr("voting start height not found"))
164182 let suggestIssuer = valueOrErrorMessage(getString(keySuggestIssuer(assetId, currentIndex)), wrapErr("voting issuer not found"))
165- let checks = [if ((status == "inProgress"))
183+ let checks = [if ((status == statusInProgress))
166184 then true
167185 else throwErr("no voting in progress"), if ((votingEndHeight > height))
168186 then true
180198 let gwxAmount = parseIntValue(lastVoteParts[2])
181199 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, index)), wrapErr("voting info not found"))
182200 let votingParts = getVotingInfoParts(votingInfoStr)
201+ let status = votingParts._5
183202 let votesFor = votingParts._9
184203 let votesAgainst = votingParts._10
185204 let partOfTheTotalVotesX8 = fraction(gwxAmount, MULT8, (votesFor + votesAgainst))
186205 let totalVotingReward = valueOrElse(getInteger(keyTotalVotingReward(assetId, index)), 0)
187206 let voterRewardAmount = fraction(partOfTheTotalVotesX8, totalVotingReward, MULT8, FLOOR)
188- voterRewardAmount
207+ let canClaim = if ((status == statusAccepted))
208+ then (voterRewardAmount > 0)
209+ else false
210+ $Tuple2(voterRewardAmount, canClaim)
189211 }
190212
191213
220242 let newIndex = if (isDefined(currentIndex))
221243 then (value(currentIndex) + 1)
222244 else 0
223- let $t087859425 = if ((size(i.payments) > 1))
245+ let $t092599899 = if ((size(i.payments) > 1))
224246 then {
225247 let votingRewardPayment = i.payments[1]
226248 let votingRewardPaymentAssetId = toBase58String(value(votingRewardPayment.assetId))
228250 $Tuple4(true, votingRewardPaymentAssetId, votingRewardPaymentAmount, [StringEntry(keyVotingRewardAssetId(assetId, newIndex), votingRewardPaymentAssetId), IntegerEntry(keyTotalVotingReward(assetId, newIndex), votingRewardPaymentAmount)])
229251 }
230252 else $Tuple4(false, "EMPTY", 0, nil)
231- let isRewardExist = $t087859425._1
232- let rewardAssetId = $t087859425._2
233- let rewardAmount = $t087859425._3
234- let votingRewardActions = $t087859425._4
253+ let isRewardExist = $t092599899._1
254+ let rewardAssetId = $t092599899._2
255+ let rewardAmount = $t092599899._3
256+ let votingRewardActions = $t092599899._4
235257 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
236- let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", "inProgress", height, (height + periodLength), votesQuorum, 0, 0)
258+ let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
237259 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
238260 let burnWxAmount = (wxPaymentAmount - finalizeCallRewardAmount)
239261 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo), StringEntry(keyAssetImage(assetId), assetImage), Burn(wxPaymentAssetId, burnWxAmount)] ++ votingRewardActions)
273295 let periodLength = valueOrErrorMessage(getInteger(keyPeriodLengthRemove), wrapErr("periodLengthRemove not set"))
274296 let votingEndHeight = (height + periodLength)
275297 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
276- let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", "inProgress", height, (height + periodLength), votesQuorum, 0, 0)
298+ let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
277299 let setAssetImageAction = match getString(keyAssetImage(assetId)) {
278300 case s: String =>
279301 nil
316338 let votingInfoParts = getVotingInfoParts(votingInfoStr)
317339 let votesFor = votingInfoParts._9
318340 let votesAgainst = votingInfoParts._10
319- let $t01308113242 = if (inFavor)
341+ let $t01356313724 = if (inFavor)
320342 then $Tuple2((votesFor + gwxAmountAtEnd), votesAgainst)
321343 else $Tuple2(votesFor, (votesAgainst + gwxAmountAtEnd))
322- let newVotesFor = $t01308113242._1
323- let newVotesAgainst = $t01308113242._2
344+ let newVotesFor = $t01356313724._1
345+ let newVotesAgainst = $t01356313724._2
324346 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
325347 let votingRewardAction = match getString(keyVotingRewardAssetId(assetId, currentIndex)) {
326348 case pk: String =>
362384 let votingInfoParts = getVotingInfoParts(votingInfoStr)
363385 let votesFor = votingInfoParts._9
364386 let votesAgainst = votingInfoParts._10
365- let $t01486715028 = if ((inFavor == "true"))
387+ let $t01534915510 = if ((inFavor == "true"))
366388 then $Tuple2((votesFor - gwxAmount), votesAgainst)
367389 else $Tuple2(votesFor, (votesAgainst - gwxAmount))
368- let newVotesFor = $t01486715028._1
369- let newVotesAgainst = $t01486715028._2
390+ let newVotesFor = $t01534915510._1
391+ let newVotesAgainst = $t01534915510._2
370392 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
371393 [StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), DeleteEntry(voteKey), DeleteEntry(keyVotingReward(i.caller, assetId, currentIndex))]
372394 }
391413 let votingQuorum = votingInfoParts._8
392414 let votesFor = votingInfoParts._9
393415 let votesAgainst = votingInfoParts._10
394- let checks = [if ((status == "inProgress"))
416+ let checks = [if ((status == statusInProgress))
395417 then true
396418 else throwErr("voting not in progress"), if ((height >= votingEndHeight))
397419 then true
406428 then true
407429 else false
408430 let newStatus = if (votingAccepted)
409- then "accepted"
410- else "rejected"
431+ then statusAccepted
432+ else statusRejected
411433 let assetImage = getStringValue(keyAssetImage(assetId))
412434 let isVotingAccepted = if (votingAccepted)
413435 then {
421443 then {
422444 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, newStatus, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, votingInfoParts._9, votingInfoParts._10)
423445 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
424-[StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)]
446+ let suggestIssuerAddress = addressFromStringValue(getStringValue(keySuggestIssuer(assetId, currentIndex)))
447+ let votingRewardAssetIdOption = getString(keyVotingRewardAssetId(assetId, currentIndex))
448+ let totalVotingRewardOption = getInteger(keyTotalVotingReward(assetId, currentIndex))
449+ let returnRewardActions = if (if (if (votingAccepted)
450+ then true
451+ else (votingRewardAssetIdOption == unit))
452+ then true
453+ else (totalVotingRewardOption == unit))
454+ then nil
455+ else [ScriptTransfer(suggestIssuerAddress, value(totalVotingRewardOption), parseAssetId(value(votingRewardAssetIdOption)))]
456+ ([StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)] ++ returnRewardActions)
425457 }
426458 else throw("Strict value is not equal to itself.")
427459 }
435467 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid address"))
436468 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
437469 let rewardAmount = if (isDefined(votingRewardAssetIdStr))
438- then calculateReward(userAddress, assetId, index)
470+ then calculateReward(userAddress, assetId, index)._1
439471 else 0
440472 $Tuple2(nil, rewardAmount)
441473 }
452484 else throwErr("already claimed")]
453485 if ((checks == checks))
454486 then {
455- let rewardAmount = if ((calculateReward(callerAddress, assetId, index) > 0))
456- then calculateReward(callerAddress, assetId, index)
457- else throwErr("nothing to claim")
458- let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
459- let rewardAction = if (isDefined(votingRewardAssetIdStr))
460- then {
461- let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
487+ let $t01951619593 = calculateReward(callerAddress, assetId, index)
488+ let rewardAmount = $t01951619593._1
489+ let canClaim = $t01951619593._2
490+ if (!(canClaim))
491+ then throwErr("nothing to claim")
492+ else {
493+ let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
494+ let rewardAction = if (isDefined(votingRewardAssetIdStr))
495+ then {
496+ let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
462497 [ScriptTransfer(callerAddress, rewardAmount, votingRewardAssetId), IntegerEntry(claimHistoryKey, rewardAmount), DeleteEntry(keyVotingReward(callerAddress, assetId, index))]
498+ }
499+ else throwErr("nothing to claim")
500+ rewardAction
463501 }
464- else throwErr("nothing to claim")
465- rewardAction
466502 }
467503 else throw("Strict value is not equal to itself.")
468504 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let MULT8 = 100000000
7+
8+let wavesString = "WAVES"
9+
10+let statusInProgress = "inProgress"
11+
12+let statusAccepted = "accepted"
13+
14+let statusRejected = "rejected"
715
816 func wrapErr (msg) = makeString(["voting_verified_v2.ride:", msg], " ")
917
1018
1119 func throwErr (msg) = throw(wrapErr(msg))
1220
1321
1422 func asInt (val) = match val {
1523 case valInt: Int =>
1624 valInt
1725 case _ =>
1826 throw("Failed to cast into Integer")
1927 }
28+
29+
30+func parseAssetId (input) = if ((input == wavesString))
31+ then unit
32+ else fromBase58String(input)
33+
34+
35+func assetIdToString (input) = if ((input == unit))
36+ then wavesString
37+ else toBase58String(value(input))
2038
2139
2240 func getIntegerOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
2341
2442
2543 func getIntegerOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((key + " is not defined")))
2644
2745
2846 func getStringOrEmpty (address,key) = valueOrElse(getString(address, key), "")
2947
3048
3149 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((key + " is not defined")))
3250
3351
3452 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3553
3654 let keyEmissionContract = makeString(["%s", "emissionContract"], separator)
3755
3856 let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
3957
4058 let boostingContract = addressFromStringValue(getStringValue(keyBoostingContract))
4159
4260 let emissionContract = addressFromStringValue(getStringValue(keyEmissionContract))
4361
4462 let assetsStoreContract = addressFromStringValue(getStringValue(keyAssetsStoreContract))
4563
4664 let keyEmissionConfig = makeString(["%s", "config"], separator)
4765
4866 let wxAssetIdStr = split(getStringOrFail(emissionContract, keyEmissionConfig), separator)[1]
4967
5068 let wxAssetId = fromBase58String(wxAssetIdStr)
5169
5270 let keyVotingThresholdAdd = makeString(["%s%s", "votingThreshold", "add"], separator)
5371
5472 let keyVotingThresholdRemove = makeString(["%s%s", "votingThreshold", "remove"], separator)
5573
5674 let keyPeriodLengthRemove = makeString(["%s", "periodLengthRemove"], separator)
5775
5876 let keyMaxPeriodLength = makeString(["%s", "maxPeriodLength"], separator)
5977
6078 let keyMinPeriodLength = makeString(["%s", "minPeriodLength"], separator)
6179
6280 func keyVotingRewardAssetId (assetId,index) = makeString(["%s%s%d", "votingRewardAssetId", assetId, toString(index)], separator)
6381
6482
6583 func keyVotingReward (userAddress,assetId,index) = makeString(["%s%s%s%d", "votingReward", toString(userAddress), assetId, toString(index)], separator)
6684
6785
6886 func keyTotalVotingReward (assetId,index) = makeString(["%s%s%d", "totalVotingReward", assetId, toString(index)], separator)
6987
7088
7189 let keyFinalizeCallRewardAmount = makeString(["%s", "finalizeCallRewardAmount"], separator)
7290
7391 let keyMinSuggestRemoveBalance = makeString(["%s", "minSuggestRemoveBalance"], separator)
7492
7593 func keyCurrentIndex (assetId) = makeString(["%s%s", "currentIndex", assetId], separator)
7694
7795
7896 func keyVote (assetId,index,caller) = makeString(["%s%s%d%s", "vote", assetId, toString(index), toString(caller)], separator)
7997
8098
8199 func voteValue (inFavor,gwxAmount) = makeString(["%s%d", toString(inFavor), toString(gwxAmount)], separator)
82100
83101
84102 func keySuggestIssuer (assetId,index) = makeString(["%s%s%d", "suggestIssuer", assetId, toString(index)], separator)
85103
86104
87105 func keyClaimHistory (userAddress,assetId,index) = makeString(["%s%s%s%d", "history", toString(userAddress), assetId, toString(index)], separator)
88106
89107
90108 let keyFeePerBlock = makeString(["%s", "feePerBlock"], separator)
91109
92110 let feePerBlock = getIntegerOrFail(this, keyFeePerBlock)
93111
94112 let keyMinWxMinForSuggestAddAmountRequired = makeString(["%s", "wxMinForSuggestAddAmountRequired"], separator)
95113
96114 let keyWxForSuggestRemoveAmountRequired = makeString(["%s", "wxForSuggestRemoveAmountRequired"], separator)
97115
98116 func keyVotingInfo (assetId,index) = makeString(["%s%s%d", "votingInfo", assetId, toString(index)], separator)
99117
100118
101119 func votingInfoValue (isRewardExist,rewardAssetId,rewardAmount,votingType,status,votingStartHeight,votingEndHeight,votesQuorum,votesFor,votesAgainst) = makeString(["%s%s%d%s%s%d%d%d%d%d", toString(isRewardExist), rewardAssetId, toString(rewardAmount), votingType, status, toString(votingStartHeight), toString(votingEndHeight), toString(votesQuorum), toString(votesFor), toString(votesAgainst)], separator)
102120
103121
104122 func keyAssetImage (assetId) = makeString(["%s%s", "assetImage", assetId], separator)
105123
106124
107125 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
108126 let gwxAmount = invoke(boostingContract, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
109127 asInt(gwxAmount)
110128 }
111129
112130
113131 func keyManagerVaultAddress () = "%s__managerVaultAddress"
114132
115133
116134 func keyManagerPublicKey () = "%s__managerPublicKey"
117135
118136
119137 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
120138 case s: String =>
121139 addressFromStringValue(s)
122140 case _ =>
123141 this
124142 }
125143
126144
127145 func managerPublicKeyOrUnit () = {
128146 let managerVaultAddress = getManagerVaultAddressOrThis()
129147 match getString(managerVaultAddress, keyManagerPublicKey()) {
130148 case s: String =>
131149 fromBase58String(s)
132150 case _: Unit =>
133151 unit
134152 case _ =>
135153 throw("Match error")
136154 }
137155 }
138156
139157
140158 func getVotingInfoParts (votingInfo) = {
141159 let votingInfoParts = split(votingInfo, separator)
142160 let isRewardExistStr = votingInfoParts[1]
143161 let isRewardExist = if ((isRewardExistStr == "true"))
144162 then true
145163 else false
146164 let rewardAssetId = votingInfoParts[2]
147165 let rewardAmount = parseIntValue(votingInfoParts[3])
148166 let votingType = votingInfoParts[4]
149167 let status = votingInfoParts[5]
150168 let votingStartHeight = parseIntValue(votingInfoParts[6])
151169 let votingEndHeight = parseIntValue(votingInfoParts[7])
152170 let votesQuorum = parseIntValue(votingInfoParts[8])
153171 let votesFor = parseIntValue(votingInfoParts[9])
154172 let votesAgainst = parseIntValue(votingInfoParts[10])
155173 $Tuple10(isRewardExist, rewardAssetId, rewardAmount, votingType, status, votingStartHeight, votingEndHeight, votesQuorum, votesFor, votesAgainst)
156174 }
157175
158176
159177 func votingExistChecks (assetId,currentIndex) = {
160178 let votingInfo = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
161179 let votingInfoArray = split(votingInfo, separator)
162180 let status = votingInfoArray[5]
163181 let votingEndHeight = valueOrErrorMessage(parseIntValue(votingInfoArray[7]), wrapErr("voting start height not found"))
164182 let suggestIssuer = valueOrErrorMessage(getString(keySuggestIssuer(assetId, currentIndex)), wrapErr("voting issuer not found"))
165- let checks = [if ((status == "inProgress"))
183+ let checks = [if ((status == statusInProgress))
166184 then true
167185 else throwErr("no voting in progress"), if ((votingEndHeight > height))
168186 then true
169187 else throwErr("voting expired")]
170188 if ((checks == checks))
171189 then $Tuple3(status, votingEndHeight, suggestIssuer)
172190 else throw("Strict value is not equal to itself.")
173191 }
174192
175193
176194 func calculateReward (voter,assetId,index) = {
177195 let voteKey = keyVote(assetId, index, voter)
178196 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
179197 let lastVoteParts = split(lastVote, separator)
180198 let gwxAmount = parseIntValue(lastVoteParts[2])
181199 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, index)), wrapErr("voting info not found"))
182200 let votingParts = getVotingInfoParts(votingInfoStr)
201+ let status = votingParts._5
183202 let votesFor = votingParts._9
184203 let votesAgainst = votingParts._10
185204 let partOfTheTotalVotesX8 = fraction(gwxAmount, MULT8, (votesFor + votesAgainst))
186205 let totalVotingReward = valueOrElse(getInteger(keyTotalVotingReward(assetId, index)), 0)
187206 let voterRewardAmount = fraction(partOfTheTotalVotesX8, totalVotingReward, MULT8, FLOOR)
188- voterRewardAmount
207+ let canClaim = if ((status == statusAccepted))
208+ then (voterRewardAmount > 0)
209+ else false
210+ $Tuple2(voterRewardAmount, canClaim)
189211 }
190212
191213
192214 @Callable(i)
193215 func suggestAdd (assetId,periodLength,assetImage) = {
194216 let wxPayment = i.payments[0]
195217 let wxPaymentAssetId = value(wxPayment.assetId)
196218 let wxPaymentAmount = value(wxPayment.amount)
197219 let minPeriodLength = getIntegerValue(keyMinPeriodLength)
198220 let maxPeriodLength = getIntegerValue(keyMaxPeriodLength)
199221 let tokenIsVerified = {
200222 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
201223 if ($isInstanceOf(@, "Boolean"))
202224 then @
203225 else throw(($getType(@) + " couldn't be cast to Boolean"))
204226 }
205227 let checks = [if (if ((periodLength >= minPeriodLength))
206228 then (maxPeriodLength >= periodLength)
207229 else false)
208230 then true
209231 else throwErr("invalid periodLength"), if ((tokenIsVerified == false))
210232 then true
211233 else throwErr("token already verified"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
212234 then true
213235 else throwErr("not enough wx for given period"), if ((wxPaymentAmount >= getIntegerValue(keyMinWxMinForSuggestAddAmountRequired)))
214236 then true
215237 else throwErr("payment less then min for suggest")]
216238 if ((checks == checks))
217239 then {
218240 let currentIndexKey = keyCurrentIndex(assetId)
219241 let currentIndex = getInteger(currentIndexKey)
220242 let newIndex = if (isDefined(currentIndex))
221243 then (value(currentIndex) + 1)
222244 else 0
223- let $t087859425 = if ((size(i.payments) > 1))
245+ let $t092599899 = if ((size(i.payments) > 1))
224246 then {
225247 let votingRewardPayment = i.payments[1]
226248 let votingRewardPaymentAssetId = toBase58String(value(votingRewardPayment.assetId))
227249 let votingRewardPaymentAmount = value(votingRewardPayment.amount)
228250 $Tuple4(true, votingRewardPaymentAssetId, votingRewardPaymentAmount, [StringEntry(keyVotingRewardAssetId(assetId, newIndex), votingRewardPaymentAssetId), IntegerEntry(keyTotalVotingReward(assetId, newIndex), votingRewardPaymentAmount)])
229251 }
230252 else $Tuple4(false, "EMPTY", 0, nil)
231- let isRewardExist = $t087859425._1
232- let rewardAssetId = $t087859425._2
233- let rewardAmount = $t087859425._3
234- let votingRewardActions = $t087859425._4
253+ let isRewardExist = $t092599899._1
254+ let rewardAssetId = $t092599899._2
255+ let rewardAmount = $t092599899._3
256+ let votingRewardActions = $t092599899._4
235257 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
236- let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", "inProgress", height, (height + periodLength), votesQuorum, 0, 0)
258+ let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
237259 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
238260 let burnWxAmount = (wxPaymentAmount - finalizeCallRewardAmount)
239261 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo), StringEntry(keyAssetImage(assetId), assetImage), Burn(wxPaymentAssetId, burnWxAmount)] ++ votingRewardActions)
240262 }
241263 else throw("Strict value is not equal to itself.")
242264 }
243265
244266
245267
246268 @Callable(i)
247269 func suggestRemove (assetId) = {
248270 let gwxAmountAtNow = getUserGwxAmountAtHeight(toString(i.caller), height)
249271 let minSuggestRemoveBalance = getIntegerValue(keyMinSuggestRemoveBalance)
250272 let wxPayment = i.payments[0]
251273 let wxPaymentAssetId = value(wxPayment.assetId)
252274 let wxPaymentAmount = value(wxPayment.amount)
253275 let tokenIsVerified = {
254276 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
255277 if ($isInstanceOf(@, "Boolean"))
256278 then @
257279 else throw(($getType(@) + " couldn't be cast to Boolean"))
258280 }
259281 let checks = [if (tokenIsVerified)
260282 then true
261283 else throwErr("token not verified"), if ((gwxAmountAtNow >= minSuggestRemoveBalance))
262284 then true
263285 else throwErr("not enough gWXes"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
264286 then true
265287 else throwErr("payment less then min for suggest")]
266288 if ((checks == checks))
267289 then {
268290 let currentIndexKey = keyCurrentIndex(assetId)
269291 let currentIndex = getInteger(currentIndexKey)
270292 let newIndex = if (isDefined(currentIndex))
271293 then (value(currentIndex) + 1)
272294 else 0
273295 let periodLength = valueOrErrorMessage(getInteger(keyPeriodLengthRemove), wrapErr("periodLengthRemove not set"))
274296 let votingEndHeight = (height + periodLength)
275297 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
276- let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", "inProgress", height, (height + periodLength), votesQuorum, 0, 0)
298+ let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
277299 let setAssetImageAction = match getString(keyAssetImage(assetId)) {
278300 case s: String =>
279301 nil
280302 case _: Unit =>
281303 let assetsStoreAssetImage = {
282304 let @ = invoke(assetsStoreContract, "getAssetLogoREADONLY", [assetId], nil)
283305 if ($isInstanceOf(@, "String"))
284306 then @
285307 else throw(($getType(@) + " couldn't be cast to String"))
286308 }
287309 [StringEntry(keyAssetImage(assetId), assetsStoreAssetImage)]
288310 case _ =>
289311 throw("Match error")
290312 }
291313 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo)] ++ setAssetImageAction)
292314 }
293315 else throw("Strict value is not equal to itself.")
294316 }
295317
296318
297319
298320 @Callable(i)
299321 func vote (assetId,inFavor) = {
300322 let currentIndexKey = keyCurrentIndex(assetId)
301323 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
302324 let votingInfo = votingExistChecks(assetId, currentIndex)
303325 if ((votingInfo == votingInfo))
304326 then {
305327 let currentVotingEndHeight = votingInfo._2
306328 let gwxAmountAtEnd = getUserGwxAmountAtHeight(toString(i.caller), currentVotingEndHeight)
307329 let voteKey = keyVote(assetId, currentIndex, i.caller)
308330 let checks = [if ((getString(voteKey) == unit))
309331 then true
310332 else throwErr("You have already voted"), if ((gwxAmountAtEnd > 0))
311333 then true
312334 else throw("You'll not have gWX at the end of voting")]
313335 if ((checks == checks))
314336 then {
315337 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
316338 let votingInfoParts = getVotingInfoParts(votingInfoStr)
317339 let votesFor = votingInfoParts._9
318340 let votesAgainst = votingInfoParts._10
319- let $t01308113242 = if (inFavor)
341+ let $t01356313724 = if (inFavor)
320342 then $Tuple2((votesFor + gwxAmountAtEnd), votesAgainst)
321343 else $Tuple2(votesFor, (votesAgainst + gwxAmountAtEnd))
322- let newVotesFor = $t01308113242._1
323- let newVotesAgainst = $t01308113242._2
344+ let newVotesFor = $t01356313724._1
345+ let newVotesAgainst = $t01356313724._2
324346 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
325347 let votingRewardAction = match getString(keyVotingRewardAssetId(assetId, currentIndex)) {
326348 case pk: String =>
327349 [StringEntry(keyVotingReward(i.caller, assetId, currentIndex), voteValue(inFavor, gwxAmountAtEnd))]
328350 case _: Unit =>
329351 nil
330352 case _ =>
331353 throw("Match error")
332354 }
333355 ([StringEntry(voteKey, voteValue(inFavor, gwxAmountAtEnd)), StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue)] ++ votingRewardAction)
334356 }
335357 else throw("Strict value is not equal to itself.")
336358 }
337359 else throw("Strict value is not equal to itself.")
338360 }
339361
340362
341363
342364 @Callable(i)
343365 func cancelVote (assetId) = {
344366 let currentIndexKey = keyCurrentIndex(assetId)
345367 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
346368 let voteKey = keyVote(assetId, currentIndex, i.caller)
347369 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
348370 let lastVoteParts = split(lastVote, separator)
349371 let inFavor = lastVoteParts[1]
350372 let gwxAmount = parseIntValue(lastVoteParts[2])
351373 let votingInfo = votingExistChecks(assetId, currentIndex)
352374 if ((votingInfo == votingInfo))
353375 then {
354376 let checks = [if (if ((inFavor == "true"))
355377 then true
356378 else (inFavor == "false"))
357379 then true
358380 else throwErr("invalid vote")]
359381 if ((checks == checks))
360382 then {
361383 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
362384 let votingInfoParts = getVotingInfoParts(votingInfoStr)
363385 let votesFor = votingInfoParts._9
364386 let votesAgainst = votingInfoParts._10
365- let $t01486715028 = if ((inFavor == "true"))
387+ let $t01534915510 = if ((inFavor == "true"))
366388 then $Tuple2((votesFor - gwxAmount), votesAgainst)
367389 else $Tuple2(votesFor, (votesAgainst - gwxAmount))
368- let newVotesFor = $t01486715028._1
369- let newVotesAgainst = $t01486715028._2
390+ let newVotesFor = $t01534915510._1
391+ let newVotesAgainst = $t01534915510._2
370392 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
371393 [StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), DeleteEntry(voteKey), DeleteEntry(keyVotingReward(i.caller, assetId, currentIndex))]
372394 }
373395 else throw("Strict value is not equal to itself.")
374396 }
375397 else throw("Strict value is not equal to itself.")
376398 }
377399
378400
379401
380402 @Callable(i)
381403 func finalize (assetId) = {
382404 let currentIndexKey = keyCurrentIndex(assetId)
383405 let currentIndex = valueOrElse(getInteger(currentIndexKey), 0)
384406 let votingThresholdAdd = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
385407 let votingThresholdRemove = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
386408 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
387409 let votingInfoParts = getVotingInfoParts(votingInfoStr)
388410 let votingType = votingInfoParts._4
389411 let status = votingInfoParts._5
390412 let votingEndHeight = votingInfoParts._7
391413 let votingQuorum = votingInfoParts._8
392414 let votesFor = votingInfoParts._9
393415 let votesAgainst = votingInfoParts._10
394- let checks = [if ((status == "inProgress"))
416+ let checks = [if ((status == statusInProgress))
395417 then true
396418 else throwErr("voting not in progress"), if ((height >= votingEndHeight))
397419 then true
398420 else throwErr("voting not finished"), if (isDefined(getString(keyAssetImage(assetId))))
399421 then true
400422 else throwErr("asset image not set")]
401423 if ((checks == checks))
402424 then {
403425 let votingAccepted = if (if (((votesFor + votesAgainst) >= votingQuorum))
404426 then (votesFor > votesAgainst)
405427 else false)
406428 then true
407429 else false
408430 let newStatus = if (votingAccepted)
409- then "accepted"
410- else "rejected"
431+ then statusAccepted
432+ else statusRejected
411433 let assetImage = getStringValue(keyAssetImage(assetId))
412434 let isVotingAccepted = if (votingAccepted)
413435 then {
414436 let votingAcceptedInvokes = if ((votingType == "verification"))
415437 then invoke(assetsStoreContract, "createOrUpdate", [assetId, assetImage, true], nil)
416438 else invoke(assetsStoreContract, "setVerified", [assetId, false], nil)
417439 votingAcceptedInvokes
418440 }
419441 else nil
420442 if ((isVotingAccepted == isVotingAccepted))
421443 then {
422444 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, newStatus, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, votingInfoParts._9, votingInfoParts._10)
423445 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
424-[StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)]
446+ let suggestIssuerAddress = addressFromStringValue(getStringValue(keySuggestIssuer(assetId, currentIndex)))
447+ let votingRewardAssetIdOption = getString(keyVotingRewardAssetId(assetId, currentIndex))
448+ let totalVotingRewardOption = getInteger(keyTotalVotingReward(assetId, currentIndex))
449+ let returnRewardActions = if (if (if (votingAccepted)
450+ then true
451+ else (votingRewardAssetIdOption == unit))
452+ then true
453+ else (totalVotingRewardOption == unit))
454+ then nil
455+ else [ScriptTransfer(suggestIssuerAddress, value(totalVotingRewardOption), parseAssetId(value(votingRewardAssetIdOption)))]
456+ ([StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)] ++ returnRewardActions)
425457 }
426458 else throw("Strict value is not equal to itself.")
427459 }
428460 else throw("Strict value is not equal to itself.")
429461 }
430462
431463
432464
433465 @Callable(i)
434466 func claimREADONLY (assetId,index,userAddressStr) = {
435467 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid address"))
436468 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
437469 let rewardAmount = if (isDefined(votingRewardAssetIdStr))
438- then calculateReward(userAddress, assetId, index)
470+ then calculateReward(userAddress, assetId, index)._1
439471 else 0
440472 $Tuple2(nil, rewardAmount)
441473 }
442474
443475
444476
445477 @Callable(i)
446478 func claim (assetId,index) = {
447479 let callerAddress = i.caller
448480 let claimHistoryKey = keyClaimHistory(callerAddress, assetId, index)
449481 let claimHistory = getInteger(claimHistoryKey)
450482 let checks = [if ((claimHistory == unit))
451483 then true
452484 else throwErr("already claimed")]
453485 if ((checks == checks))
454486 then {
455- let rewardAmount = if ((calculateReward(callerAddress, assetId, index) > 0))
456- then calculateReward(callerAddress, assetId, index)
457- else throwErr("nothing to claim")
458- let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
459- let rewardAction = if (isDefined(votingRewardAssetIdStr))
460- then {
461- let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
487+ let $t01951619593 = calculateReward(callerAddress, assetId, index)
488+ let rewardAmount = $t01951619593._1
489+ let canClaim = $t01951619593._2
490+ if (!(canClaim))
491+ then throwErr("nothing to claim")
492+ else {
493+ let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
494+ let rewardAction = if (isDefined(votingRewardAssetIdStr))
495+ then {
496+ let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
462497 [ScriptTransfer(callerAddress, rewardAmount, votingRewardAssetId), IntegerEntry(claimHistoryKey, rewardAmount), DeleteEntry(keyVotingReward(callerAddress, assetId, index))]
498+ }
499+ else throwErr("nothing to claim")
500+ rewardAction
463501 }
464- else throwErr("nothing to claim")
465- rewardAction
466502 }
467503 else throw("Strict value is not equal to itself.")
468504 }
469505
470506
471507 @Verifier(tx)
472508 func verify () = {
473509 let targetPublicKey = match managerPublicKeyOrUnit() {
474510 case pk: ByteVector =>
475511 pk
476512 case _: Unit =>
477513 tx.senderPublicKey
478514 case _ =>
479515 throw("Match error")
480516 }
481517 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
482518 }
483519

github/deemru/w8io/3ef1775 
95.32 ms