tx · HVE1RwwpGWbefxUcsi5gcN6ch3y2rsC7Vy6Ed3cSVdd4

3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS:  -0.02200000 Waves

2023.11.29 11:05 [2864427] smart account 3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS > SELF 0.00000000 Waves

{ "type": 13, "id": "HVE1RwwpGWbefxUcsi5gcN6ch3y2rsC7Vy6Ed3cSVdd4", "fee": 2200000, "feeAssetId": null, "timestamp": 1701245127090, "version": 1, "sender": "3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS", "senderPublicKey": "8h7G4haeVwXKNHXNHsWkC1miUp5CQtk3WmpBKazQPxRh", "proofs": [ "wR7kdonEcLDtDhtobG3G1KgZXWUqdPEktdguKtiUygHnQAgEFmexArkM2h3KJEFMb7sUdsdwRYmx65vekW5hTx5" ], "script": "base64:BgI0CAISAwoBARIDCgEBEgASAwoBCBIDCgEBEgMKAQgSAwoBCBIECgIYERIDCgEIEgASAwoBCD0ADGNvbnRyYWN0RmlsZQIRbDJtcF9zdGFraW5nLnJpZGUAA1NFUAICX18ABnNjYWxlOACAwtcvAAdzY2FsZTE4AICAkLu61q3wDQANc2NhbGUxOEJpZ0ludAkAtgIBBQdzY2FsZTE4ABJBRERSRVNTX0JZVEVTX1NJWkUAGgANQkxPQ0tTX0lOX0RBWQCgCwEIdGhyb3dFcnIBA21zZwkAAgEJAKwCAgkArAICBQxjb250cmFjdEZpbGUCAjogBQNtc2cACmtleUFzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCAgdhc3NldElkBQNuaWwFA1NFUAATa2V5RW1pc3Npb25QZXJCbG9jawkAuQkCCQDMCAICAiVzCQDMCAICEGVtaXNzaW9uUGVyQmxvY2sFA25pbAUDU0VQABlrZXlFbWlzc2lvblBlcmlvZEluQmxvY2tzCQC5CQIJAMwIAgICJXMJAMwIAgIWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwUDbmlsBQNTRVAADWtleVN0YXJ0QmxvY2sJALkJAgkAzAgCAgIlcwkAzAgCAgpzdGFydEJsb2NrBQNuaWwFA1NFUAAQa2V5VG90YWxMcEFtb3VudAkAuQkCCQDMCAICAiVzCQDMCAICDXRvdGFsTHBBbW91bnQFA25pbAUDU0VQABNrZXlUb3RhbEFzc2V0QW1vdW50CQC5CQIJAMwIAgICJXMJAMwIAgIQdG90YWxBc3NldEFtb3VudAUDbmlsBQNTRVAAFmtleVRvdGFsTG9ja2VkTHBBbW91bnQJALkJAgkAzAgCAgIlcwkAzAgCAhN0b3RhbExvY2tlZExwQW1vdW50BQNuaWwFA1NFUAEPa2V5VXNlckxwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIMdXNlckxwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEVa2V5VXNlckxvY2tlZExwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgISdXNlckxvY2tlZExwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAETa2V5VXNlclN0YWtpbmdOb2RlcwELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICEHVzZXJTdGFraW5nTm9kZXMJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARlrZXlVc2VyU3Rha2luZ05vZGVzU2hhcmVzAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIWdXNlclN0YWtpbmdOb2Rlc1NoYXJlcwkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGmtleVVzZXJUb3RhbEFzc2V0V2l0aGRyYXduAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgITdG90YWxBc3NldFdpdGhkcmF3bgkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIQdG90YWxBc3NldFN0YWtlZAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABCmtleUhpc3RvcnkDBHR5cGULdXNlckFkZHJlc3MEdHhJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJANgEAQUEdHhJZAUDbmlsBQNTRVABDWZvcm1hdEhpc3RvcnkEC3RvdGFsUHJvZml0BXByaWNlEHRvdGFsQXNzZXRBbW91bnQNdG90YWxMcEFtb3VudAkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQULdG90YWxQcm9maXQJAMwIAgkApgMBBQVwcmljZQkAzAgCCQCkAwEFEHRvdGFsQXNzZXRBbW91bnQJAMwIAgkApAMBBQ10b3RhbExwQW1vdW50BQNuaWwFA1NFUAANdG90YWxMcEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRBrZXlUb3RhbExwQW1vdW50AAAAEHRvdGFsQXNzZXRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUTa2V5VG90YWxBc3NldEFtb3VudAAAABN0b3RhbExvY2tlZExwQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFFmtleVRvdGFsTG9ja2VkTHBBbW91bnQAAAANYXNzZXRJZFN0cmluZwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQprZXlBc3NldElkAgVXQVZFUwAMYXNzZXRJZEJ5dGVzAwkAAAIFDWFzc2V0SWRTdHJpbmcCBVdBVkVTBQR1bml0CQDZBAEFDWFzc2V0SWRTdHJpbmcAFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUZa2V5RW1pc3Npb25QZXJpb2RJbkJsb2NrcwUNQkxPQ0tTX0lOX0RBWQARZW1pc3Npb25QZXJQZXJpb2QJAGgCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFE2tleUVtaXNzaW9uUGVyQmxvY2sAAAUWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwAPQURNSU5fTElTVF9TSVpFAAUABlFVT1JVTQADABFUWElEX0JZVEVTX0xFTkdUSAAgARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBHR4SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIJYWxsb3dUeElkCQDMCAIFBHR4SWQFA25pbAUDU0VQARBrZXlGdWxsQWRtaW5Wb3RlAgZwcmVmaXgMYWRtaW5BZGRyZXNzCQC5CQIJAMwIAgUGcHJlZml4CQDMCAIFDGFkbWluQWRkcmVzcwUDbmlsBQNTRVABE2tleUFkbWluQWRkcmVzc0xpc3QACQC5CQIJAMwIAgICJXMJAMwIAgIQYWRtaW5BZGRyZXNzTGlzdAUDbmlsBQNTRVABDmtleUFsbG93ZWRUeElkAAkAuQkCCQDMCAICAiVzCQDMCAICBHR4SWQFA25pbAUDU0VQAQxnZXRBZG1pblZvdGUCBnByZWZpeAVhZG1pbgQHdm90ZUtleQkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFBWFkbWluCQELdmFsdWVPckVsc2UCCQCfCAEFB3ZvdGVLZXkAAAENZ2V0QWRtaW5zTGlzdAAEByRtYXRjaDAJAJ0IAgUEdGhpcwkBE2tleUFkbWluQWRkcmVzc0xpc3QAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkAtQkCBQFzBQNTRVAFA25pbAENaXNJbkFkbWluTGlzdAEHYWRkcmVzcwkBD2NvbnRhaW5zRWxlbWVudAIJAQ1nZXRBZG1pbnNMaXN0AAUHYWRkcmVzcwESZ2VuVm90ZXNLZXlzSGVscGVyAgFhDGFkbWluQWRkcmVzcwQLJHQwMzU1NTM1NzkFAWEEBnJlc3VsdAgFCyR0MDM1NTUzNTc5Al8xBAZwcmVmaXgIBQskdDAzNTU1MzU3OQJfMgkAlAoCCQDNCAIFBnJlc3VsdAkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFDGFkbWluQWRkcmVzcwUGcHJlZml4AQxnZW5Wb3Rlc0tleXMBCWtleVByZWZpeAQJYWRtaW5MaXN0CQETa2V5QWRtaW5BZGRyZXNzTGlzdAAECyR0MDM3MjYzODEwCgACJGwJAQ1nZXRBZG1pbnNMaXN0AAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQlrZXlQcmVmaXgKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEmdlblZvdGVzS2V5c0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUEBnJlc3VsdAgFCyR0MDM3MjYzODEwAl8xBAZwcmVmaXgIBQskdDAzNzI2MzgxMAJfMgUGcmVzdWx0ARBjb3VudFZvdGVzSGVscGVyAgZyZXN1bHQHdm90ZUtleQkAZAIFBnJlc3VsdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd2b3RlS2V5AAABCmNvdW50Vm90ZXMBBnByZWZpeAQFdm90ZXMJAQxnZW5Wb3Rlc0tleXMBBQZwcmVmaXgKAAIkbAUFdm90ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGNvdW50Vm90ZXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFARBjbGVhclZvdGVzSGVscGVyAgZyZXN1bHQDa2V5CQDNCAIFBnJlc3VsdAkBC0RlbGV0ZUVudHJ5AQUDa2V5ARNnZXRDbGVhclZvdGVFbnRyaWVzAQZwcmVmaXgEBXZvdGVzCQEMZ2VuVm90ZXNLZXlzAQUGcHJlZml4CgACJGwFBXZvdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBjbGVhclZvdGVzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQEMdm90ZUlOVEVSTkFMBBNjYWxsZXJBZGRyZXNzU3RyaW5nCWtleVByZWZpeAhtaW5Wb3Rlcwp2b3RlUmVzdWx0BAd2b3RlS2V5CQEQa2V5RnVsbEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQQYWRtaW5DdXJyZW50Vm90ZQkBDGdldEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQDZXJyAwkBASEBCQENaXNJbkFkbWluTGlzdAEFE2NhbGxlckFkZHJlc3NTdHJpbmcJAQh0aHJvd0VycgEJAKwCAgkArAICAglBZGRyZXNzOiAFE2NhbGxlckFkZHJlc3NTdHJpbmcCEiBub3QgaW4gQWRtaW4gbGlzdAMJAAACBRBhZG1pbkN1cnJlbnRWb3RlAAEJAQh0aHJvd0VycgEJAKwCAgUHdm90ZUtleQISIHlvdSBhbHJlYWR5IHZvdGVkBQR1bml0AwkAAAIFA2VycgUDZXJyBAV2b3RlcwkBCmNvdW50Vm90ZXMBBQlrZXlQcmVmaXgDCQBnAgkAZAIFBXZvdGVzAAEFCG1pblZvdGVzBBBjbGVhclZvdGVFbnRyaWVzCQETZ2V0Q2xlYXJWb3RlRW50cmllcwEFCWtleVByZWZpeAkAzggCBRBjbGVhclZvdGVFbnRyaWVzBQp2b3RlUmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd2b3RlS2V5AAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEZc3RyaW5nTGlzdFRvSW50TGlzdEhlbHBlcgIDYWNjBXZhbHVlCQDNCAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQV2YWx1ZQEYY2FsY1RvdGFsUHJvZml0Rm9ySGVpZ2h0AQFoBApzdGFydEJsb2NrCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAQLc3RhcnRQZXJpb2QJAGsDBQpzdGFydEJsb2NrAAEFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MEDmVsYXBzZWRQZXJpb2RzCQBlAgkAaQIFAWgFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MFC3N0YXJ0UGVyaW9kCQCWAwEJAMwIAgAACQDMCAIJAGgCBRFlbWlzc2lvblBlclBlcmlvZAUOZWxhcHNlZFBlcmlvZHMFA25pbAEPY2FsY1RvdGFsUHJvZml0AAkBGGNhbGNUb3RhbFByb2ZpdEZvckhlaWdodAEFBmhlaWdodAErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQAEGnRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0CQBkAgUQdG90YWxBc3NldEFtb3VudAkBD2NhbGNUb3RhbFByb2ZpdAAEC3RvdGFsQW1vdW50BAckbWF0Y2gwBQxhc3NldElkQnl0ZXMDCQABAgUHJG1hdGNoMAIEVW5pdAQBdQUHJG1hdGNoMAkAlwMBCQDMCAIFGnRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0CQDMCAIICQDvBwEFBHRoaXMJYXZhaWxhYmxlBQNuaWwDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkAlwMBCQDMCAIFGnRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0CQDMCAIJAPAHAgUEdGhpcwUBYgUDbmlsCQACAQILTWF0Y2ggZXJyb3IDCQAAAgUNdG90YWxMcEFtb3VudAAAAAAFC3RvdGFsQW1vdW50AQ9nZXRDdXJyZW50UHJpY2UAAwkBAiE9AgUNdG90YWxMcEFtb3VudAAACQC8AgMJALYCAQkBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUABQ1zY2FsZTE4QmlnSW50CQC2AgEFDXRvdGFsTHBBbW91bnQFDXNjYWxlMThCaWdJbnQBF2dldFVzZXJTdGFraW5nTm9kZXNEYXRhAQt1c2VyQWRkcmVzcwQIbm9kZXNSYXcJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBE2tleVVzZXJTdGFraW5nTm9kZXMBBQt1c2VyQWRkcmVzcwIABAlzaGFyZXNSYXcJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBGWtleVVzZXJTdGFraW5nTm9kZXNTaGFyZXMBBQt1c2VyQWRkcmVzcwIABAlub2Rlc0xpc3QJALUJAgUIbm9kZXNSYXcFA1NFUAQQc2hhcmVzU3RyaW5nTGlzdAkAtQkCBQlzaGFyZXNSYXcFA1NFUAQKc2hhcmVzTGlzdAoAAiRsBRBzaGFyZXNTdHJpbmdMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARlzdHJpbmdMaXN0VG9JbnRMaXN0SGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIFCW5vZGVzTGlzdAUKc2hhcmVzTGlzdAEPY2FsY0Fzc2V0RnJvbUxwAQhscEFtb3VudAkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALwCAwkAtgIBBQhscEFtb3VudAkBD2dldEN1cnJlbnRQcmljZQAFDXNjYWxlMThCaWdJbnQFA25pbAEPY2FsY0xwRnJvbUFzc2V0AQthc3NldEFtb3VudAkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALwCAwkAtgIBBQthc3NldEFtb3VudAUNc2NhbGUxOEJpZ0ludAkBD2dldEN1cnJlbnRQcmljZQAFA25pbAEPZ2V0VXNlckxwQW1vdW50AQt1c2VyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEPa2V5VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MAAAEVZ2V0VXNlckxvY2tlZExwQW1vdW50AQt1c2VyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEVa2V5VXNlckxvY2tlZExwQW1vdW50AQULdXNlckFkZHJlc3MAAAEgZ2V0VXNlckF2YWlsYWJsZUFzc2V0c1RvV2l0aGRyYXcBC3VzZXJBZGRyZXNzBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwkBD2NhbGNBc3NldEZyb21McAEFDHVzZXJMcEFtb3VudAEPZ2V0U3Rha2VBY3Rpb25zAgFpC3VzZXJBZGRyZXNzBAZjaGVja3MJAMwIAgMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEGCQEIdGhyb3dFcnIBAhhzaG91bGQgaW5jbHVkZSAxIHBheW1lbnQJAMwIAgMJAAACCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFDGFzc2V0SWRCeXRlcwYJAQh0aHJvd0VycgEJAKwCAgIVcGF5bWVudCBzaG91bGQgYmUgaW4gBQ1hc3NldElkU3RyaW5nCQDMCAIDCQBmAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAYCJ3BheW1lbnQgYW1vdW50IHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMAkAzAgCAwkAAAIJAMgBAQkA2QQBBQt1c2VyQWRkcmVzcwUSQUREUkVTU19CWVRFU19TSVpFBgkBCHRocm93RXJyAQIZdXNlciBhZGRyZXNzIGlzIG5vdCB2YWxpZAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA1wYXltZW50QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQPcGF5bWVudExwQW1vdW50CQCgAwEJALwCAwkAtgIBBQ1wYXltZW50QW1vdW50BQ1zY2FsZTE4QmlnSW50CQEPZ2V0Q3VycmVudFByaWNlAAQMdXNlckxwQW1vdW50CQEPZ2V0VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MEFXVzZXJUb3RhbFN0YWtlZEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEXa2V5VXNlclRvdGFsQXNzZXRTdGFrZWQBBQt1c2VyQWRkcmVzcwAABBBuZXdUb3RhbExwQW1vdW50CQBkAgUNdG90YWxMcEFtb3VudAUPcGF5bWVudExwQW1vdW50BBNuZXdUb3RhbEFzc2V0QW1vdW50CQCgAwEJALwCAwkAtgIBBRBuZXdUb3RhbExwQW1vdW50CQEPZ2V0Q3VycmVudFByaWNlAAUNc2NhbGUxOEJpZ0ludAQPbmV3VXNlckxwQW1vdW50CQBkAgUMdXNlckxwQW1vdW50BQ9wYXltZW50THBBbW91bnQEGG5ld1VzZXJUb3RhbFN0YWtlZEFtb3VudAkAZAIFFXVzZXJUb3RhbFN0YWtlZEFtb3VudAUNcGF5bWVudEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEKa2V5SGlzdG9yeQMCBXN0YWtlBQt1c2VyQWRkcmVzcwgFAWkNdHJhbnNhY3Rpb25JZAkBDWZvcm1hdEhpc3RvcnkECQEPY2FsY1RvdGFsUHJvZml0AAkBD2dldEN1cnJlbnRQcmljZQAFDXRvdGFsTHBBbW91bnQFEHRvdGFsQXNzZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEGtleVRvdGFsTHBBbW91bnQFEG5ld1RvdGFsTHBBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tleVRvdGFsQXNzZXRBbW91bnQFE25ld1RvdGFsQXNzZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwUPbmV3VXNlckxwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEXa2V5VXNlclRvdGFsQXNzZXRTdGFrZWQBBQt1c2VyQWRkcmVzcwUYbmV3VXNlclRvdGFsU3Rha2VkQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1rZXlTdGFydEJsb2NrBQZoZWlnaHQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgESZ2V0V2l0aGRyYXdBY3Rpb25zAgFpFWxwQXNzZXRXaXRoZHJhd0Ftb3VudAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwQFY2hlY2sJAMwIAgMJAGYCBRVscEFzc2V0V2l0aGRyYXdBbW91bnQAAAYJAQh0aHJvd0VycgECH0xQIGFtb3VudCBzaG91bGQgYmUgbW9yZSB0aGFuIDAJAMwIAgMJAGcCBQx1c2VyTHBBbW91bnQFFWxwQXNzZXRXaXRoZHJhd0Ftb3VudAYJAQh0aHJvd0VycgEJAKwCAgkArAICAihjYW5ub3Qgd2l0aGRyYXcgbW9yZSB0aGFuIGF2YWlsYWJsZSBMUCAoCQCkAwEFDHVzZXJMcEFtb3VudAIBKQUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawQPbmV3VXNlckxwQW1vdW50CQBlAgUMdXNlckxwQW1vdW50BRVscEFzc2V0V2l0aGRyYXdBbW91bnQEE3dpdGhkcmF3QXNzZXRBbW91bnQJAKADAQkAvAIDCQC2AgEFFWxwQXNzZXRXaXRoZHJhd0Ftb3VudAkBD2dldEN1cnJlbnRQcmljZQAFDXNjYWxlMThCaWdJbnQEEG5ld1RvdGFsTHBBbW91bnQJAGUCBQ10b3RhbExwQW1vdW50BRVscEFzc2V0V2l0aGRyYXdBbW91bnQEE25ld1RvdGFsQXNzZXRBbW91bnQJAKADAQkAvAIDCQC2AgEFEG5ld1RvdGFsTHBBbW91bnQJAQ9nZXRDdXJyZW50UHJpY2UABQ1zY2FsZTE4QmlnSW50BBd1c2VyVG90YWxBc3NldFdpdGhkcmF3bgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEaa2V5VXNlclRvdGFsQXNzZXRXaXRoZHJhd24BBQt1c2VyQWRkcmVzcwAABBpuZXdVc2VyVG90YWxBc3NldFdpdGhkcmF3bgkAZAIFF3VzZXJUb3RhbEFzc2V0V2l0aGRyYXduBRN3aXRoZHJhd0Fzc2V0QW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQprZXlIaXN0b3J5AwIId2l0aGRyYXcFC3VzZXJBZGRyZXNzCAUBaQ10cmFuc2FjdGlvbklkCQENZm9ybWF0SGlzdG9yeQQJAQ9jYWxjVG90YWxQcm9maXQACQEPZ2V0Q3VycmVudFByaWNlAAUNdG90YWxMcEFtb3VudAUQdG90YWxBc3NldEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa2V5VG90YWxMcEFtb3VudAUQbmV3VG90YWxMcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa2V5VG90YWxBc3NldEFtb3VudAUTbmV3VG90YWxBc3NldEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD2tleVVzZXJMcEFtb3VudAEFC3VzZXJBZGRyZXNzBQ9uZXdVc2VyTHBBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJARprZXlVc2VyVG90YWxBc3NldFdpdGhkcmF3bgEFC3VzZXJBZGRyZXNzBRpuZXdVc2VyVG90YWxBc3NldFdpdGhkcmF3bgkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa2V5U3RhcnRCbG9jawUGaGVpZ2h0CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUTd2l0aGRyYXdBc3NldEFtb3VudAUMYXNzZXRJZEJ5dGVzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BGGdldFNldFN0YWtpbmdOb2RlQWN0aW9ucwMLdXNlckFkZHJlc3MLbm9kZUFkZHJlc3MJbm9kZVNoYXJlBAVjaGVjawkAzAgCAwkAAAIJAMgBAQkA2QQBBQt1c2VyQWRkcmVzcwUSQUREUkVTU19CWVRFU19TSVpFBgkBCHRocm93RXJyAQIZdXNlciBhZGRyZXNzIGlzIG5vdCB2YWxpZAkAzAgCAwkAAAIJAMgBAQkA2QQBBQtub2RlQWRkcmVzcwUSQUREUkVTU19CWVRFU19TSVpFBgkBCHRocm93RXJyAQIZbm9kZSBhZGRyZXNzIGlzIG5vdCB2YWxpZAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5VXNlclN0YWtpbmdOb2RlcwEFC3VzZXJBZGRyZXNzBQtub2RlQWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEZa2V5VXNlclN0YWtpbmdOb2Rlc1NoYXJlcwEFC3VzZXJBZGRyZXNzCQCkAwEFCW5vZGVTaGFyZQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCwFpARNzZXRFbWlzc2lvblBlckJsb2NrARBlbWlzc2lvblBlckJsb2NrBAVjaGVjawkAzAgCAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYJAQh0aHJvd0VycgECEXBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrZXlUb3RhbEFzc2V0QW1vdW50CQErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQAJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa2V5RW1pc3Npb25QZXJCbG9jawkAlgMBCQDMCAIAAAkAzAgCBRBlbWlzc2lvblBlckJsb2NrBQNuaWwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARlzZXRFbWlzc2lvblBlcmlvZEluQmxvY2tzAQFwBAVjaGVjawkAzAgCAwkAZgIFAXAAAAYJAQh0aHJvd0VycgECKGVtaXNzaW9uIHBlcmlvZCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAAACCAUBaQZjYWxsZXIFBHRoaXMGCQEIdGhyb3dFcnIBAhFwZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa2V5VG90YWxBc3NldEFtb3VudAkBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1rZXlTdGFydEJsb2NrBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFGWtleUVtaXNzaW9uUGVyaW9kSW5CbG9ja3MFAXAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVzdGFrZQAEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgkBD2dldFN0YWtlQWN0aW9ucwIFAWkFC3VzZXJBZGRyZXNzAWkBCHN0YWtlRm9yAQt1c2VyQWRkcmVzcwkBD2dldFN0YWtlQWN0aW9ucwIFAWkFC3VzZXJBZGRyZXNzAWkBCHdpdGhkcmF3ARN3aXRoZHJhd0Fzc2V0QW1vdW50BAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDHVzZXJMcEFtb3VudAkBD2dldFVzZXJMcEFtb3VudAEFC3VzZXJBZGRyZXNzBBJscEFtb3VudFRvV2l0aGRyYXcJAKADAQkAvAIDCQC2AgEFE3dpdGhkcmF3QXNzZXRBbW91bnQFDXNjYWxlMThCaWdJbnQJAQ9nZXRDdXJyZW50UHJpY2UABBx1c2VyQXZhaWxhYmxlQXNzZXRUb1dpdGhkcmF3CQEgZ2V0VXNlckF2YWlsYWJsZUFzc2V0c1RvV2l0aGRyYXcBBQt1c2VyQWRkcmVzcwQWbWluV2l0aGRyYXdBc3NldEFtb3VudAkAoAMBCQC9AgQJAQ9nZXRDdXJyZW50UHJpY2UACQC2AgEAAQUNc2NhbGUxOEJpZ0ludAUHQ0VJTElORwQFY2hlY2sJAMwIAgMJAGYCBRN3aXRoZHJhd0Fzc2V0QW1vdW50AAAGCQEIdGhyb3dFcnIBAiV3aXRoZHJhdyBhbW91bnQgc2hvdWxkIGJlIG1vcmUgdGhhbiAwCQDMCAIDCQBnAgUcdXNlckF2YWlsYWJsZUFzc2V0VG9XaXRoZHJhdwUTd2l0aGRyYXdBc3NldEFtb3VudAYJAQh0aHJvd0VycgEJAKwCAgkArAICAiVjYW5ub3Qgd2l0aGRyYXcgbW9yZSB0aGFuIGF2YWlsYWJsZSAoCQCkAwEFHHVzZXJBdmFpbGFibGVBc3NldFRvV2l0aGRyYXcCASkJAMwIAgMJAGcCBRN3aXRoZHJhd0Fzc2V0QW1vdW50BRZtaW5XaXRoZHJhd0Fzc2V0QW1vdW50BgkBCHRocm93RXJyAQkArAICCQCsAgICJHdpdGhkcmF3IGFtb3VudCBpcyB0b28gc21hbGwuIE1pbjogKAkApAMBBRZtaW5XaXRoZHJhd0Fzc2V0QW1vdW50AgEpBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrCQESZ2V0V2l0aGRyYXdBY3Rpb25zAgUBaQkAlwMBCQDMCAIFDHVzZXJMcEFtb3VudAkAzAgCCQBkAgUSbHBBbW91bnRUb1dpdGhkcmF3AAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5zZXRTdGFraW5nTm9kZQELbm9kZUFkZHJlc3MEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgkBGGdldFNldFN0YWtpbmdOb2RlQWN0aW9ucwMFC3VzZXJBZGRyZXNzBQtub2RlQWRkcmVzcwBkAWkBFnN0YWtlQW5kU2V0U3Rha2luZ05vZGUBC25vZGVBZGRyZXNzBAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJAM4IAgkBD2dldFN0YWtlQWN0aW9ucwIFAWkFC3VzZXJBZGRyZXNzCQEYZ2V0U2V0U3Rha2luZ05vZGVBY3Rpb25zAwULdXNlckFkZHJlc3MFC25vZGVBZGRyZXNzAGQBaQEHYWlyZHJvcAILYWRkcmVzc0xpc3QKYW1vdW50TGlzdAoBA3N1bQIFYWNjdW0EbmV4dAkAZAIFBWFjY3VtBQRuZXh0BA1hbW91bnRMaXN0U3VtCgACJGwFCmFtb3VudExpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA3N1bQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgOTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoEBWNoZWNrCQDMCAIDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABBgkBCHRocm93RXJyAQIYc2hvdWxkIGluY2x1ZGUgMSBwYXltZW50CQDMCAIDCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQxhc3NldElkQnl0ZXMGCQEIdGhyb3dFcnIBCQCsAgICFXBheW1lbnQgc2hvdWxkIGJlIGluIAUNYXNzZXRJZFN0cmluZwkAzAgCAwkAZgIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAGAidwYXltZW50IGFtb3VudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAAACCQCQAwEFC2FkZHJlc3NMaXN0CQCQAwEFCmFtb3VudExpc3QGCQEIdGhyb3dFcnIBAi1hZGRyZXNzTGlzdCBzaG91bGQgYmUgc2FtZSBzaXplIGFzIGFtb3VudExpc3QJAMwIAgMJAGcCCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUNYW1vdW50TGlzdFN1bQYJAQh0aHJvd0VycgECLXBheW1lbnQgYW1vdW50IGlzIGxlc3MgdGhhbiBzdW0gb2YgYW1vdW50TGlzdAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawoBFmdldEFpcmRyb3BTdGF0ZUNoYW5nZXMCBWFjY3VtC2Fzc2V0QW1vdW50BA0kdDAxNDE2MDE0MTk2BQVhY2N1bQQGcmVzdWx0CAUNJHQwMTQxNjAxNDE5NgJfMQQFaW5kZXgIBQ0kdDAxNDE2MDE0MTk2Al8yBAd0b3RhbExwCAUNJHQwMTQxNjAxNDE5NgJfMwQNYWRkZWRMcEFtb3VudAkBD2NhbGNMcEZyb21Bc3NldAEFC2Fzc2V0QW1vdW50BA91c2VyTG9ja2VkTHBLZXkJARVrZXlVc2VyTG9ja2VkTHBBbW91bnQBCQCRAwIFC2FkZHJlc3NMaXN0BQVpbmRleAQLb2xkTHBBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPdXNlckxvY2tlZExwS2V5AAAJAJUKAwkAzQgCBQZyZXN1bHQJAQxJbnRlZ2VyRW50cnkCBQ91c2VyTG9ja2VkTHBLZXkJAGQCBQtvbGRMcEFtb3VudAUNYWRkZWRMcEFtb3VudAkAZAIFBWluZGV4AAEJAGQCBQd0b3RhbExwBQ1hZGRlZExwQW1vdW50BA0kdDAxNDUyNzE0NjM2CgACJGwFCmFtb3VudExpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMFA25pbAAAAAAKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFmdldEFpcmRyb3BTdGF0ZUNoYW5nZXMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDkwCQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaBA5haXJkcm9wRW50cmllcwgFDSR0MDE0NTI3MTQ2MzYCXzEEAl9hCAUNJHQwMTQ1MjcxNDYzNgJfMgQYYWRkZWRUb3RhbExvY2tlZExwQW1vdW50CAUNJHQwMTQ1MjcxNDYzNgJfMwkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRZrZXlUb3RhbExvY2tlZExwQW1vdW50CQBkAgUTdG90YWxMb2NrZWRMcEFtb3VudAUYYWRkZWRUb3RhbExvY2tlZExwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrZXlUb3RhbExwQW1vdW50CQBkAgUNdG90YWxMcEFtb3VudAUYYWRkZWRUb3RhbExvY2tlZExwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrZXlUb3RhbEFzc2V0QW1vdW50CQBkAgUQdG90YWxBc3NldEFtb3VudAUNYW1vdW50TGlzdFN1bQUDbmlsBQ5haXJkcm9wRW50cmllcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARVnZXRVc2VyQXNzZXRzUkVBRE9OTFkBC3VzZXJBZGRyZXNzBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwQSdXNlckxvY2tlZExwQW1vdW50CQEVZ2V0VXNlckxvY2tlZExwQW1vdW50AQULdXNlckFkZHJlc3MEFXVzZXJMb2NrZWRBc3NldEFtb3VudAkBD2NhbGNBc3NldEZyb21McAEFEnVzZXJMb2NrZWRMcEFtb3VudAQcdXNlckF2YWlsYWJsZUFzc2V0VG9XaXRoZHJhdwkBIGdldFVzZXJBdmFpbGFibGVBc3NldHNUb1dpdGhkcmF3AQULdXNlckFkZHJlc3MEFXVzZXJUb3RhbFN0YWtlZEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEXa2V5VXNlclRvdGFsQXNzZXRTdGFrZWQBBQt1c2VyQWRkcmVzcwAABBd1c2VyVG90YWxBc3NldFdpdGhkcmF3bgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEaa2V5VXNlclRvdGFsQXNzZXRXaXRoZHJhd24BBQt1c2VyQWRkcmVzcwAABA0kdDAxNTgyNDE1OTE2CQEXZ2V0VXNlclN0YWtpbmdOb2Rlc0RhdGEBBQt1c2VyQWRkcmVzcwQUdXNlclN0YWtpbmdOb2Rlc0xpc3QIBQ0kdDAxNTgyNDE1OTE2Al8xBBl1c2VyU3Rha2luZ05vZGVTaGFyZXNMaXN0CAUNJHQwMTU4MjQxNTkxNgJfMgkAlAoCBQNuaWwJAJsKCQUMdXNlckxwQW1vdW50BRx1c2VyQXZhaWxhYmxlQXNzZXRUb1dpdGhkcmF3CQEPZ2V0Q3VycmVudFByaWNlAAUVdXNlclRvdGFsU3Rha2VkQW1vdW50BRd1c2VyVG90YWxBc3NldFdpdGhkcmF3bgUSdXNlckxvY2tlZExwQW1vdW50BRV1c2VyTG9ja2VkQXNzZXRBbW91bnQFFHVzZXJTdGFraW5nTm9kZXNMaXN0BRl1c2VyU3Rha2luZ05vZGVTaGFyZXNMaXN0AWkBFmdldFRvdGFsQXNzZXRzUkVBRE9OTFkACQCUCgIFA25pbAkAlwoFBQ10b3RhbExwQW1vdW50CQErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQAJAQ9nZXRDdXJyZW50UHJpY2UABRN0b3RhbExvY2tlZExwQW1vdW50CQEPY2FsY0Fzc2V0RnJvbUxwAQUTdG90YWxMb2NrZWRMcEFtb3VudAFpAQt2b3RlRm9yVHhJZAEEdHhJZAQTY2FsbGVyQWRkcmVzc1N0cmluZwkA2AQBCAgFAWkGY2FsbGVyBWJ5dGVzBAlrZXlQcmVmaXgJARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBQR0eElkBAZyZXN1bHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleUFsbG93ZWRUeElkAAUEdHhJZAUDbmlsBBFhbGxvd2VkVHhJZE9wdGlvbgkAnQgCBQR0aGlzCQEOa2V5QWxsb3dlZFR4SWQABANlcnIJAMwIAgMJAAACCQDIAQEJANkEAQUEdHhJZAURVFhJRF9CWVRFU19MRU5HVEgGCQEIdGhyb3dFcnIBCQCsAgIFBHR4SWQCEiBpcyBub3QgdmFsaWQgdHhJZAkAzAgCAwMJAAACBRFhbGxvd2VkVHhJZE9wdGlvbgUEdW5pdAYJAQIhPQIJAQV2YWx1ZQEFEWFsbG93ZWRUeElkT3B0aW9uBQR0eElkBgkBCHRocm93RXJyAQkArAICBQR0eElkAhMgaXMgYWxyZWFkeSBhbGxvd2VkBQNuaWwDCQAAAgUDZXJyBQNlcnIJAQx2b3RlSU5URVJOQUwEBRNjYWxsZXJBZGRyZXNzU3RyaW5nBQlrZXlQcmVmaXgFBlFVT1JVTQUGcmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQIYnlBZG1pbnMJAAACCAUCdHgCaWQJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5QWxsb3dlZFR4SWQAAgAEB2J5T3duZXIDCQBnAgkAkAMBCQENZ2V0QWRtaW5zTGlzdAAFBlFVT1JVTQcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkDBQhieUFkbWlucwYFB2J5T3duZXIraY25", "chainId": 84, "height": 2864427, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: G46X6NnKMcxCVGizDmfTVmSUH74kpKj8aE9DQ6cyFMuh Next: 566CZ2SDxvP2Di1GWdtPpQnXTpzEZtCoERzT5nFbq536 Diff:
OldNewDifferences
3030
3131 let keyTotalAssetAmount = makeString(["%s", "totalAssetAmount"], SEP)
3232
33+let keyTotalLockedLpAmount = makeString(["%s", "totalLockedLpAmount"], SEP)
34+
3335 func keyUserLpAmount (userAddress) = makeString(["%s%s", "userLpAmount", userAddress], SEP)
36+
37+
38+func keyUserLockedLpAmount (userAddress) = makeString(["%s%s", "userLockedLpAmount", userAddress], SEP)
39+
40+
41+func keyUserStakingNodes (userAddress) = makeString(["%s%s", "userStakingNodes", userAddress], SEP)
42+
43+
44+func keyUserStakingNodesShares (userAddress) = makeString(["%s%s", "userStakingNodesShares", userAddress], SEP)
3445
3546
3647 func keyUserTotalAssetWithdrawn (userAddress) = makeString(["%s%s", "totalAssetWithdrawn", userAddress], SEP)
4859 let totalLpAmount = valueOrElse(getInteger(this, keyTotalLpAmount), 0)
4960
5061 let totalAssetAmount = valueOrElse(getInteger(this, keyTotalAssetAmount), 0)
62+
63+let totalLockedLpAmount = valueOrElse(getInteger(this, keyTotalLockedLpAmount), 0)
5164
5265 let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
5366
95108
96109
97110 func genVotesKeysHelper (a,adminAddress) = {
98- let $t030493073 = a
99- let result = $t030493073._1
100- let prefix = $t030493073._2
111+ let $t035553579 = a
112+ let result = $t035553579._1
113+ let prefix = $t035553579._2
101114 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
102115 }
103116
104117
105118 func genVotesKeys (keyPrefix) = {
106119 let adminList = keyAdminAddressList()
107- let $t032203304 = {
120+ let $t037263810 = {
108121 let $l = getAdminsList()
109122 let $s = size($l)
110123 let $acc0 = $Tuple2(nil, keyPrefix)
118131
119132 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
120133 }
121- let result = $t032203304._1
122- let prefix = $t032203304._2
134+ let result = $t037263810._1
135+ let prefix = $t037263810._2
123136 result
124137 }
125138
186199 }
187200
188201
202+func stringListToIntListHelper (acc,value) = (acc :+ parseIntValue(value))
203+
204+
189205 func calcTotalProfitForHeight (h) = {
190- let startBlock = valueOrElse(getInteger(this, keyStartBlock), 0)
206+ let startBlock = valueOrElse(getInteger(this, keyStartBlock), height)
191207 let startPeriod = fraction(startBlock, 1, emissionPeriodInBlocks)
192208 let elapsedPeriods = ((h / emissionPeriodInBlocks) - startPeriod)
193209 max([0, (emissionPerPeriod * elapsedPeriods)])
218234 else scale18BigInt
219235
220236
237+func getUserStakingNodesData (userAddress) = {
238+ let nodesRaw = valueOrElse(getString(this, keyUserStakingNodes(userAddress)), "")
239+ let sharesRaw = valueOrElse(getString(this, keyUserStakingNodesShares(userAddress)), "")
240+ let nodesList = split(nodesRaw, SEP)
241+ let sharesStringList = split(sharesRaw, SEP)
242+ let sharesList = {
243+ let $l = sharesStringList
244+ let $s = size($l)
245+ let $acc0 = nil
246+ func $f0_1 ($a,$i) = if (($i >= $s))
247+ then $a
248+ else stringListToIntListHelper($a, $l[$i])
249+
250+ func $f0_2 ($a,$i) = if (($i >= $s))
251+ then $a
252+ else throw("List size exceeds 10")
253+
254+ $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)
255+ }
256+ $Tuple2(nodesList, sharesList)
257+ }
258+
259+
260+func calcAssetFromLp (lpAmount) = max([0, toInt(fraction(toBigInt(lpAmount), getCurrentPrice(), scale18BigInt))])
261+
262+
263+func calcLpFromAsset (assetAmount) = max([0, toInt(fraction(toBigInt(assetAmount), scale18BigInt, getCurrentPrice()))])
264+
265+
221266 func getUserLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLpAmount(userAddress)), 0)
267+
268+
269+func getUserLockedLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLockedLpAmount(userAddress)), 0)
222270
223271
224272 func getUserAvailableAssetsToWithdraw (userAddress) = {
225273 let userLpAmount = getUserLpAmount(userAddress)
226- let userAvailableAssetToWithdraw = toInt(fraction(toBigInt(userLpAmount), getCurrentPrice(), scale18BigInt))
227- if ((0 > userAvailableAssetToWithdraw))
228- then 0
229- else userAvailableAssetToWithdraw
274+ calcAssetFromLp(userLpAmount)
230275 }
231276
232277
237282 then true
238283 else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
239284 then true
240- else "payment amount should be greater than 0"]
285+ else "payment amount should be greater than 0", if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
286+ then true
287+ else throwErr("user address is not valid")]
241288 if ((checks == checks))
242289 then {
243290 let paymentAmount = i.payments[0].amount
245292 let userLpAmount = getUserLpAmount(userAddress)
246293 let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
247294 let newTotalLpAmount = (totalLpAmount + paymentLpAmount)
248- let newTotalAssetAmount = (totalAssetAmount + paymentAmount)
295+ let newTotalAssetAmount = toInt(fraction(toBigInt(newTotalLpAmount), getCurrentPrice(), scale18BigInt))
249296 let newUserLpAmount = (userLpAmount + paymentLpAmount)
250297 let newUserTotalStakedAmount = (userTotalStakedAmount + paymentAmount)
251- let updateStartHeightAction = if ((totalLpAmount == 0))
252- then [IntegerEntry(keyStartBlock, height)]
253- else nil
254- ([StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount)] ++ updateStartHeightAction)
298+[StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount), IntegerEntry(keyStartBlock, height)]
255299 }
256300 else throw("Strict value is not equal to itself.")
257301 }
275319 let newUserTotalAssetWithdrawn = (userTotalAssetWithdrawn + withdrawAssetAmount)
276320 [StringEntry(keyHistory("withdraw", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetWithdrawn(userAddress), newUserTotalAssetWithdrawn), IntegerEntry(keyStartBlock, height), ScriptTransfer(i.caller, withdrawAssetAmount, assetIdBytes)]
277321 }
322+ else throw("Strict value is not equal to itself.")
323+ }
324+
325+
326+func getSetStakingNodeActions (userAddress,nodeAddress,nodeShare) = {
327+ let check = [if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
328+ then true
329+ else throwErr("user address is not valid"), if ((size(fromBase58String(nodeAddress)) == ADDRESS_BYTES_SIZE))
330+ then true
331+ else throwErr("node address is not valid")]
332+ if ((check == check))
333+ then [StringEntry(keyUserStakingNodes(userAddress), nodeAddress), StringEntry(keyUserStakingNodesShares(userAddress), toString(nodeShare))]
278334 else throw("Strict value is not equal to itself.")
279335 }
280336
306362
307363
308364 @Callable(i)
309-func stake () = getStakeActions(i, toString(i.caller))
365+func stake () = {
366+ let userAddress = toString(i.caller)
367+ getStakeActions(i, userAddress)
368+ }
310369
311370
312371
313372 @Callable(i)
314-func stakeFor (userAddress) = {
315- let check = [if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
316- then true
317- else throwErr("address is not valid")]
318- if ((check == check))
319- then getStakeActions(i, userAddress)
320- else throw("Strict value is not equal to itself.")
321- }
373+func stakeFor (userAddress) = getStakeActions(i, userAddress)
322374
323375
324376
344396
345397
346398 @Callable(i)
347-func getUserAssetsREADONLY (userAddress) = {
348- let userLpAmount = getUserLpAmount(userAddress)
349- let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
350- let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
351- let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
352- $Tuple2(nil, $Tuple5(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn))
399+func setStakingNode (nodeAddress) = {
400+ let userAddress = toString(i.caller)
401+ getSetStakingNodeActions(userAddress, nodeAddress, 100)
353402 }
354403
355404
356405
357406 @Callable(i)
358-func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple3(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice()))
407+func stakeAndSetStakingNode (nodeAddress) = {
408+ let userAddress = toString(i.caller)
409+ (getStakeActions(i, userAddress) ++ getSetStakingNodeActions(userAddress, nodeAddress, 100))
410+ }
411+
412+
413+
414+@Callable(i)
415+func airdrop (addressList,amountList) = {
416+ func sum (accum,next) = (accum + next)
417+
418+ let amountListSum = {
419+ let $l = amountList
420+ let $s = size($l)
421+ let $acc0 = 0
422+ func $f0_1 ($a,$i) = if (($i >= $s))
423+ then $a
424+ else sum($a, $l[$i])
425+
426+ func $f0_2 ($a,$i) = if (($i >= $s))
427+ then $a
428+ else throw("List size exceeds 90")
429+
430+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
431+ }
432+ let check = [if ((size(i.payments) == 1))
433+ then true
434+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
435+ then true
436+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
437+ then true
438+ else "payment amount should be greater than 0", if ((size(addressList) == size(amountList)))
439+ then true
440+ else throwErr("addressList should be same size as amountList"), if ((i.payments[0].amount >= amountListSum))
441+ then true
442+ else throwErr("payment amount is less than sum of amountList")]
443+ if ((check == check))
444+ then {
445+ func getAirdropStateChanges (accum,assetAmount) = {
446+ let $t01416014196 = accum
447+ let result = $t01416014196._1
448+ let index = $t01416014196._2
449+ let totalLp = $t01416014196._3
450+ let addedLpAmount = calcLpFromAsset(assetAmount)
451+ let userLockedLpKey = keyUserLockedLpAmount(addressList[index])
452+ let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
453+ $Tuple3((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount))
454+ }
455+
456+ let $t01452714636 = {
457+ let $l = amountList
458+ let $s = size($l)
459+ let $acc0 = $Tuple3(nil, 0, 0)
460+ func $f1_1 ($a,$i) = if (($i >= $s))
461+ then $a
462+ else getAirdropStateChanges($a, $l[$i])
463+
464+ func $f1_2 ($a,$i) = if (($i >= $s))
465+ then $a
466+ else throw("List size exceeds 90")
467+
468+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
469+ }
470+ let airdropEntries = $t01452714636._1
471+ let _a = $t01452714636._2
472+ let addedTotalLockedLpAmount = $t01452714636._3
473+ ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, (totalAssetAmount + amountListSum))] ++ airdropEntries)
474+ }
475+ else throw("Strict value is not equal to itself.")
476+ }
477+
478+
479+
480+@Callable(i)
481+func getUserAssetsREADONLY (userAddress) = {
482+ let userLpAmount = getUserLpAmount(userAddress)
483+ let userLockedLpAmount = getUserLockedLpAmount(userAddress)
484+ let userLockedAssetAmount = calcAssetFromLp(userLockedLpAmount)
485+ let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
486+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
487+ let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
488+ let $t01582415916 = getUserStakingNodesData(userAddress)
489+ let userStakingNodesList = $t01582415916._1
490+ let userStakingNodeSharesList = $t01582415916._2
491+ $Tuple2(nil, $Tuple9(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList))
492+ }
493+
494+
495+
496+@Callable(i)
497+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple5(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount)))
359498
360499
361500
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let contractFile = "l2mp_staking.ride"
55
66 let SEP = "__"
77
88 let scale8 = 100000000
99
1010 let scale18 = 1000000000000000000
1111
1212 let scale18BigInt = toBigInt(scale18)
1313
1414 let ADDRESS_BYTES_SIZE = 26
1515
1616 let BLOCKS_IN_DAY = 1440
1717
1818 func throwErr (msg) = throw(((contractFile + ": ") + msg))
1919
2020
2121 let keyAssetId = makeString(["%s", "assetId"], SEP)
2222
2323 let keyEmissionPerBlock = makeString(["%s", "emissionPerBlock"], SEP)
2424
2525 let keyEmissionPeriodInBlocks = makeString(["%s", "emissionPeriodInBlocks"], SEP)
2626
2727 let keyStartBlock = makeString(["%s", "startBlock"], SEP)
2828
2929 let keyTotalLpAmount = makeString(["%s", "totalLpAmount"], SEP)
3030
3131 let keyTotalAssetAmount = makeString(["%s", "totalAssetAmount"], SEP)
3232
33+let keyTotalLockedLpAmount = makeString(["%s", "totalLockedLpAmount"], SEP)
34+
3335 func keyUserLpAmount (userAddress) = makeString(["%s%s", "userLpAmount", userAddress], SEP)
36+
37+
38+func keyUserLockedLpAmount (userAddress) = makeString(["%s%s", "userLockedLpAmount", userAddress], SEP)
39+
40+
41+func keyUserStakingNodes (userAddress) = makeString(["%s%s", "userStakingNodes", userAddress], SEP)
42+
43+
44+func keyUserStakingNodesShares (userAddress) = makeString(["%s%s", "userStakingNodesShares", userAddress], SEP)
3445
3546
3647 func keyUserTotalAssetWithdrawn (userAddress) = makeString(["%s%s", "totalAssetWithdrawn", userAddress], SEP)
3748
3849
3950 func keyUserTotalAssetStaked (userAddress) = makeString(["%s%s", "totalAssetStaked", userAddress], SEP)
4051
4152
4253 func keyHistory (type,userAddress,txId) = makeString(["%s%s%s", type, userAddress, toBase58String(txId)], SEP)
4354
4455
4556 func formatHistory (totalProfit,price,totalAssetAmount,totalLpAmount) = makeString(["%d%d%d%d", toString(totalProfit), toString(price), toString(totalAssetAmount), toString(totalLpAmount)], SEP)
4657
4758
4859 let totalLpAmount = valueOrElse(getInteger(this, keyTotalLpAmount), 0)
4960
5061 let totalAssetAmount = valueOrElse(getInteger(this, keyTotalAssetAmount), 0)
62+
63+let totalLockedLpAmount = valueOrElse(getInteger(this, keyTotalLockedLpAmount), 0)
5164
5265 let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
5366
5467 let assetIdBytes = if ((assetIdString == "WAVES"))
5568 then unit
5669 else fromBase58String(assetIdString)
5770
5871 let emissionPeriodInBlocks = valueOrElse(getInteger(this, keyEmissionPeriodInBlocks), BLOCKS_IN_DAY)
5972
6073 let emissionPerPeriod = (valueOrElse(getInteger(this, keyEmissionPerBlock), 0) * emissionPeriodInBlocks)
6174
6275 let ADMIN_LIST_SIZE = 5
6376
6477 let QUORUM = 3
6578
6679 let TXID_BYTES_LENGTH = 32
6780
6881 func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
6982
7083
7184 func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
7285
7386
7487 func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
7588
7689
7790 func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
7891
7992
8093 func getAdminVote (prefix,admin) = {
8194 let voteKey = keyFullAdminVote(prefix, admin)
8295 valueOrElse(getInteger(voteKey), 0)
8396 }
8497
8598
8699 func getAdminsList () = match getString(this, keyAdminAddressList()) {
87100 case s: String =>
88101 split(s, SEP)
89102 case _ =>
90103 nil
91104 }
92105
93106
94107 func isInAdminList (address) = containsElement(getAdminsList(), address)
95108
96109
97110 func genVotesKeysHelper (a,adminAddress) = {
98- let $t030493073 = a
99- let result = $t030493073._1
100- let prefix = $t030493073._2
111+ let $t035553579 = a
112+ let result = $t035553579._1
113+ let prefix = $t035553579._2
101114 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
102115 }
103116
104117
105118 func genVotesKeys (keyPrefix) = {
106119 let adminList = keyAdminAddressList()
107- let $t032203304 = {
120+ let $t037263810 = {
108121 let $l = getAdminsList()
109122 let $s = size($l)
110123 let $acc0 = $Tuple2(nil, keyPrefix)
111124 func $f0_1 ($a,$i) = if (($i >= $s))
112125 then $a
113126 else genVotesKeysHelper($a, $l[$i])
114127
115128 func $f0_2 ($a,$i) = if (($i >= $s))
116129 then $a
117130 else throw("List size exceeds 5")
118131
119132 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
120133 }
121- let result = $t032203304._1
122- let prefix = $t032203304._2
134+ let result = $t037263810._1
135+ let prefix = $t037263810._2
123136 result
124137 }
125138
126139
127140 func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
128141
129142
130143 func countVotes (prefix) = {
131144 let votes = genVotesKeys(prefix)
132145 let $l = votes
133146 let $s = size($l)
134147 let $acc0 = 0
135148 func $f0_1 ($a,$i) = if (($i >= $s))
136149 then $a
137150 else countVotesHelper($a, $l[$i])
138151
139152 func $f0_2 ($a,$i) = if (($i >= $s))
140153 then $a
141154 else throw("List size exceeds 5")
142155
143156 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
144157 }
145158
146159
147160 func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
148161
149162
150163 func getClearVoteEntries (prefix) = {
151164 let votes = genVotesKeys(prefix)
152165 let $l = votes
153166 let $s = size($l)
154167 let $acc0 = nil
155168 func $f0_1 ($a,$i) = if (($i >= $s))
156169 then $a
157170 else clearVotesHelper($a, $l[$i])
158171
159172 func $f0_2 ($a,$i) = if (($i >= $s))
160173 then $a
161174 else throw("List size exceeds 5")
162175
163176 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
164177 }
165178
166179
167180 func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
168181 let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
169182 let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
170183 let err = if (!(isInAdminList(callerAddressString)))
171184 then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
172185 else if ((adminCurrentVote == 1))
173186 then throwErr((voteKey + " you already voted"))
174187 else unit
175188 if ((err == err))
176189 then {
177190 let votes = countVotes(keyPrefix)
178191 if (((votes + 1) >= minVotes))
179192 then {
180193 let clearVoteEntries = getClearVoteEntries(keyPrefix)
181194 (clearVoteEntries ++ voteResult)
182195 }
183196 else [IntegerEntry(voteKey, 1)]
184197 }
185198 else throw("Strict value is not equal to itself.")
186199 }
187200
188201
202+func stringListToIntListHelper (acc,value) = (acc :+ parseIntValue(value))
203+
204+
189205 func calcTotalProfitForHeight (h) = {
190- let startBlock = valueOrElse(getInteger(this, keyStartBlock), 0)
206+ let startBlock = valueOrElse(getInteger(this, keyStartBlock), height)
191207 let startPeriod = fraction(startBlock, 1, emissionPeriodInBlocks)
192208 let elapsedPeriods = ((h / emissionPeriodInBlocks) - startPeriod)
193209 max([0, (emissionPerPeriod * elapsedPeriods)])
194210 }
195211
196212
197213 func calcTotalProfit () = calcTotalProfitForHeight(height)
198214
199215
200216 func getTotalAssetAmountWithProfitOrMaxAvailable () = {
201217 let totalAssetAmountWithProfit = (totalAssetAmount + calcTotalProfit())
202218 let totalAmount = match assetIdBytes {
203219 case u: Unit =>
204220 min([totalAssetAmountWithProfit, wavesBalance(this).available])
205221 case b: ByteVector =>
206222 min([totalAssetAmountWithProfit, assetBalance(this, b)])
207223 case _ =>
208224 throw("Match error")
209225 }
210226 if ((totalLpAmount == 0))
211227 then 0
212228 else totalAmount
213229 }
214230
215231
216232 func getCurrentPrice () = if ((totalLpAmount != 0))
217233 then fraction(toBigInt(getTotalAssetAmountWithProfitOrMaxAvailable()), scale18BigInt, toBigInt(totalLpAmount))
218234 else scale18BigInt
219235
220236
237+func getUserStakingNodesData (userAddress) = {
238+ let nodesRaw = valueOrElse(getString(this, keyUserStakingNodes(userAddress)), "")
239+ let sharesRaw = valueOrElse(getString(this, keyUserStakingNodesShares(userAddress)), "")
240+ let nodesList = split(nodesRaw, SEP)
241+ let sharesStringList = split(sharesRaw, SEP)
242+ let sharesList = {
243+ let $l = sharesStringList
244+ let $s = size($l)
245+ let $acc0 = nil
246+ func $f0_1 ($a,$i) = if (($i >= $s))
247+ then $a
248+ else stringListToIntListHelper($a, $l[$i])
249+
250+ func $f0_2 ($a,$i) = if (($i >= $s))
251+ then $a
252+ else throw("List size exceeds 10")
253+
254+ $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)
255+ }
256+ $Tuple2(nodesList, sharesList)
257+ }
258+
259+
260+func calcAssetFromLp (lpAmount) = max([0, toInt(fraction(toBigInt(lpAmount), getCurrentPrice(), scale18BigInt))])
261+
262+
263+func calcLpFromAsset (assetAmount) = max([0, toInt(fraction(toBigInt(assetAmount), scale18BigInt, getCurrentPrice()))])
264+
265+
221266 func getUserLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLpAmount(userAddress)), 0)
267+
268+
269+func getUserLockedLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLockedLpAmount(userAddress)), 0)
222270
223271
224272 func getUserAvailableAssetsToWithdraw (userAddress) = {
225273 let userLpAmount = getUserLpAmount(userAddress)
226- let userAvailableAssetToWithdraw = toInt(fraction(toBigInt(userLpAmount), getCurrentPrice(), scale18BigInt))
227- if ((0 > userAvailableAssetToWithdraw))
228- then 0
229- else userAvailableAssetToWithdraw
274+ calcAssetFromLp(userLpAmount)
230275 }
231276
232277
233278 func getStakeActions (i,userAddress) = {
234279 let checks = [if ((size(i.payments) == 1))
235280 then true
236281 else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
237282 then true
238283 else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
239284 then true
240- else "payment amount should be greater than 0"]
285+ else "payment amount should be greater than 0", if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
286+ then true
287+ else throwErr("user address is not valid")]
241288 if ((checks == checks))
242289 then {
243290 let paymentAmount = i.payments[0].amount
244291 let paymentLpAmount = toInt(fraction(toBigInt(paymentAmount), scale18BigInt, getCurrentPrice()))
245292 let userLpAmount = getUserLpAmount(userAddress)
246293 let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
247294 let newTotalLpAmount = (totalLpAmount + paymentLpAmount)
248- let newTotalAssetAmount = (totalAssetAmount + paymentAmount)
295+ let newTotalAssetAmount = toInt(fraction(toBigInt(newTotalLpAmount), getCurrentPrice(), scale18BigInt))
249296 let newUserLpAmount = (userLpAmount + paymentLpAmount)
250297 let newUserTotalStakedAmount = (userTotalStakedAmount + paymentAmount)
251- let updateStartHeightAction = if ((totalLpAmount == 0))
252- then [IntegerEntry(keyStartBlock, height)]
253- else nil
254- ([StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount)] ++ updateStartHeightAction)
298+[StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount), IntegerEntry(keyStartBlock, height)]
255299 }
256300 else throw("Strict value is not equal to itself.")
257301 }
258302
259303
260304 func getWithdrawActions (i,lpAssetWithdrawAmount) = {
261305 let userAddress = toString(i.caller)
262306 let userLpAmount = getUserLpAmount(userAddress)
263307 let check = [if ((lpAssetWithdrawAmount > 0))
264308 then true
265309 else throwErr("LP amount should be more than 0"), if ((userLpAmount >= lpAssetWithdrawAmount))
266310 then true
267311 else throwErr((("cannot withdraw more than available LP (" + toString(userLpAmount)) + ")"))]
268312 if ((check == check))
269313 then {
270314 let newUserLpAmount = (userLpAmount - lpAssetWithdrawAmount)
271315 let withdrawAssetAmount = toInt(fraction(toBigInt(lpAssetWithdrawAmount), getCurrentPrice(), scale18BigInt))
272316 let newTotalLpAmount = (totalLpAmount - lpAssetWithdrawAmount)
273317 let newTotalAssetAmount = toInt(fraction(toBigInt(newTotalLpAmount), getCurrentPrice(), scale18BigInt))
274318 let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
275319 let newUserTotalAssetWithdrawn = (userTotalAssetWithdrawn + withdrawAssetAmount)
276320 [StringEntry(keyHistory("withdraw", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetWithdrawn(userAddress), newUserTotalAssetWithdrawn), IntegerEntry(keyStartBlock, height), ScriptTransfer(i.caller, withdrawAssetAmount, assetIdBytes)]
277321 }
322+ else throw("Strict value is not equal to itself.")
323+ }
324+
325+
326+func getSetStakingNodeActions (userAddress,nodeAddress,nodeShare) = {
327+ let check = [if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
328+ then true
329+ else throwErr("user address is not valid"), if ((size(fromBase58String(nodeAddress)) == ADDRESS_BYTES_SIZE))
330+ then true
331+ else throwErr("node address is not valid")]
332+ if ((check == check))
333+ then [StringEntry(keyUserStakingNodes(userAddress), nodeAddress), StringEntry(keyUserStakingNodesShares(userAddress), toString(nodeShare))]
278334 else throw("Strict value is not equal to itself.")
279335 }
280336
281337
282338 @Callable(i)
283339 func setEmissionPerBlock (emissionPerBlock) = {
284340 let check = [if ((i.caller == this))
285341 then true
286342 else throwErr("permission denied")]
287343 if ((check == check))
288344 then [IntegerEntry(keyTotalAssetAmount, getTotalAssetAmountWithProfitOrMaxAvailable()), IntegerEntry(keyStartBlock, height), IntegerEntry(keyEmissionPerBlock, max([0, emissionPerBlock]))]
289345 else throw("Strict value is not equal to itself.")
290346 }
291347
292348
293349
294350 @Callable(i)
295351 func setEmissionPeriodInBlocks (p) = {
296352 let check = [if ((p > 0))
297353 then true
298354 else throwErr("emission period should be greater than 0"), if ((i.caller == this))
299355 then true
300356 else throwErr("permission denied")]
301357 if ((check == check))
302358 then [IntegerEntry(keyTotalAssetAmount, getTotalAssetAmountWithProfitOrMaxAvailable()), IntegerEntry(keyStartBlock, height), IntegerEntry(keyEmissionPeriodInBlocks, p)]
303359 else throw("Strict value is not equal to itself.")
304360 }
305361
306362
307363
308364 @Callable(i)
309-func stake () = getStakeActions(i, toString(i.caller))
365+func stake () = {
366+ let userAddress = toString(i.caller)
367+ getStakeActions(i, userAddress)
368+ }
310369
311370
312371
313372 @Callable(i)
314-func stakeFor (userAddress) = {
315- let check = [if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
316- then true
317- else throwErr("address is not valid")]
318- if ((check == check))
319- then getStakeActions(i, userAddress)
320- else throw("Strict value is not equal to itself.")
321- }
373+func stakeFor (userAddress) = getStakeActions(i, userAddress)
322374
323375
324376
325377 @Callable(i)
326378 func withdraw (withdrawAssetAmount) = {
327379 let userAddress = toString(i.caller)
328380 let userLpAmount = getUserLpAmount(userAddress)
329381 let lpAmountToWithdraw = toInt(fraction(toBigInt(withdrawAssetAmount), scale18BigInt, getCurrentPrice()))
330382 let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
331383 let minWithdrawAssetAmount = toInt(fraction(getCurrentPrice(), toBigInt(1), scale18BigInt, CEILING))
332384 let check = [if ((withdrawAssetAmount > 0))
333385 then true
334386 else throwErr("withdraw amount should be more than 0"), if ((userAvailableAssetToWithdraw >= withdrawAssetAmount))
335387 then true
336388 else throwErr((("cannot withdraw more than available (" + toString(userAvailableAssetToWithdraw)) + ")")), if ((withdrawAssetAmount >= minWithdrawAssetAmount))
337389 then true
338390 else throwErr((("withdraw amount is too small. Min: (" + toString(minWithdrawAssetAmount)) + ")"))]
339391 if ((check == check))
340392 then getWithdrawActions(i, min([userLpAmount, (lpAmountToWithdraw + 1)]))
341393 else throw("Strict value is not equal to itself.")
342394 }
343395
344396
345397
346398 @Callable(i)
347-func getUserAssetsREADONLY (userAddress) = {
348- let userLpAmount = getUserLpAmount(userAddress)
349- let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
350- let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
351- let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
352- $Tuple2(nil, $Tuple5(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn))
399+func setStakingNode (nodeAddress) = {
400+ let userAddress = toString(i.caller)
401+ getSetStakingNodeActions(userAddress, nodeAddress, 100)
353402 }
354403
355404
356405
357406 @Callable(i)
358-func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple3(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice()))
407+func stakeAndSetStakingNode (nodeAddress) = {
408+ let userAddress = toString(i.caller)
409+ (getStakeActions(i, userAddress) ++ getSetStakingNodeActions(userAddress, nodeAddress, 100))
410+ }
411+
412+
413+
414+@Callable(i)
415+func airdrop (addressList,amountList) = {
416+ func sum (accum,next) = (accum + next)
417+
418+ let amountListSum = {
419+ let $l = amountList
420+ let $s = size($l)
421+ let $acc0 = 0
422+ func $f0_1 ($a,$i) = if (($i >= $s))
423+ then $a
424+ else sum($a, $l[$i])
425+
426+ func $f0_2 ($a,$i) = if (($i >= $s))
427+ then $a
428+ else throw("List size exceeds 90")
429+
430+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
431+ }
432+ let check = [if ((size(i.payments) == 1))
433+ then true
434+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
435+ then true
436+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
437+ then true
438+ else "payment amount should be greater than 0", if ((size(addressList) == size(amountList)))
439+ then true
440+ else throwErr("addressList should be same size as amountList"), if ((i.payments[0].amount >= amountListSum))
441+ then true
442+ else throwErr("payment amount is less than sum of amountList")]
443+ if ((check == check))
444+ then {
445+ func getAirdropStateChanges (accum,assetAmount) = {
446+ let $t01416014196 = accum
447+ let result = $t01416014196._1
448+ let index = $t01416014196._2
449+ let totalLp = $t01416014196._3
450+ let addedLpAmount = calcLpFromAsset(assetAmount)
451+ let userLockedLpKey = keyUserLockedLpAmount(addressList[index])
452+ let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
453+ $Tuple3((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount))
454+ }
455+
456+ let $t01452714636 = {
457+ let $l = amountList
458+ let $s = size($l)
459+ let $acc0 = $Tuple3(nil, 0, 0)
460+ func $f1_1 ($a,$i) = if (($i >= $s))
461+ then $a
462+ else getAirdropStateChanges($a, $l[$i])
463+
464+ func $f1_2 ($a,$i) = if (($i >= $s))
465+ then $a
466+ else throw("List size exceeds 90")
467+
468+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
469+ }
470+ let airdropEntries = $t01452714636._1
471+ let _a = $t01452714636._2
472+ let addedTotalLockedLpAmount = $t01452714636._3
473+ ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, (totalAssetAmount + amountListSum))] ++ airdropEntries)
474+ }
475+ else throw("Strict value is not equal to itself.")
476+ }
477+
478+
479+
480+@Callable(i)
481+func getUserAssetsREADONLY (userAddress) = {
482+ let userLpAmount = getUserLpAmount(userAddress)
483+ let userLockedLpAmount = getUserLockedLpAmount(userAddress)
484+ let userLockedAssetAmount = calcAssetFromLp(userLockedLpAmount)
485+ let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
486+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
487+ let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
488+ let $t01582415916 = getUserStakingNodesData(userAddress)
489+ let userStakingNodesList = $t01582415916._1
490+ let userStakingNodeSharesList = $t01582415916._2
491+ $Tuple2(nil, $Tuple9(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList))
492+ }
493+
494+
495+
496+@Callable(i)
497+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple5(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount)))
359498
360499
361500
362501 @Callable(i)
363502 func voteForTxId (txId) = {
364503 let callerAddressString = toBase58String(i.caller.bytes)
365504 let keyPrefix = keyAllowedTxIdVotePrefix(txId)
366505 let result = [StringEntry(keyAllowedTxId(), txId)]
367506 let allowedTxIdOption = getString(this, keyAllowedTxId())
368507 let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
369508 then true
370509 else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
371510 then true
372511 else (value(allowedTxIdOption) != txId))
373512 then true
374513 else throwErr((txId + " is already allowed"))]
375514 if ((err == err))
376515 then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
377516 else throw("Strict value is not equal to itself.")
378517 }
379518
380519
381520 @Verifier(tx)
382521 func verify () = {
383522 let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
384523 let byOwner = if ((size(getAdminsList()) >= QUORUM))
385524 then false
386525 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
387526 if (byAdmins)
388527 then true
389528 else byOwner
390529 }
391530

github/deemru/w8io/873ac7e 
102.87 ms