tx · GWpb91ZsRwiFqQLF3rWm2fPY9JjjZowahupDCSPYYkPp

3NAfzeA3URU6oCV6HvtAiNwqGXsTs87ZpHh:  -0.02500000 Waves

2023.02.23 12:47 [2462140] smart account 3NAfzeA3URU6oCV6HvtAiNwqGXsTs87ZpHh > SELF 0.00000000 Waves

{ "type": 13, "id": "GWpb91ZsRwiFqQLF3rWm2fPY9JjjZowahupDCSPYYkPp", "fee": 2500000, "feeAssetId": null, "timestamp": 1677145706432, "version": 2, "chainId": 84, "sender": "3NAfzeA3URU6oCV6HvtAiNwqGXsTs87ZpHh", "senderPublicKey": "HiTi1JT7GQRqLNxg4yZhD1mV42y1Mv2AYvRx92JQRbwX", "proofs": [ "2SqF2ymoP5c7HgPnzbA1VFaBgb95QeFkiRRWaj9mxC3xq9FdSFxXE2kWrPLB3emJjKYQqqZbxEKQ6Z7C64z3bZ8d" ], "script": "base64:BgJYCAISBAoCAQQSBQoDCAEBEgUKAwgBARIDCgEIEgMKAQgSBAoCCAESBQoDCAEIEgUKAwgBCBIFCgMIAQgSABIDCgEBEgMKAQESBAoCAQESAwoBARIECgIBAXUABkVVTEVSOADWic+BAQAFTVVMVDYAwIQ9AAZNVUxUWDYJALYCAQDAhD0ABU1VTFQ4AIDC1y8ABk1VTFRYOAkAtgIBAIDC1y8AB01VTFRYMTAJALYCAQCAyK+gJQAGTVVMVDEyAICglKWNHQAHTVVMVFgxNgkAtgIBAICAhP6m3uERAAZNVUxUMTgJALYCAQCAgJC7utat8A0AA1NFUAICX18AB0xJU1RTRVACAToAEURFRkFVTFRTV0FQRkVFTjJXAIgnABFERUZBVUxUU1dBUEZFRVcyTgCgnAEAC0JSUFJPVEVDVEVEAKCNBgAHV0FWRVNJRAkA2QQBAgVXQVZFUwAJREFZTUlMTElTAIC4mSkBEmtleU5ldXRyaW5vQXNzZXRJZAACEW5ldXRyaW5vX2Fzc2V0X2lkAQ5rZXlOc2J0QXNzZXRJZAACDWJvbmRfYXNzZXRfaWQBDmtleVN1cmZBc3NldElkAAINc3VyZl9hc3NldF9pZAETa2V5U3dhcEFtb3VudEFQYXJhbQACGCVzJXNfX2NvbmZpZ19fc3dhcEFQYXJhbQETa2V5U3dhcEFtb3VudEJQYXJhbQACGCVzJXNfX2NvbmZpZ19fc3dhcEJQYXJhbQEXa2V5VXNkblN3YXBBbW91bnRBUGFyYW0AAhwlcyVzX19jb25maWdfX3VzZG5Td2FwQVBhcmFtARdrZXlVc2RuU3dhcEFtb3VudEJQYXJhbQACHCVzJXNfX2NvbmZpZ19fdXNkblN3YXBCUGFyYW0BE2tleU5zYnRMb2NrQ29udHJhY3QAAhQlc19fbnNidExvY2tDb250cmFjdAEPa2V5TWF0aENvbnRyYWN0AAIQJXNfX21hdGhDb250cmFjdAEPYmFza2V0QXNzZXRzS2V5AAIaJXMlc19fY29tbW9uX19iYXNrZXRBc3NldHMBCmJhc2tldERLZXkAAhUlcyVzX19jb21tb25fX2Jhc2tldEQBCmJhc2tldEJLZXkAAhUlcyVzX19jb21tb25fX2Jhc2tldEIBEmJhc2tldExvZ2JEZWx0YUtleQACHSVzJXNfX2NvbW1vbl9fYmFza2V0TG9nYkRlbHRhARZiYXNrZXRXZWlnaHRCeUFzc2V0S2V5AQdhc3NldElkCQCsAgICHyVzJXMlc19fY29tbW9uX193ZWlnaHRCeUFzc2V0X18FB2Fzc2V0SWQBCGtleVByaWNlAAIFcHJpY2UBD2tleVByaWNlQnlBc3NldAEHYXNzZXRJZAkArAICAh4lcyVzJXNfX2NvbW1vbl9fcHJpY2VCeUFzc2V0X18FB2Fzc2V0SWQBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICC3BhcmFtQnlVc2VyCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBXN0YXJ0BQNuaWwFA1NFUAELa2V5SGFsZkxpZmUAAgwlc19faGFsZkxpZmUBEGtleU1pbkxvY2tBbW91bnQAAhElc19fbWluTG9ja0Ftb3VudAEVa2V5TWluV2F2ZXNGb3JOc2J0QnV5AAISbWluX3dhdmVzX25zYnRfYnV5AQ5rZXlNaW5Oc2J0U2VsbAACDW1pbl9uc2J0X3NlbGwBF2tleVN0YXRzRGVwb3NpdEFtdEJ5RGF5AQl0aW1lc3RhbXAJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIFc3RhdHMJAMwIAgIPZGVwb3NpdEFtdEJ5RGF5CQDMCAIJAKQDAQUJdGltZXN0YW1wBQNuaWwFA1NFUAEMdG9TdGFydE9mRGF5AQl0aW1lc3RhbXAJAGgCCQBpAgUJdGltZXN0YW1wBQlEQVlNSUxMSVMFCURBWU1JTExJUwEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDGdldEludE9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQ1nZXRCb29sT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCbCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABDGdldEludE9yRWxzZQMHYWRkcmVzcwNrZXkKZGVmYXVsdFZhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkFCmRlZmF1bHRWYWwBDGdldFN0ck9yRWxzZQMHYWRkcmVzcwNrZXkKZGVmYXVsdFZhbAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQdhZGRyZXNzBQNrZXkFCmRlZmF1bHRWYWwBFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMCBmFtb3VudAVwcmljZQkAawMFBmFtb3VudAUFTVVMVDgFBXByaWNlARFjb252ZXJ0VG9rZW5Ub1VzZAIGYW1vdW50BXByaWNlCQBrAwUGYW1vdW50BQVwcmljZQUFTVVMVDgBCWFzQW55TGlzdAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMaXN0BQckbWF0Y2gwBQp2YWxBbnlMaXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQGdmFsU3RyBQckbWF0Y2gwBQZ2YWxTdHIJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBDGFzVHVwbGUySW50cwEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIKKEludCwgSW50KQQBdgUHJG1hdGNoMAUBdgkAAgECHWZhaWwgdG8gY2FzdCBpbnRvIFR1cGxlMiBpbnRzARJhc1N3YXBQYXJhbXNTVFJVQ1QBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACIyhJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQpBAZzdHJ1Y3QFByRtYXRjaDAFBnN0cnVjdAkAAgECImZhaWwgdG8gY2FzdCBpbnRvIFN3YXBQYXJhbXNTVFJVQ1QBFmFzV2l0aGRyYXdSZXN1bHRTVFJVQ1QBA3ZhbAQHJG1hdGNoMAUDdmFsAwMJAAECBQckbWF0Y2gwAjEoSW50LCBVbml0LCBJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50LCBTdHJpbmcpBgkAAQIFByRtYXRjaDACNyhJbnQsIEJ5dGVWZWN0b3IsIEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQsIFN0cmluZykEBnN0cnVjdAUHJG1hdGNoMAUGc3RydWN0CQACAQIgZmFpbCB0byBjYXN0IGludG8gV2l0aGRyYXdSZXN1bHQBC3RvVGltZXN0YW1wAQVzdGFydAMJAGYCAAAFBXN0YXJ0AP///////////wEEByRtYXRjaDAJAO0HAQUFc3RhcnQDCQABAgUHJG1hdGNoMAIJQmxvY2tJbmZvBAVibG9jawUHJG1hdGNoMAgFBWJsb2NrCXRpbWVzdGFtcAD///////////8BAQV0b1gxOAIHb3JpZ1ZhbA1vcmlnU2NhbGVNdWx0CQC8AgMJALYCAQUHb3JpZ1ZhbAUGTVVMVDE4CQC2AgEFDW9yaWdTY2FsZU11bHQBB2Zyb21YMTgCA3ZhbA9yZXN1bHRTY2FsZU11bHQJAKADAQkAvAIDBQN2YWwJALYCAQUPcmVzdWx0U2NhbGVNdWx0BQZNVUxUMTgAD25NZXRyaWNJZHhQcmljZQAAABtuTWV0cmljSWR4VXNkbkxvY2tlZEJhbGFuY2UAAQAcbk1ldHJpY0lkeFdhdmVzTG9ja2VkQmFsYW5jZQACABFuTWV0cmljSWR4UmVzZXJ2ZQADABduTWV0cmljSWR4UmVzZXJ2ZUluVXNkbgAEABRuTWV0cmljSWR4VXNkblN1cHBseQAFABFuTWV0cmljSWR4U3VycGx1cwAGABhuTWV0cmljSWR4U3VycGx1c1BlcmNlbnQABwAMbk1ldHJpY0lkeEJSAAgAFG5NZXRyaWNJZHhOc2J0U3VwcGx5AAkAF25NZXRyaWNJZHhNYXhOc2J0U3VwcGx5AAoAFG5NZXRyaWNJZHhTdXJmU3VwcGx5AAsAEm5NZXRyaWNVc2RuVXNkdFBlZwAMABZuTWV0cmljQ3VycmVudFByaWNlQWRqAA0AEW5NZXRyaWNCYXNrZXRJbmZvAA4AFG5NZXRyaWNXZWlnaHRlZFByaWNlAA8AF25NZXRyaWNUb3RhbFJlc2VydmVzVXNkABAAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALAAxiRnVuY0lkeFN1cmYAAAANYkZ1bmNJZHhXYXZlcwABAAxiRnVuY0lkeFVzZG4AAgAUYkZ1bmNJZHhSZXNlcnZlU3RhcnQAAwATYkZ1bmNJZHhTdXBwbHlTdGFydAAEAA9iRnVuY0lkeEJSU3RhcnQABQASYkZ1bmNJZHhSZXNlcnZlRW5kAAYAEWJGdW5jSWR4U3VwcGx5RW5kAAcADWJGdW5jSWR4QlJFbmQACAAMYkZ1bmNJZHhSZXN0AAkAEmJGdW5jSWR4V2F2ZXNQcmljZQAKARFrZXlDb250cm9sQWRkcmVzcwACHCVzJXNfX2NvbmZpZ19fY29udHJvbEFkZHJlc3MBDWtleUNvbnRyb2xDZmcAAhElc19fY29udHJvbENvbmZpZwEUcmVhZENvbnRyb2xDZmdPckZhaWwBB2NvbnRyb2wJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFB2NvbnRyb2wJAQ1rZXlDb250cm9sQ2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCCmNvbnRyb2xDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQpjb250cm9sQ2ZnBQNpZHgJAKwCAgItQ29udHJvbCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAPY29udHJvbENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJARFrZXlDb250cm9sQWRkcmVzcwACIzNONE5TN2Q0Sm85YTZGMTRMaUZVS0tZVmRVa2tmMmVQNFp4AApjb250cm9sQ2ZnCQEUcmVhZENvbnRyb2xDZmdPckZhaWwBBQ9jb250cm9sQ29udHJhY3QADG1hdGhDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAQbmV1dHJpbm9Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAD2F1Y3Rpb25Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFGElkeENvbnRyb2xDZmdBdWN0aW9uRGFwcAATbGlxdWlkYXRpb25Db250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCmNvbnRyb2xDZmcFHElkeENvbnRyb2xDZmdMaXF1aWRhdGlvbkRhcHAAC3JwZENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUUSWR4Q29udHJvbENmZ1JwZERhcHAAE25zYnRTdGFraW5nQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBRxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwABNzdXJmU3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAXZ25zYnRDb250cm9sbGVyQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQpjb250cm9sQ2ZnBSBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAAVbmV1dHJpbm9Bc3NldElkU3RyaW5nCQEPZ2V0U3RyaW5nT3JGYWlsAgUQbmV1dHJpbm9Db250cmFjdAkBEmtleU5ldXRyaW5vQXNzZXRJZAAAD25ldXRyaW5vQXNzZXRJZAkA2QQBBRVuZXV0cmlub0Fzc2V0SWRTdHJpbmcADm5zYnRBc3NldElkU3RyCQERQGV4dHJOYXRpdmUoMTA1MykCBRBuZXV0cmlub0NvbnRyYWN0CQEOa2V5TnNidEFzc2V0SWQAAAtuc2J0QXNzZXRJZAkA2QQBBQ5uc2J0QXNzZXRJZFN0cgAOc3VyZkFzc2V0SWRTdHIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFD2F1Y3Rpb25Db250cmFjdAkBDmtleVN1cmZBc3NldElkAAALc3VyZkFzc2V0SWQJANkEAQUOc3VyZkFzc2V0SWRTdHIBFHJlYWRVc2RuSW5jb21lRm9yRGF5AwpzdGFraW5nQWNjE3N0YXJ0T2ZEYXlUaW1lc3RhbXAPbmV1dHJpbm9NZXRyaWNzBAthbXRCeURheUtFWQkBF2tleVN0YXRzRGVwb3NpdEFtdEJ5RGF5AQUTc3RhcnRPZkRheVRpbWVzdGFtcAQJaW5jb21lU3RyCQEMZ2V0U3RyT3JFbHNlAwUKc3Rha2luZ0FjYwULYW10QnlEYXlLRVkCCiVzJXNfXzBfXzAEC2luY29tZUFycmF5CQC1CQIFCWluY29tZVN0cgUDU0VQBAh3YXZlc0FtdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2luY29tZUFycmF5AAEEB3VzZG5BbXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtpbmNvbWVBcnJheQACBAxjdXJyZW50UHJpY2UJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBQ9uTWV0cmljSWR4UHJpY2UEDndhdmVzQXNVc2RuQW10CQBrAwUId2F2ZXNBbXQFDGN1cnJlbnRQcmljZQUFTVVMVDgJAGQCBQ53YXZlc0FzVXNkbkFtdAUHdXNkbkFtdAEXY2FsY1VzZG5JbmNvbWVGb3JQZXJpb2QCCnN0YWtpbmdBY2MEZGF5cwQPbmV1dHJpbm9NZXRyaWNzCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAQOY3VyclN0YXJ0T2ZEYXkJAQx0b1N0YXJ0T2ZEYXkBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQOc3RhcnRUaW1lc3RhbXAJAGUCBQ5jdXJyU3RhcnRPZkRheQkAaAIFCURBWU1JTExJUwkAZAIFBGRheXMAAQQMZW5kVGltZXN0YW1wCQBlAgUOY3VyclN0YXJ0T2ZEYXkFCURBWU1JTExJUwQPc3RhcnRVc2RuQW10VE1QCQEUcmVhZFVzZG5JbmNvbWVGb3JEYXkDBQpzdGFraW5nQWNjBQ5zdGFydFRpbWVzdGFtcAUPbmV1dHJpbm9NZXRyaWNzBAplbmRVc2RuQW10CQEUcmVhZFVzZG5JbmNvbWVGb3JEYXkDBQpzdGFraW5nQWNjBQxlbmRUaW1lc3RhbXAFD25ldXRyaW5vTWV0cmljcwQMc3RhcnRVc2RuQW10AwkAAAIFD3N0YXJ0VXNkbkFtdFRNUAAABQplbmRVc2RuQW10BQ9zdGFydFVzZG5BbXRUTVAJAGUCBQplbmRVc2RuQW10BQxzdGFydFVzZG5BbXQBB2NhbGNBcHIECnN0YWtpbmdBY2MMcGVyaW9kSW5EYXlzD2luY29tZUZvclBlcmlvZBlzdGFraW5nQXNzZXRQcmljZVRvVXNkblg2BAt0b3RhbFN0YWtlZAkBDGdldEludE9yRWxzZQMFCnN0YWtpbmdBY2MCHiVzJXNfX3N0YXRzX19hY3RpdmVUb3RhbExvY2tlZAABBBF0b3RhbFN0YWtlZEluVXNkbgkAawMFC3RvdGFsU3Rha2VkBRlzdGFraW5nQXNzZXRQcmljZVRvVXNkblg2BQVNVUxUNgMJAGYCAAAFD2luY29tZUZvclBlcmlvZAAACQBrAwkAaAIFD2luY29tZUZvclBlcmlvZAUFTVVMVDYA7QIJAGgCBRF0b3RhbFN0YWtlZEluVXNkbgUMcGVyaW9kSW5EYXlzDwFpARhyZXZlcnNlU3dhcExpbWl0UkVBRE9OTFkCA2xpbQppc091dE11bHRpBAJCUgkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAUMbk1ldHJpY0lkeEJSBAVnTnNidAMJAGcCAAAFA2xpbQAABAhhUGFyYW1YOAkAtgIBCQEMZ2V0SW50T3JGYWlsAgUMbWF0aENvbnRyYWN0AwUKaXNPdXRNdWx0aQkBF2tleVVzZG5Td2FwQW1vdW50QVBhcmFtAAkBE2tleVN3YXBBbW91bnRBUGFyYW0ABAliUGFyYW1YMTYJALYCAQkBDGdldEludE9yRmFpbAIFDG1hdGhDb250cmFjdAMFCmlzT3V0TXVsdGkJARdrZXlVc2RuU3dhcEFtb3VudEJQYXJhbQAJARNrZXlTd2FwQW1vdW50QlBhcmFtAAQJbGltRGl2QVg4AwUKaXNPdXRNdWx0aQkAvAIDCQC8AgMJALYCAQUDbGltBQdNVUxUWDEwBQhhUGFyYW1YOAUGTVVMVFg2CQC2AgEFAkJSCQC8AgMJALYCAQUDbGltBQdNVUxUWDEwBQhhUGFyYW1YOAQHcmV2QlgxNgkAvAIDBQdNVUxUWDE2BQdNVUxUWDE2BQliUGFyYW1YMTYJAKADAQkAdgYFCWxpbURpdkFYOAAIBQdyZXZCWDE2ABAABgUHQ0VJTElORwkAlAoCBQNuaWwFBWdOc2J0AWkBEWduc2J0SW5mb0lOVEVSTkFMAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwQRdXNlckFkZHJlc3NPclRoaXMDCQECIT0CBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkCAAkBEUBleHRyTmF0aXZlKDEwNjIpAQUVdXNlckFkZHJlc3NTdHJPckVtcHR5BQR0aGlzBAxjdXJyZW50UHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2NvbnRyb2xDb250cmFjdAkBCGtleVByaWNlAAQRZ25zYnRGcm9tTnNidERpZmYFG2FkZGl0aW9uYWxOc2J0VG9TdGFrZU9yWmVybwQRZ25zYnRGcm9tU3VyZkRpZmYJAQVhc0ludAEJAPwHBAUTc3VyZlN0YWtpbmdDb250cmFjdAIYZ25zYnRGcm9tU3VyZlNZU1JFQURPTkxZCQDMCAIFG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwUDbmlsBQNuaWwECWdOc2J0RGlmZgkAZAIFEWduc2J0RnJvbU5zYnREaWZmBRFnbnNidEZyb21TdXJmRGlmZgQPc3dhcFBhcmFtc1R1cGxlCQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/AcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5CQDMCAIAAAUDbmlsBQNuaWwEEGxpbWl0TWF4VG9rZW5Vc2QIBQ9zd2FwUGFyYW1zVHVwbGUCXzEEDmJsY2tzMkxtdFJlc2V0CAUPc3dhcFBhcmFtc1R1cGxlAl8zBAhnbnNidEFtdAgFD3N3YXBQYXJhbXNUdXBsZQJfNAQNZ25zYnRBbXRUb3RhbAgFD3N3YXBQYXJhbXNUdXBsZQJfNQQMbGltaXRNYXhVc2RuCAUPc3dhcFBhcmFtc1R1cGxlAl83BBJzd2FwUGFyYW1zVHVwbGVORVcJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD8BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgUJZ05zYnREaWZmBQNuaWwFA25pbAQTbGltaXRNYXhUb2tlblVzZE5FVwgFEnN3YXBQYXJhbXNUdXBsZU5FVwJfMQQRYmxja3MyTG10UmVzZXRORVcIBRJzd2FwUGFyYW1zVHVwbGVORVcCXzMEC2duc2J0QW10TkVXCAUSc3dhcFBhcmFtc1R1cGxlTkVXAl80BBBnbnNidEFtdFRvdGFsTkVXCAUSc3dhcFBhcmFtc1R1cGxlTkVXAl81BA9saW1pdE1heFVzZG5ORVcIBRJzd2FwUGFyYW1zVHVwbGVORVcCXzcEC25zYnRCYWxhbmNlAwkBAiE9AgUVdXNlckFkZHJlc3NTdHJPckVtcHR5AgAJAPAHAgURdXNlckFkZHJlc3NPclRoaXMFC25zYnRBc3NldElkAAAEC3N1cmZCYWxhbmNlAwkBAiE9AgUVdXNlckFkZHJlc3NTdHJPckVtcHR5AgAJAPAHAgURdXNlckFkZHJlc3NPclRoaXMFC3N1cmZBc3NldElkAAAED25zYnRCYWxhbmNlRGlmZgMJAGcCBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8AAAUbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvBBFuc2J0VW5zdGFraW5nRGF0YQkBCWFzQW55TGlzdAEJAPwHBAUTbnNidFN0YWtpbmdDb250cmFjdAIYbnNidFVuc3Rha2luZ1NZU1JFQURPTkxZCQDMCAIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQkAzAgCCQBoAgD///////////8BBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8FA25pbAUDbmlsBBFuc2J0UmVjZWl2ZUFtb3VudAkBBWFzSW50AQkAkQMCBRFuc2J0VW5zdGFraW5nRGF0YQACBAZyZXN1bHQJAQEtAQURbnNidFJlY2VpdmVBbW91bnQFBnJlc3VsdAQObnNidEJhbGFuY2VOZXcJAGUCBQtuc2J0QmFsYW5jZQUPbnNidEJhbGFuY2VEaWZmBA5zdXJmQmFsYW5jZU5ldwkAZQIFC3N1cmZCYWxhbmNlBRthZGRpdGlvbmFsU3VyZlRvU3Rha2VPclplcm8ECWduc2J0RGF0YQkBCWFzQW55TGlzdAEJAPwHBAUXZ25zYnRDb250cm9sbGVyQ29udHJhY3QCFGduc2J0SW5mb1NZU1JFQURPTkxZCQDMCAIFFXVzZXJBZGRyZXNzU3RyT3JFbXB0eQkAzAgCBRthZGRpdGlvbmFsTnNidFRvU3Rha2VPclplcm8JAMwIAgUbYWRkaXRpb25hbFN1cmZUb1N0YWtlT3JaZXJvBQNuaWwFA25pbAQJZ25zYnRVc2VyCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAABApnbnNidFRvdGFsCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQABBAhuc2J0RGF0YQkBCWFzQW55TGlzdAEJAJEDAgUJZ25zYnREYXRhAAIECHN1cmZEYXRhCQEJYXNBbnlMaXN0AQkAkQMCBQlnbnNidERhdGEAAwQRdnBFZmZlY3RpdmVIZWlnaHQJAQVhc0ludAEJAJEDAgUJZ25zYnREYXRhAAQEFHZwRWZmZWN0aXZlSGVpZ2h0TkVXCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAFBBBnbnNidEFtdEZyb21Oc2J0CQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAIEEGduc2J0QW10RnJvbVN1cmYJAQVhc0ludAEJAJEDAgUIc3VyZkRhdGEAAgQTZ25zYnRBbXRGcm9tTnNidE5FVwkAZAIFEGduc2J0QW10RnJvbU5zYnQFEWduc2J0RnJvbU5zYnREaWZmBBNnbnNidEFtdEZyb21TdXJmTkVXCQBkAgUQZ25zYnRBbXRGcm9tU3VyZgURZ25zYnRGcm9tU3VyZkRpZmYEEmduc2J0RnJvbU5zYnRUb3RhbAkBBWFzSW50AQkAkQMCBQhuc2J0RGF0YQADBBJnbnNidEZyb21TdXJmVG90YWwJAQVhc0ludAEJAJEDAgUIc3VyZkRhdGEAAwQYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsAAAEGGduc2J0RnJvbVN1cmZGcm96ZW5Ub3RhbAUSZ25zYnRGcm9tU3VyZlRvdGFsBBVnbnNidEZyb21Oc2J0VG90YWxORVcJAGQCBRJnbnNidEZyb21Oc2J0VG90YWwFEWduc2J0RnJvbU5zYnREaWZmBBVnbnNidEZyb21TdXJmVG90YWxORVcJAGQCBRJnbnNidEZyb21TdXJmVG90YWwFEWduc2J0RnJvbVN1cmZEaWZmBBtnbnNidEZyb21TdXJmRnJvemVuVG90YWxORVcFFWduc2J0RnJvbVN1cmZUb3RhbE5FVwQLdm90aW5nUG93ZXIJAGsDBRBnbnNidEFtdEZyb21Oc2J0BQVNVUxUOAkAZAIFEmduc2J0RnJvbU5zYnRUb3RhbAUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBA52b3RpbmdQb3dlck5ldwkAawMFE2duc2J0QW10RnJvbU5zYnRORVcFBU1VTFQ4CQBkAgUVZ25zYnRGcm9tTnNidFRvdGFsTkVXBRhnbnNidEZyb21TdXJmQWN0aXZlVG90YWwEDnZvdGluZ1Bvd2VyTWF4CQBrAwkAZAIFEGduc2J0QW10RnJvbU5zYnQFEGduc2J0QW10RnJvbVN1cmYFBU1VTFQ4CQBkAgkAZAIFEmduc2J0RnJvbU5zYnRUb3RhbAUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBRhnbnNidEZyb21TdXJmRnJvemVuVG90YWwEEXZvdGluZ1Bvd2VyTWF4TmV3CQBrAwkAZAIFE2duc2J0QW10RnJvbU5zYnRORVcFE2duc2J0QW10RnJvbVN1cmZORVcFBU1VTFQ4CQBkAgkAZAIFFWduc2J0RnJvbU5zYnRUb3RhbE5FVwUYZ25zYnRGcm9tU3VyZkFjdGl2ZVRvdGFsBRtnbnNidEZyb21TdXJmRnJvemVuVG90YWxORVcEDnZvdGluZ1Bvd2VyRXRhAwkAAAIFEXZwRWZmZWN0aXZlSGVpZ2h0AAAFBmhlaWdodAURdnBFZmZlY3RpdmVIZWlnaHQEEXZvdGluZ1Bvd2VyRXRhTmV3AwkAAAIFFHZwRWZmZWN0aXZlSGVpZ2h0TkVXAAAFBmhlaWdodAUUdnBFZmZlY3RpdmVIZWlnaHRORVcJAJQKAgUDbmlsCQDMCAIAAAkAzAgCBQtuc2J0QmFsYW5jZQkAzAgCBQtzdXJmQmFsYW5jZQkAzAgCBQ5uc2J0QmFsYW5jZU5ldwkAzAgCBQ5zdXJmQmFsYW5jZU5ldwkAzAgCBRBnbnNidEFtdEZyb21Oc2J0CQDMCAIFEGduc2J0QW10RnJvbVN1cmYJAMwIAgUTZ25zYnRBbXRGcm9tTnNidE5FVwkAzAgCBRNnbnNidEFtdEZyb21TdXJmTkVXCQDMCAIFEmduc2J0RnJvbU5zYnRUb3RhbAkAzAgCBRJnbnNidEZyb21TdXJmVG90YWwJAMwIAgUVZ25zYnRGcm9tTnNidFRvdGFsTkVXCQDMCAIFFWduc2J0RnJvbVN1cmZUb3RhbE5FVwkAzAgCBQxsaW1pdE1heFVzZG4JAMwIAgUQbGltaXRNYXhUb2tlblVzZAkAzAgCBQ9saW1pdE1heFVzZG5ORVcJAMwIAgUTbGltaXRNYXhUb2tlblVzZE5FVwkAzAgCBQ5ibGNrczJMbXRSZXNldAkAzAgCBRFibGNrczJMbXRSZXNldE5FVwkAzAgCBQt2b3RpbmdQb3dlcgkAzAgCBQ52b3RpbmdQb3dlck5ldwkAzAgCBQ52b3RpbmdQb3dlck1heAkAzAgCBRF2b3RpbmdQb3dlck1heE5ldwkAzAgCBQ52b3RpbmdQb3dlckV0YQkAzAgCBRF2b3RpbmdQb3dlckV0YU5ldwUDbmlsAWkBEWduc2J0SW5mb1JFQURPTkxZAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkbYWRkaXRpb25hbE5zYnRUb1N0YWtlT3JaZXJvG2FkZGl0aW9uYWxTdXJmVG9TdGFrZU9yWmVybwQNZ25zYnRJbmZvREFUQQkBCWFzQW55TGlzdAEJAPwHBAUEdGhpcwIRZ25zYnRJbmZvSU5URVJOQUwJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5CQDMCAIFG2FkZGl0aW9uYWxOc2J0VG9TdGFrZU9yWmVybwkAzAgCBRthZGRpdGlvbmFsU3VyZlRvU3Rha2VPclplcm8FA25pbAUDbmlsCQCUCgIFA25pbAkAuQkCCQDMCAICMCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQABCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAIJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAAwkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAECQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAUJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEABgkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAHCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAgJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEACQkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAKCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAAsJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEADAkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQANCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBAA4JAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEADwkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAQCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABEJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAEgkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQATCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABQJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAFQkAzAgCCQCkAwEJAQVhc0ludAEJAJEDAgUNZ25zYnRJbmZvREFUQQAWCQDMCAIJAKQDAQkBBWFzSW50AQkAkQMCBQ1nbnNidEluZm9EQVRBABcJAMwIAgkApAMBCQEFYXNJbnQBCQCRAwIFDWduc2J0SW5mb0RBVEEAGAUDbmlsBQNTRVABaQEWZ25zYnRFZmZlY3RpdmVSRUFET05MWQEVdXNlckFkZHJlc3NTdHJPckVtcHR5BAlnbnNidERhdGEJAQlhc0FueUxpc3QBCQD8BwQFF2duc2J0Q29udHJvbGxlckNvbnRyYWN0AhRnbnNidEluZm9TWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgAACQDMCAIAAAUDbmlsBQNuaWwECG5zYnREYXRhCQEJYXNBbnlMaXN0AQkAkQMCBQlnbnNidERhdGEAAgQMdXNlckZyb21Oc2J0CQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAIEDXRvdGFsRnJvbU5zYnQJAQVhc0ludAEJAJEDAgUIbnNidERhdGEAAwQSdXNlck1hdHVyZUZyb21TdXJmCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAJBBN0b3RhbE1hdHVyZUZyb21TdXJmCQEFYXNJbnQBCQCRAwIFCWduc2J0RGF0YQAGCQCUCgIFA25pbAkAuQkCCQDMCAICBCVkJWQJAMwIAgkApAMBCQBkAgUNdG90YWxGcm9tTnNidAUTdG90YWxNYXR1cmVGcm9tU3VyZgkAzAgCCQCkAwEJAGQCBQx1c2VyRnJvbU5zYnQFEnVzZXJNYXR1cmVGcm9tU3VyZgUDbmlsBQNTRVABaQEScmV3YXJkSW5mb1JFQURPTkxZARV1c2VyQWRkcmVzc1N0ck9yRW1wdHkEC3Jld2FyZHNEYXRhCQEJYXNBbnlMaXN0AQkA/AcEBRdnbnNidENvbnRyb2xsZXJDb250cmFjdAIXZ25zYnRSZXdhcmRzU1lTUkVBRE9OTFkJAMwIAgUVdXNlckFkZHJlc3NTdHJPckVtcHR5BQNuaWwFA25pbAQLdXNkblJld2FyZHMJAQhhc1N0cmluZwEJAPwHBAULcnBkQ29udHJhY3QCGHVuY2xhaW1lZFJld2FyZHNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkFA25pbAUDbmlsCQCUCgIFA25pbAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCCQEIYXNTdHJpbmcBCQCRAwIFC3Jld2FyZHNEYXRhAAAJAMwIAgkBCGFzU3RyaW5nAQkAkQMCBQtyZXdhcmRzRGF0YQABCQDMCAIFC3VzZG5SZXdhcmRzBQNuaWwFA1NFUAFpARFtZXJnZU5zYnRSRUFET05MWQIUdXNlckFkZHJlc3NNYW5kYXRvcnkJbmV3QW1vdW50BAhuc2J0RGF0YQkBCWFzQW55TGlzdAEJAPwHBAUTbnNidFN0YWtpbmdDb250cmFjdAIWbnNidFN0YWtpbmdTWVNSRUFET05MWQkAzAgCBRR1c2VyQWRkcmVzc01hbmRhdG9yeQkAzAgCBQluZXdBbW91bnQFA25pbAUDbmlsBAdhbW91bnQwCQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAAEC3N0YXJ0SGVpZ2h0AwkAZwIAAAUHYW1vdW50MAD///////////8BCQEFYXNJbnQBCQCRAwIFCG5zYnREYXRhAAIEDnN0YXJ0VGltZXN0YW1wCQELdG9UaW1lc3RhbXABBQtzdGFydEhlaWdodAQOc3RhcnRIZWlnaHROZXcDCQBnAgAABQluZXdBbW91bnQFC3N0YXJ0SGVpZ2h0AwkAZwIAAAUHYW1vdW50MAUGaGVpZ2h0BAhoYWxmTGlmZQkBDGdldEludE9yRmFpbAIFE25zYnRTdGFraW5nQ29udHJhY3QJAQtrZXlIYWxmTGlmZQAJAQVhc0ludAEJAPwHBAUMbWF0aENvbnRyYWN0AhNtZXJnZVN0YWtlc1JFQURPTkxZCQDMCAIFB2Ftb3VudDAJAMwIAgULc3RhcnRIZWlnaHQJAMwIAgUJbmV3QW1vdW50CQDMCAIFBmhlaWdodAkAzAgCBQhoYWxmTGlmZQUDbmlsBQNuaWwEEXN0YXJ0VGltZXN0YW1wTmV3CQELdG9UaW1lc3RhbXABBQ5zdGFydEhlaWdodE5ldwkAlAoCBQNuaWwJALkJAgkAzAgCAgglZCVkJWQlZAkAzAgCCQCkAwEFC3N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUOc3RhcnRUaW1lc3RhbXAJAMwIAgkApAMBBQ5zdGFydEhlaWdodE5ldwkAzAgCCQCkAwEFEXN0YXJ0VGltZXN0YW1wTmV3BQNuaWwFA1NFUAFpARtzd2FwTGltaXRDYWxjdWxhdG9yUkVBRE9OTFkDEXVzZXJBZGRyZXNzU3RyT3B0C2xpbWl0V2FudGVkCmFzc2V0SWRTdHIEDGdOc2J0Q3VycmVudAMJAAACBRF1c2VyQWRkcmVzc1N0ck9wdAIAAAAJAQVhc0ludAEICQESYXNTd2FwUGFyYW1zU1RSVUNUAQkA/AcEBRBuZXV0cmlub0NvbnRyYWN0Ahtzd2FwUGFyYW1zQnlVc2VyU1lTUkVBRE9OTFkJAMwIAgURdXNlckFkZHJlc3NTdHJPcHQJAMwIAgAABQNuaWwFA25pbAJfNAQFcHJpY2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ9jb250cm9sQ29udHJhY3QJAQ9rZXlQcmljZUJ5QXNzZXQBBQphc3NldElkU3RyCQCsAgICE05vIHByaWNlIGZvciBhc3NldCAFCmFzc2V0SWRTdHIECmlzT3V0TXVsdGkJAAACBQphc3NldElkU3RyBRVuZXV0cmlub0Fzc2V0SWRTdHJpbmcED2xpbWl0V2FudGVkVXNkbgMFCmlzT3V0TXVsdGkFC2xpbWl0V2FudGVkCQERY29udmVydFRva2VuVG9Vc2QCBQtsaW1pdFdhbnRlZAUFcHJpY2UEC2dOc2J0TmVlZGVkCQEFYXNJbnQBCQD8BwQFBHRoaXMCGHJldmVyc2VTd2FwTGltaXRSRUFET05MWQkAzAgCBQ9saW1pdFdhbnRlZFVzZG4JAMwIAgUKaXNPdXRNdWx0aQUDbmlsBQNuaWwECmdOc2J0RGVsdGEJAGUCBQtnTnNidE5lZWRlZAUMZ05zYnRDdXJyZW50CQCUCgIFA25pbAkAuQkCCQDMCAICBCVzJXMJAMwIAgkApAMBBQxnTnNidEN1cnJlbnQJAMwIAgkApAMBBQpnTnNidERlbHRhBQNuaWwFA1NFUAFpARBzd2FwSW5mb1JFQURPTkxZAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkGYW1vdW50CmFzc2V0SWRTdHIED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEBXByaWNlCQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUPbk1ldHJpY0lkeFByaWNlBA9zd2FwUGFyYW1zVHVwbGUJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD8BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgAABQNuaWwFA25pbAQSbGltaXRNYXhUb2tlbkluVXNkCAUPc3dhcFBhcmFtc1R1cGxlAl8xBA5ibGNrczJMbXRSZXNldAgFD3N3YXBQYXJhbXNUdXBsZQJfMwQMbGltaXRNYXhVc2RuCAUPc3dhcFBhcmFtc1R1cGxlAl83BAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEDGJhc2tldEFzc2V0cwkBC3ZhbHVlT3JFbHNlAgkAnQgCBRBuZXV0cmlub0NvbnRyYWN0CQEPYmFza2V0QXNzZXRzS2V5AAIFV0FWRVMECHN3YXBUeXBlAwkBCGNvbnRhaW5zAgUMYmFza2V0QXNzZXRzBQphc3NldElkU3RyAgtvdXROZXV0cmlubwMJAAACBQdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQCCG91dE11bHRpCQACAQkArAICAhNDYW4ndCBzd2FwIGFzc2V0SWQ9BQphc3NldElkU3RyBA13aXRoZHJhd1R1cGxlCQEWYXNXaXRoZHJhd1Jlc3VsdFNUUlVDVAEJAPwHBAUQbmV1dHJpbm9Db250cmFjdAIdY2FsY1dpdGhkcmF3UmVzdWx0U1lTUkVBRE9OTFkJAMwIAgUIc3dhcFR5cGUJAMwIAgUGYW1vdW50CQDMCAIFBXByaWNlCQDMCAIFCmFzc2V0SWRTdHIFA25pbAUDbmlsBAxvdXROZXRBbW91bnQIBQ13aXRoZHJhd1R1cGxlAl8xBApvdXRTdXJmQW10CAUNd2l0aGRyYXdUdXBsZQJfMwQPaW5BbXRUb1N1cmZQYXJ0CAUNd2l0aGRyYXdUdXBsZQJfNAQMb3V0RmVlQW1vdW50CAUNd2l0aGRyYXdUdXBsZQJfNgQLb3V0QW10R3Jvc3MIBQ13aXRoZHJhd1R1cGxlAl83BA13aXRoZHJhd1ByaWNlCAUNd2l0aGRyYXdUdXBsZQJfOAkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUMb3V0TmV0QW1vdW50CQDMCAIJAKQDAQUKb3V0U3VyZkFtdAkAzAgCCQCkAwEFDG91dEZlZUFtb3VudAkAzAgCCQCkAwEFDXdpdGhkcmF3UHJpY2UJAMwIAgkApAMBBQ5ibGNrczJMbXRSZXNldAkAzAgCCQCkAwEFEmxpbWl0TWF4VG9rZW5JblVzZAkAzAgCCQCkAwEFDGxpbWl0TWF4VXNkbgkAzAgCCQCkAwEFD2luQW10VG9TdXJmUGFydAUDbmlsBQNTRVABaQESc3dhcEluZm9WMlJFQURPTkxZAxV1c2VyQWRkcmVzc1N0ck9yRW1wdHkGYW1vdW50CmFzc2V0SWRTdHIED25ldXRyaW5vTWV0cmljcwkBCWFzQW55TGlzdAEJAPwHBAUMbWF0aENvbnRyYWN0AhpjYWxjTmV1dGlub01ldHJpY3NSRUFET05MWQUDbmlsBQNuaWwEBXByaWNlCQEFYXNJbnQBCQCRAwIFD25ldXRyaW5vTWV0cmljcwUPbk1ldHJpY0lkeFByaWNlBA9zd2FwUGFyYW1zVHVwbGUJARJhc1N3YXBQYXJhbXNTVFJVQ1QBCQD8BwQFEG5ldXRyaW5vQ29udHJhY3QCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBRV1c2VyQWRkcmVzc1N0ck9yRW1wdHkJAMwIAgAABQNuaWwFA25pbAQSbGltaXRNYXhUb2tlbkluVXNkCAUPc3dhcFBhcmFtc1R1cGxlAl8xBA5ibGNrczJMbXRSZXNldAgFD3N3YXBQYXJhbXNUdXBsZQJfMwQMbGltaXRNYXhVc2RuCAUPc3dhcFBhcmFtc1R1cGxlAl83BAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEDGJhc2tldEFzc2V0cwkBC3ZhbHVlT3JFbHNlAgkAnQgCBRBuZXV0cmlub0NvbnRyYWN0CQEPYmFza2V0QXNzZXRzS2V5AAIFV0FWRVMECHN3YXBUeXBlAwkBCGNvbnRhaW5zAgUMYmFza2V0QXNzZXRzBQphc3NldElkU3RyAgtvdXROZXV0cmlubwMJAAACBQdhc3NldElkBQ9uZXV0cmlub0Fzc2V0SWQCCG91dE11bHRpCQACAQkArAICAhNDYW4ndCBzd2FwIGFzc2V0SWQ9BQphc3NldElkU3RyBA13aXRoZHJhd1R1cGxlCQEWYXNXaXRoZHJhd1Jlc3VsdFNUUlVDVAEJAPwHBAUQbmV1dHJpbm9Db250cmFjdAIdY2FsY1dpdGhkcmF3UmVzdWx0U1lTUkVBRE9OTFkJAMwIAgUIc3dhcFR5cGUJAMwIAgUGYW1vdW50CQDMCAIFBXByaWNlCQDMCAIFCmFzc2V0SWRTdHIFA25pbAUDbmlsBA9vdXROZXV0cmlub0luZm8JALkJAgkAzAgCBRVuZXV0cmlub0Fzc2V0SWRTdHJpbmcJAMwIAgkApAMBCAUNd2l0aGRyYXdUdXBsZQJfOAkAzAgCCQCkAwEIBQ13aXRoZHJhd1R1cGxlAl8xCQDMCAIJAKQDAQgFDXdpdGhkcmF3VHVwbGUCXzYJAMwIAgIHMTAwMDAwMAUDbmlsBQdMSVNUU0VQBA53aXRoZHJhd0Jhc2tldAMJAAACBQhzd2FwVHlwZQILb3V0TmV1dHJpbm8FD291dE5ldXRyaW5vSW5mbwgFDXdpdGhkcmF3VHVwbGUCXzkJAJQKAgUDbmlsCQC6CQIJAMwIAgIIJWQlZCVkJXMJAMwIAgkApAMBBQ5ibGNrczJMbXRSZXNldAkAzAgCCQCkAwEFEmxpbWl0TWF4VG9rZW5JblVzZAkAzAgCCQCkAwEFDGxpbWl0TWF4VXNkbgkAzAgCBQ53aXRoZHJhd0Jhc2tldAUDbmlsBQNTRVABaQESYmFza2V0SW5mb1JFQURPTkxZAAQPbmV1dHJpbm9NZXRyaWNzCQEJYXNBbnlMaXN0AQkA/AcEBQxtYXRoQ29udHJhY3QCGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQNuaWwFA25pbAQKYmFza2V0SW5mbwkBCGFzU3RyaW5nAQkAkQMCBQ9uZXV0cmlub01ldHJpY3MFEW5NZXRyaWNCYXNrZXRJbmZvBAZiYXNrZXQJALwJAgUKYmFza2V0SW5mbwIBXwoBBm1vZGlmeQIDYWNjBGl0ZW0EBXBhcnRzCQC1CQIFBGl0ZW0FB0xJU1RTRVAEB2Fzc2V0SWQJAJEDAgUFcGFydHMAAAQFZGxvZzYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBRBuZXV0cmlub0NvbnRyYWN0CQESYmFza2V0TG9nYkRlbHRhS2V5AAIebG9nKGIsIGRlbHRhKSBrZXkgaXMgdW5kZWZpbmVkBAJENgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFEG5ldXRyaW5vQ29udHJhY3QJAQpiYXNrZXRES2V5AAISRCBrZXkgaXMgdW5kZWZpbmVkBAJiNgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFEG5ldXRyaW5vQ29udHJhY3QJAQpiYXNrZXRCS2V5AAISYiBrZXkgaXMgdW5kZWZpbmVkBAJ3NgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFEG5ldXRyaW5vQ29udHJhY3QJARZiYXNrZXRXZWlnaHRCeUFzc2V0S2V5AQUHYXNzZXRJZAkArAICCQCsAgICGFRhcmdldCB3ZWlnaHQgZm9yIGFzc2V0IAUHYXNzZXRJZAINIGlzIHVuZGVmaW5lZAQCcDYJAGQCCQBlAgUFZGxvZzYFAnc2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQQBZAkAZQIFAkQ2CQBsBgUCYjYABgUCcDYABgAGBQZIQUxGVVAJAM0IAgUDYWNjCQC5CQIJAM0IAgkAzQgCBQVwYXJ0cwkApAMBBQJ3NgkApAMBBQFkBQdMSVNUU0VQBAFiCgACJGwFBmJhc2tldAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGbW9kaWZ5AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIFA25pbAkArAICAgQlc19fCQC6CQIFAWICAV8BaQEWdXNkblN0YWtpbmdBcHJSRUFET05MWQEEZGF5cwQHdG1wRGF5cwABBA9uZXV0cmlub01ldHJpY3MJAQlhc0FueUxpc3QBCQD8BwQFDG1hdGhDb250cmFjdAIaY2FsY05ldXRpbm9NZXRyaWNzUkVBRE9OTFkFA25pbAUDbmlsBAxjdXJyZW50UHJpY2UJAQVhc0ludAEJAJEDAgUPbmV1dHJpbm9NZXRyaWNzBQ9uTWV0cmljSWR4UHJpY2UEC3dhdmVzSW5jb21lCQBoAgAABQVNVUxUOAQPaW5jb21lRm9yUGVyaW9kCQBrAwULd2F2ZXNJbmNvbWUFDGN1cnJlbnRQcmljZQUFTVVMVDgEA2FwcgkBB2NhbGNBcHIEBQtycGRDb250cmFjdAUHdG1wRGF5cwUPaW5jb21lRm9yUGVyaW9kBQVNVUxUNgkAlAoCBQNuaWwJAKwCAgIEJWRfXwkApAMBBQNhcHIBaQEWc3VyZlN0YWtpbmdBcHJSRUFET05MWQEEZGF5cwQHdG1wRGF5cwADBA9pbmNvbWVGb3JQZXJpb2QJARdjYWxjVXNkbkluY29tZUZvclBlcmlvZAIFE3N1cmZTdGFraW5nQ29udHJhY3QFB3RtcERheXMEEXN1cmZQcmljZVRvVXNkblg2AICjBQQDYXByCQEHY2FsY0FwcgQFE3N1cmZTdGFraW5nQ29udHJhY3QFB3RtcERheXMFD2luY29tZUZvclBlcmlvZAURc3VyZlByaWNlVG9Vc2RuWDYJAJQKAgUDbmlsCQCsAgICBCVkX18JAKQDAQUDYXByAWkBGHN1cmZTdGFraW5nQXByVjJSRUFET05MWQIEZGF5cw9zdXJmVXNkblByaWNlWDYEB3RtcERheXMAAwQPaW5jb21lRm9yUGVyaW9kCQEXY2FsY1VzZG5JbmNvbWVGb3JQZXJpb2QCBRNzdXJmU3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBANhcHIJAQdjYWxjQXByBAUTc3VyZlN0YWtpbmdDb250cmFjdAUHdG1wRGF5cwUPaW5jb21lRm9yUGVyaW9kBQ9zdXJmVXNkblByaWNlWDYJAJQKAgUDbmlsCQCsAgICBCVkX18JAKQDAQUDYXByAWkBFm5zYnRTdGFraW5nQXByUkVBRE9OTFkBBGRheXMEB3RtcERheXMAAwQRbnNidFByaWNlVG9Vc2RuWDYAgKToAwQPaW5jb21lRm9yUGVyaW9kCQEXY2FsY1VzZG5JbmNvbWVGb3JQZXJpb2QCBRNuc2J0U3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBANhcHIJAQdjYWxjQXByBAUTbnNidFN0YWtpbmdDb250cmFjdAUHdG1wRGF5cwUPaW5jb21lRm9yUGVyaW9kBRFuc2J0UHJpY2VUb1VzZG5YNgkAlAoCBQNuaWwJAKwCAgIEJWRfXwkApAMBBQNhcHIBaQEYbnNidFN0YWtpbmdBcHJWMlJFQURPTkxZAgRkYXlzD25zYnRVc2RuUHJpY2VYNgQHdG1wRGF5cwADBA9pbmNvbWVGb3JQZXJpb2QJARdjYWxjVXNkbkluY29tZUZvclBlcmlvZAIFE25zYnRTdGFraW5nQ29udHJhY3QFB3RtcERheXMEA2FwcgkBB2NhbGNBcHIEBRNuc2J0U3Rha2luZ0NvbnRyYWN0BQd0bXBEYXlzBQ9pbmNvbWVGb3JQZXJpb2QFD25zYnRVc2RuUHJpY2VYNgkAlAoCBQNuaWwJAKwCAgIEJWRfXwkApAMBBQNhcHIAmfVX7Q==", "height": 2462140, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6bTZzmbsMRhpbhnkQDASWPq1FvQvJwEgmGGnTMyFcrk8 Next: 9ucoZspxY9njVCMc6WaBHNusJhhEvaEkSprzXFwuv9rP Diff:
OldNewDifferences
2020 let MULT18 = toBigInt(1000000000000000000)
2121
2222 let SEP = "__"
23+
24+let LISTSEP = ":"
2325
2426 let DEFAULTSWAPFEEN2W = 5000
2527
6163 func basketAssetsKey () = "%s%s__common__basketAssets"
6264
6365
66+func basketDKey () = "%s%s__common__basketD"
67+
68+
69+func basketBKey () = "%s%s__common__basketB"
70+
71+
72+func basketLogbDeltaKey () = "%s%s__common__basketLogbDelta"
73+
74+
75+func basketWeightByAssetKey (assetId) = ("%s%s%s__common__weightByAsset__" + assetId)
76+
77+
6478 func keyPrice () = "price"
79+
80+
81+func keyPriceByAsset (assetId) = ("%s%s%s__common__priceByAsset__" + assetId)
6582
6683
6784 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
103120 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
104121
105122
106-func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
123+func convertTokenToUsd (amount,price) = fraction(amount, price, MULT8)
107124
108125
109126 func asAnyList (val) = match val {
328345
329346
330347 @Callable(i)
331-func reverseSwapLimitREADONLY (lim,isWavesSwap) = {
348+func reverseSwapLimitREADONLY (lim,isOutMulti) = {
332349 let BR = asInt(asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))[nMetricIdxBR])
333350 let gNsbt = if ((0 >= lim))
334351 then 0
335352 else {
336- let aParamX8 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
337- then keySwapAmountAParam()
338- else keyUsdnSwapAmountAParam()))
339- let bParamX16 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
340- then keySwapAmountBParam()
341- else keyUsdnSwapAmountBParam()))
342- let limDivAX8 = if (isWavesSwap)
343- then fraction(toBigInt(lim), MULTX10, aParamX8)
344- else fraction(fraction(toBigInt(lim), MULTX10, aParamX8), MULTX6, toBigInt(BR))
353+ let aParamX8 = toBigInt(getIntOrFail(mathContract, if (isOutMulti)
354+ then keyUsdnSwapAmountAParam()
355+ else keySwapAmountAParam()))
356+ let bParamX16 = toBigInt(getIntOrFail(mathContract, if (isOutMulti)
357+ then keyUsdnSwapAmountBParam()
358+ else keySwapAmountBParam()))
359+ let limDivAX8 = if (isOutMulti)
360+ then fraction(fraction(toBigInt(lim), MULTX10, aParamX8), MULTX6, toBigInt(BR))
361+ else fraction(toBigInt(lim), MULTX10, aParamX8)
345362 let revBX16 = fraction(MULTX16, MULTX16, bParamX16)
346363 toInt(pow(limDivAX8, 8, revBX16, 16, 6, CEILING))
347364 }
360377 let gnsbtFromSurfDiff = asInt(invoke(surfStakingContract, "gnsbtFromSurfSYSREADONLY", [additionalSurfToStakeOrZero], nil))
361378 let gNsbtDiff = (gnsbtFromNsbtDiff + gnsbtFromSurfDiff)
362379 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
380+ let limitMaxTokenUsd = swapParamsTuple._1
363381 let blcks2LmtReset = swapParamsTuple._3
364382 let gnsbtAmt = swapParamsTuple._4
365383 let gnsbtAmtTotal = swapParamsTuple._5
366- let limitMaxWaves = swapParamsTuple._6
367384 let limitMaxUsdn = swapParamsTuple._7
368385 let swapParamsTupleNEW = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, gNsbtDiff], nil))
386+ let limitMaxTokenUsdNEW = swapParamsTupleNEW._1
369387 let blcks2LmtResetNEW = swapParamsTupleNEW._3
370388 let gnsbtAmtNEW = swapParamsTupleNEW._4
371389 let gnsbtAmtTotalNEW = swapParamsTupleNEW._5
372- let limitMaxWavesNEW = swapParamsTupleNEW._6
373390 let limitMaxUsdnNEW = swapParamsTupleNEW._7
374391 let nsbtBalance = if ((userAddressStrOrEmpty != ""))
375392 then assetBalance(userAddressOrThis, nsbtAssetId)
415432 let votingPowerEtaNew = if ((vpEffectiveHeightNEW == 0))
416433 then height
417434 else vpEffectiveHeightNEW
418- $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])
435+ $Tuple2(nil, [0, nsbtBalance, surfBalance, nsbtBalanceNew, surfBalanceNew, gnsbtAmtFromNsbt, gnsbtAmtFromSurf, gnsbtAmtFromNsbtNEW, gnsbtAmtFromSurfNEW, gnsbtFromNsbtTotal, gnsbtFromSurfTotal, gnsbtFromNsbtTotalNEW, gnsbtFromSurfTotalNEW, limitMaxUsdn, limitMaxTokenUsd, limitMaxUsdnNEW, limitMaxTokenUsdNEW, blcks2LmtReset, blcks2LmtResetNEW, votingPower, votingPowerNew, votingPowerMax, votingPowerMaxNew, votingPowerEta, votingPowerEtaNew])
419436 }
420437
421438
477494 let gNsbtCurrent = if ((userAddressStrOpt == ""))
478495 then 0
479496 else asInt(asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOpt, 0], nil))._4)
480- let limitWantedUsdn = if ((assetIdStr == "WAVES"))
481- then convertWavesToNeutrino(limitWanted, getIntegerValue(controlContract, keyPrice()))
482- else limitWanted
483- let gNsbtNeeded = asInt(invoke(this, "reverseSwapLimitREADONLY", [limitWantedUsdn, (assetIdStr == "WAVES")], nil))
497+ let price = valueOrErrorMessage(getInteger(controlContract, keyPriceByAsset(assetIdStr)), ("No price for asset " + assetIdStr))
498+ let isOutMulti = (assetIdStr == neutrinoAssetIdString)
499+ let limitWantedUsdn = if (isOutMulti)
500+ then limitWanted
501+ else convertTokenToUsd(limitWanted, price)
502+ let gNsbtNeeded = asInt(invoke(this, "reverseSwapLimitREADONLY", [limitWantedUsdn, isOutMulti], nil))
484503 let gNsbtDelta = (gNsbtNeeded - gNsbtCurrent)
485504 $Tuple2(nil, makeString(["%s%s", toString(gNsbtCurrent), toString(gNsbtDelta)], SEP))
486505 }
492511 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
493512 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
494513 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
514+ let limitMaxTokenInUsd = swapParamsTuple._1
495515 let blcks2LmtReset = swapParamsTuple._3
496- let limitMaxWaves = swapParamsTuple._6
497516 let limitMaxUsdn = swapParamsTuple._7
498517 let assetId = fromBase58String(assetIdStr)
499518 let basketAssets = valueOrElse(getString(neutrinoContract, basketAssetsKey()), "WAVES")
504523 else throw(("Can't swap assetId=" + assetIdStr))
505524 let withdrawTuple = asWithdrawResultSTRUCT(invoke(neutrinoContract, "calcWithdrawResultSYSREADONLY", [swapType, amount, price, assetIdStr], nil))
506525 let outNetAmount = withdrawTuple._1
507- let outAssetId = withdrawTuple._2
508526 let outSurfAmt = withdrawTuple._3
509527 let inAmtToSurfPart = withdrawTuple._4
510- let unleaseAmt = withdrawTuple._5
511528 let outFeeAmount = withdrawTuple._6
512529 let outAmtGross = withdrawTuple._7
513530 let withdrawPrice = withdrawTuple._8
514- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxWaves), toString(limitMaxUsdn), toString(inAmtToSurfPart)], SEP))
531+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxTokenInUsd), toString(limitMaxUsdn), toString(inAmtToSurfPart)], SEP))
515532 }
516533
517534
521538 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
522539 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
523540 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
541+ let limitMaxTokenInUsd = swapParamsTuple._1
524542 let blcks2LmtReset = swapParamsTuple._3
525- let limitMaxWaves = swapParamsTuple._6
526543 let limitMaxUsdn = swapParamsTuple._7
527544 let assetId = fromBase58String(assetIdStr)
528545 let basketAssets = valueOrElse(getString(neutrinoContract, basketAssetsKey()), "WAVES")
532549 then "outMulti"
533550 else throw(("Can't swap assetId=" + assetIdStr))
534551 let withdrawTuple = asWithdrawResultSTRUCT(invoke(neutrinoContract, "calcWithdrawResultSYSREADONLY", [swapType, amount, price, assetIdStr], nil))
535- let outNetAmount = withdrawTuple._1
536- let outAssetId = withdrawTuple._2
537- let outSurfAmt = withdrawTuple._3
538- let inAmtToSurfPart = withdrawTuple._4
539- let unleaseAmt = withdrawTuple._5
540- let outFeeAmount = withdrawTuple._6
541- let outAmtGross = withdrawTuple._7
542- let withdrawPrice = withdrawTuple._8
543- let withdrawBasket = withdrawTuple._9
544- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%s", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxWaves), toString(limitMaxUsdn), toString(inAmtToSurfPart), withdrawBasket], SEP))
552+ let outNeutrinoInfo = makeString([neutrinoAssetIdString, toString(withdrawTuple._8), toString(withdrawTuple._1), toString(withdrawTuple._6), "1000000"], LISTSEP)
553+ let withdrawBasket = if ((swapType == "outNeutrino"))
554+ then outNeutrinoInfo
555+ else withdrawTuple._9
556+ $Tuple2(nil, makeString_2C(["%d%d%d%s", toString(blcks2LmtReset), toString(limitMaxTokenInUsd), toString(limitMaxUsdn), withdrawBasket], SEP))
545557 }
546558
547559
550562 func basketInfoREADONLY () = {
551563 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
552564 let basketInfo = asString(neutrinoMetrics[nMetricBasketInfo])
553- $Tuple2(nil, makeString(["%s", basketInfo], SEP))
565+ let basket = split_4C(basketInfo, "_")
566+ func modify (acc,item) = {
567+ let parts = split(item, LISTSEP)
568+ let assetId = parts[0]
569+ let dlog6 = valueOrErrorMessage(getInteger(neutrinoContract, basketLogbDeltaKey()), "log(b, delta) key is undefined")
570+ let D6 = valueOrErrorMessage(getInteger(neutrinoContract, basketDKey()), "D key is undefined")
571+ let b6 = valueOrErrorMessage(getInteger(neutrinoContract, basketBKey()), "b key is undefined")
572+ let w6 = valueOrErrorMessage(getInteger(neutrinoContract, basketWeightByAssetKey(assetId)), (("Target weight for asset " + assetId) + " is undefined"))
573+ let p6 = ((dlog6 - w6) + parseIntValue(parts[1]))
574+ let d = (D6 - pow(b6, 6, p6, 6, 6, HALFUP))
575+ (acc :+ makeString(((parts :+ toString(w6)) :+ toString(d)), LISTSEP))
576+ }
577+
578+ let b = {
579+ let $l = basket
580+ let $s = size($l)
581+ let $acc0 = nil
582+ func $f0_1 ($a,$i) = if (($i >= $s))
583+ then $a
584+ else modify($a, $l[$i])
585+
586+ func $f0_2 ($a,$i) = if (($i >= $s))
587+ then $a
588+ else throw("List size exceeds 10")
589+
590+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
591+ }
592+ $Tuple2(nil, ("%s__" + makeString_2C(b, "_")))
554593 }
555594
556595
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 = "__"
23+
24+let LISTSEP = ":"
2325
2426 let DEFAULTSWAPFEEN2W = 5000
2527
2628 let DEFAULTSWAPFEEW2N = 20000
2729
2830 let BRPROTECTED = 100000
2931
3032 let WAVESID = fromBase58String("WAVES")
3133
3234 let DAYMILLIS = 86400000
3335
3436 func keyNeutrinoAssetId () = "neutrino_asset_id"
3537
3638
3739 func keyNsbtAssetId () = "bond_asset_id"
3840
3941
4042 func keySurfAssetId () = "surf_asset_id"
4143
4244
4345 func keySwapAmountAParam () = "%s%s__config__swapAParam"
4446
4547
4648 func keySwapAmountBParam () = "%s%s__config__swapBParam"
4749
4850
4951 func keyUsdnSwapAmountAParam () = "%s%s__config__usdnSwapAParam"
5052
5153
5254 func keyUsdnSwapAmountBParam () = "%s%s__config__usdnSwapBParam"
5355
5456
5557 func keyNsbtLockContract () = "%s__nsbtLockContract"
5658
5759
5860 func keyMathContract () = "%s__mathContract"
5961
6062
6163 func basketAssetsKey () = "%s%s__common__basketAssets"
6264
6365
66+func basketDKey () = "%s%s__common__basketD"
67+
68+
69+func basketBKey () = "%s%s__common__basketB"
70+
71+
72+func basketLogbDeltaKey () = "%s%s__common__basketLogbDelta"
73+
74+
75+func basketWeightByAssetKey (assetId) = ("%s%s%s__common__weightByAsset__" + assetId)
76+
77+
6478 func keyPrice () = "price"
79+
80+
81+func keyPriceByAsset (assetId) = ("%s%s%s__common__priceByAsset__" + assetId)
6582
6683
6784 func keyLockParamStartBlock (userAddress) = makeString(["%s%s%s", "paramByUser", userAddress, "start"], SEP)
6885
6986
7087 func keyHalfLife () = "%s__halfLife"
7188
7289
7390 func keyMinLockAmount () = "%s__minLockAmount"
7491
7592
7693 func keyMinWavesForNsbtBuy () = "min_waves_nsbt_buy"
7794
7895
7996 func keyMinNsbtSell () = "min_nsbt_sell"
8097
8198
8299 func keyStatsDepositAmtByDay (timestamp) = makeString(["%s%s%d", "stats", "depositAmtByDay", toString(timestamp)], SEP)
83100
84101
85102 func toStartOfDay (timestamp) = ((timestamp / DAYMILLIS) * DAYMILLIS)
86103
87104
88105 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
89106
90107
91108 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
92109
93110
94111 func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
95112
96113
97114 func getIntOrElse (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
98115
99116
100117 func getStrOrElse (address,key,defaultVal) = valueOrElse(getString(address, key), defaultVal)
101118
102119
103120 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
104121
105122
106-func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
123+func convertTokenToUsd (amount,price) = fraction(amount, price, MULT8)
107124
108125
109126 func asAnyList (val) = match val {
110127 case valAnyList: List[Any] =>
111128 valAnyList
112129 case _ =>
113130 throw("fail to cast into List[Any]")
114131 }
115132
116133
117134 func asInt (val) = match val {
118135 case valInt: Int =>
119136 valInt
120137 case _ =>
121138 throw("fail to cast into Int")
122139 }
123140
124141
125142 func asString (val) = match val {
126143 case valStr: String =>
127144 valStr
128145 case _ =>
129146 throw("fail to cast into String")
130147 }
131148
132149
133150 func asTuple2Ints (val) = match val {
134151 case v: (Int, Int) =>
135152 v
136153 case _ =>
137154 throw("fail to cast into Tuple2 ints")
138155 }
139156
140157
141158 func asSwapParamsSTRUCT (val) = match val {
142159 case struct: (Int, Int, Int, Int, Int, Int, Int) =>
143160 struct
144161 case _ =>
145162 throw("fail to cast into SwapParamsSTRUCT")
146163 }
147164
148165
149166 func asWithdrawResultSTRUCT (val) = match val {
150167 case struct: (Int, Unit, Int, Int, Int, Int, Int, Int, String)|(Int, ByteVector, Int, Int, Int, Int, Int, Int, String) =>
151168 struct
152169 case _ =>
153170 throw("fail to cast into WithdrawResult")
154171 }
155172
156173
157174 func toTimestamp (start) = if ((0 > start))
158175 then -1
159176 else match blockInfoByHeight(start) {
160177 case block: BlockInfo =>
161178 block.timestamp
162179 case _ =>
163180 -1
164181 }
165182
166183
167184 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
168185
169186
170187 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
171188
172189
173190 let nMetricIdxPrice = 0
174191
175192 let nMetricIdxUsdnLockedBalance = 1
176193
177194 let nMetricIdxWavesLockedBalance = 2
178195
179196 let nMetricIdxReserve = 3
180197
181198 let nMetricIdxReserveInUsdn = 4
182199
183200 let nMetricIdxUsdnSupply = 5
184201
185202 let nMetricIdxSurplus = 6
186203
187204 let nMetricIdxSurplusPercent = 7
188205
189206 let nMetricIdxBR = 8
190207
191208 let nMetricIdxNsbtSupply = 9
192209
193210 let nMetricIdxMaxNsbtSupply = 10
194211
195212 let nMetricIdxSurfSupply = 11
196213
197214 let nMetricUsdnUsdtPeg = 12
198215
199216 let nMetricCurrentPriceAdj = 13
200217
201218 let nMetricBasketInfo = 14
202219
203220 let nMetricWeightedPrice = 15
204221
205222 let nMetricTotalReservesUsd = 16
206223
207224 let IdxControlCfgNeutrinoDapp = 1
208225
209226 let IdxControlCfgAuctionDapp = 2
210227
211228 let IdxControlCfgRpdDapp = 3
212229
213230 let IdxControlCfgMathDapp = 4
214231
215232 let IdxControlCfgLiquidationDapp = 5
216233
217234 let IdxControlCfgRestDapp = 6
218235
219236 let IdxControlCfgNodeRegistryDapp = 7
220237
221238 let IdxControlCfgNsbtStakingDapp = 8
222239
223240 let IdxControlCfgMediatorDapp = 9
224241
225242 let IdxControlCfgSurfStakingDapp = 10
226243
227244 let IdxControlCfgGnsbtControllerDapp = 11
228245
229246 let bFuncIdxSurf = 0
230247
231248 let bFuncIdxWaves = 1
232249
233250 let bFuncIdxUsdn = 2
234251
235252 let bFuncIdxReserveStart = 3
236253
237254 let bFuncIdxSupplyStart = 4
238255
239256 let bFuncIdxBRStart = 5
240257
241258 let bFuncIdxReserveEnd = 6
242259
243260 let bFuncIdxSupplyEnd = 7
244261
245262 let bFuncIdxBREnd = 8
246263
247264 let bFuncIdxRest = 9
248265
249266 let bFuncIdxWavesPrice = 10
250267
251268 func keyControlAddress () = "%s%s__config__controlAddress"
252269
253270
254271 func keyControlCfg () = "%s__controlConfig"
255272
256273
257274 func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
258275
259276
260277 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
261278
262279
263280 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
264281
265282 let controlCfg = readControlCfgOrFail(controlContract)
266283
267284 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
268285
269286 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
270287
271288 let auctionContract = getContractAddressOrFail(controlCfg, IdxControlCfgAuctionDapp)
272289
273290 let liquidationContract = getContractAddressOrFail(controlCfg, IdxControlCfgLiquidationDapp)
274291
275292 let rpdContract = getContractAddressOrFail(controlCfg, IdxControlCfgRpdDapp)
276293
277294 let nsbtStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgNsbtStakingDapp)
278295
279296 let surfStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgSurfStakingDapp)
280297
281298 let gnsbtControllerContract = getContractAddressOrFail(controlCfg, IdxControlCfgGnsbtControllerDapp)
282299
283300 let neutrinoAssetIdString = getStringOrFail(neutrinoContract, keyNeutrinoAssetId())
284301
285302 let neutrinoAssetId = fromBase58String(neutrinoAssetIdString)
286303
287304 let nsbtAssetIdStr = getStringValue(neutrinoContract, keyNsbtAssetId())
288305
289306 let nsbtAssetId = fromBase58String(nsbtAssetIdStr)
290307
291308 let surfAssetIdStr = getStringValue(auctionContract, keySurfAssetId())
292309
293310 let surfAssetId = fromBase58String(surfAssetIdStr)
294311
295312 func readUsdnIncomeForDay (stakingAcc,startOfDayTimestamp,neutrinoMetrics) = {
296313 let amtByDayKEY = keyStatsDepositAmtByDay(startOfDayTimestamp)
297314 let incomeStr = getStrOrElse(stakingAcc, amtByDayKEY, "%s%s__0__0")
298315 let incomeArray = split(incomeStr, SEP)
299316 let wavesAmt = parseIntValue(incomeArray[1])
300317 let usdnAmt = parseIntValue(incomeArray[2])
301318 let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
302319 let wavesAsUsdnAmt = fraction(wavesAmt, currentPrice, MULT8)
303320 (wavesAsUsdnAmt + usdnAmt)
304321 }
305322
306323
307324 func calcUsdnIncomeForPeriod (stakingAcc,days) = {
308325 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
309326 let currStartOfDay = toStartOfDay(lastBlock.timestamp)
310327 let startTimestamp = (currStartOfDay - (DAYMILLIS * (days + 1)))
311328 let endTimestamp = (currStartOfDay - DAYMILLIS)
312329 let startUsdnAmtTMP = readUsdnIncomeForDay(stakingAcc, startTimestamp, neutrinoMetrics)
313330 let endUsdnAmt = readUsdnIncomeForDay(stakingAcc, endTimestamp, neutrinoMetrics)
314331 let startUsdnAmt = if ((startUsdnAmtTMP == 0))
315332 then endUsdnAmt
316333 else startUsdnAmtTMP
317334 (endUsdnAmt - startUsdnAmt)
318335 }
319336
320337
321338 func calcApr (stakingAcc,periodInDays,incomeForPeriod,stakingAssetPriceToUsdnX6) = {
322339 let totalStaked = getIntOrElse(stakingAcc, "%s%s__stats__activeTotalLocked", 1)
323340 let totalStakedInUsdn = fraction(totalStaked, stakingAssetPriceToUsdnX6, MULT6)
324341 if ((0 > incomeForPeriod))
325342 then 0
326343 else fraction((incomeForPeriod * MULT6), 365, (totalStakedInUsdn * periodInDays))
327344 }
328345
329346
330347 @Callable(i)
331-func reverseSwapLimitREADONLY (lim,isWavesSwap) = {
348+func reverseSwapLimitREADONLY (lim,isOutMulti) = {
332349 let BR = asInt(asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))[nMetricIdxBR])
333350 let gNsbt = if ((0 >= lim))
334351 then 0
335352 else {
336- let aParamX8 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
337- then keySwapAmountAParam()
338- else keyUsdnSwapAmountAParam()))
339- let bParamX16 = toBigInt(getIntOrFail(mathContract, if (isWavesSwap)
340- then keySwapAmountBParam()
341- else keyUsdnSwapAmountBParam()))
342- let limDivAX8 = if (isWavesSwap)
343- then fraction(toBigInt(lim), MULTX10, aParamX8)
344- else fraction(fraction(toBigInt(lim), MULTX10, aParamX8), MULTX6, toBigInt(BR))
353+ let aParamX8 = toBigInt(getIntOrFail(mathContract, if (isOutMulti)
354+ then keyUsdnSwapAmountAParam()
355+ else keySwapAmountAParam()))
356+ let bParamX16 = toBigInt(getIntOrFail(mathContract, if (isOutMulti)
357+ then keyUsdnSwapAmountBParam()
358+ else keySwapAmountBParam()))
359+ let limDivAX8 = if (isOutMulti)
360+ then fraction(fraction(toBigInt(lim), MULTX10, aParamX8), MULTX6, toBigInt(BR))
361+ else fraction(toBigInt(lim), MULTX10, aParamX8)
345362 let revBX16 = fraction(MULTX16, MULTX16, bParamX16)
346363 toInt(pow(limDivAX8, 8, revBX16, 16, 6, CEILING))
347364 }
348365 $Tuple2(nil, gNsbt)
349366 }
350367
351368
352369
353370 @Callable(i)
354371 func gnsbtInfoINTERNAL (userAddressStrOrEmpty,additionalNsbtToStakeOrZero,additionalSurfToStakeOrZero) = {
355372 let userAddressOrThis = if ((userAddressStrOrEmpty != ""))
356373 then addressFromStringValue(userAddressStrOrEmpty)
357374 else this
358375 let currentPrice = getIntegerValue(controlContract, keyPrice())
359376 let gnsbtFromNsbtDiff = additionalNsbtToStakeOrZero
360377 let gnsbtFromSurfDiff = asInt(invoke(surfStakingContract, "gnsbtFromSurfSYSREADONLY", [additionalSurfToStakeOrZero], nil))
361378 let gNsbtDiff = (gnsbtFromNsbtDiff + gnsbtFromSurfDiff)
362379 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
380+ let limitMaxTokenUsd = swapParamsTuple._1
363381 let blcks2LmtReset = swapParamsTuple._3
364382 let gnsbtAmt = swapParamsTuple._4
365383 let gnsbtAmtTotal = swapParamsTuple._5
366- let limitMaxWaves = swapParamsTuple._6
367384 let limitMaxUsdn = swapParamsTuple._7
368385 let swapParamsTupleNEW = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, gNsbtDiff], nil))
386+ let limitMaxTokenUsdNEW = swapParamsTupleNEW._1
369387 let blcks2LmtResetNEW = swapParamsTupleNEW._3
370388 let gnsbtAmtNEW = swapParamsTupleNEW._4
371389 let gnsbtAmtTotalNEW = swapParamsTupleNEW._5
372- let limitMaxWavesNEW = swapParamsTupleNEW._6
373390 let limitMaxUsdnNEW = swapParamsTupleNEW._7
374391 let nsbtBalance = if ((userAddressStrOrEmpty != ""))
375392 then assetBalance(userAddressOrThis, nsbtAssetId)
376393 else 0
377394 let surfBalance = if ((userAddressStrOrEmpty != ""))
378395 then assetBalance(userAddressOrThis, surfAssetId)
379396 else 0
380397 let nsbtBalanceDiff = if ((additionalNsbtToStakeOrZero >= 0))
381398 then additionalNsbtToStakeOrZero
382399 else {
383400 let nsbtUnstakingData = asAnyList(invoke(nsbtStakingContract, "nsbtUnstakingSYSREADONLY", [userAddressStrOrEmpty, (-1 * additionalNsbtToStakeOrZero)], nil))
384401 let nsbtReceiveAmount = asInt(nsbtUnstakingData[2])
385402 let result = -(nsbtReceiveAmount)
386403 result
387404 }
388405 let nsbtBalanceNew = (nsbtBalance - nsbtBalanceDiff)
389406 let surfBalanceNew = (surfBalance - additionalSurfToStakeOrZero)
390407 let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [userAddressStrOrEmpty, additionalNsbtToStakeOrZero, additionalSurfToStakeOrZero], nil))
391408 let gnsbtUser = asInt(gnsbtData[0])
392409 let gnsbtTotal = asInt(gnsbtData[1])
393410 let nsbtData = asAnyList(gnsbtData[2])
394411 let surfData = asAnyList(gnsbtData[3])
395412 let vpEffectiveHeight = asInt(gnsbtData[4])
396413 let vpEffectiveHeightNEW = asInt(gnsbtData[5])
397414 let gnsbtAmtFromNsbt = asInt(nsbtData[2])
398415 let gnsbtAmtFromSurf = asInt(surfData[2])
399416 let gnsbtAmtFromNsbtNEW = (gnsbtAmtFromNsbt + gnsbtFromNsbtDiff)
400417 let gnsbtAmtFromSurfNEW = (gnsbtAmtFromSurf + gnsbtFromSurfDiff)
401418 let gnsbtFromNsbtTotal = asInt(nsbtData[3])
402419 let gnsbtFromSurfTotal = asInt(surfData[3])
403420 let gnsbtFromSurfActiveTotal = 0
404421 let gnsbtFromSurfFrozenTotal = gnsbtFromSurfTotal
405422 let gnsbtFromNsbtTotalNEW = (gnsbtFromNsbtTotal + gnsbtFromNsbtDiff)
406423 let gnsbtFromSurfTotalNEW = (gnsbtFromSurfTotal + gnsbtFromSurfDiff)
407424 let gnsbtFromSurfFrozenTotalNEW = gnsbtFromSurfTotalNEW
408425 let votingPower = fraction(gnsbtAmtFromNsbt, MULT8, (gnsbtFromNsbtTotal + gnsbtFromSurfActiveTotal))
409426 let votingPowerNew = fraction(gnsbtAmtFromNsbtNEW, MULT8, (gnsbtFromNsbtTotalNEW + gnsbtFromSurfActiveTotal))
410427 let votingPowerMax = fraction((gnsbtAmtFromNsbt + gnsbtAmtFromSurf), MULT8, ((gnsbtFromNsbtTotal + gnsbtFromSurfActiveTotal) + gnsbtFromSurfFrozenTotal))
411428 let votingPowerMaxNew = fraction((gnsbtAmtFromNsbtNEW + gnsbtAmtFromSurfNEW), MULT8, ((gnsbtFromNsbtTotalNEW + gnsbtFromSurfActiveTotal) + gnsbtFromSurfFrozenTotalNEW))
412429 let votingPowerEta = if ((vpEffectiveHeight == 0))
413430 then height
414431 else vpEffectiveHeight
415432 let votingPowerEtaNew = if ((vpEffectiveHeightNEW == 0))
416433 then height
417434 else vpEffectiveHeightNEW
418- $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])
435+ $Tuple2(nil, [0, nsbtBalance, surfBalance, nsbtBalanceNew, surfBalanceNew, gnsbtAmtFromNsbt, gnsbtAmtFromSurf, gnsbtAmtFromNsbtNEW, gnsbtAmtFromSurfNEW, gnsbtFromNsbtTotal, gnsbtFromSurfTotal, gnsbtFromNsbtTotalNEW, gnsbtFromSurfTotalNEW, limitMaxUsdn, limitMaxTokenUsd, limitMaxUsdnNEW, limitMaxTokenUsdNEW, blcks2LmtReset, blcks2LmtResetNEW, votingPower, votingPowerNew, votingPowerMax, votingPowerMaxNew, votingPowerEta, votingPowerEtaNew])
419436 }
420437
421438
422439
423440 @Callable(i)
424441 func gnsbtInfoREADONLY (userAddressStrOrEmpty,additionalNsbtToStakeOrZero,additionalSurfToStakeOrZero) = {
425442 let gnsbtInfoDATA = asAnyList(invoke(this, "gnsbtInfoINTERNAL", [userAddressStrOrEmpty, additionalNsbtToStakeOrZero, additionalSurfToStakeOrZero], nil))
426443 $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))
427444 }
428445
429446
430447
431448 @Callable(i)
432449 func gnsbtEffectiveREADONLY (userAddressStrOrEmpty) = {
433450 let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [userAddressStrOrEmpty, 0, 0], nil))
434451 let nsbtData = asAnyList(gnsbtData[2])
435452 let userFromNsbt = asInt(nsbtData[2])
436453 let totalFromNsbt = asInt(nsbtData[3])
437454 let userMatureFromSurf = asInt(gnsbtData[9])
438455 let totalMatureFromSurf = asInt(gnsbtData[6])
439456 $Tuple2(nil, makeString(["%d%d", toString((totalFromNsbt + totalMatureFromSurf)), toString((userFromNsbt + userMatureFromSurf))], SEP))
440457 }
441458
442459
443460
444461 @Callable(i)
445462 func rewardInfoREADONLY (userAddressStrOrEmpty) = {
446463 let rewardsData = asAnyList(invoke(gnsbtControllerContract, "gnsbtRewardsSYSREADONLY", [userAddressStrOrEmpty], nil))
447464 let usdnRewards = asString(invoke(rpdContract, "unclaimedRewardsREADONLY", [userAddressStrOrEmpty], nil))
448465 $Tuple2(nil, makeString(["%s%s%s", asString(rewardsData[0]), asString(rewardsData[1]), usdnRewards], SEP))
449466 }
450467
451468
452469
453470 @Callable(i)
454471 func mergeNsbtREADONLY (userAddressMandatory,newAmount) = {
455472 let nsbtData = asAnyList(invoke(nsbtStakingContract, "nsbtStakingSYSREADONLY", [userAddressMandatory, newAmount], nil))
456473 let amount0 = asInt(nsbtData[0])
457474 let startHeight = if ((0 >= amount0))
458475 then -1
459476 else asInt(nsbtData[2])
460477 let startTimestamp = toTimestamp(startHeight)
461478 let startHeightNew = if ((0 >= newAmount))
462479 then startHeight
463480 else if ((0 >= amount0))
464481 then height
465482 else {
466483 let halfLife = getIntOrFail(nsbtStakingContract, keyHalfLife())
467484 asInt(invoke(mathContract, "mergeStakesREADONLY", [amount0, startHeight, newAmount, height, halfLife], nil))
468485 }
469486 let startTimestampNew = toTimestamp(startHeightNew)
470487 $Tuple2(nil, makeString(["%d%d%d%d", toString(startHeight), toString(startTimestamp), toString(startHeightNew), toString(startTimestampNew)], SEP))
471488 }
472489
473490
474491
475492 @Callable(i)
476493 func swapLimitCalculatorREADONLY (userAddressStrOpt,limitWanted,assetIdStr) = {
477494 let gNsbtCurrent = if ((userAddressStrOpt == ""))
478495 then 0
479496 else asInt(asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOpt, 0], nil))._4)
480- let limitWantedUsdn = if ((assetIdStr == "WAVES"))
481- then convertWavesToNeutrino(limitWanted, getIntegerValue(controlContract, keyPrice()))
482- else limitWanted
483- let gNsbtNeeded = asInt(invoke(this, "reverseSwapLimitREADONLY", [limitWantedUsdn, (assetIdStr == "WAVES")], nil))
497+ let price = valueOrErrorMessage(getInteger(controlContract, keyPriceByAsset(assetIdStr)), ("No price for asset " + assetIdStr))
498+ let isOutMulti = (assetIdStr == neutrinoAssetIdString)
499+ let limitWantedUsdn = if (isOutMulti)
500+ then limitWanted
501+ else convertTokenToUsd(limitWanted, price)
502+ let gNsbtNeeded = asInt(invoke(this, "reverseSwapLimitREADONLY", [limitWantedUsdn, isOutMulti], nil))
484503 let gNsbtDelta = (gNsbtNeeded - gNsbtCurrent)
485504 $Tuple2(nil, makeString(["%s%s", toString(gNsbtCurrent), toString(gNsbtDelta)], SEP))
486505 }
487506
488507
489508
490509 @Callable(i)
491510 func swapInfoREADONLY (userAddressStrOrEmpty,amount,assetIdStr) = {
492511 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
493512 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
494513 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
514+ let limitMaxTokenInUsd = swapParamsTuple._1
495515 let blcks2LmtReset = swapParamsTuple._3
496- let limitMaxWaves = swapParamsTuple._6
497516 let limitMaxUsdn = swapParamsTuple._7
498517 let assetId = fromBase58String(assetIdStr)
499518 let basketAssets = valueOrElse(getString(neutrinoContract, basketAssetsKey()), "WAVES")
500519 let swapType = if (contains(basketAssets, assetIdStr))
501520 then "outNeutrino"
502521 else if ((assetId == neutrinoAssetId))
503522 then "outMulti"
504523 else throw(("Can't swap assetId=" + assetIdStr))
505524 let withdrawTuple = asWithdrawResultSTRUCT(invoke(neutrinoContract, "calcWithdrawResultSYSREADONLY", [swapType, amount, price, assetIdStr], nil))
506525 let outNetAmount = withdrawTuple._1
507- let outAssetId = withdrawTuple._2
508526 let outSurfAmt = withdrawTuple._3
509527 let inAmtToSurfPart = withdrawTuple._4
510- let unleaseAmt = withdrawTuple._5
511528 let outFeeAmount = withdrawTuple._6
512529 let outAmtGross = withdrawTuple._7
513530 let withdrawPrice = withdrawTuple._8
514- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxWaves), toString(limitMaxUsdn), toString(inAmtToSurfPart)], SEP))
531+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxTokenInUsd), toString(limitMaxUsdn), toString(inAmtToSurfPart)], SEP))
515532 }
516533
517534
518535
519536 @Callable(i)
520537 func swapInfoV2READONLY (userAddressStrOrEmpty,amount,assetIdStr) = {
521538 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
522539 let price = asInt(neutrinoMetrics[nMetricIdxPrice])
523540 let swapParamsTuple = asSwapParamsSTRUCT(invoke(neutrinoContract, "swapParamsByUserSYSREADONLY", [userAddressStrOrEmpty, 0], nil))
541+ let limitMaxTokenInUsd = swapParamsTuple._1
524542 let blcks2LmtReset = swapParamsTuple._3
525- let limitMaxWaves = swapParamsTuple._6
526543 let limitMaxUsdn = swapParamsTuple._7
527544 let assetId = fromBase58String(assetIdStr)
528545 let basketAssets = valueOrElse(getString(neutrinoContract, basketAssetsKey()), "WAVES")
529546 let swapType = if (contains(basketAssets, assetIdStr))
530547 then "outNeutrino"
531548 else if ((assetId == neutrinoAssetId))
532549 then "outMulti"
533550 else throw(("Can't swap assetId=" + assetIdStr))
534551 let withdrawTuple = asWithdrawResultSTRUCT(invoke(neutrinoContract, "calcWithdrawResultSYSREADONLY", [swapType, amount, price, assetIdStr], nil))
535- let outNetAmount = withdrawTuple._1
536- let outAssetId = withdrawTuple._2
537- let outSurfAmt = withdrawTuple._3
538- let inAmtToSurfPart = withdrawTuple._4
539- let unleaseAmt = withdrawTuple._5
540- let outFeeAmount = withdrawTuple._6
541- let outAmtGross = withdrawTuple._7
542- let withdrawPrice = withdrawTuple._8
543- let withdrawBasket = withdrawTuple._9
544- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%s", toString(outNetAmount), toString(outSurfAmt), toString(outFeeAmount), toString(withdrawPrice), toString(blcks2LmtReset), toString(limitMaxWaves), toString(limitMaxUsdn), toString(inAmtToSurfPart), withdrawBasket], SEP))
552+ let outNeutrinoInfo = makeString([neutrinoAssetIdString, toString(withdrawTuple._8), toString(withdrawTuple._1), toString(withdrawTuple._6), "1000000"], LISTSEP)
553+ let withdrawBasket = if ((swapType == "outNeutrino"))
554+ then outNeutrinoInfo
555+ else withdrawTuple._9
556+ $Tuple2(nil, makeString_2C(["%d%d%d%s", toString(blcks2LmtReset), toString(limitMaxTokenInUsd), toString(limitMaxUsdn), withdrawBasket], SEP))
545557 }
546558
547559
548560
549561 @Callable(i)
550562 func basketInfoREADONLY () = {
551563 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
552564 let basketInfo = asString(neutrinoMetrics[nMetricBasketInfo])
553- $Tuple2(nil, makeString(["%s", basketInfo], SEP))
565+ let basket = split_4C(basketInfo, "_")
566+ func modify (acc,item) = {
567+ let parts = split(item, LISTSEP)
568+ let assetId = parts[0]
569+ let dlog6 = valueOrErrorMessage(getInteger(neutrinoContract, basketLogbDeltaKey()), "log(b, delta) key is undefined")
570+ let D6 = valueOrErrorMessage(getInteger(neutrinoContract, basketDKey()), "D key is undefined")
571+ let b6 = valueOrErrorMessage(getInteger(neutrinoContract, basketBKey()), "b key is undefined")
572+ let w6 = valueOrErrorMessage(getInteger(neutrinoContract, basketWeightByAssetKey(assetId)), (("Target weight for asset " + assetId) + " is undefined"))
573+ let p6 = ((dlog6 - w6) + parseIntValue(parts[1]))
574+ let d = (D6 - pow(b6, 6, p6, 6, 6, HALFUP))
575+ (acc :+ makeString(((parts :+ toString(w6)) :+ toString(d)), LISTSEP))
576+ }
577+
578+ let b = {
579+ let $l = basket
580+ let $s = size($l)
581+ let $acc0 = nil
582+ func $f0_1 ($a,$i) = if (($i >= $s))
583+ then $a
584+ else modify($a, $l[$i])
585+
586+ func $f0_2 ($a,$i) = if (($i >= $s))
587+ then $a
588+ else throw("List size exceeds 10")
589+
590+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
591+ }
592+ $Tuple2(nil, ("%s__" + makeString_2C(b, "_")))
554593 }
555594
556595
557596
558597 @Callable(i)
559598 func usdnStakingAprREADONLY (days) = {
560599 let tmpDays = 1
561600 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
562601 let currentPrice = asInt(neutrinoMetrics[nMetricIdxPrice])
563602 let wavesIncome = (0 * MULT8)
564603 let incomeForPeriod = fraction(wavesIncome, currentPrice, MULT8)
565604 let apr = calcApr(rpdContract, tmpDays, incomeForPeriod, MULT6)
566605 $Tuple2(nil, ("%d__" + toString(apr)))
567606 }
568607
569608
570609
571610 @Callable(i)
572611 func surfStakingAprREADONLY (days) = {
573612 let tmpDays = 3
574613 let incomeForPeriod = calcUsdnIncomeForPeriod(surfStakingContract, tmpDays)
575614 let surfPriceToUsdnX6 = 86400
576615 let apr = calcApr(surfStakingContract, tmpDays, incomeForPeriod, surfPriceToUsdnX6)
577616 $Tuple2(nil, ("%d__" + toString(apr)))
578617 }
579618
580619
581620
582621 @Callable(i)
583622 func surfStakingAprV2READONLY (days,surfUsdnPriceX6) = {
584623 let tmpDays = 3
585624 let incomeForPeriod = calcUsdnIncomeForPeriod(surfStakingContract, tmpDays)
586625 let apr = calcApr(surfStakingContract, tmpDays, incomeForPeriod, surfUsdnPriceX6)
587626 $Tuple2(nil, ("%d__" + toString(apr)))
588627 }
589628
590629
591630
592631 @Callable(i)
593632 func nsbtStakingAprREADONLY (days) = {
594633 let tmpDays = 3
595634 let nsbtPriceToUsdnX6 = 8000000
596635 let incomeForPeriod = calcUsdnIncomeForPeriod(nsbtStakingContract, tmpDays)
597636 let apr = calcApr(nsbtStakingContract, tmpDays, incomeForPeriod, nsbtPriceToUsdnX6)
598637 $Tuple2(nil, ("%d__" + toString(apr)))
599638 }
600639
601640
602641
603642 @Callable(i)
604643 func nsbtStakingAprV2READONLY (days,nsbtUsdnPriceX6) = {
605644 let tmpDays = 3
606645 let incomeForPeriod = calcUsdnIncomeForPeriod(nsbtStakingContract, tmpDays)
607646 let apr = calcApr(nsbtStakingContract, tmpDays, incomeForPeriod, nsbtUsdnPriceX6)
608647 $Tuple2(nil, ("%d__" + toString(apr)))
609648 }
610649
611650

github/deemru/w8io/026f985 
70.70 ms