2019.11.07 13:37 [1784694] smart account 3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo > SELF 0.00000000 Waves

{ "type": 13, "id": "GBUC3pfCBVG49gjDB4UeSzJLUps1UCucCGcyGNtfXSud", "fee": 1400000, "feeAssetId": null, "timestamp": 1573123113914, "version": 1, "sender": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo", "senderPublicKey": "BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht", "proofs": [ "UC6k6bwQBSnakyNfUexJ5QDiTZYhfu5tUJnYHhkEHYiJVChERU3D2JuDuQek3PKM9tnWNj6smo3Mtwkg7vWpFpc" ], "script": "base64:AAIDAAAAAAAAADQIARIAEgASBAoCCAESABIAEgMKAQgSABIDCgEIEgASBgoECAEBCBIDCgEIEgcKBQgIAQEIAAAAfQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBoAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEHAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAABAAAAGGdldFN0cmluZ0J5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAHQm9vbGVhbgQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQcAAAAADFNFTkRUWEVYUElSRQAAAAAAAAAAHgAAAAAPTElTVFNQTElUU1lNQk9MAgAAAAFfAAAAAA5MSVNUREFUQVNZTUJPTAIAAAABKwAAAAAHV0FWRUxFVAAAAAAABfXhAAAAAAAFUEFVTEkAAAAAAAAAAGQAAAAADUNSWVRJQ0FMU0hBUkUAAAAAAAAAABQAAAAADExFQVNJTkdTSEFSRQAAAAAAAAAAWgAAAAANTEVBU0lOVFhDT1VOVAAAAAAAAAAACgAAAAAIQ0FOQ0VMRUQCAAAACGNhbmNlbGVkAAAAAANORVcCAAAAA25ldwAAAAAGRklMTEVEAgAAAAZmaWxsZWQAAAAADURFRklDSVRPRkZTRVQAAAAAAAAAAAoAAAAAEk5ldXRyaW5vQXNzZXRJZEtleQIAAAARbmV1dHJpbm9fYXNzZXRfaWQAAAAADkJvbmRBc3NldElkS2V5AgAAAA1ib25kX2Fzc2V0X2lkAAAAABJSZXNlcnZlQ29udHJhY3RLZXkCAAAAEHJlc2VydmVfY29udHJhY3QAAAAAEkF1Y3Rpb25Db250cmFjdEtleQIAAAAQYXVjdGlvbl9jb250cmFjdAAAAAAOUlBEQ29udHJhY3RLZXkCAAAADHJwZF9jb250cmFjdAAAAAARQ29udG9sQ29udHJhY3RLZXkCAAAAEGNvbnRyb2xfY29udHJhY3QAAAAAFkJhbGFuY2VMb2NrSW50ZXJ2YWxLZXkCAAAAFWJhbGFuY2VfbG9ja19pbnRlcnZhbAAAAAAVTWluV2F2ZXNTd2FwQW1vdW50S2V5AgAAABVtaW5fd2F2ZXNfc3dhcF9hbW91bnQAAAAAGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQIAAAAYbWluX25ldXRyaW5vX3N3YXBfYW1vdW50AAAAAA5Ob2RlQWRkcmVzc0tleQIAAAAMbm9kZV9hZGRyZXNzAAAAABVOb2RlT3JhY2xlUHJvdmlkZXJLZXkCAAAAFG9yYWNsZV9ub2RlX3Byb3ZpZGVyAAAAABJMZWFzaW5nSW50ZXJ2YWxLZXkCAAAAEGxlYXNpbmdfaW50ZXJ2YWwAAAAACFByaWNlS2V5AgAAAAVwcmljZQAAAAANUHJpY2VJbmRleEtleQIAAAALcHJpY2VfaW5kZXgAAAAAF1NjcmlwdFVwZGF0ZUludGVydmFsS2V5AgAAABZzY3JpcHRfdXBkYXRlX2ludGVydmFsAAAAABJOZXV0cmlub0JhbGFuY2VLZXkCAAAACW5ldXRyaW5vXwAAAAAVQmFsYW5jZVVubG9ja0Jsb2NrS2V5AgAAAA5iYWxhbmNlX2Jsb2NrXwAAAAAMT3JkZXJib29rS2V5AgAAAAlvcmRlcmJvb2sAAAAADU9yZGVyVG90YWxLZXkCAAAADG9yZGVyX3RvdGFsXwAAAAANT3JkZXJPd25lcktleQIAAAAMb3JkZXJfb3duZXJfAAAAAA5PcmRlckhlaWdodEtleQIAAAANb3JkZXJfaGVpZ2h0XwAAAAATT3JkZXJGaWxsZWRUb3RhbEtleQIAAAATb3JkZXJfZmlsbGVkX3RvdGFsXwAAAAAOT3JkZXJTdGF0dXNLZXkCAAAADW9yZGVyX3N0YXR1c18AAAAAD1JQRFN5bmNJbmRleEtleQIAAAAOcnBkX3N5bmNfaW5kZXgAAAAADFJQRFByb2ZpdEtleQIAAAAKcnBkX3Byb2ZpdAAAAAANUlBEQmFsYW5jZUtleQIAAAALcnBkX2JhbGFuY2UAAAAADElzQmxvY2tlZEtleQIAAAAKaXNfYmxvY2tlZAAAAAAZSXNMZWFzaW5nUHJvZml0VHhFeGlzdEtleQIAAAARaXNfbGVhc2luZ19wcm9maXQAAAAAFFNjcmlwdFVwZGF0ZUJsb2NrS2V5AgAAABNzY3JpcHRfdXBkYXRlX2Jsb2NrAAAAAApMZWFzZVR4S2V5AgAAAAhsZWFzZV90eAAAAAAQTGVhc2VUeFN0YXR1c0tleQIAAAAPbGVhc2VfdHhfc3RhdHVzAAAAABBMZWFzaW5nQW1vdW50S2V5AgAAAA5sZWFzaW5nX2Ftb3VudAAAAAAZTGVhc2VUeEV4cGlyZVNlbmRCbG9ja0tleQIAAAATbGVhc2luZ19leHBpcmVfc2VuZAAAAAAVTGVhc2luZ0V4cGlyZUJsb2NrS2V5AgAAABRsZWFzaW5nX2V4cGlyZV9ibG9jawAAAAAOSXNSZWJhbGFuY2VLZXkCAAAADGlzX3JlYmFsYW5jZQAAAAAcU3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZUtleQIAAAAcc3dhcF9uZXV0cmlub19sb2NrZWRfYmFsYW5jZQAAAAARTGVhc2luZ1R4Q291bnRLZXkCAAAADWxlYXNpbmdfaW5kZXgAAAAAGkNhbmNlbExlYXNlVHhSZXNlcnZlRmVlS2V5AgAAABtjYW5jZWxfbGVhc2VfdHhfcmVzZXJ2ZV9mZWUBAAAAIGdldFJQRFNuYXBzaG90Q29udHJhY3RCYWxhbmNlS2V5AAAAAgAAAAVjb3VudAAAAAdhc3NldElkCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIFAAAADVJQREJhbGFuY2VLZXkCAAAAAV8JAAJYAAAAAQUAAAAHYXNzZXRJZAIAAAABXwkAAaQAAAABBQAAAAVjb3VudAEAAAAYZ2V0UlBEQ29udHJhY3RCYWxhbmNlS2V5AAAAAQAAAAdhc3NldElkCQABLAAAAAIJAAEsAAAAAgUAAAANUlBEQmFsYW5jZUtleQIAAAABXwkAAlgAAAABBQAAAAdhc3NldElkAQAAAA9nZXRSUERQcm9maXRLZXkAAAABAAAABWNvdW50CQABLAAAAAIJAAEsAAAAAgUAAAAMUlBEUHJvZml0S2V5AgAAAAFfCQABpAAAAAEFAAAABWNvdW50AQAAABVnZXROZXV0cmlub0JhbGFuY2VLZXkAAAABAAAABW93bmVyCQABLAAAAAIFAAAAEk5ldXRyaW5vQmFsYW5jZUtleQUAAAAFb3duZXIBAAAAGGdldEJhbGFuY2VVbmxvY2tCbG9ja0tleQAAAAEAAAAFb3duZXIJAAEsAAAAAgUAAAAVQmFsYW5jZVVubG9ja0Jsb2NrS2V5BQAAAAVvd25lcgEAAAAQZ2V0T3JkZXJUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA1PcmRlclRvdGFsS2V5BQAAAAdvcmRlcklkAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAIFAAAADU9yZGVyT3duZXJLZXkFAAAAB29yZGVySWQBAAAAEWdldE9yZGVySGVpZ2h0S2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAIFAAAADk9yZGVySGVpZ2h0S2V5BQAAAAdvcmRlcklkAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA5PcmRlclN0YXR1c0tleQUAAAAHb3JkZXJJZAEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAABNPcmRlckZpbGxlZFRvdGFsS2V5BQAAAAdvcmRlcklkAQAAABJnZXRQcmljZUhpc3RvcnlLZXkAAAABAAAABWJsb2NrCQABLAAAAAIJAAEsAAAAAgUAAAAIUHJpY2VLZXkCAAAAAV8JAAGkAAAAAQUAAAAFYmxvY2sBAAAAGGdldEhlaWdodFByaWNlQnlJbmRleEtleQAAAAEAAAAFaW5kZXgJAAEsAAAAAgkAASwAAAACBQAAAA1QcmljZUluZGV4S2V5AgAAAAFfCQABpAAAAAEFAAAABWluZGV4AQAAABNnZXRMZWFzZVR4U3RhdHVzS2V5AAAAAQAAAARoYXNoCQABLAAAAAIJAAEsAAAAAgUAAAAQTGVhc2VUeFN0YXR1c0tleQIAAAABXwUAAAAEaGFzaAEAAAAZZ2V0TGVhc2VUeEFtb3VudEJ5SGFzaEtleQAAAAEAAAAEaGFzaAkAASwAAAACCQABLAAAAAIFAAAAEExlYXNpbmdBbW91bnRLZXkCAAAAAV8FAAAABGhhc2gBAAAAGGdldExlYXNlVHhCeXRlc0J5SGFzaEtleQAAAAEAAAAEaGFzaAkAASwAAAACCQABLAAAAAIFAAAACkxlYXNlVHhLZXkCAAAAAV8FAAAABGhhc2gBAAAAHGdldExlYXNlVHhFeHBpcmVTZW5kQmxvY2tLZXkAAAABAAAABGhhc2gJAAEsAAAAAgkAASwAAAACBQAAABlMZWFzZVR4RXhwaXJlU2VuZEJsb2NrS2V5AgAAAAFfBQAAAARoYXNoAQAAAB1nZXRDYW5jZWxMZWFzZVR4UmVzZXJ2ZUZlZUtleQAAAAEAAAAEaGFzaAkAASwAAAACCQABLAAAAAIFAAAAGkNhbmNlbExlYXNlVHhSZXNlcnZlRmVlS2V5AgAAAAFfBQAAAARoYXNoAAAAAA9uZXV0cmlub0Fzc2V0SWQJAAJZAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASTmV1dHJpbm9Bc3NldElkS2V5AAAAAA9yZXNlcnZlQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAElJlc2VydmVDb250cmFjdEtleQAAAAAPYXVjdGlvbkNvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABJBdWN0aW9uQ29udHJhY3RLZXkAAAAAC3JwZENvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA5SUERDb250cmFjdEtleQAAAAAPY29udHJvbENvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABFDb250b2xDb250cmFjdEtleQAAAAAFcHJpY2UJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAACFByaWNlS2V5AAAAAApwcmljZUluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAA1QcmljZUluZGV4S2V5AQAAAB1jb252ZXJ0TmV1dHJpbm9Ub1dhdmVzQnlQcmljZQAAAAIAAAAGYW1vdW50AAAADGNvbnZlcnRQcmljZQkAAGkAAAACCQAAaAAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAZhbW91bnQAAAAAAAAAAGQFAAAADGNvbnZlcnRQcmljZQUAAAAHV0FWRUxFVAUAAAAFUEFVTEkBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAABAAAABmFtb3VudAkAAGkAAAACCQAAaAAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAZhbW91bnQAAAAAAAAAAGQFAAAABXByaWNlBQAAAAdXQVZFTEVUBQAAAAVQQVVMSQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEAAAAGYW1vdW50CQAAaQAAAAIJAABoAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAABmFtb3VudAUAAAAFcHJpY2UAAAAAAAAAAGQFAAAABVBBVUxJBQAAAAdXQVZFTEVUAQAAABVjb252ZXJ0TmV1dHJpbm9Ub0JvbmQAAAABAAAABmFtb3VudAkAAGkAAAACBQAAAAZhbW91bnQFAAAABVBBVUxJAQAAABVjb252ZXJ0Qm9uZFRvTmV1dHJpbm8AAAABAAAABmFtb3VudAkAAGgAAAACBQAAAAZhbW91bnQFAAAABVBBVUxJAQAAABJjb252ZXJ0V2F2ZXNUb0JvbmQAAAABAAAABmFtb3VudAkBAAAAFWNvbnZlcnROZXV0cmlub1RvQm9uZAAAAAEJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAQUAAAAGYW1vdW50AAAAAAlpc0Jsb2NrZWQJAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAAxJc0Jsb2NrZWRLZXkAAAAADmxlYXNpbmdUeENvdW50CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABFMZWFzaW5nVHhDb3VudEtleQAAAAALaXNSZWJhbGFuY2UJAQAAAAxnZXRCb29sQnlLZXkAAAABBQAAAA5Jc1JlYmFsYW5jZUtleQAAAAAPbGVhc2luZ0ludGVydmFsCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABJMZWFzaW5nSW50ZXJ2YWxLZXkAAAAAEmxlYXNpbmdFeHBpcmVCbG9jawkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAVTGVhc2luZ0V4cGlyZUJsb2NrS2V5AAAAAA1sZWFzaW5nQW1vdW50CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABBMZWFzaW5nQW1vdW50S2V5AAAAABlzd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABxTd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlS2V5AAAAAAtub2RlQWRkcmVzcwkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOTm9kZUFkZHJlc3NLZXkAAAAAFW5vZGVPcmFjbGVQcm92aWRlcktleQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAVTm9kZU9yYWNsZVByb3ZpZGVyS2V5AAAAAAxycGRTeW5jSW5kZXgJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAD1JQRFN5bmNJbmRleEtleQAAAAATYmFsYW5jZUxvY2tJbnRlcnZhbAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAWQmFsYW5jZUxvY2tJbnRlcnZhbEtleQAAAAASbWluV2F2ZXNTd2FwQW1vdW50CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABVNaW5XYXZlc1N3YXBBbW91bnRLZXkAAAAAFW1pbk5ldXRyaW5vU3dhcEFtb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAYTWluTmV1dHJpbm9Td2FwQW1vdW50S2V5AAAAAAdyZXNlcnZlCQEAAAAMd2F2ZXNCYWxhbmNlAAAAAQUAAAAEdGhpcwAAAAAVcmVzZXJ2ZVdpdGhvdXRMZWFzaW5nCQAAZQAAAAIFAAAAB3Jlc2VydmUFAAAADWxlYXNpbmdBbW91bnQAAAAACW9yZGVyYm9vawkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAMT3JkZXJib29rS2V5AAAAAAtib25kQXNzZXRJZAkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA5Cb25kQXNzZXRJZEtleQAAAAAKYm9uZFN1cHBseQQAAAAEaW5mbwkBAAAAB2V4dHJhY3QAAAABCQAD7AAAAAEFAAAAC2JvbmRBc3NldElkCQAAZQAAAAIIBQAAAARpbmZvAAAACHF1YW50aXR5CQAD6wAAAAIFAAAABHRoaXMFAAAAC2JvbmRBc3NldElkAAAAAA5uZXV0cmlub1N1cHBseQQAAAAEaW5mbwkBAAAAB2V4dHJhY3QAAAABCQAD7AAAAAEFAAAAD25ldXRyaW5vQXNzZXRJZAkAAGQAAAACCQAAZQAAAAIIBQAAAARpbmZvAAAACHF1YW50aXR5CQAD6wAAAAIFAAAABHRoaXMFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQAAAAAHc3VycGx1cwkAAGUAAAACCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEFAAAAB3Jlc2VydmUFAAAADm5ldXRyaW5vU3VwcGx5AAAAAAdkZWZpY2l0CQAAZQAAAAIFAAAADm5ldXRyaW5vU3VwcGx5CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEFAAAAB3Jlc2VydmUBAAAAFWdldFJQRENvbnRyYWN0QmFsYW5jZQAAAAEAAAAHYXNzZXRJZAkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAC3JwZENvbnRyYWN0CQEAAAAYZ2V0UlBEQ29udHJhY3RCYWxhbmNlS2V5AAAAAQUAAAAHYXNzZXRJZAEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQAAAAVibG9jawkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEFAAAABWJsb2NrAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABAAAABWluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0CQEAAAAYZ2V0SGVpZ2h0UHJpY2VCeUluZGV4S2V5AAAAAQUAAAAFaW5kZXgBAAAAGmdldENhbmNlbExlYXNlVHhSZXNlcnZlRmVlAAAAAQAAAARoYXNoCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAdZ2V0Q2FuY2VsTGVhc2VUeFJlc2VydmVGZWVLZXkAAAABBQAAAARoYXNoAQAAABJnZXROZXV0cmlub0JhbGFuY2UAAAABAAAABW93bmVyCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQUAAAAFb3duZXIBAAAAFWdldFVubG9ja0JhbGFuY2VCbG9jawAAAAEAAAAFb3duZXIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABBQAAAAVvd25lcgEAAAANZ2V0T3JkZXJUb3RhbAAAAAEAAAACaWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAACaWQBAAAADWdldE9yZGVyT3duZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEFAAAAAmlkAQAAAA5nZXRPcmRlclN0YXR1cwAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAAmlkAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABBQAAAAJpZAEAAAAMZ2V0UlBEUHJvZml0AAAAAQAAAAVjb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAD2dldFJQRFByb2ZpdEtleQAAAAEFAAAABWNvdW50AQAAABBnZXRMZWFzZVR4U3RhdHVzAAAAAQAAAARoYXNoCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAATZ2V0TGVhc2VUeFN0YXR1c0tleQAAAAEFAAAABGhhc2gBAAAAFmdldExlYXNlVHhBbW91bnRCeUhhc2gAAAABAAAABGhhc2gJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABlnZXRMZWFzZVR4QW1vdW50QnlIYXNoS2V5AAAAAQUAAAAEaGFzaAEAAAAVZ2V0TGVhc2VUeEJ5dGVzQnlIYXNoAAAAAQAAAARoYXNoCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAYZ2V0TGVhc2VUeEJ5dGVzQnlIYXNoS2V5AAAAAQUAAAAEaGFzaAEAAAAZZ2V0TGVhc2VUeEV4cGlyZVNlbmRCbG9jawAAAAEAAAAEaGFzaAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAHGdldExlYXNlVHhFeHBpcmVTZW5kQmxvY2tLZXkAAAABBQAAAARoYXNoAQAAABNnZXRPcmRlckVsZW1lbnRCeUlkAAAAAQAAAAJpZAkAASwAAAACBQAAAAJpZAUAAAAPTElTVFNQTElUU1lNQk9MAQAAAAhhZGRPcmRlcgAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAAlvcmRlcmJvb2sJAQAAABNnZXRPcmRlckVsZW1lbnRCeUlkAAAAAQUAAAAHb3JkZXJJZAEAAAAJZHJvcE9yZGVyAAAAAQAAAAdvcmRlcklkBAAAAAVwYXJ0cwkABLUAAAACBQAAAAlvcmRlcmJvb2sJAQAAABNnZXRPcmRlckVsZW1lbnRCeUlkAAAAAQUAAAAHb3JkZXJJZAkAASwAAAACCQABkQAAAAIFAAAABXBhcnRzAAAAAAAAAAAACQABkQAAAAIFAAAABXBhcnRzAAAAAAAAAAABAAAADAAAAAFpAQAAABNzd2FwV2F2ZXNUb05ldXRyaW5vAAAAAAQAAAADcG10CQEAAAAHZXh0cmFjdAAAAAEIBQAAAAFpAAAAB3BheW1lbnQDCQAAZgAAAAIFAAAAEm1pbldhdmVzU3dhcEFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAALWFuIGFtb3VudCBpcyBsZXNzIHRoYW4gbWluIGF2YWlsYWJsZSBhbW91bnQ6IAkAAaQAAAABBQAAABJtaW5XYXZlc1N3YXBBbW91bnQCAAAACSB3YXZlbGV0cwMJAQAAAAlpc0RlZmluZWQAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQJAAACAAAAAQIAAAASY2FuIHVzZSB3YXZlcyBvbmx5AwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAWmNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWxsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwQAAAAGYW1vdW50CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEIBQAAAANwbXQAAAAGYW1vdW50CQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAGYW1vdW50BQAAAA9uZXV0cmlub0Fzc2V0SWQFAAAAA25pbAAAAAFpAQAAABNzd2FwTmV1dHJpbm9Ub1dhdmVzAAAAAAQAAAADcG10CQEAAAAHZXh0cmFjdAAAAAEIBQAAAAFpAAAAB3BheW1lbnQEAAAAB2FjY291bnQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyAwkAAGYAAAACBQAAABVtaW5OZXV0cmlub1N3YXBBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAC1hbiBhbW91bnQgaXMgbGVzcyB0aGFuIG1pbiBhdmFpbGFibGUgYW1vdW50OiAJAAGkAAAAAQUAAAAVbWluTmV1dHJpbm9Td2FwQW1vdW50AgAAAA8gbmV1dHJpbm8gY2VudHMDBQAAAAlpc0Jsb2NrZWQJAAACAAAAAQIAAABaY29udHJhY3QgaXMgYmxvY2tlZCBieSBFTUVSR0VOQ1kgU0hVVERPV04gYWN0aW9ucyB1bnRpbGwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAwkBAAAAAiE9AAAAAggFAAAAA3BtdAAAAAdhc3NldElkBQAAAA9uZXV0cmlub0Fzc2V0SWQJAAACAAAAAQIAAAAoY2FuIHVzZSBhcHByb3ByaWF0ZSBuZXV0cmlubyB0b2tlbnMgb25seQMJAABmAAAAAgkBAAAAFWdldFVubG9ja0JhbGFuY2VCbG9jawAAAAEFAAAAB2FjY291bnQFAAAABmhlaWdodAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAGYXdhaXQgCQABpAAAAAEJAABlAAAAAgkBAAAAFWdldFVubG9ja0JhbGFuY2VCbG9jawAAAAEFAAAAB2FjY291bnQFAAAABmhlaWdodAIAAAAHIGJsb2NrcwMJAQAAAAIhPQAAAAIJAQAAABJnZXROZXV0cmlub0JhbGFuY2UAAAABBQAAAAdhY2NvdW50AAAAAAAAAAAACQAAAgAAAAECAAAAK3BsZWFzZSB3aXRoZHJhdyBsb2NrZWQgbmV1dHJpbm8gZnVuZHMgZmlyc3QEAAAADm5ldXRyaW5vQW1vdW50CAUAAAADcG10AAAABmFtb3VudAQAAAAcbmV3U3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQkAAGQAAAACBQAAABlzd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlBQAAAA5uZXV0cmlub0Ftb3VudAkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAFWdldE5ldXRyaW5vQmFsYW5jZUtleQAAAAEFAAAAB2FjY291bnQJAABkAAAAAgkBAAAAEmdldE5ldXRyaW5vQmFsYW5jZQAAAAEFAAAAB2FjY291bnQFAAAADm5ldXRyaW5vQW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AAAAAQUAAAAHYWNjb3VudAkAAGQAAAACBQAAAAZoZWlnaHQFAAAAE2JhbGFuY2VMb2NrSW50ZXJ2YWwJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAHFN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkFAAAAHG5ld1N3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAADklzUmViYWxhbmNlS2V5AwkAAGcAAAACBQAAABVyZXNlcnZlV2l0aG91dExlYXNpbmcJAQAAABZjb252ZXJ0TmV1dHJpbm9Ub1dhdmVzAAAAAQUAAAAcbmV3U3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQcGBQAAAANuaWwAAAABaQEAAAAId2l0aGRyYXcAAAACAAAAB2FjY291bnQAAAAFaW5kZXgEAAAADHVubG9ja0hlaWdodAkBAAAAFWdldFVubG9ja0JhbGFuY2VCbG9jawAAAAEFAAAAB2FjY291bnQEAAAADm5ldXRyaW5vQW1vdW50CQEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQUAAAAHYWNjb3VudAQAAAALaW5kZXhIZWlnaHQJAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABBQAAAAVpbmRleAQAAAAPbmV4dEluZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQkAAGQAAAACBQAAAAVpbmRleAAAAAAAAAAAAQQAAAAKaW5kZXhQcmljZQkBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEFAAAAC2luZGV4SGVpZ2h0BAAAAAZhbW91bnQJAQAAAB1jb252ZXJ0TmV1dHJpbm9Ub1dhdmVzQnlQcmljZQAAAAIFAAAADm5ldXRyaW5vQW1vdW50BQAAAAppbmRleFByaWNlAwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAWmNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWxsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwMJAABnAAAAAgAAAAAAAAAAAAUAAAAGYW1vdW50CQAAAgAAAAECAAAAE2JhbGFuY2UgZXF1YWxzIHplcm8DCQAAZgAAAAIFAAAADHVubG9ja0hlaWdodAUAAAAGaGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAABFwbGVhc2Ugd2FpdCBmb3I6IAkAAaQAAAABBQAAAAx1bmxvY2tIZWlnaHQCAAAAJSBibG9jayBoZWlnaHQgdG8gd2l0aGRyYXcgV0FWRVMgZnVuZHMDAwMJAABmAAAAAgUAAAAFaW5kZXgFAAAACnByaWNlSW5kZXgGCQAAZgAAAAIFAAAAC2luZGV4SGVpZ2h0BQAAAAx1bmxvY2tIZWlnaHQGAwkBAAAAAiE9AAAAAgUAAAAPbmV4dEluZGV4SGVpZ2h0AAAAAAAAAAAACQAAZwAAAAIFAAAADHVubG9ja0hlaWdodAUAAAAPbmV4dEluZGV4SGVpZ2h0BwkAAAIAAAABAgAAABtpbnZhbGlkIHByaWNlIGhpc3RvcnkgaW5kZXgJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQUAAAAHYWNjb3VudAkAAGUAAAACCQEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQUAAAAHYWNjb3VudAUAAAAObmV1dHJpbm9BbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAHFN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkJAABlAAAAAgUAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQUAAAAObmV1dHJpbm9BbW91bnQFAAAAA25pbAkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAAcQGV4dHJVc2VyKGFkZHJl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AQAAAA5nZXRPcmRlclN0YXR1cwAAAAEFAAAAB29yZGVySWQFAAAAA05FVwkAAAIAAAABAgAAACJpbnZhbGlkIGxpcXVpZGF0aW9uIHJlcXVlc3Qgc3RhdHVzCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAMT3JkZXJib29rS2V5CQEAAAAJZHJvcE9yZGVyAAAAAQUAAAAHb3JkZXJJZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAEWdldE9yZGVyU3RhdHVzS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAAIQ0FOQ0VMRUQFAAAAA25pbAkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAABmFtb3VudAUAAAALYm9uZEFzc2V0SWQFAAAAA25pbAAAAAFpAQAAAAxleGVjdXRlT3JkZXIAAAAABAAAAAdvcmRlcklkCQABkQAAAAIJAAS1AAAAAgUAAAAJb3JkZXJib29rBQAAAA9MSVNUU1BMSVRTWU1CT0wAAAAAAAAAAAAEAAAACm9yZGVyVG90YWwJAQAAAA1nZXRPcmRlclRvdGFsAAAAAQUAAAAHb3JkZXJJZAQAAAAKb3JkZXJPd25lcgkBAAAADWdldE9yZGVyT3duZXIAAAABBQAAAAdvcmRlcklkBAAAAAtmaWxsZWRUb3RhbAkBAAAAE2dldE9yZGVyRmlsbGVkVG90YWwAAAABBQAAAAdvcmRlcklkBAAAAAtzdXJwbHVzQm9uZAkBAAAAFWNvbnZlcnROZXV0cmlub1RvQm9uZAAAAAEFAAAAB3N1cnBsdXMDBQAAAAlpc0Jsb2NrZWQJAAACAAAAAQIAAABaY29udHJhY3QgaXMgYmxvY2tlZCBieSBFTUVSR0VOQ1kgU0hVVERPV04gYWN0aW9ucyB1bnRpbGwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAwkAAGcAAAACAAAAAAAAAAAABQAAAAtzdXJwbHVzQm9uZAkAAAIAAAABAgAAAC50aGVyZSBpcyBubyBwcm9maWNpdCBvbiB0aGUgc21hcnQgY29udHJhY3Qgbm93AwkAAAAAAAACBQAAAAlvcmRlcmJvb2sCAAAAAAkAAAIAAAABAgAAAA9lbXB0eSBvcmRlcmJvb2sEAAAABmFtb3VudAkAAGUAAAACBQAAAApvcmRlclRvdGFsBQAAAAtmaWxsZWRUb3RhbAQAAAAGc3RhdHVzAwkAAGcAAAACBQAAAAtzdXJwbHVzQm9uZAUAAAAGYW1vdW50BQAAAAZGSUxMRUQFAAAAA05FVwQAAAAObmV3RmlsbGVkVG90YWwDCQAAZwAAAAIFAAAAC3N1cnBsdXNCb25kBQAAAAZhbW91bnQFAAAABmFtb3VudAUAAAALc3VycGx1c0JvbmQJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAAxPcmRlcmJvb2tLZXkDCQAAZwAAAAIFAAAAC3N1cnBsdXNCb25kBQAAAAZhbW91bnQJAQAAAAlkcm9wT3JkZXIAAAABBQAAAAdvcmRlcklkBQAAAAlvcmRlcmJvb2sJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABZnZXRPcmRlckZpbGxlZFRvdGFsS2V5AAAAAQUAAAAHb3JkZXJJZAkAAGQAAAACBQAAAAtmaWxsZWRUb3RhbAUAAAAObmV3RmlsbGVkVG90YWwJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAB29yZGVySWQFAAAABnN0YXR1cwUAAAADbmlsCQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAAKb3JkZXJPd25lcgkBAAAAFWNvbnZlcnRCb25kVG9OZXV0cmlubwAAAAEFAAAADm5ld0ZpbGxlZFRvdGFsBQAAAA9uZXV0cmlub0Fzc2V0SWQFAAAAA25pbAAAAAFpAQAAAAh0cmFuc2ZlcgAAAAEAAAAHYWNjb3VudAQAAAADcG10CQEAAAAHZXh0cmFjdAAAAAEIBQAAAAFpAAAAB3BheW1lbnQJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAdhY2NvdW50CAUAAAADcG10AAAABmFtb3VudAgFAAAAA3BtdAAAAAdhc3NldElkBQAAAANuaWwAAAABaQEAAAAKbm9kZVJld2FyZAAAAAAEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQgFAAAAAWkAAAAHcGF5bWVudAMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAtub2RlQWRkcmVzcwkAAAIAAAABAgAAAEdvbmx5IG5vZGUgYWNjb3VudCBpcyBhYmxlIHRvIHRyYW5zZmVyIHN0YWtpbmcgcmV3YXJkcyBmcm9tIG1haW4gYWNjb3VudAMJAQAAAAlpc0RlZmluZWQAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQJAAACAAAAAQIAAAAZd2F2ZXMgdG9rZW5zIG9ubHkgYWxsb3dlZAQAAAAGYW1vdW50CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEIBQAAAANwbXQAAAAGYW1vdW50BAAAAA9uZXdScGRTeW5jSW5kZXgJAABkAAAAAgUAAAAMcnBkU3luY0luZGV4AAAAAAAAAAABCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAPUlBEU3luY0luZGV4S2V5BQAAAA9uZXdScGRTeW5jSW5kZXgJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA9nZXRSUERQcm9maXRLZXkAAAABBQAAAAxycGRTeW5jSW5kZXgFAAAABmFtb3VudAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAIGdldFJQRFNuYXBzaG90Q29udHJhY3RCYWxhbmNlS2V5AAAAAgUAAAAMcnBkU3luY0luZGV4BQAAAA9uZXV0cmlub0Fzc2V0SWQJAQAAABVnZXRSUERDb250cmFjdEJhbGFuY2UAAAAB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cnZlV2l0aG91dExlYXNpbmcJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAFmludmFsaWQgYW1vdW50KHJlc3VsdDoJAAGlAAAAAQkAAGYAAAACCQAAZQAAAAIFAAAAEHRvdGFsRnJlZVJlc2VydmUJAABkAAAAAgUAAAANbGVhc2luZ0Ftb3VudAUAAAAGYW1vdW50BQAAABVyZXNlcnZlV2l0aG91dExlYXNpbmcCAAAAASkJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAB1nZXRDYW5jZWxMZWFzZVR4UmVzZXJ2ZUZlZUtleQAAAAEFAAAABnR4SGFzaAUAAAADZmVlCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAABFMZWFzaW5nVHhDb3VudEtleQMJAAAAAAAAAgkBAAAAEGdldExlYXNlVHhTdGF0dXMAAAABBQAAAAZ0eEhhc2gCAAAAAAkAAGQAAAACBQAAAA5sZWFzaW5nVHhDb3VudAAAAAAAAAAAAQUAAAAObGVhc2luZ1R4Q291bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAEExlYXNpbmdBbW91bnRLZXkJAABkAAAAAgUAAAANbGVhc2luZ0Ftb3VudAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAABVMZWFzaW5nRXhwaXJlQmxvY2tLZXkDCQAAZgAAAAIFAAAABmhlaWdodAUAAAASbGVhc2luZ0V4cGlyZUJsb2NrCQAAZAAAAAIFAAAABmhlaWdodAUAAAAPbGVhc2luZ0ludGVydmFsBQAAABJsZWFzaW5nRXhwaXJlQmxvY2sJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABNnZXRMZWFzZVR4U3RhdHVzS2V5AAAAAQUAAAAGdHhIYXNoBQAAAANORVcJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABxnZXRMZWFzZVR4RXhwaXJlU2VuZEJsb2NrS2V5AAAAAQUAAAAGdHhIYXNoCQAAZAAAAAIFAAAABmhlaWdodAUAAAAMU0VORFRYRVhQSVJFCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAZZ2V0TGVhc2VUeEFtb3VudEJ5SGFzaEtleQAAAAEFAAAABnR4SGFzaAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAYZ2V0TGVhc2VUeEJ5dGVzQnlIYXNoS2V5AAAAAQUAAAAGdHhIYXNoCQACWgAAAAEFAAAAB3R4Qnl0ZXMFAAAAA25pbAAAAAFpAQAAABJjYW5jZWxTdHVja0xlYXNlVHgAAAABAAAABnR4SGFzaAMDAwkAAAAAAAACCQEAAAAQZ2V0TGVhc2VUeFN0YXR1cwAAAAEFAAAABnR4SGFzaAUAAAADTkVXCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABCQAD6QAAAAEJAAJZAAAAAQUAAAAGdHhIYXNoBwkAAGYAAAACBQAAAAZoZWlnaHQJAQAAABlnZXRMZWFzZVR4RXhwaXJlU2VuZEJsb2NrAAAAAQUAAAAGdHhIYXNoBwQAAAAGYW1vdW50CQEAAAAWZ2V0TGVhc2VUeEFtb3VudEJ5SGFzaAAAAAEFAAAABnR4SGFzaAkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAARTGVhc2luZ1R4Q291bnRLZXkJAABlAAAAAgUAAAAObGVhc2luZ1R4Q291bnQAAAAAAAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAEExlYXNpbmdBbW91bnRLZXkJAABlAAAAAgUAAAANbGVhc2luZ0Ftb3VudAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAATZ2V0TGVhc2VUeFN0YXR1c0tleQAAAAEFAAAABnR4SGFzaAUAAAAIQ0FOQ0VMRUQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAADklzUmViYWxhbmNlS2V5AwkAAGcAAAACCQAAZQAAAAIFAAAAFXJlc2VydmVXaXRob3V0TGVhc2luZwUAAAAGYW1vdW50CQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAEFAAAAGXN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UHBgUAAAADbmlsCQAAAgAAAAECAAAAD2ludmFsaWQgdHggaGFzaAAA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", "chainId": 87, "height": 1784694, "spentComplexity": 0 } View: original | compacted Prev: 4NaoQwY1ZoYuk1CYjT3FZ9LAmDswxugHhQsRfuEnBdRv Next: CWVytCpCF2o5zLVzfiXWJGxixXZjerzeaAiVzL6iVRkP Diff:
OldNewDifferences
4949 }
5050
5151
52+let SENDTXEXPIRE = 30
53+
5254 let LISTSPLITSYMBOL = "_"
5355
5456 let LISTDATASYMBOL = "+"
5961
6062 let CRYTICALSHARE = 20
6163
62-let LEASINGSHARE = 50
64+let LEASINGSHARE = 90
65+
66+let LEASINTXCOUNT = 10
6367
6468 let CANCELED = "canceled"
6569
6670 let NEW = "new"
6771
6872 let FILLED = "filled"
73+
74+let DEFICITOFFSET = 10
6975
7076 let NeutrinoAssetIdKey = "neutrino_asset_id"
7177
8793
8894 let NodeAddressKey = "node_address"
8995
96+let NodeOracleProviderKey = "oracle_node_provider"
97+
9098 let LeasingIntervalKey = "leasing_interval"
9199
92100 let PriceKey = "price"
96104 let ScriptUpdateIntervalKey = "script_update_interval"
97105
98106 let NeutrinoBalanceKey = "neutrino_"
99-
100-let WavesBalanceKey = "waves_"
101107
102108 let BalanceUnlockBlockKey = "balance_block_"
103109
127133
128134 let LeaseTxKey = "lease_tx"
129135
130-let LeaseTxHashKey = "lease_tx_hash"
136+let LeaseTxStatusKey = "lease_tx_status"
131137
132138 let LeasingAmountKey = "leasing_amount"
133139
137143
138144 let IsRebalanceKey = "is_rebalance"
139145
140-let SwapLockedBalanceKey = "swap_locked_balance"
146+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
141147
142-let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
148+let LeasingTxCountKey = "leasing_index"
149+
150+let CancelLeaseTxReserveFeeKey = "cancel_lease_tx_reserve_fee"
143151
144152 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
145153
151159
152160
153161 func getNeutrinoBalanceKey (owner) = (NeutrinoBalanceKey + owner)
154-
155-
156-func getWavesBalanceKey (owner) = (WavesBalanceKey + owner)
157162
158163
159164 func getBalanceUnlockBlockKey (owner) = (BalanceUnlockBlockKey + owner)
180185 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
181186
182187
188+func getLeaseTxStatusKey (hash) = ((LeaseTxStatusKey + "_") + hash)
189+
190+
191+func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash)
192+
193+
194+func getLeaseTxBytesByHashKey (hash) = ((LeaseTxKey + "_") + hash)
195+
196+
197+func getLeaseTxExpireSendBlockKey (hash) = ((LeaseTxExpireSendBlockKey + "_") + hash)
198+
199+
200+func getCancelLeaseTxReserveFeeKey (hash) = ((CancelLeaseTxReserveFeeKey + "_") + hash)
201+
202+
203+let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
204+
205+let reserveContract = getStringByKey(ReserveContractKey)
206+
207+let auctionContract = getStringByKey(AuctionContractKey)
208+
209+let rpdContract = getStringByKey(RPDContractKey)
210+
183211 let controlContract = getStringByKey(ContolContractKey)
184212
185213 let price = getNumberByAddressAndKey(controlContract, PriceKey)
204232 func convertWavesToBond (amount) = convertNeutrinoToBond(convertWavesToNeutrino(amount))
205233
206234
235+let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
236+
237+let leasingTxCount = getNumberByKey(LeasingTxCountKey)
238+
207239 let isRebalance = getBoolByKey(IsRebalanceKey)
208240
209241 let leasingInterval = getNumberByKey(LeasingIntervalKey)
210242
211-let leaseTxExpireSendBlock = getNumberByKey(LeaseTxExpireSendBlockKey)
212-
213243 let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey)
214-
215-let leaseTxHash = getStringByKey(LeaseTxHashKey)
216-
217-let leaseTxBytes = getStringByKey(LeaseTxKey)
218244
219245 let leasingAmount = getNumberByKey(LeasingAmountKey)
220246
221247 let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
222248
223-let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
224-
225249 let nodeAddress = getStringByKey(NodeAddressKey)
226250
227-let scriptUpdateInterval = getNumberByAddressAndKey(ContolContractKey, ScriptUpdateIntervalKey)
228-
229-let scriptUpdateBlock = getNumberByAddressAndKey(controlContract, ScriptUpdateBlockKey)
251+let nodeOracleProviderKey = getStringByKey(NodeOracleProviderKey)
230252
231253 let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey)
232254
233255 let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey)
234256
235-let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
236-
237257 let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey)
238258
239259 let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey)
240260
241-let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
261+let reserve = wavesBalance(this)
242262
243-let reserveContract = getStringByKey(ReserveContractKey)
244-
245-let auctionContract = getStringByKey(AuctionContractKey)
246-
247-let rpdContract = getStringByKey(RPDContractKey)
248-
249-let reserve = (wavesBalance(this) - swapWavesLockedBalance)
250-
251-let reserveWithoutLeasing = (reserve - (leasingAmount * (if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
252- then 1
253- else 0)))
263+let reserveWithoutLeasing = (reserve - leasingAmount)
254264
255265 let orderbook = getStringByKey(OrderbookKey)
256266
273283 func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId))
274284
275285
276-func getWavesBalance (owner) = getNumberByKey(getWavesBalanceKey(owner))
286+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
287+
288+
289+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
290+
291+
292+func getCancelLeaseTxReserveFee (hash) = getNumberByKey(getCancelLeaseTxReserveFeeKey(hash))
277293
278294
279295 func getNeutrinoBalance (owner) = getNumberByKey(getNeutrinoBalanceKey(owner))
297313 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
298314
299315
300-func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
316+func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash))
301317
302318
303-func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
319+func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash))
320+
321+
322+func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash))
323+
324+
325+func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash))
304326
305327
306328 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
319341 func swapWavesToNeutrino () = {
320342 let pmt = extract(i.payment)
321343 if ((minWavesSwapAmount > pmt.amount))
322- then throw("amount less min")
344+ then throw((("an amount is less than min available amount: " + toString(minWavesSwapAmount)) + " wavelets"))
323345 else if (isDefined(pmt.assetId))
324346 then throw("can use waves only")
325347 else if (isBlocked)
326- then throw("contract is blocked")
348+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
327349 else {
328350 let amount = convertWavesToNeutrino(pmt.amount)
329351 TransferSet([ScriptTransfer(i.caller, amount, neutrinoAssetId)])
337359 let pmt = extract(i.payment)
338360 let account = toString(i.caller)
339361 if ((minNeutrinoSwapAmount > pmt.amount))
340- then throw("amount less min")
362+ then throw((("an amount is less than min available amount: " + toString(minNeutrinoSwapAmount)) + " neutrino cents"))
341363 else if (isBlocked)
342- then throw("contract is blocked")
364+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
343365 else if ((pmt.assetId != neutrinoAssetId))
344- then throw("can use neutrino only")
366+ then throw("can use appropriate neutrino tokens only")
345367 else if ((getUnlockBalanceBlock(account) > height))
346368 then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
347369 else if ((getNeutrinoBalance(account) != 0))
348- then throw("use withdraw")
370+ then throw("please withdraw locked neutrino funds first")
349371 else {
350372 let neutrinoAmount = pmt.amount
351- let amount = convertNeutrinoToWaves(neutrinoAmount)
352- WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance + neutrinoAmount))])
373+ let newSwapNeutrinoLockedBalance = (swapNeutrinoLockedBalance + neutrinoAmount)
374+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(SwapNeutrinoLockedBalanceKey, newSwapNeutrinoLockedBalance), DataEntry(IsRebalanceKey, if ((reserveWithoutLeasing >= convertNeutrinoToWaves(newSwapNeutrinoLockedBalance)))
375+ then false
376+ else true)])
353377 }
354378 }
355379
357381
358382 @Callable(i)
359383 func withdraw (account,index) = {
384+ let unlockHeight = getUnlockBalanceBlock(account)
385+ let neutrinoAmount = getNeutrinoBalance(account)
360386 let indexHeight = getHeightPriceByIndex(index)
361387 let nextIndexHeight = getHeightPriceByIndex((index + 1))
362- let unlockHeight = getUnlockBalanceBlock(account)
388+ let indexPrice = getPriceHistory(indexHeight)
389+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
363390 if (isBlocked)
364- then throw("contract is blocked")
365- else if ((unlockHeight > height))
366- then throw("wait a couple of blocks for withdraw")
367- else if (if (if ((index > priceIndex))
368- then true
369- else (indexHeight > unlockHeight))
370- then true
371- else if ((nextIndexHeight != 0))
372- then (unlockHeight >= nextIndexHeight)
373- else false)
374- then throw("invalid index")
375- else {
376- let indexPrice = getPriceHistory(indexHeight)
377- let neutrinoAmount = getNeutrinoBalance(account)
378- let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
379- ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), (getWavesBalance(account) + amount), unit)]))
380- }
391+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
392+ else if ((0 >= amount))
393+ then throw("balance equals zero")
394+ else if ((unlockHeight > height))
395+ then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw WAVES funds"))
396+ else if (if (if ((index > priceIndex))
397+ then true
398+ else (indexHeight > unlockHeight))
399+ then true
400+ else if ((nextIndexHeight != 0))
401+ then (unlockHeight >= nextIndexHeight)
402+ else false)
403+ then throw("invalid price history index")
404+ else ScriptResult(WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) - neutrinoAmount)), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), amount, unit)]))
381405 }
382406
383407
387411 let balanceAuction = assetBalance(addressFromStringValue(auctionContract), bondAssetId)
388412 let amount = (convertNeutrinoToBond(deficit) - balanceAuction)
389413 if (isBlocked)
390- then throw("contract is blocked")
391- else if ((amount >= 10))
414+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
415+ else if ((amount >= ((neutrinoSupply * DEFICITOFFSET) / 100)))
392416 then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), amount, bondAssetId)])
393417 else throw("bond were generated or do not need it")
394418 }
400424 let pmt = extract(i.payment)
401425 let newOrderId = toBase58String(keccak256(((toBytes(pmt.amount) + i.caller.bytes) + toBytes(height))))
402426 if ((pmt.assetId != bondAssetId))
403- then throw("can use bond only")
427+ then throw("can use appropriate neutrino bonds tokens only")
404428 else if ((getOrderOwner(newOrderId) != ""))
405- then throw("order exists")
429+ then throw("an order is already exists")
406430 else WriteSet([DataEntry(OrderbookKey, addOrder(newOrderId)), DataEntry(getOrderTotalKey(newOrderId), pmt.amount), DataEntry(getOrderOwnerKey(newOrderId), toString(i.caller)), DataEntry(getOrderHeightKey(newOrderId), height), DataEntry(getOrderStatusKey(newOrderId), NEW)])
407431 }
408432
413437 let owner = getOrderOwner(orderId)
414438 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
415439 if ((owner != toString(i.caller)))
416- then throw("permission denied")
440+ then throw("only owner of bonds liquidation request is able to cancel it")
417441 else if ((getOrderStatus(orderId) != NEW))
418- then throw("invalid order status")
442+ then throw("invalid liquidation request status")
419443 else ScriptResult(WriteSet([DataEntry(OrderbookKey, dropOrder(orderId)), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, bondAssetId)]))
420444 }
421445
429453 let filledTotal = getOrderFilledTotal(orderId)
430454 let surplusBond = convertNeutrinoToBond(surplus)
431455 if (isBlocked)
432- then throw("contract is blocked")
456+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
433457 else if ((0 >= surplusBond))
434- then throw("surplus is less than zero")
435- else if (if ((orderOwner == ""))
436- then (surplusBond >= 10)
437- else false)
438- then {
439- let newRpdSyncIndex = (rpdSyncIndex + 1)
440- ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), surplus), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), surplus, neutrinoAssetId)]))
441- }
458+ then throw("there is no proficit on the smart contract now")
459+ else if ((orderbook == ""))
460+ then throw("empty orderbook")
442461 else {
443462 let amount = (orderTotal - filledTotal)
444463 let status = if ((surplusBond >= amount))
458477 @Callable(i)
459478 func transfer (account) = {
460479 let pmt = extract(i.payment)
461- if (isDefined(pmt.assetId))
462- then throw("can use waves only at the moment")
463- else TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, unit)])
480+ TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)])
464481 }
465482
466483
469486 func nodeReward () = {
470487 let pmt = value(i.payment)
471488 if ((i.caller != addressFromStringValue(nodeAddress)))
472- then throw("permission denied")
489+ then throw("only node account is able to transfer staking rewards from main account")
473490 else if (isDefined(pmt.assetId))
474- then throw("waves only")
491+ then throw("waves tokens only allowed")
475492 else {
476493 let amount = convertWavesToNeutrino(pmt.amount)
477494 let newRpdSyncIndex = (rpdSyncIndex + 1)
482499
483500
484501 @Callable(i)
485-func registrationLeaseTx (senderPublicKey,amount,fee,timestamp) = {
502+func registrationLeaseTx (senderPublicKey,fee,timestamp,leaseTxHash) = {
503+ let totalFreeReserve = (((reserve * LEASINGSHARE) / 100) - convertNeutrinoToWaves(swapNeutrinoLockedBalance))
504+ let amount = (totalFreeReserve / LEASINTXCOUNT)
486505 let txBytes = (((((base58'3h1H' + fromBase58String(senderPublicKey)) + fromBase58String(nodeAddress)) + toBytes(amount)) + toBytes(fee)) + toBytes(timestamp))
487- let balance = ((reserve * LEASINGSHARE) / 100)
488506 let txHashBytes = blake2b256(txBytes)
489507 let txHash = toBase58String(txHashBytes)
490- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
491- then throw("invalid pubKey")
492- else if (if ((lastBlock.timestamp > timestamp))
493- then true
494- else (timestamp > (lastBlock.timestamp + 5400000)))
495- then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
496- else if (if ((leaseTxHash != ""))
497- then if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
498- then true
499- else (leaseTxExpireSendBlock >= height)
500- else false)
501- then throw("leasing not canceled")
502- else if (if ((fee > 1000000))
503- then true
504- else (500000 > fee))
505- then throw("invalid fee")
506- else if (if ((amount != balance))
507- then true
508- else (amount == 0))
509- then throw((("invalid amount(leaseAmount:" + toString(balance)) + ")"))
510- else WriteSet([DataEntry(LeaseTxKey, toBase64String(txBytes)), DataEntry(LeaseTxHashKey, txHash), DataEntry(LeasingAmountKey, balance), DataEntry(LeaseTxExpireSendBlockKey, (height + 30)), DataEntry(LeasingExpireBlockKey, (height + leasingInterval))])
508+ let pmt = extract(i.payment)
509+ if ((toString(i.caller) == nodeOracleProviderKey))
510+ then throw("invalid caller")
511+ else if (isDefined(pmt.assetId))
512+ then throw("invalid paymtn asset")
513+ else if ((leaseTxHash != txHash))
514+ then throw((("invalid tx hash(amount:" + toString(amount)) + ")"))
515+ else if ((leasingTxCount >= LEASINTXCOUNT))
516+ then throw("the number of leasing transactions is equal to the maximum")
517+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
518+ then throw("invalid pubKey")
519+ else if (if ((lastBlock.timestamp > timestamp))
520+ then true
521+ else (timestamp > (lastBlock.timestamp + 5400000)))
522+ then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
523+ else if ((getLeaseTxStatus(txHash) != ""))
524+ then throw("tx is exist")
525+ else if ((pmt.amount != (fee * 2)))
526+ then throw("invalid payment amount")
527+ else if (if ((fee > 1000000))
528+ then true
529+ else (500000 > fee))
530+ then throw("invalid fee")
531+ else if (((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))
532+ then throw((("invalid amount(result:" + toString(((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))) + ")"))
533+ else WriteSet([DataEntry(getCancelLeaseTxReserveFeeKey(txHash), fee), DataEntry(LeasingTxCountKey, if ((getLeaseTxStatus(txHash) == ""))
534+ then (leasingTxCount + 1)
535+ else leasingTxCount), DataEntry(LeasingAmountKey, (leasingAmount + amount)), DataEntry(LeasingExpireBlockKey, if ((height > leasingExpireBlock))
536+ then (height + leasingInterval)
537+ else leasingExpireBlock), DataEntry(getLeaseTxStatusKey(txHash), NEW), DataEntry(getLeaseTxExpireSendBlockKey(txHash), (height + SENDTXEXPIRE)), DataEntry(getLeaseTxAmountByHashKey(txHash), amount), DataEntry(getLeaseTxBytesByHashKey(txHash), toBase64String(txBytes))])
511538 }
512539
513540
514541
515542 @Callable(i)
516-func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp) = {
543+func cancelStuckLeaseTx (txHash) = if (if (if ((getLeaseTxStatus(txHash) == NEW))
544+ then !(isDefined(transactionHeightById(fromBase58String(txHash))))
545+ else false)
546+ then (height > getLeaseTxExpireSendBlock(txHash))
547+ else false)
548+ then {
549+ let amount = getLeaseTxAmountByHash(txHash)
550+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(txHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
551+ then false
552+ else true)])
553+ }
554+ else throw("invalid tx hash")
555+
556+
557+
558+@Callable(i)
559+func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp,leaseTxHash) = {
517560 let txBytes = (((((base58'gm' + toBytes(chainIdString)) + fromBase58String(senderPublicKey)) + toBytes(fee)) + toBytes(timestamp)) + fromBase58String(leaseTxHash))
518561 let txHash = blake2b256(txBytes)
519- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
520- then throw("invalid pubKey")
521- else if (!(isDefined(transactionHeightById(txHash))))
522- then throw("blockchain does not contain this transaction")
523- else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
562+ if ((getLeaseTxStatus(leaseTxHash) != NEW))
563+ then throw("invalid tx status")
564+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
565+ then throw("invalid pubKey")
566+ else if (!(isDefined(transactionHeightById(txHash))))
567+ then throw("blockchain does not contain this transaction")
568+ else {
569+ let amount = getLeaseTxAmountByHash(leaseTxHash)
570+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(leaseTxHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
571+ then false
572+ else true)])
573+ }
524574 }
525575
526576
527577 @Verifier(tx)
528-func verify () = match tx {
529- case leaseTx: LeaseTransaction =>
530- if (if ((fromBase58String(leaseTxHash) == leaseTx.id))
531- then (leasingExpireBlock >= height)
532- else false)
533- then (leaseTxExpireSendBlock >= height)
534- else false
535- case unleaseTx: LeaseCancelTransaction =>
536- if (if ((fromBase58String(leaseTxHash) == unleaseTx.leaseId))
537- then if ((height > leasingExpireBlock))
578+func verify () = {
579+ let id = toBase58String(tx.id)
580+ match tx {
581+ case leaseTx: LeaseTransaction =>
582+ if (if ((leasingExpireBlock >= height))
583+ then (getLeaseTxExpireSendBlock(id) >= height)
584+ else false)
585+ then (getLeaseTxStatus(id) == NEW)
586+ else false
587+ case unleaseTx: LeaseCancelTransaction =>
588+ let leaseId = toBase58String(unleaseTx.leaseId)
589+ if (if (if ((height > leasingExpireBlock))
538590 then true
539- else isRebalance
540- else false)
541- then if ((unleaseTx.fee >= 500000))
542- then (1000000 >= unleaseTx.fee)
591+ else isRebalance)
592+ then (unleaseTx.fee == getCancelLeaseTxReserveFee(leaseId))
593+ else false)
594+ then (getLeaseTxStatus(leaseId) == NEW)
543595 else false
544- else false
545- case _ =>
546- sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
547-}
596+ case _ =>
597+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
598+ }
599+ }
548600
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = match getInteger(this, key) {
55 case a: Int =>
66 a
77 case _ =>
88 0
99 }
1010
1111
1212 func getStringByKey (key) = match getString(this, key) {
1313 case a: String =>
1414 a
1515 case _ =>
1616 ""
1717 }
1818
1919
2020 func getBoolByKey (key) = match getBoolean(this, key) {
2121 case a: Boolean =>
2222 a
2323 case _ =>
2424 false
2525 }
2626
2727
2828 func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) {
2929 case a: Int =>
3030 a
3131 case _ =>
3232 0
3333 }
3434
3535
3636 func getStringByAddressAndKey (address,key) = match getString(addressFromStringValue(address), key) {
3737 case a: String =>
3838 a
3939 case _ =>
4040 ""
4141 }
4242
4343
4444 func getBoolByAddressAndKey (address,key) = match getBoolean(addressFromStringValue(address), key) {
4545 case a: Boolean =>
4646 a
4747 case _ =>
4848 false
4949 }
5050
5151
52+let SENDTXEXPIRE = 30
53+
5254 let LISTSPLITSYMBOL = "_"
5355
5456 let LISTDATASYMBOL = "+"
5557
5658 let WAVELET = 100000000
5759
5860 let PAULI = 100
5961
6062 let CRYTICALSHARE = 20
6163
62-let LEASINGSHARE = 50
64+let LEASINGSHARE = 90
65+
66+let LEASINTXCOUNT = 10
6367
6468 let CANCELED = "canceled"
6569
6670 let NEW = "new"
6771
6872 let FILLED = "filled"
73+
74+let DEFICITOFFSET = 10
6975
7076 let NeutrinoAssetIdKey = "neutrino_asset_id"
7177
7278 let BondAssetIdKey = "bond_asset_id"
7379
7480 let ReserveContractKey = "reserve_contract"
7581
7682 let AuctionContractKey = "auction_contract"
7783
7884 let RPDContractKey = "rpd_contract"
7985
8086 let ContolContractKey = "control_contract"
8187
8288 let BalanceLockIntervalKey = "balance_lock_interval"
8389
8490 let MinWavesSwapAmountKey = "min_waves_swap_amount"
8591
8692 let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
8793
8894 let NodeAddressKey = "node_address"
8995
96+let NodeOracleProviderKey = "oracle_node_provider"
97+
9098 let LeasingIntervalKey = "leasing_interval"
9199
92100 let PriceKey = "price"
93101
94102 let PriceIndexKey = "price_index"
95103
96104 let ScriptUpdateIntervalKey = "script_update_interval"
97105
98106 let NeutrinoBalanceKey = "neutrino_"
99-
100-let WavesBalanceKey = "waves_"
101107
102108 let BalanceUnlockBlockKey = "balance_block_"
103109
104110 let OrderbookKey = "orderbook"
105111
106112 let OrderTotalKey = "order_total_"
107113
108114 let OrderOwnerKey = "order_owner_"
109115
110116 let OrderHeightKey = "order_height_"
111117
112118 let OrderFilledTotalKey = "order_filled_total_"
113119
114120 let OrderStatusKey = "order_status_"
115121
116122 let RPDSyncIndexKey = "rpd_sync_index"
117123
118124 let RPDProfitKey = "rpd_profit"
119125
120126 let RPDBalanceKey = "rpd_balance"
121127
122128 let IsBlockedKey = "is_blocked"
123129
124130 let IsLeasingProfitTxExistKey = "is_leasing_profit"
125131
126132 let ScriptUpdateBlockKey = "script_update_block"
127133
128134 let LeaseTxKey = "lease_tx"
129135
130-let LeaseTxHashKey = "lease_tx_hash"
136+let LeaseTxStatusKey = "lease_tx_status"
131137
132138 let LeasingAmountKey = "leasing_amount"
133139
134140 let LeaseTxExpireSendBlockKey = "leasing_expire_send"
135141
136142 let LeasingExpireBlockKey = "leasing_expire_block"
137143
138144 let IsRebalanceKey = "is_rebalance"
139145
140-let SwapLockedBalanceKey = "swap_locked_balance"
146+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
141147
142-let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
148+let LeasingTxCountKey = "leasing_index"
149+
150+let CancelLeaseTxReserveFeeKey = "cancel_lease_tx_reserve_fee"
143151
144152 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
145153
146154
147155 func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId))
148156
149157
150158 func getRPDProfitKey (count) = ((RPDProfitKey + "_") + toString(count))
151159
152160
153161 func getNeutrinoBalanceKey (owner) = (NeutrinoBalanceKey + owner)
154-
155-
156-func getWavesBalanceKey (owner) = (WavesBalanceKey + owner)
157162
158163
159164 func getBalanceUnlockBlockKey (owner) = (BalanceUnlockBlockKey + owner)
160165
161166
162167 func getOrderTotalKey (orderId) = (OrderTotalKey + orderId)
163168
164169
165170 func getOrderOwnerKey (orderId) = (OrderOwnerKey + orderId)
166171
167172
168173 func getOrderHeightKey (orderId) = (OrderHeightKey + orderId)
169174
170175
171176 func getOrderStatusKey (orderId) = (OrderStatusKey + orderId)
172177
173178
174179 func getOrderFilledTotalKey (orderId) = (OrderFilledTotalKey + orderId)
175180
176181
177182 func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
178183
179184
180185 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
181186
182187
188+func getLeaseTxStatusKey (hash) = ((LeaseTxStatusKey + "_") + hash)
189+
190+
191+func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash)
192+
193+
194+func getLeaseTxBytesByHashKey (hash) = ((LeaseTxKey + "_") + hash)
195+
196+
197+func getLeaseTxExpireSendBlockKey (hash) = ((LeaseTxExpireSendBlockKey + "_") + hash)
198+
199+
200+func getCancelLeaseTxReserveFeeKey (hash) = ((CancelLeaseTxReserveFeeKey + "_") + hash)
201+
202+
203+let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
204+
205+let reserveContract = getStringByKey(ReserveContractKey)
206+
207+let auctionContract = getStringByKey(AuctionContractKey)
208+
209+let rpdContract = getStringByKey(RPDContractKey)
210+
183211 let controlContract = getStringByKey(ContolContractKey)
184212
185213 let price = getNumberByAddressAndKey(controlContract, PriceKey)
186214
187215 let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
188216
189217 func convertNeutrinoToWavesByPrice (amount,convertPrice) = ((((amount * 100) / convertPrice) * WAVELET) / PAULI)
190218
191219
192220 func convertNeutrinoToWaves (amount) = ((((amount * 100) / price) * WAVELET) / PAULI)
193221
194222
195223 func convertWavesToNeutrino (amount) = ((((amount * price) / 100) * PAULI) / WAVELET)
196224
197225
198226 func convertNeutrinoToBond (amount) = (amount / PAULI)
199227
200228
201229 func convertBondToNeutrino (amount) = (amount * PAULI)
202230
203231
204232 func convertWavesToBond (amount) = convertNeutrinoToBond(convertWavesToNeutrino(amount))
205233
206234
235+let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
236+
237+let leasingTxCount = getNumberByKey(LeasingTxCountKey)
238+
207239 let isRebalance = getBoolByKey(IsRebalanceKey)
208240
209241 let leasingInterval = getNumberByKey(LeasingIntervalKey)
210242
211-let leaseTxExpireSendBlock = getNumberByKey(LeaseTxExpireSendBlockKey)
212-
213243 let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey)
214-
215-let leaseTxHash = getStringByKey(LeaseTxHashKey)
216-
217-let leaseTxBytes = getStringByKey(LeaseTxKey)
218244
219245 let leasingAmount = getNumberByKey(LeasingAmountKey)
220246
221247 let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
222248
223-let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
224-
225249 let nodeAddress = getStringByKey(NodeAddressKey)
226250
227-let scriptUpdateInterval = getNumberByAddressAndKey(ContolContractKey, ScriptUpdateIntervalKey)
228-
229-let scriptUpdateBlock = getNumberByAddressAndKey(controlContract, ScriptUpdateBlockKey)
251+let nodeOracleProviderKey = getStringByKey(NodeOracleProviderKey)
230252
231253 let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey)
232254
233255 let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey)
234256
235-let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
236-
237257 let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey)
238258
239259 let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey)
240260
241-let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
261+let reserve = wavesBalance(this)
242262
243-let reserveContract = getStringByKey(ReserveContractKey)
244-
245-let auctionContract = getStringByKey(AuctionContractKey)
246-
247-let rpdContract = getStringByKey(RPDContractKey)
248-
249-let reserve = (wavesBalance(this) - swapWavesLockedBalance)
250-
251-let reserveWithoutLeasing = (reserve - (leasingAmount * (if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
252- then 1
253- else 0)))
263+let reserveWithoutLeasing = (reserve - leasingAmount)
254264
255265 let orderbook = getStringByKey(OrderbookKey)
256266
257267 let bondAssetId = fromBase58String(getStringByKey(BondAssetIdKey))
258268
259269 let bondSupply = {
260270 let info = extract(assetInfo(bondAssetId))
261271 (info.quantity - assetBalance(this, bondAssetId))
262272 }
263273
264274 let neutrinoSupply = {
265275 let info = extract(assetInfo(neutrinoAssetId))
266276 ((info.quantity - assetBalance(this, neutrinoAssetId)) + swapNeutrinoLockedBalance)
267277 }
268278
269279 let surplus = (convertWavesToNeutrino(reserve) - neutrinoSupply)
270280
271281 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve))
272282
273283 func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId))
274284
275285
276-func getWavesBalance (owner) = getNumberByKey(getWavesBalanceKey(owner))
286+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
287+
288+
289+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
290+
291+
292+func getCancelLeaseTxReserveFee (hash) = getNumberByKey(getCancelLeaseTxReserveFeeKey(hash))
277293
278294
279295 func getNeutrinoBalance (owner) = getNumberByKey(getNeutrinoBalanceKey(owner))
280296
281297
282298 func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner))
283299
284300
285301 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
286302
287303
288304 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
289305
290306
291307 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
292308
293309
294310 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
295311
296312
297313 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
298314
299315
300-func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
316+func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash))
301317
302318
303-func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
319+func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash))
320+
321+
322+func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash))
323+
324+
325+func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash))
304326
305327
306328 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
307329
308330
309331 func addOrder (orderId) = (orderbook + getOrderElementById(orderId))
310332
311333
312334 func dropOrder (orderId) = {
313335 let parts = split(orderbook, getOrderElementById(orderId))
314336 (parts[0] + parts[1])
315337 }
316338
317339
318340 @Callable(i)
319341 func swapWavesToNeutrino () = {
320342 let pmt = extract(i.payment)
321343 if ((minWavesSwapAmount > pmt.amount))
322- then throw("amount less min")
344+ then throw((("an amount is less than min available amount: " + toString(minWavesSwapAmount)) + " wavelets"))
323345 else if (isDefined(pmt.assetId))
324346 then throw("can use waves only")
325347 else if (isBlocked)
326- then throw("contract is blocked")
348+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
327349 else {
328350 let amount = convertWavesToNeutrino(pmt.amount)
329351 TransferSet([ScriptTransfer(i.caller, amount, neutrinoAssetId)])
330352 }
331353 }
332354
333355
334356
335357 @Callable(i)
336358 func swapNeutrinoToWaves () = {
337359 let pmt = extract(i.payment)
338360 let account = toString(i.caller)
339361 if ((minNeutrinoSwapAmount > pmt.amount))
340- then throw("amount less min")
362+ then throw((("an amount is less than min available amount: " + toString(minNeutrinoSwapAmount)) + " neutrino cents"))
341363 else if (isBlocked)
342- then throw("contract is blocked")
364+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
343365 else if ((pmt.assetId != neutrinoAssetId))
344- then throw("can use neutrino only")
366+ then throw("can use appropriate neutrino tokens only")
345367 else if ((getUnlockBalanceBlock(account) > height))
346368 then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
347369 else if ((getNeutrinoBalance(account) != 0))
348- then throw("use withdraw")
370+ then throw("please withdraw locked neutrino funds first")
349371 else {
350372 let neutrinoAmount = pmt.amount
351- let amount = convertNeutrinoToWaves(neutrinoAmount)
352- WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance + neutrinoAmount))])
373+ let newSwapNeutrinoLockedBalance = (swapNeutrinoLockedBalance + neutrinoAmount)
374+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(SwapNeutrinoLockedBalanceKey, newSwapNeutrinoLockedBalance), DataEntry(IsRebalanceKey, if ((reserveWithoutLeasing >= convertNeutrinoToWaves(newSwapNeutrinoLockedBalance)))
375+ then false
376+ else true)])
353377 }
354378 }
355379
356380
357381
358382 @Callable(i)
359383 func withdraw (account,index) = {
384+ let unlockHeight = getUnlockBalanceBlock(account)
385+ let neutrinoAmount = getNeutrinoBalance(account)
360386 let indexHeight = getHeightPriceByIndex(index)
361387 let nextIndexHeight = getHeightPriceByIndex((index + 1))
362- let unlockHeight = getUnlockBalanceBlock(account)
388+ let indexPrice = getPriceHistory(indexHeight)
389+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
363390 if (isBlocked)
364- then throw("contract is blocked")
365- else if ((unlockHeight > height))
366- then throw("wait a couple of blocks for withdraw")
367- else if (if (if ((index > priceIndex))
368- then true
369- else (indexHeight > unlockHeight))
370- then true
371- else if ((nextIndexHeight != 0))
372- then (unlockHeight >= nextIndexHeight)
373- else false)
374- then throw("invalid index")
375- else {
376- let indexPrice = getPriceHistory(indexHeight)
377- let neutrinoAmount = getNeutrinoBalance(account)
378- let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
379- ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), (getWavesBalance(account) + amount), unit)]))
380- }
391+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
392+ else if ((0 >= amount))
393+ then throw("balance equals zero")
394+ else if ((unlockHeight > height))
395+ then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw WAVES funds"))
396+ else if (if (if ((index > priceIndex))
397+ then true
398+ else (indexHeight > unlockHeight))
399+ then true
400+ else if ((nextIndexHeight != 0))
401+ then (unlockHeight >= nextIndexHeight)
402+ else false)
403+ then throw("invalid price history index")
404+ else ScriptResult(WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) - neutrinoAmount)), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), amount, unit)]))
381405 }
382406
383407
384408
385409 @Callable(i)
386410 func generateBond () = {
387411 let balanceAuction = assetBalance(addressFromStringValue(auctionContract), bondAssetId)
388412 let amount = (convertNeutrinoToBond(deficit) - balanceAuction)
389413 if (isBlocked)
390- then throw("contract is blocked")
391- else if ((amount >= 10))
414+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
415+ else if ((amount >= ((neutrinoSupply * DEFICITOFFSET) / 100)))
392416 then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), amount, bondAssetId)])
393417 else throw("bond were generated or do not need it")
394418 }
395419
396420
397421
398422 @Callable(i)
399423 func setOrder () = {
400424 let pmt = extract(i.payment)
401425 let newOrderId = toBase58String(keccak256(((toBytes(pmt.amount) + i.caller.bytes) + toBytes(height))))
402426 if ((pmt.assetId != bondAssetId))
403- then throw("can use bond only")
427+ then throw("can use appropriate neutrino bonds tokens only")
404428 else if ((getOrderOwner(newOrderId) != ""))
405- then throw("order exists")
429+ then throw("an order is already exists")
406430 else WriteSet([DataEntry(OrderbookKey, addOrder(newOrderId)), DataEntry(getOrderTotalKey(newOrderId), pmt.amount), DataEntry(getOrderOwnerKey(newOrderId), toString(i.caller)), DataEntry(getOrderHeightKey(newOrderId), height), DataEntry(getOrderStatusKey(newOrderId), NEW)])
407431 }
408432
409433
410434
411435 @Callable(i)
412436 func cancelOrder (orderId) = {
413437 let owner = getOrderOwner(orderId)
414438 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
415439 if ((owner != toString(i.caller)))
416- then throw("permission denied")
440+ then throw("only owner of bonds liquidation request is able to cancel it")
417441 else if ((getOrderStatus(orderId) != NEW))
418- then throw("invalid order status")
442+ then throw("invalid liquidation request status")
419443 else ScriptResult(WriteSet([DataEntry(OrderbookKey, dropOrder(orderId)), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, bondAssetId)]))
420444 }
421445
422446
423447
424448 @Callable(i)
425449 func executeOrder () = {
426450 let orderId = split(orderbook, LISTSPLITSYMBOL)[0]
427451 let orderTotal = getOrderTotal(orderId)
428452 let orderOwner = getOrderOwner(orderId)
429453 let filledTotal = getOrderFilledTotal(orderId)
430454 let surplusBond = convertNeutrinoToBond(surplus)
431455 if (isBlocked)
432- then throw("contract is blocked")
456+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
433457 else if ((0 >= surplusBond))
434- then throw("surplus is less than zero")
435- else if (if ((orderOwner == ""))
436- then (surplusBond >= 10)
437- else false)
438- then {
439- let newRpdSyncIndex = (rpdSyncIndex + 1)
440- ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), surplus), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), surplus, neutrinoAssetId)]))
441- }
458+ then throw("there is no proficit on the smart contract now")
459+ else if ((orderbook == ""))
460+ then throw("empty orderbook")
442461 else {
443462 let amount = (orderTotal - filledTotal)
444463 let status = if ((surplusBond >= amount))
445464 then FILLED
446465 else NEW
447466 let newFilledTotal = if ((surplusBond >= amount))
448467 then amount
449468 else surplusBond
450469 ScriptResult(WriteSet([DataEntry(OrderbookKey, if ((surplusBond >= amount))
451470 then dropOrder(orderId)
452471 else orderbook), DataEntry(getOrderFilledTotalKey(orderId), (filledTotal + newFilledTotal)), DataEntry(getOrderStatusKey(orderId), status)]), TransferSet([ScriptTransfer(addressFromStringValue(orderOwner), convertBondToNeutrino(newFilledTotal), neutrinoAssetId)]))
453472 }
454473 }
455474
456475
457476
458477 @Callable(i)
459478 func transfer (account) = {
460479 let pmt = extract(i.payment)
461- if (isDefined(pmt.assetId))
462- then throw("can use waves only at the moment")
463- else TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, unit)])
480+ TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)])
464481 }
465482
466483
467484
468485 @Callable(i)
469486 func nodeReward () = {
470487 let pmt = value(i.payment)
471488 if ((i.caller != addressFromStringValue(nodeAddress)))
472- then throw("permission denied")
489+ then throw("only node account is able to transfer staking rewards from main account")
473490 else if (isDefined(pmt.assetId))
474- then throw("waves only")
491+ then throw("waves tokens only allowed")
475492 else {
476493 let amount = convertWavesToNeutrino(pmt.amount)
477494 let newRpdSyncIndex = (rpdSyncIndex + 1)
478495 ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), amount), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), amount, neutrinoAssetId)]))
479496 }
480497 }
481498
482499
483500
484501 @Callable(i)
485-func registrationLeaseTx (senderPublicKey,amount,fee,timestamp) = {
502+func registrationLeaseTx (senderPublicKey,fee,timestamp,leaseTxHash) = {
503+ let totalFreeReserve = (((reserve * LEASINGSHARE) / 100) - convertNeutrinoToWaves(swapNeutrinoLockedBalance))
504+ let amount = (totalFreeReserve / LEASINTXCOUNT)
486505 let txBytes = (((((base58'3h1H' + fromBase58String(senderPublicKey)) + fromBase58String(nodeAddress)) + toBytes(amount)) + toBytes(fee)) + toBytes(timestamp))
487- let balance = ((reserve * LEASINGSHARE) / 100)
488506 let txHashBytes = blake2b256(txBytes)
489507 let txHash = toBase58String(txHashBytes)
490- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
491- then throw("invalid pubKey")
492- else if (if ((lastBlock.timestamp > timestamp))
493- then true
494- else (timestamp > (lastBlock.timestamp + 5400000)))
495- then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
496- else if (if ((leaseTxHash != ""))
497- then if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
498- then true
499- else (leaseTxExpireSendBlock >= height)
500- else false)
501- then throw("leasing not canceled")
502- else if (if ((fee > 1000000))
503- then true
504- else (500000 > fee))
505- then throw("invalid fee")
506- else if (if ((amount != balance))
507- then true
508- else (amount == 0))
509- then throw((("invalid amount(leaseAmount:" + toString(balance)) + ")"))
510- else WriteSet([DataEntry(LeaseTxKey, toBase64String(txBytes)), DataEntry(LeaseTxHashKey, txHash), DataEntry(LeasingAmountKey, balance), DataEntry(LeaseTxExpireSendBlockKey, (height + 30)), DataEntry(LeasingExpireBlockKey, (height + leasingInterval))])
508+ let pmt = extract(i.payment)
509+ if ((toString(i.caller) == nodeOracleProviderKey))
510+ then throw("invalid caller")
511+ else if (isDefined(pmt.assetId))
512+ then throw("invalid paymtn asset")
513+ else if ((leaseTxHash != txHash))
514+ then throw((("invalid tx hash(amount:" + toString(amount)) + ")"))
515+ else if ((leasingTxCount >= LEASINTXCOUNT))
516+ then throw("the number of leasing transactions is equal to the maximum")
517+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
518+ then throw("invalid pubKey")
519+ else if (if ((lastBlock.timestamp > timestamp))
520+ then true
521+ else (timestamp > (lastBlock.timestamp + 5400000)))
522+ then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
523+ else if ((getLeaseTxStatus(txHash) != ""))
524+ then throw("tx is exist")
525+ else if ((pmt.amount != (fee * 2)))
526+ then throw("invalid payment amount")
527+ else if (if ((fee > 1000000))
528+ then true
529+ else (500000 > fee))
530+ then throw("invalid fee")
531+ else if (((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))
532+ then throw((("invalid amount(result:" + toString(((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))) + ")"))
533+ else WriteSet([DataEntry(getCancelLeaseTxReserveFeeKey(txHash), fee), DataEntry(LeasingTxCountKey, if ((getLeaseTxStatus(txHash) == ""))
534+ then (leasingTxCount + 1)
535+ else leasingTxCount), DataEntry(LeasingAmountKey, (leasingAmount + amount)), DataEntry(LeasingExpireBlockKey, if ((height > leasingExpireBlock))
536+ then (height + leasingInterval)
537+ else leasingExpireBlock), DataEntry(getLeaseTxStatusKey(txHash), NEW), DataEntry(getLeaseTxExpireSendBlockKey(txHash), (height + SENDTXEXPIRE)), DataEntry(getLeaseTxAmountByHashKey(txHash), amount), DataEntry(getLeaseTxBytesByHashKey(txHash), toBase64String(txBytes))])
511538 }
512539
513540
514541
515542 @Callable(i)
516-func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp) = {
543+func cancelStuckLeaseTx (txHash) = if (if (if ((getLeaseTxStatus(txHash) == NEW))
544+ then !(isDefined(transactionHeightById(fromBase58String(txHash))))
545+ else false)
546+ then (height > getLeaseTxExpireSendBlock(txHash))
547+ else false)
548+ then {
549+ let amount = getLeaseTxAmountByHash(txHash)
550+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(txHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
551+ then false
552+ else true)])
553+ }
554+ else throw("invalid tx hash")
555+
556+
557+
558+@Callable(i)
559+func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp,leaseTxHash) = {
517560 let txBytes = (((((base58'gm' + toBytes(chainIdString)) + fromBase58String(senderPublicKey)) + toBytes(fee)) + toBytes(timestamp)) + fromBase58String(leaseTxHash))
518561 let txHash = blake2b256(txBytes)
519- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
520- then throw("invalid pubKey")
521- else if (!(isDefined(transactionHeightById(txHash))))
522- then throw("blockchain does not contain this transaction")
523- else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
562+ if ((getLeaseTxStatus(leaseTxHash) != NEW))
563+ then throw("invalid tx status")
564+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
565+ then throw("invalid pubKey")
566+ else if (!(isDefined(transactionHeightById(txHash))))
567+ then throw("blockchain does not contain this transaction")
568+ else {
569+ let amount = getLeaseTxAmountByHash(leaseTxHash)
570+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(leaseTxHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
571+ then false
572+ else true)])
573+ }
524574 }
525575
526576
527577 @Verifier(tx)
528-func verify () = match tx {
529- case leaseTx: LeaseTransaction =>
530- if (if ((fromBase58String(leaseTxHash) == leaseTx.id))
531- then (leasingExpireBlock >= height)
532- else false)
533- then (leaseTxExpireSendBlock >= height)
534- else false
535- case unleaseTx: LeaseCancelTransaction =>
536- if (if ((fromBase58String(leaseTxHash) == unleaseTx.leaseId))
537- then if ((height > leasingExpireBlock))
578+func verify () = {
579+ let id = toBase58String(tx.id)
580+ match tx {
581+ case leaseTx: LeaseTransaction =>
582+ if (if ((leasingExpireBlock >= height))
583+ then (getLeaseTxExpireSendBlock(id) >= height)
584+ else false)
585+ then (getLeaseTxStatus(id) == NEW)
586+ else false
587+ case unleaseTx: LeaseCancelTransaction =>
588+ let leaseId = toBase58String(unleaseTx.leaseId)
589+ if (if (if ((height > leasingExpireBlock))
538590 then true
539- else isRebalance
540- else false)
541- then if ((unleaseTx.fee >= 500000))
542- then (1000000 >= unleaseTx.fee)
591+ else isRebalance)
592+ then (unleaseTx.fee == getCancelLeaseTxReserveFee(leaseId))
593+ else false)
594+ then (getLeaseTxStatus(leaseId) == NEW)
543595 else false
544- else false
545- case _ =>
546- sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
547-}
596+ case _ =>
597+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
598+ }
599+ }
548600

github/deemru/w8io/786bc32 
136.31 ms