tx · 3u4aJct23eHfBtSMFRzP1USEqeyUsiRnDwFa6oQUs9Cv

3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c:  -0.02200000 Waves

2023.12.26 15:39 [2903726] smart account 3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c > SELF 0.00000000 Waves

{ "type": 13, "id": "3u4aJct23eHfBtSMFRzP1USEqeyUsiRnDwFa6oQUs9Cv", "fee": 2200000, "feeAssetId": null, "timestamp": 1703594428755, "version": 2, "chainId": 84, "sender": "3MptKi7f3jwXjzqhHpvLLzsSpEQdZiwAo5c", "senderPublicKey": "44kjsoExo76qSrM51NMhbG8FtdLkcPtyJxEDrwDyT8kz", "proofs": [ "2MmZUXQPKSBN6HMTtRcsDtjP8NGNGTQv3uJLM64aS3ysM4uGP7ausaJYeKF9QGtkY61VvZUjEokRpBeLoE3bcqPt" ], "script": "base64:BgLlIggCEgkKBwEBAQEBCAESABIECgIICBIDCgEIEgQKAggIEgQKAggIIg9nZXRTdHJpbmdPckZhaWwiA2tleSIDU0VQIghCVUZTQ0FMRSIGc2NhbGU4Igh0aHJvd0VyciIDbXNnIghhc1N0cmluZyIDdmFsIgckbWF0Y2gwIgZ2YWxTdHIiHWNvbnZlcnRQcmljZUFzc2V0SW50b0lkb0Fzc2V0IhBwcmljZUFzc2V0QW1vdW50Ig5wcmljZUFzc2V0TVVMVCIFcHJpY2UiCXByaWNlTVVMVCIMaWRvQXNzZXRNVUxUIg9iUHJpY2VBc3NldE1VTFQiDWJJZG9Bc3NldE1VTFQiDmJQcmljZUFzc2V0QlVGIg9iQW1vdW50QXNzZXRCVUYiDklkeENmZ0lkb1N0YXJ0IhFJZHhDZmdJZG9EdXJhdGlvbiIQSWR4Q2ZnQ2xhaW1TdGFydCITSWR4Q2ZnQ2xhaW1EdXJhdGlvbiILSWR4Q2ZnUHJpY2UiD0lkeENmZ1ByaWNlTXVsdCIQSWR4Q2ZnSWRvQXNzZXRJZCISSWR4Q2ZnSWRvQXNzZXRNdWx0IhJJZHhDZmdQcmljZUFzc2V0SWQiFElkeENmZ1ByaWNlQXNzZXRNdWx0IhVJZHhDZmdNaW5JbnZlc3RBbW91bnQiDWZyb21hdENvbmZpZ1MiCGlkb1N0YXJ0IgtpZG9EdXJhdGlvbiIKY2xhaW1TdGFydCINY2xhaW1EdXJhdGlvbiIJcHJpY2VNdWx0IgxpZG9Bc3NldElkNTgiDGlkb0Fzc2V0TXVsdCIOcHJpY2VBc3NldElkNTgiDnByaWNlQXNzZXRNdWx0Ig9taW5JbnZlc3RBbW91bnQiE3RvdGFsSWRvQXNzZXRUb1NlbGwiDGZyb21hdENvbmZpZyIRSWR4SW52VG90YWxBbW91bnQiFUlkeEludlJlbWFpbmluZ0Ftb3VudCIdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQiG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudCIXSWR4SW52TGFzdENsYWltZWRIZWlnaHQiD2Zvcm1hdEludmVzdG9yUyILdG90YWxBbW91bnQiD3JlbWFpbmluZ0Ftb3VudCIXY2xhaW1lZFByaWNlQXNzZXRBbW91bnQiFWNsYWltZWRJZG9Bc3NldEFtb3VudCIRbGFzdENsYWltZWRIZWlnaHQiDmZvcm1hdEludmVzdG9yIhNmb3JtYXRIaXN0b3J5UmVjb3JkIg5pZG9Bc3NldEFtb3VudCIJa2V5Q29uZmlnIgtrZXlJbnZlc3RvciILdXNlckFkZHJlc3MiCWtleVRvdGFscyIZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZCIEdHlwZSIGdHhJZDU4IhRrZXlVU0ROQ2xhaW1EaXNhYmxlZCIVa2V5VVNETkNsYWltRW5kSGVpZ2h0Ig9rZXlQZXJpb2RMZW5ndGgiEGtleUN1cnJlbnRQZXJpb2QiFGtleVBlcmlvZFN0YXJ0SGVpZ2h0IglwZXJpb2ROdW0iEmtleVBlcmlvZEVuZEhlaWdodCIfa2V5VXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbyIXa2V5VG90YWxQZXJpb2RBbGxvd2FuY2UiB2Fzc2V0SWQiFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UiHmtleVBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbSIda2V5UGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0iG2tleVVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbCIOa2V5VXNkdEFzc2V0SWQiFGtleVByaWNlQXNzZXRCYWxhbmNlIgdhZGRyZXNzIhprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudCIXa2V5VG90YWxSZW1haW5pbmdBbW91bnQiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiFWtleUNsYWltQ2xvc2luZ0hlaWdodCISY2xhaW1DbG9zaW5nSGVpZ2h0Ig9yZWFkQ29uZmlnQXJyYXkiI3JlYWRUb3RhbHNBcnJheU9yRGVmYXVsdEJ5Q3VzdG9tS2V5IgljdXN0b21LZXkiGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdCIacmVhZEludmVzdG9yQXJyYXlPckRlZmF1bHQiF3JlYWRJbnZlc3RvckFycmF5T3JGYWlsIhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIgFzIhVJZHhEaWZmVG90YWxJbmNyZW1lbnQiJElkeERpZmZSZW1haW5pbmdQcmljZUFtb3VudEluY3JlbWVudCIiSWR4RGlmZkNsYWltZWRQcmljZUFtb3VudEluY3JlbWVudCIlSWR4RGlmZkNsYWltZWRJZG9Bc3NldEFtb3VudEluY3JlbWVudCILVG90YWxzRW50cnkiCW9yaWdBcnJheSINaW5jcmVtZW50RGlmZiIUbmV3TGFzdENsYWltZWRIZWlnaHQiEXByaWNlQXNzZXRCYWxhbmNlIg5uZXdUb3RhbEFtb3VudCISbmV3UmVtYWluaW5nQW1vdW50IghjZmdBcnJheSIScHJpY2VBc3NldERlY2ltYWxzIiNwcmljZUFzc2V0QmFsYW5jZVByaWNlQXNzZXREZWNpbWFscyIabmV3Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQiGG5ld0NsYWltZWRJZG9Bc3NldEFtb3VudCIHZW50cmllcyIEZGlmZiIXbmV3TG9naWNSZW1haW5pbmdBbW91bnQiG0ludmVzdE9wZXJhdGlvbkhpc3RvcnlFbnRyeSIEdHhJZCIaQ2xhaW1PcGVyYXRpb25IaXN0b3J5RW50cnkiDWludGVybmFsQ2xhaW0iEGNsYWltZWRBc3NldElkNTgiCGNsYWltRW5kIgppZG9Bc3NldElkIgxwcmljZUFzc2V0SWQiDXVzZXJBZGRyZXNzNTgiD29yaWdJbnZlc3RBcnJheSIRaW52ZXN0VG90YWxBbW91bnQiGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QIhdpbnZlc3RMYXN0Q2xhaW1lZEhlaWdodCIUbmV3Q2xhaW1QZXJpb2RIZWlnaHQiDmNsYWltaW5nQmxvY2tzIhhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQiFmNsYWltaW5nSWRvQXNzZXRBbW91bnQiBmlzVVNETiITaXNVU0ROQ2xhaW1EaXNhYmxlZCIGY2hlY2tzIg9pbnRlcm5hbENsYWltVjIiCW91dEFtb3VudCIZdG90YWxVc2VyQXZhaWxhYmxlVG9DbGFpbSIedG90YWxQZXJpb2RQcmljZUFzc2V0QWxsb3dhbmNlIh11c2VyUGVyaW9kUHJpY2VBc3NldEFsbG93YW5jZSIMcGVyaW9kTGVuZ3RoIg1jdXJyZW50UGVyaW9kIht6ZXJvUGVyaW9kRW5kSGVpZ2hJc0RlZmluZWQiDSR0MDEzMjc0MTUxNDQiFWxhc3RQZXJpb2RTdGFydEhlaWdodCITbGFzdFBlcmlvZEVuZEhlaWdodCINJHQwMTM1MzQxNDIzOSIUdXBkYXRlZEN1cnJlbnRQZXJpb2QiC3BlcmlvZFN0YXJ0IhdibG9ja3NUb0xhc3RQZXJpb2RTdGFydCIJcGVyaW9kRW5kIhV6ZXJvUGVyaW9kU3RhcnRIZWlnaHQiE3plcm9QZXJpb2RFbmRIZWlnaHQiDSR0MDE0NDk0MTQ4NzYiG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbSIacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0iGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0iHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8iG3B1dE9uZVRrblYyUHJpY2VBc3NldEFtb3VudCINJHQwMTU4OTkxNjE1MiIBQCIFYm9udXMiCWZlZUFtb3VudCIIbHBBbW91bnQiC3VzZHRBc3NldElkIg0kdDAxNjIxNDE2NDMyIhRnZXRPbmVUa25WMkZlZUFtb3VudCIKdXNkdEFtb3VudCIaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8iE2VuZFBlcmlvZEJsb2Nrc0xlZnQiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiC211c3RNYW5hZ2VyIgFpIgJwZCICcGsiBmlkb0VuZCIDcG10IgxpZG9Bc3NldEluZm8iDnByaWNlQXNzZXRJbmZvIg9vcmlnVG90YWxzQXJyYXkiCnRvdGFsc0RpZmYiDm1pbkl2ZXN0QW1vdW50IgpwbXRBc3NldElkIglwbXRBbW91bnQiEW9yaWdJbnZlc3RvckFycmF5IhNuZXdQcmljZVRvdGFsQW1vdW50IhZyZXF1aXJlZElkb0Fzc2V0QW1vdW50Ig9jYWxsZXJBZGRyZXNzNTgiEGNsYWltUmVzdWx0VHVwbGUiCm91dEFzc2V0SWQiGmNsYWltZWRQcmljZUFtb3VudEZyb21EaWZmIh1jbGFpbWVkSWRvQXNzZXRBbW91bnRGcm9tRGlmZiINJHQwMjIyNzYyMjcyMCIidXBkYXRlZFBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbSIhdXBkYXRlZFBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltIg5ldmFsdWF0ZVJlc3VsdCIbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltIhBsYXN0Q2xhaW1FbnRyaWVzIhNpbnZlc3RvclRvdGFsQW1vdW50IhdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudCIZaW52ZXN0b3JQcmljZUFzc2V0QmFsYW5jZSIXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UiGWludmVzdG9yTGFzdENsYWltZWRIZWlnaHQiDm5ld0ludmVzdEFycmF5IgZ0b3RhbHMiEXRvdGFsc1RvdGFsQW1vdW50IhV0b3RhbHNSZW1haW5pbmdBbW91bnQiHXRvdGFsc0NsYWltZWRQcmljZUFzc2V0QW1vdW50Iht0b3RhbHNDbGFpbWVkSWRvQXNzZXRBbW91bnQiF3RvdGFsc0xhc3RDbGFpbWVkSGVpZ2h0IhhuZXdUb3RhbHNSZW1haW5pbmdBbW91bnQiDW5ld1RvdGFsQXJyYXkiF25ld1RvdGFsUmVtYWluaW5nQW1vdW50Ihh1cGRhdGVkUHJpY2VBc3NldEJhbGFuY2UiHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMiFGNoZWNrVW5jbGFpbWVkQXNzZXRzIghpbnZlc3RvciIcaW52ZXN0b3JSZW1haW5pbmdBbW91bnRDaGVjayILbmV3SW52ZXN0b3IiCW5ld1RvdGFscyIVYXZhaWxhYmxlVG9DbGFpbUFycmF5IhlhdmFpbGFibGVJZG9BbW91bnRUb0NsYWltIi5hdmFpbGFibGVJZG9BbW91bnRUb0NsYWltV2l0aFByaWNlQXNzZXRCYWxhbmNlIg0kdDAzNDEwNTM0NTE3IhZjdXJyZW50UGVyaW9kRW5kSGVpZ2h0Ihp1c2VyVG90YWxQcmljZUFzc2V0Q2xhaW1lZCIMcmVzdWx0U3RyaW5nIgxwZXJpb2RMZW5naHQiE3VzZXJQZXJpb2RBbGxvd2FuY2UiFHRvdGFsUGVyaW9kQWxsb3dhbmNlIgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXlFAQFhAQFiCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQUBYgkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBYgIPIGlzIG5vdCBkZWZpbmVkAAFjAgJfXwABZAkAtgIBAICAkLu61q3wDQABZQCAwtcvAQFmAQFnCQACAQkAuQkCCQDMCAICCWlkby5yaWRlOgkAzAgCBQFnBQNuaWwCASABAWgBAWkEAWoFAWkDCQABAgUBagIGU3RyaW5nBAFrBQFqBQFrCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQFsBQFtAW4BbwFwAXEEAXIJALYCAQUBbgQBcwkAtgIBBQFxBAF0CQC8AgMJALYCAQUBbQUBZAUBcgQBdQkAvAIDBQF0CQC2AgEFAXAJALYCAQUBbwkAoAMBCQC8AgMFAXUJALYCAQUBcQUBZAABdgABAAF3AAIAAXgAAwABeQAEAAF6AAUAAUEABgABQgAHAAFDAAgAAUQACQABRQAKAAFGAAsBAUcMAUgBSQFKAUsBbwFMAU0BTgFPAVABUQFSCQC5CQIJAMwIAgIYJWQlZCVkJWQlZCVkJXMlZCVzJWQlZCVkCQDMCAIFAUgJAMwIAgUBSQkAzAgCBQFKCQDMCAIFAUsJAMwIAgUBbwkAzAgCBQFMCQDMCAIFAU0JAMwIAgUBTgkAzAgCBQFPCQDMCAIFAVAJAMwIAgUBUQkAzAgCBQFSBQNuaWwFAWMBAVMMAUgBSQFKAUsBbwFMAU0BTgFPAVABUQFSCQEBRwwJAKQDAQUBSAkApAMBBQFJCQCkAwEFAUoJAKQDAQUBSwkApAMBBQFvCQCkAwEFAUwFAU0JAKQDAQUBTgUBTwkApAMBBQFQCQCkAwEFAVEJAKQDAQUBUgABVAABAAFVAAIAAVYAAwABVwAEAAFYAAUBAVkFAVoCYWECYWICYWMCYWQJALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIFAVoJAMwIAgUCYWEJAMwIAgUCYWIJAMwIAgUCYWMJAMwIAgUCYWQFA25pbAUBYwECYWUFAVoCYWECYWICYWMCYWQJAQFZBQkApAMBBQFaCQCkAwEFAmFhCQCkAwEFAmFiCQCkAwEFAmFjCQCkAwEFAmFkAQJhZgIBbQJhZwkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQUGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQFtCQDMCAIJAKQDAQUCYWcFA25pbAUBYwECYWgAAgolc19fY29uZmlnAQJhaQECYWoJAKwCAgIEJXNfXwUCYWoBAmFrAAIKJXNfX3RvdGFscwECYWwDAmFtAmFqAmFuCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCYW0JAMwIAgUCYWoJAMwIAgUCYW4FA25pbAUBYwECYW8AAhUlc19fdXNkbkNsYWltRGlzYWJsZWQBAmFwAAIWJXNfX3VzZG5DbGFpbUVuZEhlaWdodAECYXEACQC5CQIJAMwIAgICJXMJAMwIAgIMcGVyaW9kTGVuZ3RoBQNuaWwFAWMBAmFyAAkAuQkCCQDMCAICAiVzCQDMCAICDWN1cnJlbnRQZXJpb2QFA25pbAUBYwECYXMBAmF0CQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFwZXJpb2RTdGFydEhlaWdodAkAzAgCCQCkAwEFAmF0BQNuaWwFAWMBAmF1AQJhdAkAuQkCCQDMCAICBCVzJXMJAMwIAgIPcGVyaW9kRW5kSGVpZ2h0CQDMCAIJAKQDAQUCYXQFA25pbAUBYwECYXYACQC5CQIJAMwIAgICJXMJAMwIAgIcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwUDbmlsBQFjAQJhdwECYXgJALkJAgkAzAgCAgQlcyVzCQDMCAICFHRvdGFsUGVyaW9kQWxsb3dhbmNlCQDMCAIFAmF4BQNuaWwFAWMBAmF5AQJheAkAuQkCCQDMCAICBCVzJXMJAMwIAgITdXNlclBlcmlvZEFsbG93YW5jZQkAzAgCBQJheAUDbmlsBQFjAQJhegICYXgCYXQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCQDMCAIFAmF4CQDMCAIJAKQDAQUCYXQFA25pbAUBYwECYUEDAmF4AmF0AmFqCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgIacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0JAMwIAgUCYXgJAMwIAgkApAMBBQJhdAkAzAgCBQJhagUDbmlsBQFjAQJhQgAJALkJAgkAzAgCAgIlcwkAzAgCAhh1c2R0UHJpY2VBc3NldFN0YWJsZVBvb2wFA25pbAUBYwECYUMACQC5CQIJAMwIAgICJXMJAMwIAgILdXNkdEFzc2V0SWQFA25pbAUBYwECYUQBAmFFCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFwcmljZUFzc2V0QmFsYW5jZQkAzAgCBQJhRQUDbmlsBQFjAQJhRgECYUUJALkJAgkAzAgCAgQlcyVzCQDMCAICF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQDMCAIFAmFFBQNuaWwFAWMBAmFHAAkAuQkCCQDMCAICAiVzCQDMCAICFHRvdGFsUmVtYWluaW5nQW1vdW50BQNuaWwFAWMBAmFIAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAmFJAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAmFKAAIWJXNfX2NsYWltQ2xvc2luZ0hlaWdodAACYUsJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFKAAAAAQJhTAAJALUJAgkBAWEBCQECYWgABQFjAQJhTQECYU4JALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQJhTgkBAVkFAgEwAgEwAgEwAgEwAgEwBQFjAQJhTwAJAQJhTQEJAQJhawABAmFQAQJhagkBAmFNAQkBAmFpAQUCYWoBAmFRAQJhagkAtQkCCQEBYQEJAQJhaQEFAmFqBQFjAQJhUgAEAWoJAKIIAQkBAmFJAAMJAAECBQFqAgZTdHJpbmcEAmFTBQFqCQERQGV4dHJOYXRpdmUoMTA2MikBBQJhUwUEdGhpcwACYVQAAAACYVUAAQACYVYAAgACYVcAAwECYVgFAWICYVkCYVoCYmECYmIEAVoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhWQUBVAQCYWEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhWQUBVQQCYWIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhWQUBVgQCYWMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhWQUBVwQCYWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhWQUBWAQCYmMJAGQCBQFaCQCRAwIFAmFaBQJhVAQCYmQJAGQCBQJhYQkAkQMCBQJhWgUCYVUEAmJlCQECYUwABAFPCQCRAwIFAmJlBQFEBAJiZggJAQV2YWx1ZQEJAOwHAQkA2QQBBQFPCGRlY2ltYWxzBAJiZwkAawMFAmJiBQFlCQBsBgAKAAAFAmJmAAAAAAUERE9XTgQCYmgJAGUCCQBkAgUCYWIJAJEDAgUCYVoFAmFWBQJiYgQCYmkJAGQCCQBkAgUCYWMJAJEDAgUCYVoFAmFXBQJiZwQCYmoDCQBmAgAABQJiZAQCYmsJAGUCCQBlAgUCYmMFAmJoBQJiaQQCYmwDCQBmAgAABQJiawAABQJiawkBC1N0cmluZ0VudHJ5AgUBYgkBAmFlBQUCYmMFAmJsBQJiaAUCYmkFAmJhCQELU3RyaW5nRW50cnkCBQFiCQECYWUFBQJiYwUCYmQFAmJoBQJiaQUCYmEFAmJqAQJibQQCYWoBbQJhZwJibgkBC1N0cmluZ0VudHJ5AgkBAmFsAwIGaW52ZXN0BQJhagkA2AQBBQJibgkBAmFmAgUBbQUCYWcBAmJvBAJhagFtAmFnAmJuCQELU3RyaW5nRW50cnkCCQECYWwDAgVjbGFpbQUCYWoJANgEAQUCYm4JAQJhZgIFAW0FAmFnAQJicAMCYnECYWoCYm4EAmJlCQECYUwABAFKCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAXgEAUsJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiZQUBeQQCYnIJAGQCBQFKBQFLBAFvCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAXoEAUwJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiZQUBQQQBTQkAkQMCBQJiZQUBQgQCYnMJANkEAQUBTQQBTgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJlBQFDBAFPCQCRAwIFAmJlBQFEBAJidAkA2QQBBQFPBAFQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAUUEAmJ1CQClCAEFAmFqBAJidgkBAmFRAQUCYnUEAmJ3CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVQEAmJ4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVgEAmJ5AwkAZwIFAUoFAmJ4BQFKBQJieAQCYnoDCQBmAgUGaGVpZ2h0BQJicgUCYnIDCQBmAgUBSgUGaGVpZ2h0BQFKBQZoZWlnaHQEAmJBCQBlAgUCYnoFAmJ5BAJiQgkAawMFAmJ3BQJiQQUBSwQCYkMJAQFsBQUCYkIFAVAFAW8FAUwFAU4EAmJECQAAAgUCYnEFAU8EAmJFCQELdmFsdWVPckVsc2UCCQCgCAEJAQJhbwAHBAJiRgkAzAgCAwkBASEBAwUCYkQFAmJFBwYJAAIBAhZVU0ROIGNsYWltIGlzIGRpc2FibGVkBQNuaWwDCQAAAgUCYkYFAmJGAwkAAAIFAmJxBQFPCQCYCgYJAMwIAgAACQDMCAIJAQEtAQUCYkIJAMwIAgUCYkIJAMwIAgAABQNuaWwFAmJCBQJidAUCYnYFAmJ6CQDMCAIFAmJCCQDMCAIFAmJDBQNuaWwDCQAAAgUCYnEFAU0JAJgKBgkAzAgCAAAJAMwIAgkBAS0BBQJiQgkAzAgCAAAJAMwIAgUCYkMFA25pbAUCYkMFAmJzBQJidgUCYnoJAMwIAgUCYkIJAMwIAgUCYkMFA25pbAkAAgEJAKwCAgIVdW5zdXBwb3J0ZWQgYXNzZXRJZDogBQJicQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECYkcEAU8CYnUCYkgCYkkEAmJKCQEFdmFsdWUBCQCfCAEJAQJhdwEFAU8EAmJLCQEFdmFsdWUBCQCfCAEJAQJheQEFAU8EAmJMCQEFdmFsdWUBCQCfCAEJAQJhcQAEAmJNCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhcgAAAAQCYk4JAQlpc0RlZmluZWQBCQCfCAEJAQJhdQEAAAQCYk8DCQBmAgUCYk0AAAQCYlAJAQV2YWx1ZQEJAJ8IAQkBAmFzAQUCYk0EAmJRCQEFdmFsdWUBCQCfCAEJAQJhdQEFAmJNBAJiUgMJAGYCBQZoZWlnaHQFAmJRBAJiUwkAZAIFAmJNAAEEAmJUAwkAZgIFBmhlaWdodAkAZAIFAmJRBQJiTAQCYlUJAGoCCQBlAgUGaGVpZ2h0BQJiUQUCYkwDCQAAAgUCYlUAAAkAZAIJAGUCBQZoZWlnaHQFAmJMAAEJAGUCBQZoZWlnaHQFAmJVCQBkAgUCYlEAAQQCYlYJAGUCCQBkAgUCYlQFAmJMAAEJAJUKAwUCYlMFAmJUBQJiVgkAlQoDBQJiTQUCYlAFAmJRBAJiUwgFAmJSAl8xBAJiVAgFAmJSAl8yBAJiVggFAmJSAl8zCQCVCgMFAmJTBQJiVAUCYlYDBQJiTgQCYlcJAQV2YWx1ZQEJAJ8IAQkBAmFzAQAABAJiWAkBBXZhbHVlAQkAnwgBCQECYXUBAAAEAmJZAwkAZgIFBmhlaWdodAUCYlgEAmJTCQBkAgUCYk0AAQQCYlQJAGQCBQJiWAABBAJiVgkAZQIJAGQCBQJiVAUCYkwAAQkAlQoDBQJiUwUCYlQFAmJWCQCVCgMFAmJNBQJiVwUCYlgEAmJTCAUCYlkCXzEEAmJUCAUCYlkCXzIEAmJWCAUCYlkCXzMJAJUKAwUCYlMFAmJUBQJiVgkAlQoDBQJiTQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXMBBQJiTQUGaGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJAQJhdQEFAmJNCQBlAgkAZAIFBmhlaWdodAUCYkwAAQQCYlMIBQJiTwJfMQQCYlQIBQJiTwJfMgQCYlYIBQJiTwJfMwQCYloJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmF6AgUBTwUCYlMFAmJKBAJjYQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYUEDBQFPBQJiUwUCYnUFAmJLBAJiYgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYUQBBQJidQAABAJjYgkAlwMBCQDMCAIJAGQCBQJiSAUCYmIJAMwIAgUCYloJAMwIAgUCY2EFA25pbAQCY2MJAQV2YWx1ZQEJAJ8IAQkBAmF2AAQCY2QFAWUEAmNlCgACY2YJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQkAoggBCQECYUIAAiFwdXRPbmVUa25WMldpdGhvdXRUYWtlRmVlUkVBRE9OTFkJAMwIAgUCY2QJAMwIAgUBTwUDbmlsBQNuaWwDCQABAgUCY2YCDyhJbnQsIEludCwgSW50KQUCY2YJAAIBCQCsAgIJAAMBBQJjZgIkIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50LCBJbnQpAwkAAAIFAmNlBQJjZQQCY2cIBQJjZQJfMwQCY2gIBQJjZQJfMgQCY2kIBQJjZQJfMQQCY2oJAQV2YWx1ZQEJAKIIAQkBAmFDAAQCY2sKAAJjZgkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBCQEFdmFsdWUBCQCiCAEJAQJhQgACE2dldE9uZVRrblYyUkVBRE9OTFkJAMwIAgUCY2oJAMwIAgUCY2kFA25pbAUDbmlsAwkAAQIFAmNmAgooSW50LCBJbnQpBQJjZgkAAgEJAKwCAgkAAwEFAmNmAh8gY291bGRuJ3QgYmUgY2FzdCB0byAoSW50LCBJbnQpAwkAAAIFAmNrBQJjawQCY2wIBQJjawJfMgQCY20IBQJjawJfMQQCY24JAGsDBQJjZAUBZQUCY20EAmNvCQBlAgUCYlYFBmhlaWdodAkAnAoKBQJjYgUCYloFAmNhBQJiSQUCY2MFAmNuBQJjbwUCYlMFAmJUBQJiVgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY3AABAJjcQkBAmFSAAQBagkAnQgCBQJjcQkBAmFIAAMJAAECBQFqAgZTdHJpbmcEAmFTBQFqCQDZBAEFAmFTAwkAAQIFAWoCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECY3IBAmNzBAJjdAkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAFqCQECY3AAAwkAAQIFAWoCCkJ5dGVWZWN0b3IEAmN1BQFqAwkAAAIIBQJjcw9jYWxsZXJQdWJsaWNLZXkFAmN1BgUCY3QDCQABAgUBagIEVW5pdAMJAAACCAUCY3MGY2FsbGVyBQR0aGlzBgUCY3QJAAIBAgtNYXRjaCBlcnJvcgYCY3MBC2NvbnN0cnVjdG9yBwFIAUkBSgFLAW8BTwFRBAFMCQBoAgkAaAIAZADoBwDoBwQCY3YJAGQCBQFIBQFJAwkBCWlzRGVmaW5lZAEJAKIIAQkBAmFoAAkAAgECE2FscmVhZHkgaW5pdGlhbGl6ZWQDCQECIT0CAiMzUE1FSEx4MWo2emVyYXJaVFlmc0dxRGVlWnFRb01weHE1UwkApQgBCAUCY3MGY2FsbGVyCQACAQIObm90IGF1dGhvcml6ZWQDCQECIT0CCQCQAwEIBQJjcwhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAMJAGcCBQJjdgUBSgkAAgECJmNsYWltU3RhcnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gaWRvRW5kBAJjdwkBBXZhbHVlAQkAkQMCCAUCY3MIcGF5bWVudHMAAAQCYnMJAQV2YWx1ZQEIBQJjdwdhc3NldElkBAJjeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJzAhtmYWlsIHRvIGxvYWQgaWRvIGFzc2V0IGluZm8EAU0JANgEAQUCYnMEAU4JAGwGAAoAAAgFAmN4CGRlY2ltYWxzAAAAAAUERE9XTgQCYnQJANkEAQUBTwQCY3kJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJidAIdZmFpbCB0byBsb2FkIHByaWNlIGFzc2V0IGluZm8EAVAJAGwGAAoAAAgFAmN5CGRlY2ltYWxzAAAAAAUERE9XTgQCY3oJAQJhTwAEAmNBCQDMCAIAAAkAzAgCAAAJAMwIAgAACQDMCAIAAAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhaAAJAQFTDAUBSAUBSQUBSgUBSwUBbwUBTAUBTQUBTgUBTwUBUAUBUQgFAmN3BmFtb3VudAkAzAgCCQECYVgFCQECYWsABQJjegUCY0EFAUoAAAUDbmlsAmNzAQZpbnZlc3QABAJiZQkBAmFMAAQBSAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJlBQF2BAFJCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAXcEAmN2CQBkAgUBSAUBSQQBSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJlBQF4BAFLCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAXkEAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiZQUBegQBTAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJlBQFBBAFNCQCRAwIFAmJlBQFCBAJicwkA2QQBBQFNBAFOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmUFAUMEAU8JAJEDAgUCYmUFAUQEAmJ0CQDZBAEFAU8EAVAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiZQUBRQQCY0IJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiZQUBRgQCYWoJAKUIAQgFAmNzBmNhbGxlcgMJAGYCBQFIBQZoZWlnaHQJAAIBAhxpZG8gaGFzIG5vdCBiZWVuIHN0YXJ0ZWQgeWV0AwkAZgIFBmhlaWdodAUCY3YJAAIBAhppZG8gaGFzIGJlZW4gYWxyZWFkeSBlbmRlZAMJAQIhPQIJAJADAQgFAmNzCHBheW1lbnRzAAEJAAIBAh1leGFjdGx5IDEgcGF5bWVudCBpcyBleHBlY3RlZAQCY3cJAQV2YWx1ZQEJAJEDAggFAmNzCHBheW1lbnRzAAAEAmNDCQEFdmFsdWUBCAUCY3cHYXNzZXRJZAQCY0QIBQJjdwZhbW91bnQDCQECIT0CBQJjQwUCYnQJAAIBCQCsAgIJAKwCAgIaaW52YWxpZCBwYXltZW50IGFzc2V0IGlkOiAJANgEAQUCY0MCDCBpcyBleHBlY3RlZAQCY0UJAQJhUAEFAmFqBAJjegkBAmFPAAQCY0YJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY3oFAVQFAmNEBAJjRwkAaAIFAmNGAGQDCQBmAgUCY0cJAPAHAgUEdGhpcwUCYnMJAAIBAjlJRE8gYXNzZXQgaGFzIGJlZW4gLSBzb2xkIGNvbnNpZGVyIHRvIHVzZSBzbWFsbGVyIHBheW1lbnQEAmNBCQDMCAIFAmNECQDMCAIFAmNECQDMCAIAAAkAzAgCAAAFA25pbAkAzAgCCQECYVgFCQECYWkBBQJhagUCY0UFAmNBBQFKAAAJAMwIAgkBAmFYBQkBAmFrAAUCY3oFAmNBBQFKAAAJAMwIAgkBAmJtBAUCYWoFAmNEAAAIBQJjcw10cmFuc2FjdGlvbklkBQNuaWwCY3MBBWNsYWltAgJicQJidQQCY0gJAKUIAQgFAmNzBmNhbGxlcgMJAQIhPQIFAmJ1BQJjSAkAAgECDm5vdCBhdXRob3JpemVkBAJiZQkBAmFMAAQBTwkAkQMCBQJiZQUBRAQCY0kJAQJicAMFAmJxCAUCY3MGY2FsbGVyCAUCY3MNdHJhbnNhY3Rpb25JZAQCY0EIBQJjSQJfMQQCYkgIBQJjSQJfMgQCY0oIBQJjSQJfMwQCYnYIBQJjSQJfNAQCYnoIBQJjSQJfNQQCY0sJAJEDAgUCY0EFAmFWBAJjTAkAkQMCBQJjQQUCYVcEAmJiCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhRAEFAmJ1AAAEAmJmCAkBBXZhbHVlAQkA7AcBCQDZBAEFAU8IZGVjaW1hbHMEAmJqAwkAAAIFAmJxBQFPBAJjTQkBAmJHBAUBTwUCYnUFAmJICQCRAwIFAmNBBQJhVgQCY2IIBQJjTQJfMQQCYloIBQJjTQJfMgQCY2EIBQJjTQJfMwQCYkkIBQJjTQJfNAQCY2MIBQJjTQJfNQQCY24IBQJjTQJfNgQCY28IBQJjTQJfNwQCYlMIBQJjTQJfOAQCYlQIBQJjTQJfOQQCYlYIBQJjTQNfMTAEAmJGCQDMCAIDCQBmAgUCY2EAAAYJAQFmAQI6dW5hdmFpbGFibGUgdG8gY2xhaW0gYmVjYXVzZSB1c2VyIHBlcmlvZCBhbGxvd2FuY2UgcmVhY2hlZAkAzAgCAwkAZgIFAmJaAAAGCQEBZgECO3VuYXZhaWxhYmxlIHRvIGNsYWltIGJlY2F1c2UgdG90YWwgcGVyaW9kIGFsbG93YW5jZSByZWFjaGVkCQDMCAIDCQBmAgUCY2IAAAYJAQFmAQIQbm90aGluZyB0byBjbGFpbQkAzAgCAwkAZgIFAmNjBQJjbgYJAQFmAQJPdW5hdmFpbGFibGUgdG8gY2xhaW0gYmVjYXVzZSB1c2RuIHByaWNlIGxvd2VyIHRoYW4gdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwkAzAgCAwMDCQECIT0CBQJicQUBTwYJAAACBQJhSwAABgkAZgIFAmFLBQZoZWlnaHQGCQEBZgECEUNsYWltIGlzIGRpc2FibGVkBQNuaWwDCQAAAgUCYkYFAmJGBAJjTgkAZQIFAmJaBQJjYgQCY08JAGUCBQJjYQUCY2IEAmJqAwkAZgIFAmJiBQJjYgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCY3MGY2FsbGVyBQJjYgUCY0oJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhRAEFAmJ1CQBlAgUCYmIFAmNiBQNuaWwEAmNQCQC1CQIJAQFoAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFAU8JAMwIAgUCYnUFA25pbAUDbmlsBQFjAwkAAAIFAmNQBQJjUAQCY1EJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjUAADBAJjUgMJAAACBQJjUQUCY2IEAmNTCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVQEAmNUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVUEAmNVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVYEAmNWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVcEAmNXCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnYFAVgEAmNYCQDMCAIJAKQDAQUCY1MJAMwIAgIBMAkAzAgCCQCkAwEFAmNVCQDMCAIJAKQDAQUCY1YJAMwIAgkApAMBBQJjVwUDbmlsBAJjWQkBAmFPAAQCY1oJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjWQUBVAQCZGEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjWQUBVQQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjWQUBVgQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjWQUBVwQCZGQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjWQUBWAQCZGUJAGUCBQJkYQUCY1QEAmRmCQDMCAIJAKQDAQUCY1oJAMwIAgkApAMBBQJkZQkAzAgCCQCkAwEFAmRiCQDMCAIJAKQDAQUCZGMJAMwIAgkApAMBBQJkZAUDbmlsBAJkZwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmFHAAAABQJjVAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUYBBQJidQkApAMBBQJjVAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUcACQCkAwEFAmRnCQDMCAIJAQJhWAUJAQJhaQEFAmJ1BQJjWAUCY0EFAmJ6AAAJAMwIAgkBAmFYBQkBAmFrAAUCZGYFAmNBBQJiegAABQNuaWwJAMwIAgkBAmFYBQkBAmFpAQUCYnUFAmJ2BQJjQQUCYnoAAAkAzAgCCQECYVgFCQECYWsACQECYU8ABQJjQQUCYnoAAAUDbmlsBAJkaAkAZQIJAGQCBQJiYgUCYkgFAmNiCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmNzBmNhbGxlcgUCY2IFAmNKCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUQBBQJidQUCZGgFA25pbAUCY1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXIABQJiUwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFzAQUCYlMFAmJUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXUBBQJiUwUCYlYJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhegIFAU8FAmJTBQJjTgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFBAwUBTwUCYlMFAmJ1BQJjTwkAzAgCCQECYm8EBQJidQUCY2IFAmNMCAUCY3MNdHJhbnNhY3Rpb25JZAUDbmlsBQJiagUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQCZGkJAGsDBQJiYgUBZQkAbAYACgAABQJiZgAAAAAFBERPV04JAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCY3MGY2FsbGVyCQBkAgUCYkgFAmRpBQJjSgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFEAQUCYnUAAAkAzAgCCQECYVgFCQECYWkBBQJidQUCYnYFAmNBBQJiegUCYmIJAMwIAgkBAmFYBQkBAmFrAAkBAmFPAAUCY0EFAmJ6BQJiYgkAzAgCCQECYm8EBQJidQUCY0sJAGQCBQJjTAUCZGkIBQJjcw10cmFuc2FjdGlvbklkBQNuaWwFBHVuaXQFAmJqAmNzARJjbGVhblJlbWFpbmdBbW91bnQBAmJ1BAFPCQCRAwIJAQJhTAAFAUQEAmNQCQC1CQIJAQFoAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFAU8JAMwIAgUCYnUFA25pbAUDbmlsBQFjAwkAAAIFAmNQBQJjUAQCY1EJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjUAACBAJkagMJAAACBQJjUQAABgkBAWYBAhp1c2VyIGhhdmUgdW5jbGFpbWVkIGFzc2V0cwMJAAACBQJkagUCZGoEAmRrCQC1CQIJAQV2YWx1ZQEJAKIIAQkBAmFpAQUCYnUFAWMEAmNTCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGsFAVQEAmNUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGsFAVUEAmNVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGsFAVYEAmNWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGsFAVcEAmNXCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGsFAVgEAmRsAwkBAiE9AgUCY1QAAAYJAQFmAQIkaW52ZXN0b3JSZW1haW5pbmdBbW91bnQgYWxyZWFkeSB6ZXJvAwkAAAIFAmRsBQJkbAQCZG0JALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIJAKQDAQUCY1MJAMwIAgIBMAkAzAgCCQCkAwEFAmNVCQDMCAIJAKQDAQUCY1YJAMwIAgkApAMBBQJjVwUDbmlsBQFjBAJjWQkAtQkCCQEFdmFsdWUBCQCiCAEJAQJhawAFAWMEAmNaCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY1kFAVQEAmRhCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY1kFAVUEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY1kFAVYEAmRjCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY1kFAVcEAmRkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY1kFAVgEAmRuCQC5CQIJAMwIAgIKJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNaCQDMCAIJAKQDAQkAZQIFAmRhBQJjVAkAzAgCCQCkAwEFAmRiCQDMCAIJAKQDAQUCZGMJAMwIAgkApAMBBQJkZAUDbmlsBQFjBAJkZwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmFHAAAABQJjVAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUYBBQJidQkApAMBBQJjVAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUcACQCkAwEFAmRnCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhaQEFAmJ1BQJkbQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWsABQJkbgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNzAQ1jbGFpbVJFQURPTkxZAgJicQJidQQCY0kJAQJicAMFAmJxCQERQGV4dHJOYXRpdmUoMTA2MikBBQJidQkA2QQBAgAEAmNBCAUCY0kCXzEEAmJICAUCY0kCXzIEAmNKCAUCY0kCXzMEAmJ2CAUCY0kCXzQEAmJ6CAUCY0kCXzUEAmRvCAUCY0kCXzYEAmNRCQCRAwIFAmRvAAAEAmRwCQCRAwIFAmRvAAEJAJQKAgUDbmlsCQC5CQIJAMwIAgIGJXMlZCVkCQDMCAIFAmJ1CQDMCAIJAKQDAQUCY1EJAMwIAgkApAMBBQJkcAUDbmlsBQFjAmNzAQ9jbGFpbVYyUkVBRE9OTFkCAmJxAmJ1BAJjSQkBAmJwAwUCYnEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmJ1CQDZBAECAAQCY0EIBQJjSQJfMQQCYkgIBQJjSQJfMgQCY0oIBQJjSQJfMwQCYnYIBQJjSQJfNAQCYnoIBQJjSQJfNQQCZG8IBQJjSQJfNgQCY1EJAJEDAgUCZG8AAAQCZHAJAJEDAgUCZG8AAQQCYmUJAQJhTAAEAU8JAJEDAgUCYmUFAUQEAmJiCQELdmFsdWVPckVsc2UCCQCfCAEJAQJhRAEFAmJ1AAAEAmRpCQBoAgUCYmIAZAQCZHEJAGQCBQJkcAUCZGkEAmRyCQECYkcEBQFPBQJidQUCYkgJAJEDAgUCY0EFAmFWBAJjYggFAmRyAl8xBAJiWggFAmRyAl8yBAJjYQgFAmRyAl8zBAJiSQgFAmRyAl80BAJjYwgFAmRyAl81BAJjbggFAmRyAl82BAJjbwgFAmRyAl83BAJiUwgFAmRyAl84BAJiVAgFAmRyAl85BAJiVggFAmRyA18xMAQCZHMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmF1AQUCYlMAAAQCZHQJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkBAmFRAQUCYnUFAVYFAmJiBAJkdQMJAGYCBQZoZWlnaHQFAmRzBAJkdgkBBXZhbHVlAQkAnwgBCQECYXEABAJkdwkBBXZhbHVlAQkAnwgBCQECYXkBBQFPBAJkeAkBBXZhbHVlAQkAnwgBCQECYXcBBQFPCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZHEJAMwIAgkApAMBBQJkdwkAzAgCCQCkAwEFAmR4CQDMCAIJAKQDAQUCY2MJAMwIAgkApAMBBQJjbgkAzAgCCQCkAwEFAmR2CQDMCAIJAKQDAQUCZHQFA25pbAUBYwkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmRxCQDMCAIJAKQDAQUCY2IJAMwIAgkApAMBBQJiWgkAzAgCCQCkAwEFAmNjCQDMCAIJAKQDAQUCY24JAMwIAgkApAMBBQJjbwkAzAgCCQCkAwEFAmR0BQNuaWwFAWMJAJQKAgUDbmlsBQJkdQECZHkBAmR6AAQCZEEEAWoJAQJjcAADCQABAgUBagIKQnl0ZVZlY3RvcgQCY3UFAWoFAmN1AwkAAQIFAWoCBFVuaXQIBQJkeQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCZHkJYm9keUJ5dGVzCQCRAwIIBQJkeQZwcm9vZnMAAAUCZEETxv4A", "height": 2903726, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4f29r3Rifad8HW7x6XTxQu9UJTY38KEgaB7s9HGyiYyY Next: 6wXwheUY3rpdrUDcVj4odsPa7cnjXsvPJCCmWXt3xo91 Diff:
OldNewDifferences
143143 func keyManagerVaultAddress () = "%s__managerVaultAddress"
144144
145145
146+func keyClaimClosingHeight () = "%s__claimClosingHeight"
147+
148+
149+let claimClosingHeight = valueOrElse(getInteger(this, keyClaimClosingHeight()), 0)
150+
146151 func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
147152
148153
258263 let periodLength = value(getInteger(keyPeriodLength()))
259264 let currentPeriod = valueOrElse(getInteger(keyCurrentPeriod()), 0)
260265 let zeroPeriodEndHeighIsDefined = isDefined(getInteger(keyPeriodEndHeight(0)))
261- let $t01313615006 = if ((currentPeriod > 0))
266+ let $t01327415144 = if ((currentPeriod > 0))
262267 then {
263268 let lastPeriodStartHeight = value(getInteger(keyPeriodStartHeight(currentPeriod)))
264269 let lastPeriodEndHeight = value(getInteger(keyPeriodEndHeight(currentPeriod)))
265- let $t01339614101 = if ((height > lastPeriodEndHeight))
270+ let $t01353414239 = if ((height > lastPeriodEndHeight))
266271 then {
267272 let updatedCurrentPeriod = (currentPeriod + 1)
268273 let periodStart = if ((height > (lastPeriodEndHeight + periodLength)))
277282 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
278283 }
279284 else $Tuple3(currentPeriod, lastPeriodStartHeight, lastPeriodEndHeight)
280- let updatedCurrentPeriod = $t01339614101._1
281- let periodStart = $t01339614101._2
282- let periodEnd = $t01339614101._3
285+ let updatedCurrentPeriod = $t01353414239._1
286+ let periodStart = $t01353414239._2
287+ let periodEnd = $t01353414239._3
283288 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
284289 }
285290 else if (zeroPeriodEndHeighIsDefined)
286291 then {
287292 let zeroPeriodStartHeight = value(getInteger(keyPeriodStartHeight(0)))
288293 let zeroPeriodEndHeight = value(getInteger(keyPeriodEndHeight(0)))
289- let $t01435614738 = if ((height > zeroPeriodEndHeight))
294+ let $t01449414876 = if ((height > zeroPeriodEndHeight))
290295 then {
291296 let updatedCurrentPeriod = (currentPeriod + 1)
292297 let periodStart = (zeroPeriodEndHeight + 1)
294299 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
295300 }
296301 else $Tuple3(currentPeriod, zeroPeriodStartHeight, zeroPeriodEndHeight)
297- let updatedCurrentPeriod = $t01435614738._1
298- let periodStart = $t01435614738._2
299- let periodEnd = $t01435614738._3
302+ let updatedCurrentPeriod = $t01449414876._1
303+ let periodStart = $t01449414876._2
304+ let periodEnd = $t01449414876._3
300305 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
301306 }
302307 else $Tuple3(currentPeriod, valueOrElse(getInteger(keyPeriodStartHeight(currentPeriod)), height), valueOrElse(getInteger(keyPeriodEndHeight(currentPeriod)), ((height + periodLength) - 1)))
303- let updatedCurrentPeriod = $t01313615006._1
304- let periodStart = $t01313615006._2
305- let periodEnd = $t01313615006._3
308+ let updatedCurrentPeriod = $t01327415144._1
309+ let periodStart = $t01327415144._2
310+ let periodEnd = $t01327415144._3
306311 let periodTotalAvailableToClaim = valueOrElse(getInteger(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod)), totalPeriodPriceAssetAllowance)
307312 let periodUserAvailableToClaim = valueOrElse(getInteger(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58)), userPeriodPriceAssetAllowance)
308313 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
309314 let periodMinAvailableToClaim = min([(outAmount + priceAssetBalance), periodTotalAvailableToClaim, periodUserAvailableToClaim])
310315 let usdtPriceAssetAllowableRatio = value(getInteger(keyUsdtPriceAssetAllowableRatio()))
311316 let putOneTknV2PriceAssetAmount = scale8
312- let $t01576116014 = {
317+ let $t01589916152 = {
313318 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "putOneTknV2WithoutTakeFeeREADONLY", [putOneTknV2PriceAssetAmount, priceAssetId58], nil)
314319 if ($isInstanceOf(@, "(Int, Int, Int)"))
315320 then @
316321 else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
317322 }
318- if (($t01576116014 == $t01576116014))
323+ if (($t01589916152 == $t01589916152))
319324 then {
320- let bonus = $t01576116014._3
321- let feeAmount = $t01576116014._2
322- let lpAmount = $t01576116014._1
325+ let bonus = $t01589916152._3
326+ let feeAmount = $t01589916152._2
327+ let lpAmount = $t01589916152._1
323328 let usdtAssetId = value(getString(keyUsdtAssetId()))
324- let $t01607616294 = {
329+ let $t01621416432 = {
325330 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "getOneTknV2READONLY", [usdtAssetId, lpAmount], nil)
326331 if ($isInstanceOf(@, "(Int, Int)"))
327332 then @
328333 else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
329334 }
330- if (($t01607616294 == $t01607616294))
335+ if (($t01621416432 == $t01621416432))
331336 then {
332- let getOneTknV2FeeAmount = $t01607616294._2
333- let usdtAmount = $t01607616294._1
337+ let getOneTknV2FeeAmount = $t01621416432._2
338+ let usdtAmount = $t01621416432._1
334339 let currentUsdtPriceAssetRatio = fraction(putOneTknV2PriceAssetAmount, scale8, usdtAmount)
335340 let endPeriodBlocksLeft = (periodEnd - height)
336341 $Tuple10(periodMinAvailableToClaim, periodTotalAvailableToClaim, periodUserAvailableToClaim, totalUserAvailableToClaim, usdtPriceAssetAllowableRatio, currentUsdtPriceAssetRatio, endPeriodBlocksLeft, updatedCurrentPeriod, periodStart, periodEnd)
467472 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
468473 let entries = if ((claimedAssetId58 == priceAssetId58))
469474 then {
470- let $t02213822582 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
471- let periodMinAvailableToClaim = $t02213822582._1
472- let periodTotalAvailableToClaim = $t02213822582._2
473- let periodUserAvailableToClaim = $t02213822582._3
474- let totalUserAvailableToClaim = $t02213822582._4
475- let usdtPriceAssetAllowableRatio = $t02213822582._5
476- let currentUsdtPriceAssetRatio = $t02213822582._6
477- let endPeriodBlocksLeft = $t02213822582._7
478- let updatedCurrentPeriod = $t02213822582._8
479- let periodStart = $t02213822582._9
480- let periodEnd = $t02213822582._10
475+ let $t02227622720 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
476+ let periodMinAvailableToClaim = $t02227622720._1
477+ let periodTotalAvailableToClaim = $t02227622720._2
478+ let periodUserAvailableToClaim = $t02227622720._3
479+ let totalUserAvailableToClaim = $t02227622720._4
480+ let usdtPriceAssetAllowableRatio = $t02227622720._5
481+ let currentUsdtPriceAssetRatio = $t02227622720._6
482+ let endPeriodBlocksLeft = $t02227622720._7
483+ let updatedCurrentPeriod = $t02227622720._8
484+ let periodStart = $t02227622720._9
485+ let periodEnd = $t02227622720._10
481486 let checks = [if ((periodUserAvailableToClaim > 0))
482487 then true
483488 else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
486491 then true
487492 else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
488493 then true
489- else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
494+ else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio"), if (if (if ((claimedAssetId58 != priceAssetId58))
495+ then true
496+ else (claimClosingHeight == 0))
497+ then true
498+ else (claimClosingHeight > height))
499+ then true
500+ else throwErr("Claim is disabled")]
490501 if ((checks == checks))
491502 then {
492503 let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
612623 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
613624 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
614625 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
615- let $t03383334245 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
616- let periodMinAvailableToClaim = $t03383334245._1
617- let periodTotalAvailableToClaim = $t03383334245._2
618- let periodUserAvailableToClaim = $t03383334245._3
619- let totalUserAvailableToClaim = $t03383334245._4
620- let usdtPriceAssetAllowableRatio = $t03383334245._5
621- let currentUsdtPriceAssetRatio = $t03383334245._6
622- let endPeriodBlocksLeft = $t03383334245._7
623- let updatedCurrentPeriod = $t03383334245._8
624- let periodStart = $t03383334245._9
625- let periodEnd = $t03383334245._10
626+ let $t03410534517 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
627+ let periodMinAvailableToClaim = $t03410534517._1
628+ let periodTotalAvailableToClaim = $t03410534517._2
629+ let periodUserAvailableToClaim = $t03410534517._3
630+ let totalUserAvailableToClaim = $t03410534517._4
631+ let usdtPriceAssetAllowableRatio = $t03410534517._5
632+ let currentUsdtPriceAssetRatio = $t03410534517._6
633+ let endPeriodBlocksLeft = $t03410534517._7
634+ let updatedCurrentPeriod = $t03410534517._8
635+ let periodStart = $t03410534517._9
636+ let periodEnd = $t03410534517._10
626637 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
627638 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
628639 let resultString = if ((height > currentPeriodEndHeight))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
55
66
77 let SEP = "__"
88
99 let BUFSCALE = toBigInt(1000000000000000000)
1010
1111 let scale8 = 100000000
1212
1313 func throwErr (msg) = throw(makeString(["ido.ride:", msg], " "))
1414
1515
1616 func asString (val) = match val {
1717 case valStr: String =>
1818 valStr
1919 case _ =>
2020 throw("fail to cast into String")
2121 }
2222
2323
2424 func convertPriceAssetIntoIdoAsset (priceAssetAmount,priceAssetMULT,price,priceMULT,idoAssetMULT) = {
2525 let bPriceAssetMULT = toBigInt(priceAssetMULT)
2626 let bIdoAssetMULT = toBigInt(idoAssetMULT)
2727 let bPriceAssetBUF = fraction(toBigInt(priceAssetAmount), BUFSCALE, bPriceAssetMULT)
2828 let bAmountAssetBUF = fraction(bPriceAssetBUF, toBigInt(priceMULT), toBigInt(price))
2929 toInt(fraction(bAmountAssetBUF, toBigInt(idoAssetMULT), BUFSCALE))
3030 }
3131
3232
3333 let IdxCfgIdoStart = 1
3434
3535 let IdxCfgIdoDuration = 2
3636
3737 let IdxCfgClaimStart = 3
3838
3939 let IdxCfgClaimDuration = 4
4040
4141 let IdxCfgPrice = 5
4242
4343 let IdxCfgPriceMult = 6
4444
4545 let IdxCfgIdoAssetId = 7
4646
4747 let IdxCfgIdoAssetMult = 8
4848
4949 let IdxCfgPriceAssetId = 9
5050
5151 let IdxCfgPriceAssetMult = 10
5252
5353 let IdxCfgMinInvestAmount = 11
5454
5555 func fromatConfigS (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = makeString(["%d%d%d%d%d%d%s%d%s%d%d%d", idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, totalIdoAssetToSell], SEP)
5656
5757
5858 func fromatConfig (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = fromatConfigS(toString(idoStart), toString(idoDuration), toString(claimStart), toString(claimDuration), toString(price), toString(priceMult), idoAssetId58, toString(idoAssetMult), priceAssetId58, toString(priceAssetMult), toString(minInvestAmount), toString(totalIdoAssetToSell))
5959
6060
6161 let IdxInvTotalAmount = 1
6262
6363 let IdxInvRemainingAmount = 2
6464
6565 let IdxInvClaimedPriceAssetAmount = 3
6666
6767 let IdxInvClaimedIdoAssetAmount = 4
6868
6969 let IdxInvLastClaimedHeight = 5
7070
7171 func formatInvestorS (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, claimedPriceAssetAmount, claimedIdoAssetAmount, lastClaimedHeight], SEP)
7272
7373
7474 func formatInvestor (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = formatInvestorS(toString(totalAmount), toString(remainingAmount), toString(claimedPriceAssetAmount), toString(claimedIdoAssetAmount), toString(lastClaimedHeight))
7575
7676
7777 func formatHistoryRecord (priceAssetAmount,idoAssetAmount) = makeString(["%d%d%d%d", toString(height), toString(lastBlock.timestamp), toString(priceAssetAmount), toString(idoAssetAmount)], SEP)
7878
7979
8080 func keyConfig () = "%s__config"
8181
8282
8383 func keyInvestor (userAddress) = ("%s__" + userAddress)
8484
8585
8686 func keyTotals () = "%s__totals"
8787
8888
8989 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
9090
9191
9292 func keyUSDNClaimDisabled () = "%s__usdnClaimDisabled"
9393
9494
9595 func keyUSDNClaimEndHeight () = "%s__usdnClaimEndHeight"
9696
9797
9898 func keyPeriodLength () = makeString(["%s", "periodLength"], SEP)
9999
100100
101101 func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
102102
103103
104104 func keyPeriodStartHeight (periodNum) = makeString(["%s%s", "periodStartHeight", toString(periodNum)], SEP)
105105
106106
107107 func keyPeriodEndHeight (periodNum) = makeString(["%s%s", "periodEndHeight", toString(periodNum)], SEP)
108108
109109
110110 func keyUsdtPriceAssetAllowableRatio () = makeString(["%s", "usdtPriceAssetAllowableRatio"], SEP)
111111
112112
113113 func keyTotalPeriodAllowance (assetId) = makeString(["%s%s", "totalPeriodAllowance", assetId], SEP)
114114
115115
116116 func keyUserPeriodAllowance (assetId) = makeString(["%s%s", "userPeriodAllowance", assetId], SEP)
117117
118118
119119 func keyPeriodTotalAvailableToClaim (assetId,periodNum) = makeString(["%s%s%s", "periodTotalAvailableToClaim", assetId, toString(periodNum)], SEP)
120120
121121
122122 func keyPeriodUserAvailableToClaim (assetId,periodNum,userAddress) = makeString(["%s%s%s%s", "periodUserAvailableToClaim", assetId, toString(periodNum), userAddress], SEP)
123123
124124
125125 func keyUsdtPriceAssetStablePool () = makeString(["%s", "usdtPriceAssetStablePool"], SEP)
126126
127127
128128 func keyUsdtAssetId () = makeString(["%s", "usdtAssetId"], SEP)
129129
130130
131131 func keyPriceAssetBalance (address) = makeString(["%s%s", "priceAssetBalance", address], SEP)
132132
133133
134134 func keyInvestorRemainingAmount (address) = makeString(["%s%s", "investorRemainingAmount", address], SEP)
135135
136136
137137 func keyTotalRemainingAmount () = makeString(["%s", "totalRemainingAmount"], SEP)
138138
139139
140140 func keyManagerPublicKey () = "%s__managerPublicKey"
141141
142142
143143 func keyManagerVaultAddress () = "%s__managerVaultAddress"
144144
145145
146+func keyClaimClosingHeight () = "%s__claimClosingHeight"
147+
148+
149+let claimClosingHeight = valueOrElse(getInteger(this, keyClaimClosingHeight()), 0)
150+
146151 func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
147152
148153
149154 func readTotalsArrayOrDefaultByCustomKey (customKey) = split(valueOrElse(getString(customKey), formatInvestorS("0", "0", "0", "0", "0")), SEP)
150155
151156
152157 func readTotalsArrayOrDefault () = readTotalsArrayOrDefaultByCustomKey(keyTotals())
153158
154159
155160 func readInvestorArrayOrDefault (userAddress) = readTotalsArrayOrDefaultByCustomKey(keyInvestor(userAddress))
156161
157162
158163 func readInvestorArrayOrFail (userAddress) = split(getStringOrFail(keyInvestor(userAddress)), SEP)
159164
160165
161166 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
162167 case s: String =>
163168 addressFromStringValue(s)
164169 case _ =>
165170 this
166171 }
167172
168173
169174 let IdxDiffTotalIncrement = 0
170175
171176 let IdxDiffRemainingPriceAmountIncrement = 1
172177
173178 let IdxDiffClaimedPriceAmountIncrement = 2
174179
175180 let IdxDiffClaimedIdoAssetAmountIncrement = 3
176181
177182 func TotalsEntry (key,origArray,incrementDiff,newLastClaimedHeight,priceAssetBalance) = {
178183 let totalAmount = parseIntValue(origArray[IdxInvTotalAmount])
179184 let remainingAmount = parseIntValue(origArray[IdxInvRemainingAmount])
180185 let claimedPriceAssetAmount = parseIntValue(origArray[IdxInvClaimedPriceAssetAmount])
181186 let claimedIdoAssetAmount = parseIntValue(origArray[IdxInvClaimedIdoAssetAmount])
182187 let lastClaimedHeight = parseIntValue(origArray[IdxInvLastClaimedHeight])
183188 let newTotalAmount = (totalAmount + incrementDiff[IdxDiffTotalIncrement])
184189 let newRemainingAmount = (remainingAmount + incrementDiff[IdxDiffRemainingPriceAmountIncrement])
185190 let cfgArray = readConfigArray()
186191 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
187192 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
188193 let priceAssetBalancePriceAssetDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
189194 let newClaimedPriceAssetAmount = ((claimedPriceAssetAmount + incrementDiff[IdxDiffClaimedPriceAmountIncrement]) - priceAssetBalance)
190195 let newClaimedIdoAssetAmount = ((claimedIdoAssetAmount + incrementDiff[IdxDiffClaimedIdoAssetAmountIncrement]) + priceAssetBalancePriceAssetDecimals)
191196 let entries = if ((0 > newRemainingAmount))
192197 then {
193198 let diff = ((newTotalAmount - newClaimedPriceAssetAmount) - newClaimedIdoAssetAmount)
194199 let newLogicRemainingAmount = if ((0 > diff))
195200 then 0
196201 else diff
197202 StringEntry(key, formatInvestor(newTotalAmount, newLogicRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
198203 }
199204 else StringEntry(key, formatInvestor(newTotalAmount, newRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
200205 entries
201206 }
202207
203208
204209 func InvestOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("invest", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
205210
206211
207212 func ClaimOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("claim", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
208213
209214
210215 func internalClaim (claimedAssetId58,userAddress,txId) = {
211216 let cfgArray = readConfigArray()
212217 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
213218 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
214219 let claimEnd = (claimStart + claimDuration)
215220 let price = parseIntValue(cfgArray[IdxCfgPrice])
216221 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
217222 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
218223 let idoAssetId = fromBase58String(idoAssetId58)
219224 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
220225 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
221226 let priceAssetId = fromBase58String(priceAssetId58)
222227 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
223228 let userAddress58 = toString(userAddress)
224229 let origInvestArray = readInvestorArrayOrFail(userAddress58)
225230 let investTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
226231 let investLastClaimedHeightTMP = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
227232 let investLastClaimedHeight = if ((claimStart >= investLastClaimedHeightTMP))
228233 then claimStart
229234 else investLastClaimedHeightTMP
230235 let newClaimPeriodHeight = if ((height > claimEnd))
231236 then claimEnd
232237 else if ((claimStart > height))
233238 then claimStart
234239 else height
235240 let claimingBlocks = (newClaimPeriodHeight - investLastClaimedHeight)
236241 let claimingPriceAssetAmount = fraction(investTotalAmount, claimingBlocks, claimDuration)
237242 let claimingIdoAssetAmount = convertPriceAssetIntoIdoAsset(claimingPriceAssetAmount, priceAssetMult, price, priceMult, idoAssetMult)
238243 let isUSDN = (claimedAssetId58 == priceAssetId58)
239244 let isUSDNClaimDisabled = valueOrElse(getBoolean(keyUSDNClaimDisabled()), false)
240245 let checks = [if (!(if (isUSDN)
241246 then isUSDNClaimDisabled
242247 else false))
243248 then true
244249 else throw("USDN claim is disabled")]
245250 if ((checks == checks))
246251 then if ((claimedAssetId58 == priceAssetId58))
247252 then $Tuple6([0, -(claimingPriceAssetAmount), claimingPriceAssetAmount, 0], claimingPriceAssetAmount, priceAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
248253 else if ((claimedAssetId58 == idoAssetId58))
249254 then $Tuple6([0, -(claimingPriceAssetAmount), 0, claimingIdoAssetAmount], claimingIdoAssetAmount, idoAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
250255 else throw(("unsupported assetId: " + claimedAssetId58))
251256 else throw("Strict value is not equal to itself.")
252257 }
253258
254259
255260 func internalClaimV2 (priceAssetId58,userAddress58,outAmount,totalUserAvailableToClaim) = {
256261 let totalPeriodPriceAssetAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
257262 let userPeriodPriceAssetAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
258263 let periodLength = value(getInteger(keyPeriodLength()))
259264 let currentPeriod = valueOrElse(getInteger(keyCurrentPeriod()), 0)
260265 let zeroPeriodEndHeighIsDefined = isDefined(getInteger(keyPeriodEndHeight(0)))
261- let $t01313615006 = if ((currentPeriod > 0))
266+ let $t01327415144 = if ((currentPeriod > 0))
262267 then {
263268 let lastPeriodStartHeight = value(getInteger(keyPeriodStartHeight(currentPeriod)))
264269 let lastPeriodEndHeight = value(getInteger(keyPeriodEndHeight(currentPeriod)))
265- let $t01339614101 = if ((height > lastPeriodEndHeight))
270+ let $t01353414239 = if ((height > lastPeriodEndHeight))
266271 then {
267272 let updatedCurrentPeriod = (currentPeriod + 1)
268273 let periodStart = if ((height > (lastPeriodEndHeight + periodLength)))
269274 then {
270275 let blocksToLastPeriodStart = ((height - lastPeriodEndHeight) % periodLength)
271276 if ((blocksToLastPeriodStart == 0))
272277 then ((height - periodLength) + 1)
273278 else (height - blocksToLastPeriodStart)
274279 }
275280 else (lastPeriodEndHeight + 1)
276281 let periodEnd = ((periodStart + periodLength) - 1)
277282 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
278283 }
279284 else $Tuple3(currentPeriod, lastPeriodStartHeight, lastPeriodEndHeight)
280- let updatedCurrentPeriod = $t01339614101._1
281- let periodStart = $t01339614101._2
282- let periodEnd = $t01339614101._3
285+ let updatedCurrentPeriod = $t01353414239._1
286+ let periodStart = $t01353414239._2
287+ let periodEnd = $t01353414239._3
283288 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
284289 }
285290 else if (zeroPeriodEndHeighIsDefined)
286291 then {
287292 let zeroPeriodStartHeight = value(getInteger(keyPeriodStartHeight(0)))
288293 let zeroPeriodEndHeight = value(getInteger(keyPeriodEndHeight(0)))
289- let $t01435614738 = if ((height > zeroPeriodEndHeight))
294+ let $t01449414876 = if ((height > zeroPeriodEndHeight))
290295 then {
291296 let updatedCurrentPeriod = (currentPeriod + 1)
292297 let periodStart = (zeroPeriodEndHeight + 1)
293298 let periodEnd = ((periodStart + periodLength) - 1)
294299 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
295300 }
296301 else $Tuple3(currentPeriod, zeroPeriodStartHeight, zeroPeriodEndHeight)
297- let updatedCurrentPeriod = $t01435614738._1
298- let periodStart = $t01435614738._2
299- let periodEnd = $t01435614738._3
302+ let updatedCurrentPeriod = $t01449414876._1
303+ let periodStart = $t01449414876._2
304+ let periodEnd = $t01449414876._3
300305 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
301306 }
302307 else $Tuple3(currentPeriod, valueOrElse(getInteger(keyPeriodStartHeight(currentPeriod)), height), valueOrElse(getInteger(keyPeriodEndHeight(currentPeriod)), ((height + periodLength) - 1)))
303- let updatedCurrentPeriod = $t01313615006._1
304- let periodStart = $t01313615006._2
305- let periodEnd = $t01313615006._3
308+ let updatedCurrentPeriod = $t01327415144._1
309+ let periodStart = $t01327415144._2
310+ let periodEnd = $t01327415144._3
306311 let periodTotalAvailableToClaim = valueOrElse(getInteger(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod)), totalPeriodPriceAssetAllowance)
307312 let periodUserAvailableToClaim = valueOrElse(getInteger(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58)), userPeriodPriceAssetAllowance)
308313 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
309314 let periodMinAvailableToClaim = min([(outAmount + priceAssetBalance), periodTotalAvailableToClaim, periodUserAvailableToClaim])
310315 let usdtPriceAssetAllowableRatio = value(getInteger(keyUsdtPriceAssetAllowableRatio()))
311316 let putOneTknV2PriceAssetAmount = scale8
312- let $t01576116014 = {
317+ let $t01589916152 = {
313318 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "putOneTknV2WithoutTakeFeeREADONLY", [putOneTknV2PriceAssetAmount, priceAssetId58], nil)
314319 if ($isInstanceOf(@, "(Int, Int, Int)"))
315320 then @
316321 else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
317322 }
318- if (($t01576116014 == $t01576116014))
323+ if (($t01589916152 == $t01589916152))
319324 then {
320- let bonus = $t01576116014._3
321- let feeAmount = $t01576116014._2
322- let lpAmount = $t01576116014._1
325+ let bonus = $t01589916152._3
326+ let feeAmount = $t01589916152._2
327+ let lpAmount = $t01589916152._1
323328 let usdtAssetId = value(getString(keyUsdtAssetId()))
324- let $t01607616294 = {
329+ let $t01621416432 = {
325330 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "getOneTknV2READONLY", [usdtAssetId, lpAmount], nil)
326331 if ($isInstanceOf(@, "(Int, Int)"))
327332 then @
328333 else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
329334 }
330- if (($t01607616294 == $t01607616294))
335+ if (($t01621416432 == $t01621416432))
331336 then {
332- let getOneTknV2FeeAmount = $t01607616294._2
333- let usdtAmount = $t01607616294._1
337+ let getOneTknV2FeeAmount = $t01621416432._2
338+ let usdtAmount = $t01621416432._1
334339 let currentUsdtPriceAssetRatio = fraction(putOneTknV2PriceAssetAmount, scale8, usdtAmount)
335340 let endPeriodBlocksLeft = (periodEnd - height)
336341 $Tuple10(periodMinAvailableToClaim, periodTotalAvailableToClaim, periodUserAvailableToClaim, totalUserAvailableToClaim, usdtPriceAssetAllowableRatio, currentUsdtPriceAssetRatio, endPeriodBlocksLeft, updatedCurrentPeriod, periodStart, periodEnd)
337342 }
338343 else throw("Strict value is not equal to itself.")
339344 }
340345 else throw("Strict value is not equal to itself.")
341346 }
342347
343348
344349 func managerPublicKeyOrUnit () = {
345350 let managerVaultAddress = getManagerVaultAddressOrThis()
346351 match getString(managerVaultAddress, keyManagerPublicKey()) {
347352 case s: String =>
348353 fromBase58String(s)
349354 case _: Unit =>
350355 unit
351356 case _ =>
352357 throw("Match error")
353358 }
354359 }
355360
356361
357362 func mustManager (i) = {
358363 let pd = throw("Permission denied")
359364 match managerPublicKeyOrUnit() {
360365 case pk: ByteVector =>
361366 if ((i.callerPublicKey == pk))
362367 then true
363368 else pd
364369 case _: Unit =>
365370 if ((i.caller == this))
366371 then true
367372 else pd
368373 case _ =>
369374 throw("Match error")
370375 }
371376 }
372377
373378
374379 @Callable(i)
375380 func constructor (idoStart,idoDuration,claimStart,claimDuration,price,priceAssetId58,minInvestAmount) = {
376381 let priceMult = ((100 * 1000) * 1000)
377382 let idoEnd = (idoStart + idoDuration)
378383 if (isDefined(getString(keyConfig())))
379384 then throw("already initialized")
380385 else if (("3PMEHLx1j6zerarZTYfsGqDeeZqQoMpxq5S" != toString(i.caller)))
381386 then throw("not authorized")
382387 else if ((size(i.payments) != 1))
383388 then throw("exactly 1 payment must be attached")
384389 else if ((idoEnd >= claimStart))
385390 then throw("claimStart must be greater than idoEnd")
386391 else {
387392 let pmt = value(i.payments[0])
388393 let idoAssetId = value(pmt.assetId)
389394 let idoAssetInfo = valueOrErrorMessage(assetInfo(idoAssetId), "fail to load ido asset info")
390395 let idoAssetId58 = toBase58String(idoAssetId)
391396 let idoAssetMult = pow(10, 0, idoAssetInfo.decimals, 0, 0, DOWN)
392397 let priceAssetId = fromBase58String(priceAssetId58)
393398 let priceAssetInfo = valueOrErrorMessage(assetInfo(priceAssetId), "fail to load price asset info")
394399 let priceAssetMult = pow(10, 0, priceAssetInfo.decimals, 0, 0, DOWN)
395400 let origTotalsArray = readTotalsArrayOrDefault()
396401 let totalsDiff = [0, 0, 0, 0]
397402 [StringEntry(keyConfig(), fromatConfig(idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, pmt.amount)), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0)]
398403 }
399404 }
400405
401406
402407
403408 @Callable(i)
404409 func invest () = {
405410 let cfgArray = readConfigArray()
406411 let idoStart = parseIntValue(cfgArray[IdxCfgIdoStart])
407412 let idoDuration = parseIntValue(cfgArray[IdxCfgIdoDuration])
408413 let idoEnd = (idoStart + idoDuration)
409414 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
410415 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
411416 let price = parseIntValue(cfgArray[IdxCfgPrice])
412417 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
413418 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
414419 let idoAssetId = fromBase58String(idoAssetId58)
415420 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
416421 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
417422 let priceAssetId = fromBase58String(priceAssetId58)
418423 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
419424 let minIvestAmount = parseIntValue(cfgArray[IdxCfgMinInvestAmount])
420425 let userAddress = toString(i.caller)
421426 if ((idoStart > height))
422427 then throw("ido has not been started yet")
423428 else if ((height > idoEnd))
424429 then throw("ido has been already ended")
425430 else if ((size(i.payments) != 1))
426431 then throw("exactly 1 payment is expected")
427432 else {
428433 let pmt = value(i.payments[0])
429434 let pmtAssetId = value(pmt.assetId)
430435 let pmtAmount = pmt.amount
431436 if ((pmtAssetId != priceAssetId))
432437 then throw((("invalid payment asset id: " + toBase58String(pmtAssetId)) + " is expected"))
433438 else {
434439 let origInvestorArray = readInvestorArrayOrDefault(userAddress)
435440 let origTotalsArray = readTotalsArrayOrDefault()
436441 let newPriceTotalAmount = (parseIntValue(origTotalsArray[IdxInvTotalAmount]) + pmtAmount)
437442 let requiredIdoAssetAmount = (newPriceTotalAmount * 100)
438443 if ((requiredIdoAssetAmount > assetBalance(this, idoAssetId)))
439444 then throw("IDO asset has been - sold consider to use smaller payment")
440445 else {
441446 let totalsDiff = [pmtAmount, pmtAmount, 0, 0]
442447 [TotalsEntry(keyInvestor(userAddress), origInvestorArray, totalsDiff, claimStart, 0), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0), InvestOperationHistoryEntry(userAddress, pmtAmount, 0, i.transactionId)]
443448 }
444449 }
445450 }
446451 }
447452
448453
449454
450455 @Callable(i)
451456 func claim (claimedAssetId58,userAddress58) = {
452457 let callerAddress58 = toString(i.caller)
453458 if ((userAddress58 != callerAddress58))
454459 then throw("not authorized")
455460 else {
456461 let cfgArray = readConfigArray()
457462 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
458463 let claimResultTuple = internalClaim(claimedAssetId58, i.caller, i.transactionId)
459464 let totalsDiff = claimResultTuple._1
460465 let outAmount = claimResultTuple._2
461466 let outAssetId = claimResultTuple._3
462467 let origInvestArray = claimResultTuple._4
463468 let newClaimPeriodHeight = claimResultTuple._5
464469 let claimedPriceAmountFromDiff = totalsDiff[IdxDiffClaimedPriceAmountIncrement]
465470 let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
466471 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
467472 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
468473 let entries = if ((claimedAssetId58 == priceAssetId58))
469474 then {
470- let $t02213822582 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
471- let periodMinAvailableToClaim = $t02213822582._1
472- let periodTotalAvailableToClaim = $t02213822582._2
473- let periodUserAvailableToClaim = $t02213822582._3
474- let totalUserAvailableToClaim = $t02213822582._4
475- let usdtPriceAssetAllowableRatio = $t02213822582._5
476- let currentUsdtPriceAssetRatio = $t02213822582._6
477- let endPeriodBlocksLeft = $t02213822582._7
478- let updatedCurrentPeriod = $t02213822582._8
479- let periodStart = $t02213822582._9
480- let periodEnd = $t02213822582._10
475+ let $t02227622720 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
476+ let periodMinAvailableToClaim = $t02227622720._1
477+ let periodTotalAvailableToClaim = $t02227622720._2
478+ let periodUserAvailableToClaim = $t02227622720._3
479+ let totalUserAvailableToClaim = $t02227622720._4
480+ let usdtPriceAssetAllowableRatio = $t02227622720._5
481+ let currentUsdtPriceAssetRatio = $t02227622720._6
482+ let endPeriodBlocksLeft = $t02227622720._7
483+ let updatedCurrentPeriod = $t02227622720._8
484+ let periodStart = $t02227622720._9
485+ let periodEnd = $t02227622720._10
481486 let checks = [if ((periodUserAvailableToClaim > 0))
482487 then true
483488 else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
484489 then true
485490 else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
486491 then true
487492 else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
488493 then true
489- else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
494+ else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio"), if (if (if ((claimedAssetId58 != priceAssetId58))
495+ then true
496+ else (claimClosingHeight == 0))
497+ then true
498+ else (claimClosingHeight > height))
499+ then true
500+ else throwErr("Claim is disabled")]
490501 if ((checks == checks))
491502 then {
492503 let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
493504 let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
494505 let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
495506 then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
496507 else {
497508 let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
498509 if ((evaluateResult == evaluateResult))
499510 then {
500511 let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
501512 let lastClaimEntries = if ((availablePriceAmountToClaim == periodMinAvailableToClaim))
502513 then {
503514 let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
504515 let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
505516 let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
506517 let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
507518 let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
508519 let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
509520 let totals = readTotalsArrayOrDefault()
510521 let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
511522 let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
512523 let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
513524 let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
514525 let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
515526 let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
516527 let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
517528 let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
518529 [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
519530 }
520531 else [TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, 0)]
521532 let updatedPriceAssetBalance = ((priceAssetBalance + outAmount) - periodMinAvailableToClaim)
522533 ([ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), updatedPriceAssetBalance)] ++ lastClaimEntries)
523534 }
524535 else throw("Strict value is not equal to itself.")
525536 }
526537 $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
527538 }
528539 else throw("Strict value is not equal to itself.")
529540 }
530541 else {
531542 let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
532543 $Tuple2([ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
533544 }
534545 entries
535546 }
536547 }
537548
538549
539550
540551 @Callable(i)
541552 func cleanRemaingAmount (userAddress58) = {
542553 let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
543554 let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
544555 if ((evaluateResult == evaluateResult))
545556 then {
546557 let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
547558 let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
548559 then true
549560 else throwErr("user have unclaimed assets")
550561 if ((checkUnclaimedAssets == checkUnclaimedAssets))
551562 then {
552563 let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
553564 let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
554565 let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
555566 let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
556567 let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
557568 let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
558569 let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
559570 then true
560571 else throwErr("investorRemainingAmount already zero")
561572 if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
562573 then {
563574 let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
564575 let totals = split(value(getString(keyTotals())), SEP)
565576 let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
566577 let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
567578 let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
568579 let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
569580 let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
570581 let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
571582 let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
572583 [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
573584 }
574585 else throw("Strict value is not equal to itself.")
575586 }
576587 else throw("Strict value is not equal to itself.")
577588 }
578589 else throw("Strict value is not equal to itself.")
579590 }
580591
581592
582593
583594 @Callable(i)
584595 func claimREADONLY (claimedAssetId58,userAddress58) = {
585596 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
586597 let totalsDiff = claimResultTuple._1
587598 let outAmount = claimResultTuple._2
588599 let outAssetId = claimResultTuple._3
589600 let origInvestArray = claimResultTuple._4
590601 let newClaimPeriodHeight = claimResultTuple._5
591602 let availableToClaimArray = claimResultTuple._6
592603 let availablePriceAmountToClaim = availableToClaimArray[0]
593604 let availableIdoAmountToClaim = availableToClaimArray[1]
594605 $Tuple2(nil, makeString(["%s%d%d", userAddress58, toString(availablePriceAmountToClaim), toString(availableIdoAmountToClaim)], SEP))
595606 }
596607
597608
598609
599610 @Callable(i)
600611 func claimV2READONLY (claimedAssetId58,userAddress58) = {
601612 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
602613 let totalsDiff = claimResultTuple._1
603614 let outAmount = claimResultTuple._2
604615 let outAssetId = claimResultTuple._3
605616 let origInvestArray = claimResultTuple._4
606617 let newClaimPeriodHeight = claimResultTuple._5
607618 let availableToClaimArray = claimResultTuple._6
608619 let availablePriceAmountToClaim = availableToClaimArray[0]
609620 let availableIdoAmountToClaim = availableToClaimArray[1]
610621 let cfgArray = readConfigArray()
611622 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
612623 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
613624 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
614625 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
615- let $t03383334245 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
616- let periodMinAvailableToClaim = $t03383334245._1
617- let periodTotalAvailableToClaim = $t03383334245._2
618- let periodUserAvailableToClaim = $t03383334245._3
619- let totalUserAvailableToClaim = $t03383334245._4
620- let usdtPriceAssetAllowableRatio = $t03383334245._5
621- let currentUsdtPriceAssetRatio = $t03383334245._6
622- let endPeriodBlocksLeft = $t03383334245._7
623- let updatedCurrentPeriod = $t03383334245._8
624- let periodStart = $t03383334245._9
625- let periodEnd = $t03383334245._10
626+ let $t03410534517 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
627+ let periodMinAvailableToClaim = $t03410534517._1
628+ let periodTotalAvailableToClaim = $t03410534517._2
629+ let periodUserAvailableToClaim = $t03410534517._3
630+ let totalUserAvailableToClaim = $t03410534517._4
631+ let usdtPriceAssetAllowableRatio = $t03410534517._5
632+ let currentUsdtPriceAssetRatio = $t03410534517._6
633+ let endPeriodBlocksLeft = $t03410534517._7
634+ let updatedCurrentPeriod = $t03410534517._8
635+ let periodStart = $t03410534517._9
636+ let periodEnd = $t03410534517._10
626637 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
627638 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
628639 let resultString = if ((height > currentPeriodEndHeight))
629640 then {
630641 let periodLenght = value(getInteger(keyPeriodLength()))
631642 let userPeriodAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
632643 let totalPeriodAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
633644 makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(userPeriodAllowance), toString(totalPeriodAllowance), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(periodLenght), toString(userTotalPriceAssetClaimed)], SEP)
634645 }
635646 else makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(periodMinAvailableToClaim), toString(periodTotalAvailableToClaim), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(endPeriodBlocksLeft), toString(userTotalPriceAssetClaimed)], SEP)
636647 $Tuple2(nil, resultString)
637648 }
638649
639650
640651 @Verifier(tx)
641652 func verify () = {
642653 let targetPublicKey = match managerPublicKeyOrUnit() {
643654 case pk: ByteVector =>
644655 pk
645656 case _: Unit =>
646657 tx.senderPublicKey
647658 case _ =>
648659 throw("Match error")
649660 }
650661 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
651662 }
652663

github/deemru/w8io/6500d08 
123.07 ms