tx · 7Dm2AdTsyibbZjun99FPgFytSWCPwkkWEyvWNpxEUHKt

3Mzep1R5kHeC1ecKFkWjuhU3Gw4LAdCib9N:  -0.01700000 Waves

2024.02.13 12:01 [2974251] smart account 3Mzep1R5kHeC1ecKFkWjuhU3Gw4LAdCib9N > SELF 0.00000000 Waves

{ "type": 13, "id": "7Dm2AdTsyibbZjun99FPgFytSWCPwkkWEyvWNpxEUHKt", "fee": 1700000, "feeAssetId": null, "timestamp": 1707814899536, "version": 2, "chainId": 84, "sender": "3Mzep1R5kHeC1ecKFkWjuhU3Gw4LAdCib9N", "senderPublicKey": "41THq9VrFxHEvVGJyz2oMpJQErnSkkqJXpBypSDxa5Mv", "proofs": [ "4NoFj5TS5MQwy6XvrVppJTmybPpPhN7UKQCyWH7niyAfp5AbnHBg9uQT9ToKDjQzjfH8naaJkvrxduSSWmAYborH" ], "script": "base64:BwIoCAISBAoCAhgSBgoEAgICARIECgICGBIECgICGBIECgICGBIECgICGDEAB2NoYWluSWQJAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEACGNoYWluSWRUAQFUAAhjaGFpbklkVwEBVwADU0VQAgJfXwAFV0FWRVMCBVdBVkVTABBjb250cmFjdEZpbGVuYW1lAhV3eGRhb19jYWxjdWxhdG9yLnJpZGUABW11bHQ4AIDC1y8ABm11bHQxOAkAtgIBAICAkLu61q3wDQANd2F2ZXNEZWNpbWFscwAIAAx1c2R0RGVjaW1hbHMABgEFdG9YMTgCB29yaWdWYWwNb3JpZ1NjYWxlTXVsdAkAvAIDCQC2AgEFB29yaWdWYWwFBm11bHQxOAkAtgIBBQ1vcmlnU2NhbGVNdWx0AQdmcm9tWDE4AgN2YWwPcmVzdWx0U2NhbGVNdWx0CQCgAwEJALwCAwUDdmFsCQC2AgEFD3Jlc3VsdFNjYWxlTXVsdAUGbXVsdDE4AQd3cmFwRXJyAQFzCQCsAgIJAKwCAgUQY29udHJhY3RGaWxlbmFtZQICOiAFAXMBCHRocm93RXJyAQFzCQACAQkBB3dyYXBFcnIBBQFzAQtvbmx5QWRkcmVzcwIBaQdhZGRyZXNzAwkAAAIIBQFpBmNhbGxlcgUHYWRkcmVzcwYJAQh0aHJvd0VycgECEXBlcm1pc3Npb24gZGVuaWVkAQhvbmx5VGhpcwEBaQkBC29ubHlBZGRyZXNzAgUBaQUEdGhpcwAJd3hBc3NldElkAwkAAAIFB2NoYWluSWQFCGNoYWluSWRXASCTARyrqcduJVfOZp5xtr2qa/g86FgLKu7ZoE67PNwUsQMJAAACBQdjaGFpbklkBQhjaGFpbklkVAEgxlIegU7qbuM8wJewDl8s8mrp7Z2yhtGaQnioYH0+G7EJAQh0aHJvd0VycgECEGludmFsaWQgY2hhaW4gaWQBEGtleUN1cnJlbnRQZXJpb2QACQC5CQIJAMwIAgICJXMJAMwIAgINY3VycmVudFBlcmlvZAUDbmlsBQNTRVABFmtleVN0YXJ0SGVpZ2h0QnlQZXJpb2QBBnBlcmlvZAkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQZwZXJpb2QFA25pbAUDU0VQAQ9rZXlQZXJpb2RMZW5ndGgACQC5CQIJAMwIAgICJXMJAMwIAgIMcGVyaW9kTGVuZ3RoBQNuaWwFA1NFUAEYa2V5VHJlYXN1cnlWYWx1ZUJ5UGVyaW9kAQZwZXJpb2QJALkJAgkAzAgCAgQlcyVkCQDMCAICDXRyZWFzdXJ5VmFsdWUJAMwIAgkApAMBBQZwZXJpb2QFA25pbAUDU0VQARRrZXlMb2NrR2xvYmFsQ291bnRlcgAJALkJAgkAzAgCAgIlcwkAzAgCAhFsb2NrR2xvYmFsQ291bnRlcgUDbmlsBQNTRVABD2tleUxvY2tEdXJhdGlvbgAJALkJAgkAzAgCAgIlcwkAzAgCAgxsb2NrRHVyYXRpb24FA25pbAUDU0VQAQdrZXlMb2NrAgt1c2VyQWRkcmVzcwdjb3VudGVyCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBGxvY2sJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCCQCkAwEFB2NvdW50ZXIFA25pbAUDU0VQAQxrZXlTa2luVG90YWwBD3RyZWFzdXJ5QWRkcmVzcwkArAICAgtza2luX3RvdGFsXwkApQgBBQ90cmVhc3VyeUFkZHJlc3MBFWtleVBvd2VyQ29uZmlnQWRkcmVzcwACFiVzX19wb3dlckNvbmZpZ0FkZHJlc3MBEnBvd2VyQ29uZmlnQWRkcmVzcwEOZmFjdG9yeUFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQHJG1hdGNoMAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwkBFWtleVBvd2VyQ29uZmlnQWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yCQEHd3JhcEVycgECHGludmFsaWQgcG93ZXIgY29uZmlnIGFkZHJlc3MBD2tleVBvd2VyQXNzZXRJZAACDHBvd2VyQXNzZXRJZAEPZ2V0UG93ZXJBc3NldElkAQ5mYWN0b3J5QWRkcmVzcwkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBEnBvd2VyQ29uZmlnQWRkcmVzcwEFDmZhY3RvcnlBZGRyZXNzCQEPa2V5UG93ZXJBc3NldElkAAkBB3dyYXBFcnIBAhZpbnZhbGlkIHBvd2VyIGFzc2V0IGlkARdrZXlQb3dlckNvbnRyYWN0QWRkcmVzcwACGCVzX19wb3dlckNvbnRyYWN0QWRkcmVzcwEUcG93ZXJDb250cmFjdEFkZHJlc3MBDmZhY3RvcnlBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIEByRtYXRjaDAJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARdrZXlQb3dlckNvbnRyYWN0QWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yCQEHd3JhcEVycgECHmludmFsaWQgcG93ZXIgY29udHJhY3QgYWRkcmVzcwEOa2V5TG9ja0FkZHJlc3MAAg8lc19fbG9ja0FkZHJlc3MBC2xvY2tBZGRyZXNzAQ5mYWN0b3J5QWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAckbWF0Y2gwCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEOa2V5TG9ja0FkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgkBB3dyYXBFcnIBAh1pbnZhbGlkIGxvY2sgY29udHJhY3QgYWRkcmVzcwEWa2V5UG9vbHNGYWN0b3J5QWRkcmVzcwACFyVzX19wb29sc0ZhY3RvcnlBZGRyZXNzARZnZXRQb29sc0ZhY3RvcnlBZGRyZXNzAQ5mYWN0b3J5QWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAckbWF0Y2gwCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEWa2V5UG9vbHNGYWN0b3J5QWRkcmVzcwADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQCmCAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yCQEHd3JhcEVycgECHWludmFsaWQgcG9vbHMgZmFjdG9yeSBhZGRyZXNzARJrZXlUcmVhc3VyeUFkZHJlc3MAAhMlc19fdHJlYXN1cnlBZGRyZXNzARJnZXRUcmVhc3VyeUFkZHJlc3MBDmZhY3RvcnlBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIEByRtYXRjaDAJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARJrZXlUcmVhc3VyeUFkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgkBB3dyYXBFcnIBAhhpbnZhbGlkIHRyZWFzdXJ5IGFkZHJlc3MBCWtleUFzc2V0cwACCiVzX19hc3NldHMBDGdldEFzc2V0c1N0cgEOZmFjdG9yeUFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQ5mYWN0b3J5QWRkcmVzcwkBCWtleUFzc2V0cwAJAQd3cmFwRXJyAQIOaW52YWxpZCBhc3NldHMBDGtleUxwQXNzZXRJZAACDSVzX19scEFzc2V0SWQBDGdldExwQXNzZXRJZAEOZmFjdG9yeUFkZHJlc3MJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEMa2V5THBBc3NldElkAAkBB3dyYXBFcnIBAhNpbnZhbGlkIGxwIGFzc2V0IGlkARJnZXRBc3NldEluZm9PckZhaWwBB2Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQdhc3NldElkCQEHd3JhcEVycgECEmludmFsaWQgYXNzZXQgaW5mbwEKbG9ja0Zvcm1hdAQEZnJvbQJ0bwdhc3NldElkBmFtb3VudAkAzAgCCQCkAwEFBGZyb20JAMwIAgkApAMBBQJ0bwkAzAgCCQDYBAEFB2Fzc2V0SWQJAMwIAgkApAMBBQZhbW91bnQFA25pbAEJbG9ja1BhcnNlAQFzBAVwYXJ0cwkAtQkCBQFzBQNTRVAJAJYKBAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUFcGFydHMAAAkBB3dyYXBFcnIBAillcnJvciBkdXJpbmcgcHJvY2Vzc2luZyBsb2NrIHN0YXJ0IGhlaWdodAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUFcGFydHMAAQkBB3dyYXBFcnIBAidlcnJvciBkdXJpbmcgcHJvY2Vzc2luZyBsb2NrIGVuZCBoZWlnaHQJANkEAQkAkQMCBQVwYXJ0cwACCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQVwYXJ0cwADCQEHd3JhcEVycgECI2Vycm9yIGR1cmluZyBwcm9jZXNzaW5nIGxvY2sgYW1vdW50ARFnZXRBc3NldHNCYWxhbmNlcwINdGFyZ2V0QWRkcmVzcwthc3NldElkTGlzdAoBA21hcAIDYWNjDm5leHRBc3NldElkU3RyBAdiYWxhbmNlAwkAAAIFDm5leHRBc3NldElkU3RyBQVXQVZFUwkBBXRvWDE4AggJAO8HAQUNdGFyZ2V0QWRkcmVzcwlhdmFpbGFibGUJAGwGAAoAAAUNd2F2ZXNEZWNpbWFscwAAAAAFBERPV04EB2Fzc2V0SWQJANkEAQUObmV4dEFzc2V0SWRTdHIEDWFzc2V0RGVjaW1hbHMICQESZ2V0QXNzZXRJbmZvT3JGYWlsAQUHYXNzZXRJZAhkZWNpbWFscwkBBXRvWDE4AgkA8AcCBQ10YXJnZXRBZGRyZXNzBQdhc3NldElkCQBsBgAKAAAFDWFzc2V0RGVjaW1hbHMAAAAABQRET1dOCQDNCAIFA2FjYwUHYmFsYW5jZQoAAiRsBQthc3NldElkTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDbWFwAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAQ9nZXRBc3NldHNQcmljZXMCE3Bvb2xzRmFjdG9yeUFkZHJlc3MLYXNzZXRJZExpc3QDCQAAAgUHY2hhaW5JZAUIY2hhaW5JZFcEE3dhdmVzVXNkdEFkZHJlc3NTdHICIzNQS2ZydXBFeWRVMm5aQWdoVmpaQWZ2Q3dNQmt6dVIxRjUyBA53YXZlc1VzZHRQcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRN3YXZlc1VzZHRBZGRyZXNzU3RyBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcEEndhdmVzWHRuQWRkcmVzc1N0cgIjM1BQWldnRk5SS0hMdk01MXB3UzkzNEM4Vlo3ZDJGNFo1OGcEDXdhdmVzWHRuUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUSd2F2ZXNYdG5BZGRyZXNzU3RyBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcEDHh0blVzZHRQcmljZQkAvAIDBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4BQ13YXZlc1h0blByaWNlCgEDbWFwAgNhY2MLbmV4dEFzc2V0SWQEBXByaWNlBAckbWF0Y2gwBQtuZXh0QXNzZXRJZAMJAAACAiwydGhzQUN1SG16RE11TmV6UE0zMndnOWEzQndVekJXRGVTS2FrZ3ozY3cyMQUHJG1hdGNoMAQScHdyV2F2ZXNBZGRyZXNzU3RyAiMzUERpN1FxOHBMUVl2dEt5VGZRdXFxUFVXeWhvWWJVOTU3dAQNcHdyV2F2ZXNQcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRJwd3JXYXZlc0FkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBQ1wd3JXYXZlc1ByaWNlBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4AwkAAAICLEF0cXY1OUVZempGR3VpdEtWbk1SazZIOEZ1a2pvVjNrdFBvcmJFeXMyNW9uBQckbWF0Y2gwBBF3eFdhdmVzQWRkcmVzc1N0cgIjM1BGemFIMmdocHdBTkhGZ2pldmE4M04xeXh6RXJFTHgyZWgEDHd4V2F2ZXNQcmljZQkApwMBCgABQAkA/AcEBRNwb29sc0ZhY3RvcnlBZGRyZXNzAghnZXRQcmljZQkAzAgCBRF3eFdhdmVzQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nCQC8AgMFDHd4V2F2ZXNQcmljZQUOd2F2ZXNVc2R0UHJpY2UFBm11bHQxOAMJAAACAiwzNE45WWNFRVRMV245M3FZUTY0RXNQMXg4OXRTcnVKVTQ0UnJFTVNYWEVQSgUHJG1hdGNoMAQWd2F2ZXNVc2R0d3hnQWRkcmVzc1N0cgIjM1BLTVZaN2tRZWFSRWFqWWk4WWMyNVJvNm1jTnc1RDZRU2EEEXdhdmVzVXNkdHd4Z1ByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFFndhdmVzVXNkdHd4Z0FkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4BRF3YXZlc1VzZHR3eGdQcmljZQMJAAACAiw2WHRIanBYYnM5UlJKUDJTcjlHVXlWcXpBQ2NieTlUa1RoSFhualZDNUNESgUHJG1hdGNoMAQWd2F2ZXNVc2Rjd3hnQWRkcmVzc1N0cgIjM1AzZzNlaXBmRzJOWktLUUU4RFpYdDJFOXRSSnFpaTlqY1gEEXdhdmVzVXNkY3d4Z1ByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFFndhdmVzVXNkY3d4Z0FkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBQ53YXZlc1VzZHRQcmljZQUGbXVsdDE4BRF3YXZlc1VzZGN3eGdQcmljZQMJAAACAixIWmsxbWJmdUpwbXhVMUZzNEFYNU1XTFZZdGN0c05jZzZlMkM2VktxSzh6awUHJG1hdGNoMAQTbHRjd3hnWHRuQWRkcmVzc1N0cgIjM1A5NHd2dTVnQTdWaGpQZ0FCM3R3YWVxZHdIQ3dOSzJ2c24EDmx0Y3d4Z1h0blByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFE2x0Y3d4Z1h0bkFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBQ5sdGN3eGdYdG5QcmljZQUMeHRuVXNkdFByaWNlBQZtdWx0MTgDCQAAAgIsNDc0alRlWXgycjJWYTM1Nzk0dENTY0FYV0pHOWhVMkhjZ3h6TW93YVpVbnUFByRtYXRjaDAEFWV0aHd4Z1dhdmVzQWRkcmVzc1N0cgIjM1AzWEdUTjZzMjkyZzlpd1loczNURXFKcUhpZmZRWW9qdUUEEGV0aHd4Z1dhdmVzUHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUVZXRod3hnV2F2ZXNBZGRyZXNzU3RyBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJALwCAwUQZXRod3hnV2F2ZXNQcmljZQUOd2F2ZXNVc2R0UHJpY2UFBm11bHQxOAMJAAACAiw4TFFXOGY3UDVkNVBaTTdHdFpFQmdhcVJQR1N6UzNEZlB1aVhyVVJKNEFKUwUHJG1hdGNoMAQTYnRjd3hnWHRuQWRkcmVzc1N0cgIjM1BDQldEVEE2anJGc3dkN2dRZ2FFM1hrN2dMTTVSS29mdnAEDmJ0Y3d4Z1h0blByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFE2J0Y3d4Z1h0bkFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAvAIDBQ5idGN3eGdYdG5QcmljZQUMeHRuVXNkdFByaWNlBQZtdWx0MTgJAQh0aHJvd0VycgECEGludmFsaWQgYXNzZXQgaWQJAM0IAgUDYWNjBQVwcmljZQoAAiRsBQthc3NldElkTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDbWFwAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFB2NoYWluSWQFCGNoYWluSWRUCgEDbWFwAgNhY2MLbmV4dEFzc2V0SWQEBXByaWNlBAckbWF0Y2gwBQtuZXh0QXNzZXRJZAMJAAACAixFTUFNTHhEbnYzeGl6OFJYZzhCdGozM2pjRXczd0xjekwzSktZWW11dWJwYwUHJG1hdGNoMAQQd3hVc2R0QWRkcmVzc1N0cgIjM01yVUxRUkxjNTJHV3JKRjF0TWNBbTRNNzhmUGU1N285S3QEC3d4VXNkdFByaWNlCQCnAwEKAAFACQD8BwQFE3Bvb2xzRmFjdG9yeUFkZHJlc3MCCGdldFByaWNlCQDMCAIFEHd4VXNkdEFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwULd3hVc2R0UHJpY2UDCQAAAgIsQTdLc2g3Zlh5cW0xS2hLQWlLM2JBQjJhaVBTaXRRUUY2djFweXU5U1MzRlIFByRtYXRjaDAEEnVzZGNVc2R0QWRkcmVzc1N0cgIjM016S1NkVEgyakZieXBMc29OZnJIN1Fna3pTYngzRVl3Q0EEDXVzZGNVc2R0UHJpY2UJAKcDAQoAAUAJAPwHBAUTcG9vbHNGYWN0b3J5QWRkcmVzcwIIZ2V0UHJpY2UJAMwIAgUSdXNkY1VzZHRBZGRyZXNzU3RyBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcFDXVzZGNVc2R0UHJpY2UDCQAAAgIsOFE2U0UyQU5lYnVmdzhKdVBqSlZSalpENmRyRDhpaGpOak04eGFHVVNmZFIFByRtYXRjaDAEBXByaWNlCQEFdG9YMTgCAICjw0cJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgUFcHJpY2UJAQh0aHJvd0VycgECEGludmFsaWQgYXNzZXQgaWQJAM0IAgUDYWNjBQVwcmljZQoAAiRsBQthc3NldElkTGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDbWFwAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQEIdGhyb3dFcnIBAhBpbnZhbGlkIGNoYWluIGlkARFjYWxjVHJlYXN1cnlWYWx1ZQEOZmFjdG9yeUFkZHJlc3MED3RyZWFzdXJ5QWRkcmVzcwkBEmdldFRyZWFzdXJ5QWRkcmVzcwEFDmZhY3RvcnlBZGRyZXNzBBNwb29sc0ZhY3RvcnlBZGRyZXNzCQEWZ2V0UG9vbHNGYWN0b3J5QWRkcmVzcwEFDmZhY3RvcnlBZGRyZXNzBAlhc3NldHNTdHIJALUJAgkBDGdldEFzc2V0c1N0cgEFDmZhY3RvcnlBZGRyZXNzBQNTRVAEDmFzc2V0c0JhbGFuY2VzCQERZ2V0QXNzZXRzQmFsYW5jZXMCBQ90cmVhc3VyeUFkZHJlc3MFCWFzc2V0c1N0cgQMYXNzZXRzUHJpY2VzCQEPZ2V0QXNzZXRzUHJpY2VzAgUTcG9vbHNGYWN0b3J5QWRkcmVzcwUJYXNzZXRzU3RyCgEGcmVkdWNlAgNhY2MObmV4dEFzc2V0SWRTdHIEB2Fzc2V0SWQJANkEAQUObmV4dEFzc2V0SWRTdHIEBWluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUJYXNzZXRzU3RyBQ5uZXh0QXNzZXRJZFN0cgkBB3dyYXBFcnIBAhBpbnZhbGlkIGFzc2V0IGlkBAdiYWxhbmNlCQCRAwIFDmFzc2V0c0JhbGFuY2VzBQVpbmRleAQFcHJpY2UJAJEDAgUMYXNzZXRzUHJpY2VzBQVpbmRleAQKYXNzZXRWYWx1ZQkAvAIDBQdiYWxhbmNlBQVwcmljZQUGbXVsdDE4CQC3AgIFA2FjYwUKYXNzZXRWYWx1ZQQNdHJlYXN1cnlWYWx1ZQoAAiRsBQlhc3NldHNTdHIKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQC2AgEAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGcmVkdWNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBQ10cmVhc3VyeVZhbHVlARJjYWxjUmV3YXJkc0FuZExvY2sDDmZhY3RvcnlBZGRyZXNzDXBheW1lbnRBbW91bnQRdXNlckFkZHJlc3NPcHRpb24ECWFzc2V0c1N0cgkAtQkCCQEMZ2V0QXNzZXRzU3RyAQUOZmFjdG9yeUFkZHJlc3MFA1NFUAQNd3hkYW9RdWFudGl0eQgJARJnZXRBc3NldEluZm9PckZhaWwBCQEMZ2V0THBBc3NldElkAQUOZmFjdG9yeUFkZHJlc3MIcXVhbnRpdHkDCQAAAgUNd3hkYW9RdWFudGl0eQUNd3hkYW9RdWFudGl0eQQOYXNzZXRzQmFsYW5jZXMJARFnZXRBc3NldHNCYWxhbmNlcwIFDmZhY3RvcnlBZGRyZXNzBQlhc3NldHNTdHIKAQNtYXACA2FjYw5uZXh0QXNzZXRJZFN0cgQHYXNzZXRJZAkA2QQBBQ5uZXh0QXNzZXRJZFN0cgQFaW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQlhc3NldHNTdHIFDm5leHRBc3NldElkU3RyCQEHd3JhcEVycgECFWludmFsaWQgYXNzZXQgYmFsYW5jZQQNYXNzZXREZWNpbWFscwgJARJnZXRBc3NldEluZm9PckZhaWwBBQdhc3NldElkCGRlY2ltYWxzBAdiYWxhbmNlCQEHZnJvbVgxOAIJAJEDAgUOYXNzZXRzQmFsYW5jZXMFBWluZGV4CQBsBgAKAAAFDWFzc2V0RGVjaW1hbHMAAAAABQRET1dOBAZhbW91bnQJAGsDBQdiYWxhbmNlBQ1wYXltZW50QW1vdW50BQ13eGRhb1F1YW50aXR5AwkAZgIFBmFtb3VudAAABARsb2NrAwkAAAIFEXVzZXJBZGRyZXNzT3B0aW9uBQR1bml0BQR1bml0CQD8BwQFBHRoaXMCDGxvY2tJbnRlcm5hbAkAzAgCCAUOZmFjdG9yeUFkZHJlc3MFYnl0ZXMJAMwIAggJAQV2YWx1ZQEFEXVzZXJBZGRyZXNzT3B0aW9uBWJ5dGVzCQDMCAIFB2Fzc2V0SWQJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQRsb2NrBQRsb2NrCQCUCgIJAM0IAggFA2FjYwJfMQUHYXNzZXRJZAkAzQgCCAUDYWNjAl8yBQZhbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA2FjYwoAAiRsBQlhc3NldHNTdHIKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQNtYXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BCWNhbGNQcmljZQEOZmFjdG9yeUFkZHJlc3MEE3Bvb2xzRmFjdG9yeUFkZHJlc3MJARZnZXRQb29sc0ZhY3RvcnlBZGRyZXNzAQUOZmFjdG9yeUFkZHJlc3MEDWN1cnJlbnRQZXJpb2QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBEGtleUN1cnJlbnRQZXJpb2QACQEHd3JhcEVycgECFmludmFsaWQgY3VycmVudCBwZXJpb2QEEnN0YXJ0VHJlYXN1cnlWYWx1ZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEYa2V5VHJlYXN1cnlWYWx1ZUJ5UGVyaW9kAQUNY3VycmVudFBlcmlvZAkBB3dyYXBFcnIBCQCsAgICImludmFsaWQgdHJlYXN1cnkgdmFsdWUgZm9yIHBlcmlvZCAJAKQDAQUNY3VycmVudFBlcmlvZAQNdHJlYXN1cnlWYWx1ZQkBB2Zyb21YMTgCCQERY2FsY1RyZWFzdXJ5VmFsdWUBBQ5mYWN0b3J5QWRkcmVzcwkAbAYACgAABQx1c2R0RGVjaW1hbHMAAAAABQRET1dOBBF0cmVhc3VyeVZhbHVlRGlmZgkAZQIFDXRyZWFzdXJ5VmFsdWUFEnN0YXJ0VHJlYXN1cnlWYWx1ZQQUdHJlYXN1cnlWYWx1ZURpZmZYMTgJAQV0b1gxOAIFEXRyZWFzdXJ5VmFsdWVEaWZmCQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04ECnB3ckFzc2V0SWQJAQ9nZXRQb3dlckFzc2V0SWQBBQ5mYWN0b3J5QWRkcmVzcwQHcHdySW5mbwkBEmdldEFzc2V0SW5mb09yRmFpbAEFCnB3ckFzc2V0SWQEC3B3clByaWNlWDE4CQCRAwIJAQ9nZXRBc3NldHNQcmljZXMCBRNwb29sc0ZhY3RvcnlBZGRyZXNzCQDMCAIJANgEAQUKcHdyQXNzZXRJZAUDbmlsAAAECHB3clByaWNlAwkAvwICBQtwd3JQcmljZVgxOAkAtgIBAAAJAQdmcm9tWDE4AgULcHdyUHJpY2VYMTgJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgkBCHRocm93RXJyAQIRaW52YWxpZCBQV1IgcHJpY2UED3RyZWFzdXJ5QWRkcmVzcwkBEmdldFRyZWFzdXJ5QWRkcmVzcwEFDmZhY3RvcnlBZGRyZXNzBAlza2luVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgkBFHBvd2VyQ29udHJhY3RBZGRyZXNzAQUOZmFjdG9yeUFkZHJlc3MJAQxrZXlTa2luVG90YWwBBQ90cmVhc3VyeUFkZHJlc3MAAAQJd3hkYW9JbmZvCQESZ2V0QXNzZXRJbmZvT3JGYWlsAQkBDGdldExwQXNzZXRJZAEFDmZhY3RvcnlBZGRyZXNzBAxwd3JSZW1haW5pbmcJAGkCCAUJd3hkYW9JbmZvCHF1YW50aXR5AGQECXB3ckFtb3VudAkAZAIFCXNraW5Ub3RhbAUMcHdyUmVtYWluaW5nBAxwd3JBbW91bnRYMTgJAQV0b1gxOAIFCXB3ckFtb3VudAkAbAYACgAACAUHcHdySW5mbwhkZWNpbWFscwAAAAAFBERPV04EGmZhY3RvcnlBZGRyZXNzV3hCYWxhbmNlWDE4CQCRAwIJARFnZXRBc3NldHNCYWxhbmNlcwIFDmZhY3RvcnlBZGRyZXNzCQDMCAIJANgEAQUJd3hBc3NldElkBQNuaWwAAAQXZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2UJAQdmcm9tWDE4AgUaZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2VYMTgJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgQKd3hQcmljZVgxOAkAkQMCCQEPZ2V0QXNzZXRzUHJpY2VzAgUTcG9vbHNGYWN0b3J5QWRkcmVzcwkAzAgCCQDYBAEFCXd4QXNzZXRJZAUDbmlsAAAEB3d4UHJpY2UDCQC/AgIFCnd4UHJpY2VYMTgJALYCAQAACQEHZnJvbVgxOAIFCnd4UHJpY2VYMTgJAGwGAAoAAAUMdXNkdERlY2ltYWxzAAAAAAUERE9XTgkBCHRocm93RXJyAQIQaW52YWxpZCB3eCBwcmljZQQNd3hkYW9RdWFudGl0eQgFCXd4ZGFvSW5mbwhxdWFudGl0eQQQd3hkYW9RdWFudGl0eVgxOAkBBXRvWDE4AgUNd3hkYW9RdWFudGl0eQkAbAYACgAACAUJd3hkYW9JbmZvCGRlY2ltYWxzAAAAAAUERE9XTgQNd3hEYW9QcmljZVgxOAkAugICCQC3AgIJALcCAgULcHdyUHJpY2VYMTgJALwCAwkAuQICBRpmYWN0b3J5QWRkcmVzc1d4QmFsYW5jZVgxOAkAtgIBAGQFCnd4UHJpY2VYMTgFEHd4ZGFvUXVhbnRpdHlYMTgJALwCAwkAmAMBCQDMCAIFFHRyZWFzdXJ5VmFsdWVEaWZmWDE4CQDMCAIJALYCAQAABQNuaWwJALkCAgkAtgIBAAIFBm11bHQxOAkAuQICCQC2AgEACgUMcHdyQW1vdW50WDE4CQC2AgEAZAQKd3hEYW9QcmljZQkBB2Zyb21YMTgCBQ13eERhb1ByaWNlWDE4CQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04EDXJld2FyZHNQcmljZXMJARJjYWxjUmV3YXJkc0FuZExvY2sDBQ5mYWN0b3J5QWRkcmVzcwkAbAYACgAACAUJd3hkYW9JbmZvCGRlY2ltYWxzAAAAAAUERE9XTgUEdW5pdAkAlAoCCQDMCAIFCnd4RGFvUHJpY2UJAMwIAgUNcmV3YXJkc1ByaWNlcwUDbmlsCQDMCAIJAMwIAgIKd3hEYW9QcmljZQkAzAgCBQp3eERhb1ByaWNlBQNuaWwJAMwIAgkAzAgCAghwd3JQcmljZQkAzAgCBQhwd3JQcmljZQUDbmlsCQDMCAIJAMwIAgIXZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2UJAMwIAgUXZmFjdG9yeUFkZHJlc3NXeEJhbGFuY2UFA25pbAkAzAgCCQDMCAICB3d4UHJpY2UJAMwIAgUHd3hQcmljZQUDbmlsCQDMCAIJAMwIAgINd3hkYW9RdWFudGl0eQkAzAgCBQ13eGRhb1F1YW50aXR5BQNuaWwJAMwIAgkAzAgCAhF0cmVhc3VyeVZhbHVlRGlmZgkAzAgCBRF0cmVhc3VyeVZhbHVlRGlmZgUDbmlsCQDMCAIJAMwIAgIJcHdyQW1vdW50CQDMCAIFCXB3ckFtb3VudAUDbmlsCQDMCAIJAMwIAgIJc2tpblRvdGFsCQDMCAIFCXNraW5Ub3RhbAUDbmlsCQDMCAIJAMwIAgIMcHdyUmVtYWluaW5nCQDMCAIFDHB3clJlbWFpbmluZwUDbmlsBQNuaWwGAWkBBHN3YXACD2NhbGxlclB1YmxpY0tleQRhcmdzBA5mYWN0b3J5QWRkcmVzcwgFAWkGY2FsbGVyBAt1c2VyQWRkcmVzcwkApwgBBQ9jYWxsZXJQdWJsaWNLZXkEB3BheW1lbnQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABCQCRAwIIBQFpCHBheW1lbnRzAAAJAQh0aHJvd0VycgECFTEgcGF5bWVudCBpcyByZXF1aXJlZAQDZXJyCQEHd3JhcEVycgECGGludmFsaWQgcGF5bWVudCBhc3NldCBpZAQOcGF5bWVudEFzc2V0SWQDCQAAAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUHcGF5bWVudAdhc3NldElkBQNlcnIJAQxnZXRMcEFzc2V0SWQBBQ5mYWN0b3J5QWRkcmVzcwkBBXZhbHVlAQgFB3BheW1lbnQHYXNzZXRJZAkBCHRocm93RXJyAQUDZXJyBAhwd3JQcmljZQBkBAlwd3JBbW91bnQJAGkCCAUHcGF5bWVudAZhbW91bnQFCHB3clByaWNlBAdyZXdhcmRzCQESY2FsY1Jld2FyZHNBbmRMb2NrAwUOZmFjdG9yeUFkZHJlc3MIBQdwYXltZW50BmFtb3VudAULdXNlckFkZHJlc3MDCQAAAgUHcmV3YXJkcwUHcmV3YXJkcwQUYWRkaXRpb25hbExvY2tSb3VuZHMAAAQOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIgY29tbWl0QWZ0ZXJTdGFydFdpdGhMb2NrUm91bmRGb3IJAMwIAgkApQgBCQEUcG93ZXJDb250cmFjdEFkZHJlc3MBBQ5mYWN0b3J5QWRkcmVzcwkAzAgCCQClCAEJARJnZXRUcmVhc3VyeUFkZHJlc3MBBQ5mYWN0b3J5QWRkcmVzcwkAzAgCCQClCAEFC3VzZXJBZGRyZXNzCQDMCAIFFGFkZGl0aW9uYWxMb2NrUm91bmRzCQDMCAIJAQ9nZXRQb3dlckFzc2V0SWQBBQ5mYWN0b3J5QWRkcmVzcwkAzAgCBQlwd3JBbW91bnQFA25pbAUDbmlsBQNuaWwJAJQKAgkAzAgCCQEEQnVybgIFDnBheW1lbnRBc3NldElkCAUHcGF5bWVudAZhbW91bnQFA25pbAUOZmFjdG9yeUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMbG9ja0ludGVybmFsBBNmYWN0b3J5QWRkcmVzc0J5dGVzEHVzZXJBZGRyZXNzQnl0ZXMHYXNzZXRJZAZhbW91bnQEC2NoZWNrQ2FsbGVyCQEIb25seVRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQOZmFjdG9yeUFkZHJlc3MJAQdBZGRyZXNzAQUTZmFjdG9yeUFkZHJlc3NCeXRlcwQLdXNlckFkZHJlc3MJAQdBZGRyZXNzAQUQdXNlckFkZHJlc3NCeXRlcwQRbG9ja0dsb2JhbENvdW50ZXIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJARRrZXlMb2NrR2xvYmFsQ291bnRlcgAAAAQMbG9ja0R1cmF0aW9uCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQ9rZXlMb2NrRHVyYXRpb24ACQEHd3JhcEVycgECFWludmFsaWQgbG9jayBkdXJhdGlvbgQHYWN0aW9ucwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQELbG9ja0FkZHJlc3MBBQ5mYWN0b3J5QWRkcmVzcwUGYW1vdW50BQdhc3NldElkBQNuaWwEDmZhY3RvcnlBY3Rpb25zCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJAQdrZXlMb2NrAgULdXNlckFkZHJlc3MFEWxvY2tHbG9iYWxDb3VudGVyCQDMCAIJAQpsb2NrRm9ybWF0BAUGaGVpZ2h0CQBkAgUGaGVpZ2h0BQxsb2NrRHVyYXRpb24FB2Fzc2V0SWQFBmFtb3VudAUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJARRrZXlMb2NrR2xvYmFsQ291bnRlcgAJAMwIAgkAZAIFEWxvY2tHbG9iYWxDb3VudGVyAAEFA25pbAUDbmlsBQNuaWwJAJQKAgUHYWN0aW9ucwUOZmFjdG9yeUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEGdW5sb2NrAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQOZmFjdG9yeUFkZHJlc3MIBQFpBmNhbGxlcgQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BAdjb3VudGVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIPaW52YWxpZCBjb3VudGVyBA0kdDAxNzYyNTE3NzkwCQEJbG9ja1BhcnNlAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEHa2V5TG9jawIFC3VzZXJBZGRyZXNzBQdjb3VudGVyCQEHd3JhcEVycgECDGludmFsaWQgbG9jawQEZnJvbQgFDSR0MDE3NjI1MTc3OTACXzEEAnRvCAUNJHQwMTc2MjUxNzc5MAJfMgQHYXNzZXRJZAgFDSR0MDE3NjI1MTc3OTACXzMEBmFtb3VudAgFDSR0MDE3NjI1MTc3OTACXzQEBnJlc3VsdAMJAGYCBQZoZWlnaHQFAnRvCQDMCAIJAPwHBAkBC2xvY2tBZGRyZXNzAQUOZmFjdG9yeUFkZHJlc3MCDXRyYW5zZmVyQXNzZXQJAMwIAggFC3VzZXJBZGRyZXNzBWJ5dGVzCQDMCAIFBmFtb3VudAkAzAgCBQdhc3NldElkBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtkZWxldGVFbnRyeQkAzAgCCQEHa2V5TG9jawIFC3VzZXJBZGRyZXNzBQdjb3VudGVyBQNuaWwFA25pbAUDbmlsBQR1bml0CQCUCgIFA25pbAUGcmVzdWx0AWkBBXByaWNlAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQOZmFjdG9yeUFkZHJlc3MIBQFpBmNhbGxlcgkAlAoCBQNuaWwICQEJY2FsY1ByaWNlAQUOZmFjdG9yeUFkZHJlc3MCXzEBaQEKcHJpY2VEZWJ1ZwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEDmZhY3RvcnlBZGRyZXNzCAUBaQZjYWxsZXIJAJQKAgUDbmlsCAkBCWNhbGNQcmljZQEFDmZhY3RvcnlBZGRyZXNzAl8yAWkBEGdldFRyZWFzdXJ5VmFsdWUCD2NhbGxlclB1YmxpY0tleQRhcmdzBA5mYWN0b3J5QWRkcmVzcwgFAWkGY2FsbGVyBA10cmVhc3VyeVZhbHVlCQEHZnJvbVgxOAIJARFjYWxjVHJlYXN1cnlWYWx1ZQEFDmZhY3RvcnlBZGRyZXNzCQBsBgAKAAAFDHVzZHREZWNpbWFscwAAAAAFBERPV04JAJQKAgUDbmlsBQ10cmVhc3VyeVZhbHVlAQJ0eAEGdmVyaWZ5AAkAAAIFB2NoYWluSWQFCGNoYWluSWRUzFkf2A==", "height": 2974251, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 39vgKtpBYiPeCfEuRJCMUJ2MnrG4Z75NhSZScURj9HeE Next: HWanK6PzTPuGB1KZ3wK7oQTmXjENDKdZuPYrZe6RDrWQ Diff:
OldNewDifferences
3333 func throwErr (s) = throw(wrapErr(s))
3434
3535
36+func onlyAddress (i,address) = if ((i.caller == address))
37+ then true
38+ else throwErr("permission denied")
39+
40+
41+func onlyThis (i) = onlyAddress(i, this)
42+
43+
3644 let wxAssetId = if ((chainId == chainIdW))
3745 then base58'Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on'
3846 else if ((chainId == chainIdT))
4957
5058
5159 func keyTreasuryValueByPeriod (period) = makeString(["%s%d", "treasuryValue", toString(period)], SEP)
60+
61+
62+func keyLockGlobalCounter () = makeString(["%s", "lockGlobalCounter"], SEP)
63+
64+
65+func keyLockDuration () = makeString(["%s", "lockDuration"], SEP)
66+
67+
68+func keyLock (userAddress,counter) = makeString(["%s%s%d", "lock", toString(userAddress), toString(counter)], SEP)
5269
5370
5471 func keySkinTotal (treasuryAddress) = ("skin_total_" + toString(treasuryAddress))
84101 case _ =>
85102 throw("Match error")
86103 }, wrapErr("invalid power contract address"))
104+
105+
106+func keyLockAddress () = "%s__lockAddress"
107+
108+
109+func lockAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyLockAddress()) {
110+ case s: String =>
111+ addressFromString(s)
112+ case _: Unit =>
113+ unit
114+ case _ =>
115+ throw("Match error")
116+}, wrapErr("invalid lock contract address"))
87117
88118
89119 func keyPoolsFactoryAddress () = "%s__poolsFactoryAddress"
125155
126156
127157 func getAssetInfoOrFail (assetId) = valueOrErrorMessage(assetInfo(assetId), wrapErr("invalid asset info"))
158+
159+
160+func lockFormat (from,to,assetId,amount) = [toString(from), toString(to), toBase58String(assetId), toString(amount)]
161+
162+
163+func lockParse (s) = {
164+ let parts = split(s, SEP)
165+ $Tuple4(valueOrErrorMessage(parseInt(parts[0]), wrapErr("error during processing lock start height")), valueOrErrorMessage(parseInt(parts[1]), wrapErr("error during processing lock end height")), fromBase58String(parts[2]), valueOrErrorMessage(parseInt(parts[3]), wrapErr("error during processing lock amount")))
166+ }
128167
129168
130169 func getAssetsBalances (targetAddress,assetIdList) = {
355394 }
356395
357396
358-func calcRewards (factoryAddress,paymentAmount) = {
397+func calcRewardsAndLock (factoryAddress,paymentAmount,userAddressOption) = {
359398 let assetsStr = split(getAssetsStr(factoryAddress), SEP)
360399 let wxdaoQuantity = getAssetInfoOrFail(getLpAssetId(factoryAddress)).quantity
361400 if ((wxdaoQuantity == wxdaoQuantity))
368407 let balance = fromX18(assetsBalances[index], pow(10, 0, assetDecimals, 0, 0, DOWN))
369408 let amount = fraction(balance, paymentAmount, wxdaoQuantity)
370409 if ((amount > 0))
371- then $Tuple2((acc._1 :+ assetId), (acc._2 :+ amount))
410+ then {
411+ let lock = if ((userAddressOption == unit))
412+ then unit
413+ else invoke(this, "lockInternal", [factoryAddress.bytes, value(userAddressOption).bytes, assetId, amount], nil)
414+ if ((lock == lock))
415+ then $Tuple2((acc._1 :+ assetId), (acc._2 :+ amount))
416+ else throw("Strict value is not equal to itself.")
417+ }
372418 else acc
373419 }
374420
395441 let startTreasuryValue = valueOrErrorMessage(getInteger(factoryAddress, keyTreasuryValueByPeriod(currentPeriod)), wrapErr(("invalid treasury value for period " + toString(currentPeriod))))
396442 let treasuryValue = fromX18(calcTreasuryValue(factoryAddress), pow(10, 0, usdtDecimals, 0, 0, DOWN))
397443 let treasuryValueDiff = (treasuryValue - startTreasuryValue)
398- let treasuryValueDiffRaw = toX18(treasuryValueDiff, pow(10, 0, usdtDecimals, 0, 0, DOWN))
444+ let treasuryValueDiffX18 = toX18(treasuryValueDiff, pow(10, 0, usdtDecimals, 0, 0, DOWN))
399445 let pwrAssetId = getPowerAssetId(factoryAddress)
400446 let pwrInfo = getAssetInfoOrFail(pwrAssetId)
401- let pwrPriceRaw = getAssetsPrices(poolsFactoryAddress, [toBase58String(pwrAssetId)])[0]
402- let pwrPrice = if ((pwrPriceRaw > toBigInt(0)))
403- then fromX18(pwrPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
447+ let pwrPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(pwrAssetId)])[0]
448+ let pwrPrice = if ((pwrPriceX18 > toBigInt(0)))
449+ then fromX18(pwrPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
404450 else throwErr("invalid PWR price")
405451 let treasuryAddress = getTreasuryAddress(factoryAddress)
406452 let skinTotal = valueOrElse(getInteger(powerContractAddress(factoryAddress), keySkinTotal(treasuryAddress)), 0)
407453 let wxdaoInfo = getAssetInfoOrFail(getLpAssetId(factoryAddress))
408454 let pwrRemaining = (wxdaoInfo.quantity / 100)
409455 let pwrAmount = (skinTotal + pwrRemaining)
410- let pwrAmountRaw = toX18(pwrAmount, pow(10, 0, pwrInfo.decimals, 0, 0, DOWN))
411- let factoryAddressWxBalanceRaw = getAssetsBalances(factoryAddress, [toBase58String(wxAssetId)])[0]
412- let factoryAddressWxBalance = fromX18(factoryAddressWxBalanceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
413- let wxPriceRaw = getAssetsPrices(poolsFactoryAddress, [toBase58String(wxAssetId)])[0]
414- let wxPrice = if ((wxPriceRaw > toBigInt(0)))
415- then fromX18(wxPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
456+ let pwrAmountX18 = toX18(pwrAmount, pow(10, 0, pwrInfo.decimals, 0, 0, DOWN))
457+ let factoryAddressWxBalanceX18 = getAssetsBalances(factoryAddress, [toBase58String(wxAssetId)])[0]
458+ let factoryAddressWxBalance = fromX18(factoryAddressWxBalanceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
459+ let wxPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(wxAssetId)])[0]
460+ let wxPrice = if ((wxPriceX18 > toBigInt(0)))
461+ then fromX18(wxPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
416462 else throwErr("invalid wx price")
417463 let wxdaoQuantity = wxdaoInfo.quantity
418- let wxdaoQuantityRaw = toX18(wxdaoQuantity, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
419- let wxDaoPriceRaw = (((pwrPriceRaw + fraction((factoryAddressWxBalanceRaw * toBigInt(100)), wxPriceRaw, wxdaoQuantityRaw)) + fraction(max([treasuryValueDiffRaw, toBigInt(0)]), (toBigInt(2) * mult18), (toBigInt(10) * pwrAmountRaw))) / toBigInt(100))
420- let wxDaoPrice = fromX18(wxDaoPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
421- let rewardsPrices = calcRewards(factoryAddress, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
464+ let wxdaoQuantityX18 = toX18(wxdaoQuantity, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
465+ let wxDaoPriceX18 = (((pwrPriceX18 + fraction((factoryAddressWxBalanceX18 * toBigInt(100)), wxPriceX18, wxdaoQuantityX18)) + fraction(max([treasuryValueDiffX18, toBigInt(0)]), (toBigInt(2) * mult18), (toBigInt(10) * pwrAmountX18))) / toBigInt(100))
466+ let wxDaoPrice = fromX18(wxDaoPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
467+ let rewardsPrices = calcRewardsAndLock(factoryAddress, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN), unit)
422468 $Tuple2([wxDaoPrice, rewardsPrices], [["wxDaoPrice", wxDaoPrice], ["pwrPrice", pwrPrice], ["factoryAddressWxBalance", factoryAddressWxBalance], ["wxPrice", wxPrice], ["wxdaoQuantity", wxdaoQuantity], ["treasuryValueDiff", treasuryValueDiff], ["pwrAmount", pwrAmount], ["skinTotal", skinTotal], ["pwrRemaining", pwrRemaining]])
423469 }
424470
436482 else throwErr(err)
437483 let pwrPrice = 100
438484 let pwrAmount = (payment.amount / pwrPrice)
439- let transfers = calcRewards(factoryAddress, payment.amount)
440- if ((transfers == transfers))
485+ let rewards = calcRewardsAndLock(factoryAddress, payment.amount, userAddress)
486+ if ((rewards == rewards))
441487 then {
442488 let additionalLockRounds = 0
443- let factoryActions = ([invoke(factoryAddress, "commitAfterStartWithLockRoundFor", [toString(powerContractAddress(factoryAddress)), toString(getTreasuryAddress(factoryAddress)), toString(userAddress), additionalLockRounds, getPowerAssetId(factoryAddress), pwrAmount], nil)] ++ (if ((size(transfers._1) == 0))
444- then nil
445- else [invoke(factoryAddress, "transferAssets", [userAddress.bytes, transfers._1, transfers._2], nil)]))
489+ let factoryActions = [invoke(factoryAddress, "commitAfterStartWithLockRoundFor", [toString(powerContractAddress(factoryAddress)), toString(getTreasuryAddress(factoryAddress)), toString(userAddress), additionalLockRounds, getPowerAssetId(factoryAddress), pwrAmount], nil)]
446490 $Tuple2([Burn(paymentAssetId, payment.amount)], factoryActions)
447491 }
448492 else throw("Strict value is not equal to itself.")
493+ }
494+
495+
496+
497+@Callable(i)
498+func lockInternal (factoryAddressBytes,userAddressBytes,assetId,amount) = {
499+ let checkCaller = onlyThis(i)
500+ if ((checkCaller == checkCaller))
501+ then {
502+ let factoryAddress = Address(factoryAddressBytes)
503+ let userAddress = Address(userAddressBytes)
504+ let lockGlobalCounter = valueOrElse(getInteger(factoryAddress, keyLockGlobalCounter()), 0)
505+ let lockDuration = valueOrErrorMessage(getInteger(factoryAddress, keyLockDuration()), wrapErr("invalid lock duration"))
506+ let actions = [ScriptTransfer(lockAddress(factoryAddress), amount, assetId)]
507+ let factoryActions = [invoke(factoryAddress, "stringEntry", [keyLock(userAddress, lockGlobalCounter), lockFormat(height, (height + lockDuration), assetId, amount)], nil), invoke(factoryAddress, "integerEntry", [keyLockGlobalCounter(), (lockGlobalCounter + 1)], nil)]
508+ $Tuple2(actions, factoryActions)
509+ }
510+ else throw("Strict value is not equal to itself.")
511+ }
512+
513+
514+
515+@Callable(i)
516+func unlock (callerPublicKey,args) = {
517+ let factoryAddress = i.caller
518+ let userAddress = addressFromPublicKey(callerPublicKey)
519+ let counter = valueOrErrorMessage(parseInt(args[0]), wrapErr("invalid counter"))
520+ let $t01762517790 = lockParse(valueOrErrorMessage(getString(factoryAddress, keyLock(userAddress, counter)), wrapErr("invalid lock")))
521+ let from = $t01762517790._1
522+ let to = $t01762517790._2
523+ let assetId = $t01762517790._3
524+ let amount = $t01762517790._4
525+ let result = if ((height > to))
526+ then [invoke(lockAddress(factoryAddress), "transferAsset", [userAddress.bytes, amount, assetId], nil), invoke(factoryAddress, "deleteEntry", [keyLock(userAddress, counter)], nil)]
527+ else unit
528+ $Tuple2(nil, result)
449529 }
450530
451531
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 7 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let chainId = take(drop(this.bytes, 1), 1)
55
66 let chainIdT = base58'2T'
77
88 let chainIdW = base58'2W'
99
1010 let SEP = "__"
1111
1212 let WAVES = "WAVES"
1313
1414 let contractFilename = "wxdao_calculator.ride"
1515
1616 let mult8 = 100000000
1717
1818 let mult18 = toBigInt(1000000000000000000)
1919
2020 let wavesDecimals = 8
2121
2222 let usdtDecimals = 6
2323
2424 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), mult18, toBigInt(origScaleMult))
2525
2626
2727 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), mult18))
2828
2929
3030 func wrapErr (s) = ((contractFilename + ": ") + s)
3131
3232
3333 func throwErr (s) = throw(wrapErr(s))
3434
3535
36+func onlyAddress (i,address) = if ((i.caller == address))
37+ then true
38+ else throwErr("permission denied")
39+
40+
41+func onlyThis (i) = onlyAddress(i, this)
42+
43+
3644 let wxAssetId = if ((chainId == chainIdW))
3745 then base58'Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on'
3846 else if ((chainId == chainIdT))
3947 then base58'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc'
4048 else throwErr("invalid chain id")
4149
4250 func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
4351
4452
4553 func keyStartHeightByPeriod (period) = makeString(["%s%d", "startHeight", toString(period)], SEP)
4654
4755
4856 func keyPeriodLength () = makeString(["%s", "periodLength"], SEP)
4957
5058
5159 func keyTreasuryValueByPeriod (period) = makeString(["%s%d", "treasuryValue", toString(period)], SEP)
60+
61+
62+func keyLockGlobalCounter () = makeString(["%s", "lockGlobalCounter"], SEP)
63+
64+
65+func keyLockDuration () = makeString(["%s", "lockDuration"], SEP)
66+
67+
68+func keyLock (userAddress,counter) = makeString(["%s%s%d", "lock", toString(userAddress), toString(counter)], SEP)
5269
5370
5471 func keySkinTotal (treasuryAddress) = ("skin_total_" + toString(treasuryAddress))
5572
5673
5774 func keyPowerConfigAddress () = "%s__powerConfigAddress"
5875
5976
6077 func powerConfigAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyPowerConfigAddress()) {
6178 case s: String =>
6279 addressFromString(s)
6380 case _: Unit =>
6481 unit
6582 case _ =>
6683 throw("Match error")
6784 }, wrapErr("invalid power config address"))
6885
6986
7087 func keyPowerAssetId () = "powerAssetId"
7188
7289
7390 func getPowerAssetId (factoryAddress) = fromBase58String(valueOrErrorMessage(getString(powerConfigAddress(factoryAddress), keyPowerAssetId()), wrapErr("invalid power asset id")))
7491
7592
7693 func keyPowerContractAddress () = "%s__powerContractAddress"
7794
7895
7996 func powerContractAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyPowerContractAddress()) {
8097 case s: String =>
8198 addressFromString(s)
8299 case _: Unit =>
83100 unit
84101 case _ =>
85102 throw("Match error")
86103 }, wrapErr("invalid power contract address"))
104+
105+
106+func keyLockAddress () = "%s__lockAddress"
107+
108+
109+func lockAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyLockAddress()) {
110+ case s: String =>
111+ addressFromString(s)
112+ case _: Unit =>
113+ unit
114+ case _ =>
115+ throw("Match error")
116+}, wrapErr("invalid lock contract address"))
87117
88118
89119 func keyPoolsFactoryAddress () = "%s__poolsFactoryAddress"
90120
91121
92122 func getPoolsFactoryAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyPoolsFactoryAddress()) {
93123 case s: String =>
94124 addressFromString(s)
95125 case _: Unit =>
96126 unit
97127 case _ =>
98128 throw("Match error")
99129 }, wrapErr("invalid pools factory address"))
100130
101131
102132 func keyTreasuryAddress () = "%s__treasuryAddress"
103133
104134
105135 func getTreasuryAddress (factoryAddress) = valueOrErrorMessage(match getString(factoryAddress, keyTreasuryAddress()) {
106136 case s: String =>
107137 addressFromString(s)
108138 case _: Unit =>
109139 unit
110140 case _ =>
111141 throw("Match error")
112142 }, wrapErr("invalid treasury address"))
113143
114144
115145 func keyAssets () = "%s__assets"
116146
117147
118148 func getAssetsStr (factoryAddress) = valueOrErrorMessage(getString(factoryAddress, keyAssets()), wrapErr("invalid assets"))
119149
120150
121151 func keyLpAssetId () = "%s__lpAssetId"
122152
123153
124154 func getLpAssetId (factoryAddress) = fromBase58String(valueOrErrorMessage(getString(factoryAddress, keyLpAssetId()), wrapErr("invalid lp asset id")))
125155
126156
127157 func getAssetInfoOrFail (assetId) = valueOrErrorMessage(assetInfo(assetId), wrapErr("invalid asset info"))
158+
159+
160+func lockFormat (from,to,assetId,amount) = [toString(from), toString(to), toBase58String(assetId), toString(amount)]
161+
162+
163+func lockParse (s) = {
164+ let parts = split(s, SEP)
165+ $Tuple4(valueOrErrorMessage(parseInt(parts[0]), wrapErr("error during processing lock start height")), valueOrErrorMessage(parseInt(parts[1]), wrapErr("error during processing lock end height")), fromBase58String(parts[2]), valueOrErrorMessage(parseInt(parts[3]), wrapErr("error during processing lock amount")))
166+ }
128167
129168
130169 func getAssetsBalances (targetAddress,assetIdList) = {
131170 func map (acc,nextAssetIdStr) = {
132171 let balance = if ((nextAssetIdStr == WAVES))
133172 then toX18(wavesBalance(targetAddress).available, pow(10, 0, wavesDecimals, 0, 0, DOWN))
134173 else {
135174 let assetId = fromBase58String(nextAssetIdStr)
136175 let assetDecimals = getAssetInfoOrFail(assetId).decimals
137176 toX18(assetBalance(targetAddress, assetId), pow(10, 0, assetDecimals, 0, 0, DOWN))
138177 }
139178 (acc :+ balance)
140179 }
141180
142181 let $l = assetIdList
143182 let $s = size($l)
144183 let $acc0 = nil
145184 func $f0_1 ($a,$i) = if (($i >= $s))
146185 then $a
147186 else map($a, $l[$i])
148187
149188 func $f0_2 ($a,$i) = if (($i >= $s))
150189 then $a
151190 else throw("List size exceeds 10")
152191
153192 $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)
154193 }
155194
156195
157196 func getAssetsPrices (poolsFactoryAddress,assetIdList) = if ((chainId == chainIdW))
158197 then {
159198 let wavesUsdtAddressStr = "3PKfrupEydU2nZAghVjZAfvCwMBkzuR1F52"
160199 let wavesUsdtPrice = parseBigIntValue({
161200 let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdtAddressStr], nil)
162201 if ($isInstanceOf(@, "String"))
163202 then @
164203 else throw(($getType(@) + " couldn't be cast to String"))
165204 })
166205 let wavesXtnAddressStr = "3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g"
167206 let wavesXtnPrice = parseBigIntValue({
168207 let @ = invoke(poolsFactoryAddress, "getPrice", [wavesXtnAddressStr], nil)
169208 if ($isInstanceOf(@, "String"))
170209 then @
171210 else throw(($getType(@) + " couldn't be cast to String"))
172211 })
173212 let xtnUsdtPrice = fraction(wavesUsdtPrice, mult18, wavesXtnPrice)
174213 func map (acc,nextAssetId) = {
175214 let price = match nextAssetId {
176215 case _ =>
177216 if (("2thsACuHmzDMuNezPM32wg9a3BwUzBWDeSKakgz3cw21" == $match0))
178217 then {
179218 let pwrWavesAddressStr = "3PDi7Qq8pLQYvtKyTfQuqqPUWyhoYbU957t"
180219 let pwrWavesPrice = parseBigIntValue({
181220 let @ = invoke(poolsFactoryAddress, "getPrice", [pwrWavesAddressStr], nil)
182221 if ($isInstanceOf(@, "String"))
183222 then @
184223 else throw(($getType(@) + " couldn't be cast to String"))
185224 })
186225 fraction(pwrWavesPrice, wavesUsdtPrice, mult18)
187226 }
188227 else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0))
189228 then {
190229 let wxWavesAddressStr = "3PFzaH2ghpwANHFgjeva83N1yxzErELx2eh"
191230 let wxWavesPrice = parseBigIntValue({
192231 let @ = invoke(poolsFactoryAddress, "getPrice", [wxWavesAddressStr], nil)
193232 if ($isInstanceOf(@, "String"))
194233 then @
195234 else throw(($getType(@) + " couldn't be cast to String"))
196235 })
197236 fraction(wxWavesPrice, wavesUsdtPrice, mult18)
198237 }
199238 else if (("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ" == $match0))
200239 then {
201240 let wavesUsdtwxgAddressStr = "3PKMVZ7kQeaREajYi8Yc25Ro6mcNw5D6QSa"
202241 let wavesUsdtwxgPrice = parseBigIntValue({
203242 let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdtwxgAddressStr], nil)
204243 if ($isInstanceOf(@, "String"))
205244 then @
206245 else throw(($getType(@) + " couldn't be cast to String"))
207246 })
208247 fraction(wavesUsdtPrice, mult18, wavesUsdtwxgPrice)
209248 }
210249 else if (("6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ" == $match0))
211250 then {
212251 let wavesUsdcwxgAddressStr = "3P3g3eipfG2NZKKQE8DZXt2E9tRJqii9jcX"
213252 let wavesUsdcwxgPrice = parseBigIntValue({
214253 let @ = invoke(poolsFactoryAddress, "getPrice", [wavesUsdcwxgAddressStr], nil)
215254 if ($isInstanceOf(@, "String"))
216255 then @
217256 else throw(($getType(@) + " couldn't be cast to String"))
218257 })
219258 fraction(wavesUsdtPrice, mult18, wavesUsdcwxgPrice)
220259 }
221260 else if (("HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk" == $match0))
222261 then {
223262 let ltcwxgXtnAddressStr = "3P94wvu5gA7VhjPgAB3twaeqdwHCwNK2vsn"
224263 let ltcwxgXtnPrice = parseBigIntValue({
225264 let @ = invoke(poolsFactoryAddress, "getPrice", [ltcwxgXtnAddressStr], nil)
226265 if ($isInstanceOf(@, "String"))
227266 then @
228267 else throw(($getType(@) + " couldn't be cast to String"))
229268 })
230269 fraction(ltcwxgXtnPrice, xtnUsdtPrice, mult18)
231270 }
232271 else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0))
233272 then {
234273 let ethwxgWavesAddressStr = "3P3XGTN6s292g9iwYhs3TEqJqHiffQYojuE"
235274 let ethwxgWavesPrice = parseBigIntValue({
236275 let @ = invoke(poolsFactoryAddress, "getPrice", [ethwxgWavesAddressStr], nil)
237276 if ($isInstanceOf(@, "String"))
238277 then @
239278 else throw(($getType(@) + " couldn't be cast to String"))
240279 })
241280 fraction(ethwxgWavesPrice, wavesUsdtPrice, mult18)
242281 }
243282 else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0))
244283 then {
245284 let btcwxgXtnAddressStr = "3PCBWDTA6jrFswd7gQgaE3Xk7gLM5RKofvp"
246285 let btcwxgXtnPrice = parseBigIntValue({
247286 let @ = invoke(poolsFactoryAddress, "getPrice", [btcwxgXtnAddressStr], nil)
248287 if ($isInstanceOf(@, "String"))
249288 then @
250289 else throw(($getType(@) + " couldn't be cast to String"))
251290 })
252291 fraction(btcwxgXtnPrice, xtnUsdtPrice, mult18)
253292 }
254293 else throwErr("invalid asset id")
255294 }
256295 (acc :+ price)
257296 }
258297
259298 let $l = assetIdList
260299 let $s = size($l)
261300 let $acc0 = nil
262301 func $f0_1 ($a,$i) = if (($i >= $s))
263302 then $a
264303 else map($a, $l[$i])
265304
266305 func $f0_2 ($a,$i) = if (($i >= $s))
267306 then $a
268307 else throw("List size exceeds 10")
269308
270309 $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)
271310 }
272311 else if ((chainId == chainIdT))
273312 then {
274313 func map (acc,nextAssetId) = {
275314 let price = match nextAssetId {
276315 case _ =>
277316 if (("EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc" == $match0))
278317 then {
279318 let wxUsdtAddressStr = "3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt"
280319 let wxUsdtPrice = parseBigIntValue({
281320 let @ = invoke(poolsFactoryAddress, "getPrice", [wxUsdtAddressStr], nil)
282321 if ($isInstanceOf(@, "String"))
283322 then @
284323 else throw(($getType(@) + " couldn't be cast to String"))
285324 })
286325 wxUsdtPrice
287326 }
288327 else if (("A7Ksh7fXyqm1KhKAiK3bAB2aiPSitQQF6v1pyu9SS3FR" == $match0))
289328 then {
290329 let usdcUsdtAddressStr = "3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA"
291330 let usdcUsdtPrice = parseBigIntValue({
292331 let @ = invoke(poolsFactoryAddress, "getPrice", [usdcUsdtAddressStr], nil)
293332 if ($isInstanceOf(@, "String"))
294333 then @
295334 else throw(($getType(@) + " couldn't be cast to String"))
296335 })
297336 usdcUsdtPrice
298337 }
299338 else if (("8Q6SE2ANebufw8JuPjJVRjZD6drD8ihjNjM8xaGUSfdR" == $match0))
300339 then {
301340 let price = toX18(150000000, pow(10, 0, usdtDecimals, 0, 0, DOWN))
302341 price
303342 }
304343 else throwErr("invalid asset id")
305344 }
306345 (acc :+ price)
307346 }
308347
309348 let $l = assetIdList
310349 let $s = size($l)
311350 let $acc0 = nil
312351 func $f0_1 ($a,$i) = if (($i >= $s))
313352 then $a
314353 else map($a, $l[$i])
315354
316355 func $f0_2 ($a,$i) = if (($i >= $s))
317356 then $a
318357 else throw("List size exceeds 10")
319358
320359 $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)
321360 }
322361 else throwErr("invalid chain id")
323362
324363
325364 func calcTreasuryValue (factoryAddress) = {
326365 let treasuryAddress = getTreasuryAddress(factoryAddress)
327366 let poolsFactoryAddress = getPoolsFactoryAddress(factoryAddress)
328367 let assetsStr = split(getAssetsStr(factoryAddress), SEP)
329368 let assetsBalances = getAssetsBalances(treasuryAddress, assetsStr)
330369 let assetsPrices = getAssetsPrices(poolsFactoryAddress, assetsStr)
331370 func reduce (acc,nextAssetIdStr) = {
332371 let assetId = fromBase58String(nextAssetIdStr)
333372 let index = valueOrErrorMessage(indexOf(assetsStr, nextAssetIdStr), wrapErr("invalid asset id"))
334373 let balance = assetsBalances[index]
335374 let price = assetsPrices[index]
336375 let assetValue = fraction(balance, price, mult18)
337376 (acc + assetValue)
338377 }
339378
340379 let treasuryValue = {
341380 let $l = assetsStr
342381 let $s = size($l)
343382 let $acc0 = toBigInt(0)
344383 func $f0_1 ($a,$i) = if (($i >= $s))
345384 then $a
346385 else reduce($a, $l[$i])
347386
348387 func $f0_2 ($a,$i) = if (($i >= $s))
349388 then $a
350389 else throw("List size exceeds 10")
351390
352391 $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)
353392 }
354393 treasuryValue
355394 }
356395
357396
358-func calcRewards (factoryAddress,paymentAmount) = {
397+func calcRewardsAndLock (factoryAddress,paymentAmount,userAddressOption) = {
359398 let assetsStr = split(getAssetsStr(factoryAddress), SEP)
360399 let wxdaoQuantity = getAssetInfoOrFail(getLpAssetId(factoryAddress)).quantity
361400 if ((wxdaoQuantity == wxdaoQuantity))
362401 then {
363402 let assetsBalances = getAssetsBalances(factoryAddress, assetsStr)
364403 func map (acc,nextAssetIdStr) = {
365404 let assetId = fromBase58String(nextAssetIdStr)
366405 let index = valueOrErrorMessage(indexOf(assetsStr, nextAssetIdStr), wrapErr("invalid asset balance"))
367406 let assetDecimals = getAssetInfoOrFail(assetId).decimals
368407 let balance = fromX18(assetsBalances[index], pow(10, 0, assetDecimals, 0, 0, DOWN))
369408 let amount = fraction(balance, paymentAmount, wxdaoQuantity)
370409 if ((amount > 0))
371- then $Tuple2((acc._1 :+ assetId), (acc._2 :+ amount))
410+ then {
411+ let lock = if ((userAddressOption == unit))
412+ then unit
413+ else invoke(this, "lockInternal", [factoryAddress.bytes, value(userAddressOption).bytes, assetId, amount], nil)
414+ if ((lock == lock))
415+ then $Tuple2((acc._1 :+ assetId), (acc._2 :+ amount))
416+ else throw("Strict value is not equal to itself.")
417+ }
372418 else acc
373419 }
374420
375421 let $l = assetsStr
376422 let $s = size($l)
377423 let $acc0 = $Tuple2(nil, nil)
378424 func $f0_1 ($a,$i) = if (($i >= $s))
379425 then $a
380426 else map($a, $l[$i])
381427
382428 func $f0_2 ($a,$i) = if (($i >= $s))
383429 then $a
384430 else throw("List size exceeds 6")
385431
386432 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
387433 }
388434 else throw("Strict value is not equal to itself.")
389435 }
390436
391437
392438 func calcPrice (factoryAddress) = {
393439 let poolsFactoryAddress = getPoolsFactoryAddress(factoryAddress)
394440 let currentPeriod = valueOrErrorMessage(getInteger(factoryAddress, keyCurrentPeriod()), wrapErr("invalid current period"))
395441 let startTreasuryValue = valueOrErrorMessage(getInteger(factoryAddress, keyTreasuryValueByPeriod(currentPeriod)), wrapErr(("invalid treasury value for period " + toString(currentPeriod))))
396442 let treasuryValue = fromX18(calcTreasuryValue(factoryAddress), pow(10, 0, usdtDecimals, 0, 0, DOWN))
397443 let treasuryValueDiff = (treasuryValue - startTreasuryValue)
398- let treasuryValueDiffRaw = toX18(treasuryValueDiff, pow(10, 0, usdtDecimals, 0, 0, DOWN))
444+ let treasuryValueDiffX18 = toX18(treasuryValueDiff, pow(10, 0, usdtDecimals, 0, 0, DOWN))
399445 let pwrAssetId = getPowerAssetId(factoryAddress)
400446 let pwrInfo = getAssetInfoOrFail(pwrAssetId)
401- let pwrPriceRaw = getAssetsPrices(poolsFactoryAddress, [toBase58String(pwrAssetId)])[0]
402- let pwrPrice = if ((pwrPriceRaw > toBigInt(0)))
403- then fromX18(pwrPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
447+ let pwrPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(pwrAssetId)])[0]
448+ let pwrPrice = if ((pwrPriceX18 > toBigInt(0)))
449+ then fromX18(pwrPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
404450 else throwErr("invalid PWR price")
405451 let treasuryAddress = getTreasuryAddress(factoryAddress)
406452 let skinTotal = valueOrElse(getInteger(powerContractAddress(factoryAddress), keySkinTotal(treasuryAddress)), 0)
407453 let wxdaoInfo = getAssetInfoOrFail(getLpAssetId(factoryAddress))
408454 let pwrRemaining = (wxdaoInfo.quantity / 100)
409455 let pwrAmount = (skinTotal + pwrRemaining)
410- let pwrAmountRaw = toX18(pwrAmount, pow(10, 0, pwrInfo.decimals, 0, 0, DOWN))
411- let factoryAddressWxBalanceRaw = getAssetsBalances(factoryAddress, [toBase58String(wxAssetId)])[0]
412- let factoryAddressWxBalance = fromX18(factoryAddressWxBalanceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
413- let wxPriceRaw = getAssetsPrices(poolsFactoryAddress, [toBase58String(wxAssetId)])[0]
414- let wxPrice = if ((wxPriceRaw > toBigInt(0)))
415- then fromX18(wxPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
456+ let pwrAmountX18 = toX18(pwrAmount, pow(10, 0, pwrInfo.decimals, 0, 0, DOWN))
457+ let factoryAddressWxBalanceX18 = getAssetsBalances(factoryAddress, [toBase58String(wxAssetId)])[0]
458+ let factoryAddressWxBalance = fromX18(factoryAddressWxBalanceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
459+ let wxPriceX18 = getAssetsPrices(poolsFactoryAddress, [toBase58String(wxAssetId)])[0]
460+ let wxPrice = if ((wxPriceX18 > toBigInt(0)))
461+ then fromX18(wxPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
416462 else throwErr("invalid wx price")
417463 let wxdaoQuantity = wxdaoInfo.quantity
418- let wxdaoQuantityRaw = toX18(wxdaoQuantity, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
419- let wxDaoPriceRaw = (((pwrPriceRaw + fraction((factoryAddressWxBalanceRaw * toBigInt(100)), wxPriceRaw, wxdaoQuantityRaw)) + fraction(max([treasuryValueDiffRaw, toBigInt(0)]), (toBigInt(2) * mult18), (toBigInt(10) * pwrAmountRaw))) / toBigInt(100))
420- let wxDaoPrice = fromX18(wxDaoPriceRaw, pow(10, 0, usdtDecimals, 0, 0, DOWN))
421- let rewardsPrices = calcRewards(factoryAddress, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
464+ let wxdaoQuantityX18 = toX18(wxdaoQuantity, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN))
465+ let wxDaoPriceX18 = (((pwrPriceX18 + fraction((factoryAddressWxBalanceX18 * toBigInt(100)), wxPriceX18, wxdaoQuantityX18)) + fraction(max([treasuryValueDiffX18, toBigInt(0)]), (toBigInt(2) * mult18), (toBigInt(10) * pwrAmountX18))) / toBigInt(100))
466+ let wxDaoPrice = fromX18(wxDaoPriceX18, pow(10, 0, usdtDecimals, 0, 0, DOWN))
467+ let rewardsPrices = calcRewardsAndLock(factoryAddress, pow(10, 0, wxdaoInfo.decimals, 0, 0, DOWN), unit)
422468 $Tuple2([wxDaoPrice, rewardsPrices], [["wxDaoPrice", wxDaoPrice], ["pwrPrice", pwrPrice], ["factoryAddressWxBalance", factoryAddressWxBalance], ["wxPrice", wxPrice], ["wxdaoQuantity", wxdaoQuantity], ["treasuryValueDiff", treasuryValueDiff], ["pwrAmount", pwrAmount], ["skinTotal", skinTotal], ["pwrRemaining", pwrRemaining]])
423469 }
424470
425471
426472 @Callable(i)
427473 func swap (callerPublicKey,args) = {
428474 let factoryAddress = i.caller
429475 let userAddress = addressFromPublicKey(callerPublicKey)
430476 let payment = if ((size(i.payments) == 1))
431477 then i.payments[0]
432478 else throwErr("1 payment is required")
433479 let err = wrapErr("invalid payment asset id")
434480 let paymentAssetId = if ((valueOrErrorMessage(payment.assetId, err) == getLpAssetId(factoryAddress)))
435481 then value(payment.assetId)
436482 else throwErr(err)
437483 let pwrPrice = 100
438484 let pwrAmount = (payment.amount / pwrPrice)
439- let transfers = calcRewards(factoryAddress, payment.amount)
440- if ((transfers == transfers))
485+ let rewards = calcRewardsAndLock(factoryAddress, payment.amount, userAddress)
486+ if ((rewards == rewards))
441487 then {
442488 let additionalLockRounds = 0
443- let factoryActions = ([invoke(factoryAddress, "commitAfterStartWithLockRoundFor", [toString(powerContractAddress(factoryAddress)), toString(getTreasuryAddress(factoryAddress)), toString(userAddress), additionalLockRounds, getPowerAssetId(factoryAddress), pwrAmount], nil)] ++ (if ((size(transfers._1) == 0))
444- then nil
445- else [invoke(factoryAddress, "transferAssets", [userAddress.bytes, transfers._1, transfers._2], nil)]))
489+ let factoryActions = [invoke(factoryAddress, "commitAfterStartWithLockRoundFor", [toString(powerContractAddress(factoryAddress)), toString(getTreasuryAddress(factoryAddress)), toString(userAddress), additionalLockRounds, getPowerAssetId(factoryAddress), pwrAmount], nil)]
446490 $Tuple2([Burn(paymentAssetId, payment.amount)], factoryActions)
447491 }
448492 else throw("Strict value is not equal to itself.")
493+ }
494+
495+
496+
497+@Callable(i)
498+func lockInternal (factoryAddressBytes,userAddressBytes,assetId,amount) = {
499+ let checkCaller = onlyThis(i)
500+ if ((checkCaller == checkCaller))
501+ then {
502+ let factoryAddress = Address(factoryAddressBytes)
503+ let userAddress = Address(userAddressBytes)
504+ let lockGlobalCounter = valueOrElse(getInteger(factoryAddress, keyLockGlobalCounter()), 0)
505+ let lockDuration = valueOrErrorMessage(getInteger(factoryAddress, keyLockDuration()), wrapErr("invalid lock duration"))
506+ let actions = [ScriptTransfer(lockAddress(factoryAddress), amount, assetId)]
507+ let factoryActions = [invoke(factoryAddress, "stringEntry", [keyLock(userAddress, lockGlobalCounter), lockFormat(height, (height + lockDuration), assetId, amount)], nil), invoke(factoryAddress, "integerEntry", [keyLockGlobalCounter(), (lockGlobalCounter + 1)], nil)]
508+ $Tuple2(actions, factoryActions)
509+ }
510+ else throw("Strict value is not equal to itself.")
511+ }
512+
513+
514+
515+@Callable(i)
516+func unlock (callerPublicKey,args) = {
517+ let factoryAddress = i.caller
518+ let userAddress = addressFromPublicKey(callerPublicKey)
519+ let counter = valueOrErrorMessage(parseInt(args[0]), wrapErr("invalid counter"))
520+ let $t01762517790 = lockParse(valueOrErrorMessage(getString(factoryAddress, keyLock(userAddress, counter)), wrapErr("invalid lock")))
521+ let from = $t01762517790._1
522+ let to = $t01762517790._2
523+ let assetId = $t01762517790._3
524+ let amount = $t01762517790._4
525+ let result = if ((height > to))
526+ then [invoke(lockAddress(factoryAddress), "transferAsset", [userAddress.bytes, amount, assetId], nil), invoke(factoryAddress, "deleteEntry", [keyLock(userAddress, counter)], nil)]
527+ else unit
528+ $Tuple2(nil, result)
449529 }
450530
451531
452532
453533 @Callable(i)
454534 func price (callerPublicKey,args) = {
455535 let factoryAddress = i.caller
456536 $Tuple2(nil, calcPrice(factoryAddress)._1)
457537 }
458538
459539
460540
461541 @Callable(i)
462542 func priceDebug (callerPublicKey,args) = {
463543 let factoryAddress = i.caller
464544 $Tuple2(nil, calcPrice(factoryAddress)._2)
465545 }
466546
467547
468548
469549 @Callable(i)
470550 func getTreasuryValue (callerPublicKey,args) = {
471551 let factoryAddress = i.caller
472552 let treasuryValue = fromX18(calcTreasuryValue(factoryAddress), pow(10, 0, usdtDecimals, 0, 0, DOWN))
473553 $Tuple2(nil, treasuryValue)
474554 }
475555
476556
477557 @Verifier(tx)
478558 func verify () = (chainId == chainIdT)
479559

github/deemru/w8io/c3f4982 
55.41 ms