tx · 4vPaHqZC5m7isPt1EnhiRwn2YVmPVRaf91eGUNUipm14

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.02900000 Waves

2022.06.24 14:52 [2110456] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "4vPaHqZC5m7isPt1EnhiRwn2YVmPVRaf91eGUNUipm14", "fee": 2900000, "feeAssetId": null, "timestamp": 1656071556832, "version": 1, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "25YtsjGwoG9HBBKJMv4XHY9QT7X2W7jAit7nhjhtSJ1R3evSfzS4TyqiorHMLRJNWrH8zS3Lio6wVX7rmJWjucXw" ], "script": "base64:BgI5CAISCAoGCAgBAQEIEgMKAQESAwoBARIECgIICBIECgIICBIDCgEIEgMKAQgSBAoCCAESAwoBCBIAZQADU0VQAgJfXwAGU0NBTEU4AAgABU1VTFQ4AIDC1y8ADlBPT0xXRUlHSFRNVUxUBQVNVUxUOAEEc3RyZgIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAQNpb3oCB2FkZHJlc3MDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQAAAQNpb2QDB2FkZHJlc3MDa2V5CmRlZmF1bHRWYWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUHYWRkcmVzcwUDa2V5BQpkZWZhdWx0VmFsAQNpb2YCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEDYWJzAQN2YWwDCQBmAgAABQN2YWwJAQEtAQUDdmFsBQN2YWwBA2FhbAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMeXN0BQckbWF0Y2gwBQp2YWxBbnlMeXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQJhaQEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAERa2V5RmFjdG9yeUFkZHJlc3MAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAQAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAACABRJZHhGYWN0b3J5Q2ZnSWRvRGFwcAADABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAABAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAFABVJZHhGYWN0b3J5Q2ZnUmVzdERhcHAABgAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAHABRJZHhGYWN0b3J5Q2ZnRGFvRGFwcAAIABpJZHhGYWN0b3J5Q2ZnTWFya2V0aW5nRGFwcAAJABpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcAAKABZJZHhGYWN0b3J5Q2ZnQmlyZHNEYXBwAAsBDWtleUZhY3RvcnlDZmcAAhElc19fZmFjdG9yeUNvbmZpZwEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARBrZXlGYWN0b3J5THBMaXN0AAIQJXNfX2xwVG9rZW5zTGlzdAEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARRrZXlGYWN0b3J5UG9vbFdlaWdodAEPY29udHJhY3RBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFD2NvbnRyYWN0QWRkcmVzcwUDbmlsBQNTRVABG2tleUZhY3RvcnlQb29sV2VpZ2h0SGlzdG9yeQILcG9vbEFkZHJlc3MDbnVtCQCsAgIJAKwCAgkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FC3Bvb2xBZGRyZXNzAgJfXwkApAMBBQNudW0BGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQRzdHJmAgUEdGhpcwkBEWtleUZhY3RvcnlBZGRyZXNzAAEKcmVhZExwTGlzdAAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCCQEYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAkBEGtleUZhY3RvcnlMcExpc3QAAgAFA1NFUAEUcmVhZEZhY3RvcnlDZmdPckZhaWwBB2ZhY3RvcnkJALUJAgkBBHN0cmYCBQdmYWN0b3J5CQENa2V5RmFjdG9yeUNmZwAFA1NFUAEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABGWdldEd3eFJld2FyZEFkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHABE2tleU1hbmFnZXJQdWJsaWNLZXkAAhQlc19fbWFuYWdlclB1YmxpY0tleQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAIeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50ARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAIYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uARNrZXlFbWlzc2lvbkVuZEJsb2NrAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQ1rZXlOZXh0UGVyaW9kAAIOJXNfX25leHRQZXJpb2QBH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQAAiglcyVzX19nd3hSZXdhcmRFbWlzc2lvblBhcnRfX3N0YXJ0SGVpZ2h0AA1JZHhDZmdBc3NldElkAAEAE0lkeENmZ01pbkxvY2tBbW91bnQAAgAVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uAAMAFUlkeENmZ01heExvY2tEdXJhdGlvbgAEABJJZHhDZmdNYXRoQ29udHJhY3QABQEJa2V5Q29uZmlnAAIKJXNfX2NvbmZpZwEVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAkAtQkCCQEEc3RyZgIFBHRoaXMJAQlrZXlDb25maWcABQNTRVABDWZvcm1hdENvbmZpZ1MFB2Fzc2V0SWQNbWluTG9ja0Ftb3VudA9taW5Mb2NrRHVyYXRpb24PbWF4TG9ja0R1cmF0aW9uDG1hdGhDb250cmFjdAkAuQkCCQDMCAICCCVzJWQlZCVkCQDMCAIFB2Fzc2V0SWQJAMwIAgUNbWluTG9ja0Ftb3VudAkAzAgCBQ9taW5Mb2NrRHVyYXRpb24JAMwIAgUPbWF4TG9ja0R1cmF0aW9uCQDMCAIFDG1hdGhDb250cmFjdAUDbmlsBQNTRVABDGZvcm1hdENvbmZpZwUHYXNzZXRJZA1taW5Mb2NrQW1vdW50D21pbkxvY2tEdXJhdGlvbg9tYXhMb2NrRHVyYXRpb24MbWF0aENvbnRyYWN0CQENZm9ybWF0Q29uZmlnUwUFB2Fzc2V0SWQJAKQDAQUNbWluTG9ja0Ftb3VudAkApAMBBQ9taW5Mb2NrRHVyYXRpb24JAKQDAQUPbWF4TG9ja0R1cmF0aW9uBQxtYXRoQ29udHJhY3QBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARNrZXlNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yAA5JZHhMb2NrVXNlck51bQABAA1JZHhMb2NrQW1vdW50AAIADElkeExvY2tTdGFydAADAA9JZHhMb2NrRHVyYXRpb24ABAANSWR4TG9ja1BhcmFtSwAFAA1JZHhMb2NrUGFyYW1CAAYBE2tleUxvY2tQYXJhbXNSZWNvcmQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIKJXMlc19fbG9jawkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQt1c2VyQWRkcmVzcwkAtQkCCQEEc3RyZgIFBHRoaXMJARNrZXlMb2NrUGFyYW1zUmVjb3JkAQULdXNlckFkZHJlc3MFA1NFUAEXZm9ybWF0TG9ja1BhcmFtc1JlY29yZFMIB3VzZXJOdW0GYW1vdW50BXN0YXJ0CGR1cmF0aW9uBnBhcmFtSwZwYXJhbUIQbGFzdFVwZFRpbWVzdGFtcAlnd3hBbW91bnQJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIFB3VzZXJOdW0JAMwIAgUGYW1vdW50CQDMCAIFBXN0YXJ0CQDMCAIFCGR1cmF0aW9uCQDMCAIFBnBhcmFtSwkAzAgCBQZwYXJhbUIJAMwIAgUQbGFzdFVwZFRpbWVzdGFtcAkAzAgCBQlnd3hBbW91bnQFA25pbAUDU0VQARZmb3JtYXRMb2NrUGFyYW1zUmVjb3JkBwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgZwYXJhbUsGcGFyYW1CCWd3eEFtb3VudAkBF2Zvcm1hdExvY2tQYXJhbXNSZWNvcmRTCAUHdXNlck51bQkApAMBBQZhbW91bnQJAKQDAQUFc3RhcnQJAKQDAQUIZHVyYXRpb24JAKQDAQUGcGFyYW1LCQCkAwEFBnBhcmFtQgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkApAMBBQlnd3hBbW91bnQBDmtleU5leHRVc2VyTnVtAAIPJXNfX25leHRVc2VyTnVtARJrZXlVc2VyMk51bU1hcHBpbmcBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX191c2VyMm51bQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABEmtleU51bTJVc2VyTWFwcGluZwEDbnVtCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX19udW0ydXNlcgkAzAgCBQNudW0FA25pbAUDU0VQARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQd1c2VyTnVtCQDMCAICBmFtb3VudAUDbmlsBQNTRVABFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIFc3RhcnQFA25pbAUDU0VQARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAghkdXJhdGlvbgUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUsBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBawUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUIBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgUDbmlsBQNTRVABFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwIHdXNlck51bQZwZXJpb2QJALkJAgkAzAgCAhclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkAzAgCBQd1c2VyTnVtCQDMCAICAWsJAMwIAgUGcGVyaW9kBQNuaWwFA1NFUAEVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAgd1c2VyTnVtBnBlcmlvZAkAuQkCCQDMCAICFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgkAzAgCBQZwZXJpb2QFA25pbAUDU0VQARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAACHiVzJXNfX3N0YXRzX19hY3RpdmVUb3RhbExvY2tlZAEga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MAAiUlcyVzX19zdGF0c19fbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzARJrZXlTdGF0c0xvY2tzQ291bnQAAhclcyVzX19zdGF0c19fbG9ja3NDb3VudAESa2V5U3RhdHNVc2Vyc0NvdW50AAIdJXMlc19fc3RhdHNfX2FjdGl2ZVVzZXJzQ291bnQBIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIeJXMlZF9fdXNlckJvb3N0RW1pc3Npb25MYXN0SW50CQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQASJrZXlVc2VyTHBCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAgd1c2VyTnVtCWxwQXNzZXRJZAkAuQkCCQDMCAICHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkAzAgCBQd1c2VyTnVtCQDMCAIFCWxwQXNzZXRJZAUDbmlsBQNTRVABF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIRJXMlZF9fbWF4Qm9vc3RJbnQJAMwIAgUHdXNlck51bQUDbmlsBQNTRVABGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAACGCVzJXNfX21heEJvb3N0SW50X190b3RhbAEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQd1c2VyTnVtCQC5CQIJAMwIAgIkJXMlZF9fdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQARNrZXlVc2VyQm9vc3RDbGFpbWVkAQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZF9fdXNlckJvb3N0Q2xhaW1lZAkAzAgCBQd1c2VyTnVtBQNuaWwFA1NFUAERa2V5VG90YWxDYWNoZWRHd3gAAhYlcyVzX19nd3hDYWNoZWRfX3RvdGFsAA9mYWN0b3J5Q29udHJhY3QJARhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwAAApmYWN0b3J5Q2ZnCQEUcmVhZEZhY3RvcnlDZmdPckZhaWwBBQ9mYWN0b3J5Q29udHJhY3QAEGVtaXNzaW9uQ29udHJhY3QJARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBBQpmYWN0b3J5Q2ZnAA9zdGFraW5nQ29udHJhY3QJARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcAEWd3eFJld2FyZENvbnRyYWN0CQEZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcBDEhpc3RvcnlFbnRyeQgEdHlwZQR1c2VyBmFtb3VudAlsb2NrU3RhcnQIZHVyYXRpb24BawFiAWkECmhpc3RvcnlLRVkJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFBHVzZXIJAMwIAgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFA1NFUAQLaGlzdG9yeURBVEEJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQZhbW91bnQJAMwIAgkApAMBBQlsb2NrU3RhcnQJAMwIAgkApAMBBQhkdXJhdGlvbgkAzAgCCQCkAwEFAWsJAMwIAgkApAMBBQFiBQNuaWwFA1NFUAkBC1N0cmluZ0VudHJ5AgUKaGlzdG9yeUtFWQULaGlzdG9yeURBVEEBClN0YXRzRW50cnkEDnRvdGFsTG9ja2VkSW5jC2R1cmF0aW9uSW5jDGxvY2tDb3VudEluYw11c2Vyc0NvdW50SW5jBBtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJASBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwAEDWxvY2tzQ291bnRLRVkJARJrZXlTdGF0c0xvY2tzQ291bnQABA11c2Vyc0NvdW50S0VZCQESa2V5U3RhdHNVc2Vyc0NvdW50AAQOdG90YWxBbW91bnRLRVkJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwkBA2lvegIFBHRoaXMFG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQQKbG9ja3NDb3VudAkBA2lvegIFBHRoaXMFDWxvY2tzQ291bnRLRVkECnVzZXJzQ291bnQJAQNpb3oCBQR0aGlzBQ11c2Vyc0NvdW50S0VZBAt0b3RhbEFtb3VudAkBA2lvegIFBHRoaXMFDnRvdGFsQW1vdW50S0VZCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJAGQCBRhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MFC2R1cmF0aW9uSW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1sb2Nrc0NvdW50S0VZCQBkAgUKbG9ja3NDb3VudAUMbG9ja0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ11c2Vyc0NvdW50S0VZCQBkAgUKdXNlcnNDb3VudAUNdXNlcnNDb3VudEluYwkAzAgCCQEMSW50ZWdlckVudHJ5AgUOdG90YWxBbW91bnRLRVkJAGQCBQt0b3RhbEFtb3VudAUOdG90YWxMb2NrZWRJbmMFA25pbAENY2FsY0d3eEFtb3VudAMEa1JhdwRiUmF3AWgEBVNDQUxFAOgHCQBpAgkAZAIJAGgCBQRrUmF3BQFoBQRiUmF3BQVTQ0FMRQEPTG9ja1BhcmFtc0VudHJ5CAt1c2VyQWRkcmVzcwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgFrAWIGcGVyaW9kBA11c2VyQW1vdW50S0VZCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFB3VzZXJOdW0EDXN0YXJ0QmxvY2tLRVkJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQUHdXNlck51bQQLZHVyYXRpb25LRVkJARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEFB3VzZXJOdW0EBGtLRVkJAQ1rZXlMb2NrUGFyYW1LAQUHdXNlck51bQQEYktFWQkBDWtleUxvY2tQYXJhbUIBBQd1c2VyTnVtBAxrQnlQZXJpb2RLRVkJARVrZXlMb2NrUGFyYW1CeVBlcmlvZEsCBQd1c2VyTnVtBQZwZXJpb2QEDGJCeVBlcmlvZEtFWQkBFWtleUxvY2tQYXJhbUJ5UGVyaW9kQgIFB3VzZXJOdW0FBnBlcmlvZAQJZ3d4QW1vdW50CQENY2FsY0d3eEFtb3VudAMFAWsFAWIFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNdXNlckFtb3VudEtFWQUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1zdGFydEJsb2NrS0VZBQVzdGFydAkAzAgCCQEMSW50ZWdlckVudHJ5AgULZHVyYXRpb25LRVkFCGR1cmF0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrS0VZBQFrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRiS0VZBQFiCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQxrQnlQZXJpb2RLRVkFAWsJAMwIAgkBDEludGVnZXJFbnRyeQIFDGJCeVBlcmlvZEtFWQUBYgkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TG9ja1BhcmFtc1JlY29yZAEFC3VzZXJBZGRyZXNzCQEWZm9ybWF0TG9ja1BhcmFtc1JlY29yZAcFB3VzZXJOdW0FBmFtb3VudAUFc3RhcnQFCGR1cmF0aW9uBQFrBQFiBQlnd3hBbW91bnQFA25pbAEiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbAIBaQ9leHBlY3RlZEFzc2V0SWQDCQBmAgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIbb25seSBvbmUgcGF5bWVudCBpcyBhbGxvd2VkAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAAABANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUPZXhwZWN0ZWRBc3NldElkCQACAQIbaW52YWxpZCBhc3NldCBpZCBpbiBwYXltZW50CAUDcG10BmFtb3VudAEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAILdXNlckFkZHJlc3MMdGFyZ2V0SGVpZ2h0BAVFTVBUWQIFZW1wdHkEEnVzZXIyTnVtTWFwcGluZ0tFWQkBEmtleVVzZXIyTnVtTWFwcGluZwEFC3VzZXJBZGRyZXNzBAd1c2VyTnVtCQELdmFsdWVPckVsc2UCCQCiCAEFEnVzZXIyTnVtTWFwcGluZ0tFWQUFRU1QVFkEAWsJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDWtleUxvY2tQYXJhbUsBBQd1c2VyTnVtAAAEAWIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDWtleUxvY2tQYXJhbUIBBQd1c2VyTnVtAAAEDWd3eEFtb3VudENhbGMJAQ1jYWxjR3d4QW1vdW50AwUBawUBYgUMdGFyZ2V0SGVpZ2h0BAlnd3hBbW91bnQDCQBmAgAABQ1nd3hBbW91bnRDYWxjAAAFDWd3eEFtb3VudENhbGMFCWd3eEFtb3VudAEUY2FsY0N1cnJlbnRHd3hBbW91bnQBC3VzZXJBZGRyZXNzCQEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAIFC3VzZXJBZGRyZXNzBQZoZWlnaHQBFGludGVybmFsQ2xhaW1XeEJvb3N0AwxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIIcmVhZE9ubHkEBUVNUFRZAgVFTVBUWQQRdXNlclJlY29yZE9yRW1wdHkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBE2tleUxvY2tQYXJhbXNSZWNvcmQBBQ51c2VyQWRkcmVzc1N0cgUFRU1QVFkDCQAAAgURdXNlclJlY29yZE9yRW1wdHkFBUVNUFRZCQCVCgMAAAUDbmlsAhV1c2VyUmVjb3JkOjppczo6ZW1wdHkED3VzZXJSZWNvcmRBcnJheQkAtQkCBRF1c2VyUmVjb3JkT3JFbXB0eQUDU0VQBAp1c2VyTnVtU3RyCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUOSWR4TG9ja1VzZXJOdW0EHGd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgURZ3d4UmV3YXJkQ29udHJhY3QJAR9rZXlHd3hSZXdhcmRFbWlzc2lvblN0YXJ0SGVpZ2h0AAAABAhFTVBUWVNUUgIFZW1wdHkEDSR0MDEzMTY3MTM3MzUDCQECIT0CBQxscEFzc2V0SWRTdHIFCEVNUFRZU1RSBA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBANwdzEJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2ZhY3RvcnlDb250cmFjdAkBFGtleUZhY3RvcnlQb29sV2VpZ2h0AQUOcG9vbEFkZHJlc3NTdHIEA3B3MAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9mYWN0b3J5Q29udHJhY3QJARtrZXlGYWN0b3J5UG9vbFdlaWdodEhpc3RvcnkCBQ5wb29sQWRkcmVzc1N0cgAABQNwdzEJAJQKAgUDcHcwBQNwdzEDBQhyZWFkT25seQkAlAoCAAAAAAkAAgEJAKwCAgIobm90IHJlYWRvbmx5IG1vZGU6IHVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAtwb29sV2VpZ2h0MAgFDSR0MDEzMTY3MTM3MzUCXzEEC3Bvb2xXZWlnaHQxCAUNJHQwMTMxNjcxMzczNQJfMgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBImtleVVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwCBQp1c2VyTnVtU3RyBQxscEFzc2V0SWRTdHIEIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwBBQp1c2VyTnVtU3RyBB11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBSJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEDaW96AgUEdGhpcwUgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGUCBRVib29zdEVtaXNzaW9uSW50ZWdyYWwFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsBAN1ZGgJAGsDBRl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsAAMJAGgCAAIFEnd4RW1pc3Npb25QZXJCbG9jawQGdUxhc3RICQBlAgUBaAUDdWRoBAR1ZGgwCQCWAwEJAMwIAgkAZQIFHGd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQFBnVMYXN0SAkAzAgCAAAFA25pbAQEdWRoMQkAZQIJAGUCBQFoBQZ1TGFzdEgFBHVkaDADAwMJAGYCAAAFBnVMYXN0SAYJAGYCAAAFBHVkaDEGCQBnAgkBA2FicwEJAGUCCQBkAgUEdWRoMAUEdWRoMQUDdWRoAAEJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFmludmFsaWQgdWRoIGNhbGM6IHVkaD0JAKQDAQUDdWRoAgggdUxhc3RIPQkApAMBBQZ1TGFzdEgCBiB1ZGgwPQkApAMBBQR1ZGgwAgYgdWRoMT0JAKQDAQUEdWRoMQMJAGYCAAAFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAAIBAhJ3cm9uZyBjYWxjdWxhdGlvbnMEF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEXa2V5VXNlck1heEJvb3N0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJARhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwABA91c2VyTWF4Qm9vc3RJbnQJAQNpb3oCBQR0aGlzBRd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWQQQdG90YWxNYXhCb29zdEludAkBA2lvegIFBHRoaXMFGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQQRdG90YWxDYWNoZWRHd3hLRVkJARFrZXlUb3RhbENhY2hlZEd3eAAEDnRvdGFsQ2FjaGVkR3d4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEXRvdGFsQ2FjaGVkR3d4S0VZAAAEC3VzZXJDdXJyR3d4CQEUY2FsY0N1cnJlbnRHd3hBbW91bnQBBQ51c2VyQWRkcmVzc1N0cgQhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQUKdXNlck51bVN0cgQedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEDaW96AgUEdGhpcwUhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMAUDdWRoBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMQUDdWRoBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDAJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULcG9vbFdlaWdodDAFDlBPT0xXRUlHSFRNVUxUBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDEJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULcG9vbFdlaWdodDEFDlBPT0xXRUlHSFRNVUxUBCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwAwkAAAIFDnRvdGFsQ2FjaGVkR3d4AAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULdXNlckN1cnJHd3gFDnRvdGFsQ2FjaGVkR3d4BCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxAwkAAAIFDnRvdGFsQ2FjaGVkR3d4AAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULdXNlckN1cnJHd3gFDnRvdGFsQ2FjaGVkR3d4BCF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAGQCBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxBBN1c2VyQm9vc3RDbGFpbWVkS0VZCQETa2V5VXNlckJvb3N0Q2xhaW1lZAEFCnVzZXJOdW1TdHIEEHVzZXJCb29zdENsYWltZWQJAQNpb3oCBQR0aGlzBRN1c2VyQm9vc3RDbGFpbWVkS0VZBBJ1c2VyQm9vc3RBdmFpbGFibGUJAGUCBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFEHVzZXJCb29zdENsYWltZWQECWRhdGFTdGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUVYm9vc3RFbWlzc2lvbkludGVncmFsBQNuaWwEBWRlYnVnCQC5CQIJAMwIAgkArAICAh51c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbD0JAKQDAQUddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwJAMwIAgkArAICAhp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsPQkApAMBBRl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQDMCAIJAKwCAgIQdXNlck1heEJvb3N0SW50PQkApAMBBQ91c2VyTWF4Qm9vc3RJbnQJAMwIAgkArAICAhF0b3RhbE1heEJvb3N0SW50PQkApAMBBRB0b3RhbE1heEJvb3N0SW50CQDMCAIJAKwCAgIfdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsPQkApAMBBR51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAMwIAgkArAICAiJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXc9CQCkAwEFIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkAzAgCCQCsAgICEXVzZXJCb29zdENsYWltZWQ9CQCkAwEFEHVzZXJCb29zdENsYWltZWQJAMwIAgkArAICAhN1c2VyQm9vc3RBdmFpbGFibGU9CQCkAwEFEnVzZXJCb29zdEF2YWlsYWJsZQkAzAgCCQCsAgICG3VzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwPQkApAMBBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAkAzAgCCQCsAgICG3VzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwxPQkApAMBBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQkAzAgCCQCsAgICH3Bvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMD0JAKQDAQUecG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwCQDMCAIJAKwCAgIfcG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwxPQkApAMBBR5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDEJAMwIAgkArAICAgxwb29sV2VpZ2h0MD0JAKQDAQULcG9vbFdlaWdodDAJAMwIAgkArAICAgxwb29sV2VpZ2h0MT0JAKQDAQULcG9vbFdlaWdodDEJAMwIAgkArAICAgJoPQkApAMBBQFoCQDMCAIJAKwCAgIEdWRoPQkApAMBBQN1ZGgJAMwIAgkArAICAgd1TGFzdEg9CQCkAwEFBnVMYXN0SAkAzAgCCQCsAgICBXVkaDA9CQCkAwEFBHVkaDAJAMwIAgkArAICAgV1ZGgxPQkApAMBBQR1ZGgxCQDMCAIJAKwCAgIMdXNlckN1cnJHd3g9CQCkAwEFC3VzZXJDdXJyR3d4CQDMCAIJAKwCAgIPdG90YWxDYWNoZWRHd3g9CQCkAwEFDnRvdGFsQ2FjaGVkR3d4BQNuaWwCAjo6CQCVCgMFIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwUJZGF0YVN0YXRlBQVkZWJ1ZwoBaQELY29uc3RydWN0b3IGEWZhY3RvcnlBZGRyZXNzU3RyDmxvY2tBc3NldElkU3RyDW1pbkxvY2tBbW91bnQLbWluRHVyYXRpb24LbWF4RHVyYXRpb24MbWF0aENvbnRyYWN0BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmtleU5leHRVc2VyTnVtAAAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAQlrZXlDb25maWcACQEMZm9ybWF0Q29uZmlnBQUObG9ja0Fzc2V0SWRTdHIFDW1pbkxvY2tBbW91bnQFC21pbkR1cmF0aW9uBQttYXhEdXJhdGlvbgUMbWF0aENvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlGYWN0b3J5QWRkcmVzcwAFEWZhY3RvcnlBZGRyZXNzU3RyBQNuaWwJAQpTdGF0c0VudHJ5BAAAAAAAAAAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBGxvY2sBCGR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQNbWluTG9ja0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRNJZHhDZmdNaW5Mb2NrQW1vdW50BA9taW5Mb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBA9tYXhMb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uBAxtYXRoQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ01hdGhDb250cmFjdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECNGludmFsaWQgcGF5bWVudCAtIGV4YWN0IG9uZSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAlwbXRBbW91bnQIBQNwbXQGYW1vdW50AwkBAiE9AgUHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkCQACAQkArAICCQCsAgICHmludmFsaWQgYXNzZXQgaXMgaW4gcGF5bWVudCAtIAUKYXNzZXRJZFN0cgIMIGlzIGV4cGVjdGVkBA5uZXh0VXNlck51bUtFWQkBDmtleU5leHRVc2VyTnVtAAQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBA51c2VySXNFeGlzdGluZwkBCWlzRGVmaW5lZAEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyBAp1c2VyTnVtU3RyAwUOdXNlcklzRXhpc3RpbmcJAQV2YWx1ZQEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyCQCkAwEJAQNpb2YCBQR0aGlzBQ5uZXh0VXNlck51bUtFWQQHdXNlck51bQkBDXBhcnNlSW50VmFsdWUBBQp1c2VyTnVtU3RyBAlsb2NrU3RhcnQFBmhlaWdodAQNc3RhcnRCbG9ja0tFWQkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQp1c2VyTnVtU3RyBAtkdXJhdGlvbktFWQkBFGtleUxvY2tQYXJhbUR1cmF0aW9uAQUKdXNlck51bVN0cgQNdXNlckFtb3VudEtFWQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQp1c2VyTnVtU3RyAwkAZgIFDW1pbkxvY2tBbW91bnQFCXBtdEFtb3VudAkAAgEJAKwCAgIiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkApAMBBQ1taW5Mb2NrQW1vdW50AwkAZgIFD21pbkxvY2tEdXJhdGlvbgUIZHVyYXRpb24JAAIBCQCsAgICLXBhc3NlZCBkdXJhdGlvbiBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUIZHVyYXRpb24FD21heExvY2tEdXJhdGlvbgkAAgEJAKwCAgIwcGFzc2VkIGR1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFD21heExvY2tEdXJhdGlvbgMDBQ51c2VySXNFeGlzdGluZwkAZwIJAGQCCQEDaW9mAgUEdGhpcwUNc3RhcnRCbG9ja0tFWQkBA2lvZgIFBHRoaXMFC2R1cmF0aW9uS0VZBQlsb2NrU3RhcnQHCQACAQI2dGhlcmUgaXMgYW4gYWN0aXZlIGxvY2sgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrAwkAZgIJAQNpb3oCBQR0aGlzBQ11c2VyQW1vdW50S0VZAAAJAAIBCQCsAgICNHRoZXJlIGFyZSBsb2NrZWQgV1hzIC0gY29uc2lkZXIgdG8gdXNlIGluY3JlYXNlTG9jayAFDXVzZXJBbW91bnRLRVkEB2NvZWZmWDgJAGsDBQhkdXJhdGlvbgUFTVVMVDgFD21heExvY2tEdXJhdGlvbgQOZ1d4QW1vdW50U3RhcnQJAGsDBQlwbXRBbW91bnQFB2NvZWZmWDgFBU1VTFQ4BBNnV3hQYXJhbXNSZXN1bHRMaXN0CQEDYWFsAQkA/AcEBQxtYXRoQ29udHJhY3QCFWNhbGNHd3hQYXJhbXNSRUFET05MWQkAzAgCBQ5nV3hBbW91bnRTdGFydAkAzAgCBQlsb2NrU3RhcnQJAMwIAgUIZHVyYXRpb24FA25pbAUDbmlsBAFrCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAQBYgkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAEEBnBlcmlvZAkApAMBCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEXa2V5VXNlck1heEJvb3N0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJARhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwABA91c2VyTWF4Qm9vc3RJbnQJAGkCCQBoAgUOZ1d4QW1vdW50U3RhcnQFCGR1cmF0aW9uAAIEEHRvdGFsTWF4Qm9vc3RJbnQJAQNpb3oCBQR0aGlzBRh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEEXRvdGFsQ2FjaGVkR3d4S0VZCQERa2V5VG90YWxDYWNoZWRHd3gABA50b3RhbENhY2hlZEd3eAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRF0b3RhbENhY2hlZEd3eEtFWQAABANhcnIDBQ51c2VySXNFeGlzdGluZwUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5uZXh0VXNlck51bUtFWQkAZAIFB3VzZXJOdW0AAQkAzAgCCQELU3RyaW5nRW50cnkCCQESa2V5VXNlcjJOdW1NYXBwaW5nAQUOdXNlckFkZHJlc3NTdHIFCnVzZXJOdW1TdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEmtleU51bTJVc2VyTWFwcGluZwEFCnVzZXJOdW1TdHIFDnVzZXJBZGRyZXNzU3RyBQNuaWwJAM4IAgkAzQgCCQDOCAIJAM4IAgUDYXJyCQEPTG9ja1BhcmFtc0VudHJ5CAUOdXNlckFkZHJlc3NTdHIFCnVzZXJOdW1TdHIFCXBtdEFtb3VudAUJbG9ja1N0YXJ0BQhkdXJhdGlvbgUBawUBYgUGcGVyaW9kCQEKU3RhdHNFbnRyeQQFCXBtdEFtb3VudAUIZHVyYXRpb24AAQMFDnVzZXJJc0V4aXN0aW5nAAAAAQkBDEhpc3RvcnlFbnRyeQgCBGxvY2sFDnVzZXJBZGRyZXNzU3RyBQlwbXRBbW91bnQFCWxvY2tTdGFydAUIZHVyYXRpb24FAWsFAWIFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBRVib29zdEVtaXNzaW9uSW50ZWdyYWwJAMwIAgkBDEludGVnZXJFbnRyeQIFEXRvdGFsQ2FjaGVkR3d4S0VZCQBkAgUOdG90YWxDYWNoZWRHd3gFDmdXeEFtb3VudFN0YXJ0BQNuaWwBaQEMaW5jcmVhc2VMb2NrAQ1kZWx0YUR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQPbWluTG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01pbkxvY2tEdXJhdGlvbgQPbWF4TG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01heExvY2tEdXJhdGlvbgQMbWF0aENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdNYXRoQ29udHJhY3QECXBtdEFtb3VudAkBImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwCBQFpBQdhc3NldElkBA51c2VyQWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQUOdXNlckFkZHJlc3NTdHIECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24EEXJlbWFpbmluZ0R1cmF0aW9uCQCWAwEJAMwIAgkAZQIFB2xvY2tFbmQFBmhlaWdodAkAzAgCAAAFA25pbAQNdXNlckFtb3VudE5ldwkAZAIFCnVzZXJBbW91bnQFCXBtdEFtb3VudAQPbG9ja0R1cmF0aW9uTmV3CQBkAgURcmVtYWluaW5nRHVyYXRpb24FDWRlbHRhRHVyYXRpb24DCQBmAgAABQ1kZWx0YUR1cmF0aW9uCQACAQIaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQBmAgUPbWluTG9ja0R1cmF0aW9uBQ9sb2NrRHVyYXRpb25OZXcJAAIBCQCsAgICLWxvY2tEdXJhdGlvbk5ldyBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUPbG9ja0R1cmF0aW9uTmV3BQ9tYXhMb2NrRHVyYXRpb24JAAIBCQCsAgICRGRlbHRhRHVyYXRpb24gKyBleGlzdGVkTG9ja0R1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFD21heExvY2tEdXJhdGlvbgQHY29lZmZYOAkAawMFD2xvY2tEdXJhdGlvbk5ldwUFTVVMVDgFD21heExvY2tEdXJhdGlvbgQOZ1d4QW1vdW50U3RhcnQJAGsDBQ11c2VyQW1vdW50TmV3BQdjb2VmZlg4BQVNVUxUOAQMbG9ja1N0YXJ0TmV3BQZoZWlnaHQEE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQNhYWwBCQD8BwQFDG1hdGhDb250cmFjdAIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFDmdXeEFtb3VudFN0YXJ0CQDMCAIFDGxvY2tTdGFydE5ldwkAzAgCBQ9sb2NrRHVyYXRpb25OZXcFA25pbAUDbmlsBAFrCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAQBYgkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAEEBnBlcmlvZAkApAMBCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEDaW96AgUEdGhpcwUgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGUCBRVib29zdEVtaXNzaW9uSW50ZWdyYWwFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAZgIAAAUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAgECEndyb25nIGNhbGN1bGF0aW9ucwQXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJARdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAED3VzZXJNYXhCb29zdEludAkBA2lvegIFBHRoaXMFF3VzZXJNYXhCb29zdEludGVncmFsS0VZBBB0b3RhbE1heEJvb3N0SW50CQEDaW96AgUEdGhpcwUYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAtjdXJyVXNlckd3eAkBFGNhbGNDdXJyZW50R3d4QW1vdW50AQUOdXNlckFkZHJlc3NTdHIEB2d3eERpZmYJAGUCBQ5nV3hBbW91bnRTdGFydAULY3VyclVzZXJHd3gDCQBmAgAABQdnd3hEaWZmCQACAQkArAICAhhnd3hEaWZmIGlzIGxlc3MgdGhlbiAwOiAJAKQDAQUHZ3d4RGlmZgQRdG90YWxDYWNoZWRHd3hLRVkJARFrZXlUb3RhbENhY2hlZEd3eAAEDnRvdGFsQ2FjaGVkR3d4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEXRvdGFsQ2FjaGVkR3d4S0VZAAAEIXVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbEtFWQkBIWtleVVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbAEFCnVzZXJOdW1TdHIEHnVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbAkBA2lvegIFBHRoaXMFIXVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbEtFWQQhdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3CQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAULY3VyclVzZXJHd3gFDnRvdGFsQ2FjaGVkR3d4BBJ1c2VyTWF4Qm9vc3RJbnROZXcJAGkCCQBoAgUOZ1d4QW1vdW50U3RhcnQFD2xvY2tEdXJhdGlvbk5ldwACBBhyZW1haW5pbmdVc2VyTWF4Qm9vc3RJbnQJAGkCCQBoAgULY3VyclVzZXJHd3gFEXJlbWFpbmluZ0R1cmF0aW9uAAIEE3VzZXJNYXhCb29zdEludERpZmYJAGUCBRJ1c2VyTWF4Qm9vc3RJbnROZXcFGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAkAzggCCQDNCAIJAM4IAgkBD0xvY2tQYXJhbXNFbnRyeQgFDnVzZXJBZGRyZXNzU3RyBQp1c2VyTnVtU3RyBQ11c2VyQW1vdW50TmV3BQxsb2NrU3RhcnROZXcFD2xvY2tEdXJhdGlvbk5ldwUBawUBYgUGcGVyaW9kCQEKU3RhdHNFbnRyeQQFCXBtdEFtb3VudAUNZGVsdGFEdXJhdGlvbgAAAAAJAQxIaXN0b3J5RW50cnkIAgRsb2NrBQ51c2VyQWRkcmVzc1N0cgUJcG10QW1vdW50BQlsb2NrU3RhcnQFD2xvY2tEdXJhdGlvbk5ldwUBawUBYgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgURdG90YWxDYWNoZWRHd3hLRVkJAGQCBQ50b3RhbENhY2hlZEd3eAUHZ3d4RGlmZgUDbmlsAWkBDGNsYWltV3hCb29zdAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyAwkBAiE9AgUPc3Rha2luZ0NvbnRyYWN0CAUBaQZjYWxsZXIJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQEDSR0MDI3NzUwMjc4NTIJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIHBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAyNzc1MDI3ODUyAl8xBAlkYXRhU3RhdGUIBQ0kdDAyNzc1MDI3ODUyAl8yBAVkZWJ1ZwgFDSR0MDI3NzUwMjc4NTICXzMJAJQKAgUJZGF0YVN0YXRlCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQUDbmlsAWkBFGNsYWltV3hCb29zdFJFQURPTkxZAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDSR0MDI3OTg0MjgwODUJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIGBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAyNzk4NDI4MDg1Al8xBAlkYXRhU3RhdGUIBQ0kdDAyNzk4NDI4MDg1Al8yBAVkZWJ1ZwgFDSR0MDI3OTg0MjgwODUCXzMJAJQKAgUDbmlsCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQkAzAgCBQVkZWJ1ZwUDbmlsAWkBBnVubG9jawELdXNlckFkZHJlc3MED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQULdXNlckFkZHJlc3MECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24ECGNmZ0FycmF5CQEVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAQHYXNzZXRJZAkA2QQBCQCRAwIFCGNmZ0FycmF5BQ1JZHhDZmdBc3NldElkBAxtYXRoQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ01hdGhDb250cmFjdAMJAGcCBQdsb2NrRW5kBQZoZWlnaHQJAAIBCQCsAgIJAKwCAgIFd2FpdCAJAKQDAQUHbG9ja0VuZAIKIHRvIHVubG9jawMJAGcCAAAFCnVzZXJBbW91bnQJAAIBAhFub3RoaW5nIHRvIHVubG9jawQGcGVyaW9kCQELdmFsdWVPckVsc2UCCQCaCAIFDG1hdGhDb250cmFjdAkBDWtleU5leHRQZXJpb2QAAAAJAM0IAgkAzQgCCQDOCAIJAQ9Mb2NrUGFyYW1zRW50cnkIBQt1c2VyQWRkcmVzcwUKdXNlck51bVN0cgAABQlsb2NrU3RhcnQFDGxvY2tEdXJhdGlvbgAAAAAJAKQDAQUGcGVyaW9kCQEKU3RhdHNFbnRyeQQJAQEtAQUKdXNlckFtb3VudAAAAAAA////////////AQkBDEhpc3RvcnlFbnRyeQgCBnVubG9jawULdXNlckFkZHJlc3MFCnVzZXJBbW91bnQFCWxvY2tTdGFydAUMbG9ja0R1cmF0aW9uAAAAAAUBaQkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQULdXNlckFkZHJlc3MFCnVzZXJBbW91bnQFB2Fzc2V0SWQBaQETZ3d4VXNlckluZm9SRUFET05MWQELdXNlckFkZHJlc3MECWd3eEFtb3VudAkBFGNhbGNDdXJyZW50R3d4QW1vdW50AQULdXNlckFkZHJlc3MJAJQKAgUDbmlsCQDMCAIFCWd3eEFtb3VudAUDbmlsAWkBIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZAgt1c2VyQWRkcmVzcwx0YXJnZXRIZWlnaHQECWd3eEFtb3VudAkBGWNhbGNVc2VyR3d4QW1vdW50QXRIZWlnaHQCBQt1c2VyQWRkcmVzcwUMdGFyZ2V0SGVpZ2h0CQCUCgIFA25pbAUJZ3d4QW1vdW50AWkBCnNldE1hbmFnZXIBF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEFWNoZWNrTWFuYWdlclB1YmxpY0tleQkA2QQBBRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQMJAAACBRVjaGVja01hbmFnZXJQdWJsaWNLZXkFFWNoZWNrTWFuYWdlclB1YmxpY0tleQkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmNvbmZpcm1NYW5hZ2VyAAQCcG0JAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEBWhhc1BNAwkBCWlzRGVmaW5lZAEFAnBtBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQVoYXNQTQUFaGFzUE0EB2NoZWNrUE0DCQAAAggFAWkPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJwbQYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUHY2hlY2tQTQUHY2hlY2tQTQkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TWFuYWdlclB1YmxpY0tleQAJANgEAQkBBXZhbHVlAQUCcG0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V58j41ng==", "chainId": 84, "height": 2110456, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9heaPi1NThZTuxzCg1yfszA6b4YefV7GErYeH45e7MmE Next: 8UkmtTr11M8siA41f1yFbnZKPZT25WgFgrZCLGxidLWx Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
1212 func strf (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1313
1414
15-func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
15+func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
1616
1717
18-func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
18+func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1919
2020
21-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
21+func iof (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2222
2323
2424 func abs (val) = if ((0 > val))
2626 else val
2727
2828
29-func asAnyList (val) = match val {
29+func aal (val) = match val {
3030 case valAnyLyst: List[Any] =>
3131 valAnyLyst
3232 case _ =>
3434 }
3535
3636
37-func asInt (val) = match val {
37+func ai (val) = match val {
3838 case valInt: Int =>
3939 valInt
4040 case _ =>
301301 let locksCountKEY = keyStatsLocksCount()
302302 let usersCountKEY = keyStatsUsersCount()
303303 let totalAmountKEY = keyLockParamTotalAmount()
304- let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
305- let locksCount = getIntOrZero(this, locksCountKEY)
306- let usersCount = getIntOrZero(this, usersCountKEY)
307- let totalAmount = getIntOrZero(this, totalAmountKEY)
304+ let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
305+ let locksCount = ioz(this, locksCountKEY)
306+ let usersCount = ioz(this, usersCountKEY)
307+ let totalAmount = ioz(this, totalAmountKEY)
308308 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
309309 }
310310
367367 let userNumStr = userRecordArray[IdxLockUserNum]
368368 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
369369 let EMPTYSTR = "empty"
370- let $t01317413742 = if ((lpAssetIdStr != EMPTYSTR))
370+ let $t01316713735 = if ((lpAssetIdStr != EMPTYSTR))
371371 then {
372372 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373373 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
377377 else if (readOnly)
378378 then $Tuple2(0, 0)
379379 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
380- let poolWeight0 = $t01317413742._1
381- let poolWeight1 = $t01317413742._2
382- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
383- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
384- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
380+ let poolWeight0 = $t01316713735._1
381+ let poolWeight1 = $t01316713735._2
382+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
383+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
384+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
385385 let h = if ((height > emissionEnd))
386386 then emissionEnd
387387 else height
388388 let dh = max([(h - emissionStart), 0])
389389 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
390390 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
391- let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
391+ let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
392392 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
393393 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
394394 let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
406406 else {
407407 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
408408 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
409- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
410- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
409+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
410+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
411411 let totalCachedGwxKEY = keyTotalCachedGwx()
412412 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
413413 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
414414 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
415- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
416- let userBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral, udh0, udh)
417- let userBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral, udh1, udh)
415+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
416+ let userBoostEmissionIntegral0 = if ((udh == 0))
417+ then 0
418+ else fraction(userBoostEmissionIntegral, udh0, udh)
419+ let userBoostEmissionIntegral1 = if ((udh == 0))
420+ then 0
421+ else fraction(userBoostEmissionIntegral, udh1, udh)
418422 let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
419423 let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
420424 let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
425429 else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
426430 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
427431 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
428- let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
432+ let userBoostClaimed = ioz(this, userBoostClaimedKEY)
429433 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
430434 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
431435 let debug = makeString([("userBoostEmissionLastIntegral=" + toString(userBoostEmissionLastIntegral)), ("userBoostEmissionIntegral=" + toString(userBoostEmissionIntegral)), ("userMaxBoostInt=" + toString(userMaxBoostInt)), ("totalMaxBoostInt=" + toString(totalMaxBoostInt)), ("userBoostAvaliableToClaimTotal=" + toString(userBoostAvaliableToClaimTotal)), ("userBoostAvaliableToClaimTotalNew=" + toString(userBoostAvaliableToClaimTotalNew)), ("userBoostClaimed=" + toString(userBoostClaimed)), ("userBoostAvailable=" + toString(userBoostAvailable)), ("userBoostEmissionIntegral0=" + toString(userBoostEmissionIntegral0)), ("userBoostEmissionIntegral1=" + toString(userBoostEmissionIntegral1)), ("poolUserBoostEmissionIntegral0=" + toString(poolUserBoostEmissionIntegral0)), ("poolUserBoostEmissionIntegral1=" + toString(poolUserBoostEmissionIntegral1)), ("poolWeight0=" + toString(poolWeight0)), ("poolWeight1=" + toString(poolWeight1)), ("h=" + toString(h)), ("udh=" + toString(udh)), ("uLastH=" + toString(uLastH)), ("udh0=" + toString(udh0)), ("udh1=" + toString(udh1)), ("userCurrGwx=" + toString(userCurrGwx)), ("totalCachedGwx=" + toString(totalCachedGwx))], "::")
467471 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
468472 let userNumStr = if (userIsExisting)
469473 then value(getString(keyUser2NumMapping(userAddressStr)))
470- else toString(getIntOrFail(this, nextUserNumKEY))
474+ else toString(iof(this, nextUserNumKEY))
471475 let userNum = parseIntValue(userNumStr)
472476 let lockStart = height
473477 let startBlockKEY = keyLockParamStartBlock(userNumStr)
480484 else if ((duration > maxLockDuration))
481485 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
482486 else if (if (userIsExisting)
483- then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
487+ then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
484488 else false)
485489 then throw("there is an active lock - consider to use increaseLock")
486- else if ((getIntOrZero(this, userAmountKEY) > 0))
490+ else if ((ioz(this, userAmountKEY) > 0))
487491 then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
488492 else {
489493 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
490494 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
491- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
492- let k = asInt(gWxParamsResultList[0])
493- let b = asInt(gWxParamsResultList[1])
494- let period = toString(asInt(gWxParamsResultList[2]))
495- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
496- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
497- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
495+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
496+ let k = ai(gWxParamsResultList[0])
497+ let b = ai(gWxParamsResultList[1])
498+ let period = toString(ai(gWxParamsResultList[2]))
499+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
500+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
501+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
498502 let h = if ((height > emissionEnd))
499503 then emissionEnd
500504 else height
504508 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
505509 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
506510 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
507- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
511+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
508512 let totalCachedGwxKEY = keyTotalCachedGwx()
509513 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
510514 let arr = if (userIsExisting)
549553 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
550554 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
551555 let lockStartNew = height
552- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
553- let k = asInt(gWxParamsResultList[0])
554- let b = asInt(gWxParamsResultList[1])
555- let period = toString(asInt(gWxParamsResultList[2]))
556- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
557- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
558- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
556+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
557+ let k = ai(gWxParamsResultList[0])
558+ let b = ai(gWxParamsResultList[1])
559+ let period = toString(ai(gWxParamsResultList[2]))
560+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
561+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
562+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
559563 let h = if ((height > emissionEnd))
560564 then emissionEnd
561565 else height
562566 let dh = max([(h - emissionStart), 0])
563567 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
564- let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
568+ let userBoostEmissionLastIntegral = ioz(this, userBoostEmissionLastIntegralKEY)
565569 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
566570 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
567571 if ((0 > userBoostEmissionIntegral))
569573 else {
570574 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
571575 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
572- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
573- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
576+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
577+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
574578 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
575579 let gwxDiff = (gWxAmountStart - currUserGwx)
576580 if ((0 > gwxDiff))
579583 let totalCachedGwxKEY = keyTotalCachedGwx()
580584 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
581585 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
582- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
586+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
583587 let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
584588 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
585589 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
596600 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
597601 then throw("permissions denied")
598602 else {
599- let $t02794228044 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
600- let userBoostAvailable = $t02794228044._1
601- let dataState = $t02794228044._2
602- let debug = $t02794228044._3
603+ let $t02775027852 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
604+ let userBoostAvailable = $t02775027852._1
605+ let dataState = $t02775027852._2
606+ let debug = $t02775027852._3
603607 $Tuple2(dataState, [userBoostAvailable])
604608 }
605609
607611
608612 @Callable(i)
609613 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
610- let $t02817628277 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
611- let userBoostAvailable = $t02817628277._1
612- let dataState = $t02817628277._2
613- let debug = $t02817628277._3
614+ let $t02798428085 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
615+ let userBoostAvailable = $t02798428085._1
616+ let dataState = $t02798428085._2
617+ let debug = $t02798428085._3
614618 $Tuple2(nil, [userBoostAvailable, debug])
615619 }
616620
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let SCALE8 = 8
77
88 let MULT8 = 100000000
99
1010 let POOLWEIGHTMULT = MULT8
1111
1212 func strf (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1313
1414
15-func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
15+func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
1616
1717
18-func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
18+func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1919
2020
21-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
21+func iof (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2222
2323
2424 func abs (val) = if ((0 > val))
2525 then -(val)
2626 else val
2727
2828
29-func asAnyList (val) = match val {
29+func aal (val) = match val {
3030 case valAnyLyst: List[Any] =>
3131 valAnyLyst
3232 case _ =>
3333 throw("fail to cast into List[Any]")
3434 }
3535
3636
37-func asInt (val) = match val {
37+func ai (val) = match val {
3838 case valInt: Int =>
3939 valInt
4040 case _ =>
4141 throw("fail to cast into Int")
4242 }
4343
4444
4545 func keyFactoryAddress () = "%s%s__config__factoryAddress"
4646
4747
4848 let IdxFactoryCfgStakingDapp = 1
4949
5050 let IdxFactoryCfgBoostingDapp = 2
5151
5252 let IdxFactoryCfgIdoDapp = 3
5353
5454 let IdxFactoryCfgTeamDapp = 4
5555
5656 let IdxFactoryCfgEmissionDapp = 5
5757
5858 let IdxFactoryCfgRestDapp = 6
5959
6060 let IdxFactoryCfgSlippageDapp = 7
6161
6262 let IdxFactoryCfgDaoDapp = 8
6363
6464 let IdxFactoryCfgMarketingDapp = 9
6565
6666 let IdxFactoryCfgGwxRewardDapp = 10
6767
6868 let IdxFactoryCfgBirdsDapp = 11
6969
7070 func keyFactoryCfg () = "%s__factoryConfig"
7171
7272
7373 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
7474
7575
7676 func keyFactoryLpList () = "%s__lpTokensList"
7777
7878
7979 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
8080
8181
8282 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
8383
8484
8585 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
8686
8787
8888 func readFactoryAddressOrFail () = addressFromStringValue(strf(this, keyFactoryAddress()))
8989
9090
9191 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
9292
9393
9494 func readFactoryCfgOrFail (factory) = split(strf(factory, keyFactoryCfg()), SEP)
9595
9696
9797 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
9898
9999
100100 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
101101
102102
103103 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
104104
105105
106106 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
107107
108108
109109 func keyManagerPublicKey () = "%s__managerPublicKey"
110110
111111
112112 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
113113
114114
115115 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
116116
117117
118118 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
119119
120120
121121 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
122122
123123
124124 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
125125
126126
127127 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
128128
129129
130130 func keyNextPeriod () = "%s__nextPeriod"
131131
132132
133133 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
134134
135135
136136 let IdxCfgAssetId = 1
137137
138138 let IdxCfgMinLockAmount = 2
139139
140140 let IdxCfgMinLockDuration = 3
141141
142142 let IdxCfgMaxLockDuration = 4
143143
144144 let IdxCfgMathContract = 5
145145
146146 func keyConfig () = "%s__config"
147147
148148
149149 func readConfigArrayOrFail () = split(strf(this, keyConfig()), SEP)
150150
151151
152152 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
153153
154154
155155 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
156156
157157
158158 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
159159 case s: String =>
160160 fromBase58String(s)
161161 case _: Unit =>
162162 unit
163163 case _ =>
164164 throw("Match error")
165165 }
166166
167167
168168 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
169169 case s: String =>
170170 fromBase58String(s)
171171 case _: Unit =>
172172 unit
173173 case _ =>
174174 throw("Match error")
175175 }
176176
177177
178178 func mustManager (i) = {
179179 let pd = throw("Permission denied")
180180 match managerPublicKeyOrUnit() {
181181 case pk: ByteVector =>
182182 if ((i.callerPublicKey == pk))
183183 then true
184184 else pd
185185 case _: Unit =>
186186 if ((i.caller == this))
187187 then true
188188 else pd
189189 case _ =>
190190 throw("Match error")
191191 }
192192 }
193193
194194
195195 let IdxLockUserNum = 1
196196
197197 let IdxLockAmount = 2
198198
199199 let IdxLockStart = 3
200200
201201 let IdxLockDuration = 4
202202
203203 let IdxLockParamK = 5
204204
205205 let IdxLockParamB = 6
206206
207207 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
208208
209209
210210 func readLockParamsRecordOrFail (userAddress) = split(strf(this, keyLockParamsRecord(userAddress)), SEP)
211211
212212
213213 func formatLockParamsRecordS (userNum,amount,start,duration,paramK,paramB,lastUpdTimestamp,gwxAmount) = makeString(["%d%d%d%d%d%d%d%d", userNum, amount, start, duration, paramK, paramB, lastUpdTimestamp, gwxAmount], SEP)
214214
215215
216216 func formatLockParamsRecord (userNum,amount,start,duration,paramK,paramB,gwxAmount) = formatLockParamsRecordS(userNum, toString(amount), toString(start), toString(duration), toString(paramK), toString(paramB), toString(lastBlock.timestamp), toString(gwxAmount))
217217
218218
219219 func keyNextUserNum () = "%s__nextUserNum"
220220
221221
222222 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
223223
224224
225225 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
226226
227227
228228 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
229229
230230
231231 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
232232
233233
234234 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
235235
236236
237237 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
238238
239239
240240 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
241241
242242
243243 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
244244
245245
246246 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
247247
248248
249249 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
250250
251251
252252 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
253253
254254
255255 func keyStatsLocksCount () = "%s%s__stats__locksCount"
256256
257257
258258 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
259259
260260
261261 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
262262
263263
264264 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
265265
266266
267267 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
268268
269269
270270 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
271271
272272
273273 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
274274
275275
276276 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
277277
278278
279279 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
280280
281281
282282 let factoryContract = readFactoryAddressOrFail()
283283
284284 let factoryCfg = readFactoryCfgOrFail(factoryContract)
285285
286286 let emissionContract = getEmissionAddressOrFail(factoryCfg)
287287
288288 let stakingContract = getStakingAddressOrFail(factoryCfg)
289289
290290 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
291291
292292 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
293293 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
294294 let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(k), toString(b)], SEP)
295295 StringEntry(historyKEY, historyDATA)
296296 }
297297
298298
299299 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
300300 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
301301 let locksCountKEY = keyStatsLocksCount()
302302 let usersCountKEY = keyStatsUsersCount()
303303 let totalAmountKEY = keyLockParamTotalAmount()
304- let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
305- let locksCount = getIntOrZero(this, locksCountKEY)
306- let usersCount = getIntOrZero(this, usersCountKEY)
307- let totalAmount = getIntOrZero(this, totalAmountKEY)
304+ let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
305+ let locksCount = ioz(this, locksCountKEY)
306+ let usersCount = ioz(this, usersCountKEY)
307+ let totalAmount = ioz(this, totalAmountKEY)
308308 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
309309 }
310310
311311
312312 func calcGwxAmount (kRaw,bRaw,h) = {
313313 let SCALE = 1000
314314 (((kRaw * h) + bRaw) / SCALE)
315315 }
316316
317317
318318 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
319319 let userAmountKEY = keyLockParamUserAmount(userNum)
320320 let startBlockKEY = keyLockParamStartBlock(userNum)
321321 let durationKEY = keyLockParamDuration(userNum)
322322 let kKEY = keyLockParamK(userNum)
323323 let bKEY = keyLockParamB(userNum)
324324 let kByPeriodKEY = keyLockParamByPeriodK(userNum, period)
325325 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
326326 let gwxAmount = calcGwxAmount(k, b, height)
327327 [IntegerEntry(userAmountKEY, amount), IntegerEntry(startBlockKEY, start), IntegerEntry(durationKEY, duration), IntegerEntry(kKEY, k), IntegerEntry(bKEY, b), IntegerEntry(kByPeriodKEY, k), IntegerEntry(bByPeriodKEY, b), StringEntry(keyLockParamsRecord(userAddress), formatLockParamsRecord(userNum, amount, start, duration, k, b, gwxAmount))]
328328 }
329329
330330
331331 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
332332 then throw("only one payment is allowed")
333333 else if ((size(i.payments) == 0))
334334 then 0
335335 else {
336336 let pmt = i.payments[0]
337337 if ((value(pmt.assetId) != expectedAssetId))
338338 then throw("invalid asset id in payment")
339339 else pmt.amount
340340 }
341341
342342
343343 func calcUserGwxAmountAtHeight (userAddress,targetHeight) = {
344344 let EMPTY = "empty"
345345 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
346346 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
347347 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
348348 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
349349 let gwxAmountCalc = calcGwxAmount(k, b, targetHeight)
350350 let gwxAmount = if ((0 > gwxAmountCalc))
351351 then 0
352352 else gwxAmountCalc
353353 gwxAmount
354354 }
355355
356356
357357 func calcCurrentGwxAmount (userAddress) = calcUserGwxAmountAtHeight(userAddress, height)
358358
359359
360360 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
361361 let EMPTY = "EMPTY"
362362 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
363363 if ((userRecordOrEmpty == EMPTY))
364364 then $Tuple3(0, nil, "userRecord::is::empty")
365365 else {
366366 let userRecordArray = split(userRecordOrEmpty, SEP)
367367 let userNumStr = userRecordArray[IdxLockUserNum]
368368 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
369369 let EMPTYSTR = "empty"
370- let $t01317413742 = if ((lpAssetIdStr != EMPTYSTR))
370+ let $t01316713735 = if ((lpAssetIdStr != EMPTYSTR))
371371 then {
372372 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373373 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
374374 let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
375375 $Tuple2(pw0, pw1)
376376 }
377377 else if (readOnly)
378378 then $Tuple2(0, 0)
379379 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
380- let poolWeight0 = $t01317413742._1
381- let poolWeight1 = $t01317413742._2
382- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
383- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
384- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
380+ let poolWeight0 = $t01316713735._1
381+ let poolWeight1 = $t01316713735._2
382+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
383+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
384+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
385385 let h = if ((height > emissionEnd))
386386 then emissionEnd
387387 else height
388388 let dh = max([(h - emissionStart), 0])
389389 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
390390 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
391- let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
391+ let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
392392 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
393393 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
394394 let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
395395 let uLastH = (h - udh)
396396 let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
397397 let udh1 = ((h - uLastH) - udh0)
398398 if (if (if ((0 > uLastH))
399399 then true
400400 else (0 > udh1))
401401 then true
402402 else (abs(((udh0 + udh1) - udh)) >= 1))
403403 then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
404404 else if ((0 > userBoostEmissionIntegral))
405405 then throw("wrong calculations")
406406 else {
407407 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
408408 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
409- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
410- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
409+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
410+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
411411 let totalCachedGwxKEY = keyTotalCachedGwx()
412412 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
413413 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
414414 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
415- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
416- let userBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral, udh0, udh)
417- let userBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral, udh1, udh)
415+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
416+ let userBoostEmissionIntegral0 = if ((udh == 0))
417+ then 0
418+ else fraction(userBoostEmissionIntegral, udh0, udh)
419+ let userBoostEmissionIntegral1 = if ((udh == 0))
420+ then 0
421+ else fraction(userBoostEmissionIntegral, udh1, udh)
418422 let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
419423 let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
420424 let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
421425 then 0
422426 else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
423427 let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
424428 then 0
425429 else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
426430 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
427431 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
428- let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
432+ let userBoostClaimed = ioz(this, userBoostClaimedKEY)
429433 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
430434 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
431435 let debug = makeString([("userBoostEmissionLastIntegral=" + toString(userBoostEmissionLastIntegral)), ("userBoostEmissionIntegral=" + toString(userBoostEmissionIntegral)), ("userMaxBoostInt=" + toString(userMaxBoostInt)), ("totalMaxBoostInt=" + toString(totalMaxBoostInt)), ("userBoostAvaliableToClaimTotal=" + toString(userBoostAvaliableToClaimTotal)), ("userBoostAvaliableToClaimTotalNew=" + toString(userBoostAvaliableToClaimTotalNew)), ("userBoostClaimed=" + toString(userBoostClaimed)), ("userBoostAvailable=" + toString(userBoostAvailable)), ("userBoostEmissionIntegral0=" + toString(userBoostEmissionIntegral0)), ("userBoostEmissionIntegral1=" + toString(userBoostEmissionIntegral1)), ("poolUserBoostEmissionIntegral0=" + toString(poolUserBoostEmissionIntegral0)), ("poolUserBoostEmissionIntegral1=" + toString(poolUserBoostEmissionIntegral1)), ("poolWeight0=" + toString(poolWeight0)), ("poolWeight1=" + toString(poolWeight1)), ("h=" + toString(h)), ("udh=" + toString(udh)), ("uLastH=" + toString(uLastH)), ("udh0=" + toString(udh0)), ("udh1=" + toString(udh1)), ("userCurrGwx=" + toString(userCurrGwx)), ("totalCachedGwx=" + toString(totalCachedGwx))], "::")
432436 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
433437 }
434438 }
435439 }
436440
437441
438442 @Callable(i)
439443 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
440444 let checkCaller = mustManager(i)
441445 if ((checkCaller == checkCaller))
442446 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
443447 else throw("Strict value is not equal to itself.")
444448 }
445449
446450
447451
448452 @Callable(i)
449453 func lock (duration) = {
450454 let cfgArray = readConfigArrayOrFail()
451455 let assetIdStr = cfgArray[IdxCfgAssetId]
452456 let assetId = fromBase58String(assetIdStr)
453457 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
454458 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
455459 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
456460 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
457461 if ((size(i.payments) != 1))
458462 then throw("invalid payment - exact one payment must be attached")
459463 else {
460464 let pmt = i.payments[0]
461465 let pmtAmount = pmt.amount
462466 if ((assetId != value(pmt.assetId)))
463467 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
464468 else {
465469 let nextUserNumKEY = keyNextUserNum()
466470 let userAddressStr = toString(i.caller)
467471 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
468472 let userNumStr = if (userIsExisting)
469473 then value(getString(keyUser2NumMapping(userAddressStr)))
470- else toString(getIntOrFail(this, nextUserNumKEY))
474+ else toString(iof(this, nextUserNumKEY))
471475 let userNum = parseIntValue(userNumStr)
472476 let lockStart = height
473477 let startBlockKEY = keyLockParamStartBlock(userNumStr)
474478 let durationKEY = keyLockParamDuration(userNumStr)
475479 let userAmountKEY = keyLockParamUserAmount(userNumStr)
476480 if ((minLockAmount > pmtAmount))
477481 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
478482 else if ((minLockDuration > duration))
479483 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
480484 else if ((duration > maxLockDuration))
481485 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
482486 else if (if (userIsExisting)
483- then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
487+ then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
484488 else false)
485489 then throw("there is an active lock - consider to use increaseLock")
486- else if ((getIntOrZero(this, userAmountKEY) > 0))
490+ else if ((ioz(this, userAmountKEY) > 0))
487491 then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
488492 else {
489493 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
490494 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
491- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
492- let k = asInt(gWxParamsResultList[0])
493- let b = asInt(gWxParamsResultList[1])
494- let period = toString(asInt(gWxParamsResultList[2]))
495- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
496- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
497- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
495+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
496+ let k = ai(gWxParamsResultList[0])
497+ let b = ai(gWxParamsResultList[1])
498+ let period = toString(ai(gWxParamsResultList[2]))
499+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
500+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
501+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
498502 let h = if ((height > emissionEnd))
499503 then emissionEnd
500504 else height
501505 let dh = max([(h - emissionStart), 0])
502506 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
503507 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
504508 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
505509 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
506510 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
507- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
511+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
508512 let totalCachedGwxKEY = keyTotalCachedGwx()
509513 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
510514 let arr = if (userIsExisting)
511515 then nil
512516 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
513517 ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
514518 then 0
515519 else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
516520 }
517521 }
518522 }
519523 }
520524
521525
522526
523527 @Callable(i)
524528 func increaseLock (deltaDuration) = {
525529 let cfgArray = readConfigArrayOrFail()
526530 let assetIdStr = cfgArray[IdxCfgAssetId]
527531 let assetId = fromBase58String(assetIdStr)
528532 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
529533 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
530534 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
531535 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
532536 let userAddressStr = toString(i.caller)
533537 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
534538 let userNumStr = userRecordArray[IdxLockUserNum]
535539 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
536540 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
537541 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
538542 let lockEnd = (lockStart + lockDuration)
539543 let remainingDuration = max([(lockEnd - height), 0])
540544 let userAmountNew = (userAmount + pmtAmount)
541545 let lockDurationNew = (remainingDuration + deltaDuration)
542546 if ((0 > deltaDuration))
543547 then throw("duration is less then zero")
544548 else if ((minLockDuration > lockDurationNew))
545549 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
546550 else if ((lockDurationNew > maxLockDuration))
547551 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
548552 else {
549553 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
550554 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
551555 let lockStartNew = height
552- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
553- let k = asInt(gWxParamsResultList[0])
554- let b = asInt(gWxParamsResultList[1])
555- let period = toString(asInt(gWxParamsResultList[2]))
556- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
557- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
558- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
556+ let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
557+ let k = ai(gWxParamsResultList[0])
558+ let b = ai(gWxParamsResultList[1])
559+ let period = toString(ai(gWxParamsResultList[2]))
560+ let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
561+ let emissionStart = iof(emissionContract, keyEmissionStartBlock())
562+ let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
559563 let h = if ((height > emissionEnd))
560564 then emissionEnd
561565 else height
562566 let dh = max([(h - emissionStart), 0])
563567 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
564- let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
568+ let userBoostEmissionLastIntegral = ioz(this, userBoostEmissionLastIntegralKEY)
565569 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
566570 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
567571 if ((0 > userBoostEmissionIntegral))
568572 then throw("wrong calculations")
569573 else {
570574 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
571575 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
572- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
573- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
576+ let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
577+ let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
574578 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
575579 let gwxDiff = (gWxAmountStart - currUserGwx)
576580 if ((0 > gwxDiff))
577581 then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
578582 else {
579583 let totalCachedGwxKEY = keyTotalCachedGwx()
580584 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
581585 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
582- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
586+ let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
583587 let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
584588 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
585589 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
586590 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
587591 (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gwxDiff))])
588592 }
589593 }
590594 }
591595 }
592596
593597
594598
595599 @Callable(i)
596600 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
597601 then throw("permissions denied")
598602 else {
599- let $t02794228044 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
600- let userBoostAvailable = $t02794228044._1
601- let dataState = $t02794228044._2
602- let debug = $t02794228044._3
603+ let $t02775027852 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
604+ let userBoostAvailable = $t02775027852._1
605+ let dataState = $t02775027852._2
606+ let debug = $t02775027852._3
603607 $Tuple2(dataState, [userBoostAvailable])
604608 }
605609
606610
607611
608612 @Callable(i)
609613 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
610- let $t02817628277 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
611- let userBoostAvailable = $t02817628277._1
612- let dataState = $t02817628277._2
613- let debug = $t02817628277._3
614+ let $t02798428085 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
615+ let userBoostAvailable = $t02798428085._1
616+ let dataState = $t02798428085._2
617+ let debug = $t02798428085._3
614618 $Tuple2(nil, [userBoostAvailable, debug])
615619 }
616620
617621
618622
619623 @Callable(i)
620624 func unlock (userAddress) = {
621625 let userRecordArray = readLockParamsRecordOrFail(userAddress)
622626 let userNumStr = userRecordArray[IdxLockUserNum]
623627 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
624628 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
625629 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
626630 let lockEnd = (lockStart + lockDuration)
627631 let cfgArray = readConfigArrayOrFail()
628632 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
629633 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
630634 if ((lockEnd >= height))
631635 then throw((("wait " + toString(lockEnd)) + " to unlock"))
632636 else if ((0 >= userAmount))
633637 then throw("nothing to unlock")
634638 else {
635639 let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
636640 (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
637641 }
638642 }
639643
640644
641645
642646 @Callable(i)
643647 func gwxUserInfoREADONLY (userAddress) = {
644648 let gwxAmount = calcCurrentGwxAmount(userAddress)
645649 $Tuple2(nil, [gwxAmount])
646650 }
647651
648652
649653
650654 @Callable(i)
651655 func getUserGwxAmountAtHeightREADONLY (userAddress,targetHeight) = {
652656 let gwxAmount = calcUserGwxAmountAtHeight(userAddress, targetHeight)
653657 $Tuple2(nil, gwxAmount)
654658 }
655659
656660
657661
658662 @Callable(i)
659663 func setManager (pendingManagerPublicKey) = {
660664 let checkCaller = mustManager(i)
661665 if ((checkCaller == checkCaller))
662666 then {
663667 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
664668 if ((checkManagerPublicKey == checkManagerPublicKey))
665669 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
666670 else throw("Strict value is not equal to itself.")
667671 }
668672 else throw("Strict value is not equal to itself.")
669673 }
670674
671675
672676
673677 @Callable(i)
674678 func confirmManager () = {
675679 let pm = pendingManagerPublicKeyOrUnit()
676680 let hasPM = if (isDefined(pm))
677681 then true
678682 else throw("No pending manager")
679683 if ((hasPM == hasPM))
680684 then {
681685 let checkPM = if ((i.callerPublicKey == value(pm)))
682686 then true
683687 else throw("You are not pending manager")
684688 if ((checkPM == checkPM))
685689 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
686690 else throw("Strict value is not equal to itself.")
687691 }
688692 else throw("Strict value is not equal to itself.")
689693 }
690694
691695
692696 @Verifier(tx)
693697 func verify () = {
694698 let targetPublicKey = match managerPublicKeyOrUnit() {
695699 case pk: ByteVector =>
696700 pk
697701 case _: Unit =>
698702 tx.senderPublicKey
699703 case _ =>
700704 throw("Match error")
701705 }
702706 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
703707 }
704708

github/deemru/w8io/026f985 
99.82 ms