tx · 486qMbpXFGSkkC1biqL7VnqquwU4Y6NAHQRyJH4kF4hx

3ND5e5puMFTnV5TfaMoyrSQYrfSZFosGJuy:  -0.01400000 Waves

2022.01.13 13:53 [1877081] smart account 3ND5e5puMFTnV5TfaMoyrSQYrfSZFosGJuy > SELF 0.00000000 Waves

{ "type": 13, "id": "486qMbpXFGSkkC1biqL7VnqquwU4Y6NAHQRyJH4kF4hx", "fee": 1400000, "feeAssetId": null, "timestamp": 1642071219394, "version": 2, "chainId": 84, "sender": "3ND5e5puMFTnV5TfaMoyrSQYrfSZFosGJuy", "senderPublicKey": "C6iMaphKmZhNNRTWqKgEoycaCTfy6skgkLcPNxABf8aj", "proofs": [ "LhmMMzm4FssdXnnwtHKtD7QPcBedU1dwnSTYJrsr6dGsauHb8tAmR6MJpzq7K6YUtHm9AreXuRrGh6tFbiSj5Mx", "2Z19RpMErz7L1Xd17FGNj7X9567TNc2mARb2GBzAsFtTVfTQ6fpF4wiCStL8UqUgrz7uBMA223uFSSX48J4R2Gox" ], "script": "base64:AAIFAAAAAAAAADMIAhIDCgEEEgcKBQEBCAgEEgMKAQESAwoBARIAEgMKAQESABIAEgMKAQESBQoDBAEIEgAAAABYAAAAAAd2ZXJzaW9uAgAAAAUxLjAuMAAAAAAKa2V5VmVyc2lvbgIAAAAHdmVyc2lvbgAAAAAJa2V5QWN0aXZlAgAAAAZhY3RpdmUAAAAAC2tleUFzc2V0SWRBAgAAAApBX2Fzc2V0X2lkAAAAAAtrZXlBc3NldElkQgIAAAAKQl9hc3NldF9pZAAAAAALa2V5QmFsYW5jZUECAAAAD0FfYXNzZXRfYmFsYW5jZQAAAAALa2V5QmFsYW5jZUICAAAAD0JfYXNzZXRfYmFsYW5jZQAAAAAPa2V5QmFsYW5jZUluaXRBAgAAAAxBX2Fzc2V0X2luaXQAAAAAD2tleUJhbGFuY2VJbml0QgIAAAAMQl9hc3NldF9pbml0AAAAAA9rZXlTaGFyZUFzc2V0SWQCAAAADnNoYXJlX2Fzc2V0X2lkAAAAABNrZXlTaGFyZUFzc2V0U3VwcGx5AgAAABJzaGFyZV9hc3NldF9zdXBwbHkAAAAADWtleUNvbW1pc3Npb24CAAAACmNvbW1pc3Npb24AAAAAG2tleUNvbW1pc3Npb25TY2FsZURlbGltaXRlcgIAAAAaY29tbWlzc2lvbl9zY2FsZV9kZWxpbWl0ZXIAAAAACGtleUNhdXNlAgAAAA5zaHV0ZG93bl9jYXVzZQAAAAAPa2V5Rmlyc3RIYXJ2ZXN0AgAAAA1maXJzdF9oYXJ2ZXN0AAAAABVrZXlGaXJzdEhhcnZlc3RIZWlnaHQCAAAAFGZpcnN0X2hhcnZlc3RfaGVpZ2h0AAAAAAtrU2hhcmVMaW1pdAIAAAAcc2hhcmVfbGltaXRfb25fZmlyc3RfaGFydmVzdAAAAAALa0Jhc2VQZXJpb2QCAAAAC2Jhc2VfcGVyaW9kAAAAAA1rUGVyaW9kTGVuZ3RoAgAAAA1wZXJpb2RfbGVuZ3RoAAAAAAxrU3RhcnRIZWlnaHQCAAAADHN0YXJ0X2hlaWdodAAAAAATa0ZpcnN0SGFydmVzdEhlaWdodAIAAAAUZmlyc3RfaGFydmVzdF9oZWlnaHQAAAAAEmtleVVTRE5OU0JUQWRkcmVzcwIAAAAYc3Rha2luZ191c2RubnNidF9hZGRyZXNzAAAAAA5rZXlFVVJOQWRkcmVzcwIAAAAUc3Rha2luZ19ldXJuX2FkZHJlc3MAAAAADmtleUxlYXNpbmdQb29sAgAAAA9sZWFzaW5nX2FkZHJlc3MAAAAAEGtleUxlYXNpbmdBbW91bnQCAAAADmxlYXNpbmdfYW1vdW50AAAAAAxrZXlMZWFzaW5nSWQCAAAACmxlYXNpbmdfaWQAAAAAD2tleUFkbWluUHViS2V5MQIAAAALYWRtaW5fcHViXzEAAAAAD2tleUFkbWluUHViS2V5MgIAAAALYWRtaW5fcHViXzIAAAAAD2tleUFkbWluUHViS2V5MwIAAAALYWRtaW5fcHViXzMAAAAABm9yYWNsZQkBAAAAB0FkZHJlc3MAAAABAQAAABoBVOlFqh6QLzqu8boO5i6akl8amITh82KzCAEAAAALZ2V0QWRtaW5QdWIAAAABAAAAC2tleUFkbWluUHViBAAAAAckbWF0Y2gwCQAEHQAAAAIFAAAABm9yYWNsZQUAAAALa2V5QWRtaW5QdWIDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAAGc3RyaW5nBQAAAAckbWF0Y2gwCQACWQAAAAEFAAAABnN0cmluZwQAAAAHbm90aGluZwUAAAAHJG1hdGNoMAkAAAIAAAABAgAAABlBZG1pbiBwdWJsaWMga2V5IGlzIGVtcHR5AAAAAAxhZG1pblB1YktleTEJAQAAAAtnZXRBZG1pblB1YgAAAAEFAAAAD2tleUFkbWluUHViS2V5MQAAAAAMYWRtaW5QdWJLZXkyCQEAAAALZ2V0QWRtaW5QdWIAAAABBQAAAA9rZXlBZG1pblB1YktleTIAAAAADGFkbWluUHViS2V5MwkBAAAAC2dldEFkbWluUHViAAAAAQUAAAAPa2V5QWRtaW5QdWJLZXkzAAAAABRhZG1pblB1YktleVN0YXJ0U3RvcAEAAAAgBM915WTQwQ9OZ7kfE2TEGg3qhCRCMX0zkF1AWAqdk0oAAAAAEmFkbWluUHViS2V5U3Rha2luZwEAAAAgBM915WTQwQ9OZ7kfE2TEGg3qhCRCMX0zkF1AWAqdk0oAAAAADXdhbGxldEFkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVTfPUuXiVhZ3hXg5FELVt09el+9tX+FIYkAAAAADXZvdGluZ0FkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVQaNn7fV6KdJ2lc/r/3JtTn+6HDaD4gyn8AAAAABFVTRE4BAAAAIG8ko8qrMNxSKZjoLGFa7lp/I03CLXW76Z2qVODS0AfBAAAAAAROU0JUAQAAACAfMcqomheEmok3YjT1FeDjokifQYVi6vQeAO1aIhqpJAAAAAAEU1dPUAEAAAAgEv+BIJFIbrNA9tN9ExhCV/1vofsy06rszWo/nWl9O/gAAAAABEVVUk4BAAAAIMQE2t9aD0a2OEs+TuVY8nwo/62rHJEwmJzJLDjfxJK/AAAAAA1zdGFraW5nQXNzZXRzCQAETAAAAAICAAAABVdBVkVTCQAETAAAAAIJAAJYAAAAAQUAAAAEVVNETgkABEwAAAACCQACWAAAAAEFAAAABE5TQlQJAARMAAAAAgkAAlgAAAABBQAAAARFVVJOBQAAAANuaWwAAAAAFnN0YWtpbmdVU0ROTlNCVEFkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAGb3JhY2xlBQAAABJrZXlVU0ROTlNCVEFkZHJlc3MCAAAAF25vIHVzZG4gc3Rha2luZyBhZGRyZXNzAAAAABJzdGFraW5nRVVSTkFkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQkAAlkAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAGb3JhY2xlBQAAAA5rZXlFVVJOQWRkcmVzcwIAAAAXbm8gdXNkbiBzdGFraW5nIGFkZHJlc3MAAAAAFFVTRE5Ub1dhdmVzRXhjaGFuZ2VyCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFUypap/9cFMncn8kUuv9CKh+qtjirIv4W0AAAAABNVU0ROVG9OU0JURXhjaGFuZ2VyCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFUEWMEcf3cA2tBGebrexcf04K7NL8f1D3ZAAAAAApiYXNlUGVyaW9kCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAANdm90aW5nQWRkcmVzcwUAAAALa0Jhc2VQZXJpb2QCAAAAEUVtcHR5IGtCYXNlUGVyaW9kAAAAAAtzdGFydEhlaWdodAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADXZvdGluZ0FkZHJlc3MFAAAADGtTdGFydEhlaWdodAIAAAASRW1wdHkga1N0YXJ0SGVpZ2h0AAAAAAxwZXJpb2RMZW5ndGgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA12b3RpbmdBZGRyZXNzBQAAAA1rUGVyaW9kTGVuZ3RoAgAAABNFbXB0eSBrUGVyaW9kTGVuZ3RoAAAAABVmaXJzdEhhcnZlc3RFbmRQZXJpb2QJAABkAAAAAgkAAGQAAAACBQAAAApiYXNlUGVyaW9kCQAAaQAAAAIJAABlAAAAAgUAAAAGaGVpZ2h0BQAAAAtzdGFydEhlaWdodAUAAAAMcGVyaW9kTGVuZ3RoAAAAAAAAAAADAAAAAAZhY3RpdmUJAQAAABFAZXh0ck5hdGl2ZSgxMDUxKQAAAAIFAAAABHRoaXMFAAAACWtleUFjdGl2ZQAAAAALc3RyQXNzZXRJZEEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAC2tleUFzc2V0SWRBAAAAAAtzdHJBc3NldElkQgkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAEdGhpcwUAAAALa2V5QXNzZXRJZEIAAAAACGFzc2V0SWRBAwkAAAAAAAACBQAAAAtzdHJBc3NldElkQQIAAAAFV0FWRVMFAAAABHVuaXQJAAJZAAAAAQUAAAALc3RyQXNzZXRJZEEAAAAACGFzc2V0SWRCAwkAAAAAAAACBQAAAAtzdHJBc3NldElkQgIAAAAFV0FWRVMFAAAABHVuaXQJAAJZAAAAAQUAAAALc3RyQXNzZXRJZEIAAAAACmFzc2V0TmFtZUEEAAAAByRtYXRjaDAFAAAACGFzc2V0SWRBAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJpZAUAAAAHJG1hdGNoMAgJAQAAAAV2YWx1ZQAAAAEJAAPsAAAAAQUAAAACaWQAAAAEbmFtZQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAQAAAAF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bnQAAAABBQAAAAhhc3NldElkQgAAAAAKYXNzZXRJbml0QQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAAPa2V5QmFsYW5jZUluaXRBAAAAAAphc3NldEluaXRCCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAA9rZXlCYWxhbmNlSW5pdEIAAAAAEWF2YWlsYWJsZUJhbGFuY2VBCQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAAA1zdGFrZWRBbW91bnRBAAAAABFhdmFpbGFibGVCYWxhbmNlQgkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAANc3Rha2VkQW1vdW50QgAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQQUAAAANc3Rha2VkQW1vdW50QQAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQgUAAAANc3Rha2VkQW1vdW50QgAAAAAQaGFzRW5vdWdoQmFsYW5jZQMJAABnAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQUAAAAIYmFsYW5jZUEJAABnAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIHAQAAAAxnZXRBc3NldEluZm8AAAABAAAAB2Fzc2V0SWQEAAAAByRtYXRjaDAFAAAAB2Fzc2V0SWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAmlkBQAAAAckbWF0Y2gwBAAAAAhzdHJpbmdJZAkAAlgAAAABBQAAAAJpZAQAAAAEaW5mbwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAD7AAAAAEFAAAAAmlkCQABLAAAAAIJAAEsAAAAAgIAAAAGQXNzZXQgBQAAAAhzdHJpbmdJZAIAAAAOIGRvZXNuJ3QgZXhpc3QJAAUVAAAAAwUAAAAIc3RyaW5nSWQIBQAAAARpbmZvAAAABG5hbWUIBQAAAARpbmZvAAAACGRlY2ltYWxzAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0BAAAAAV3YXZlcwUAAAAHJG1hdGNoMAkABRUAAAADAgAAAAVXQVZFUwIAAAAFV0FWRVMAAAAAAAAAAAgJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IBAAAAFmdldEFzc2V0SW5mb0Zyb21TdHJpbmcAAAABAAAACGFzc2V0U3RyAwkAAAAAAAACBQAAAAhhc3NldFN0cgIAAAAFV0FWRVMJAAUVAAAAAwIAAAAFV0FWRVMCAAAABVdBVkVTAAAAAAAAAAAIBAAAAAhzdHJpbmdJZAUAAAAIYXNzZXRTdHIEAAAAAmlkCQACWQAAAAEFAAAACGFzc2V0U3RyBAAAAARpbmZvCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAPsAAAAAQUAAAACaWQJAAEsAAAAAgkAASwAAAACAgAAAAZBc3NldCAFAAAACHN0cmluZ0lkAgAAAA4gZG9lc24ndCBleGlzdAkABRUAAAADBQAAAAhzdHJpbmdJZAgFAAAABGluZm8AAAAEbmFtZQgFAAAABGluZm8AAAAIZGVjaW1hbHMBAAAAB3N1c3BlbmQAAAABAAAABWNhdXNlCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAAlrZXlBY3RpdmUHCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAACGtleUNhdXNlBQAAAAVjYXVzZQUAAAADbmlsAQAAABhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMAAAACAAAABXN0YWtlAAAAB2Fzc2V0SWQDBQAAAAVzdGFrZQMJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEVVNETgkABRQAAAACAgAAAAxsb2NrTmV1dHJpbm8FAAAAFnN0YWtpbmdVU0ROTlNCVEFkZHJlc3MDCQAAAAAAAAIFAAAAB2Fzc2V0SWQFAAAABE5TQlQJAAUUAAAAAgIAAAAIbG9ja05zYnQFAAAAFnN0YWtpbmdVU0ROTlNCVEFkZHJlc3MJAAUUAAAAAgIAAAAMc3RhcnRTdGFraW5nBQAAABJzdGFraW5nRVVSTkFkZHJlc3MDCQAAAAAAAAIFAAAAB2Fzc2V0SWQFAAAABFVTRE4JAAUUAAAAAgIAAAAOdW5sb2NrTmV1dHJpbm8FAAAAFnN0YWtpbmdVU0ROTlNCVEFkZHJlc3MDCQAAAAAAAAIFAAAAB2Fzc2V0SWQFAAAABE5TQlQJAAUUAAAAAgIAAAAKdW5sb2NrTnNidAUAAAAWc3Rha2luZ1VTRE5OU0JUQWRkcmVzcwkABRQAAAACAgAAAAtzdG9wU3Rha2luZwUAAAASc3Rha2luZ0VVUk5BZGRyZXNzAQAAABFjYWxjU3Rha2luZ1BhcmFtcwAAAAMAAAAFc3Rha2UAAAAGYW1vdW50AAAAB2Fzc2V0SWQDBQAAAAVzdGFrZQQAAAALJHQwNjkyMTY5ODcJAQAAABhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMAAAACBQAAAAVzdGFrZQUAAAAHYXNzZXRJZAQAAAAEY2FsbAgFAAAACyR0MDY5MjE2OTg3AAAAAl8xBAAAAAtzdGFraW5nQWRkcggFAAAACyR0MDY5MjE2OTg3AAAAAl8yCQAFFgAAAAQFAAAABGNhbGwFAAAAC3N0YWtpbmdBZGRyBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAAB2Fzc2V0SWQFAAAABmFtb3VudAUAAAADbmlsBAAAAAskdDA3MDczNzEzOQkBAAAAGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwAAAAIFAAAABXN0YWtlBQAAAAdhc3NldElkBAAAAARjYWxsCAUAAAALJHQwNzA3MzcxMzkAAAACXzEEAAAAC3N0YWtpbmdBZGRyCAUAAAALJHQwNzA3MzcxMzkAAAACXzIJAAUWAAAABAUAAAAEY2FsbAUAAAALc3Rha2luZ0FkZHIJAARMAAAAAgUAAAAGYW1vdW50CQAETAAAAAIJAAJYAAAAAQUAAAAHYXNzZXRJZAUAAAADbmlsBQAAAANuaWwBAAAADWNhbGN1bGF0ZUZlZXMAAAAEAAAACXBtdEFtb3VudAAAABJtaW5BbW91bnRUb1JlY2VpdmUAAAAJdG9rZW5Gcm9tAAAAB3Rva2VuVG8EAAAAEGFtb3VudFdpdGhvdXRGZWUJAABrAAAAAwUAAAAHdG9rZW5UbwUAAAAJcG10QW1vdW50CQAAZAAAAAIFAAAACXBtdEFtb3VudAUAAAAJdG9rZW5Gcm9tBAAAAA1hbW91bnRXaXRoRmVlCQAAawAAAAMFAAAAEGFtb3VudFdpdGhvdXRGZWUJAABlAAAAAgUAAAAYY29tbWlzc2lvblNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABhjb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIEAAAAEGdvdmVybmFuY2VSZXdhcmQJAABrAAAAAwUAAAAQYW1vdW50V2l0aG91dEZlZQUAAAAUY29tbWlzc2lvbkdvdmVybmFuY2UFAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgMJAABmAAAAAgUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAA1hbW91bnRXaXRoRmVlCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAHUNhbGN1bGF0ZWQgYW1vdW50IHRvIHJlY2VpdmUgCQABpAAAAAEFAAAADWFtb3VudFdpdGhGZWUCAAAAICBpcyBsZXNzIHRoYW4gc3BlY2lmaWVkIG1pbmltdW0gCQABpAAAAAEFAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQkABRUAAAADBQAAABBhbW91bnRXaXRob3V0RmVlBQAAAA1hbW91bnRXaXRoRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkAQAAABFzdXNwZW5kU3VzcGljaW91cwAAAAAJAQAAAAdzdXNwZW5kAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAjU3VzcGljaW91cyBzdGF0ZS4gQWN0dWFsIGJhbGFuY2VzOiAJAAGkAAAAAQUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQIAAAABIAUAAAAKYXNzZXROYW1lQQIAAAACLCAJAAGkAAAAAQUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgIAAAABIAUAAAAKYXNzZXROYW1lQgIAAAAJLiBTdGF0ZTogCQABpAAAAAEFAAAACGJhbGFuY2VBAgAAAAEgBQAAAAphc3NldE5hbWVBAgAAAAIsIAkA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AAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAtrZXlBc3NldElkQQUAAAAOcG10U3RyQXNzZXRJZEEJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAALa2V5QXNzZXRJZEIFAAAADnBtdFN0ckFzc2V0SWRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAAKcG10QW1vdW50QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAACnBtdEFtb3VudEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADWtleUNvbW1pc3Npb24FAAAACmNvbW1pc3Npb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAG2tleUNvbW1pc3Npb25TY2FsZURlbGltaXRlcgUAAAAYY29tbWlzc2lvblNjYWxlRGVsaW1pdGVyCQAETAAAAAIFAAAACnNoYXJlSXNzdWUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAPa2V5U2hhcmVBc3NldElkCQACWAAAAAEFAAAADHNoYXJlSXNzdWVJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAATa2V5U2hhcmVBc3NldFN1cHBseQUAAAASc2hhcmVJbml0aWFsU3VwcGx5CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAASc2hhcmVJbml0aWFsU3VwcGx5BQAAAAxzaGFyZUlzc3VlSWQFAAAAA25pbAMFAAAADGZpcnN0SGFydmVzdAkABE4AAAACBQAAAAliYXNlRW50cnkJAARMAAAAAgkBAAAADEJvb2xlYW5FbnRyeQAAAAIFAAAAD2tleUZpcnN0SGFydmVzdAUAAAAMZmlyc3RIYXJ2ZXN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVrZXlGaXJzdEhhcnZlc3RIZWlnaHQJAABkAAAAAgUAAAALc3RhcnRIZWlnaHQJAABoAAAAAgUAAAAVZmlyc3RIYXJ2ZXN0RW5kUGVyaW9kBQAAAAxwZXJpb2RMZW5ndGgFAAAAA25pbAUAAAAJYmFzZUVudHJ5CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAARaW5pdFdpdGhJbml0UmF0aW8AAAAFAAAACWFtdEFzc2V0QQAAAAlhbXRBc3NldEIAAAALc3RyQXNzZXRJZEEAAAALc3RyQXNzZXRJZEIAAAAMZmlyc3RIYXJ2ZXN0BAAAAA0kdDAxMTIyMTExMzA4CQEAAAAWZ2V0QXNzZXRJbmZvRnJvbVN0cmluZwAAAAEFAAAAC3N0ckFzc2V0SWRBBAAAAA5wbXRTdHJBc3NldElkQQgFAAAADSR0MDExMjIxMTEzMDgAAAACXzEEAAAADXBtdEFzc2V0TmFtZUEIBQAAAA0kdDAxMTIyMTExMzA4AAAAAl8yBAAAAAxwbXREZWNpbWFsc0EIBQAAAA0kdDAxMTIyMTExMzA4AAAAAl8zBAAAAA0kdDAxMTMxMzExNDAwCQEAAAAWZ2V0QXNzZXRJbmZvRnJvbVN0cmluZwAAAAEFAAAAC3N0ckFzc2V0SWRCBAAAAA5wbXRTdHJBc3NldElkQggFAAAADSR0MDExMzEzMTE0MDAAAAACXzEEAAAADXBtdEFzc2V0TmFtZUIIBQAAAA0kdDAxMTMxMzExNDAwAAAAAl8yBAAAAAxwbXREZWNpbWFsc0IIBQAAAA0kdDAxMTMxMzExNDAwAAAAAl8zAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABJhZG1pblB1YktleVN0YWtpbmcFAAAAA25pbAgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgMJAQAAAAlpc0RlZmluZWQAAAABCQAEGwAAAAIFAAAABHRoaXMFAAAACWtleUFjdGl2ZQkAAAIAAAABAgAAABZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAwkAAAAAAAACBQAAAAtzdHJBc3NldElkQQUAAAALc3RyQXNzZXRJZEIJAAACAAAAAQIAAAAYQXNzZXRzIG11c3QgYmUgZGlmZmVyZW50BAAAAAlzaGFyZU5hbWUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAAXMJAAEvAAAAAgUAAAANcG10QXNzZXROYW1lQQAAAAAAAAAABwIAAAABXwkAAS8AAAACBQAAAA1wbXRBc3NldE5hbWVCAAAAAAAAAAAHBAAAABBzaGFyZURlc2NyaXB0aW9uCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAiU2hhcmVUb2tlbiBvZiBTd29wRmkgcHJvdG9jb2wgZm9yIAUAAAANcG10QXNzZXROYW1lQQIAAAAFIGFuZCAFAAAADXBtdEFzc2V0TmFtZUICAAAADCBhdCBhZGRyZXNzIAkABCUAAAABBQAAAAR0aGlzBAAAAA1zaGFyZURlY2ltYWxzCQAAaQAAAAIJAABkAAAAAgUAAAAMcG10RGVjaW1hbHNBBQAAAAxwbXREZWNpbWFsc0IAAAAAAAAAAAIEAAAAEnNoYXJlSW5pdGlhbFN1cHBseQAAAAAAAAAAAAQAAAAKc2hhcmVJc3N1ZQkABEIAAAAFBQAAAAlzaGFyZU5hbWUFAAAAEHNoYXJlRGVzY3JpcHRpb24FAAAAEnNoYXJlSW5pdGlhbFN1cHBseQUAAAANc2hhcmVEZWNpbWFscwYEAAAADHNoYXJlSXNzdWVJZAkABDgAAAABBQAAAApzaGFyZUlzc3VlBAAAAAliYXNlRW50cnkJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAKa2V5VmVyc2lvbgUAAAAHdmVyc2lvbgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAJa2V5QWN0aXZlBgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAtrZXlBc3NldElkQQUAAAAOcG10U3RyQXNzZXRJZEEJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAALa2V5QXNzZXRJZEIFAAAADnBtdFN0ckFzc2V0SWRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA9rZXlCYWxhbmNlSW5pdEEFAAAACWFtdEFzc2V0QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAPa2V5QmFsYW5jZUluaXRCBQAAAAlhbXRBc3NldEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBAAAAAAAAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQgAAAAAAAAAAAAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANa2V5Q29tbWlzc2lvbgUAAAAKY29tbWlzc2lvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAba2V5Q29tbWlzc2lvblNjYWxlRGVsaW1pdGVyBQAAABhjb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIJAARMAAAAAgUAAAAKc2hhcmVJc3N1ZQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA9rZXlTaGFyZUFzc2V0SWQJAAJYAAAAAQUAAAAMc2hhcmVJc3N1ZUlkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5BQAAABJzaGFyZUluaXRpYWxTdXBwbHkFAAAAA25pbAMFAAAADGZpcnN0SGFydmVzdAkABE4AAAACBQAAAAliYXNlRW50cnkJAARMAAAAAgkBAAAADEJvb2xlYW5FbnRyeQAAAAIFAAAAD2tleUZpcnN0SGFydmVzdAUAAAAMZmlyc3RIYXJ2ZXN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVrZXlGaXJzdEhhcnZlc3RIZWlnaHQJAABkAAAAAgUAAAALc3RhcnRIZWlnaHQJAABoAAAAAgUAAAAVZmlyc3RIYXJ2ZXN0RW5kUGVyaW9kBQAAAAxwZXJpb2RMZW5ndGgFAAAAA25pbAUAAAAJYmFzZUVudHJ5AAAAAWkBAAAAGGtlZXBMaW1pdEZvckZpcnN0SGFydmVzdAAAAAEAAAAKc2hhcmVMaW1pdAkBAAAAC3ZhbHVlT3JF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QW1vdW50QQUAAAALc2NhbGVWYWx1ZTgFAAAACGJhbGFuY2VBCQAETAAAAAIJAABrAAAAAwUAAAAKcG10QW1vdW50QgUAAAALc2NhbGVWYWx1ZTgFAAAACGJhbGFuY2VCBQAAAANuaWwFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAAC3NjYWxlVmFsdWU4AwMJAABmAAAAAgAAAAAAAAAAAAUAAAARc2xpcHBhZ2VUb2xlcmFuY2UGCQAAZgAAAAIFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAClTbGlwcGFnZSB0b2xlcmFuY2UgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIAkAAaQAAAABBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgIAAAAWIGluY2x1c2l2ZWx5LiBBY3R1YWw6IAkAAaQAAAABBQAAABFzbGlwcGFnZVRvbGVyYW5jZQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAIJAAACAAAAAQIAAAAcVHdvIGF0dGFjaGVkIGFzc2V0cyBleHBlY3RlZAMDCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQQUAAAAIYXNzZXRJZEEGCQEAAAACIT0AAAACBQAAAAtwbXRBc3NldElkQgUAAAAIYXNzZXRJZEIJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAlSW5jb3JyZWN0IGFzc2V0cyBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAUAAAALc3RyQXNzZXRJZEECAAAABSBhbmQgBQAAAAtzdHJBc3NldElkQgMDCQAAZgAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlMwkAAGUAAAACBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAAAp0b2tlblJhdGlvBgkAAGYAAAACBQAAAAp0b2tlblJhdGlvCQAAaQAAAAIJAABoAAAAAgUAAAALc2NhbGVWYWx1ZTMJAABkAAAAAgUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgkAAAIAAAABAgAAAD1JbmNvcnJlY3QgYXNzZXRzIGFtb3VudDogYW1vdW50cyBtdXN0IGhhdmUgdGhlIGNvbnRyYWN0IHJhdGlvAwkAAAAAAAACBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQAAAAAAAAAAAAJAAACAAAAAQIAAAAdVG9vIHNtYWxsIGFtb3VudCB0byByZXBsZW5pc2gDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACnBtdEFtb3VudEEFAAAAC3BtdEFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QgUAAAALcG10QXNzZXRJZEIFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAQAAAAGc3Rha2UxAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAADXN0YWtpbmdBc3NldHMFAAAADnBtdFN0ckFzc2V0SWRBCQAD/AAAAAQFAAAABHRoaXMCAAAADHN0YWtlVW5zdGFrZQkABEwAAAACBgkABEwAAAACBQAAAApwbXRBbW91bnRBCQAETAAAAAIFAAAADnBtdFN0ckFzc2V0SWRBBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAA5wbXRTdHJBc3NldElkQgkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgYJAARMAAAAAgUAAAAKcG10QW1vdW50QgkABEwAAAACBQAAAA5wbXRTdHJBc3NldElkQgUAAAADbmls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AAAGCQAAAAAAAAIFAAAACGJhbGFuY2VCAAAAAAAAAAAACQAAAgAAAAECAAAAIENhbid0IGV4Y2hhbmdlIHdpdGggemVybyBiYWxhbmNlAwkAAGcAAAACAAAAAAAAAAAABQAAABJtaW5BbW91bnRUb1JlY2VpdmUJAAACAAAAAQkAASwAAAACAgAAADRNaW5pbWFsIGFtb3VudCB0byByZWNlaXZlIG11c3QgYmUgcG9zaXRpdmUuIEFjdHVhbDogCQABpAAAAAEFAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAdT25lIGF0dGFjaGVkIHBheW1lbnQgZXhwZWN0ZWQDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAAROAAAAAgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACXBtdEFtb3VudAUAAAAKcG10QXNzZXRJZAUAAAADbmlsCQEAAAARc3VzcGVuZFN1c3BpY2lvdXMAAAAAAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQQAAAALYXNzZXRJZFNlbmQFAAAACGFzc2V0SWRCBAAAAA0kdDAxODg0NDE4OTY2CQEAAAANY2FsY3VsYXRlRmVlcwAAAAQFAAAACXBtdEFtb3VudAUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAAhiYWxhbmNlQQUAAAAIYmFsYW5jZUIEAAAAEGFtb3VudFdpdGhvdXRGZWUIBQAAAA0kdDAxODg0NDE4OTY2AAAAAl8xBAAAAA1hbW91bnRXaXRoRmVlCAUAAAANJHQwMTg4NDQxODk2NgAAAAJfMgQAAAAQZ292ZXJuYW5jZVJld2FyZAgFAAAADSR0MDE4ODQ0MTg5NjYAAAACXzMEAAAAC25ld0JhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQEAAAAC25ld0JhbGFuY2VCCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUIFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQEAAAABnN0YWtlMQMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAAtzdHJBc3NldElkQQkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgYJAARMAAAAAgUAAAAJcG10QW1vdW50CQAETAAAAAIFAAAAC3N0ckFzc2V0SWRBBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAAtzdHJBc3NldElkQgkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgcJAARMAAAAAgkAAGQAAAACBQAAAA1hbW91bnRXaXRoRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkCQAETAAAAAIFAAAAC3N0ckFzc2V0SWRCBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UyBQAAAAZzdGFrZTIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAANYW1vdW50V2l0aEZlZQUAAAALYXNzZXRJZFNlbmQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAANd2FsbGV0QWRkcmVzcwUAAAAQZ292ZXJuYW5jZVJld2FyZAUAAAALYXNzZXRJZFNlbmQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQgQAAAALYXNzZXRJZFNlbmQFAAAACGFzc2V0SWRBBAAAAA0kdDAxOTkyMTIwMDQzCQEAAAANY2FsY3VsYXRlRmVlcwAAAAQFAAAACXBtdEFtb3VudAUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAAhiYWxhbmNlQgUAAAAIYmFsYW5jZUEEAAAAEGFtb3VudFdpdGhvdXRGZWUIBQAAAA0kdDAxOTkyMTIwMDQzAAAAAl8xBAAAAA1hbW91bnRXaXRoRmVlCAUAAAANJHQwMTk5MjEyMDA0MwAAAAJfMgQAAAAQZ292ZXJuYW5jZVJld2FyZAgFAAAADSR0MDE5OTIxMjAwNDMAAAACXzMEAAAAC25ld0JhbGFuY2VBCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQEAAAAC25ld0JhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAABnN0YWtlMQMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAAtzdHJBc3NldElkQQkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgcJAARMAAAAAgkAAGQAAAACBQAAAA1hbW91bnRXaXRoRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkCQAETAAAAAIFAAAAC3N0ckFzc2V0SWRBBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UxBQAAAAZzdGFrZTEEAAAABnN0YWtlMgMJAQAAAA9jb250YWluc0VsZW1lbnQAAAACBQAAAA1zdGFraW5nQXNzZXRzBQAAAAtzdHJBc3NldElkQgkAA/wAAAAEBQAAAAR0aGlzAgAAAAxzdGFrZVVuc3Rha2UJAARMAAAAAgYJAARMAAAAAgUAAAAJcG10QW1vdW50CQAETAAAAAIFAAAAC3N0ckFzc2V0SWRCBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAMJAAAAAAAAAgUAAAAGc3Rha2UyBQAAAAZzdGFrZTIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAANYW1vdW50V2l0aEZlZQUAAAALYXNzZXRJZFNlbmQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAANd2FsbGV0QWRkcmVzcwUAAAAQZ292ZXJuYW5jZVJld2FyZAUAAAALYXNzZXRJZFNlbmQFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJEluY29ycmVjdCBhc3NldCBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAUAAAALc3RyQXNzZXRJZEECAAAABCBvciAFAAAAC3N0ckFzc2V0SWRCAAAAAWkBAAAACHNodXRkb3duAAAAAAMJAQAAAAEhAAAAAQUAAAAGYWN0aXZlCQAAAgAAAAEJAAEsAAAAAgIAAAAiREFwcCBpcyBhbHJlYWR5IHN1c3BlbmRlZC4gQ2F1c2U6IAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAhrZXlDYXVzZQIAAAAadGhlIGNhdXNlIHdhc24ndCBzcGVjaWZpZWQDCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzCQAETAAAAAIFAAAAFGFkbWluUHViS2V5U3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkAAAIAAAABAgAAACFPbmx5IGFkbWluIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24JAQAAAAdzdXNwZW5kAAAAAQIAAAAPUGF1c2VkIGJ5IGFkbWluAAAAAWkBAAAACGFjdGl2YXRlAAAAAAMFAAAABmFjdGl2ZQkAAAIAAAABAgAAABZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABRhZG1pblB1YktleVN0YXJ0U3RvcAUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAAACAAAAAQIAAAAhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAAlrZXlBY3RpdmUGCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAACGtleUNhdXNlBQAAAANuaWwAAAABaQEAAAAZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwAAAAEAAAALYW1vdW50TGVhdmUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAAAhpc0FjdGl2ZQAAAAAEAAAAHXVuY291bnRhYmxlQW1vdW50RW5yb2xsQXNzZXRBCQAAZQAAAAIFAAAAGWFjY291bnRCYWxhbmNlV2l0aFN0YWtlZEEFAAAACGJhbGFuY2VBBAAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QgkAAGUAAAACBQAAABlhY2NvdW50QmFsYW5jZVdpdGhTdGFrZWRCBQAAAAhiYWxhbmNlQgQAAAANYW1vdW50RW5yb2xsQQkAAGUAAAACBQAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QQMJAAAAAAAAAgUAAAAIYXNzZXRJZEEFAAAABHVuaXQFAAAAC2Ftb3VudExlYXZlAAAAAAAAAAAABAAAAA1hbW91bnRFbnJvbGxCCQAAZQAAAAIFAAAAHXVuY291bnRhYmxlQW1vdW50RW5yb2xsQXNzZXRCAwkAAAAAAAACBQAAAAhhc3NldElkQgUAAAAEdW5pdAUAAAAL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AAAAAggFAAAAA2ludgAAAAhmdW5jdGlvbgIAAAAZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwcEAAAAD2V4Y2hhbmdlVG9XYXZlcwMDAwkAAAAAAAACCAUAAAADaW52AAAABGRBcHAFAAAAFFVTRE5Ub1dhdmVzRXhjaGFuZ2VyCQAAAAAAAAIIBQAAAANpbnYAAAAIZnVuY3Rpb24CAAAACGV4Y2hhbmdlBwkAAAAAAAACBQAAAAhhc3NldElkQQUAAAAEVVNETgcGAwMJAAAAAAAAAgUAAAAIYXNzZXRJZEIFAAAABFVTRE4JAAAAAAAAAgkAAZAAAAABCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAABBwkAAAAAAAACCAkAAZEAAAACCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQFAAAABFVTRE4HBAAAAA9leGNoYW5nZVRvTlNCVHMDAwMJAAAAAAAAAggFAAAAA2ludgAAAARkQXBwBQAAABNVU0ROVG9OU0JURXhjaGFuZ2VyCQAAAAAAAAIIBQAAAANpbnYAAAAIZnVuY3Rpb24CAAAACGV4Y2hhbmdlBwkAAAAAAAACBQAAAAhhc3NldElkQQUAAAAETlNCVAcGAwMJAAAAAAAAAgUAAAAIYXNzZXRJZEIFAAAABE5TQlQJAAAAAAAAAgkAAZAAAAABCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAABBwkAAAAAAAACCAkAAZEAAAACCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQFAAAABFVTRE4HBAAAAA1zaWduZWRCeUFkbWluAwMDCQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAUAAAAMYWRtaW5QdWJLZXkxBgkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAADGFkbWluUHViS2V5MgYJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAABQAAAAxhZG1pblB1YktleTMGCQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAUAAAASYWRtaW5QdWJLZXlTdGFraW5nAwMDAwUAAAATY2FsbFRha2VJbnRvQWNjb3VudAYFAAAAD2V4Y2hhbmdlVG9XYXZlcwYFAAAAD2V4Y2hhbmdlVG9OU0JUcwUAAAANc2lnbmVkQnlBZG1pbgcGBQAAABNtdWx0aVNpZ25lZEJ5QWRtaW5zBQAAABNtdWx0aVNpZ25lZEJ5QWRtaW5zcfqn+g==", "height": 1877081, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EKGryZBJNkvtqUa49WZ9pXvnQThXHooWS9TKRkLT4LxZ Next: 7bMNFegWKSo1XCdp6sccFNVC8VdKc5mhFj4tHC1uP6Ay Diff:
OldNewDifferences
4040 let kPeriodLength = "period_length"
4141
4242 let kStartHeight = "start_height"
43+
44+let kFirstHarvestHeight = "first_harvest_height"
4345
4446 let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
4547
8587
8688 let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
8789
90+let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
91+
8892 let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
8993
9094 let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(NSBT), toBase58String(EURN)]
105109
106110 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
107111
108-let isActive = getBooleanValue(this, keyActive)
112+let active = getBooleanValue(this, keyActive)
109113
110114 let strAssetIdA = getStringValue(this, keyAssetIdA)
111115
147151
148152 let commission = 3000
149153
154+let commissionGovernance = 1200
155+
150156 let commissionScaleDelimiter = 1000000
151157
152158 let scaleValue3 = 1000
154160 let scaleValue8 = 100000000
155161
156162 let slippageToleranceDelimiter = 1000
163+
164+let scaleValue8Digits = 8
157165
158166 func accountBalance (assetId) = match assetId {
159167 case id: ByteVector =>
249257
250258 func calcStakingParams (stake,amount,assetId) = if (stake)
251259 then {
252- let $t069306996 = calcStakingFuncAndAddres(stake, assetId)
253- let call = $t069306996._1
254- let stakingAddr = $t069306996._2
260+ let $t069216987 = calcStakingFuncAndAddres(stake, assetId)
261+ let call = $t069216987._1
262+ let stakingAddr = $t069216987._2
255263 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
256264 }
257265 else {
258- let $t070827148 = calcStakingFuncAndAddres(stake, assetId)
259- let call = $t070827148._1
260- let stakingAddr = $t070827148._2
266+ let $t070737139 = calcStakingFuncAndAddres(stake, assetId)
267+ let call = $t070737139._1
268+ let stakingAddr = $t070737139._2
261269 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
262270 }
263271
264272
265-func throwInsufficientAvailableBalance (amount,available,assetName) = throw((((((((("Insufficient DApp balance to pay " + toString(amount)) + " ") + assetName) + " due to staking. Available: ") + toString(available)) + " ") + assetName) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
266-
267-
268-func throwInsufficientAvailableBalances (amountA,amountB) = throw((((((((((((((((("Insufficient DApp balance to pay " + toString(amountA)) + " ") + assetNameA) + " and ") + toString(amountB)) + " ") + assetNameB) + " due to staking. Available: ") + toString(availableBalanceA)) + " ") + assetNameA) + " and ") + toString(availableBalanceB)) + " ") + assetNameB) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
273+func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo) = {
274+ let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
275+ let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
276+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
277+ if ((minAmountToReceive > amountWithFee))
278+ then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
279+ else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
280+ }
269281
270282
271283 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
272284
273285
286+func isActive () = if (active)
287+ then unit
288+ else throw("DApp is inactive at this moment")
289+
290+
274291 @Callable(i)
275292 func init (firstHarvest) = {
276- let $t083358412 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277- let pmtAmountA = $t083358412._1
278- let pmtAssetIdA = $t083358412._2
279- let $t084178494 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280- let pmtAmountB = $t084178494._1
281- let pmtAssetIdB = $t084178494._2
282- let $t084998576 = getAssetInfo(pmtAssetIdA)
283- let pmtStrAssetIdA = $t084998576._1
284- let pmtAssetNameA = $t084998576._2
285- let pmtDecimalsA = $t084998576._3
286- let $t085818658 = getAssetInfo(pmtAssetIdB)
287- let pmtStrAssetIdB = $t085818658._1
288- let pmtAssetNameB = $t085818658._2
289- let pmtDecimalsB = $t085818658._3
293+ let $t083098386 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
294+ let pmtAmountA = $t083098386._1
295+ let pmtAssetIdA = $t083098386._2
296+ let $t083918468 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
297+ let pmtAmountB = $t083918468._1
298+ let pmtAssetIdB = $t083918468._2
299+ let $t084738550 = getAssetInfo(pmtAssetIdA)
300+ let pmtStrAssetIdA = $t084738550._1
301+ let pmtAssetNameA = $t084738550._2
302+ let pmtDecimalsA = $t084738550._3
303+ let $t085558632 = getAssetInfo(pmtAssetIdB)
304+ let pmtStrAssetIdB = $t085558632._1
305+ let pmtAssetNameB = $t085558632._2
306+ let pmtDecimalsB = $t085558632._3
290307 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291308 then throw("Only admin can call this function")
292309 else if (isDefined(getBoolean(this, keyActive)))
328345
329346 @Callable(i)
330347 func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
331- let $t01124711334 = getAssetInfoFromString(strAssetIdA)
332- let pmtStrAssetIdA = $t01124711334._1
333- let pmtAssetNameA = $t01124711334._2
334- let pmtDecimalsA = $t01124711334._3
335- let $t01133911426 = getAssetInfoFromString(strAssetIdB)
336- let pmtStrAssetIdB = $t01133911426._1
337- let pmtAssetNameB = $t01133911426._2
338- let pmtDecimalsB = $t01133911426._3
348+ let $t01122111308 = getAssetInfoFromString(strAssetIdA)
349+ let pmtStrAssetIdA = $t01122111308._1
350+ let pmtAssetNameA = $t01122111308._2
351+ let pmtDecimalsA = $t01122111308._3
352+ let $t01131311400 = getAssetInfoFromString(strAssetIdB)
353+ let pmtStrAssetIdB = $t01131311400._1
354+ let pmtAssetNameB = $t01131311400._2
355+ let pmtDecimalsB = $t01131311400._3
339356 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
340357 then throw("Only admin can call this function")
341358 else if (isDefined(getBoolean(this, keyActive)))
359376
360377
361378 @Callable(i)
362-func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
363- then throw("DApp is inactive at this moment")
364- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
365- then throw("Only admin can call this function")
366- else [IntegerEntry(kShareLimit, shareLimit)]
379+func keepLimitForFirstHarvest (shareLimit) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
380+ then throw("Only admin can call this function")
381+ else [IntegerEntry(kShareLimit, shareLimit)])
367382
368383
369384
370385 @Callable(i)
371-func replenishWithTwoTokens (slippageTolerance) = {
386+func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
372387 let pmtAssetIdA = i.payments[0].assetId
373388 let pmtAssetIdB = i.payments[1].assetId
374389 let pmtAmountA = i.payments[0].amount
375390 let pmtAmountB = i.payments[1].amount
376- let $t01392314000 = getAssetInfo(pmtAssetIdA)
377- let pmtStrAssetIdA = $t01392314000._1
378- let pmtAssetNameA = $t01392314000._2
379- let pmtDecimalsA = $t01392314000._3
380- let $t01400514082 = getAssetInfo(pmtAssetIdB)
381- let pmtStrAssetIdB = $t01400514082._1
382- let pmtAssetNameB = $t01400514082._2
383- let pmtDecimalsB = $t01400514082._3
384- if (if ((balanceA == 0))
391+ let $t01386813945 = getAssetInfo(pmtAssetIdA)
392+ let pmtStrAssetIdA = $t01386813945._1
393+ let pmtAssetNameA = $t01386813945._2
394+ let pmtDecimalsA = $t01386813945._3
395+ let $t01395014027 = getAssetInfo(pmtAssetIdB)
396+ let pmtStrAssetIdB = $t01395014027._1
397+ let pmtAssetNameB = $t01395014027._2
398+ let pmtDecimalsB = $t01395014027._3
399+ let inital = if (if ((balanceA == 0))
385400 then (balanceB == 0)
386401 else false)
387- then {
388- let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
389- if ((pmtAssetIdA == pmtAssetIdB))
390- then throw("Assets must be different")
391- else {
392- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
393- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
394- if (!(isActive))
395- then throw("DApp is inactive at this moment")
396- else if (if ((0 > slippageTolerance))
397- then true
398- else (slippageTolerance > slippageToleranceDelimiter))
399- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
400- else if ((size(i.payments) != 2))
401- then throw("Two attached assets expected")
402- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
403- then true
404- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
405- then throw("Incorrect assets amount: amounts must have the contract ratio")
406- else if (if ((pmtAssetIdA != assetIdA))
407- then true
408- else (pmtAssetIdB != assetIdB))
409- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
410- else if ((shareInitialSupply == 0))
411- then throw("Too small amount to replenish")
412- else if (!(hasEnoughBalance))
413- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
414- else {
415- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
416- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
417- else 0
418- if ((stake1 == stake1))
419- then {
420- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
421- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
422- else 0
423- if ((stake2 == stake2))
424- then [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
425- else throw("Strict value is not equal to itself.")
426- }
427- else throw("Strict value is not equal to itself.")
428- }
429- }
430- }
431- else {
432- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
433- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
434- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
435- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
436- if (!(isActive))
437- then throw("DApp is inactive at this moment")
438- else if (if ((0 > slippageTolerance))
402+ then true
403+ else false
404+ let tokenRatio = if (inital)
405+ then fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
406+ else fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
407+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
408+ let shareTokenToPayAmount = if (inital)
409+ then fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
410+ else fraction(min([fraction(pmtAmountA, scaleValue8, balanceA), fraction(pmtAmountB, scaleValue8, balanceB)]), shareAssetSupply, scaleValue8)
411+ if (if ((0 > slippageTolerance))
412+ then true
413+ else (slippageTolerance > slippageToleranceDelimiter))
414+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
415+ else if ((size(i.payments) != 2))
416+ then throw("Two attached assets expected")
417+ else if (if ((pmtAssetIdA != assetIdA))
418+ then true
419+ else (pmtAssetIdB != assetIdB))
420+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
421+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
439422 then true
440- else (slippageTolerance > slippageToleranceDelimiter))
441- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
442- else if ((size(i.payments) != 2))
443- then throw("Two attached assets expected")
444- else if (if ((pmtAssetIdA != assetIdA))
445- then true
446- else (pmtAssetIdB != assetIdB))
447- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
448- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
449- then true
450- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
451- then throw("Incorrect assets amount: amounts must have the contract ratio")
452- else if ((shareTokenToPayAmount == 0))
453- then throw("Too small amount to replenish")
454- else if (!(hasEnoughBalance))
455- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
456- else {
457- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
458- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
459- else 0
460- if ((stake1 == stake1))
461- then {
462- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
463- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
464- else 0
465- if ((stake2 == stake2))
466- then [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
467- else throw("Strict value is not equal to itself.")
468- }
469- else throw("Strict value is not equal to itself.")
470- }
471- }
472- }
423+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
424+ then throw("Incorrect assets amount: amounts must have the contract ratio")
425+ else if ((shareTokenToPayAmount == 0))
426+ then throw("Too small amount to replenish")
427+ else if (!(hasEnoughBalance))
428+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
429+ else {
430+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
431+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
432+ else 0
433+ if ((stake1 == stake1))
434+ then {
435+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
436+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
437+ else 0
438+ if ((stake2 == stake2))
439+ then [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
440+ else throw("Strict value is not equal to itself.")
441+ }
442+ else throw("Strict value is not equal to itself.")
443+ }
444+ })
473445
474446
475447
476448 @Callable(i)
477-func withdraw () = {
478- let $t01925119326 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
479- let pmtAmount = $t01925119326._1
480- let pmtAssetId = $t01925119326._2
449+func withdraw () = valueOrElse(isActive(), {
450+ let $t01683316908 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
451+ let pmtAmount = $t01683316908._1
452+ let pmtAssetId = $t01683316908._2
481453 let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
482454 let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
483- if (!(isActive))
484- then throw("DApp is inactive at this moment")
485- else if ((size(i.payments) != 1))
486- then throw("One attached payment expected")
487- else if ((pmtAssetId != shareAssetId))
488- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
455+ if ((size(i.payments) != 1))
456+ then throw("One attached payment expected")
457+ else if ((pmtAssetId != shareAssetId))
458+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
459+ else if (!(hasEnoughBalance))
460+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
461+ else {
462+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
463+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
464+ else 0
465+ if ((stake1 == stake1))
466+ then {
467+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
468+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
469+ else 0
470+ if ((stake2 == stake2))
471+ then [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
472+ else throw("Strict value is not equal to itself.")
473+ }
474+ else throw("Strict value is not equal to itself.")
475+ }
476+ })
477+
478+
479+
480+@Callable(i)
481+func exchange (minAmountToReceive) = valueOrElse(isActive(), {
482+ let $t01821418289 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
483+ let pmtAmount = $t01821418289._1
484+ let pmtAssetId = $t01821418289._2
485+ if (if ((balanceA == 0))
486+ then true
487+ else (balanceB == 0))
488+ then throw("Can't exchange with zero balance")
489+ else if ((0 >= minAmountToReceive))
490+ then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
491+ else if ((size(i.payments) != 1))
492+ then throw("One attached payment expected")
489493 else if (!(hasEnoughBalance))
490494 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
491- else if (if ((amountToPayA > availableBalanceA))
492- then true
493- else (amountToPayB > availableBalanceB))
494- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
495- else {
495+ else if ((pmtAssetId == assetIdA))
496+ then {
497+ let assetIdSend = assetIdB
498+ let $t01884418966 = calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB)
499+ let amountWithoutFee = $t01884418966._1
500+ let amountWithFee = $t01884418966._2
501+ let governanceReward = $t01884418966._3
502+ let newBalanceA = (balanceA + pmtAmount)
503+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
496504 let stake1 = if (containsElement(stakingAssets, strAssetIdA))
497- then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
505+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
498506 else 0
499507 if ((stake1 == stake1))
500508 then {
501509 let stake2 = if (containsElement(stakingAssets, strAssetIdB))
502- then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
510+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
503511 else 0
504512 if ((stake2 == stake2))
505- then [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
513+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
506514 else throw("Strict value is not equal to itself.")
507515 }
508516 else throw("Strict value is not equal to itself.")
509517 }
510- }
511-
512-
513-
514-@Callable(i)
515-func exchange (minAmountToReceive) = {
516- let $t02084120916 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
517- let pmtAmount = $t02084120916._1
518- let pmtAssetId = $t02084120916._2
519- func calculateFees (tokenFrom,tokenTo) = {
520- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
521- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
522- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
523- if ((minAmountToReceive > amountWithFee))
524- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
525- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
526- }
527-
528- if (!(isActive))
529- then throw("DApp is inactive at this moment")
530- else if (if ((balanceA == 0))
531- then true
532- else (balanceB == 0))
533- then throw("Can't exchange with zero balance")
534- else if ((0 >= minAmountToReceive))
535- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
536- else if ((size(i.payments) != 1))
537- then throw("One attached payment expected")
538- else if (!(hasEnoughBalance))
539- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
540- else if ((pmtAssetId == assetIdA))
518+ else if ((pmtAssetId == assetIdB))
541519 then {
542- let assetIdSend = assetIdB
543- let $t02219022281 = calculateFees(balanceA, balanceB)
544- let amountWithoutFee = $t02219022281._1
545- let amountWithFee = $t02219022281._2
546- let governanceReward = $t02219022281._3
547- let newBalanceA = (balanceA + pmtAmount)
548- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
520+ let assetIdSend = assetIdA
521+ let $t01992120043 = calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA)
522+ let amountWithoutFee = $t01992120043._1
523+ let amountWithFee = $t01992120043._2
524+ let governanceReward = $t01992120043._3
525+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
526+ let newBalanceB = (balanceB + pmtAmount)
549527 let stake1 = if (containsElement(stakingAssets, strAssetIdA))
550- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
528+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
551529 else 0
552530 if ((stake1 == stake1))
553531 then {
554532 let stake2 = if (containsElement(stakingAssets, strAssetIdB))
555- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
533+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
556534 else 0
557535 if ((stake2 == stake2))
558536 then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
560538 }
561539 else throw("Strict value is not equal to itself.")
562540 }
563- else if ((pmtAssetId == assetIdB))
564- then {
565- let assetIdSend = assetIdA
566- let $t02323623327 = calculateFees(balanceB, balanceA)
567- let amountWithoutFee = $t02323623327._1
568- let amountWithFee = $t02323623327._2
569- let governanceReward = $t02323623327._3
570- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
571- let newBalanceB = (balanceB + pmtAmount)
572- if (if ((stakedAmountA >= newBalanceA))
573- then true
574- else (stakedAmountB >= newBalanceB))
575- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
576- else {
577- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
578- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
579- else 0
580- if ((stake1 == stake1))
581- then {
582- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
583- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
584- else 0
585- if ((stake2 == stake2))
586- then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
587- else throw("Strict value is not equal to itself.")
588- }
589- else throw("Strict value is not equal to itself.")
590- }
591- }
592- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
593- }
541+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
542+ })
594543
595544
596545
597546 @Callable(i)
598-func shutdown () = if (!(isActive))
547+func shutdown () = if (!(active))
599548 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
600549 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
601550 then throw("Only admin can call this function")
604553
605554
606555 @Callable(i)
607-func activate () = if (isActive)
556+func activate () = if (active)
608557 then throw("DApp is already active")
609558 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
610559 then throw("Only admin can call this function")
613562
614563
615564 @Callable(i)
616-func takeIntoAccountExtraFunds (amountLeave) = {
565+func takeIntoAccountExtraFunds (amountLeave) = valueOrElse(isActive(), {
617566 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
618567 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
619568 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
622571 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
623572 then amountLeave
624573 else 0))
625- if (!(isActive))
626- then throw("DApp is inactive at this moment")
627- else if ((i.caller != this))
628- then throw("Only the DApp itself can call this function")
629- else if ((0 > amountLeave))
630- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
631- else if (if ((0 > uncountableAmountEnrollAssetA))
574+ if ((i.caller != this))
575+ then throw("Only the DApp itself can call this function")
576+ else if ((0 > amountLeave))
577+ then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
578+ else if (if ((0 > uncountableAmountEnrollAssetA))
579+ then true
580+ else (0 > uncountableAmountEnrollAssetB))
581+ then suspend("Enroll amount negative")
582+ else if (if ((0 > amountEnrollA))
632583 then true
633- else (0 > uncountableAmountEnrollAssetB))
634- then suspend("Enroll amount negative")
635- else if (if ((0 > amountEnrollA))
636- then true
637- else (0 > amountEnrollB))
638- then throw("Too large amountLeave")
639- else {
640- let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
641- then (amountEnrollA > 0)
642- else false)
643- then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
644- else 0
645- if ((stake1 == stake1))
646- then {
647- let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
648- then (amountEnrollB > 0)
649- else false)
650- then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
651- else 0
652- if ((stake2 == stake2))
653- then [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
654- else throw("Strict value is not equal to itself.")
655- }
656- else throw("Strict value is not equal to itself.")
657- }
658- }
584+ else (0 > amountEnrollB))
585+ then throw("Too large amountLeave")
586+ else {
587+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
588+ then (amountEnrollA > 0)
589+ else false)
590+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
591+ else 0
592+ if ((stake1 == stake1))
593+ then {
594+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
595+ then (amountEnrollB > 0)
596+ else false)
597+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
598+ else 0
599+ if ((stake2 == stake2))
600+ then [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
601+ else throw("Strict value is not equal to itself.")
602+ }
603+ else throw("Strict value is not equal to itself.")
604+ }
605+ })
659606
660607
661608
681628 }
682629 }
683630 else {
684- let $t02793128034 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
685- let call = $t02793128034._1
686- let addr = $t02793128034._2
687- let params = $t02793128034._3
688- let payments = $t02793128034._4
631+ let $t02422724330 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
632+ let call = $t02422724330._1
633+ let addr = $t02422724330._2
634+ let params = $t02422724330._3
635+ let payments = $t02422724330._4
689636 let inv = invoke(addr, call, params, payments)
690- nil
637+ if ((inv == inv))
638+ then nil
639+ else throw("Strict value is not equal to itself.")
691640 }
692641
693642
694643
695644 @Callable(i)
696-func stakeAll () = if (!(isActive))
697- then throw("DApp is inactive at this moment")
698- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
699- then throw("Only admin can call this function")
700- else {
701- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
702- then {
703- let amountA = (balanceA - stakedAmountA)
704- if ((amountA > 0))
705- then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
706- else 0
707- }
708- else 0
709- if ((stake1 == stake1))
710- then {
711- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
712- then {
713- let amountB = (balanceB - stakedAmountB)
714- if ((amountB > 0))
715- then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
716- else 0
717- }
718- else 0
719- if ((stake2 == stake2))
720- then nil
721- else throw("Strict value is not equal to itself.")
722- }
723- else throw("Strict value is not equal to itself.")
724- }
645+func stakeAll () = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
646+ then throw("Only admin can call this function")
647+ else {
648+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
649+ then {
650+ let amountA = (balanceA - stakedAmountA)
651+ if ((amountA > 0))
652+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
653+ else 0
654+ }
655+ else 0
656+ if ((stake1 == stake1))
657+ then {
658+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
659+ then {
660+ let amountB = (balanceB - stakedAmountB)
661+ if ((amountB > 0))
662+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
663+ else 0
664+ }
665+ else 0
666+ if ((stake2 == stake2))
667+ then nil
668+ else throw("Strict value is not equal to itself.")
669+ }
670+ else throw("Strict value is not equal to itself.")
671+ })
725672
726673
727674 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "1.0.0"
55
66 let keyVersion = "version"
77
88 let keyActive = "active"
99
1010 let keyAssetIdA = "A_asset_id"
1111
1212 let keyAssetIdB = "B_asset_id"
1313
1414 let keyBalanceA = "A_asset_balance"
1515
1616 let keyBalanceB = "B_asset_balance"
1717
1818 let keyBalanceInitA = "A_asset_init"
1919
2020 let keyBalanceInitB = "B_asset_init"
2121
2222 let keyShareAssetId = "share_asset_id"
2323
2424 let keyShareAssetSupply = "share_asset_supply"
2525
2626 let keyCommission = "commission"
2727
2828 let keyCommissionScaleDelimiter = "commission_scale_delimiter"
2929
3030 let keyCause = "shutdown_cause"
3131
3232 let keyFirstHarvest = "first_harvest"
3333
3434 let keyFirstHarvestHeight = "first_harvest_height"
3535
3636 let kShareLimit = "share_limit_on_first_harvest"
3737
3838 let kBasePeriod = "base_period"
3939
4040 let kPeriodLength = "period_length"
4141
4242 let kStartHeight = "start_height"
43+
44+let kFirstHarvestHeight = "first_harvest_height"
4345
4446 let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
4547
4648 let keyEURNAddress = "staking_eurn_address"
4749
4850 let keyLeasingPool = "leasing_address"
4951
5052 let keyLeasingAmount = "leasing_amount"
5153
5254 let keyLeasingId = "leasing_id"
5355
5456 let keyAdminPubKey1 = "admin_pub_1"
5557
5658 let keyAdminPubKey2 = "admin_pub_2"
5759
5860 let keyAdminPubKey3 = "admin_pub_3"
5961
6062 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
6163
6264 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
6365 case string: String =>
6466 fromBase58String(string)
6567 case nothing =>
6668 throw("Admin public key is empty")
6769 }
6870
6971
7072 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
7173
7274 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
7375
7476 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
7577
7678 let adminPubKeyStartStop = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
7779
7880 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
7981
8082 let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
8183
8284 let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
8385
8486 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
8587
8688 let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
8789
90+let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
91+
8892 let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
8993
9094 let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(NSBT), toBase58String(EURN)]
9195
9296 let stakingUSDNNSBTAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyUSDNNSBTAddress), "no usdn staking address")))
9397
9498 let stakingEURNAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyEURNAddress), "no usdn staking address")))
9599
96100 let USDNToWavesExchanger = Address(base58'3N8PGkzXhbtTvEwEQTtE2xiTJmsDEQ9XfoZ')
97101
98102 let USDNToNSBTExchanger = Address(base58'3MqW1t2cxdYy2emEMk3YtZkRwQPhHaTfWRe')
99103
100104 let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
101105
102106 let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
103107
104108 let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
105109
106110 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
107111
108-let isActive = getBooleanValue(this, keyActive)
112+let active = getBooleanValue(this, keyActive)
109113
110114 let strAssetIdA = getStringValue(this, keyAssetIdA)
111115
112116 let strAssetIdB = getStringValue(this, keyAssetIdB)
113117
114118 let assetIdA = if ((strAssetIdA == "WAVES"))
115119 then unit
116120 else fromBase58String(strAssetIdA)
117121
118122 let assetIdB = if ((strAssetIdB == "WAVES"))
119123 then unit
120124 else fromBase58String(strAssetIdB)
121125
122126 let assetNameA = match assetIdA {
123127 case id: ByteVector =>
124128 value(assetInfo(id)).name
125129 case waves: Unit =>
126130 "WAVES"
127131 case _ =>
128132 throw("Match error")
129133 }
130134
131135 let assetNameB = match assetIdB {
132136 case id: ByteVector =>
133137 value(assetInfo(id)).name
134138 case waves: Unit =>
135139 "WAVES"
136140 case _ =>
137141 throw("Match error")
138142 }
139143
140144 let balanceA = getIntegerValue(this, keyBalanceA)
141145
142146 let balanceB = getIntegerValue(this, keyBalanceB)
143147
144148 let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId))
145149
146150 let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply)
147151
148152 let commission = 3000
149153
154+let commissionGovernance = 1200
155+
150156 let commissionScaleDelimiter = 1000000
151157
152158 let scaleValue3 = 1000
153159
154160 let scaleValue8 = 100000000
155161
156162 let slippageToleranceDelimiter = 1000
163+
164+let scaleValue8Digits = 8
157165
158166 func accountBalance (assetId) = match assetId {
159167 case id: ByteVector =>
160168 assetBalance(this, id)
161169 case waves: Unit =>
162170 wavesBalance(this).available
163171 case _ =>
164172 throw("Match error")
165173 }
166174
167175
168176 func stakedAmount (assetId) = {
169177 let stakedAmountCalculated = match assetId {
170178 case aId: ByteVector =>
171179 if (if ((aId == USDN))
172180 then true
173181 else (aId == NSBT))
174182 then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
175183 else if ((aId == EURN))
176184 then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
177185 else 0
178186 case _: Unit =>
179187 valueOrElse(getInteger(this, keyLeasingAmount), 0)
180188 case _ =>
181189 throw("Match error")
182190 }
183191 match stakedAmountCalculated {
184192 case i: Int =>
185193 i
186194 case _ =>
187195 0
188196 }
189197 }
190198
191199
192200 let stakedAmountA = stakedAmount(assetIdA)
193201
194202 let stakedAmountB = stakedAmount(assetIdB)
195203
196204 let assetInitA = getIntegerValue(this, keyBalanceInitA)
197205
198206 let assetInitB = getIntegerValue(this, keyBalanceInitB)
199207
200208 let availableBalanceA = (balanceA - stakedAmountA)
201209
202210 let availableBalanceB = (balanceB - stakedAmountB)
203211
204212 let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
205213
206214 let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
207215
208216 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
209217 then (accountBalanceWithStakedB >= balanceB)
210218 else false
211219
212220 func getAssetInfo (assetId) = match assetId {
213221 case id: ByteVector =>
214222 let stringId = toBase58String(id)
215223 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
216224 $Tuple3(stringId, info.name, info.decimals)
217225 case waves: Unit =>
218226 $Tuple3("WAVES", "WAVES", 8)
219227 case _ =>
220228 throw("Match error")
221229 }
222230
223231
224232 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
225233 then $Tuple3("WAVES", "WAVES", 8)
226234 else {
227235 let stringId = assetStr
228236 let id = fromBase58String(assetStr)
229237 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
230238 $Tuple3(stringId, info.name, info.decimals)
231239 }
232240
233241
234242 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
235243
236244
237245 func calcStakingFuncAndAddres (stake,assetId) = if (stake)
238246 then if ((assetId == USDN))
239247 then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
240248 else if ((assetId == NSBT))
241249 then $Tuple2("lockNsbt", stakingUSDNNSBTAddress)
242250 else $Tuple2("startStaking", stakingEURNAddress)
243251 else if ((assetId == USDN))
244252 then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
245253 else if ((assetId == NSBT))
246254 then $Tuple2("unlockNsbt", stakingUSDNNSBTAddress)
247255 else $Tuple2("stopStaking", stakingEURNAddress)
248256
249257
250258 func calcStakingParams (stake,amount,assetId) = if (stake)
251259 then {
252- let $t069306996 = calcStakingFuncAndAddres(stake, assetId)
253- let call = $t069306996._1
254- let stakingAddr = $t069306996._2
260+ let $t069216987 = calcStakingFuncAndAddres(stake, assetId)
261+ let call = $t069216987._1
262+ let stakingAddr = $t069216987._2
255263 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
256264 }
257265 else {
258- let $t070827148 = calcStakingFuncAndAddres(stake, assetId)
259- let call = $t070827148._1
260- let stakingAddr = $t070827148._2
266+ let $t070737139 = calcStakingFuncAndAddres(stake, assetId)
267+ let call = $t070737139._1
268+ let stakingAddr = $t070737139._2
261269 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
262270 }
263271
264272
265-func throwInsufficientAvailableBalance (amount,available,assetName) = throw((((((((("Insufficient DApp balance to pay " + toString(amount)) + " ") + assetName) + " due to staking. Available: ") + toString(available)) + " ") + assetName) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
266-
267-
268-func throwInsufficientAvailableBalances (amountA,amountB) = throw((((((((((((((((("Insufficient DApp balance to pay " + toString(amountA)) + " ") + assetNameA) + " and ") + toString(amountB)) + " ") + assetNameB) + " due to staking. Available: ") + toString(availableBalanceA)) + " ") + assetNameA) + " and ") + toString(availableBalanceB)) + " ") + assetNameB) + ". Please contact support in Telegram: https://t.me/swopfisupport"))
273+func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo) = {
274+ let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
275+ let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
276+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
277+ if ((minAmountToReceive > amountWithFee))
278+ then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
279+ else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
280+ }
269281
270282
271283 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
272284
273285
286+func isActive () = if (active)
287+ then unit
288+ else throw("DApp is inactive at this moment")
289+
290+
274291 @Callable(i)
275292 func init (firstHarvest) = {
276- let $t083358412 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277- let pmtAmountA = $t083358412._1
278- let pmtAssetIdA = $t083358412._2
279- let $t084178494 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280- let pmtAmountB = $t084178494._1
281- let pmtAssetIdB = $t084178494._2
282- let $t084998576 = getAssetInfo(pmtAssetIdA)
283- let pmtStrAssetIdA = $t084998576._1
284- let pmtAssetNameA = $t084998576._2
285- let pmtDecimalsA = $t084998576._3
286- let $t085818658 = getAssetInfo(pmtAssetIdB)
287- let pmtStrAssetIdB = $t085818658._1
288- let pmtAssetNameB = $t085818658._2
289- let pmtDecimalsB = $t085818658._3
293+ let $t083098386 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
294+ let pmtAmountA = $t083098386._1
295+ let pmtAssetIdA = $t083098386._2
296+ let $t083918468 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
297+ let pmtAmountB = $t083918468._1
298+ let pmtAssetIdB = $t083918468._2
299+ let $t084738550 = getAssetInfo(pmtAssetIdA)
300+ let pmtStrAssetIdA = $t084738550._1
301+ let pmtAssetNameA = $t084738550._2
302+ let pmtDecimalsA = $t084738550._3
303+ let $t085558632 = getAssetInfo(pmtAssetIdB)
304+ let pmtStrAssetIdB = $t085558632._1
305+ let pmtAssetNameB = $t085558632._2
306+ let pmtDecimalsB = $t085558632._3
290307 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291308 then throw("Only admin can call this function")
292309 else if (isDefined(getBoolean(this, keyActive)))
293310 then throw("DApp is already active")
294311 else if ((pmtAssetIdA == pmtAssetIdB))
295312 then throw("Assets must be different")
296313 else {
297314 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
298315 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
299316 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
300317 let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
301318 let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
302319 let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
303320 let shareInitialSupply = fraction(arg1, arg2, arg3)
304321 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
305322 let shareIssueId = calculateAssetId(shareIssue)
306323 let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
307324 then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
308325 else 0
309326 if ((stake1 == stake1))
310327 then {
311328 let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
312329 then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
313330 else 0
314331 if ((stake2 == stake2))
315332 then {
316333 let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
317334 if (firstHarvest)
318335 then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
319336 else baseEntry
320337 }
321338 else throw("Strict value is not equal to itself.")
322339 }
323340 else throw("Strict value is not equal to itself.")
324341 }
325342 }
326343
327344
328345
329346 @Callable(i)
330347 func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
331- let $t01124711334 = getAssetInfoFromString(strAssetIdA)
332- let pmtStrAssetIdA = $t01124711334._1
333- let pmtAssetNameA = $t01124711334._2
334- let pmtDecimalsA = $t01124711334._3
335- let $t01133911426 = getAssetInfoFromString(strAssetIdB)
336- let pmtStrAssetIdB = $t01133911426._1
337- let pmtAssetNameB = $t01133911426._2
338- let pmtDecimalsB = $t01133911426._3
348+ let $t01122111308 = getAssetInfoFromString(strAssetIdA)
349+ let pmtStrAssetIdA = $t01122111308._1
350+ let pmtAssetNameA = $t01122111308._2
351+ let pmtDecimalsA = $t01122111308._3
352+ let $t01131311400 = getAssetInfoFromString(strAssetIdB)
353+ let pmtStrAssetIdB = $t01131311400._1
354+ let pmtAssetNameB = $t01131311400._2
355+ let pmtDecimalsB = $t01131311400._3
339356 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
340357 then throw("Only admin can call this function")
341358 else if (isDefined(getBoolean(this, keyActive)))
342359 then throw("DApp is already active")
343360 else if ((strAssetIdA == strAssetIdB))
344361 then throw("Assets must be different")
345362 else {
346363 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
347364 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
348365 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
349366 let shareInitialSupply = 0
350367 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
351368 let shareIssueId = calculateAssetId(shareIssue)
352369 let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)]
353370 if (firstHarvest)
354371 then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
355372 else baseEntry
356373 }
357374 }
358375
359376
360377
361378 @Callable(i)
362-func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
363- then throw("DApp is inactive at this moment")
364- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
365- then throw("Only admin can call this function")
366- else [IntegerEntry(kShareLimit, shareLimit)]
379+func keepLimitForFirstHarvest (shareLimit) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
380+ then throw("Only admin can call this function")
381+ else [IntegerEntry(kShareLimit, shareLimit)])
367382
368383
369384
370385 @Callable(i)
371-func replenishWithTwoTokens (slippageTolerance) = {
386+func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
372387 let pmtAssetIdA = i.payments[0].assetId
373388 let pmtAssetIdB = i.payments[1].assetId
374389 let pmtAmountA = i.payments[0].amount
375390 let pmtAmountB = i.payments[1].amount
376- let $t01392314000 = getAssetInfo(pmtAssetIdA)
377- let pmtStrAssetIdA = $t01392314000._1
378- let pmtAssetNameA = $t01392314000._2
379- let pmtDecimalsA = $t01392314000._3
380- let $t01400514082 = getAssetInfo(pmtAssetIdB)
381- let pmtStrAssetIdB = $t01400514082._1
382- let pmtAssetNameB = $t01400514082._2
383- let pmtDecimalsB = $t01400514082._3
384- if (if ((balanceA == 0))
391+ let $t01386813945 = getAssetInfo(pmtAssetIdA)
392+ let pmtStrAssetIdA = $t01386813945._1
393+ let pmtAssetNameA = $t01386813945._2
394+ let pmtDecimalsA = $t01386813945._3
395+ let $t01395014027 = getAssetInfo(pmtAssetIdB)
396+ let pmtStrAssetIdB = $t01395014027._1
397+ let pmtAssetNameB = $t01395014027._2
398+ let pmtDecimalsB = $t01395014027._3
399+ let inital = if (if ((balanceA == 0))
385400 then (balanceB == 0)
386401 else false)
387- then {
388- let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
389- if ((pmtAssetIdA == pmtAssetIdB))
390- then throw("Assets must be different")
391- else {
392- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
393- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
394- if (!(isActive))
395- then throw("DApp is inactive at this moment")
396- else if (if ((0 > slippageTolerance))
397- then true
398- else (slippageTolerance > slippageToleranceDelimiter))
399- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
400- else if ((size(i.payments) != 2))
401- then throw("Two attached assets expected")
402- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
403- then true
404- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
405- then throw("Incorrect assets amount: amounts must have the contract ratio")
406- else if (if ((pmtAssetIdA != assetIdA))
407- then true
408- else (pmtAssetIdB != assetIdB))
409- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
410- else if ((shareInitialSupply == 0))
411- then throw("Too small amount to replenish")
412- else if (!(hasEnoughBalance))
413- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
414- else {
415- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
416- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
417- else 0
418- if ((stake1 == stake1))
419- then {
420- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
421- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
422- else 0
423- if ((stake2 == stake2))
424- then [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
425- else throw("Strict value is not equal to itself.")
426- }
427- else throw("Strict value is not equal to itself.")
428- }
429- }
430- }
431- else {
432- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
433- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
434- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
435- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
436- if (!(isActive))
437- then throw("DApp is inactive at this moment")
438- else if (if ((0 > slippageTolerance))
402+ then true
403+ else false
404+ let tokenRatio = if (inital)
405+ then fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
406+ else fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
407+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
408+ let shareTokenToPayAmount = if (inital)
409+ then fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
410+ else fraction(min([fraction(pmtAmountA, scaleValue8, balanceA), fraction(pmtAmountB, scaleValue8, balanceB)]), shareAssetSupply, scaleValue8)
411+ if (if ((0 > slippageTolerance))
412+ then true
413+ else (slippageTolerance > slippageToleranceDelimiter))
414+ then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
415+ else if ((size(i.payments) != 2))
416+ then throw("Two attached assets expected")
417+ else if (if ((pmtAssetIdA != assetIdA))
418+ then true
419+ else (pmtAssetIdB != assetIdB))
420+ then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
421+ else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
439422 then true
440- else (slippageTolerance > slippageToleranceDelimiter))
441- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
442- else if ((size(i.payments) != 2))
443- then throw("Two attached assets expected")
444- else if (if ((pmtAssetIdA != assetIdA))
445- then true
446- else (pmtAssetIdB != assetIdB))
447- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
448- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
449- then true
450- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
451- then throw("Incorrect assets amount: amounts must have the contract ratio")
452- else if ((shareTokenToPayAmount == 0))
453- then throw("Too small amount to replenish")
454- else if (!(hasEnoughBalance))
455- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
456- else {
457- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
458- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
459- else 0
460- if ((stake1 == stake1))
461- then {
462- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
463- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
464- else 0
465- if ((stake2 == stake2))
466- then [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
467- else throw("Strict value is not equal to itself.")
468- }
469- else throw("Strict value is not equal to itself.")
470- }
471- }
472- }
423+ else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
424+ then throw("Incorrect assets amount: amounts must have the contract ratio")
425+ else if ((shareTokenToPayAmount == 0))
426+ then throw("Too small amount to replenish")
427+ else if (!(hasEnoughBalance))
428+ then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
429+ else {
430+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
431+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
432+ else 0
433+ if ((stake1 == stake1))
434+ then {
435+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
436+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
437+ else 0
438+ if ((stake2 == stake2))
439+ then [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
440+ else throw("Strict value is not equal to itself.")
441+ }
442+ else throw("Strict value is not equal to itself.")
443+ }
444+ })
473445
474446
475447
476448 @Callable(i)
477-func withdraw () = {
478- let $t01925119326 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
479- let pmtAmount = $t01925119326._1
480- let pmtAssetId = $t01925119326._2
449+func withdraw () = valueOrElse(isActive(), {
450+ let $t01683316908 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
451+ let pmtAmount = $t01683316908._1
452+ let pmtAssetId = $t01683316908._2
481453 let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
482454 let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
483- if (!(isActive))
484- then throw("DApp is inactive at this moment")
485- else if ((size(i.payments) != 1))
486- then throw("One attached payment expected")
487- else if ((pmtAssetId != shareAssetId))
488- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
455+ if ((size(i.payments) != 1))
456+ then throw("One attached payment expected")
457+ else if ((pmtAssetId != shareAssetId))
458+ then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
459+ else if (!(hasEnoughBalance))
460+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
461+ else {
462+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
463+ then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
464+ else 0
465+ if ((stake1 == stake1))
466+ then {
467+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
468+ then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
469+ else 0
470+ if ((stake2 == stake2))
471+ then [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
472+ else throw("Strict value is not equal to itself.")
473+ }
474+ else throw("Strict value is not equal to itself.")
475+ }
476+ })
477+
478+
479+
480+@Callable(i)
481+func exchange (minAmountToReceive) = valueOrElse(isActive(), {
482+ let $t01821418289 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
483+ let pmtAmount = $t01821418289._1
484+ let pmtAssetId = $t01821418289._2
485+ if (if ((balanceA == 0))
486+ then true
487+ else (balanceB == 0))
488+ then throw("Can't exchange with zero balance")
489+ else if ((0 >= minAmountToReceive))
490+ then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
491+ else if ((size(i.payments) != 1))
492+ then throw("One attached payment expected")
489493 else if (!(hasEnoughBalance))
490494 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
491- else if (if ((amountToPayA > availableBalanceA))
492- then true
493- else (amountToPayB > availableBalanceB))
494- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
495- else {
495+ else if ((pmtAssetId == assetIdA))
496+ then {
497+ let assetIdSend = assetIdB
498+ let $t01884418966 = calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB)
499+ let amountWithoutFee = $t01884418966._1
500+ let amountWithFee = $t01884418966._2
501+ let governanceReward = $t01884418966._3
502+ let newBalanceA = (balanceA + pmtAmount)
503+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
496504 let stake1 = if (containsElement(stakingAssets, strAssetIdA))
497- then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
505+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
498506 else 0
499507 if ((stake1 == stake1))
500508 then {
501509 let stake2 = if (containsElement(stakingAssets, strAssetIdB))
502- then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
510+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
503511 else 0
504512 if ((stake2 == stake2))
505- then [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
513+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
506514 else throw("Strict value is not equal to itself.")
507515 }
508516 else throw("Strict value is not equal to itself.")
509517 }
510- }
511-
512-
513-
514-@Callable(i)
515-func exchange (minAmountToReceive) = {
516- let $t02084120916 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
517- let pmtAmount = $t02084120916._1
518- let pmtAssetId = $t02084120916._2
519- func calculateFees (tokenFrom,tokenTo) = {
520- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
521- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
522- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
523- if ((minAmountToReceive > amountWithFee))
524- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
525- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
526- }
527-
528- if (!(isActive))
529- then throw("DApp is inactive at this moment")
530- else if (if ((balanceA == 0))
531- then true
532- else (balanceB == 0))
533- then throw("Can't exchange with zero balance")
534- else if ((0 >= minAmountToReceive))
535- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
536- else if ((size(i.payments) != 1))
537- then throw("One attached payment expected")
538- else if (!(hasEnoughBalance))
539- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
540- else if ((pmtAssetId == assetIdA))
518+ else if ((pmtAssetId == assetIdB))
541519 then {
542- let assetIdSend = assetIdB
543- let $t02219022281 = calculateFees(balanceA, balanceB)
544- let amountWithoutFee = $t02219022281._1
545- let amountWithFee = $t02219022281._2
546- let governanceReward = $t02219022281._3
547- let newBalanceA = (balanceA + pmtAmount)
548- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
520+ let assetIdSend = assetIdA
521+ let $t01992120043 = calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA)
522+ let amountWithoutFee = $t01992120043._1
523+ let amountWithFee = $t01992120043._2
524+ let governanceReward = $t01992120043._3
525+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
526+ let newBalanceB = (balanceB + pmtAmount)
549527 let stake1 = if (containsElement(stakingAssets, strAssetIdA))
550- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
528+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
551529 else 0
552530 if ((stake1 == stake1))
553531 then {
554532 let stake2 = if (containsElement(stakingAssets, strAssetIdB))
555- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
533+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
556534 else 0
557535 if ((stake2 == stake2))
558536 then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
559537 else throw("Strict value is not equal to itself.")
560538 }
561539 else throw("Strict value is not equal to itself.")
562540 }
563- else if ((pmtAssetId == assetIdB))
564- then {
565- let assetIdSend = assetIdA
566- let $t02323623327 = calculateFees(balanceB, balanceA)
567- let amountWithoutFee = $t02323623327._1
568- let amountWithFee = $t02323623327._2
569- let governanceReward = $t02323623327._3
570- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
571- let newBalanceB = (balanceB + pmtAmount)
572- if (if ((stakedAmountA >= newBalanceA))
573- then true
574- else (stakedAmountB >= newBalanceB))
575- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
576- else {
577- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
578- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
579- else 0
580- if ((stake1 == stake1))
581- then {
582- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
583- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
584- else 0
585- if ((stake2 == stake2))
586- then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
587- else throw("Strict value is not equal to itself.")
588- }
589- else throw("Strict value is not equal to itself.")
590- }
591- }
592- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
593- }
541+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
542+ })
594543
595544
596545
597546 @Callable(i)
598-func shutdown () = if (!(isActive))
547+func shutdown () = if (!(active))
599548 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
600549 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
601550 then throw("Only admin can call this function")
602551 else suspend("Paused by admin")
603552
604553
605554
606555 @Callable(i)
607-func activate () = if (isActive)
556+func activate () = if (active)
608557 then throw("DApp is already active")
609558 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
610559 then throw("Only admin can call this function")
611560 else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
612561
613562
614563
615564 @Callable(i)
616-func takeIntoAccountExtraFunds (amountLeave) = {
565+func takeIntoAccountExtraFunds (amountLeave) = valueOrElse(isActive(), {
617566 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
618567 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
619568 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
620569 then amountLeave
621570 else 0))
622571 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
623572 then amountLeave
624573 else 0))
625- if (!(isActive))
626- then throw("DApp is inactive at this moment")
627- else if ((i.caller != this))
628- then throw("Only the DApp itself can call this function")
629- else if ((0 > amountLeave))
630- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
631- else if (if ((0 > uncountableAmountEnrollAssetA))
574+ if ((i.caller != this))
575+ then throw("Only the DApp itself can call this function")
576+ else if ((0 > amountLeave))
577+ then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
578+ else if (if ((0 > uncountableAmountEnrollAssetA))
579+ then true
580+ else (0 > uncountableAmountEnrollAssetB))
581+ then suspend("Enroll amount negative")
582+ else if (if ((0 > amountEnrollA))
632583 then true
633- else (0 > uncountableAmountEnrollAssetB))
634- then suspend("Enroll amount negative")
635- else if (if ((0 > amountEnrollA))
636- then true
637- else (0 > amountEnrollB))
638- then throw("Too large amountLeave")
639- else {
640- let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
641- then (amountEnrollA > 0)
642- else false)
643- then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
644- else 0
645- if ((stake1 == stake1))
646- then {
647- let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
648- then (amountEnrollB > 0)
649- else false)
650- then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
651- else 0
652- if ((stake2 == stake2))
653- then [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
654- else throw("Strict value is not equal to itself.")
655- }
656- else throw("Strict value is not equal to itself.")
657- }
658- }
584+ else (0 > amountEnrollB))
585+ then throw("Too large amountLeave")
586+ else {
587+ let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
588+ then (amountEnrollA > 0)
589+ else false)
590+ then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
591+ else 0
592+ if ((stake1 == stake1))
593+ then {
594+ let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
595+ then (amountEnrollB > 0)
596+ else false)
597+ then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
598+ else 0
599+ if ((stake2 == stake2))
600+ then [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
601+ else throw("Strict value is not equal to itself.")
602+ }
603+ else throw("Strict value is not equal to itself.")
604+ }
605+ })
659606
660607
661608
662609 @Callable(i)
663610 func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
664611 then throw("Only contract itself can invoke this function")
665612 else if ((assetIdString == "WAVES"))
666613 then {
667614 let pool = addressFromStringValue(valueOrErrorMessage(getString(oracle, keyLeasingPool), "No leasing pool in oracle"))
668615 let leasingId = getBinary(this, keyLeasingId)
669616 let leasingAmount = valueOrElse(getInteger(this, keyLeasingAmount), 0)
670617 let newLeaseAmount = if (stake)
671618 then (leasingAmount + amount)
672619 else (leasingAmount - amount)
673620 let newLease = Lease(pool, newLeaseAmount)
674621 let newLeaseId = calculateLeaseId(newLease)
675622 let baseEtry = [newLease, BinaryEntry(keyLeasingId, newLeaseId), IntegerEntry(keyLeasingAmount, newLeaseAmount)]
676623 match leasingId {
677624 case lId: ByteVector =>
678625 ([LeaseCancel(lId)] ++ baseEtry)
679626 case _ =>
680627 baseEtry
681628 }
682629 }
683630 else {
684- let $t02793128034 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
685- let call = $t02793128034._1
686- let addr = $t02793128034._2
687- let params = $t02793128034._3
688- let payments = $t02793128034._4
631+ let $t02422724330 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
632+ let call = $t02422724330._1
633+ let addr = $t02422724330._2
634+ let params = $t02422724330._3
635+ let payments = $t02422724330._4
689636 let inv = invoke(addr, call, params, payments)
690- nil
637+ if ((inv == inv))
638+ then nil
639+ else throw("Strict value is not equal to itself.")
691640 }
692641
693642
694643
695644 @Callable(i)
696-func stakeAll () = if (!(isActive))
697- then throw("DApp is inactive at this moment")
698- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
699- then throw("Only admin can call this function")
700- else {
701- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
702- then {
703- let amountA = (balanceA - stakedAmountA)
704- if ((amountA > 0))
705- then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
706- else 0
707- }
708- else 0
709- if ((stake1 == stake1))
710- then {
711- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
712- then {
713- let amountB = (balanceB - stakedAmountB)
714- if ((amountB > 0))
715- then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
716- else 0
717- }
718- else 0
719- if ((stake2 == stake2))
720- then nil
721- else throw("Strict value is not equal to itself.")
722- }
723- else throw("Strict value is not equal to itself.")
724- }
645+func stakeAll () = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
646+ then throw("Only admin can call this function")
647+ else {
648+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
649+ then {
650+ let amountA = (balanceA - stakedAmountA)
651+ if ((amountA > 0))
652+ then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
653+ else 0
654+ }
655+ else 0
656+ if ((stake1 == stake1))
657+ then {
658+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
659+ then {
660+ let amountB = (balanceB - stakedAmountB)
661+ if ((amountB > 0))
662+ then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
663+ else 0
664+ }
665+ else 0
666+ if ((stake2 == stake2))
667+ then nil
668+ else throw("Strict value is not equal to itself.")
669+ }
670+ else throw("Strict value is not equal to itself.")
671+ })
725672
726673
727674 @Verifier(tx)
728675 func verify () = {
729676 let multiSignedByAdmins = {
730677 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
731678 then 1
732679 else 0
733680 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
734681 then 1
735682 else 0
736683 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
737684 then 1
738685 else 0
739686 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
740687 }
741688 match tx {
742689 case inv: InvokeScriptTransaction =>
743690 let callTakeIntoAccount = if ((inv.dApp == this))
744691 then (inv.function == "takeIntoAccountExtraFunds")
745692 else false
746693 let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
747694 then (inv.function == "exchange")
748695 else false)
749696 then (assetIdA == USDN)
750697 else false)
751698 then true
752699 else if (if ((assetIdB == USDN))
753700 then (size(inv.payments) == 1)
754701 else false)
755702 then (inv.payments[0].assetId == USDN)
756703 else false
757704 let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
758705 then (inv.function == "exchange")
759706 else false)
760707 then (assetIdA == NSBT)
761708 else false)
762709 then true
763710 else if (if ((assetIdB == NSBT))
764711 then (size(inv.payments) == 1)
765712 else false)
766713 then (inv.payments[0].assetId == USDN)
767714 else false
768715 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
769716 then true
770717 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
771718 then true
772719 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
773720 then true
774721 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
775722 if (if (if (if (callTakeIntoAccount)
776723 then true
777724 else exchangeToWaves)
778725 then true
779726 else exchangeToNSBTs)
780727 then signedByAdmin
781728 else false)
782729 then true
783730 else multiSignedByAdmins
784731 case _ =>
785732 multiSignedByAdmins
786733 }
787734 }
788735

github/deemru/w8io/873ac7e 
1134.55 ms