tx · 5WZLzSkU8YrnK71Knck2rbhg9tvQ6AogkthRYwJDCu3t 3PQtGwmFsbKygGi8wPfUxz4bTUNgYodK3je: -0.01800000 Waves 2024.02.27 14:50 [4060412] smart account 3PQtGwmFsbKygGi8wPfUxz4bTUNgYodK3je > SELF 0.00000000 Waves
{ "type": 13, "id": "5WZLzSkU8YrnK71Knck2rbhg9tvQ6AogkthRYwJDCu3t", "fee": 1800000, "feeAssetId": null, "timestamp": 1709034583259, "version": 2, "chainId": 87, "sender": "3PQtGwmFsbKygGi8wPfUxz4bTUNgYodK3je", "senderPublicKey": "CtYpnoMZ1pX6F6Mo3Ghxuk2tz2wd4zwyxZPvELGU1pQK", "proofs": [ "38Fnk5buaLTRxmeYJ4jE7G2btzrqZ9uxTicE4TZADy6RcDK78necc3Ax6MTLgVsXHvpRLBajCr7WDKAJBh1xpEGE" ], "script": "base64:BwIoCAISBAoCAhgSBgoEAgIBARIECgICGBIECgICGBIECgICGBIECgICGDUAB2NoYWluSWQJAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEACGNoYWluSWRSAQFSAAhjaGFpbklkVAEBVAAIY2hhaW5JZFcBAVcAA1NFUAICX18ABVdBVkVTAgVXQVZFUwAQY29udHJhY3RGaWxlbmFtZQIVd3hkYW9fY2FsY3VsYXRvci5yaWRlAAVtdWx0OACAwtcvAAZtdWx0MTgJALYCAQCAgJC7utat8A0ADXdhdmVzRGVjaW1hbHMACAAMdXNkdERlY2ltYWxzAAYBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQZtdWx0MTgJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFBm11bHQxOAEHd3JhcEVycgEBcwkArAICCQCsAgIFEGNvbnRyYWN0RmlsZW5hbWUCAjogBQFzAQh0aHJvd0VycgEBcwkAAgEJAQd3cmFwRXJyAQUBcwERa2V5RmFjdG9yeUFkZHJlc3MAAhIlc19fZmFjdG9yeUFkZHJlc3MBDmZhY3RvcnlBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAckbWF0Y2gwCQCdCAIFBHRoaXMJARFrZXlGYWN0b3J5QWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yCQEHd3JhcEVycgECF2ludmFsaWQgZmFjdG9yeSBhZGRyZXNzAQtvbmx5QWRkcmVzcwIBaQdhZGRyZXNzAwkAAAIIBQFpBmNhbGxlcgUHYWRkcmVzcwYJAQh0aHJvd0VycgECEXBlcm1pc3Npb24gZGVuaWVkAQhvbmx5VGhpcwEBaQkBC29ubHlBZGRyZXNzAgUBaQUEdGhpcwELb25seUZhY3RvcnkBAWkJAQtvbmx5QWRkcmVzcwIFAWkJAQ5mYWN0b3J5QWRkcmVzcwAACXd4QXNzZXRJZAMJAAACBQdjaGFpbklkBQhjaGFpbklkVwEgkwEcq6nHbiVXzmaecba9qmv4POhYCyru2aBOuzzcFLEDCQAAAgUHY2hhaW5JZAUIY2hhaW5JZFQBIMZSHoFO6m7jPMCXsA5fLPJq6e2dsobRmkJ4qGB9PhuxCQEIdGhyb3dFcnIBAhBpbnZhbGlkIGNoYWluIGlkARBrZXlDdXJyZW50UGVyaW9kAAkAuQkCCQDMCAICAiVzCQDMCAICDWN1cnJlbnRQZXJpb2QFA25pbAUDU0VQARZrZXlTdGFydEhlaWdodEJ5UGVyaW9kAQZwZXJpb2QJALkJAgkAzAgCAgQlcyVkCQDMCAICC3N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUGcGVyaW9kBQNuaWwFA1NFUAEPa2V5UGVyaW9kTGVuZ3RoAAkAuQkCCQDMCAICAiVzCQDMCAICDHBlcmlvZExlbmd0aAUDbmlsBQNTRVABGGtleVRyZWFzdXJ5VmFsdWVCeVBlcmlvZAEGcGVyaW9kCQC5CQIJAMwIAgIEJXMlZAkAzAgCAg10cmVhc3VyeVZhbHVlCQDMCAIJAKQDAQUGcGVyaW9kBQNuaWwFA1NFUAEUa2V5TG9ja0dsb2JhbENvdW50ZXIACQC5CQIJAMwIAgICJXMJAMwIAgIRbG9ja0dsb2JhbENvdW50ZXIFA25pbAUDU0VQAQ9rZXlMb2NrRHVyYXRpb24ACQC5CQIJAMwIAgICJXMJAMwIAgIMbG9ja0R1cmF0aW9uBQNuaWwFA1NFUAEHa2V5TG9jawILdXNlckFkZHJlc3MHY291bnRlcgkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgRsb2NrCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgkApAMBBQdjb3VudGVyBQNuaWwFA1NFUAEMa2V5U2tpblRvdGFsAQ90cmVhc3VyeUFkZHJlc3MJAKwCAgILc2tpbl90b3RhbF8JAKUIAQUPdHJlYXN1cnlBZGRyZXNzARVrZXlQb3dlckNvbmZpZ0FkZHJlc3MAAhYlc19fcG93ZXJDb25maWdBZGRyZXNzARJwb3dlckNvbmZpZ0FkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIEByRtYXRjaDAJAJ0IAgkBDmZhY3RvcnlBZGRyZXNzAAkBFWtleVBvd2VyQ29uZmlnQWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yCQEHd3JhcEVycgECHGludmFsaWQgcG93ZXIgY29uZmlnIGFkZHJlc3MBD2tleVBvd2VyQXNzZXRJZAACDHBvd2VyQXNzZXRJZAEPZ2V0UG93ZXJBc3NldElkAAkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBEnBvd2VyQ29uZmlnQWRkcmVzcwAJAQ9rZXlQb3dlckFzc2V0SWQACQEHd3JhcEVycgECFmludmFsaWQgcG93ZXIgYXNzZXQgaWQBF2tleVBvd2VyQ29udHJhY3RBZGRyZXNzAAIYJXNfX3Bvd2VyQ29udHJhY3RBZGRyZXNzARRwb3dlckNvbnRyYWN0QWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQHJG1hdGNoMAkAnQgCCQEOZmFjdG9yeUFkZHJlc3MACQEXa2V5UG93ZXJDb250cmFjdEFkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgkBB3dyYXBFcnIBAh5pbnZhbGlkIHBvd2VyIGNvbnRyYWN0IGFkZHJlc3MBDmtleUxvY2tBZGRyZXNzAAIPJXNfX2xvY2tBZGRyZXNzAQtsb2NrQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQHJG1hdGNoMAkAnQgCCQEOZmFjdG9yeUFkZHJlc3MACQEOa2V5TG9ja0FkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgkBB3dyYXBFcnIBAh1pbnZhbGlkIGxvY2sgY29udHJhY3QgYWRkcmVzcwEWa2V5UG9vbHNGYWN0b3J5QWRkcmVzcwACFyVzX19wb29sc0ZhY3RvcnlBZGRyZXNzARZnZXRQb29sc0ZhY3RvcnlBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAckbWF0Y2gwCQCdCAIJAQ5mYWN0b3J5QWRkcmVzcwAJARZrZXlQb29sc0ZhY3RvcnlBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAKYIAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IJAQd3cmFwRXJyAQIdaW52YWxpZCBwb29scyBmYWN0b3J5IGFkZHJlc3MBEmtleVRyZWFzdXJ5QWRkcmVzcwACEyVzX190cmVhc3VyeUFkZHJlc3MBEmdldFRyZWFzdXJ5QWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQHJG1hdGNoMAkAnQgCCQEOZmFjdG9yeUFkZHJlc3MACQESa2V5VHJlYXN1cnlBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAKYIAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IJAQd3cmFwRXJyAQIYaW52YWxpZCB0cmVhc3VyeSBhZGRyZXNzAQlrZXlBc3NldHMAAgolc19fYXNzZXRzAQxnZXRBc3NldHNTdHIACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBDmZhY3RvcnlBZGRyZXNzAAkBCWtleUFzc2V0cwAJAQd3cmFwRXJyAQIOaW52YWxpZCBhc3NldHMBDGtleUxwQXNzZXRJZAACDSVzX19scEFzc2V0SWQBDGdldExwQXNzZXRJZAAJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQ5mYWN0b3J5QWRkcmVzcwAJAQxrZXlMcEFzc2V0SWQACQEHd3JhcEVycgECE2ludmFsaWQgbHAgYXNzZXQgaWQBEmdldEFzc2V0SW5mb09yRmFpbAEHYXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFB2Fzc2V0SWQJAQd3cmFwRXJyAQISaW52YWxpZCBhc3NldCBpbmZvAQpsb2NrRm9ybWF0BQRmcm9tAnRvB2Fzc2V0SWQGYW1vdW50DWxwQXNzZXRBbW91bnQJALkJAgkAzAgCAgolZCVkJXMlZCVkCQDMCAIJAKQDAQUEZnJvbQkAzAgCCQCkAwEFAnRvCQDMCAIJANgEAQUHYXNzZXRJZAkAzAgCCQCkAwEFBmFtb3VudAkAzAgCCQCkAwEFDWxwQXNzZXRBbW91bnQFA25pbAUDU0VQAQlsb2NrUGFyc2UBAXMEBXBhcnRzCQC1CQIFAXMFA1NFUAkAlgoECQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQVwYXJ0cwABCQEHd3JhcEVycgECKWVycm9yIGR1cmluZyBwcm9jZXNzaW5nIGxvY2sgc3RhcnQgaGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQVwYXJ0cwACCQEHd3JhcEVycgECJ2Vycm9yIGR1cmluZyBwcm9jZXNzaW5nIGxvY2sgZW5kIGhlaWdodAkA2QQBCQCRAwIFBXBhcnRzAAMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFBXBhcnRzAAQJAQd3cmFwRXJyAQIjZXJyb3IgZHVyaW5nIHByb2Nlc3NpbmcgbG9jayBhbW91bnQBEWdldEFzc2V0c0JhbGFuY2VzAg10YXJnZXRBZGRyZXNzC2Fzc2V0SWRMaXN0CgEDbWFwAgNhY2MObmV4dEFzc2V0SWRTdHIEB2JhbGFuY2UDCQAAAgUObmV4dEFzc2V0SWRTdHIFBVdBVkVTCQEFdG9YMTgCCAkA7wcBBQ10YXJnZXRBZGRyZXNzCWF2YWlsYWJsZQkAbAYACgAABQ13YXZlc0RlY2ltYWxzAAAAAAUERE9XTgQHYXNzZXRJZAkA2QQBBQ5uZXh0QXNzZXRJZFN0cgQNYXNzZXREZWNpbWFscwgJARJnZXRBc3NldEluZm9PckZhaWwBBQdhc3NldElkCGRlY2ltYWxzCQEFdG9YMTgCCQDwBwIFDXRhcmdldEFkZHJlc3MFB2Fzc2V0SWQJAGwGAAoAAAUNYXNzZXREZWNpbWFscwAAAAAFBERPV04JAM0IAgUDYWNjBQdiYWxhbmNlCgACJGwFC2Fzc2V0SWRMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtYXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBD2dldEFzc2V0c1ByaWNlcwITcG9vbHNGYWN0b3J5QWRkcmVzcwthc3NldElkTGlzdAMJAAACBQdjaGFpbklkBQhjaGFpbklkVwQTd2F2ZXNVc2R0QWRkcmVzc1N0cgIjM1BLZnJ1cEV5ZFUyblpBZ2hWalpBZnZDd01Ca3p1UjFGNTIEDndhdmVzVXNkdFByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFE3dhdmVzVXNkdEFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQSd2F2ZXNYdG5BZGRyZXNzU3RyAiMzUFBaV2dGTlJLSEx2TTUxcHdTOTM0QzhWWjdkMkY0WjU4ZwQNd2F2ZXNYdG5QcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRJ3YXZlc1h0bkFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQMeHRuVXNkdFByaWNlCQC8AgMFDndhdmVzVXNkdFByaWNlBQZtdWx0MTgFDXdhdmVzWHRuUHJpY2UKAQNtYXACA2FjYwtuZXh0QXNzZXRJZAQFcHJpY2UEByRtYXRjaDAFC25leHRBc3NldElkAwkAAAICLDJ0aHNBQ3VIbXpETXVOZXpQTTMyd2c5YTNCd1V6QldEZVNLYWtnejNjdzIxBQckbWF0Y2gwBBJwd3JXYXZlc0FkZHJlc3NTdHICIzNQRGk3UXE4cExRWXZ0S3lUZlF1cXFQVVd5aG9ZYlU5NTd0BA1wd3JXYXZlc1ByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFEnB3cldhdmVzQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDXB3cldhdmVzUHJpY2UFDndhdmVzVXNkdFByaWNlBQZtdWx0MTgDCQAAAgIsQXRxdjU5RVl6akZHdWl0S1ZuTVJrNkg4RnVram9WM2t0UG9yYkV5czI1b24FByRtYXRjaDAEEXd4V2F2ZXNBZGRyZXNzU3RyAiMzUEZ6YUgyZ2hwd0FOSEZnamV2YTgzTjF5eHpFckVMeDJlaAQMd3hXYXZlc1ByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFEXd4V2F2ZXNBZGRyZXNzU3RyBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJALwCAwUMd3hXYXZlc1ByaWNlBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4AwkAAAICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKBQckbWF0Y2gwBBZ3YXZlc1VzZHR3eGdBZGRyZXNzU3RyAiMzUEtNVlo3a1FlYVJFYWpZaThZYzI1Um82bWNOdzVENlFTYQQRd2F2ZXNVc2R0d3hnUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUWd2F2ZXNVc2R0d3hnQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDndhdmVzVXNkdFByaWNlBQZtdWx0MTgFEXdhdmVzVXNkdHd4Z1ByaWNlAwkAAAICLDZYdEhqcFhiczlSUkpQMlNyOUdVeVZxekFDY2J5OVRrVGhIWG5qVkM1Q0RKBQckbWF0Y2gwBBZ3YXZlc1VzZGN3eGdBZGRyZXNzU3RyAiMzUDNnM2VpcGZHMk5aS0tRRThEWlh0MkU5dFJKcWlpOWpjWAQRd2F2ZXNVc2Rjd3hnUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUWd2F2ZXNVc2Rjd3hnQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDndhdmVzVXNkdFByaWNlBQZtdWx0MTgFEXdhdmVzVXNkY3d4Z1ByaWNlAwkAAAICLEhaazFtYmZ1SnBteFUxRnM0QVg1TVdMVll0Y3RzTmNnNmUyQzZWS3FLOHprBQckbWF0Y2gwBBNsdGN3eGdYdG5BZGRyZXNzU3RyAiMzUDk0d3Z1NWdBN1ZoalBnQUIzdHdhZXFkd0hDd05LMnZzbgQObHRjd3hnWHRuUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUTbHRjd3hnWHRuQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDmx0Y3d4Z1h0blByaWNlBQx4dG5Vc2R0UHJpY2UFBm11bHQxOAMJAAACAiw0NzRqVGVZeDJyMlZhMzU3OTR0Q1NjQVhXSkc5aFUySGNneHpNb3dhWlVudQUHJG1hdGNoMAQVZXRod3hnV2F2ZXNBZGRyZXNzU3RyAiMzUDNYR1RONnMyOTJnOWl3WWhzM1RFcUpxSGlmZlFZb2p1RQQQZXRod3hnV2F2ZXNQcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRVldGh3eGdXYXZlc0FkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBRBldGh3eGdXYXZlc1ByaWNlBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4AwkAAAICLDhMUVc4ZjdQNWQ1UFpNN0d0WkVCZ2FxUlBHU3pTM0RmUHVpWHJVUko0QUpTBQckbWF0Y2gwBBNidGN3eGdYdG5BZGRyZXNzU3RyAiMzUENCV0RUQTZqckZzd2Q3Z1FnYUUzWGs3Z0xNNVJLb2Z2cAQOYnRjd3hnWHRuUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUTYnRjd3hnWHRuQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDmJ0Y3d4Z1h0blByaWNlBQx4dG5Vc2R0UHJpY2UFBm11bHQxOAkBCHRocm93RXJyAQIQaW52YWxpZCBhc3NldCBpZAkAzQgCBQNhY2MFBXByaWNlCgACJGwFC2Fzc2V0SWRMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtYXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQAAAgUHY2hhaW5JZAUIY2hhaW5JZFQKAQNtYXACA2FjYwtuZXh0QXNzZXRJZAQFcHJpY2UEByRtYXRjaDAFC25leHRBc3NldElkAwkAAAICLEVNQU1MeERudjN4aXo4UlhnOEJ0ajMzamNFdzN3TGN6TDNKS1lZbXV1YnBjBQckbWF0Y2gwBBB3eFVzZHRBZGRyZXNzU3RyAiMzTXJVTFFSTGM1MkdXckpGMXRNY0FtNE03OGZQZTU3bzlLdAQLd3hVc2R0UHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUQd3hVc2R0QWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBQt3eFVzZHRQcmljZQMJAAACAixBN0tzaDdmWHlxbTFLaEtBaUszYkFCMmFpUFNpdFFRRjZ2MXB5dTlTUzNGUgUHJG1hdGNoMAQSdXNkY1VzZHRBZGRyZXNzU3RyAiMzTXpLU2RUSDJqRmJ5cExzb05mckg3UWdrelNieDNFWXdDQQQNdXNkY1VzZHRQcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRJ1c2RjVXNkdEFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwUNdXNkY1VzZHRQcmljZQMJAAACAiw4UTZTRTJBTmVidWZ3OEp1UGpKVlJqWkQ2ZHJEOGloak5qTTh4YUdVU2ZkUgUHJG1hdGNoMAQFcHJpY2UJAQV0b1gxOAIAgKPDRwkAbAYACgAABQx1c2R0RGVjaW1hbHMAAAAABQRET1dOBQVwcmljZQkBCHRocm93RXJyAQIQaW52YWxpZCBhc3NldCBpZAkAzQgCBQNhY2MFBXByaWNlCgACJGwFC2Fzc2V0SWRMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtYXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAQh0aHJvd0VycgECEGludmFsaWQgY2hhaW4gaWQBEWNhbGNUcmVhc3VyeVZhbHVlAAQPdHJlYXN1cnlBZGRyZXNzCQESZ2V0VHJlYXN1cnlBZGRyZXNzAAQTcG9vbHNGYWN0b3J5QWRkcmVzcwkBFmdldFBvb2xzRmFjdG9yeUFkZHJlc3MABAlhc3NldHNTdHIJALUJAgkBDGdldEFzc2V0c1N0cgAFA1NFUAQOYXNzZXRzQmFsYW5jZXMJARFnZXRBc3NldHNCYWxhbmNlcwIFD3RyZWFzdXJ5QWRkcmVzcwUJYXNzZXRzU3RyBAxhc3NldHNQcmljZXMJAQ9nZXRBc3NldHNQcmljZXMCBRNwb29sc0ZhY3RvcnlBZGRyZXNzBQlhc3NldHNTdHIKAQZyZWR1Y2UCA2FjYw5uZXh0QXNzZXRJZFN0cgQHYXNzZXRJZAkA2QQBBQ5uZXh0QXNzZXRJZFN0cgQFaW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQlhc3NldHNTdHIFDm5leHRBc3NldElkU3RyCQEHd3JhcEVycgECEGludmFsaWQgYXNzZXQgaWQEB2JhbGFuY2UJAJEDAgUOYXNzZXRzQmFsYW5jZXMFBWluZGV4BAVwcmljZQkAkQMCBQxhc3NldHNQcmljZXMFBWluZGV4BAphc3NldFZhbHVlCQC8AgMFB2JhbGFuY2UFBXByaWNlBQZtdWx0MTgJALcCAgUDYWNjBQphc3NldFZhbHVlBA10cmVhc3VyeVZhbHVlCgACJGwFCWFzc2V0c1N0cgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJALYCAQAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZyZWR1Y2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoFDXRyZWFzdXJ5VmFsdWUBEmNhbGNSZXdhcmRzQW5kTG9jawINcGF5bWVudEFtb3VudBF1c2VyQWRkcmVzc09wdGlvbgQJYXNzZXRzU3RyCQC1CQIJAQxnZXRBc3NldHNTdHIABQNTRVAEDXd4ZGFvUXVhbnRpdHkICQESZ2V0QXNzZXRJbmZvT3JGYWlsAQkBDGdldExwQXNzZXRJZAAIcXVhbnRpdHkDCQAAAgUNd3hkYW9RdWFudGl0eQUNd3hkYW9RdWFudGl0eQQOYXNzZXRzQmFsYW5jZXMJARFnZXRBc3NldHNCYWxhbmNlcwIJAQ5mYWN0b3J5QWRkcmVzcwAFCWFzc2V0c1N0cgoBA21hcAIDYWNjDm5leHRBc3NldElkU3RyBAdhc3NldElkCQDZBAEFDm5leHRBc3NldElkU3RyBAVpbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCWFzc2V0c1N0cgUObmV4dEFzc2V0SWRTdHIJAQd3cmFwRXJyAQIVaW52YWxpZCBhc3NldCBiYWxhbmNlBA1hc3NldERlY2ltYWxzCAkBEmdldEFzc2V0SW5mb09yRmFpbAEFB2Fzc2V0SWQIZGVjaW1hbHMEB2JhbGFuY2UJAQdmcm9tWDE4AgkAkQMCBQ5hc3NldHNCYWxhbmNlcwUFaW5kZXgJAGwGAAoAAAUNYXNzZXREZWNpbWFscwAAAAAFBERPV04EBmFtb3VudAkAawMFB2JhbGFuY2UFDXBheW1lbnRBbW91bnQFDXd4ZGFvUXVhbnRpdHkDCQBmAgUGYW1vdW50AAAEBGxvY2sDCQAAAgURdXNlckFkZHJlc3NPcHRpb24FBHVuaXQFBHVuaXQJAPwHBAUEdGhpcwIMbG9ja0ludGVybmFsCQDMCAIICQEFdmFsdWUBBRF1c2VyQWRkcmVzc09wdGlvbgVieXRlcwkAzAgCBQdhc3NldElkCQDMCAIFBmFtb3VudAkAzAgCBQ1wYXltZW50QW1vdW50BQNuaWwFA25pbAMJAAACBQRsb2NrBQRsb2NrCQCUCgIJAM0IAggFA2FjYwJfMQUHYXNzZXRJZAkAzQgCCAUDYWNjAl8yBQZhbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA2FjYwoAAiRsBQlhc3NldHNTdHIKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtYXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BCWNhbGNQcmljZQAEE3Bvb2xzRmFjdG9yeUFkZHJlc3MJARZnZXRQb29sc0ZhY3RvcnlBZGRyZXNzAAQNY3VycmVudFBlcmlvZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIJAQ5mYWN0b3J5QWRkcmVzcwAJARBrZXlDdXJyZW50UGVyaW9kAAkBB3dyYXBFcnIBAhZpbnZhbGlkIGN1cnJlbnQgcGVyaW9kBBJzdGFydFRyZWFzdXJ5VmFsdWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCCQEOZmFjdG9yeUFkZHJlc3MACQEYa2V5VHJlYXN1cnlWYWx1ZUJ5UGVyaW9kAQUNY3VycmVudFBlcmlvZAkBB3dyYXBFcnIBCQCsAgICImludmFsaWQgdHJlYXN1cnkgdmFsdWUgZm9yIHBlcmlvZCAJAKQDAQUNY3VycmVudFBlcmlvZAQNdHJlYXN1cnlWYWx1ZQkBB2Zyb21YMTgCCQERY2FsY1RyZWFzdXJ5VmFsdWUACQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04EEXRyZWFzdXJ5VmFsdWVEaWZmCQBlAgUNdHJlYXN1cnlWYWx1ZQUSc3RhcnRUcmVhc3VyeVZhbHVlBBR0cmVhc3VyeVZhbHVlRGlmZlgxOAkBBXRvWDE4AgURdHJlYXN1cnlWYWx1ZURpZmYJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgQKcHdyQXNzZXRJZAkBD2dldFBvd2VyQXNzZXRJZAAEB3B3ckluZm8JARJnZXRBc3NldEluZm9PckZhaWwBBQpwd3JBc3NldElkBAtwd3JQcmljZVgxOAkAkQMCCQEPZ2V0QXNzZXRzUHJpY2VzAgUTcG9vbHNGYWN0b3J5QWRkcmVzcwkAzAgCCQDYBAEFCnB3ckFzc2V0SWQFA25pbAAABAhwd3JQcmljZQMJAL8CAgULcHdyUHJpY2VYMTgJALYCAQAACQEHZnJvbVgxOAIFC3B3clByaWNlWDE4CQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04JAQh0aHJvd0VycgECEWludmFsaWQgUFdSIHByaWNlBA90cmVhc3VyeUFkZHJlc3MJARJnZXRUcmVhc3VyeUFkZHJlc3MABAlza2luVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgkBFHBvd2VyQ29udHJhY3RBZGRyZXNzAAkBDGtleVNraW5Ub3RhbAEFD3RyZWFzdXJ5QWRkcmVzcwAABAl3eGRhb0luZm8JARJnZXRBc3NldEluZm9PckZhaWwBCQEMZ2V0THBBc3NldElkAAQMcHdyUmVtYWluaW5nCQBpAggFCXd4ZGFvSW5mbwhxdWFudGl0eQBkBAlwd3JBbW91bnQJAGQCBQlza2luVG90YWwFDHB3clJlbWFpbmluZwQMcHdyQW1vdW50WDE4CQEFdG9YMTgCBQlwd3JBbW91bnQJAGwGAAoAAAgFB3B3ckluZm8IZGVjaW1hbHMAAAAABQRET1dOBBpmYWN0b3J5QWRkcmVzc1d4QmFsYW5jZVgxOAkAkQMCCQERZ2V0QXNzZXRzQmFsYW5jZXMCCQEOZmFjdG9yeUFkZHJlc3MACQDMCAIJANgEAQUJd3hBc3NldElkBQNuaWwAAAQXZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2UJAQdmcm9tWDE4AgUaZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2VYMTgJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgQKd3hQcmljZVgxOAkAkQMCCQEPZ2V0QXNzZXRzUHJpY2VzAgUTcG9vbHNGYWN0b3J5QWRkcmVzcwkAzAgCCQDYBAEFCXd4QXNzZXRJZAUDbmlsAAAEB3d4UHJpY2UDCQC/AgIFCnd4UHJpY2VYMTgJALYCAQAACQEHZnJvbVgxOAIFCnd4UHJpY2VYMTgJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgkBCHRocm93RXJyAQIQaW52YWxpZCB3eCBwcmljZQQNd3hkYW9RdWFudGl0eQgFCXd4ZGFvSW5mbwhxdWFudGl0eQQQd3hkYW9RdWFudGl0eVgxOAkBBXRvWDE4AgUNd3hkYW9RdWFudGl0eQkAbAYACgAACAUJd3hkYW9JbmZvCGRlY2ltYWxzAAAAAAUERE9XTgQNd3hEYW9QcmljZVgxOAkAugICCQC3AgIJALcCAgULcHdyUHJpY2VYMTgJALwCAwkAuQICBRpmYWN0b3J5QWRkcmVzc1d4QmFsYW5jZVgxOAkAtgIBAGQFCnd4UHJpY2VYMTgFEHd4ZGFvUXVhbnRpdHlYMTgJALwCAwkAmAMBCQDMCAIFFHRyZWFzdXJ5VmFsdWVEaWZmWDE4CQDMCAIJALYCAQAABQNuaWwJALkCAgkAtgIBAAIFBm11bHQxOAkAuQICCQC2AgEACgUMcHdyQW1vdW50WDE4CQC2AgEAZAQKd3hEYW9QcmljZQkBB2Zyb21YMTgCBQ13eERhb1ByaWNlWDE4CQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04EDXJld2FyZHNQcmljZXMJARJjYWxjUmV3YXJkc0FuZExvY2sCCQBsBgAKAAAIBQl3eGRhb0luZm8IZGVjaW1hbHMAAAAABQRET1dOBQR1bml0CQCUCgIJAMwIAgUKd3hEYW9QcmljZQkAzAgCBQ1yZXdhcmRzUHJpY2VzBQNuaWwJAMwIAgkAzAgCAgp3eERhb1ByaWNlCQDMCAIFCnd4RGFvUHJpY2UFA25pbAkAzAgCCQDMCAICCHB3clByaWNlCQDMCAIFCHB3clByaWNlBQNuaWwJAMwIAgkAzAgCAhdmYWN0b3J5QWRkcmVzc1d4QmFsYW5jZQkAzAgCBRdmYWN0b3J5QWRkcmVzc1d4QmFsYW5jZQUDbmlsCQDMCAIJAMwIAgIHd3hQcmljZQkAzAgCBQd3eFByaWNlBQNuaWwJAMwIAgkAzAgCAg13eGRhb1F1YW50aXR5CQDMCAIFDXd4ZGFvUXVhbnRpdHkFA25pbAkAzAgCCQDMCAICEXRyZWFzdXJ5VmFsdWVEaWZmCQDMCAIFEXRyZWFzdXJ5VmFsdWVEaWZmBQNuaWwJAMwIAgkAzAgCAglwd3JBbW91bnQJAMwIAgUJcHdyQW1vdW50BQNuaWwJAMwIAgkAzAgCAglza2luVG90YWwJAMwIAgUJc2tpblRvdGFsBQNuaWwJAMwIAgkAzAgCAgxwd3JSZW1haW5pbmcJAMwIAgUMcHdyUmVtYWluaW5nBQNuaWwFA25pbAYBaQEEc3dhcAIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2NoZWNrQ2FsbGVyCQELb25seUZhY3RvcnkBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BAdwYXltZW50AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQkAkQMCCAUBaQhwYXltZW50cwAACQEIdGhyb3dFcnIBAhUxIHBheW1lbnQgaXMgcmVxdWlyZWQEA2VycgkBB3dyYXBFcnIBAhhpbnZhbGlkIHBheW1lbnQgYXNzZXQgaWQEDnBheW1lbnRBc3NldElkAwkAAAIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggFB3BheW1lbnQHYXNzZXRJZAUDZXJyCQEMZ2V0THBBc3NldElkAAkBBXZhbHVlAQgFB3BheW1lbnQHYXNzZXRJZAkBCHRocm93RXJyAQUDZXJyBAhwd3JQcmljZQBkBAlwd3JBbW91bnQJAGkCCAUHcGF5bWVudAZhbW91bnQFCHB3clByaWNlBAdyZXdhcmRzCQESY2FsY1Jld2FyZHNBbmRMb2NrAggFB3BheW1lbnQGYW1vdW50BQt1c2VyQWRkcmVzcwMJAAACBQdyZXdhcmRzBQdyZXdhcmRzBBRhZGRpdGlvbmFsTG9ja1JvdW5kcwAABA5mYWN0b3J5QWN0aW9ucwkAzAgCCQD8BwQJAQ5mYWN0b3J5QWRkcmVzcwACIGNvbW1pdEFmdGVyU3RhcnRXaXRoTG9ja1JvdW5kRm9yCQDMCAIJAKUIAQkBFHBvd2VyQ29udHJhY3RBZGRyZXNzAAkAzAgCCQClCAEJARJnZXRUcmVhc3VyeUFkZHJlc3MACQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgUUYWRkaXRpb25hbExvY2tSb3VuZHMJAMwIAgkBD2dldFBvd2VyQXNzZXRJZAAJAMwIAgUJcHdyQW1vdW50BQNuaWwFA25pbAUDbmlsCQCUCgIJAMwIAgkBBEJ1cm4CBQ5wYXltZW50QXNzZXRJZAgFB3BheW1lbnQGYW1vdW50BQNuaWwFDmZhY3RvcnlBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDGxvY2tJbnRlcm5hbAQQdXNlckFkZHJlc3NCeXRlcwdhc3NldElkBmFtb3VudA1scEFzc2V0QW1vdW50BAtjaGVja0NhbGxlcgkBCG9ubHlUaGlzAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEC3VzZXJBZGRyZXNzCQEHQWRkcmVzcwEFEHVzZXJBZGRyZXNzQnl0ZXMEEWxvY2tHbG9iYWxDb3VudGVyCQELdmFsdWVPckVsc2UCCQCaCAIJAQ5mYWN0b3J5QWRkcmVzcwAJARRrZXlMb2NrR2xvYmFsQ291bnRlcgAAAAQMbG9ja0R1cmF0aW9uCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgkBDmZhY3RvcnlBZGRyZXNzAAkBD2tleUxvY2tEdXJhdGlvbgAJAQd3cmFwRXJyAQIVaW52YWxpZCBsb2NrIGR1cmF0aW9uBAlnZXRBc3NldHMJAPwHBAkBDmZhY3RvcnlBZGRyZXNzAAINdHJhbnNmZXJBc3NldAkAzAgCCAkBC2xvY2tBZGRyZXNzAAVieXRlcwkAzAgCBQZhbW91bnQJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUJZ2V0QXNzZXRzBQlnZXRBc3NldHMEDmZhY3RvcnlBY3Rpb25zCQDMCAIJAPwHBAkBDmZhY3RvcnlBZGRyZXNzAAILc3RyaW5nRW50cnkJAMwIAgkBB2tleUxvY2sCBQt1c2VyQWRkcmVzcwURbG9ja0dsb2JhbENvdW50ZXIJAMwIAgkBCmxvY2tGb3JtYXQFBQZoZWlnaHQJAGQCBQZoZWlnaHQFDGxvY2tEdXJhdGlvbgUHYXNzZXRJZAUGYW1vdW50BQ1scEFzc2V0QW1vdW50BQNuaWwFA25pbAkAzAgCCQD8BwQJAQ5mYWN0b3J5QWRkcmVzcwACDGludGVnZXJFbnRyeQkAzAgCCQEUa2V5TG9ja0dsb2JhbENvdW50ZXIACQDMCAIJAGQCBRFsb2NrR2xvYmFsQ291bnRlcgABBQNuaWwFA25pbAUDbmlsCQCUCgIFA25pbAUOZmFjdG9yeUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEGdW5sb2NrAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQLY2hlY2tDYWxsZXIJAQtvbmx5RmFjdG9yeQEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyBAt1c2VyQWRkcmVzcwkApwgBBQ9jYWxsZXJQdWJsaWNLZXkKAQRmb2xkAgNhY2MEbmV4dAQHY291bnRlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFBG5leHQJAQd3cmFwRXJyAQIPaW52YWxpZCBjb3VudGVyBA0kdDAxNzYzOTE3ODQ4CQEJbG9ja1BhcnNlAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQ5mYWN0b3J5QWRkcmVzcwAJAQdrZXlMb2NrAgULdXNlckFkZHJlc3MFB2NvdW50ZXIJAQd3cmFwRXJyAQkArAICAg5pbnZhbGlkIGxvY2s6IAkBB2tleUxvY2sCBQt1c2VyQWRkcmVzcwUHY291bnRlcgQEZnJvbQgFDSR0MDE3NjM5MTc4NDgCXzEEAnRvCAUNJHQwMTc2MzkxNzg0OAJfMgQHYXNzZXRJZAgFDSR0MDE3NjM5MTc4NDgCXzMEBmFtb3VudAgFDSR0MDE3NjM5MTc4NDgCXzQEBnJlc3VsdAMJAGYCBQZoZWlnaHQFAnRvCQDMCAIJAPwHBAkBC2xvY2tBZGRyZXNzAAINdHJhbnNmZXJBc3NldAkAzAgCCAULdXNlckFkZHJlc3MFYnl0ZXMJAMwIAgUGYW1vdW50CQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsCQDMCAIJAPwHBAkBDmZhY3RvcnlBZGRyZXNzAAILZGVsZXRlRW50cnkJAMwIAgkBB2tleUxvY2sCBQt1c2VyQWRkcmVzcwUHY291bnRlcgUDbmlsBQNuaWwFA25pbAkBCHRocm93RXJyAQIOaW52YWxpZCBoZWlnaHQJAM0IAgUDYWNjBQZyZXN1bHQEBnJlc3VsdAoAAiRsBQRhcmdzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQRmb2xkAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAzMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgkAlAoCBQNuaWwFBnJlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVwcmljZQIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2NoZWNrQ2FsbGVyCQELb25seUZhY3RvcnkBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAlAoCBQNuaWwICQEJY2FsY1ByaWNlAAJfMQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpwcmljZURlYnVnAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQLY2hlY2tDYWxsZXIJAQtvbmx5RmFjdG9yeQEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyCQCUCgIFA25pbAgJAQljYWxjUHJpY2UAAl8yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEGdldFRyZWFzdXJ5VmFsdWUCD2NhbGxlclB1YmxpY0tleQRhcmdzBAtjaGVja0NhbGxlcgkBC29ubHlGYWN0b3J5AQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEDXRyZWFzdXJ5VmFsdWUJAQdmcm9tWDE4AgkBEWNhbGNUcmVhc3VyeVZhbHVlAAkAbAYACgAABQx1c2R0RGVjaW1hbHMAAAAABQRET1dOCQCUCgIFA25pbAUNdHJlYXN1cnlWYWx1ZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQADCQAAAgUHY2hhaW5JZAUIY2hhaW5JZFQGCQAAAgUHY2hhaW5JZAUIY2hhaW5JZFKLtctf", "height": 4060412, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 7 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let chainId = take(drop(this.bytes, 1), 1) | |
5 | + | ||
6 | + | let chainIdR = base58'2R' | |
7 | + | ||
8 | + | let chainIdT = base58'2T' | |
9 | + | ||
10 | + | let chainIdW = base58'2W' | |
11 | + | ||
12 | + | let SEP = "__" | |
13 | + | ||
14 | + | let WAVES = "WAVES" | |
15 | + | ||
16 | + | let contractFilename = "wxdao_calculator.ride" | |
17 | + | ||
18 | + | let mult8 = 100000000 | |
19 | + | ||
20 | + | let mult18 = toBigInt(1000000000000000000) | |
21 | + | ||
22 | + | let wavesDecimals = 8 | |
23 | + | ||
24 | + | let usdtDecimals = 6 | |
25 | + | ||
26 | + | func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), mult18, toBigInt(origScaleMult)) | |
27 | + | ||
28 | + | ||
29 | + | func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), mult18)) | |
30 | + | ||
31 | + | ||
32 | + | func wrapErr (s) = ((contractFilename + ": ") + s) | |
33 | + | ||
34 | + | ||
35 | + | func throwErr (s) = throw(wrapErr(s)) | |
36 | + | ||
37 | + | ||
38 | + | func keyFactoryAddress () = "%s__factoryAddress" | |
39 | + | ||
40 | + | ||
41 | + | func factoryAddress () = valueOrErrorMessage(match getString(this, keyFactoryAddress()) { | |
42 | + | case s: String => | |
43 | + | addressFromString(s) | |
44 | + | case _: Unit => | |
45 | + | unit | |
46 | + | case _ => | |
47 | + | throw("Match error") | |
48 | + | }, wrapErr("invalid factory address")) | |
49 | + | ||
50 | + | ||
51 | + | func onlyAddress (i,address) = if ((i.caller == address)) | |
52 | + | then true | |
53 | + | else throwErr("permission denied") | |
54 | + | ||
55 | + | ||
56 | + | func onlyThis (i) = onlyAddress(i, this) | |
57 | + | ||
58 | + | ||
59 | + | func onlyFactory (i) = onlyAddress(i, factoryAddress()) | |
60 | + | ||
61 | + | ||
62 | + | let wxAssetId = if ((chainId == chainIdW)) | |
63 | + | then base58'Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on' | |
64 | + | else if ((chainId == chainIdT)) | |
65 | + | then base58'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc' | |
66 | + | else throwErr("invalid chain id") | |
67 | + | ||
68 | + | func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP) | |
69 | + | ||
70 | + | ||
71 | + | func keyStartHeightByPeriod (period) = makeString(["%s%d", "startHeight", toString(period)], SEP) | |
72 | + | ||
73 | + | ||
74 | + | func keyPeriodLength () = makeString(["%s", "periodLength"], SEP) | |
75 | + | ||
76 | + | ||
77 | + | func keyTreasuryValueByPeriod (period) = makeString(["%s%d", "treasuryValue", toString(period)], SEP) | |
78 | + | ||
79 | + | ||
80 | + | func keyLockGlobalCounter () = makeString(["%s", "lockGlobalCounter"], SEP) | |
81 | + | ||
82 | + | ||
83 | + | func keyLockDuration () = makeString(["%s", "lockDuration"], SEP) | |
84 | + | ||
85 | + | ||
86 | + | func keyLock (userAddress,counter) = makeString(["%s%s%d", "lock", toString(userAddress), toString(counter)], SEP) | |
87 | + | ||
88 | + | ||
89 | + | func keySkinTotal (treasuryAddress) = ("skin_total_" + toString(treasuryAddress)) | |
90 | + | ||
91 | + | ||
92 | + | func keyPowerConfigAddress () = "%s__powerConfigAddress" | |
93 | + | ||
94 | + | ||
95 | + | func powerConfigAddress () = valueOrErrorMessage(match getString(factoryAddress(), keyPowerConfigAddress()) { | |
96 | + | case s: String => | |
97 | + | addressFromString(s) | |
98 | + | case _: Unit => | |
99 | + | unit | |
100 | + | case _ => | |
101 | + | throw("Match error") | |
102 | + | }, wrapErr("invalid power config address")) | |
103 | + | ||
104 | + | ||
105 | + | func keyPowerAssetId () = "powerAssetId" | |
106 | + | ||
107 | + | ||
108 | + | func getPowerAssetId () = fromBase58String(valueOrErrorMessage(getString(powerConfigAddress(), keyPowerAssetId()), wrapErr("invalid power asset id"))) | |
109 | + | ||
110 | + | ||
111 | + | func keyPowerContractAddress () = "%s__powerContractAddress" | |
112 | + | ||
113 | + | ||
114 | + | func powerContractAddress () = valueOrErrorMessage(match getString(factoryAddress(), keyPowerContractAddress()) { | |
115 | + | case s: String => | |
116 | + | addressFromString(s) | |
117 | + | case _: Unit => | |
118 | + | unit | |
119 | + | case _ => | |
120 | + | throw("Match error") | |
121 | + | }, wrapErr("invalid power contract address")) | |
122 | + | ||
123 | + | ||
124 | + | func keyLockAddress () = "%s__lockAddress" | |
125 | + | ||
126 | + | ||
127 | + | func lockAddress () = valueOrErrorMessage(match getString(factoryAddress(), keyLockAddress()) { | |
128 | + | case s: String => | |
129 | + | addressFromString(s) | |
130 | + | case _: Unit => | |
131 | + | unit | |
132 | + | case _ => | |
133 | + | throw("Match error") | |
134 | + | }, wrapErr("invalid lock contract address")) | |
135 | + | ||
136 | + | ||
137 | + | func keyPoolsFactoryAddress () = "%s__poolsFactoryAddress" | |
138 | + | ||
139 | + | ||
140 | + | func getPoolsFactoryAddress () = valueOrErrorMessage(match getString(factoryAddress(), keyPoolsFactoryAddress()) { | |
141 | + | case s: String => | |
142 | + | addressFromString(s) | |
143 | + | case _: Unit => | |
144 | + | unit | |
145 | + | case _ => | |
146 | + | throw("Match error") | |
147 | + | }, wrapErr("invalid pools factory address")) | |
148 | + | ||
149 | + | ||
150 | + | func keyTreasuryAddress () = "%s__treasuryAddress" | |
151 | + | ||
152 | + | ||
153 | + | func getTreasuryAddress () = valueOrErrorMessage(match getString(factoryAddress(), keyTreasuryAddress()) { | |
154 | + | case s: String => | |
155 | + | addressFromString(s) | |
156 | + | case _: Unit => | |
157 | + | unit | |
158 | + | case _ => | |
159 | + | throw("Match error") | |
160 | + | }, wrapErr("invalid treasury address")) | |
161 | + | ||
162 | + | ||
163 | + | func keyAssets () = "%s__assets" | |
164 | + | ||
165 | + | ||
166 | + | func getAssetsStr () = valueOrErrorMessage(getString(factoryAddress(), keyAssets()), wrapErr("invalid assets")) | |
167 | + | ||
168 | + | ||
169 | + | func keyLpAssetId () = "%s__lpAssetId" | |
170 | + | ||
171 | + | ||
172 | + | func getLpAssetId () = fromBase58String(valueOrErrorMessage(getString(factoryAddress(), keyLpAssetId()), wrapErr("invalid lp asset id"))) | |
173 | + | ||
174 | + | ||
175 | + | func getAssetInfoOrFail (assetId) = valueOrErrorMessage(assetInfo(assetId), wrapErr("invalid asset info")) | |
176 | + | ||
177 | + | ||
178 | + | func lockFormat (from,to,assetId,amount,lpAssetAmount) = makeString(["%d%d%s%d%d", toString(from), toString(to), toBase58String(assetId), toString(amount), toString(lpAssetAmount)], SEP) | |
179 | + | ||
180 | + | ||
181 | + | func lockParse (s) = { | |
182 | + | let parts = split(s, SEP) | |
183 | + | $Tuple4(valueOrErrorMessage(parseInt(parts[1]), wrapErr("error during processing lock start height")), valueOrErrorMessage(parseInt(parts[2]), wrapErr("error during processing lock end height")), fromBase58String(parts[3]), valueOrErrorMessage(parseInt(parts[4]), wrapErr("error during processing lock amount"))) | |
184 | + | } | |
185 | + | ||
186 | + | ||
187 | + | func getAssetsBalances (targetAddress,assetIdList) = { | |
188 | + | func map (acc,nextAssetIdStr) = { | |
189 | + | let balance = if ((nextAssetIdStr == WAVES)) | |
190 | + | then toX18(wavesBalance(targetAddress).available, pow(10, 0, wavesDecimals, 0, 0, DOWN)) | |
191 | + | else { | |
192 | + | let assetId = fromBase58String(nextAssetIdStr) | |
193 | + | let assetDecimals = getAssetInfoOrFail(assetId).decimals | |
194 | + | toX18(assetBalance(targetAddress, assetId), pow(10, 0, assetDecimals, 0, 0, DOWN)) | |
195 | + | } | |
196 | + | (acc :+ balance) | |
197 | + | } | |
198 | + | ||
199 | + | let $l = assetIdList | |
200 | + | let $s = size($l) | |
201 | + | let $acc0 = nil | |
202 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
203 | + | then $a | |
204 | + | else map($a, $l[$i]) | |
205 | + | ||
206 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
207 | + | then $a | |
208 | + | else throw("List size exceeds 10") | |
209 | + | ||
210 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
211 | + | } | |
212 | + | ||
213 | + | ||
214 | + | func getAssetsPrices (poolsFactoryAddress,assetIdList) = if ((chainId == chainIdW)) | |
215 | + | then { | |
216 | + | let wavesUsdtAddressStr = "3PKfrupEydU2nZAghVjZAfvCwMBkzuR1F52" | |
217 | + | let wavesUsdtPrice = parseBigIntValue({ | |
218 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdtAddressStr], nil) | |
219 | + | if ($isInstanceOf(@, "String")) | |
220 | + | then @ | |
221 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
222 | + | }) | |
223 | + | let wavesXtnAddressStr = "3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g" | |
224 | + | let wavesXtnPrice = parseBigIntValue({ | |
225 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wavesXtnAddressStr], nil) | |
226 | + | if ($isInstanceOf(@, "String")) | |
227 | + | then @ | |
228 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
229 | + | }) | |
230 | + | let xtnUsdtPrice = fraction(wavesUsdtPrice, mult18, wavesXtnPrice) | |
231 | + | func map (acc,nextAssetId) = { | |
232 | + | let price = match nextAssetId { | |
233 | + | case _ => | |
234 | + | if (("2thsACuHmzDMuNezPM32wg9a3BwUzBWDeSKakgz3cw21" == $match0)) | |
235 | + | then { | |
236 | + | let pwrWavesAddressStr = "3PDi7Qq8pLQYvtKyTfQuqqPUWyhoYbU957t" | |
237 | + | let pwrWavesPrice = parseBigIntValue({ | |
238 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [pwrWavesAddressStr], nil) | |
239 | + | if ($isInstanceOf(@, "String")) | |
240 | + | then @ | |
241 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
242 | + | }) | |
243 | + | fraction(pwrWavesPrice, wavesUsdtPrice, mult18) | |
244 | + | } | |
245 | + | else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0)) | |
246 | + | then { | |
247 | + | let wxWavesAddressStr = "3PFzaH2ghpwANHFgjeva83N1yxzErELx2eh" | |
248 | + | let wxWavesPrice = parseBigIntValue({ | |
249 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wxWavesAddressStr], nil) | |
250 | + | if ($isInstanceOf(@, "String")) | |
251 | + | then @ | |
252 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
253 | + | }) | |
254 | + | fraction(wxWavesPrice, wavesUsdtPrice, mult18) | |
255 | + | } | |
256 | + | else if (("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ" == $match0)) | |
257 | + | then { | |
258 | + | let wavesUsdtwxgAddressStr = "3PKMVZ7kQeaREajYi8Yc25Ro6mcNw5D6QSa" | |
259 | + | let wavesUsdtwxgPrice = parseBigIntValue({ | |
260 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdtwxgAddressStr], nil) | |
261 | + | if ($isInstanceOf(@, "String")) | |
262 | + | then @ | |
263 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
264 | + | }) | |
265 | + | fraction(wavesUsdtPrice, mult18, wavesUsdtwxgPrice) | |
266 | + | } | |
267 | + | else if (("6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ" == $match0)) | |
268 | + | then { | |
269 | + | let wavesUsdcwxgAddressStr = "3P3g3eipfG2NZKKQE8DZXt2E9tRJqii9jcX" | |
270 | + | let wavesUsdcwxgPrice = parseBigIntValue({ | |
271 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdcwxgAddressStr], nil) | |
272 | + | if ($isInstanceOf(@, "String")) | |
273 | + | then @ | |
274 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
275 | + | }) | |
276 | + | fraction(wavesUsdtPrice, mult18, wavesUsdcwxgPrice) | |
277 | + | } | |
278 | + | else if (("HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk" == $match0)) | |
279 | + | then { | |
280 | + | let ltcwxgXtnAddressStr = "3P94wvu5gA7VhjPgAB3twaeqdwHCwNK2vsn" | |
281 | + | let ltcwxgXtnPrice = parseBigIntValue({ | |
282 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [ltcwxgXtnAddressStr], nil) | |
283 | + | if ($isInstanceOf(@, "String")) | |
284 | + | then @ | |
285 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
286 | + | }) | |
287 | + | fraction(ltcwxgXtnPrice, xtnUsdtPrice, mult18) | |
288 | + | } | |
289 | + | else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0)) | |
290 | + | then { | |
291 | + | let ethwxgWavesAddressStr = "3P3XGTN6s292g9iwYhs3TEqJqHiffQYojuE" | |
292 | + | let ethwxgWavesPrice = parseBigIntValue({ | |
293 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [ethwxgWavesAddressStr], nil) | |
294 | + | if ($isInstanceOf(@, "String")) | |
295 | + | then @ | |
296 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
297 | + | }) | |
298 | + | fraction(ethwxgWavesPrice, wavesUsdtPrice, mult18) | |
299 | + | } | |
300 | + | else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0)) | |
301 | + | then { | |
302 | + | let btcwxgXtnAddressStr = "3PCBWDTA6jrFswd7gQgaE3Xk7gLM5RKofvp" | |
303 | + | let btcwxgXtnPrice = parseBigIntValue({ | |
304 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [btcwxgXtnAddressStr], nil) | |
305 | + | if ($isInstanceOf(@, "String")) | |
306 | + | then @ | |
307 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
308 | + | }) | |
309 | + | fraction(btcwxgXtnPrice, xtnUsdtPrice, mult18) | |
310 | + | } | |
311 | + | else throwErr("invalid asset id") | |
312 | + | } | |
313 | + | (acc :+ price) | |
314 | + | } | |
315 | + | ||
316 | + | let $l = assetIdList | |
317 | + | let $s = size($l) | |
318 | + | let $acc0 = nil | |
319 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
320 | + | then $a | |
321 | + | else map($a, $l[$i]) | |
322 | + | ||
323 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
324 | + | then $a | |
325 | + | else throw("List size exceeds 10") | |
326 | + | ||
327 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
328 | + | } | |
329 | + | else if ((chainId == chainIdT)) | |
330 | + | then { | |
331 | + | func map (acc,nextAssetId) = { | |
332 | + | let price = match nextAssetId { | |
333 | + | case _ => | |
334 | + | if (("EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc" == $match0)) | |
335 | + | then { | |
336 | + | let wxUsdtAddressStr = "3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt" | |
337 | + | let wxUsdtPrice = parseBigIntValue({ | |
338 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [wxUsdtAddressStr], nil) | |
339 | + | if ($isInstanceOf(@, "String")) | |
340 | + | then @ | |
341 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
342 | + | }) | |
343 | + | wxUsdtPrice | |
344 | + | } | |
345 | + | else if (("A7Ksh7fXyqm1KhKAiK3bAB2aiPSitQQF6v1pyu9SS3FR" == $match0)) | |
346 | + | then { | |
347 | + | let usdcUsdtAddressStr = "3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA" | |
348 | + | let usdcUsdtPrice = parseBigIntValue({ | |
349 | + | let @ = invoke(poolsFactoryAddress, "getPrice", [usdcUsdtAddressStr], nil) | |
350 | + | if ($isInstanceOf(@, "String")) | |
351 | + | then @ | |
352 | + | else throw(($getType(@) + " couldn't be cast to String")) | |
353 | + | }) | |
354 | + | usdcUsdtPrice | |
355 | + | } | |
356 | + | else if (("8Q6SE2ANebufw8JuPjJVRjZD6drD8ihjNjM8xaGUSfdR" == $match0)) | |
357 | + | then { | |
358 | + | let price = toX18(150000000, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
359 | + | price | |
360 | + | } | |
361 | + | else throwErr("invalid asset id") | |
362 | + | } | |
363 | + | (acc :+ price) | |
364 | + | } | |
365 | + | ||
366 | + | let $l = assetIdList | |
367 | + | let $s = size($l) | |
368 | + | let $acc0 = nil | |
369 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
370 | + | then $a | |
371 | + | else map($a, $l[$i]) | |
372 | + | ||
373 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
374 | + | then $a | |
375 | + | else throw("List size exceeds 10") | |
376 | + | ||
377 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
378 | + | } | |
379 | + | else throwErr("invalid chain id") | |
380 | + | ||
381 | + | ||
382 | + | func calcTreasuryValue () = { | |
383 | + | let treasuryAddress = getTreasuryAddress() | |
384 | + | let poolsFactoryAddress = getPoolsFactoryAddress() | |
385 | + | let assetsStr = split(getAssetsStr(), SEP) | |
386 | + | let assetsBalances = getAssetsBalances(treasuryAddress, assetsStr) | |
387 | + | let assetsPrices = getAssetsPrices(poolsFactoryAddress, assetsStr) | |
388 | + | func reduce (acc,nextAssetIdStr) = { | |
389 | + | let assetId = fromBase58String(nextAssetIdStr) | |
390 | + | let index = valueOrErrorMessage(indexOf(assetsStr, nextAssetIdStr), wrapErr("invalid asset id")) | |
391 | + | let balance = assetsBalances[index] | |
392 | + | let price = assetsPrices[index] | |
393 | + | let assetValue = fraction(balance, price, mult18) | |
394 | + | (acc + assetValue) | |
395 | + | } | |
396 | + | ||
397 | + | let treasuryValue = { | |
398 | + | let $l = assetsStr | |
399 | + | let $s = size($l) | |
400 | + | let $acc0 = toBigInt(0) | |
401 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
402 | + | then $a | |
403 | + | else reduce($a, $l[$i]) | |
404 | + | ||
405 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
406 | + | then $a | |
407 | + | else throw("List size exceeds 10") | |
408 | + | ||
409 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
410 | + | } | |
411 | + | treasuryValue | |
412 | + | } | |
413 | + | ||
414 | + | ||
415 | + | func calcRewardsAndLock (paymentAmount,userAddressOption) = { | |
416 | + | let assetsStr = split(getAssetsStr(), SEP) | |
417 | + | let wxdaoQuantity = getAssetInfoOrFail(getLpAssetId()).quantity | |
418 | + | if ((wxdaoQuantity == wxdaoQuantity)) | |
419 | + | then { | |
420 | + | let assetsBalances = getAssetsBalances(factoryAddress(), assetsStr) | |
421 | + | func map (acc,nextAssetIdStr) = { | |
422 | + | let assetId = fromBase58String(nextAssetIdStr) | |
423 | + | let index = valueOrErrorMessage(indexOf(assetsStr, nextAssetIdStr), wrapErr("invalid asset balance")) | |
424 | + | let assetDecimals = getAssetInfoOrFail(assetId).decimals | |
425 | + | let balance = fromX18(assetsBalances[index], pow(10, 0, assetDecimals, 0, 0, DOWN)) | |
426 | + | let amount = fraction(balance, paymentAmount, wxdaoQuantity) | |
427 | + | if ((amount > 0)) | |
428 | + | then { | |
429 | + | let lock = if ((userAddressOption == unit)) | |
430 | + | then unit | |
431 | + | else invoke(this, "lockInternal", [value(userAddressOption).bytes, assetId, amount, paymentAmount], nil) | |
432 | + | if ((lock == lock)) | |
433 | + | then $Tuple2((acc._1 :+ assetId), (acc._2 :+ amount)) | |
434 | + | else throw("Strict value is not equal to itself.") | |
435 | + | } | |
436 | + | else acc | |
437 | + | } | |
438 | + | ||
439 | + | let $l = assetsStr | |
440 | + | let $s = size($l) | |
441 | + | let $acc0 = $Tuple2(nil, nil) | |
442 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
443 | + | then $a | |
444 | + | else map($a, $l[$i]) | |
445 | + | ||
446 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
447 | + | then $a | |
448 | + | else throw("List size exceeds 6") | |
449 | + | ||
450 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
451 | + | } | |
452 | + | else throw("Strict value is not equal to itself.") | |
453 | + | } | |
454 | + | ||
455 | + | ||
456 | + | func calcPrice () = { | |
457 | + | let poolsFactoryAddress = getPoolsFactoryAddress() | |
458 | + | let currentPeriod = valueOrErrorMessage(getInteger(factoryAddress(), keyCurrentPeriod()), wrapErr("invalid current period")) | |
459 | + | let startTreasuryValue = valueOrErrorMessage(getInteger(factoryAddress(), keyTreasuryValueByPeriod(currentPeriod)), wrapErr(("invalid treasury value for period " + toString(currentPeriod)))) | |
460 | + | let treasuryValue = fromX18(calcTreasuryValue(), pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
461 | + | let treasuryValueDiff = (treasuryValue - startTreasuryValue) | |
462 | + | let treasuryValueDiffX18 = toX18(treasuryValueDiff, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
463 | + | let pwrAssetId = getPowerAssetId() | |
464 | + | let pwrInfo = getAssetInfoOrFail(pwrAssetId) | |
465 | + | let pwrPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(pwrAssetId)])[0] | |
466 | + | let pwrPrice = if ((pwrPriceX18 > toBigInt(0))) | |
467 | + | then fromX18(pwrPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
468 | + | else throwErr("invalid PWR price") | |
469 | + | let treasuryAddress = getTreasuryAddress() | |
470 | + | let skinTotal = valueOrElse(getInteger(powerContractAddress(), keySkinTotal(treasuryAddress)), 0) | |
471 | + | let wxdaoInfo = getAssetInfoOrFail(getLpAssetId()) | |
472 | + | let pwrRemaining = (wxdaoInfo.quantity / 100) | |
473 | + | let pwrAmount = (skinTotal + pwrRemaining) | |
474 | + | let pwrAmountX18 = toX18(pwrAmount, pow(10, 0, pwrInfo.decimals, 0, 0, DOWN)) | |
475 | + | let factoryAddressWxBalanceX18 = getAssetsBalances(factoryAddress(), [toBase58String(wxAssetId)])[0] | |
476 | + | let factoryAddressWxBalance = fromX18(factoryAddressWxBalanceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
477 | + | let wxPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(wxAssetId)])[0] | |
478 | + | let wxPrice = if ((wxPriceX18 > toBigInt(0))) | |
479 | + | then fromX18(wxPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
480 | + | else throwErr("invalid wx price") | |
481 | + | let wxdaoQuantity = wxdaoInfo.quantity | |
482 | + | let wxdaoQuantityX18 = toX18(wxdaoQuantity, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN)) | |
483 | + | let wxDaoPriceX18 = (((pwrPriceX18 + fraction((factoryAddressWxBalanceX18 * toBigInt(100)), wxPriceX18, wxdaoQuantityX18)) + fraction(max([treasuryValueDiffX18, toBigInt(0)]), (toBigInt(2) * mult18), (toBigInt(10) * pwrAmountX18))) / toBigInt(100)) | |
484 | + | let wxDaoPrice = fromX18(wxDaoPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
485 | + | let rewardsPrices = calcRewardsAndLock(pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN), unit) | |
486 | + | $Tuple2([wxDaoPrice, rewardsPrices], [["wxDaoPrice", wxDaoPrice], ["pwrPrice", pwrPrice], ["factoryAddressWxBalance", factoryAddressWxBalance], ["wxPrice", wxPrice], ["wxdaoQuantity", wxdaoQuantity], ["treasuryValueDiff", treasuryValueDiff], ["pwrAmount", pwrAmount], ["skinTotal", skinTotal], ["pwrRemaining", pwrRemaining]]) | |
487 | + | } | |
488 | + | ||
489 | + | ||
490 | + | @Callable(i) | |
491 | + | func swap (callerPublicKey,args) = { | |
492 | + | let checkCaller = onlyFactory(i) | |
493 | + | if ((checkCaller == checkCaller)) | |
494 | + | then { | |
495 | + | let userAddress = addressFromPublicKey(callerPublicKey) | |
496 | + | let payment = if ((size(i.payments) == 1)) | |
497 | + | then i.payments[0] | |
498 | + | else throwErr("1 payment is required") | |
499 | + | let err = wrapErr("invalid payment asset id") | |
500 | + | let paymentAssetId = if ((valueOrErrorMessage(payment.assetId, err) == getLpAssetId())) | |
501 | + | then value(payment.assetId) | |
502 | + | else throwErr(err) | |
503 | + | let pwrPrice = 100 | |
504 | + | let pwrAmount = (payment.amount / pwrPrice) | |
505 | + | let rewards = calcRewardsAndLock(payment.amount, userAddress) | |
506 | + | if ((rewards == rewards)) | |
507 | + | then { | |
508 | + | let additionalLockRounds = 0 | |
509 | + | let factoryActions = [invoke(factoryAddress(), "commitAfterStartWithLockRoundFor", [toString(powerContractAddress()), toString(getTreasuryAddress()), toString(userAddress), additionalLockRounds, getPowerAssetId(), pwrAmount], nil)] | |
510 | + | $Tuple2([Burn(paymentAssetId, payment.amount)], factoryActions) | |
511 | + | } | |
512 | + | else throw("Strict value is not equal to itself.") | |
513 | + | } | |
514 | + | else throw("Strict value is not equal to itself.") | |
515 | + | } | |
516 | + | ||
517 | + | ||
518 | + | ||
519 | + | @Callable(i) | |
520 | + | func lockInternal (userAddressBytes,assetId,amount,lpAssetAmount) = { | |
521 | + | let checkCaller = onlyThis(i) | |
522 | + | if ((checkCaller == checkCaller)) | |
523 | + | then { | |
524 | + | let userAddress = Address(userAddressBytes) | |
525 | + | let lockGlobalCounter = valueOrElse(getInteger(factoryAddress(), keyLockGlobalCounter()), 0) | |
526 | + | let lockDuration = valueOrErrorMessage(getInteger(factoryAddress(), keyLockDuration()), wrapErr("invalid lock duration")) | |
527 | + | let getAssets = invoke(factoryAddress(), "transferAsset", [lockAddress().bytes, amount, assetId], nil) | |
528 | + | if ((getAssets == getAssets)) | |
529 | + | then { | |
530 | + | let factoryActions = [invoke(factoryAddress(), "stringEntry", [keyLock(userAddress, lockGlobalCounter), lockFormat(height, (height + lockDuration), assetId, amount, lpAssetAmount)], nil), invoke(factoryAddress(), "integerEntry", [keyLockGlobalCounter(), (lockGlobalCounter + 1)], nil)] | |
531 | + | $Tuple2(nil, factoryActions) | |
532 | + | } | |
533 | + | else throw("Strict value is not equal to itself.") | |
534 | + | } | |
535 | + | else throw("Strict value is not equal to itself.") | |
536 | + | } | |
537 | + | ||
538 | + | ||
539 | + | ||
540 | + | @Callable(i) | |
541 | + | func unlock (callerPublicKey,args) = { | |
542 | + | let checkCaller = onlyFactory(i) | |
543 | + | if ((checkCaller == checkCaller)) | |
544 | + | then { | |
545 | + | let userAddress = addressFromPublicKey(callerPublicKey) | |
546 | + | func fold (acc,next) = { | |
547 | + | let counter = valueOrErrorMessage(parseInt(next), wrapErr("invalid counter")) | |
548 | + | let $t01763917848 = lockParse(valueOrErrorMessage(getString(factoryAddress(), keyLock(userAddress, counter)), wrapErr(("invalid lock: " + keyLock(userAddress, counter))))) | |
549 | + | let from = $t01763917848._1 | |
550 | + | let to = $t01763917848._2 | |
551 | + | let assetId = $t01763917848._3 | |
552 | + | let amount = $t01763917848._4 | |
553 | + | let result = if ((height > to)) | |
554 | + | then [invoke(lockAddress(), "transferAsset", [userAddress.bytes, amount, assetId], nil), invoke(factoryAddress(), "deleteEntry", [keyLock(userAddress, counter)], nil)] | |
555 | + | else throwErr("invalid height") | |
556 | + | (acc :+ result) | |
557 | + | } | |
558 | + | ||
559 | + | let result = { | |
560 | + | let $l = args | |
561 | + | let $s = size($l) | |
562 | + | let $acc0 = nil | |
563 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
564 | + | then $a | |
565 | + | else fold($a, $l[$i]) | |
566 | + | ||
567 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
568 | + | then $a | |
569 | + | else throw("List size exceeds 30") | |
570 | + | ||
571 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30) | |
572 | + | } | |
573 | + | $Tuple2(nil, result) | |
574 | + | } | |
575 | + | else throw("Strict value is not equal to itself.") | |
576 | + | } | |
577 | + | ||
578 | + | ||
579 | + | ||
580 | + | @Callable(i) | |
581 | + | func price (callerPublicKey,args) = { | |
582 | + | let checkCaller = onlyFactory(i) | |
583 | + | if ((checkCaller == checkCaller)) | |
584 | + | then $Tuple2(nil, calcPrice()._1) | |
585 | + | else throw("Strict value is not equal to itself.") | |
586 | + | } | |
587 | + | ||
588 | + | ||
589 | + | ||
590 | + | @Callable(i) | |
591 | + | func priceDebug (callerPublicKey,args) = { | |
592 | + | let checkCaller = onlyFactory(i) | |
593 | + | if ((checkCaller == checkCaller)) | |
594 | + | then $Tuple2(nil, calcPrice()._2) | |
595 | + | else throw("Strict value is not equal to itself.") | |
596 | + | } | |
597 | + | ||
598 | + | ||
599 | + | ||
600 | + | @Callable(i) | |
601 | + | func getTreasuryValue (callerPublicKey,args) = { | |
602 | + | let checkCaller = onlyFactory(i) | |
603 | + | if ((checkCaller == checkCaller)) | |
604 | + | then { | |
605 | + | let treasuryValue = fromX18(calcTreasuryValue(), pow(10, 0, usdtDecimals, 0, 0, DOWN)) | |
606 | + | $Tuple2(nil, treasuryValue) | |
607 | + | } | |
608 | + | else throw("Strict value is not equal to itself.") | |
609 | + | } | |
610 | + | ||
611 | + | ||
612 | + | @Verifier(tx) | |
613 | + | func verify () = if ((chainId == chainIdT)) | |
614 | + | then true | |
615 | + | else (chainId == chainIdR) | |
616 | + |
github/deemru/w8io/0e76f2f 36.11 ms ◑