tx · 4qQKw6gcYMdFU4Xy6QCWjJ4p4yitfybnhgBmhAQcH77q

3PEC6NWG5h1NjWpTsBq1b5RF7NN1UbFsoy9:  -0.02200000 Waves

2022.10.27 19:30 [3356451] smart account 3PEC6NWG5h1NjWpTsBq1b5RF7NN1UbFsoy9 > SELF 0.00000000 Waves

{ "type": 13, "id": "4qQKw6gcYMdFU4Xy6QCWjJ4p4yitfybnhgBmhAQcH77q", "fee": 2200000, "feeAssetId": null, "timestamp": 1666891723281, "version": 1, "sender": "3PEC6NWG5h1NjWpTsBq1b5RF7NN1UbFsoy9", "senderPublicKey": "CnEx6woaCe8kVcywJXVxsfdsGsEsCJuyzJVmaqc9htzj", "proofs": [ "2PkDV9wVCcQC43ThXAgSFqTAp97TpAfcYY4uAu3Z9cQTWCYRH1D78FBTeKdALtLDoSGKnhBNxkhzLunZLWY5Annx" ], "script": "base64:BgJNCAISBAoCAQQSBQoDCAEBEgUKAwgBARIDCgEIEgQKAggBEgUKAwgBCBIFCgMIAQgSAwoBARIDCgEBEgMKAQESAwoBARIDCgEBEgMKAQFyAAZFVUxFUjgA1onPgQEABU1VTFQ2AMCEPQAGTVVMVFg2CQC2AgEAwIQ9AAVNVUxUOACAwtcvAAZNVUxUWDgJALYCAQCAwtcvAAdNVUxUWDEwCQC2AgEAgMivoCUABk1VTFQxMgCAoJSljR0AB01VTFRYMTYJALYCAQCAgIT+pt7hEQAGTVVMVDE4CQC2AgEAgICQu7rWrfANAANTRVACAl9fABFERUZBVUxUU1dBUEZFRU4yVwCIJwARREVGQVVMVFNXQVBGRUVXMk4AoJwBAAtCUlBST1RFQ1RFRACgjQYAB1dBVkVTSUQJANkEAQIFV0FWRVMACURBWU1JTExJUwCAuJkpARJrZXlOZXV0cmlub0Fzc2V0SWQAAhFuZXV0cmlub19hc3NldF9pZAEOa2V5TnNidEFzc2V0SWQAAg1ib25kX2Fzc2V0X2lkAQ5rZXlTdXJmQXNzZXRJZAACDXN1cmZfYXNzZXRfaWQBEGtleUJhbGFuY2VMb2NrZWQAAg1iYWxhbmNlX2xvY2tfARVrZXlXYXZlc0xvY2tlZEJhbGFuY2UACQCsAgIJARBrZXlCYWxhbmNlTG9ja2VkAAIFd2F2ZXMBGGtleU5ldXRyaW5vTG9ja2VkQmFsYW5jZQAJAKwCAgkBEGtleUJhbGFuY2VMb2NrZWQAAghuZXV0cmlubwEVa2V5TWluV2F2ZXNTd2FwQW1vdW50AAIVbWluX3dhdmVzX3N3YXBfYW1vdW50ARhrZXlNaW5OZXV0cmlub1N3YXBBbW91bnQAAhhtaW5fbmV1dHJpbm9fc3dhcF9hbW91bnQBEmtleVdhdmVzT3V0RmVlUGFydAACFXdhdmVzT3V0X3N3YXBfZmVlUGFydAEVa2V5TmV1dHJpbm9PdXRGZWVQYXJ0AAIYbmV1dHJpbm9PdXRfc3dhcF9mZWVQYXJ0ARNrZXlTd2FwQW1vdW50QVBhcmFtAAIYJXMlc19fY29uZmlnX19zd2FwQVBhcmFtARNrZXlTd2FwQW1vdW50QlBhcmFtAAIYJXMlc19fY29uZmlnX19zd2FwQlBhcmFtARdrZXlVc2RuU3dhcEFtb3VudEFQYXJhbQACHCVzJXNfX2NvbmZpZ19fdXNkblN3YXBBUGFyYW0BF2tleVVzZG5Td2FwQW1vdW50QlBhcmFtAAIcJXMlc19fY29uZmlnX191c2RuU3dhcEJQYXJhbQETa2V5TnNidExvY2tDb250cmFjdAACFCVzX19uc2J0TG9ja0NvbnRyYWN0AQ9rZXlNYXRoQ29udHJhY3QAAhAlc19fbWF0aENvbnRyYWN0ARtrZXlCYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWwAAhtiYWxhbmNlX3dhdmVzX2xvY2tfaW50ZXJ2YWwBHmtleUJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbAACHmJhbGFuY2VfbmV1dHJpbm9fbG9ja19pbnRlcnZhbAEIa2V5UHJpY2UAAgVwcmljZQEWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawELdXNlckFkZHJlc3MJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgILcGFyYW1CeVVzZXIJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIFc3RhcnQFA25pbAUDU0VQAQtrZXlIYWxmTGlmZQACDCVzX19oYWxmTGlmZQEQa2V5TWluTG9ja0Ftb3VudAACESVzX19taW5Mb2NrQW1vdW50ARVrZXlNaW5XYXZlc0Zvck5zYnRCdXkAAhJtaW5fd2F2ZXNfbnNidF9idXkBDmtleU1pbk5zYnRTZWxsAAINbWluX25zYnRfc2VsbAEXa2V5U3RhdHNEZXBvc2l0QW10QnlEYXkBCXRpbWVzdGFtcAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgVzdGF0cwkAzAgCAg9kZXBvc2l0QW10QnlEYXkJAMwIAgkApAMBBQl0aW1lc3RhbXAFA25pbAUDU0VQAQx0b1N0YXJ0T2ZEYXkBCXRpbWVzdGFtcAkAaAIJAGkCBQl0aW1lc3RhbXAFCURBWU1JTExJUwUJREFZTUlMTElTAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAEMZ2V0SW50T3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDWdldEJvb2xPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJsIAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAEMZ2V0SW50T3JFbHNlAwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEMZ2V0U3RyT3JFbHNlAwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCdCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEWY29udmVydE5ldXRyaW5vVG9XYXZlcwIGYW1vdW50BXByaWNlCQBrAwUGYW1vdW50BQVNVUxUOAUFcHJpY2UBFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8CBmFtb3VudAVwcmljZQkAawMFBmFtb3VudAUFcHJpY2UFBU1VTFQ4AQlhc0FueUxpc3QBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQKdmFsQW55TGlzdAUHJG1hdGNoMAUKdmFsQW55TGlzdAkAAgECG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEFYXNJbnQBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACA0ludAQGdmFsSW50BQckbWF0Y2gwBQZ2YWxJbnQJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBCGFzU3RyaW5nAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEBnZhbFN0cgUHJG1hdGNoMAUGdmFsU3RyCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQxhc1R1cGxlMkludHMBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACCihJbnQsIEludCkEAXYFByRtYXRjaDAFAXYJAAIBAh1mYWlsIHRvIGNhc3QgaW50byBUdXBsZTIgaW50cwESYXNTd2FwUGFyYW1zU1RSVUNUAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAiMoSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50KQQGc3RydWN0BQckbWF0Y2gwBQZzdHJ1Y3QJAAIBAiJmYWlsIHRvIGNhc3QgaW50byBTd2FwUGFyYW1zU1RSVUNUARZhc1dpdGhkcmF3UmVzdWx0U1RSVUNUAQN2YWwEByRtYXRjaDAFA3ZhbAMDCQABAgUHJG1hdGNoMAIkKEludCwgVW5pdCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQpBgkAAQIFByRtYXRjaDACKihJbnQsIEJ5dGVWZWN0b3IsIEludCwgSW50LCBJbnQsIEludCwgSW50KQQGc3RydWN0BQckbWF0Y2gwBQZzdHJ1Y3QJAAIBAiBmYWlsIHRvIGNhc3QgaW50byBXaXRoZHJhd1Jlc3VsdAELdG9UaW1lc3RhbXABBXN0YXJ0AwkAZgIAAAUFc3RhcnQA////////////AQQHJG1hdGNoMAkA7QcBBQVzdGFydAMJAAECBQckbWF0Y2gwAglCbG9ja0luZm8EBWJsb2NrBQckbWF0Y2gwCAUFYmxvY2sJdGltZXN0YW1wAP///////////wEBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQZNVUxUMTgJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFBk1VTFQxOAAPbk1ldHJpY0lkeFByaWNlAAAAG25NZXRyaWNJZHhVc2RuTG9ja2VkQmFsYW5jZQABABxuTWV0cmljSWR4V2F2ZXNMb2NrZWRCYWxhbmNlAAIAEW5NZXRyaWNJZHhSZXNlcnZlAAMAF25NZXRyaWNJZHhSZXNlcnZlSW5Vc2RuAAQAFG5NZXRyaWNJZHhVc2RuU3VwcGx5AAUAEW5NZXRyaWNJZHhTdXJwbHVzAAYAGG5NZXRyaWNJZHhTdXJwbHVzUGVyY2VudAAHAAxuTWV0cmljSWR4QlIACAAUbk1ldHJpY0lkeE5zYnRTdXBwbHkACQAXbk1ldHJpY0lkeE1heE5zYnRTdXBwbHkACgAUbk1ldHJpY0lkeFN1cmZTdXBwbHkACwAZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAABABhJZHhDb250cm9sQ2ZnQXVjdGlvbkRhcHAAAgAUSWR4Q29udHJvbENmZ1JwZERhcHAAAwAVSWR4Q29udHJvbENmZ01hdGhEYXBwAAQAHElkeENvbnRyb2xDZmdMaXF1aWRhdGlvbkRhcHAABQAVSWR4Q29udHJvbENmZ1Jlc3REYXBwAAYAHUlkeENvbnRyb2xDZmdOb2RlUmVnaXN0cnlEYXBwAAcAHElkeENvbnRyb2xDZmdOc2J0U3Rha2luZ0RhcHAACAAZSWR4Q29udHJvbENmZ01lZGlhdG9yRGFwcAAJABxJZHhDb250cm9sQ2ZnU3VyZlN0YWtpbmdEYXBwAAoAIElkeENvbnRyb2xDZmdHbnNidENvbnRyb2xsZXJEYXBwAAsADGJGdW5jSWR4U3VyZgAAAA1iRnVuY0lkeFdhdmVzAAEADGJGdW5jSWR4VXNkbgACABRiRnVuY0lkeFJlc2VydmVTdGFydAADABNiRnVuY0lkeFN1cHBseVN0YXJ0AAQAD2JGdW5jSWR4QlJTdGFydAAFABJiRnVuY0lkeFJlc2VydmVFbmQABgARYkZ1bmNJZHhTdXBwbHlFbmQABwANYkZ1bmNJZHhCUkVuZAAIAAxiRnVuY0lkeFJlc3QACQASYkZ1bmNJZHhXYXZlc1ByaWNlAAoBEWtleUNvbnRyb2xBZGRyZXNzAAIcJXMlc19fY29uZmlnX19jb250cm9sQWRkcmVzcwENa2V5Q29udHJvbENmZwACESVzX19jb250cm9sQ29uZmlnARRyZWFkQ29udHJvbENmZ09yRmFpbAEHY29udHJvbAkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUHY29udHJvbAkBDWtleUNvbnRyb2xDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIKY29udHJvbENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFCmNvbnRyb2xDZmcFA2lkeAkArAICAi1Db250cm9sIGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AA9jb250cm9sQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBEWtleUNvbnRyb2xBZGRyZXNzAAIjM1A1QmZkNThQUGZOdkJNMkh5OFFmYmNEcU1lTnR6ZzdLZlAACmNvbnRyb2xDZmcJARRyZWFkQ29udHJvbENmZ09yRmFpbAEFD2NvbnRyb2xDb250cmFjdAAMbWF0aENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUVSWR4Q29udHJvbENmZ01hdGhEYXBwABBuZXV0cmlub0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAPYXVjdGlvbkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwABNsaXF1aWRhdGlvbkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUcSWR4Q29udHJvbENmZ0xpcXVpZGF0aW9uRGFwcAALcnBkQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRRJZHhDb250cm9sQ2ZnUnBkRGFwcAATbnNidFN0YWtpbmdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFHElkeENvbnRyb2xDZmdOc2J0U3Rha2luZ0RhcHAAE3N1cmZTdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRxJZHhDb250cm9sQ2ZnU3VyZlN0YWtpbmdEYXBwABdnbnNidENvbnRyb2xsZXJDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFIElkeENvbnRyb2xDZmdHbnNidENvbnRyb2xsZXJEYXBwABVuZXV0cmlub0Fzc2V0SWRTdHJpbmcJAQ9nZXRTdHJpbmdPckZhaWwCBRBuZXV0cmlub0NvbnRyYWN0CQESa2V5TmV1dHJpbm9Bc3NldElkAAAPbmV1dHJpbm9Bc3NldElkCQDZBAEFFW5ldXRyaW5vQXNzZXRJZFN0cmluZwAObnNidEFzc2V0SWRTdHIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFEG5ldXRyaW5vQ29udHJhY3QJAQ5rZXlOc2J0QXNzZXRJZAAAC25zYnRBc3NldElkCQDZBAEFDm5zYnRBc3NldElkU3RyAA5zdXJmQXNzZXRJZFN0cgkBEUBleHRyTmF0aXZlKDEwNTMpAgUPYXVjdGlvbkNvbnRyYWN0CQEOa2V5U3VyZkFzc2V0SWQAAAtzdXJmQXNzZXRJZAkA2QQBBQ5zdXJmQXNzZXRJZFN0cgEUcmVhZFVzZG5JbmNvbWVGb3JEYXkDCnN0YWtpbmdBY2MTc3RhcnRPZkRheVRpbWVzdGFtcA9uZXV0cmlub01ldHJpY3MEC2FtdEJ5RGF5S0VZCQEXa2V5U3RhdHNEZXBvc2l0QW10QnlEYXkBBRNzdGFydE9mRGF5VGltZXN0YW1wBAlpbmNvbWVTdHIJAQxnZXRTdHJPckVsc2UDBQpzdGFraW5nQWNjBQthbXRCeURheUtFWQIKJXMlc19fMF9fMAQLaW5jb21lQXJyYXkJALUJAgUJaW5jb21lU3RyBQNTRVAECHdhdmVzQW10CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULaW5jb21lQXJyYXkAAQQHdXNkbkFtdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2luY29tZUFycmF5AAIEDGN1cnJlbnRQcmljZQkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFD25NZXRyaWNJZHhQcmljZQQOd2F2ZXNBc1VzZG5BbXQJAGsDBQh3YXZlc0FtdAUMY3VycmVudFByaWNlBQVNVUxUOAkAZAIFDndhdmVzQXNVc2RuQW10BQd1c2RuQW10ARdjYWxjVXNkbkluY29tZUZvclBlcmlvZAIKc3Rha2luZ0FjYwRkYXlzBA9uZXV0cmlub01ldHJpY3MJAQlhc0FueUxpc3QBCQD8BwQFDG1hdGhDb250cmFjdAIaY2FsY05ldXRpbm9NZXRyaWNzUkVBRE9OTFkFA25pbAUDbmlsBA5jdXJyU3RhcnRPZkRheQkBDHRvU3RhcnRPZkRheQEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBA5zdGFydFRpbWVzdGFtcAkAZQIFDmN1cnJTdGFydE9mRGF5CQBoAgUJREFZTUlMTElTCQBkAgUEZGF5cwABBAxlbmRUaW1lc3RhbXAJAGUCBQ5jdXJyU3RhcnRPZkRheQUJREFZTUlMTElTBAxzdGFydFVzZG5BbXQJARRyZWFkVXNkbkluY29tZUZvckRheQMFE3N1cmZTdGFraW5nQ29udHJhY3QFDnN0YXJ0VGltZXN0YW1wBQ9uZXV0cmlub01ldHJpY3MECmVuZFVzZG5BbXQJARRyZWFkVXNkbkluY29tZUZvckRheQMFE3N1cmZTdGFraW5nQ29udHJhY3QFDGVuZFRpbWVzdGFtcAUPbmV1dHJpbm9NZXRyaWNzCQBlAgUKZW5kVXNkbkFtdAUMc3RhcnRVc2RuQW10AQdjYWxjQXByBApzdGFraW5nQWNjDHBlcmlvZEluRGF5cw9pbmNvbWVGb3JQZXJpb2QZc3Rha2luZ0Fzc2V0UHJpY2VUb1VzZG5YNgQLdG90YWxTdGFrZWQJAQxnZXRJbnRPckVsc2UDBRNzdXJmU3Rha2luZ0NvbnRyYWN0Ah4lcyVzX19zdGF0c19fYWN0aXZlVG90YWxMb2NrZWQAAQQRdG90YWxTdGFrZWRJblVzZG4JAGsDBQt0b3RhbFN0YWtlZAUZc3Rha2luZ0Fzc2V0UHJpY2VUb1VzZG5YNgUFTVVMVDYJAGsDCQBoAgUPaW5jb21lRm9yUGVyaW9kBQVNVUxUNgDtAgkAaAIFEXRvdGFsU3Rha2VkSW5Vc2RuBQxwZXJpb2RJbkRheXMNAWkBGHJldmVyc2VTd2FwTGltaXRSRUFET05MWQIDbGltC2lzV2F2ZXNTd2FwBAJCUgkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAUMbk1ldHJpY0lkeEJSBAVnTnNidAMJAGcCAAAFA2xpbQAABAhhUGFyYW1YOAkAtgIBCQEMZ2V0SW50T3JGYWlsAgUMbWF0aENvbnRyYWN0AwULaXNXYXZlc1N3YXAJARNrZXlTd2FwQW1vdW50QVBhcmFtAAkBF2tleVVzZG5Td2FwQW1vdW50QVBhcmFtAAQJYlBhcmFtWDE2CQC2AgEJAQxnZXRJbnRPckZhaWwCBQxtYXRoQ29udHJhY3QDBQtpc1dhdmVzU3dhcAkBE2tleVN3YXBBbW91bnRCUGFyYW0ACQEXa2V5VXNkblN3YXBBbW91bnRCUGFyYW0ABAlsaW1EaXZBWDgDBQtpc1dhdmVzU3dhcAkAvAIDCQC2AgEFA2xpbQUHTVVMVFgxMAUIYVBhcmFtWDgJALwCAwkAvAIDCQC2AgEFA2xpbQUHTVVMVFgxMAUIYVBhcmFtWDgFBk1VTFRYNgkAtgIBBQJCUgQHcmV2QlgxNgkAvAIDBQdNVUxUWDE2BQdNVUxUWDE2BQliUGFyYW1YMTYJAKADAQkAdgYFCWxpbURpdkFYOAAIBQdyZXZCWDE2ABAABgUHQ0VJTElORwkAlAoCBQNuaWwFBWdOc2J0AWkBEWduc2J0SW5mb0lOVEVSTkFMAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwQRdXNlckFkZHJlc3NPclRoaXMDCQECIT0CBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkCAAkBEUBleHRyTmF0aXZlKDEwNjIpAQUVdXNlckFkZHJlc3NTdHJPckVtcHR5BQR0aGlzBAxjdXJyZW50UHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2NvbnRyb2xDb250cmFjdAkBCGtleVByaWNlAAQRZ25zYnRGcm9tTnNidERpZmYFG2FkZGl0aW9uYWxOc2J0VG9TdGFrZU9yWmVybwQRZ25zYnRGcm9tU3VyZkRpZmYJAQVhc0ludAEJAPwHBAUTc3VyZlN0YWtpbmdDb250cmFjdAIYZ25zYnRGcm9tU3VyZlNZU1JFQURPTkxZCQDMCAIFG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwUDbmlsBQNuaWwECWdOc2J0RGlmZgkAZAIFEWduc2J0RnJvbU5zYnREaWZmBRFnbnNidEZyb21TdXJmRGlmZgQPc3dhcFBhcmFtc1R1cGxlCQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/AcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5CQDMCAIAAAUDbmlsBQNuaWwEDmJsY2tzMkxtdFJlc2V0CAUPc3dhcFBhcmFtc1R1cGxlAl8zBAhnbnNidEFtdAgFD3N3YXBQYXJhbXNUdXBsZQJfNAQNZ25zYnRBbXRUb3RhbAgFD3N3YXBQYXJhbXNUdXBsZQJfNQQNbGltaXRNYXhXYXZlcwgFD3N3YXBQYXJhbXNUdXBsZQJfNgQMbGltaXRNYXhVc2RuCAUPc3dhcFBhcmFtc1R1cGxlAl83BBJzd2FwUGFyYW1zVHVwbGVORVcJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD8BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgUJZ05zYnREaWZmBQNuaWwFA25pbAQRYmxja3MyTG10UmVzZXRORVcIBRJzd2FwUGFyYW1zVHVwbGVORVcCXzMEC2duc2J0QW10TkVXCAUSc3dhcFBhcmFtc1R1cGxlTkVXAl80BBBnbnNidEFtdFRvdGFsTkVXCAUSc3dhcFBhcmFtc1R1cGxlTkVXAl81BBBsaW1pdE1heFdhdmVzTkVXCAUSc3dhcFBhcmFtc1R1cGxlTkVXAl82BA9saW1pdE1heFVzZG5ORVcIBRJzd2FwUGFyYW1zVHVwbGVORVcCXzcEC25zYnRCYWxhbmNlAwkBAiE9AgUVdXNlckFkZHJlc3NTdHJPckVtcHR5AgAJAPAHAgURdXNlckFkZHJlc3NPclRoaXMFC25zYnRBc3NldElkAAAEC3N1cmZCYWxhbmNlAwkBAiE9AgUVdXNlckFkZHJlc3NTdHJPckVtcHR5AgAJAPAHAgURdXNlckFkZHJlc3NPclRoaXMFC3N1cmZBc3NldElkAAAED25zYnRCYWxhbmNlRGlmZgMJAGcCBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8AAAUbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvBBFuc2J0VW5zdGFraW5nRGF0YQkBCWFzQW55TGlzdAEJAPwHBAUTbnNidFN0YWtpbmdDb250cmFjdAIYbnNidFVuc3Rha2luZ1NZU1JFQURPTkxZCQDMCAIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQkAzAgCCQBoAgD///////////8BBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8FA25pbAUDbmlsBBFuc2J0UmVjZWl2ZUFtb3VudAkBBWFzSW50AQkAkQMCBRFuc2J0VW5zdGFraW5nRGF0YQACBAZyZXN1bHQJAQEtAQURbnNidFJlY2VpdmVBbW91bnQFBnJlc3VsdAQObnNidEJhbGFuY2VOZXcJAGUCBQtuc2J0QmFsYW5jZQUPbnNidEJhbGFuY2VEaWZmBA5zdXJmQmFsYW5jZU5ldwkAZQIFC3N1cmZCYWxhbmNlBRthZGRpdGlvbmFsU3VyZlRvU3Rha2VPclplcm8ECWduc2J0RGF0YQkBCWFzQW55TGlzdAEJAPwHBAUXZ25zYnRDb250cm9sbGVyQ29udHJhY3QCFGduc2J0SW5mb1NZU1JFQURPTkxZCQDMCAIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQkAzAgCBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8JAMwIAgUbYWRkaXRpb25hbFN1cmZUb1N0YWtlT3JaZXJvBQNuaWwFA25pbAQJZ25zYnRVc2VyCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAABApnbnNidFRvdGFsCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQABBAhuc2J0RGF0YQkBCWFzQW55TGlzdAEJAJEDAgUJZ25zYnREYXRhAAIECHN1cmZEYXRhCQEJYXNBbnlMaXN0AQkAkQMCBQlnbnNidERhdGEAAwQRdnBFZmZlY3RpdmVIZWlnaHQJAQVhc0ludAEJAJEDAgUJZ25zYnREYXRhAAQEFHZwRWZmZWN0aXZlSGVpZ2h0TkVXCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAFBBBnbnNidEFtdEZyb21Oc2J0CQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAIEEGduc2J0QW10RnJvbVN1cmYJAQVhc0ludAEJAJEDAgUIc3VyZkRhdGEAAgQTZ25zYnRBbXRGcm9tTnNidE5FVwkAZAIFEGduc2J0QW10RnJvbU5zYnQFEWduc2J0RnJvbU5zYnREaWZmBBNnbnNidEFtdEZyb21TdXJmTkVXCQBkAgUQZ25zYnRBbXRGcm9tU3VyZgURZ25zYnRGcm9tU3VyZkRpZmYEEmduc2J0RnJvbU5zYnRUb3RhbAkBBWFzSW50AQkAkQMCBQhuc2J0RGF0YQADBBJnbnNidEZyb21TdXJmVG90YWwJAQVhc0ludAEJAJEDAgUIc3VyZkRhdGEAAwQYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsAAAEGGduc2J0RnJvbVN1cmZGcm96ZW5Ub3RhbAUSZ25zYnRGcm9tU3VyZlRvdGFsBBVnbnNidEZyb21Oc2J0VG90YWxORVcJAGQCBRJnbnNidEZyb21Oc2J0VG90YWwFEWduc2J0RnJvbU5zYnREaWZmBBVnbnNidEZyb21TdXJmVG90YWxORVcJAGQCBRJnbnNidEZyb21TdXJmVG90YWwFEWduc2J0RnJvbVN1cmZEaWZmBBtnbnNidEZyb21TdXJmRnJvemVuVG90YWxORVcFFWduc2J0RnJvbVN1cmZUb3RhbE5FVwQLdm90aW5nUG93ZXIJAGsDBRBnbnNidEFtdEZyb21Oc2J0BQVNVUxUOAkAZAIFEmduc2J0RnJvbU5zYnRUb3RhbAUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBA52b3RpbmdQb3dlck5ldwkAawMFE2duc2J0QW10RnJvbU5zYnRORVcFBU1VTFQ4CQBkAgUVZ25zYnRGcm9tTnNidFRvdGFsTkVXBRhnbnNidEZyb21TdXJmQWN0aXZlVG90YWwEDnZvdGluZ1Bvd2VyTWF4CQBrAwkAZAIFEGduc2J0QW10RnJvbU5zYnQFEGduc2J0QW10RnJvbVN1cmYFBU1VTFQ4CQBkAgkAZAIFEmduc2J0RnJvbU5zYnRUb3RhbAUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBRhnbnNidEZyb21TdXJmRnJvemVuVG90YWwEEXZvdGluZ1Bvd2VyTWF4TmV3CQBrAwkAZAIFE2duc2J0QW10RnJvbU5zYnRORVcFE2duc2J0QW10RnJvbVN1cmZORVcFBU1VTFQ4CQBkAgkAZAIFFWduc2J0RnJvbU5zYnRUb3RhbE5FVwUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBRtnbnNidEZyb21TdXJmRnJvemVuVG90YWxORVcEDnZvdGluZ1Bvd2VyRXRhAwkAAAIFEXZwRWZmZWN0aXZlSGVpZ2h0AAAFBmhlaWdodAURdnBFZmZlY3RpdmVIZWlnaHQEEXZvdGluZ1Bvd2VyRXRhTmV3AwkAAAIFFHZwRWZmZWN0aXZlSGVpZ2h0TkVXAAAFBmhlaWdodAUUdnBFZmZlY3RpdmVIZWlnaHRORVcJAJQKAgUDbmlsCQDMCAIAAAkAzAgCBQtuc2J0QmFsYW5jZQkAzAgCBQtzdXJmQmFsYW5jZQkAzAgCBQ5uc2J0QmFsYW5jZU5ldwkAzAgCBQ5zdXJmQmFsYW5jZU5ldwkAzAgCBRBnbnNidEFtdEZyb21Oc2J0CQDMCAIFEGduc2J0QW10RnJvbVN1cmYJAMwIAgUTZ25zYnRBbXRGcm9tTnNidE5FVwkAzAgCBRNnbnNidEFtdEZyb21TdXJmTkVXCQDMCAIFEmduc2J0RnJvbU5zYnRUb3RhbAkAzAgCBRJnbnNidEZyb21TdXJmVG90YWwJAMwIAgUVZ25zYnRGcm9tTnNidFRvdGFsTkVXCQDMCAIFFWduc2J0RnJvbVN1cmZUb3RhbE5FVwkAzAgCBQxsaW1pdE1heFVzZG4JAMwIAgUNbGltaXRNYXhXYXZlcwkAzAgCBQ9saW1pdE1heFVzZG5ORVcJAMwIAgUQbGltaXRNYXhXYXZlc05FVwkAzAgCBQ5ibGNrczJMbXRSZXNldAkAzAgCBRFibGNrczJMbXRSZXNldE5FVwkAzAgCBQt2b3RpbmdQb3dlcgkAzAgCBQ52b3RpbmdQb3dlck5ldwkAzAgCBQ52b3RpbmdQb3dlck1heAkAzAgCBRF2b3RpbmdQb3dlck1heE5ldwkAzAgCBQ52b3RpbmdQb3dlckV0YQkAzAgCBRF2b3RpbmdQb3dlckV0YU5ldwUDbmlsAWkBEWduc2J0SW5mb1JFQURPTkxZAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwQNZ25zYnRJbmZvREFUQQkBCWFzQW55TGlzdAEJAPwHBAUEdGhpcwIRZ25zYnRJbmZvSU5URVJOQUwJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5CQDMCAIFG2FkZGl0aW9uYWxOc2J0VG9TdGFrZU9yWmVybwkAzAgCBRthZGRpdGlvbmFsU3VyZlRvU3Rha2VPclplcm8FA25pbAUDbmlsCQCUCgIFA25pbAkAuQkCCQDMCAICMCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQABCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAIJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAAwkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAECQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAUJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEABgkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAHCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAgJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEACQkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAKCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAsJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEADAkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQANCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAA4JAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEADwkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAQCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABEJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAEgkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQATCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABQJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAFQkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAWCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABcJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAGAUDbmlsBQNTRVABaQEScmV3YXJkSW5mb1JFQURPTkxZARV1c2VyQWRkcmVzc1N0ck9yRW1wdHkEC3Jld2FyZHNEYXRhCQEJYXNBbnlMaXN0AQkA/AcEBRdnbnNidENvbnRyb2xsZXJDb250cmFjdAIXZ25zYnRSZXdhcmRzU1lTUkVBRE9OTFkJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5BQNuaWwFA25pbAQLdXNkblJld2FyZHMJAQhhc1N0cmluZwEJAPwHBAULcnBkQ29udHJhY3QCGHVuY2xhaW1lZFJld2FyZHNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkFA25pbAUDbmlsCQCUCgIFA25pbAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCCQEIYXNTdHJpbmcBCQCRAwIFC3Jld2FyZHNEYXRhAAAJAMwIAgkBCGFzU3RyaW5nAQkAkQMCBQtyZXdhcmRzRGF0YQABCQDMCAIFC3VzZG5SZXdhcmRzBQNuaWwFA1NFUAFpARFtZXJnZU5zYnRSRUFET05MWQIUdXNlckFkZHJlc3NNYW5kYXRvcnkJbmV3QW1vdW50BAhuc2J0RGF0YQkBCWFzQW55TGlzdAEJAPwHBAUTbnNidFN0YWtpbmdDb250cmFjdAIWbnNidFN0YWtpbmdTWVNSRUFET05MWQkAzAgCBRR1c2VyQWRkcmVzc01hbmRhdG9yeQkAzAgCBQluZXdBbW91bnQFA25pbAUDbmlsBAdhbW91bnQwCQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAAEC3N0YXJ0SGVpZ2h0AwkAZwIAAAUHYW1vdW50MAD///////////8BCQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAIEDnN0YXJ0VGltZXN0YW1wCQELdG9UaW1lc3RhbXABBQtzdGFydEhlaWdodAQOc3RhcnRIZWlnaHROZXcDCQBnAgAABQluZXdBbW91bnQFC3N0YXJ0SGVpZ2h0BAhoYWxmTGlmZQkBDGdldEludE9yRmFpbAIFE25zYnRTdGFraW5nQ29udHJhY3QJAQtrZXlIYWxmTGlmZQAJAQVhc0ludAEJAPwHBAUMbWF0aENvbnRyYWN0AhNtZXJnZVN0YWtlc1JFQURPTkxZCQDMCAIFB2Ftb3VudDAJAMwIAgULc3RhcnRIZWlnaHQJAMwIAgUJbmV3QW1vdW50CQDMCAIFBmhlaWdodAkAzAgCBQhoYWxmTGlmZQUDbmlsBQNuaWwEEXN0YXJ0VGltZXN0YW1wTmV3CQELdG9UaW1lc3RhbXABBQ5zdGFydEhlaWdodE5ldwkAlAoCBQNuaWwJALkJAgkAzAgCAgglZCVkJWQlZAkAzAgCCQCkAwEFC3N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUOc3RhcnRUaW1lc3RhbXAJAMwIAgkApAMBBQ5zdGFydEhlaWdodE5ldwkAzAgCCQCkAwEFEXN0YXJ0VGltZXN0YW1wTmV3BQNuaWwFA1NFUAFpARtzd2FwTGltaXRDYWxjdWxhdG9yUkVBRE9OTFkDEXVzZXJBZGRyZXNzU3RyT3B0C2xpbWl0V2FudGVkCmFzc2V0SWRTdHIEDGdOc2J0Q3VycmVudAMJAAACBRF1c2VyQWRkcmVzc1N0ck9wdAIAAAAJAQVhc0ludAEICQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/AcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgURdXNlckFkZHJlc3NTdHJPcHQJAMwIAgAABQNuaWwFA25pbAJfNAQPbGltaXRXYW50ZWRVc2RuAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTCQEWY29udmVydFdhdmVzVG9OZXV0cmlubwIFC2xpbWl0V2FudGVkCQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9jb250cm9sQ29udHJhY3QJAQhrZXlQcmljZQAFC2xpbWl0V2FudGVkBAtnTnNidE5lZWRlZAkBBWFzSW50AQkA/AcEBQR0aGlzAhhyZXZlcnNlU3dhcExpbWl0UkVBRE9OTFkJAMwIAgUPbGltaXRXYW50ZWRVc2RuCQDMCAIJAAACBQphc3NldElkU3RyAgVXQVZFUwUDbmlsBQNuaWwECmdOc2J0RGVsdGEJAGUCBQtnTnNidE5lZWRlZAUMZ05zYnRDdXJyZW50CQCUCgIFA25pbAkAuQkCCQDMCAICBCVzJXMJAMwIAgkApAMBBQxnTnNidEN1cnJlbnQJAMwIAgkApAMBBQpnTnNidERlbHRhBQNuaWwFA1NFUAFpARBzd2FwSW5mb1JFQURPTkxZAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkGYW1vdW50CmFzc2V0SWRTdHIED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEBXByaWNlCQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUPbk1ldHJpY0lkeFByaWNlBA9zd2FwUGFyYW1zVHVwbGUJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD8BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgAABQNuaWwFA25pbAQOYmxja3MyTG10UmVzZXQIBQ9zd2FwUGFyYW1zVHVwbGUCXzMEDWxpbWl0TWF4V2F2ZXMIBQ9zd2FwUGFyYW1zVHVwbGUCXzYEDGxpbWl0TWF4VXNkbggFD3N3YXBQYXJhbXNUdXBsZQJfNwQHYXNzZXRJZAkA2QQBBQphc3NldElkU3RyBAhzd2FwVHlwZQMJAAACBQdhc3NldElkBQdXQVZFU0lEAgV3YXZlcwMJAAACBQdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQCCG5ldXRyaW5vCQACAQkArAICAhNDYW4ndCBzd2FwIGFzc2V0SWQ9BQphc3NldElkU3RyBA13aXRoZHJhd1R1cGxlCQEWYXNXaXRoZHJhd1Jlc3VsdFNUUlVDVAEJAPwHBAUQbmV1dHJpbm9Db250cmFjdAIdY2FsY1dpdGhkcmF3UmVzdWx0U1lTUkVBRE9OTFkJAMwIAgUIc3dhcFR5cGUJAMwIAgUGYW1vdW50CQDMCAIFBXByaWNlBQNuaWwFA25pbAQMb3V0TmV0QW1vdW50CAUNd2l0aGRyYXdUdXBsZQJfMQQKb3V0QXNzZXRJZAgFDXdpdGhkcmF3VHVwbGUCXzIECm91dFN1cmZBbXQIBQ13aXRoZHJhd1R1cGxlAl8zBA9pbkFtdFRvU3VyZlBhcnQIBQ13aXRoZHJhd1R1cGxlAl80BAp1bmxlYXNlQW10CAUNd2l0aGRyYXdUdXBsZQJfNQQMb3V0RmVlQW1vdW50CAUNd2l0aGRyYXdUdXBsZQJfNgQLb3V0QW10R3Jvc3MIBQ13aXRoZHJhd1R1cGxlAl83CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQxvdXROZXRBbW91bnQJAMwIAgkApAMBBQpvdXRTdXJmQW10CQDMCAIJAKQDAQUMb3V0RmVlQW1vdW50CQDMCAIJAKQDAQUFcHJpY2UJAMwIAgkApAMBBQ5ibGNrczJMbXRSZXNldAkAzAgCCQCkAwEFDWxpbWl0TWF4V2F2ZXMJAMwIAgkApAMBBQxsaW1pdE1heFVzZG4JAMwIAgkApAMBBQ9pbkFtdFRvU3VyZlBhcnQFA25pbAUDU0VQAWkBFnVzZG5TdGFraW5nQXByUkVBRE9OTFkBBGRheXMJAJQKAgUDbmlsAgklZF9fNjAwMDABaQEWc3VyZlN0YWtpbmdBcHJSRUFET05MWQEEZGF5cwkAlAoCBQNuaWwCCSVkX183MDAwMAFpARZuc2J0U3Rha2luZ0FwclJFQURPTkxZAQRkYXlzCQCUCgIFA25pbAIJJWRfXzkwMDAwAWkBGnVzZG5TdGFraW5nQXByVGVzdFJFQURPTkxZAQRkYXlzBAd0bXBEYXlzAAEED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEDGN1cnJlbnRQcmljZQkBBWFzSW50AQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFD25NZXRyaWNJZHhQcmljZQQLd2F2ZXNJbmNvbWUJAGgCAPAuBQVNVUxUOAQPaW5jb21lRm9yUGVyaW9kCQBrAwULd2F2ZXNJbmNvbWUFDGN1cnJlbnRQcmljZQUFTVVMVDgEA2FwcgkBB2NhbGNBcHIEBQtycGRDb250cmFjdAUHdG1wRGF5cwUPaW5jb21lRm9yUGVyaW9kBQVNVUxUNgkAlAoCBQNuaWwJAKwCAgIEJWRfXwkApAMBBQNhcHIBaQEac3VyZlN0YWtpbmdBcHJUZXN0UkVBRE9OTFkBBGRheXMEB3RtcERheXMAAwQPaW5jb21lRm9yUGVyaW9kCQEXY2FsY1VzZG5JbmNvbWVGb3JQZXJpb2QCBRNzdXJmU3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBBFzdXJmUHJpY2VUb1VzZG5YNgCAowUEA2FwcgkBB2NhbGNBcHIEBRNzdXJmU3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBQ9pbmNvbWVGb3JQZXJpb2QFEXN1cmZQcmljZVRvVXNkblg2CQCUCgIFA25pbAkArAICAgQlZF9fCQCkAwEFA2FwcgFpARpuc2J0U3Rha2luZ0FwclRlc3RSRUFET05MWQEEZGF5cwQHdG1wRGF5cwADBBFuc2J0UHJpY2VUb1VzZG5YNgCApOgDBA9pbmNvbWVGb3JQZXJpb2QJARdjYWxjVXNkbkluY29tZUZvclBlcmlvZAIFE25zYnRTdGFraW5nQ29udHJhY3QFB3RtcERheXMEA2FwcgkBB2NhbGNBcHIEBRNuc2J0U3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBQ9pbmNvbWVGb3JQZXJpb2QFEW5zYnRQcmljZVRvVXNkblg2CQCUCgIFA25pbAkArAICAgQlZF9fCQCkAwEFA2FwcgAq3r5o", "chainId": 87, "height": 3356451, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: AiNCMojdKn3TwPP5899VtjRScPYLapaFXEzfbSp48dAZ Next: 2ydaG6f18zy2BHCq26Ury8P1L31WEr9xGarh7nDB14ba Diff:
OldNewDifferences
2828 let BRPROTECTED = 100000
2929
3030 let WAVESID = fromBase58String("WAVES")
31+
32+let DAYMILLIS = 86400000
3133
3234 func keyNeutrinoAssetId () = "neutrino_asset_id"
3335
101103 func keyMinNsbtSell () = "min_nsbt_sell"
102104
103105
106+func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], SEP)
107+
108+
109+func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
110+
111+
104112 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
105113
106114
108116
109117
110118 func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
119+
120+
121+func getIntOrElse (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
122+
123+
124+func getStrOrElse (address,key,defaultVal) = valueOrElse(getString(address, key), defaultVal)
111125
112126
113127 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
291305 let surfAssetIdStr = getStringValue(auctionContract, keySurfAssetId())
292306
293307 let surfAssetId = fromBase58String(surfAssetIdStr)
308+
309+func readUsdnIncomeForDay (stakingAcc,startOfDayTimestamp,neutrinoMetrics) = {
310+ let amtByDayKEY = keyStatsDepositAmtByDay(startOfDayTimestamp)
311+ let incomeStr = getStrOrElse(stakingAcc, amtByDayKEY, "%s%s__0__0")
312+ let incomeArray = split(incomeStr, SEP)
313+ let wavesAmt = parseIntValue(incomeArray[1])
314+ let usdnAmt = parseIntValue(incomeArray[2])
315+ let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
316+ let wavesAsUsdnAmt = fraction(wavesAmt, currentPrice, MULT8)
317+ (wavesAsUsdnAmt + usdnAmt)
318+ }
319+
320+
321+func calcUsdnIncomeForPeriod (stakingAcc,days) = {
322+ let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
323+ let currStartOfDay = toStartOfDay(lastBlock.timestamp)
324+ let startTimestamp = (currStartOfDay - (DAYMILLIS * (days + 1)))
325+ let endTimestamp = (currStartOfDay - DAYMILLIS)
326+ let startUsdnAmt = readUsdnIncomeForDay(surfStakingContract, startTimestamp, neutrinoMetrics)
327+ let endUsdnAmt = readUsdnIncomeForDay(surfStakingContract, endTimestamp, neutrinoMetrics)
328+ (endUsdnAmt - startUsdnAmt)
329+ }
330+
331+
332+func calcApr (stakingAcc,periodInDays,incomeForPeriod,stakingAssetPriceToUsdnX6) = {
333+ let totalStaked = getIntOrElse(surfStakingContract, "%s%s__stats__activeTotalLocked", 1)
334+ let totalStakedInUsdn = fraction(totalStaked, stakingAssetPriceToUsdnX6, MULT6)
335+ fraction((incomeForPeriod * MULT6), 365, (totalStakedInUsdn * periodInDays))
336+ }
337+
294338
295339 @Callable(i)
296340 func reverseSwapLimitREADONLY (lim,isWavesSwap) = {
478522 func nsbtStakingAprREADONLY (days) = $Tuple2(nil, "%d__90000")
479523
480524
525+
526+@Callable(i)
527+func usdnStakingAprTestREADONLY (days) = {
528+ let tmpDays = 1
529+ let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
530+ let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
531+ let wavesIncome = (6000 * MULT8)
532+ let incomeForPeriod = fraction(wavesIncome, currentPrice, MULT8)
533+ let apr = calcApr(rpdContract, tmpDays, incomeForPeriod, MULT6)
534+ $Tuple2(nil, ("%d__" + toString(apr)))
535+ }
536+
537+
538+
539+@Callable(i)
540+func surfStakingAprTestREADONLY (days) = {
541+ let tmpDays = 3
542+ let incomeForPeriod = calcUsdnIncomeForPeriod(surfStakingContract, tmpDays)
543+ let surfPriceToUsdnX6 = 86400
544+ let apr = calcApr(surfStakingContract, tmpDays, incomeForPeriod, surfPriceToUsdnX6)
545+ $Tuple2(nil, ("%d__" + toString(apr)))
546+ }
547+
548+
549+
550+@Callable(i)
551+func nsbtStakingAprTestREADONLY (days) = {
552+ let tmpDays = 3
553+ let nsbtPriceToUsdnX6 = 8000000
554+ let incomeForPeriod = calcUsdnIncomeForPeriod(nsbtStakingContract, tmpDays)
555+ let apr = calcApr(nsbtStakingContract, tmpDays, incomeForPeriod, nsbtPriceToUsdnX6)
556+ $Tuple2(nil, ("%d__" + toString(apr)))
557+ }
558+
559+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let EULER8 = 271828182
55
66 let MULT6 = 1000000
77
88 let MULTX6 = toBigInt(1000000)
99
1010 let MULT8 = 100000000
1111
1212 let MULTX8 = toBigInt(100000000)
1313
1414 let MULTX10 = toBigInt(10000000000)
1515
1616 let MULT12 = 1000000000000
1717
1818 let MULTX16 = toBigInt(10000000000000000)
1919
2020 let MULT18 = toBigInt(1000000000000000000)
2121
2222 let SEP = "__"
2323
2424 let DEFAULTSWAPFEEN2W = 5000
2525
2626 let DEFAULTSWAPFEEW2N = 20000
2727
2828 let BRPROTECTED = 100000
2929
3030 let WAVESID = fromBase58String("WAVES")
31+
32+let DAYMILLIS = 86400000
3133
3234 func keyNeutrinoAssetId () = "neutrino_asset_id"
3335
3436
3537 func keyNsbtAssetId () = "bond_asset_id"
3638
3739
3840 func keySurfAssetId () = "surf_asset_id"
3941
4042
4143 func keyBalanceLocked () = "balance_lock_"
4244
4345
4446 func keyWavesLockedBalance () = (keyBalanceLocked() + "waves")
4547
4648
4749 func keyNeutrinoLockedBalance () = (keyBalanceLocked() + "neutrino")
4850
4951
5052 func keyMinWavesSwapAmount () = "min_waves_swap_amount"
5153
5254
5355 func keyMinNeutrinoSwapAmount () = "min_neutrino_swap_amount"
5456
5557
5658 func keyWavesOutFeePart () = "wavesOut_swap_feePart"
5759
5860
5961 func keyNeutrinoOutFeePart () = "neutrinoOut_swap_feePart"
6062
6163
6264 func keySwapAmountAParam () = "%s%s__config__swapAParam"
6365
6466
6567 func keySwapAmountBParam () = "%s%s__config__swapBParam"
6668
6769
6870 func keyUsdnSwapAmountAParam () = "%s%s__config__usdnSwapAParam"
6971
7072
7173 func keyUsdnSwapAmountBParam () = "%s%s__config__usdnSwapBParam"
7274
7375
7476 func keyNsbtLockContract () = "%s__nsbtLockContract"
7577
7678
7779 func keyMathContract () = "%s__mathContract"
7880
7981
8082 func keyBalanceWavesLockInterval () = "balance_waves_lock_interval"
8183
8284
8385 func keyBalanceNeutrinoLockInterval () = "balance_neutrino_lock_interval"
8486
8587
8688 func keyPrice () = "price"
8789
8890
8991 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
9092
9193
9294 func keyHalfLife () = "%s__halfLife"
9395
9496
9597 func keyMinLockAmount () = "%s__minLockAmount"
9698
9799
98100 func keyMinWavesForNsbtBuy () = "min_waves_nsbt_buy"
99101
100102
101103 func keyMinNsbtSell () = "min_nsbt_sell"
102104
103105
106+func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], SEP)
107+
108+
109+func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
110+
111+
104112 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
105113
106114
107115 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
108116
109117
110118 func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
119+
120+
121+func getIntOrElse (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
122+
123+
124+func getStrOrElse (address,key,defaultVal) = valueOrElse(getString(address, key), defaultVal)
111125
112126
113127 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
114128
115129
116130 func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
117131
118132
119133 func asAnyList (val) = match val {
120134 case valAnyList: List[Any] =>
121135 valAnyList
122136 case _ =>
123137 throw("fail to cast into List[Any]")
124138 }
125139
126140
127141 func asInt (val) = match val {
128142 case valInt: Int =>
129143 valInt
130144 case _ =>
131145 throw("fail to cast into Int")
132146 }
133147
134148
135149 func asString (val) = match val {
136150 case valStr: String =>
137151 valStr
138152 case _ =>
139153 throw("fail to cast into String")
140154 }
141155
142156
143157 func asTuple2Ints (val) = match val {
144158 case v: (Int, Int) =>
145159 v
146160 case _ =>
147161 throw("fail to cast into Tuple2 ints")
148162 }
149163
150164
151165 func asSwapParamsSTRUCT (val) = match val {
152166 case struct: (Int, Int, Int, Int, Int, Int, Int) =>
153167 struct
154168 case _ =>
155169 throw("fail to cast into SwapParamsSTRUCT")
156170 }
157171
158172
159173 func asWithdrawResultSTRUCT (val) = match val {
160174 case struct: (Int, Unit, Int, Int, Int, Int, Int)|(Int, ByteVector, Int, Int, Int, Int, Int) =>
161175 struct
162176 case _ =>
163177 throw("fail to cast into WithdrawResult")
164178 }
165179
166180
167181 func toTimestamp (start) = if ((0 > start))
168182 then -1
169183 else match blockInfoByHeight(start) {
170184 case block: BlockInfo =>
171185 block.timestamp
172186 case _ =>
173187 -1
174188 }
175189
176190
177191 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
178192
179193
180194 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
181195
182196
183197 let nMetricIdxPrice = 0
184198
185199 let nMetricIdxUsdnLockedBalance = 1
186200
187201 let nMetricIdxWavesLockedBalance = 2
188202
189203 let nMetricIdxReserve = 3
190204
191205 let nMetricIdxReserveInUsdn = 4
192206
193207 let nMetricIdxUsdnSupply = 5
194208
195209 let nMetricIdxSurplus = 6
196210
197211 let nMetricIdxSurplusPercent = 7
198212
199213 let nMetricIdxBR = 8
200214
201215 let nMetricIdxNsbtSupply = 9
202216
203217 let nMetricIdxMaxNsbtSupply = 10
204218
205219 let nMetricIdxSurfSupply = 11
206220
207221 let IdxControlCfgNeutrinoDapp = 1
208222
209223 let IdxControlCfgAuctionDapp = 2
210224
211225 let IdxControlCfgRpdDapp = 3
212226
213227 let IdxControlCfgMathDapp = 4
214228
215229 let IdxControlCfgLiquidationDapp = 5
216230
217231 let IdxControlCfgRestDapp = 6
218232
219233 let IdxControlCfgNodeRegistryDapp = 7
220234
221235 let IdxControlCfgNsbtStakingDapp = 8
222236
223237 let IdxControlCfgMediatorDapp = 9
224238
225239 let IdxControlCfgSurfStakingDapp = 10
226240
227241 let IdxControlCfgGnsbtControllerDapp = 11
228242
229243 let bFuncIdxSurf = 0
230244
231245 let bFuncIdxWaves = 1
232246
233247 let bFuncIdxUsdn = 2
234248
235249 let bFuncIdxReserveStart = 3
236250
237251 let bFuncIdxSupplyStart = 4
238252
239253 let bFuncIdxBRStart = 5
240254
241255 let bFuncIdxReserveEnd = 6
242256
243257 let bFuncIdxSupplyEnd = 7
244258
245259 let bFuncIdxBREnd = 8
246260
247261 let bFuncIdxRest = 9
248262
249263 let bFuncIdxWavesPrice = 10
250264
251265 func keyControlAddress () = "%s%s__config__controlAddress"
252266
253267
254268 func keyControlCfg () = "%s__controlConfig"
255269
256270
257271 func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
258272
259273
260274 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
261275
262276
263277 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
264278
265279 let controlCfg = readControlCfgOrFail(controlContract)
266280
267281 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
268282
269283 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
270284
271285 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
272286
273287 let liquidationContract = getContractAddressOrFail(controlCfg, IdxControlCfgLiquidationDapp)
274288
275289 let rpdContract = getContractAddressOrFail(controlCfg, IdxControlCfgRpdDapp)
276290
277291 let nsbtStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgNsbtStakingDapp)
278292
279293 let surfStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgSurfStakingDapp)
280294
281295 let gnsbtControllerContract = getContractAddressOrFail(controlCfg, IdxControlCfgGnsbtControllerDapp)
282296
283297 let neutrinoAssetIdString = getStringOrFail(neutrinoContract, keyNeutrinoAssetId())
284298
285299 let neutrinoAssetId = fromBase58String(neutrinoAssetIdString)
286300
287301 let nsbtAssetIdStr = getStringValue(neutrinoContract, keyNsbtAssetId())
288302
289303 let nsbtAssetId = fromBase58String(nsbtAssetIdStr)
290304
291305 let surfAssetIdStr = getStringValue(auctionContract, keySurfAssetId())
292306
293307 let surfAssetId = fromBase58String(surfAssetIdStr)
308+
309+func readUsdnIncomeForDay (stakingAcc,startOfDayTimestamp,neutrinoMetrics) = {
310+ let amtByDayKEY = keyStatsDepositAmtByDay(startOfDayTimestamp)
311+ let incomeStr = getStrOrElse(stakingAcc, amtByDayKEY, "%s%s__0__0")
312+ let incomeArray = split(incomeStr, SEP)
313+ let wavesAmt = parseIntValue(incomeArray[1])
314+ let usdnAmt = parseIntValue(incomeArray[2])
315+ let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
316+ let wavesAsUsdnAmt = fraction(wavesAmt, currentPrice, MULT8)
317+ (wavesAsUsdnAmt + usdnAmt)
318+ }
319+
320+
321+func calcUsdnIncomeForPeriod (stakingAcc,days) = {
322+ let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
323+ let currStartOfDay = toStartOfDay(lastBlock.timestamp)
324+ let startTimestamp = (currStartOfDay - (DAYMILLIS * (days + 1)))
325+ let endTimestamp = (currStartOfDay - DAYMILLIS)
326+ let startUsdnAmt = readUsdnIncomeForDay(surfStakingContract, startTimestamp, neutrinoMetrics)
327+ let endUsdnAmt = readUsdnIncomeForDay(surfStakingContract, endTimestamp, neutrinoMetrics)
328+ (endUsdnAmt - startUsdnAmt)
329+ }
330+
331+
332+func calcApr (stakingAcc,periodInDays,incomeForPeriod,stakingAssetPriceToUsdnX6) = {
333+ let totalStaked = getIntOrElse(surfStakingContract, "%s%s__stats__activeTotalLocked", 1)
334+ let totalStakedInUsdn = fraction(totalStaked, stakingAssetPriceToUsdnX6, MULT6)
335+ fraction((incomeForPeriod * MULT6), 365, (totalStakedInUsdn * periodInDays))
336+ }
337+
294338
295339 @Callable(i)
296340 func reverseSwapLimitREADONLY (lim,isWavesSwap) = {
297341 let BR = asInt(asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))[nMetricIdxBR])
298342 let gNsbt = if ((0 >= lim))
299343 then 0
300344 else {
301345 let aParamX8 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
302346 then keySwapAmountAParam()
303347 else keyUsdnSwapAmountAParam()))
304348 let bParamX16 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
305349 then keySwapAmountBParam()
306350 else keyUsdnSwapAmountBParam()))
307351 let limDivAX8 = if (isWavesSwap)
308352 then fraction(toBigInt(lim), MULTX10, aParamX8)
309353 else fraction(fraction(toBigInt(lim), MULTX10, aParamX8), MULTX6, toBigInt(BR))
310354 let revBX16 = fraction(MULTX16, MULTX16, bParamX16)
311355 toInt(pow(limDivAX8, 8, revBX16, 16, 6, CEILING))
312356 }
313357 $Tuple2(nil, gNsbt)
314358 }
315359
316360
317361
318362 @Callable(i)
319363 func gnsbtInfoINTERNAL (userAddressStrOrEmpty,additionalNsbtToStakeOrZero,additionalSurfToStakeOrZero) = {
320364 let userAddressOrThis = if ((userAddressStrOrEmpty != ""))
321365 then addressFromStringValue(userAddressStrOrEmpty)
322366 else this
323367 let currentPrice = getIntegerValue(controlContract, keyPrice())
324368 let gnsbtFromNsbtDiff = additionalNsbtToStakeOrZero
325369 let gnsbtFromSurfDiff = asInt(invoke(surfStakingContract, "gnsbtFromSurfSYSREADONLY", [additionalSurfToStakeOrZero], nil))
326370 let gNsbtDiff = (gnsbtFromNsbtDiff + gnsbtFromSurfDiff)
327371 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
328372 let blcks2LmtReset = swapParamsTuple._3
329373 let gnsbtAmt = swapParamsTuple._4
330374 let gnsbtAmtTotal = swapParamsTuple._5
331375 let limitMaxWaves = swapParamsTuple._6
332376 let limitMaxUsdn = swapParamsTuple._7
333377 let swapParamsTupleNEW = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, gNsbtDiff], nil))
334378 let blcks2LmtResetNEW = swapParamsTupleNEW._3
335379 let gnsbtAmtNEW = swapParamsTupleNEW._4
336380 let gnsbtAmtTotalNEW = swapParamsTupleNEW._5
337381 let limitMaxWavesNEW = swapParamsTupleNEW._6
338382 let limitMaxUsdnNEW = swapParamsTupleNEW._7
339383 let nsbtBalance = if ((userAddressStrOrEmpty != ""))
340384 then assetBalance(userAddressOrThis, nsbtAssetId)
341385 else 0
342386 let surfBalance = if ((userAddressStrOrEmpty != ""))
343387 then assetBalance(userAddressOrThis, surfAssetId)
344388 else 0
345389 let nsbtBalanceDiff = if ((additionalNsbtToStakeOrZero >= 0))
346390 then additionalNsbtToStakeOrZero
347391 else {
348392 let nsbtUnstakingData = asAnyList(invoke(nsbtStakingContract, "nsbtUnstakingSYSREADONLY", [userAddressStrOrEmpty, (-1 * additionalNsbtToStakeOrZero)], nil))
349393 let nsbtReceiveAmount = asInt(nsbtUnstakingData[2])
350394 let result = -(nsbtReceiveAmount)
351395 result
352396 }
353397 let nsbtBalanceNew = (nsbtBalance - nsbtBalanceDiff)
354398 let surfBalanceNew = (surfBalance - additionalSurfToStakeOrZero)
355399 let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [userAddressStrOrEmpty, additionalNsbtToStakeOrZero, additionalSurfToStakeOrZero], nil))
356400 let gnsbtUser = asInt(gnsbtData[0])
357401 let gnsbtTotal = asInt(gnsbtData[1])
358402 let nsbtData = asAnyList(gnsbtData[2])
359403 let surfData = asAnyList(gnsbtData[3])
360404 let vpEffectiveHeight = asInt(gnsbtData[4])
361405 let vpEffectiveHeightNEW = asInt(gnsbtData[5])
362406 let gnsbtAmtFromNsbt = asInt(nsbtData[2])
363407 let gnsbtAmtFromSurf = asInt(surfData[2])
364408 let gnsbtAmtFromNsbtNEW = (gnsbtAmtFromNsbt + gnsbtFromNsbtDiff)
365409 let gnsbtAmtFromSurfNEW = (gnsbtAmtFromSurf + gnsbtFromSurfDiff)
366410 let gnsbtFromNsbtTotal = asInt(nsbtData[3])
367411 let gnsbtFromSurfTotal = asInt(surfData[3])
368412 let gnsbtFromSurfActiveTotal = 0
369413 let gnsbtFromSurfFrozenTotal = gnsbtFromSurfTotal
370414 let gnsbtFromNsbtTotalNEW = (gnsbtFromNsbtTotal + gnsbtFromNsbtDiff)
371415 let gnsbtFromSurfTotalNEW = (gnsbtFromSurfTotal + gnsbtFromSurfDiff)
372416 let gnsbtFromSurfFrozenTotalNEW = gnsbtFromSurfTotalNEW
373417 let votingPower = fraction(gnsbtAmtFromNsbt, MULT8, (gnsbtFromNsbtTotal + gnsbtFromSurfActiveTotal))
374418 let votingPowerNew = fraction(gnsbtAmtFromNsbtNEW, MULT8, (gnsbtFromNsbtTotalNEW + gnsbtFromSurfActiveTotal))
375419 let votingPowerMax = fraction((gnsbtAmtFromNsbt + gnsbtAmtFromSurf), MULT8, ((gnsbtFromNsbtTotal + gnsbtFromSurfActiveTotal) + gnsbtFromSurfFrozenTotal))
376420 let votingPowerMaxNew = fraction((gnsbtAmtFromNsbtNEW + gnsbtAmtFromSurfNEW), MULT8, ((gnsbtFromNsbtTotalNEW + gnsbtFromSurfActiveTotal) + gnsbtFromSurfFrozenTotalNEW))
377421 let votingPowerEta = if ((vpEffectiveHeight == 0))
378422 then height
379423 else vpEffectiveHeight
380424 let votingPowerEtaNew = if ((vpEffectiveHeightNEW == 0))
381425 then height
382426 else vpEffectiveHeightNEW
383427 $Tuple2(nil, [0, nsbtBalance, surfBalance, nsbtBalanceNew, surfBalanceNew, gnsbtAmtFromNsbt, gnsbtAmtFromSurf, gnsbtAmtFromNsbtNEW, gnsbtAmtFromSurfNEW, gnsbtFromNsbtTotal, gnsbtFromSurfTotal, gnsbtFromNsbtTotalNEW, gnsbtFromSurfTotalNEW, limitMaxUsdn, limitMaxWaves, limitMaxUsdnNEW, limitMaxWavesNEW, blcks2LmtReset, blcks2LmtResetNEW, votingPower, votingPowerNew, votingPowerMax, votingPowerMaxNew, votingPowerEta, votingPowerEtaNew])
384428 }
385429
386430
387431
388432 @Callable(i)
389433 func gnsbtInfoREADONLY (userAddressStrOrEmpty,additionalNsbtToStakeOrZero,additionalSurfToStakeOrZero) = {
390434 let gnsbtInfoDATA = asAnyList(invoke(this, "gnsbtInfoINTERNAL", [userAddressStrOrEmpty, additionalNsbtToStakeOrZero, additionalSurfToStakeOrZero], nil))
391435 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", toString(asInt(gnsbtInfoDATA[1])), toString(asInt(gnsbtInfoDATA[2])), toString(asInt(gnsbtInfoDATA[3])), toString(asInt(gnsbtInfoDATA[4])), toString(asInt(gnsbtInfoDATA[5])), toString(asInt(gnsbtInfoDATA[6])), toString(asInt(gnsbtInfoDATA[7])), toString(asInt(gnsbtInfoDATA[8])), toString(asInt(gnsbtInfoDATA[9])), toString(asInt(gnsbtInfoDATA[10])), toString(asInt(gnsbtInfoDATA[11])), toString(asInt(gnsbtInfoDATA[12])), toString(asInt(gnsbtInfoDATA[13])), toString(asInt(gnsbtInfoDATA[14])), toString(asInt(gnsbtInfoDATA[15])), toString(asInt(gnsbtInfoDATA[16])), toString(asInt(gnsbtInfoDATA[17])), toString(asInt(gnsbtInfoDATA[18])), toString(asInt(gnsbtInfoDATA[19])), toString(asInt(gnsbtInfoDATA[20])), toString(asInt(gnsbtInfoDATA[21])), toString(asInt(gnsbtInfoDATA[22])), toString(asInt(gnsbtInfoDATA[23])), toString(asInt(gnsbtInfoDATA[24]))], SEP))
392436 }
393437
394438
395439
396440 @Callable(i)
397441 func rewardInfoREADONLY (userAddressStrOrEmpty) = {
398442 let rewardsData = asAnyList(invoke(gnsbtControllerContract, "gnsbtRewardsSYSREADONLY", [userAddressStrOrEmpty], nil))
399443 let usdnRewards = asString(invoke(rpdContract, "unclaimedRewardsREADONLY", [userAddressStrOrEmpty], nil))
400444 $Tuple2(nil, makeString(["%s%s%s", asString(rewardsData[0]), asString(rewardsData[1]), usdnRewards], SEP))
401445 }
402446
403447
404448
405449 @Callable(i)
406450 func mergeNsbtREADONLY (userAddressMandatory,newAmount) = {
407451 let nsbtData = asAnyList(invoke(nsbtStakingContract, "nsbtStakingSYSREADONLY", [userAddressMandatory, newAmount], nil))
408452 let amount0 = asInt(nsbtData[0])
409453 let startHeight = if ((0 >= amount0))
410454 then -1
411455 else asInt(nsbtData[2])
412456 let startTimestamp = toTimestamp(startHeight)
413457 let startHeightNew = if ((0 >= newAmount))
414458 then startHeight
415459 else {
416460 let halfLife = getIntOrFail(nsbtStakingContract, keyHalfLife())
417461 asInt(invoke(mathContract, "mergeStakesREADONLY", [amount0, startHeight, newAmount, height, halfLife], nil))
418462 }
419463 let startTimestampNew = toTimestamp(startHeightNew)
420464 $Tuple2(nil, makeString(["%d%d%d%d", toString(startHeight), toString(startTimestamp), toString(startHeightNew), toString(startTimestampNew)], SEP))
421465 }
422466
423467
424468
425469 @Callable(i)
426470 func swapLimitCalculatorREADONLY (userAddressStrOpt,limitWanted,assetIdStr) = {
427471 let gNsbtCurrent = if ((userAddressStrOpt == ""))
428472 then 0
429473 else asInt(asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOpt, 0], nil))._4)
430474 let limitWantedUsdn = if ((assetIdStr == "WAVES"))
431475 then convertWavesToNeutrino(limitWanted, getIntegerValue(controlContract, keyPrice()))
432476 else limitWanted
433477 let gNsbtNeeded = asInt(invoke(this, "reverseSwapLimitREADONLY", [limitWantedUsdn, (assetIdStr == "WAVES")], nil))
434478 let gNsbtDelta = (gNsbtNeeded - gNsbtCurrent)
435479 $Tuple2(nil, makeString(["%s%s", toString(gNsbtCurrent), toString(gNsbtDelta)], SEP))
436480 }
437481
438482
439483
440484 @Callable(i)
441485 func swapInfoREADONLY (userAddressStrOrEmpty,amount,assetIdStr) = {
442486 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
443487 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
444488 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
445489 let blcks2LmtReset = swapParamsTuple._3
446490 let limitMaxWaves = swapParamsTuple._6
447491 let limitMaxUsdn = swapParamsTuple._7
448492 let assetId = fromBase58String(assetIdStr)
449493 let swapType = if ((assetId == WAVESID))
450494 then "waves"
451495 else if ((assetId == neutrinoAssetId))
452496 then "neutrino"
453497 else throw(("Can't swap assetId=" + assetIdStr))
454498 let withdrawTuple = asWithdrawResultSTRUCT(invoke(neutrinoContract, "calcWithdrawResultSYSREADONLY", [swapType, amount, price], nil))
455499 let outNetAmount = withdrawTuple._1
456500 let outAssetId = withdrawTuple._2
457501 let outSurfAmt = withdrawTuple._3
458502 let inAmtToSurfPart = withdrawTuple._4
459503 let unleaseAmt = withdrawTuple._5
460504 let outFeeAmount = withdrawTuple._6
461505 let outAmtGross = withdrawTuple._7
462506 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(price), toString(blcks2LmtReset), toString(limitMaxWaves), toString(limitMaxUsdn), toString(inAmtToSurfPart)], SEP))
463507 }
464508
465509
466510
467511 @Callable(i)
468512 func usdnStakingAprREADONLY (days) = $Tuple2(nil, "%d__60000")
469513
470514
471515
472516 @Callable(i)
473517 func surfStakingAprREADONLY (days) = $Tuple2(nil, "%d__70000")
474518
475519
476520
477521 @Callable(i)
478522 func nsbtStakingAprREADONLY (days) = $Tuple2(nil, "%d__90000")
479523
480524
525+
526+@Callable(i)
527+func usdnStakingAprTestREADONLY (days) = {
528+ let tmpDays = 1
529+ let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
530+ let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
531+ let wavesIncome = (6000 * MULT8)
532+ let incomeForPeriod = fraction(wavesIncome, currentPrice, MULT8)
533+ let apr = calcApr(rpdContract, tmpDays, incomeForPeriod, MULT6)
534+ $Tuple2(nil, ("%d__" + toString(apr)))
535+ }
536+
537+
538+
539+@Callable(i)
540+func surfStakingAprTestREADONLY (days) = {
541+ let tmpDays = 3
542+ let incomeForPeriod = calcUsdnIncomeForPeriod(surfStakingContract, tmpDays)
543+ let surfPriceToUsdnX6 = 86400
544+ let apr = calcApr(surfStakingContract, tmpDays, incomeForPeriod, surfPriceToUsdnX6)
545+ $Tuple2(nil, ("%d__" + toString(apr)))
546+ }
547+
548+
549+
550+@Callable(i)
551+func nsbtStakingAprTestREADONLY (days) = {
552+ let tmpDays = 3
553+ let nsbtPriceToUsdnX6 = 8000000
554+ let incomeForPeriod = calcUsdnIncomeForPeriod(nsbtStakingContract, tmpDays)
555+ let apr = calcApr(nsbtStakingContract, tmpDays, incomeForPeriod, nsbtPriceToUsdnX6)
556+ $Tuple2(nil, ("%d__" + toString(apr)))
557+ }
558+
559+

github/deemru/w8io/6500d08 
63.70 ms