tx · AD1yy84NgB3UNpyKryCJTDD6pqGyKCm22BovMbXr8F5j

3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE:  -0.02300000 Waves

2023.10.17 09:50 [2802280] smart account 3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE > SELF 0.00000000 Waves

{ "type": 13, "id": "AD1yy84NgB3UNpyKryCJTDD6pqGyKCm22BovMbXr8F5j", "fee": 2300000, "feeAssetId": null, "timestamp": 1697525446471, "version": 2, "chainId": 84, "sender": "3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE", "senderPublicKey": "6t3vrhP1jCmG7CeKBmL8hUibtdP3cMXGC2XtPYEPPC5w", "proofs": [ "5Zsw6b3GaJTvK5LWt5knqiJY97grqK4bf2RVS2aixxzKWNnpmG4mV2s5fuuMUXRHbRpp4xrqRSA9sk4FAEKTMWKW" ], "script": "base64:BgIrCAISBQoDCAEIEgMKAQgSBAoCCAQSAwoBCBIDCgEIEgUKAwgBCBIECgIIATYACXNlcGFyYXRvcgICX18ABU1VTFQ4AIDC1y8AC3dhdmVzU3RyaW5nAgVXQVZFUwAQc3RhdHVzSW5Qcm9ncmVzcwIKaW5Qcm9ncmVzcwAOc3RhdHVzQWNjZXB0ZWQCCGFjY2VwdGVkAA5zdGF0dXNSZWplY3RlZAIIcmVqZWN0ZWQBB3dyYXBFcnIBA21zZwkAuQkCCQDMCAICGHZvdGluZ192ZXJpZmllZF92Mi5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIdGhyb3dFcnIBA21zZwkAAgEJAQd3cmFwRXJyAQUDbXNnAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECG0ZhaWxlZCB0byBjYXN0IGludG8gSW50ZWdlcgEMcGFyc2VBc3NldElkAQVpbnB1dAMJAAACBQVpbnB1dAULd2F2ZXNTdHJpbmcFBHVuaXQJANkEAQUFaW5wdXQBD2Fzc2V0SWRUb1N0cmluZwEFaW5wdXQDCQAAAgUFaW5wdXQFBHVuaXQFC3dhdmVzU3RyaW5nCQDYBAEJAQV2YWx1ZQEFBWlucHV0ARBnZXRJbnRlZ2VyT3JaZXJvAgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEQZ2V0SW50ZWdlck9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEQZ2V0U3RyaW5nT3JFbXB0eQIHYWRkcmVzcwNrZXkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUHYWRkcmVzcwUDa2V5AgABD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAATa2V5Qm9vc3RpbmdDb250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUJc2VwYXJhdG9yABNrZXlFbWlzc2lvbkNvbnRyYWN0CQC5CQIJAMwIAgICJXMJAMwIAgIQZW1pc3Npb25Db250cmFjdAUDbmlsBQlzZXBhcmF0b3IAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QJALkJAgkAzAgCAgIlcwkAzAgCAhNhc3NldHNTdG9yZUNvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgAQYm9vc3RpbmdDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5Qm9vc3RpbmdDb250cmFjdAAQZW1pc3Npb25Db250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5RW1pc3Npb25Db250cmFjdAATYXNzZXRzU3RvcmVDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUWa2V5QXNzZXRzU3RvcmVDb250cmFjdAARa2V5RW1pc3Npb25Db25maWcJALkJAgkAzAgCAgIlcwkAzAgCAgZjb25maWcFA25pbAUJc2VwYXJhdG9yAAx3eEFzc2V0SWRTdHIJAJEDAgkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAURa2V5RW1pc3Npb25Db25maWcFCXNlcGFyYXRvcgABAAl3eEFzc2V0SWQJANkEAQUMd3hBc3NldElkU3RyABVrZXlWb3RpbmdUaHJlc2hvbGRBZGQJALkJAgkAzAgCAgQlcyVzCQDMCAICD3ZvdGluZ1RocmVzaG9sZAkAzAgCAgNhZGQFA25pbAUJc2VwYXJhdG9yABhrZXlWb3RpbmdUaHJlc2hvbGRSZW1vdmUJALkJAgkAzAgCAgQlcyVzCQDMCAICD3ZvdGluZ1RocmVzaG9sZAkAzAgCAgZyZW1vdmUFA25pbAUJc2VwYXJhdG9yABVrZXlQZXJpb2RMZW5ndGhSZW1vdmUJALkJAgkAzAgCAgIlcwkAzAgCAhJwZXJpb2RMZW5ndGhSZW1vdmUFA25pbAUJc2VwYXJhdG9yABJrZXlNYXhQZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAg9tYXhQZXJpb2RMZW5ndGgFA25pbAUJc2VwYXJhdG9yABJrZXlNaW5QZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAg9taW5QZXJpb2RMZW5ndGgFA25pbAUJc2VwYXJhdG9yARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICE3ZvdGluZ1Jld2FyZEFzc2V0SWQJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEPa2V5Vm90aW5nUmV3YXJkAwt1c2VyQWRkcmVzcwdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmV3YXJkCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEUa2V5VG90YWxWb3RpbmdSZXdhcmQCB2Fzc2V0SWQFaW5kZXgJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIRdG90YWxWb3RpbmdSZXdhcmQJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgAba2V5RmluYWxpemVDYWxsUmV3YXJkQW1vdW50CQC5CQIJAMwIAgICJXMJAMwIAgIYZmluYWxpemVDYWxsUmV3YXJkQW1vdW50BQNuaWwFCXNlcGFyYXRvcgAaa2V5TWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UJALkJAgkAzAgCAgIlcwkAzAgCAhdtaW5TdWdnZXN0UmVtb3ZlQmFsYW5jZQUDbmlsBQlzZXBhcmF0b3IBD2tleUN1cnJlbnRJbmRleAEHYXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIMY3VycmVudEluZGV4CQDMCAIFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yAQdrZXlWb3RlAwdhc3NldElkBWluZGV4BmNhbGxlcgkAuQkCCQDMCAICCCVzJXMlZCVzCQDMCAICBHZvdGUJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4CQDMCAIJAKUIAQUGY2FsbGVyBQNuaWwFCXNlcGFyYXRvcgEJdm90ZVZhbHVlAgdpbkZhdm9yCWd3eEFtb3VudAkAuQkCCQDMCAICBCVzJWQJAMwIAgkApQMBBQdpbkZhdm9yCQDMCAIJAKQDAQUJZ3d4QW1vdW50BQNuaWwFCXNlcGFyYXRvcgEQa2V5U3VnZ2VzdElzc3VlcgIHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAg1zdWdnZXN0SXNzdWVyCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQVpbmRleAUDbmlsBQlzZXBhcmF0b3IBD2tleUNsYWltSGlzdG9yeQMLdXNlckFkZHJlc3MHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICB2hpc3RvcnkJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgFA25pbAUJc2VwYXJhdG9yAA5rZXlGZWVQZXJCbG9jawkAuQkCCQDMCAICAiVzCQDMCAICC2ZlZVBlckJsb2NrBQNuaWwFCXNlcGFyYXRvcgALZmVlUGVyQmxvY2sJARBnZXRJbnRlZ2VyT3JGYWlsAgUEdGhpcwUOa2V5RmVlUGVyQmxvY2sAJmtleU1pbld4TWluRm9yU3VnZ2VzdEFkZEFtb3VudFJlcXVpcmVkCQC5CQIJAMwIAgICJXMJAMwIAgIgd3hNaW5Gb3JTdWdnZXN0QWRkQW1vdW50UmVxdWlyZWQFA25pbAUJc2VwYXJhdG9yACNrZXlXeEZvclN1Z2dlc3RSZW1vdmVBbW91bnRSZXF1aXJlZAkAuQkCCQDMCAICAiVzCQDMCAICIHd4Rm9yU3VnZ2VzdFJlbW92ZUFtb3VudFJlcXVpcmVkBQNuaWwFCXNlcGFyYXRvcgENa2V5Vm90aW5nSW5mbwIHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgp2b3RpbmdJbmZvCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQVpbmRleAUDbmlsBQlzZXBhcmF0b3IBD3ZvdGluZ0luZm9WYWx1ZQoNaXNSZXdhcmRFeGlzdA1yZXdhcmRBc3NldElkDHJld2FyZEFtb3VudAp2b3RpbmdUeXBlBnN0YXR1cxF2b3RpbmdTdGFydEhlaWdodA92b3RpbmdFbmRIZWlnaHQLdm90ZXNRdW9ydW0Idm90ZXNGb3IMdm90ZXNBZ2FpbnN0CQC5CQIJAMwIAgIUJXMlcyVkJXMlcyVkJWQlZCVkJWQJAMwIAgkApQMBBQ1pc1Jld2FyZEV4aXN0CQDMCAIFDXJld2FyZEFzc2V0SWQJAMwIAgkApAMBBQxyZXdhcmRBbW91bnQJAMwIAgUKdm90aW5nVHlwZQkAzAgCBQZzdGF0dXMJAMwIAgkApAMBBRF2b3RpbmdTdGFydEhlaWdodAkAzAgCCQCkAwEFD3ZvdGluZ0VuZEhlaWdodAkAzAgCCQCkAwEFC3ZvdGVzUXVvcnVtCQDMCAIJAKQDAQUIdm90ZXNGb3IJAMwIAgkApAMBBQx2b3Rlc0FnYWluc3QFA25pbAUJc2VwYXJhdG9yAQ1rZXlBc3NldEltYWdlAQdhc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgphc3NldEltYWdlCQDMCAIFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yARhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQCC3VzZXJBZGRyZXNzDHRhcmdldEhlaWdodAQJZ3d4QW1vdW50CQD8BwQFEGJvb3N0aW5nQ29udHJhY3QCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFDHRhcmdldEhlaWdodAUDbmlsBQNuaWwJAQVhc0ludAEFCWd3eEFtb3VudAEWa2V5TWFuYWdlclZhdWx0QWRkcmVzcwACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzARNrZXlNYW5hZ2VyUHVibGljS2V5AAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMABAckbWF0Y2gwCQCiCAEJARZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAXMFBHRoaXMBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABBNtYW5hZ2VyVmF1bHRBZGRyZXNzCQEcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcwAEByRtYXRjaDAJAJ0IAgUTbWFuYWdlclZhdWx0QWRkcmVzcwkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgESZ2V0Vm90aW5nSW5mb1BhcnRzAQp2b3RpbmdJbmZvBA92b3RpbmdJbmZvUGFydHMJALUJAgUKdm90aW5nSW5mbwUJc2VwYXJhdG9yBBBpc1Jld2FyZEV4aXN0U3RyCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwABBA1pc1Jld2FyZEV4aXN0AwkAAAIFEGlzUmV3YXJkRXhpc3RTdHICBHRydWUGBwQNcmV3YXJkQXNzZXRJZAkAkQMCBQ92b3RpbmdJbmZvUGFydHMAAgQMcmV3YXJkQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAMECnZvdGluZ1R5cGUJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAQEBnN0YXR1cwkAkQMCBQ92b3RpbmdJbmZvUGFydHMABQQRdm90aW5nU3RhcnRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMABgQPdm90aW5nRW5kSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAcEC3ZvdGVzUXVvcnVtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAgECHZvdGVzRm9yCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAkEDHZvdGVzQWdhaW5zdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwAKCQCcCgoFDWlzUmV3YXJkRXhpc3QFDXJld2FyZEFzc2V0SWQFDHJld2FyZEFtb3VudAUKdm90aW5nVHlwZQUGc3RhdHVzBRF2b3RpbmdTdGFydEhlaWdodAUPdm90aW5nRW5kSGVpZ2h0BQt2b3Rlc1F1b3J1bQUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAERdm90aW5nRXhpc3RDaGVja3MCB2Fzc2V0SWQMY3VycmVudEluZGV4BAp2b3RpbmdJbmZvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgJAQd3cmFwRXJyAQIVdm90aW5nIGluZm8gbm90IGZvdW5kBA92b3RpbmdJbmZvQXJyYXkJALUJAgUKdm90aW5nSW5mbwUJc2VwYXJhdG9yBAZzdGF0dXMJAJEDAgUPdm90aW5nSW5mb0FycmF5AAUED3ZvdGluZ0VuZEhlaWdodAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb0FycmF5AAcJAQd3cmFwRXJyAQIddm90aW5nIHN0YXJ0IGhlaWdodCBub3QgZm91bmQEDXN1Z2dlc3RJc3N1ZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhd2b3RpbmcgaXNzdWVyIG5vdCBmb3VuZAQGY2hlY2tzCQDMCAIDCQAAAgUGc3RhdHVzBRBzdGF0dXNJblByb2dyZXNzBgkBCHRocm93RXJyAQIVbm8gdm90aW5nIGluIHByb2dyZXNzCQDMCAIDCQBmAgUPdm90aW5nRW5kSGVpZ2h0BQZoZWlnaHQGCQEIdGhyb3dFcnIBAg52b3RpbmcgZXhwaXJlZAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzCQCVCgMFBnN0YXR1cwUPdm90aW5nRW5kSGVpZ2h0BQ1zdWdnZXN0SXNzdWVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9jYWxjdWxhdGVSZXdhcmQDBXZvdGVyB2Fzc2V0SWQFaW5kZXgEB3ZvdGVLZXkJAQdrZXlWb3RlAwUHYXNzZXRJZAUFaW5kZXgFBXZvdGVyBAhsYXN0Vm90ZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEFB3ZvdGVLZXkJAQd3cmFwRXJyAQISeW91IGhhdmUgbm90IHZvdGVkBA1sYXN0Vm90ZVBhcnRzCQC1CQIFCGxhc3RWb3RlBQlzZXBhcmF0b3IECWd3eEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDWxhc3RWb3RlUGFydHMAAgQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUFaW5kZXgJAQd3cmFwRXJyAQIVdm90aW5nIGluZm8gbm90IGZvdW5kBAt2b3RpbmdQYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIEBnN0YXR1cwgFC3ZvdGluZ1BhcnRzAl81BAh2b3Rlc0ZvcggFC3ZvdGluZ1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQt2b3RpbmdQYXJ0cwNfMTAEFXBhcnRPZlRoZVRvdGFsVm90ZXNYOAkAawMFCWd3eEFtb3VudAUFTVVMVDgJAGQCBQh2b3Rlc0ZvcgUMdm90ZXNBZ2FpbnN0BBF0b3RhbFZvdGluZ1Jld2FyZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQVpbmRleAAABBF2b3RlclJld2FyZEFtb3VudAkAbgQFFXBhcnRPZlRoZVRvdGFsVm90ZXNYOAURdG90YWxWb3RpbmdSZXdhcmQFBU1VTFQ4BQVGTE9PUgQIY2FuQ2xhaW0DCQAAAgUGc3RhdHVzBQ5zdGF0dXNBY2NlcHRlZAkAZgIFEXZvdGVyUmV3YXJkQW1vdW50AAAHCQCUCgIFEXZvdGVyUmV3YXJkQW1vdW50BQhjYW5DbGFpbQcBaQEKc3VnZ2VzdEFkZAMHYXNzZXRJZAxwZXJpb2RMZW5ndGgKYXNzZXRJbWFnZQQJd3hQYXltZW50CQCRAwIIBQFpCHBheW1lbnRzAAAEEHd4UGF5bWVudEFzc2V0SWQJAQV2YWx1ZQEIBQl3eFBheW1lbnQHYXNzZXRJZAQPd3hQYXltZW50QW1vdW50CQEFdmFsdWUBCAUJd3hQYXltZW50BmFtb3VudAQPbWluUGVyaW9kTGVuZ3RoCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJrZXlNaW5QZXJpb2RMZW5ndGgED21heFBlcmlvZExlbmd0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQUSa2V5TWF4UGVyaW9kTGVuZ3RoBA90b2tlbklzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQUBQAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQGY2hlY2tzCQDMCAIDAwkAZwIFDHBlcmlvZExlbmd0aAUPbWluUGVyaW9kTGVuZ3RoCQBnAgUPbWF4UGVyaW9kTGVuZ3RoBQxwZXJpb2RMZW5ndGgHBgkBCHRocm93RXJyAQIUaW52YWxpZCBwZXJpb2RMZW5ndGgJAMwIAgMJAAACBQ90b2tlbklzVmVyaWZpZWQHBgkBCHRocm93RXJyAQIWdG9rZW4gYWxyZWFkeSB2ZXJpZmllZAkAzAgCAwkAZwIFD3d4UGF5bWVudEFtb3VudAkAaAIFDHBlcmlvZExlbmd0aAULZmVlUGVyQmxvY2sGCQEIdGhyb3dFcnIBAh5ub3QgZW5vdWdoIHd4IGZvciBnaXZlbiBwZXJpb2QJAMwIAgMJAGcCBQ93eFBheW1lbnRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFJmtleU1pbld4TWluRm9yU3VnZ2VzdEFkZEFtb3VudFJlcXVpcmVkBgkBCHRocm93RXJyAQIhcGF5bWVudCBsZXNzIHRoZW4gbWluIGZvciBzdWdnZXN0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MED2N1cnJlbnRJbmRleEtleQkBD2tleUN1cnJlbnRJbmRleAEFB2Fzc2V0SWQEDGN1cnJlbnRJbmRleAkAnwgBBQ9jdXJyZW50SW5kZXhLZXkECG5ld0luZGV4AwkBCWlzRGVmaW5lZAEFDGN1cnJlbnRJbmRleAkAZAIJAQV2YWx1ZQEFDGN1cnJlbnRJbmRleAABAAAECyR0MDkyNTk5ODk5AwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAQQTdm90aW5nUmV3YXJkUGF5bWVudAkAkQMCCAUBaQhwYXltZW50cwABBBp2b3RpbmdSZXdhcmRQYXltZW50QXNzZXRJZAkA2AQBCQEFdmFsdWUBCAUTdm90aW5nUmV3YXJkUGF5bWVudAdhc3NldElkBBl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQEFdmFsdWUBCAUTdm90aW5nUmV3YXJkUGF5bWVudAZhbW91bnQJAJYKBAYFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkBRl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgUHYXNzZXRJZAUIbmV3SW5kZXgFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQhuZXdJbmRleAUZdm90aW5nUmV3YXJkUGF5bWVudEFtb3VudAUDbmlsCQCWCgQHAgVFTVBUWQAABQNuaWwEDWlzUmV3YXJkRXhpc3QIBQskdDA5MjU5OTg5OQJfMQQNcmV3YXJkQXNzZXRJZAgFCyR0MDkyNTk5ODk5Al8yBAxyZXdhcmRBbW91bnQIBQskdDA5MjU5OTg5OQJfMwQTdm90aW5nUmV3YXJkQWN0aW9ucwgFCyR0MDkyNTk5ODk5Al80BAt2b3Rlc1F1b3J1bQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFFWtleVZvdGluZ1RocmVzaG9sZEFkZAkBB3dyYXBFcnIBAhp2b3RpbmdUaHJlc2hvbGRBZGQgbm90IHNldAQKdm90aW5nSW5mbwkBD3ZvdGluZ0luZm9WYWx1ZQoFDWlzUmV3YXJkRXhpc3QFDXJld2FyZEFzc2V0SWQFDHJld2FyZEFtb3VudAIMdmVyaWZpY2F0aW9uBRBzdGF0dXNJblByb2dyZXNzBQZoZWlnaHQJAGQCBQZoZWlnaHQFDHBlcmlvZExlbmd0aAULdm90ZXNRdW9ydW0AAAAABBhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFG2tleUZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAQMYnVybld4QW1vdW50CQBlAgUPd3hQYXltZW50QW1vdW50BRhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPY3VycmVudEluZGV4S2V5BQhuZXdJbmRleAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFCG5ld0luZGV4CQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFCG5ld0luZGV4BQp2b3RpbmdJbmZvCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1rZXlBc3NldEltYWdlAQUHYXNzZXRJZAUKYXNzZXRJbWFnZQkAzAgCCQEEQnVybgIFEHd4UGF5bWVudEFzc2V0SWQFDGJ1cm5XeEFtb3VudAUDbmlsBRN2b3RpbmdSZXdhcmRBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN1Z2dlc3RSZW1vdmUBB2Fzc2V0SWQEDmd3eEFtb3VudEF0Tm93CQEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgkApQgBCAUBaQZjYWxsZXIFBmhlaWdodAQXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UJARFAZXh0ck5hdGl2ZSgxMDU1KQEFGmtleU1pblN1Z2dlc3RSZW1vdmVCYWxhbmNlBAl3eFBheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQQd3hQYXltZW50QXNzZXRJZAkBBXZhbHVlAQgFCXd4UGF5bWVudAdhc3NldElkBA93eFBheW1lbnRBbW91bnQJAQV2YWx1ZQEIBQl3eFBheW1lbnQGYW1vdW50BA90b2tlbklzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQUBQAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQGY2hlY2tzCQDMCAIDBQ90b2tlbklzVmVyaWZpZWQGCQEIdGhyb3dFcnIBAhJ0b2tlbiBub3QgdmVyaWZpZWQJAMwIAgMJAGcCBQ5nd3hBbW91bnRBdE5vdwUXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UGCQEIdGhyb3dFcnIBAhBub3QgZW5vdWdoIGdXWGVzCQDMCAIDCQBnAgUPd3hQYXltZW50QW1vdW50CQERQGV4dHJOYXRpdmUoMTA1NSkBBSNrZXlXeEZvclN1Z2dlc3RSZW1vdmVBbW91bnRSZXF1aXJlZAYJAQh0aHJvd0VycgECIXBheW1lbnQgbGVzcyB0aGVuIG1pbiBmb3Igc3VnZ2VzdAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA9jdXJyZW50SW5kZXhLZXkJAQ9rZXlDdXJyZW50SW5kZXgBBQdhc3NldElkBAxjdXJyZW50SW5kZXgJAJ8IAQUPY3VycmVudEluZGV4S2V5BAhuZXdJbmRleAMJAQlpc0RlZmluZWQBBQxjdXJyZW50SW5kZXgJAGQCCQEFdmFsdWUBBQxjdXJyZW50SW5kZXgAAQAABAxwZXJpb2RMZW5ndGgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRVrZXlQZXJpb2RMZW5ndGhSZW1vdmUJAQd3cmFwRXJyAQIacGVyaW9kTGVuZ3RoUmVtb3ZlIG5vdCBzZXQED3ZvdGluZ0VuZEhlaWdodAkAZAIFBmhlaWdodAUMcGVyaW9kTGVuZ3RoBAt2b3Rlc1F1b3J1bQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFGGtleVZvdGluZ1RocmVzaG9sZFJlbW92ZQkBB3dyYXBFcnIBAh12b3RpbmdUaHJlc2hvbGRSZW1vdmUgbm90IHNldAQKdm90aW5nSW5mbwkBD3ZvdGluZ0luZm9WYWx1ZQoHAgVFTVBUWQAAAg5kZXZlcmlmaWNhdGlvbgUQc3RhdHVzSW5Qcm9ncmVzcwUGaGVpZ2h0CQBkAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgFC3ZvdGVzUXVvcnVtAAAAAAQTc2V0QXNzZXRJbWFnZUFjdGlvbgQHJG1hdGNoMAkAoggBCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQNuaWwDCQABAgUHJG1hdGNoMAIEVW5pdAQVYXNzZXRzU3RvcmVBc3NldEltYWdlCgABQAkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0AhRnZXRBc3NldExvZ29SRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleUFzc2V0SW1hZ2UBBQdhc3NldElkBRVhc3NldHNTdG9yZUFzc2V0SW1hZ2UFA25pbAkAAgECC01hdGNoIGVycm9yCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFD2N1cnJlbnRJbmRleEtleQUIbmV3SW5kZXgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVN1Z2dlc3RJc3N1ZXICBQdhc3NldElkBQhuZXdJbmRleAkApQgBCAUBaQZjYWxsZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQhuZXdJbmRleAUKdm90aW5nSW5mbwUDbmlsBRNzZXRBc3NldEltYWdlQWN0aW9uCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBHZvdGUCB2Fzc2V0SWQHaW5GYXZvcgQPY3VycmVudEluZGV4S2V5CQEPa2V5Q3VycmVudEluZGV4AQUHYXNzZXRJZAQMY3VycmVudEluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUPY3VycmVudEluZGV4S2V5CQEHd3JhcEVycgECFXZvdGluZyBkb2VzIG5vdCBleGlzdAQKdm90aW5nSW5mbwkBEXZvdGluZ0V4aXN0Q2hlY2tzAgUHYXNzZXRJZAUMY3VycmVudEluZGV4AwkAAAIFCnZvdGluZ0luZm8FCnZvdGluZ0luZm8EFmN1cnJlbnRWb3RpbmdFbmRIZWlnaHQIBQp2b3RpbmdJbmZvAl8yBA5nd3hBbW91bnRBdEVuZAkBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAIJAKUIAQgFAWkGY2FsbGVyBRZjdXJyZW50Vm90aW5nRW5kSGVpZ2h0BAd2b3RlS2V5CQEHa2V5Vm90ZQMFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAgFAWkGY2FsbGVyBAZjaGVja3MJAMwIAgMJAAACCQCiCAEFB3ZvdGVLZXkFBHVuaXQGCQEIdGhyb3dFcnIBAhZZb3UgaGF2ZSBhbHJlYWR5IHZvdGVkCQDMCAIDCQBmAgUOZ3d4QW1vdW50QXRFbmQAAAYJAAIBAihZb3UnbGwgbm90IGhhdmUgZ1dYIGF0IHRoZSBlbmQgb2Ygdm90aW5nBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDXZvdGluZ0luZm9TdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQED3ZvdGluZ0luZm9QYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIECHZvdGVzRm9yCAUPdm90aW5nSW5mb1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQ92b3RpbmdJbmZvUGFydHMDXzEwBA0kdDAxMzU2MzEzNzI0AwUHaW5GYXZvcgkAlAoCCQBkAgUIdm90ZXNGb3IFDmd3eEFtb3VudEF0RW5kBQx2b3Rlc0FnYWluc3QJAJQKAgUIdm90ZXNGb3IJAGQCBQx2b3Rlc0FnYWluc3QFDmd3eEFtb3VudEF0RW5kBAtuZXdWb3Rlc0ZvcggFDSR0MDEzNTYzMTM3MjQCXzEED25ld1ZvdGVzQWdhaW5zdAgFDSR0MDEzNTYzMTM3MjQCXzIEEm5ld1ZvdGluZ0luZm9WYWx1ZQkBD3ZvdGluZ0luZm9WYWx1ZQoIBQ92b3RpbmdJbmZvUGFydHMCXzEIBQ92b3RpbmdJbmZvUGFydHMCXzIIBQ92b3RpbmdJbmZvUGFydHMCXzMIBQ92b3RpbmdJbmZvUGFydHMCXzQIBQ92b3RpbmdJbmZvUGFydHMCXzUIBQ92b3RpbmdJbmZvUGFydHMCXzYIBQ92b3RpbmdJbmZvUGFydHMCXzcIBQ92b3RpbmdJbmZvUGFydHMCXzgFC25ld1ZvdGVzRm9yBQ9uZXdWb3Rlc0FnYWluc3QEEnZvdGluZ1Jld2FyZEFjdGlvbgQHJG1hdGNoMAkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAnBrBQckbWF0Y2gwCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlWb3RpbmdSZXdhcmQDCAUBaQZjYWxsZXIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBCXZvdGVWYWx1ZQIFB2luRmF2b3IFDmd3eEFtb3VudEF0RW5kBQNuaWwDCQABAgUHJG1hdGNoMAIEVW5pdAUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQd2b3RlS2V5CQEJdm90ZVZhbHVlAgUHaW5GYXZvcgUOZ3d4QW1vdW50QXRFbmQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgFEm5ld1ZvdGluZ0luZm9WYWx1ZQUDbmlsBRJ2b3RpbmdSZXdhcmRBY3Rpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKY2FuY2VsVm90ZQEHYXNzZXRJZAQPY3VycmVudEluZGV4S2V5CQEPa2V5Q3VycmVudEluZGV4AQUHYXNzZXRJZAQMY3VycmVudEluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUPY3VycmVudEluZGV4S2V5CQEHd3JhcEVycgECFXZvdGluZyBkb2VzIG5vdCBleGlzdAQHdm90ZUtleQkBB2tleVZvdGUDBQdhc3NldElkBQxjdXJyZW50SW5kZXgIBQFpBmNhbGxlcgQIbGFzdFZvdGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBBQd2b3RlS2V5CQEHd3JhcEVycgECEnlvdSBoYXZlIG5vdCB2b3RlZAQNbGFzdFZvdGVQYXJ0cwkAtQkCBQhsYXN0Vm90ZQUJc2VwYXJhdG9yBAdpbkZhdm9yCQCRAwIFDWxhc3RWb3RlUGFydHMAAQQJZ3d4QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNbGFzdFZvdGVQYXJ0cwACBAp2b3RpbmdJbmZvCQERdm90aW5nRXhpc3RDaGVja3MCBQdhc3NldElkBQxjdXJyZW50SW5kZXgDCQAAAgUKdm90aW5nSW5mbwUKdm90aW5nSW5mbwQGY2hlY2tzCQDMCAIDAwkAAAIFB2luRmF2b3ICBHRydWUGCQAAAgUHaW5GYXZvcgIFZmFsc2UGCQEIdGhyb3dFcnIBAgxpbnZhbGlkIHZvdGUFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEHd3JhcEVycgECFXZvdGluZyBpbmZvIG5vdCBmb3VuZAQPdm90aW5nSW5mb1BhcnRzCQESZ2V0Vm90aW5nSW5mb1BhcnRzAQUNdm90aW5nSW5mb1N0cgQIdm90ZXNGb3IIBQ92b3RpbmdJbmZvUGFydHMCXzkEDHZvdGVzQWdhaW5zdAgFD3ZvdGluZ0luZm9QYXJ0cwNfMTAEDSR0MDE1MzQ5MTU1MTADCQAAAgUHaW5GYXZvcgIEdHJ1ZQkAlAoCCQBlAgUIdm90ZXNGb3IFCWd3eEFtb3VudAUMdm90ZXNBZ2FpbnN0CQCUCgIFCHZvdGVzRm9yCQBlAgUMdm90ZXNBZ2FpbnN0BQlnd3hBbW91bnQEC25ld1ZvdGVzRm9yCAUNJHQwMTUzNDkxNTUxMAJfMQQPbmV3Vm90ZXNBZ2FpbnN0CAUNJHQwMTUzNDkxNTUxMAJfMgQSbmV3Vm90aW5nSW5mb1ZhbHVlCQEPdm90aW5nSW5mb1ZhbHVlCggFD3ZvdGluZ0luZm9QYXJ0cwJfMQgFD3ZvdGluZ0luZm9QYXJ0cwJfMggFD3ZvdGluZ0luZm9QYXJ0cwJfMwgFD3ZvdGluZ0luZm9QYXJ0cwJfNAgFD3ZvdGluZ0luZm9QYXJ0cwJfNQgFD3ZvdGluZ0luZm9QYXJ0cwJfNggFD3ZvdGluZ0luZm9QYXJ0cwJfNwgFD3ZvdGluZ0luZm9QYXJ0cwJfOAULbmV3Vm90ZXNGb3IFD25ld1ZvdGVzQWdhaW5zdAkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAUSbmV3Vm90aW5nSW5mb1ZhbHVlCQDMCAIJAQtEZWxldGVFbnRyeQEFB3ZvdGVLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBD2tleVZvdGluZ1Jld2FyZAMIBQFpBmNhbGxlcgUHYXNzZXRJZAUMY3VycmVudEluZGV4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIZmluYWxpemUBB2Fzc2V0SWQED2N1cnJlbnRJbmRleEtleQkBD2tleUN1cnJlbnRJbmRleAEFB2Fzc2V0SWQEDGN1cnJlbnRJbmRleAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ9jdXJyZW50SW5kZXhLZXkAAAQSdm90aW5nVGhyZXNob2xkQWRkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUVa2V5Vm90aW5nVGhyZXNob2xkQWRkCQEHd3JhcEVycgECGnZvdGluZ1RocmVzaG9sZEFkZCBub3Qgc2V0BBV2b3RpbmdUaHJlc2hvbGRSZW1vdmUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRhrZXlWb3RpbmdUaHJlc2hvbGRSZW1vdmUJAQd3cmFwRXJyAQIddm90aW5nVGhyZXNob2xkUmVtb3ZlIG5vdCBzZXQEDXZvdGluZ0luZm9TdHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQED3ZvdGluZ0luZm9QYXJ0cwkBEmdldFZvdGluZ0luZm9QYXJ0cwEFDXZvdGluZ0luZm9TdHIECnZvdGluZ1R5cGUIBQ92b3RpbmdJbmZvUGFydHMCXzQEBnN0YXR1cwgFD3ZvdGluZ0luZm9QYXJ0cwJfNQQPdm90aW5nRW5kSGVpZ2h0CAUPdm90aW5nSW5mb1BhcnRzAl83BAx2b3RpbmdRdW9ydW0IBQ92b3RpbmdJbmZvUGFydHMCXzgECHZvdGVzRm9yCAUPdm90aW5nSW5mb1BhcnRzAl85BAx2b3Rlc0FnYWluc3QIBQ92b3RpbmdJbmZvUGFydHMDXzEwBAZjaGVja3MJAMwIAgMJAAACBQZzdGF0dXMFEHN0YXR1c0luUHJvZ3Jlc3MGCQEIdGhyb3dFcnIBAhZ2b3Rpbmcgbm90IGluIHByb2dyZXNzCQDMCAIDCQBnAgUGaGVpZ2h0BQ92b3RpbmdFbmRIZWlnaHQGCQEIdGhyb3dFcnIBAhN2b3Rpbmcgbm90IGZpbmlzaGVkCQDMCAIDCQEJaXNEZWZpbmVkAQkAoggBCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQGCQEIdGhyb3dFcnIBAhNhc3NldCBpbWFnZSBub3Qgc2V0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDnZvdGluZ0FjY2VwdGVkAwMJAGcCCQBkAgUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAUMdm90aW5nUXVvcnVtCQBmAgUIdm90ZXNGb3IFDHZvdGVzQWdhaW5zdAcGBwQJbmV3U3RhdHVzAwUOdm90aW5nQWNjZXB0ZWQFDnN0YXR1c0FjY2VwdGVkBQ5zdGF0dXNSZWplY3RlZAQKYXNzZXRJbWFnZQkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDWtleUFzc2V0SW1hZ2UBBQdhc3NldElkBBBpc1ZvdGluZ0FjY2VwdGVkAwUOdm90aW5nQWNjZXB0ZWQEFXZvdGluZ0FjY2VwdGVkSW52b2tlcwMJAAACBQp2b3RpbmdUeXBlAgx2ZXJpZmljYXRpb24JAPwHBAUTYXNzZXRzU3RvcmVDb250cmFjdAIOY3JlYXRlT3JVcGRhdGUJAMwIAgUHYXNzZXRJZAkAzAgCBQphc3NldEltYWdlCQDMCAIGBQNuaWwFA25pbAkAzAgCCQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCC3NldFZlcmlmaWVkCQDMCAIFB2Fzc2V0SWQJAMwIAgcFA25pbAUDbmlsCQDMCAIJAPwHBAUTYXNzZXRzU3RvcmVDb250cmFjdAILb25FbGltaW5hdGUJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwFA25pbAUVdm90aW5nQWNjZXB0ZWRJbnZva2VzBQNuaWwDCQAAAgUQaXNWb3RpbmdBY2NlcHRlZAUQaXNWb3RpbmdBY2NlcHRlZAQSbmV3Vm90aW5nSW5mb1ZhbHVlCQEPdm90aW5nSW5mb1ZhbHVlCggFD3ZvdGluZ0luZm9QYXJ0cwJfMQgFD3ZvdGluZ0luZm9QYXJ0cwJfMggFD3ZvdGluZ0luZm9QYXJ0cwJfMwgFD3ZvdGluZ0luZm9QYXJ0cwJfNAUJbmV3U3RhdHVzCAUPdm90aW5nSW5mb1BhcnRzAl82CAUPdm90aW5nSW5mb1BhcnRzAl83CAUPdm90aW5nSW5mb1BhcnRzAl84CAUPdm90aW5nSW5mb1BhcnRzAl85CAUPdm90aW5nSW5mb1BhcnRzA18xMAQYZmluYWxpemVDYWxsUmV3YXJkQW1vdW50CQERQGV4dHJOYXRpdmUoMTA1NSkBBRtrZXlGaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQEFHN1Z2dlc3RJc3N1ZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAQZdm90aW5nUmV3YXJkQXNzZXRJZE9wdGlvbgkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAQXdG90YWxWb3RpbmdSZXdhcmRPcHRpb24JAJ8IAQkBFGtleVRvdGFsVm90aW5nUmV3YXJkAgUHYXNzZXRJZAUMY3VycmVudEluZGV4BBNyZXR1cm5SZXdhcmRBY3Rpb25zAwMDBQ52b3RpbmdBY2NlcHRlZAYJAAACBRl2b3RpbmdSZXdhcmRBc3NldElkT3B0aW9uBQR1bml0BgkAAAIFF3RvdGFsVm90aW5nUmV3YXJkT3B0aW9uBQR1bml0BQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUUc3VnZ2VzdElzc3VlckFkZHJlc3MJAQV2YWx1ZQEFF3RvdGFsVm90aW5nUmV3YXJkT3B0aW9uCQEMcGFyc2VBc3NldElkAQkBBXZhbHVlAQUZdm90aW5nUmV3YXJkQXNzZXRJZE9wdGlvbgUDbmlsCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgFEm5ld1ZvdGluZ0luZm9WYWx1ZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFGGZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAUJd3hBc3NldElkBQNuaWwFE3JldHVyblJld2FyZEFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENY2xhaW1SRUFET05MWQMHYXNzZXRJZAVpbmRleA51c2VyQWRkcmVzc1N0cgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgkBB3dyYXBFcnIBAg9pbnZhbGlkIGFkZHJlc3MEFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIJAKIIAQkBFmtleVZvdGluZ1Jld2FyZEFzc2V0SWQCBQdhc3NldElkBQVpbmRleAQMcmV3YXJkQW1vdW50AwkBCWlzRGVmaW5lZAEFFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIICQEPY2FsY3VsYXRlUmV3YXJkAwULdXNlckFkZHJlc3MFB2Fzc2V0SWQFBWluZGV4Al8xAAAJAJQKAgUDbmlsBQxyZXdhcmRBbW91bnQBaQEFY2xhaW0CB2Fzc2V0SWQFaW5kZXgEDWNhbGxlckFkZHJlc3MIBQFpBmNhbGxlcgQPY2xhaW1IaXN0b3J5S2V5CQEPa2V5Q2xhaW1IaXN0b3J5AwUNY2FsbGVyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgEDGNsYWltSGlzdG9yeQkAnwgBBQ9jbGFpbUhpc3RvcnlLZXkEBmNoZWNrcwkAzAgCAwkAAAIFDGNsYWltSGlzdG9yeQUEdW5pdAYJAQh0aHJvd0VycgECD2FscmVhZHkgY2xhaW1lZAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA0kdDAxOTYwMDE5Njc3CQEPY2FsY3VsYXRlUmV3YXJkAwUNY2FsbGVyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgEDHJld2FyZEFtb3VudAgFDSR0MDE5NjAwMTk2NzcCXzEECGNhbkNsYWltCAUNJHQwMTk2MDAxOTY3NwJfMgMJAQEhAQUIY2FuQ2xhaW0JAQh0aHJvd0VycgECEG5vdGhpbmcgdG8gY2xhaW0EFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIJAKIIAQkBFmtleVZvdGluZ1Jld2FyZEFzc2V0SWQCBQdhc3NldElkBQVpbmRleAQMcmV3YXJkQWN0aW9uAwkBCWlzRGVmaW5lZAEFFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIEE3ZvdGluZ1Jld2FyZEFzc2V0SWQJANkEAQkBBXZhbHVlAQUWdm90aW5nUmV3YXJkQXNzZXRJZFN0cgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ1jYWxsZXJBZGRyZXNzBQxyZXdhcmRBbW91bnQFE3ZvdGluZ1Jld2FyZEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIFD2NsYWltSGlzdG9yeUtleQUMcmV3YXJkQW1vdW50CQDMCAIJAQtEZWxldGVFbnRyeQEJAQ9rZXlWb3RpbmdSZXdhcmQDBQ1jYWxsZXJBZGRyZXNzBQdhc3NldElkBQVpbmRleAUDbmlsCQEIdGhyb3dFcnIBAhBub3RoaW5nIHRvIGNsYWltBQxyZXdhcmRBY3Rpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXk+OaFQ", "height": 2802280, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HWRVNKksKRyErxvrkwAf8rVMTEMyGvCfkRPvFeVdmHKA Next: none Diff:
OldNewDifferences
435435 then {
436436 let votingAcceptedInvokes = if ((votingType == "verification"))
437437 then invoke(assetsStoreContract, "createOrUpdate", [assetId, assetImage, true], nil)
438- else invoke(assetsStoreContract, "setVerified", [assetId, false], nil)
438+ else [invoke(assetsStoreContract, "setVerified", [assetId, false], nil), invoke(assetsStoreContract, "onEliminate", [assetId], nil)]
439439 votingAcceptedInvokes
440440 }
441441 else nil
484484 else throwErr("already claimed")]
485485 if ((checks == checks))
486486 then {
487- let $t01951619593 = calculateReward(callerAddress, assetId, index)
488- let rewardAmount = $t01951619593._1
489- let canClaim = $t01951619593._2
487+ let $t01960019677 = calculateReward(callerAddress, assetId, index)
488+ let rewardAmount = $t01960019677._1
489+ let canClaim = $t01960019677._2
490490 if (!(canClaim))
491491 then throwErr("nothing to claim")
492492 else {
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let MULT8 = 100000000
77
88 let wavesString = "WAVES"
99
1010 let statusInProgress = "inProgress"
1111
1212 let statusAccepted = "accepted"
1313
1414 let statusRejected = "rejected"
1515
1616 func wrapErr (msg) = makeString(["voting_verified_v2.ride:", msg], " ")
1717
1818
1919 func throwErr (msg) = throw(wrapErr(msg))
2020
2121
2222 func asInt (val) = match val {
2323 case valInt: Int =>
2424 valInt
2525 case _ =>
2626 throw("Failed to cast into Integer")
2727 }
2828
2929
3030 func parseAssetId (input) = if ((input == wavesString))
3131 then unit
3232 else fromBase58String(input)
3333
3434
3535 func assetIdToString (input) = if ((input == unit))
3636 then wavesString
3737 else toBase58String(value(input))
3838
3939
4040 func getIntegerOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
4141
4242
4343 func getIntegerOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((key + " is not defined")))
4444
4545
4646 func getStringOrEmpty (address,key) = valueOrElse(getString(address, key), "")
4747
4848
4949 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((key + " is not defined")))
5050
5151
5252 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
5353
5454 let keyEmissionContract = makeString(["%s", "emissionContract"], separator)
5555
5656 let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
5757
5858 let boostingContract = addressFromStringValue(getStringValue(keyBoostingContract))
5959
6060 let emissionContract = addressFromStringValue(getStringValue(keyEmissionContract))
6161
6262 let assetsStoreContract = addressFromStringValue(getStringValue(keyAssetsStoreContract))
6363
6464 let keyEmissionConfig = makeString(["%s", "config"], separator)
6565
6666 let wxAssetIdStr = split(getStringOrFail(emissionContract, keyEmissionConfig), separator)[1]
6767
6868 let wxAssetId = fromBase58String(wxAssetIdStr)
6969
7070 let keyVotingThresholdAdd = makeString(["%s%s", "votingThreshold", "add"], separator)
7171
7272 let keyVotingThresholdRemove = makeString(["%s%s", "votingThreshold", "remove"], separator)
7373
7474 let keyPeriodLengthRemove = makeString(["%s", "periodLengthRemove"], separator)
7575
7676 let keyMaxPeriodLength = makeString(["%s", "maxPeriodLength"], separator)
7777
7878 let keyMinPeriodLength = makeString(["%s", "minPeriodLength"], separator)
7979
8080 func keyVotingRewardAssetId (assetId,index) = makeString(["%s%s%d", "votingRewardAssetId", assetId, toString(index)], separator)
8181
8282
8383 func keyVotingReward (userAddress,assetId,index) = makeString(["%s%s%s%d", "votingReward", toString(userAddress), assetId, toString(index)], separator)
8484
8585
8686 func keyTotalVotingReward (assetId,index) = makeString(["%s%s%d", "totalVotingReward", assetId, toString(index)], separator)
8787
8888
8989 let keyFinalizeCallRewardAmount = makeString(["%s", "finalizeCallRewardAmount"], separator)
9090
9191 let keyMinSuggestRemoveBalance = makeString(["%s", "minSuggestRemoveBalance"], separator)
9292
9393 func keyCurrentIndex (assetId) = makeString(["%s%s", "currentIndex", assetId], separator)
9494
9595
9696 func keyVote (assetId,index,caller) = makeString(["%s%s%d%s", "vote", assetId, toString(index), toString(caller)], separator)
9797
9898
9999 func voteValue (inFavor,gwxAmount) = makeString(["%s%d", toString(inFavor), toString(gwxAmount)], separator)
100100
101101
102102 func keySuggestIssuer (assetId,index) = makeString(["%s%s%d", "suggestIssuer", assetId, toString(index)], separator)
103103
104104
105105 func keyClaimHistory (userAddress,assetId,index) = makeString(["%s%s%s%d", "history", toString(userAddress), assetId, toString(index)], separator)
106106
107107
108108 let keyFeePerBlock = makeString(["%s", "feePerBlock"], separator)
109109
110110 let feePerBlock = getIntegerOrFail(this, keyFeePerBlock)
111111
112112 let keyMinWxMinForSuggestAddAmountRequired = makeString(["%s", "wxMinForSuggestAddAmountRequired"], separator)
113113
114114 let keyWxForSuggestRemoveAmountRequired = makeString(["%s", "wxForSuggestRemoveAmountRequired"], separator)
115115
116116 func keyVotingInfo (assetId,index) = makeString(["%s%s%d", "votingInfo", assetId, toString(index)], separator)
117117
118118
119119 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)
120120
121121
122122 func keyAssetImage (assetId) = makeString(["%s%s", "assetImage", assetId], separator)
123123
124124
125125 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
126126 let gwxAmount = invoke(boostingContract, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
127127 asInt(gwxAmount)
128128 }
129129
130130
131131 func keyManagerVaultAddress () = "%s__managerVaultAddress"
132132
133133
134134 func keyManagerPublicKey () = "%s__managerPublicKey"
135135
136136
137137 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
138138 case s: String =>
139139 addressFromStringValue(s)
140140 case _ =>
141141 this
142142 }
143143
144144
145145 func managerPublicKeyOrUnit () = {
146146 let managerVaultAddress = getManagerVaultAddressOrThis()
147147 match getString(managerVaultAddress, keyManagerPublicKey()) {
148148 case s: String =>
149149 fromBase58String(s)
150150 case _: Unit =>
151151 unit
152152 case _ =>
153153 throw("Match error")
154154 }
155155 }
156156
157157
158158 func getVotingInfoParts (votingInfo) = {
159159 let votingInfoParts = split(votingInfo, separator)
160160 let isRewardExistStr = votingInfoParts[1]
161161 let isRewardExist = if ((isRewardExistStr == "true"))
162162 then true
163163 else false
164164 let rewardAssetId = votingInfoParts[2]
165165 let rewardAmount = parseIntValue(votingInfoParts[3])
166166 let votingType = votingInfoParts[4]
167167 let status = votingInfoParts[5]
168168 let votingStartHeight = parseIntValue(votingInfoParts[6])
169169 let votingEndHeight = parseIntValue(votingInfoParts[7])
170170 let votesQuorum = parseIntValue(votingInfoParts[8])
171171 let votesFor = parseIntValue(votingInfoParts[9])
172172 let votesAgainst = parseIntValue(votingInfoParts[10])
173173 $Tuple10(isRewardExist, rewardAssetId, rewardAmount, votingType, status, votingStartHeight, votingEndHeight, votesQuorum, votesFor, votesAgainst)
174174 }
175175
176176
177177 func votingExistChecks (assetId,currentIndex) = {
178178 let votingInfo = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
179179 let votingInfoArray = split(votingInfo, separator)
180180 let status = votingInfoArray[5]
181181 let votingEndHeight = valueOrErrorMessage(parseIntValue(votingInfoArray[7]), wrapErr("voting start height not found"))
182182 let suggestIssuer = valueOrErrorMessage(getString(keySuggestIssuer(assetId, currentIndex)), wrapErr("voting issuer not found"))
183183 let checks = [if ((status == statusInProgress))
184184 then true
185185 else throwErr("no voting in progress"), if ((votingEndHeight > height))
186186 then true
187187 else throwErr("voting expired")]
188188 if ((checks == checks))
189189 then $Tuple3(status, votingEndHeight, suggestIssuer)
190190 else throw("Strict value is not equal to itself.")
191191 }
192192
193193
194194 func calculateReward (voter,assetId,index) = {
195195 let voteKey = keyVote(assetId, index, voter)
196196 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
197197 let lastVoteParts = split(lastVote, separator)
198198 let gwxAmount = parseIntValue(lastVoteParts[2])
199199 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, index)), wrapErr("voting info not found"))
200200 let votingParts = getVotingInfoParts(votingInfoStr)
201201 let status = votingParts._5
202202 let votesFor = votingParts._9
203203 let votesAgainst = votingParts._10
204204 let partOfTheTotalVotesX8 = fraction(gwxAmount, MULT8, (votesFor + votesAgainst))
205205 let totalVotingReward = valueOrElse(getInteger(keyTotalVotingReward(assetId, index)), 0)
206206 let voterRewardAmount = fraction(partOfTheTotalVotesX8, totalVotingReward, MULT8, FLOOR)
207207 let canClaim = if ((status == statusAccepted))
208208 then (voterRewardAmount > 0)
209209 else false
210210 $Tuple2(voterRewardAmount, canClaim)
211211 }
212212
213213
214214 @Callable(i)
215215 func suggestAdd (assetId,periodLength,assetImage) = {
216216 let wxPayment = i.payments[0]
217217 let wxPaymentAssetId = value(wxPayment.assetId)
218218 let wxPaymentAmount = value(wxPayment.amount)
219219 let minPeriodLength = getIntegerValue(keyMinPeriodLength)
220220 let maxPeriodLength = getIntegerValue(keyMaxPeriodLength)
221221 let tokenIsVerified = {
222222 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
223223 if ($isInstanceOf(@, "Boolean"))
224224 then @
225225 else throw(($getType(@) + " couldn't be cast to Boolean"))
226226 }
227227 let checks = [if (if ((periodLength >= minPeriodLength))
228228 then (maxPeriodLength >= periodLength)
229229 else false)
230230 then true
231231 else throwErr("invalid periodLength"), if ((tokenIsVerified == false))
232232 then true
233233 else throwErr("token already verified"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
234234 then true
235235 else throwErr("not enough wx for given period"), if ((wxPaymentAmount >= getIntegerValue(keyMinWxMinForSuggestAddAmountRequired)))
236236 then true
237237 else throwErr("payment less then min for suggest")]
238238 if ((checks == checks))
239239 then {
240240 let currentIndexKey = keyCurrentIndex(assetId)
241241 let currentIndex = getInteger(currentIndexKey)
242242 let newIndex = if (isDefined(currentIndex))
243243 then (value(currentIndex) + 1)
244244 else 0
245245 let $t092599899 = if ((size(i.payments) > 1))
246246 then {
247247 let votingRewardPayment = i.payments[1]
248248 let votingRewardPaymentAssetId = toBase58String(value(votingRewardPayment.assetId))
249249 let votingRewardPaymentAmount = value(votingRewardPayment.amount)
250250 $Tuple4(true, votingRewardPaymentAssetId, votingRewardPaymentAmount, [StringEntry(keyVotingRewardAssetId(assetId, newIndex), votingRewardPaymentAssetId), IntegerEntry(keyTotalVotingReward(assetId, newIndex), votingRewardPaymentAmount)])
251251 }
252252 else $Tuple4(false, "EMPTY", 0, nil)
253253 let isRewardExist = $t092599899._1
254254 let rewardAssetId = $t092599899._2
255255 let rewardAmount = $t092599899._3
256256 let votingRewardActions = $t092599899._4
257257 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
258258 let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
259259 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
260260 let burnWxAmount = (wxPaymentAmount - finalizeCallRewardAmount)
261261 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo), StringEntry(keyAssetImage(assetId), assetImage), Burn(wxPaymentAssetId, burnWxAmount)] ++ votingRewardActions)
262262 }
263263 else throw("Strict value is not equal to itself.")
264264 }
265265
266266
267267
268268 @Callable(i)
269269 func suggestRemove (assetId) = {
270270 let gwxAmountAtNow = getUserGwxAmountAtHeight(toString(i.caller), height)
271271 let minSuggestRemoveBalance = getIntegerValue(keyMinSuggestRemoveBalance)
272272 let wxPayment = i.payments[0]
273273 let wxPaymentAssetId = value(wxPayment.assetId)
274274 let wxPaymentAmount = value(wxPayment.amount)
275275 let tokenIsVerified = {
276276 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
277277 if ($isInstanceOf(@, "Boolean"))
278278 then @
279279 else throw(($getType(@) + " couldn't be cast to Boolean"))
280280 }
281281 let checks = [if (tokenIsVerified)
282282 then true
283283 else throwErr("token not verified"), if ((gwxAmountAtNow >= minSuggestRemoveBalance))
284284 then true
285285 else throwErr("not enough gWXes"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
286286 then true
287287 else throwErr("payment less then min for suggest")]
288288 if ((checks == checks))
289289 then {
290290 let currentIndexKey = keyCurrentIndex(assetId)
291291 let currentIndex = getInteger(currentIndexKey)
292292 let newIndex = if (isDefined(currentIndex))
293293 then (value(currentIndex) + 1)
294294 else 0
295295 let periodLength = valueOrErrorMessage(getInteger(keyPeriodLengthRemove), wrapErr("periodLengthRemove not set"))
296296 let votingEndHeight = (height + periodLength)
297297 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
298298 let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
299299 let setAssetImageAction = match getString(keyAssetImage(assetId)) {
300300 case s: String =>
301301 nil
302302 case _: Unit =>
303303 let assetsStoreAssetImage = {
304304 let @ = invoke(assetsStoreContract, "getAssetLogoREADONLY", [assetId], nil)
305305 if ($isInstanceOf(@, "String"))
306306 then @
307307 else throw(($getType(@) + " couldn't be cast to String"))
308308 }
309309 [StringEntry(keyAssetImage(assetId), assetsStoreAssetImage)]
310310 case _ =>
311311 throw("Match error")
312312 }
313313 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo)] ++ setAssetImageAction)
314314 }
315315 else throw("Strict value is not equal to itself.")
316316 }
317317
318318
319319
320320 @Callable(i)
321321 func vote (assetId,inFavor) = {
322322 let currentIndexKey = keyCurrentIndex(assetId)
323323 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
324324 let votingInfo = votingExistChecks(assetId, currentIndex)
325325 if ((votingInfo == votingInfo))
326326 then {
327327 let currentVotingEndHeight = votingInfo._2
328328 let gwxAmountAtEnd = getUserGwxAmountAtHeight(toString(i.caller), currentVotingEndHeight)
329329 let voteKey = keyVote(assetId, currentIndex, i.caller)
330330 let checks = [if ((getString(voteKey) == unit))
331331 then true
332332 else throwErr("You have already voted"), if ((gwxAmountAtEnd > 0))
333333 then true
334334 else throw("You'll not have gWX at the end of voting")]
335335 if ((checks == checks))
336336 then {
337337 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
338338 let votingInfoParts = getVotingInfoParts(votingInfoStr)
339339 let votesFor = votingInfoParts._9
340340 let votesAgainst = votingInfoParts._10
341341 let $t01356313724 = if (inFavor)
342342 then $Tuple2((votesFor + gwxAmountAtEnd), votesAgainst)
343343 else $Tuple2(votesFor, (votesAgainst + gwxAmountAtEnd))
344344 let newVotesFor = $t01356313724._1
345345 let newVotesAgainst = $t01356313724._2
346346 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
347347 let votingRewardAction = match getString(keyVotingRewardAssetId(assetId, currentIndex)) {
348348 case pk: String =>
349349 [StringEntry(keyVotingReward(i.caller, assetId, currentIndex), voteValue(inFavor, gwxAmountAtEnd))]
350350 case _: Unit =>
351351 nil
352352 case _ =>
353353 throw("Match error")
354354 }
355355 ([StringEntry(voteKey, voteValue(inFavor, gwxAmountAtEnd)), StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue)] ++ votingRewardAction)
356356 }
357357 else throw("Strict value is not equal to itself.")
358358 }
359359 else throw("Strict value is not equal to itself.")
360360 }
361361
362362
363363
364364 @Callable(i)
365365 func cancelVote (assetId) = {
366366 let currentIndexKey = keyCurrentIndex(assetId)
367367 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
368368 let voteKey = keyVote(assetId, currentIndex, i.caller)
369369 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
370370 let lastVoteParts = split(lastVote, separator)
371371 let inFavor = lastVoteParts[1]
372372 let gwxAmount = parseIntValue(lastVoteParts[2])
373373 let votingInfo = votingExistChecks(assetId, currentIndex)
374374 if ((votingInfo == votingInfo))
375375 then {
376376 let checks = [if (if ((inFavor == "true"))
377377 then true
378378 else (inFavor == "false"))
379379 then true
380380 else throwErr("invalid vote")]
381381 if ((checks == checks))
382382 then {
383383 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
384384 let votingInfoParts = getVotingInfoParts(votingInfoStr)
385385 let votesFor = votingInfoParts._9
386386 let votesAgainst = votingInfoParts._10
387387 let $t01534915510 = if ((inFavor == "true"))
388388 then $Tuple2((votesFor - gwxAmount), votesAgainst)
389389 else $Tuple2(votesFor, (votesAgainst - gwxAmount))
390390 let newVotesFor = $t01534915510._1
391391 let newVotesAgainst = $t01534915510._2
392392 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
393393 [StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), DeleteEntry(voteKey), DeleteEntry(keyVotingReward(i.caller, assetId, currentIndex))]
394394 }
395395 else throw("Strict value is not equal to itself.")
396396 }
397397 else throw("Strict value is not equal to itself.")
398398 }
399399
400400
401401
402402 @Callable(i)
403403 func finalize (assetId) = {
404404 let currentIndexKey = keyCurrentIndex(assetId)
405405 let currentIndex = valueOrElse(getInteger(currentIndexKey), 0)
406406 let votingThresholdAdd = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
407407 let votingThresholdRemove = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
408408 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
409409 let votingInfoParts = getVotingInfoParts(votingInfoStr)
410410 let votingType = votingInfoParts._4
411411 let status = votingInfoParts._5
412412 let votingEndHeight = votingInfoParts._7
413413 let votingQuorum = votingInfoParts._8
414414 let votesFor = votingInfoParts._9
415415 let votesAgainst = votingInfoParts._10
416416 let checks = [if ((status == statusInProgress))
417417 then true
418418 else throwErr("voting not in progress"), if ((height >= votingEndHeight))
419419 then true
420420 else throwErr("voting not finished"), if (isDefined(getString(keyAssetImage(assetId))))
421421 then true
422422 else throwErr("asset image not set")]
423423 if ((checks == checks))
424424 then {
425425 let votingAccepted = if (if (((votesFor + votesAgainst) >= votingQuorum))
426426 then (votesFor > votesAgainst)
427427 else false)
428428 then true
429429 else false
430430 let newStatus = if (votingAccepted)
431431 then statusAccepted
432432 else statusRejected
433433 let assetImage = getStringValue(keyAssetImage(assetId))
434434 let isVotingAccepted = if (votingAccepted)
435435 then {
436436 let votingAcceptedInvokes = if ((votingType == "verification"))
437437 then invoke(assetsStoreContract, "createOrUpdate", [assetId, assetImage, true], nil)
438- else invoke(assetsStoreContract, "setVerified", [assetId, false], nil)
438+ else [invoke(assetsStoreContract, "setVerified", [assetId, false], nil), invoke(assetsStoreContract, "onEliminate", [assetId], nil)]
439439 votingAcceptedInvokes
440440 }
441441 else nil
442442 if ((isVotingAccepted == isVotingAccepted))
443443 then {
444444 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, newStatus, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, votingInfoParts._9, votingInfoParts._10)
445445 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
446446 let suggestIssuerAddress = addressFromStringValue(getStringValue(keySuggestIssuer(assetId, currentIndex)))
447447 let votingRewardAssetIdOption = getString(keyVotingRewardAssetId(assetId, currentIndex))
448448 let totalVotingRewardOption = getInteger(keyTotalVotingReward(assetId, currentIndex))
449449 let returnRewardActions = if (if (if (votingAccepted)
450450 then true
451451 else (votingRewardAssetIdOption == unit))
452452 then true
453453 else (totalVotingRewardOption == unit))
454454 then nil
455455 else [ScriptTransfer(suggestIssuerAddress, value(totalVotingRewardOption), parseAssetId(value(votingRewardAssetIdOption)))]
456456 ([StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)] ++ returnRewardActions)
457457 }
458458 else throw("Strict value is not equal to itself.")
459459 }
460460 else throw("Strict value is not equal to itself.")
461461 }
462462
463463
464464
465465 @Callable(i)
466466 func claimREADONLY (assetId,index,userAddressStr) = {
467467 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid address"))
468468 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
469469 let rewardAmount = if (isDefined(votingRewardAssetIdStr))
470470 then calculateReward(userAddress, assetId, index)._1
471471 else 0
472472 $Tuple2(nil, rewardAmount)
473473 }
474474
475475
476476
477477 @Callable(i)
478478 func claim (assetId,index) = {
479479 let callerAddress = i.caller
480480 let claimHistoryKey = keyClaimHistory(callerAddress, assetId, index)
481481 let claimHistory = getInteger(claimHistoryKey)
482482 let checks = [if ((claimHistory == unit))
483483 then true
484484 else throwErr("already claimed")]
485485 if ((checks == checks))
486486 then {
487- let $t01951619593 = calculateReward(callerAddress, assetId, index)
488- let rewardAmount = $t01951619593._1
489- let canClaim = $t01951619593._2
487+ let $t01960019677 = calculateReward(callerAddress, assetId, index)
488+ let rewardAmount = $t01960019677._1
489+ let canClaim = $t01960019677._2
490490 if (!(canClaim))
491491 then throwErr("nothing to claim")
492492 else {
493493 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
494494 let rewardAction = if (isDefined(votingRewardAssetIdStr))
495495 then {
496496 let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
497497 [ScriptTransfer(callerAddress, rewardAmount, votingRewardAssetId), IntegerEntry(claimHistoryKey, rewardAmount), DeleteEntry(keyVotingReward(callerAddress, assetId, index))]
498498 }
499499 else throwErr("nothing to claim")
500500 rewardAction
501501 }
502502 }
503503 else throw("Strict value is not equal to itself.")
504504 }
505505
506506
507507 @Verifier(tx)
508508 func verify () = {
509509 let targetPublicKey = match managerPublicKeyOrUnit() {
510510 case pk: ByteVector =>
511511 pk
512512 case _: Unit =>
513513 tx.senderPublicKey
514514 case _ =>
515515 throw("Match error")
516516 }
517517 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
518518 }
519519

github/deemru/w8io/6500d08 
93.07 ms