tx · 2LTK732vi8aB4QFRma3uRF58mittn2M4YRsLhk7Gpbok

3MusKJNN7kfh3cADeGFLr3EQbyuDgzKTRUB:  -0.01400000 Waves

2021.12.30 18:21 [1857147] smart account 3MusKJNN7kfh3cADeGFLr3EQbyuDgzKTRUB > SELF 0.00000000 Waves

{ "type": 13, "id": "2LTK732vi8aB4QFRma3uRF58mittn2M4YRsLhk7Gpbok", "fee": 1400000, "feeAssetId": null, "timestamp": 1640877737986, "version": 2, "chainId": 84, "sender": "3MusKJNN7kfh3cADeGFLr3EQbyuDgzKTRUB", "senderPublicKey": "GMJWspY59AzYVuhb8nu637nUYeueKxE2Z6csvKL6uXf1", "proofs": [ "2s5PGUpfaQ9sBUkrWRV7tYAHEm7q6zHpuxhnuF4u6pqQrd6jFuuVkHLZmgSxWrebAnQiLjjo4GTLzbwKxJP6t8N5", "21GxUF8kHJqcZhBsQmHvcd7T6w2PB1duqS4Pok4ujifYv4dShf8PimfBP9V9M2oY8WgMU5kbVVqLm7MscK62w2nN" ], "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": 1857147, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 96AUmX6dirDjr8yry2uzqFjWkFbrtMM5vpwnMz9eUBQt Next: none Diff:
OldNewDifferences
4343
4444 let kFirstHarvestHeight = "first_harvest_height"
4545
46+let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
47+
48+let keyEURNAddress = "staking_eurn_address"
49+
50+let keyLeasingPool = "leasing_address"
51+
52+let keyLeasingAmount = "leasing_amount"
53+
54+let keyLeasingId = "leasing_id"
55+
4656 let keyAdminPubKey1 = "admin_pub_1"
4757
4858 let keyAdminPubKey2 = "admin_pub_2"
7383
7484 let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
7585
76-let stakingAddress = Address(base58'3MyVqAbmKWh339gF6hy8faWw1jGeTV2wnGE')
86+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
7787
78-let EURNToWavesExchanger = Address(base58'3MqsiNaG42muSdN4QxfMQqiwCWccvH368W2')
88+let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
89+
90+let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
91+
92+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
93+
94+let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(NSBT), toBase58String(EURN)]
95+
96+let stakingUSDNNSBTAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyUSDNNSBTAddress), "no usdn staking address")))
97+
98+let stakingEURNAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyEURNAddress), "no usdn staking address")))
99+
100+let USDNToWavesExchanger = Address(base58'3N8PGkzXhbtTvEwEQTtE2xiTJmsDEQ9XfoZ')
101+
102+let USDNToNSBTExchanger = Address(base58'3MqW1t2cxdYy2emEMk3YtZkRwQPhHaTfWRe')
79103
80104 let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
81105
85109
86110 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
87111
88-let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
89-
90-let stakingFeeInEURN = 234000
91-
92-let isActive = getBooleanValue(this, keyActive)
112+let active = getBooleanValue(this, keyActive)
93113
94114 let strAssetIdA = getStringValue(this, keyAssetIdA)
95115
153173 }
154174
155175
156-let stakedAmountEURN = match getInteger(stakingAddress, ((("%s%s%s__stakingBalance__" + toBase58String(EURN)) + "__") + toString(this))) {
157- case staked: Int =>
158- staked
159- case nothing: Unit =>
160- 0
161- case _ =>
162- throw("Match error")
163-}
176+func stakedAmount (assetId) = {
177+ let stakedAmountCalculated = match assetId {
178+ case aId: ByteVector =>
179+ if (if ((aId == USDN))
180+ then true
181+ else (aId == NSBT))
182+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
183+ else if ((aId == EURN))
184+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
185+ else 0
186+ case _: Unit =>
187+ valueOrElse(getInteger(this, keyLeasingAmount), 0)
188+ case _ =>
189+ throw("Match error")
190+ }
191+ match stakedAmountCalculated {
192+ case i: Int =>
193+ i
194+ case _ =>
195+ 0
196+ }
197+ }
198+
199+
200+let stakedAmountA = stakedAmount(assetIdA)
201+
202+let stakedAmountB = stakedAmount(assetIdB)
164203
165204 let assetInitA = getIntegerValue(this, keyBalanceInitA)
166205
167206 let assetInitB = getIntegerValue(this, keyBalanceInitB)
168207
169-let availableBalanceA = (balanceA - (if ((assetIdA == EURN))
170- then stakedAmountEURN
171- else 0))
208+let availableBalanceA = (balanceA - stakedAmountA)
172209
173-let availableBalanceB = (balanceB - (if ((assetIdB == EURN))
174- then stakedAmountEURN
175- else 0))
210+let availableBalanceB = (balanceB - stakedAmountB)
176211
177-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == EURN))
178- then stakedAmountEURN
179- else 0))
212+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
180213
181-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == EURN))
182- then stakedAmountEURN
183- else 0))
214+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
184215
185216 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
186217 then (accountBalanceWithStakedB >= balanceB)
211242 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
212243
213244
214-func deductStakingFee (amount,assetId) = if ((assetId == EURN))
215- then {
216- let result = (amount - stakingFeeInEURN)
217- if ((0 >= result))
218- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInEURN)) + " USD-N"))
219- else result
220- }
221- else amount
245+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
246+ then if ((assetId == USDN))
247+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
248+ else if ((assetId == NSBT))
249+ then $Tuple2("lockNsbt", stakingUSDNNSBTAddress)
250+ else $Tuple2("startStaking", stakingEURNAddress)
251+ else if ((assetId == USDN))
252+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
253+ else if ((assetId == NSBT))
254+ then $Tuple2("unlockNsbt", stakingUSDNNSBTAddress)
255+ else $Tuple2("stopStaking", stakingEURNAddress)
222256
223257
224-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"))
258+func calcStakingParams (stake,amount,assetId) = if (stake)
259+ then {
260+ let $t069216987 = calcStakingFuncAndAddres(stake, assetId)
261+ let call = $t069216987._1
262+ let stakingAddr = $t069216987._2
263+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
264+ }
265+ else {
266+ let $t070737139 = calcStakingFuncAndAddres(stake, assetId)
267+ let call = $t070737139._1
268+ let stakingAddr = $t070737139._2
269+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
270+ }
225271
226272
227-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+ }
228281
229282
230283 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
231284
232285
286+func isActive () = if (active)
287+ then unit
288+ else throw("DApp is inactive at this moment")
289+
290+
233291 @Callable(i)
234292 func init (firstHarvest) = {
235- let $t067146791 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
236- let pmtAmountA = $t067146791._1
237- let pmtAssetIdA = $t067146791._2
238- let $t067966873 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
239- let pmtAmountB = $t067966873._1
240- let pmtAssetIdB = $t067966873._2
241- let $t068786955 = getAssetInfo(pmtAssetIdA)
242- let pmtStrAssetIdA = $t068786955._1
243- let pmtAssetNameA = $t068786955._2
244- let pmtDecimalsA = $t068786955._3
245- let $t069607037 = getAssetInfo(pmtAssetIdB)
246- let pmtStrAssetIdB = $t069607037._1
247- let pmtAssetNameB = $t069607037._2
248- let pmtDecimalsB = $t069607037._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
249307 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
250308 then throw("Only admin can call this function")
251309 else if (isDefined(getBoolean(this, keyActive)))
256314 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
257315 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
258316 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
259- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
317+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
318+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
319+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
320+ let shareInitialSupply = fraction(arg1, arg2, arg3)
260321 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
261322 let shareIssueId = calculateAssetId(shareIssue)
262- 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)]
263- if (firstHarvest)
264- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
265- else baseEntry
323+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
324+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
325+ else 0
326+ if ((stake1 == stake1))
327+ then {
328+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
329+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
330+ else 0
331+ if ((stake2 == stake2))
332+ then {
333+ 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)]
334+ if (firstHarvest)
335+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
336+ else baseEntry
337+ }
338+ else throw("Strict value is not equal to itself.")
339+ }
340+ else throw("Strict value is not equal to itself.")
266341 }
267342 }
268343
270345
271346 @Callable(i)
272347 func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
273- let $t092339320 = getAssetInfoFromString(strAssetIdA)
274- let pmtStrAssetIdA = $t092339320._1
275- let pmtAssetNameA = $t092339320._2
276- let pmtDecimalsA = $t092339320._3
277- let $t093259412 = getAssetInfoFromString(strAssetIdB)
278- let pmtStrAssetIdB = $t093259412._1
279- let pmtAssetNameB = $t093259412._2
280- let pmtDecimalsB = $t093259412._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
281356 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
282357 then throw("Only admin can call this function")
283358 else if (isDefined(getBoolean(this, keyActive)))
301376
302377
303378 @Callable(i)
304-func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
305- then throw("DApp is inactive at this moment")
306- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
307- then throw("Only admin can call this function")
308- 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)])
309382
310383
311384
312385 @Callable(i)
313-func replenishWithTwoTokens (slippageTolerance) = {
386+func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
314387 let pmtAssetIdA = i.payments[0].assetId
315388 let pmtAssetIdB = i.payments[1].assetId
316- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
317- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
318- if (if ((balanceA == 0))
389+ let pmtAmountA = i.payments[0].amount
390+ let pmtAmountB = i.payments[1].amount
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))
319400 then (balanceB == 0)
320401 else false)
321- then {
322- let $t01209712174 = getAssetInfo(pmtAssetIdA)
323- let pmtStrAssetIdA = $t01209712174._1
324- let pmtAssetNameA = $t01209712174._2
325- let pmtDecimalsA = $t01209712174._3
326- let $t01218312260 = getAssetInfo(pmtAssetIdB)
327- let pmtStrAssetIdB = $t01218312260._1
328- let pmtAssetNameB = $t01218312260._2
329- let pmtDecimalsB = $t01218312260._3
330- let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
331- if ((pmtAssetIdA == pmtAssetIdB))
332- then throw("Assets must be different")
333- else {
334- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
336- if (!(isActive))
337- then throw("DApp is inactive at this moment")
338- else if (if ((0 > slippageTolerance))
339- then true
340- else (slippageTolerance > slippageToleranceDelimiter))
341- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
342- else if ((size(i.payments) != 2))
343- then throw("Two attached assets expected")
344- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
345- then true
346- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
347- then throw("Incorrect assets amount: amounts must have the contract ratio")
348- else if (if ((pmtAssetIdA != assetIdA))
349- then true
350- else (pmtAssetIdB != assetIdB))
351- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
352- else if ((shareInitialSupply == 0))
353- then throw("Too small amount to replenish")
354- else if (!(hasEnoughBalance))
355- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
356- else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
357- }
358- }
359- else {
360- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
361- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
362- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
363- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
364- if (!(isActive))
365- then throw("DApp is inactive at this moment")
366- 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))
367422 then true
368- else (slippageTolerance > slippageToleranceDelimiter))
369- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
370- else if ((size(i.payments) != 2))
371- then throw("Two attached assets expected")
372- else if (if ((pmtAssetIdA != assetIdA))
373- then true
374- else (pmtAssetIdB != assetIdB))
375- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
376- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
377- then true
378- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
379- then throw("Incorrect assets amount: amounts must have the contract ratio")
380- else if ((shareTokenToPayAmount == 0))
381- then throw("Too small amount to replenish")
382- else if (!(hasEnoughBalance))
383- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
384- else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
385- }
386- }
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+ })
387445
388446
389447
390448 @Callable(i)
391-func withdraw () = {
392- let $t01665916809 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
393- let pmtAmount = $t01665916809._1
394- let pmtAssetId = $t01665916809._2
395- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
396- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
397- if (!(isActive))
398- then throw("DApp is inactive at this moment")
399- else if ((size(i.payments) != 1))
400- then throw("One attached payment expected")
401- else if ((pmtAssetId != shareAssetId))
402- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
403- else if (!(hasEnoughBalance))
404- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
405- else if (if ((amountToPayA > availableBalanceA))
406- then true
407- else (amountToPayB > availableBalanceB))
408- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
409- else [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)]
410- }
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
453+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
454+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
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+ })
411477
412478
413479
414480 @Callable(i)
415-func exchange (minAmountToReceive) = {
416- let $t01801518090 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
417- let pmtAmount = $t01801518090._1
418- let pmtAssetId = $t01801518090._2
419- func calculateFees (tokenFrom,tokenTo) = {
420- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
421- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
422- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
423- if ((minAmountToReceive > amountWithFee))
424- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
425- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
426- }
427-
428- if (!(isActive))
429- then throw("DApp is inactive at this moment")
430- else if (if ((balanceA == 0))
431- then true
432- else (balanceB == 0))
433- then throw("Can't exchange with zero balance")
434- else if ((0 >= minAmountToReceive))
435- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
436- else if ((size(i.payments) != 1))
437- then throw("One attached payment expected")
438- else if (!(hasEnoughBalance))
439- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
440- else if ((pmtAssetId == assetIdA))
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")
493+ else if (!(hasEnoughBalance))
494+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
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)
504+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
505+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
506+ else 0
507+ if ((stake1 == stake1))
508+ then {
509+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
510+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
511+ else 0
512+ if ((stake2 == stake2))
513+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
514+ else throw("Strict value is not equal to itself.")
515+ }
516+ else throw("Strict value is not equal to itself.")
517+ }
518+ else if ((pmtAssetId == assetIdB))
441519 then {
442- let assetIdSend = assetIdB
443- let $t01936419455 = calculateFees(balanceA, balanceB)
444- let amountWithoutFee = $t01936419455._1
445- let amountWithFee = $t01936419455._2
446- let governanceReward = $t01936419455._3
447- let newBalanceA = (balanceA + pmtAmount)
448- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
449- if (if (if ((assetIdA == EURN))
450- then (stakedAmountEURN >= newBalanceA)
451- else false)
452- then true
453- else if ((assetIdB == EURN))
454- then (stakedAmountEURN >= newBalanceB)
455- else false)
456- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
457- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
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)
527+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
528+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
529+ else 0
530+ if ((stake1 == stake1))
531+ then {
532+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
533+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
534+ else 0
535+ if ((stake2 == stake2))
536+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
537+ else throw("Strict value is not equal to itself.")
538+ }
539+ else throw("Strict value is not equal to itself.")
458540 }
459- else if ((pmtAssetId == assetIdB))
460- then {
461- let assetIdSend = assetIdA
462- let $t02032420415 = calculateFees(balanceB, balanceA)
463- let amountWithoutFee = $t02032420415._1
464- let amountWithFee = $t02032420415._2
465- let governanceReward = $t02032420415._3
466- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
467- let newBalanceB = (balanceB + pmtAmount)
468- if (if (if ((assetIdA == EURN))
469- then (stakedAmountEURN >= newBalanceA)
470- else false)
471- then true
472- else if ((assetIdB == EURN))
473- then (stakedAmountEURN >= newBalanceB)
474- else false)
475- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
476- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
477- }
478- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
479- }
541+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
542+ })
480543
481544
482545
483546 @Callable(i)
484-func shutdown () = if (!(isActive))
547+func shutdown () = if (!(active))
485548 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
486549 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
487550 then throw("Only admin can call this function")
490553
491554
492555 @Callable(i)
493-func activate () = if (isActive)
556+func activate () = if (active)
494557 then throw("DApp is already active")
495558 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
496559 then throw("Only admin can call this function")
499562
500563
501564 @Callable(i)
502-func takeIntoAccountExtraFunds (amountLeave) = {
565+func takeIntoAccountExtraFunds (amountLeave) = valueOrElse(isActive(), {
503566 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
504567 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
505568 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
508571 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
509572 then amountLeave
510573 else 0))
511- if (!(isActive))
512- then throw("DApp is inactive at this moment")
513- else if ((i.caller != this))
514- then throw("Only the DApp itself can call this function")
515- else if ((0 > amountLeave))
516- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
517- 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))
518583 then true
519- else (0 > uncountableAmountEnrollAssetB))
520- then suspend("Enroll amount negative")
521- else if (if ((0 > amountEnrollA))
522- then true
523- else (0 > amountEnrollB))
524- then throw("Too large amountLeave")
525- else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
526- }
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+ })
606+
607+
608+
609+@Callable(i)
610+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
611+ then throw("Only contract itself can invoke this function")
612+ else if ((assetIdString == "WAVES"))
613+ then {
614+ let pool = addressFromStringValue(valueOrErrorMessage(getString(oracle, keyLeasingPool), "No leasing pool in oracle"))
615+ let leasingId = getBinary(this, keyLeasingId)
616+ let leasingAmount = valueOrElse(getInteger(this, keyLeasingAmount), 0)
617+ let newLeaseAmount = if (stake)
618+ then (leasingAmount + amount)
619+ else (leasingAmount - amount)
620+ let newLease = Lease(pool, newLeaseAmount)
621+ let newLeaseId = calculateLeaseId(newLease)
622+ let baseEtry = [newLease, BinaryEntry(keyLeasingId, newLeaseId), IntegerEntry(keyLeasingAmount, newLeaseAmount)]
623+ match leasingId {
624+ case lId: ByteVector =>
625+ ([LeaseCancel(lId)] ++ baseEtry)
626+ case _ =>
627+ baseEtry
628+ }
629+ }
630+ else {
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
636+ let inv = invoke(addr, call, params, payments)
637+ if ((inv == inv))
638+ then nil
639+ else throw("Strict value is not equal to itself.")
640+ }
641+
642+
643+
644+@Callable(i)
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+ })
527672
528673
529674 @Verifier(tx)
530-func verify () = match tx {
531- case inv: InvokeScriptTransaction =>
532- let callTakeIntoAccount = if ((inv.dApp == this))
533- then (inv.function == "takeIntoAccountExtraFunds")
534- else false
535- let callStaking = if ((inv.dApp == stakingAddress))
536- then if (if (if ((inv.function == "startStaking"))
537- then (size(inv.payments) == 1)
538- else false)
539- then (inv.payments[0].assetId == EURN)
540- else false)
541- then true
542- else if ((inv.function == "stopStaking"))
543- then (size(inv.payments) == 0)
544- else false
545- else false
546- let exchangeToWaves = if (if (if ((inv.dApp == EURNToWavesExchanger))
547- then (inv.function == "exchange")
548- else false)
549- then (assetIdA == EURN)
550- else false)
551- then true
552- else if ((assetIdB == EURN))
553- then (inv.payments[0].assetId == EURN)
554- else false
555- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
556- then true
557- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
558- then true
559- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
560- then true
561- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
562- if (if (if (callTakeIntoAccount)
563- then true
564- else callStaking)
565- then true
566- else exchangeToWaves)
567- then signedByAdmin
568- else false
569- case _ =>
675+func verify () = {
676+ let multiSignedByAdmins = {
570677 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
571678 then 1
572679 else 0
577684 then 1
578685 else 0
579686 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
580-}
687+ }
688+ match tx {
689+ case inv: InvokeScriptTransaction =>
690+ let callTakeIntoAccount = if ((inv.dApp == this))
691+ then (inv.function == "takeIntoAccountExtraFunds")
692+ else false
693+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
694+ then (inv.function == "exchange")
695+ else false)
696+ then (assetIdA == USDN)
697+ else false)
698+ then true
699+ else if (if ((assetIdB == USDN))
700+ then (size(inv.payments) == 1)
701+ else false)
702+ then (inv.payments[0].assetId == USDN)
703+ else false
704+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
705+ then (inv.function == "exchange")
706+ else false)
707+ then (assetIdA == NSBT)
708+ else false)
709+ then true
710+ else if (if ((assetIdB == NSBT))
711+ then (size(inv.payments) == 1)
712+ else false)
713+ then (inv.payments[0].assetId == USDN)
714+ else false
715+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
716+ then true
717+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
718+ then true
719+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
720+ then true
721+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
722+ if (if (if (if (callTakeIntoAccount)
723+ then true
724+ else exchangeToWaves)
725+ then true
726+ else exchangeToNSBTs)
727+ then signedByAdmin
728+ else false)
729+ then true
730+ else multiSignedByAdmins
731+ case _ =>
732+ multiSignedByAdmins
733+ }
734+ }
581735
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"
4343
4444 let kFirstHarvestHeight = "first_harvest_height"
4545
46+let keyUSDNNSBTAddress = "staking_usdnnsbt_address"
47+
48+let keyEURNAddress = "staking_eurn_address"
49+
50+let keyLeasingPool = "leasing_address"
51+
52+let keyLeasingAmount = "leasing_amount"
53+
54+let keyLeasingId = "leasing_id"
55+
4656 let keyAdminPubKey1 = "admin_pub_1"
4757
4858 let keyAdminPubKey2 = "admin_pub_2"
4959
5060 let keyAdminPubKey3 = "admin_pub_3"
5161
5262 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
5363
5464 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
5565 case string: String =>
5666 fromBase58String(string)
5767 case nothing =>
5868 throw("Admin public key is empty")
5969 }
6070
6171
6272 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
6373
6474 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
6575
6676 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
6777
6878 let adminPubKeyStartStop = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
6979
7080 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
7181
7282 let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
7383
7484 let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
7585
76-let stakingAddress = Address(base58'3MyVqAbmKWh339gF6hy8faWw1jGeTV2wnGE')
86+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
7787
78-let EURNToWavesExchanger = Address(base58'3MqsiNaG42muSdN4QxfMQqiwCWccvH368W2')
88+let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
89+
90+let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
91+
92+let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
93+
94+let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(NSBT), toBase58String(EURN)]
95+
96+let stakingUSDNNSBTAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyUSDNNSBTAddress), "no usdn staking address")))
97+
98+let stakingEURNAddress = Address(fromBase58String(valueOrErrorMessage(getString(oracle, keyEURNAddress), "no usdn staking address")))
99+
100+let USDNToWavesExchanger = Address(base58'3N8PGkzXhbtTvEwEQTtE2xiTJmsDEQ9XfoZ')
101+
102+let USDNToNSBTExchanger = Address(base58'3MqW1t2cxdYy2emEMk3YtZkRwQPhHaTfWRe')
79103
80104 let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
81105
82106 let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
83107
84108 let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
85109
86110 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
87111
88-let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
89-
90-let stakingFeeInEURN = 234000
91-
92-let isActive = getBooleanValue(this, keyActive)
112+let active = getBooleanValue(this, keyActive)
93113
94114 let strAssetIdA = getStringValue(this, keyAssetIdA)
95115
96116 let strAssetIdB = getStringValue(this, keyAssetIdB)
97117
98118 let assetIdA = if ((strAssetIdA == "WAVES"))
99119 then unit
100120 else fromBase58String(strAssetIdA)
101121
102122 let assetIdB = if ((strAssetIdB == "WAVES"))
103123 then unit
104124 else fromBase58String(strAssetIdB)
105125
106126 let assetNameA = match assetIdA {
107127 case id: ByteVector =>
108128 value(assetInfo(id)).name
109129 case waves: Unit =>
110130 "WAVES"
111131 case _ =>
112132 throw("Match error")
113133 }
114134
115135 let assetNameB = match assetIdB {
116136 case id: ByteVector =>
117137 value(assetInfo(id)).name
118138 case waves: Unit =>
119139 "WAVES"
120140 case _ =>
121141 throw("Match error")
122142 }
123143
124144 let balanceA = getIntegerValue(this, keyBalanceA)
125145
126146 let balanceB = getIntegerValue(this, keyBalanceB)
127147
128148 let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId))
129149
130150 let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply)
131151
132152 let commission = 3000
133153
134154 let commissionGovernance = 1200
135155
136156 let commissionScaleDelimiter = 1000000
137157
138158 let scaleValue3 = 1000
139159
140160 let scaleValue8 = 100000000
141161
142162 let slippageToleranceDelimiter = 1000
143163
144164 let scaleValue8Digits = 8
145165
146166 func accountBalance (assetId) = match assetId {
147167 case id: ByteVector =>
148168 assetBalance(this, id)
149169 case waves: Unit =>
150170 wavesBalance(this).available
151171 case _ =>
152172 throw("Match error")
153173 }
154174
155175
156-let stakedAmountEURN = match getInteger(stakingAddress, ((("%s%s%s__stakingBalance__" + toBase58String(EURN)) + "__") + toString(this))) {
157- case staked: Int =>
158- staked
159- case nothing: Unit =>
160- 0
161- case _ =>
162- throw("Match error")
163-}
176+func stakedAmount (assetId) = {
177+ let stakedAmountCalculated = match assetId {
178+ case aId: ByteVector =>
179+ if (if ((aId == USDN))
180+ then true
181+ else (aId == NSBT))
182+ then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
183+ else if ((aId == EURN))
184+ then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
185+ else 0
186+ case _: Unit =>
187+ valueOrElse(getInteger(this, keyLeasingAmount), 0)
188+ case _ =>
189+ throw("Match error")
190+ }
191+ match stakedAmountCalculated {
192+ case i: Int =>
193+ i
194+ case _ =>
195+ 0
196+ }
197+ }
198+
199+
200+let stakedAmountA = stakedAmount(assetIdA)
201+
202+let stakedAmountB = stakedAmount(assetIdB)
164203
165204 let assetInitA = getIntegerValue(this, keyBalanceInitA)
166205
167206 let assetInitB = getIntegerValue(this, keyBalanceInitB)
168207
169-let availableBalanceA = (balanceA - (if ((assetIdA == EURN))
170- then stakedAmountEURN
171- else 0))
208+let availableBalanceA = (balanceA - stakedAmountA)
172209
173-let availableBalanceB = (balanceB - (if ((assetIdB == EURN))
174- then stakedAmountEURN
175- else 0))
210+let availableBalanceB = (balanceB - stakedAmountB)
176211
177-let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == EURN))
178- then stakedAmountEURN
179- else 0))
212+let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
180213
181-let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == EURN))
182- then stakedAmountEURN
183- else 0))
214+let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
184215
185216 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
186217 then (accountBalanceWithStakedB >= balanceB)
187218 else false
188219
189220 func getAssetInfo (assetId) = match assetId {
190221 case id: ByteVector =>
191222 let stringId = toBase58String(id)
192223 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
193224 $Tuple3(stringId, info.name, info.decimals)
194225 case waves: Unit =>
195226 $Tuple3("WAVES", "WAVES", 8)
196227 case _ =>
197228 throw("Match error")
198229 }
199230
200231
201232 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
202233 then $Tuple3("WAVES", "WAVES", 8)
203234 else {
204235 let stringId = assetStr
205236 let id = fromBase58String(assetStr)
206237 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
207238 $Tuple3(stringId, info.name, info.decimals)
208239 }
209240
210241
211242 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
212243
213244
214-func deductStakingFee (amount,assetId) = if ((assetId == EURN))
215- then {
216- let result = (amount - stakingFeeInEURN)
217- if ((0 >= result))
218- then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakingFeeInEURN)) + " USD-N"))
219- else result
220- }
221- else amount
245+func calcStakingFuncAndAddres (stake,assetId) = if (stake)
246+ then if ((assetId == USDN))
247+ then $Tuple2("lockNeutrino", stakingUSDNNSBTAddress)
248+ else if ((assetId == NSBT))
249+ then $Tuple2("lockNsbt", stakingUSDNNSBTAddress)
250+ else $Tuple2("startStaking", stakingEURNAddress)
251+ else if ((assetId == USDN))
252+ then $Tuple2("unlockNeutrino", stakingUSDNNSBTAddress)
253+ else if ((assetId == NSBT))
254+ then $Tuple2("unlockNsbt", stakingUSDNNSBTAddress)
255+ else $Tuple2("stopStaking", stakingEURNAddress)
222256
223257
224-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"))
258+func calcStakingParams (stake,amount,assetId) = if (stake)
259+ then {
260+ let $t069216987 = calcStakingFuncAndAddres(stake, assetId)
261+ let call = $t069216987._1
262+ let stakingAddr = $t069216987._2
263+ $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
264+ }
265+ else {
266+ let $t070737139 = calcStakingFuncAndAddres(stake, assetId)
267+ let call = $t070737139._1
268+ let stakingAddr = $t070737139._2
269+ $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
270+ }
225271
226272
227-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+ }
228281
229282
230283 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
231284
232285
286+func isActive () = if (active)
287+ then unit
288+ else throw("DApp is inactive at this moment")
289+
290+
233291 @Callable(i)
234292 func init (firstHarvest) = {
235- let $t067146791 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
236- let pmtAmountA = $t067146791._1
237- let pmtAssetIdA = $t067146791._2
238- let $t067966873 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
239- let pmtAmountB = $t067966873._1
240- let pmtAssetIdB = $t067966873._2
241- let $t068786955 = getAssetInfo(pmtAssetIdA)
242- let pmtStrAssetIdA = $t068786955._1
243- let pmtAssetNameA = $t068786955._2
244- let pmtDecimalsA = $t068786955._3
245- let $t069607037 = getAssetInfo(pmtAssetIdB)
246- let pmtStrAssetIdB = $t069607037._1
247- let pmtAssetNameB = $t069607037._2
248- let pmtDecimalsB = $t069607037._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
249307 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
250308 then throw("Only admin can call this function")
251309 else if (isDefined(getBoolean(this, keyActive)))
252310 then throw("DApp is already active")
253311 else if ((pmtAssetIdA == pmtAssetIdB))
254312 then throw("Assets must be different")
255313 else {
256314 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
257315 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
258316 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
259- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
317+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
318+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
319+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
320+ let shareInitialSupply = fraction(arg1, arg2, arg3)
260321 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
261322 let shareIssueId = calculateAssetId(shareIssue)
262- 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)]
263- if (firstHarvest)
264- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
265- else baseEntry
323+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
324+ then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
325+ else 0
326+ if ((stake1 == stake1))
327+ then {
328+ let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
329+ then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
330+ else 0
331+ if ((stake2 == stake2))
332+ then {
333+ 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)]
334+ if (firstHarvest)
335+ then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
336+ else baseEntry
337+ }
338+ else throw("Strict value is not equal to itself.")
339+ }
340+ else throw("Strict value is not equal to itself.")
266341 }
267342 }
268343
269344
270345
271346 @Callable(i)
272347 func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
273- let $t092339320 = getAssetInfoFromString(strAssetIdA)
274- let pmtStrAssetIdA = $t092339320._1
275- let pmtAssetNameA = $t092339320._2
276- let pmtDecimalsA = $t092339320._3
277- let $t093259412 = getAssetInfoFromString(strAssetIdB)
278- let pmtStrAssetIdB = $t093259412._1
279- let pmtAssetNameB = $t093259412._2
280- let pmtDecimalsB = $t093259412._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
281356 if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
282357 then throw("Only admin can call this function")
283358 else if (isDefined(getBoolean(this, keyActive)))
284359 then throw("DApp is already active")
285360 else if ((strAssetIdA == strAssetIdB))
286361 then throw("Assets must be different")
287362 else {
288363 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
289364 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
290365 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
291366 let shareInitialSupply = 0
292367 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
293368 let shareIssueId = calculateAssetId(shareIssue)
294369 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)]
295370 if (firstHarvest)
296371 then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
297372 else baseEntry
298373 }
299374 }
300375
301376
302377
303378 @Callable(i)
304-func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
305- then throw("DApp is inactive at this moment")
306- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
307- then throw("Only admin can call this function")
308- 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)])
309382
310383
311384
312385 @Callable(i)
313-func replenishWithTwoTokens (slippageTolerance) = {
386+func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
314387 let pmtAssetIdA = i.payments[0].assetId
315388 let pmtAssetIdB = i.payments[1].assetId
316- let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
317- let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
318- if (if ((balanceA == 0))
389+ let pmtAmountA = i.payments[0].amount
390+ let pmtAmountB = i.payments[1].amount
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))
319400 then (balanceB == 0)
320401 else false)
321- then {
322- let $t01209712174 = getAssetInfo(pmtAssetIdA)
323- let pmtStrAssetIdA = $t01209712174._1
324- let pmtAssetNameA = $t01209712174._2
325- let pmtDecimalsA = $t01209712174._3
326- let $t01218312260 = getAssetInfo(pmtAssetIdB)
327- let pmtStrAssetIdB = $t01218312260._1
328- let pmtAssetNameB = $t01218312260._2
329- let pmtDecimalsB = $t01218312260._3
330- let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
331- if ((pmtAssetIdA == pmtAssetIdB))
332- then throw("Assets must be different")
333- else {
334- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335- let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
336- if (!(isActive))
337- then throw("DApp is inactive at this moment")
338- else if (if ((0 > slippageTolerance))
339- then true
340- else (slippageTolerance > slippageToleranceDelimiter))
341- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
342- else if ((size(i.payments) != 2))
343- then throw("Two attached assets expected")
344- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
345- then true
346- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
347- then throw("Incorrect assets amount: amounts must have the contract ratio")
348- else if (if ((pmtAssetIdA != assetIdA))
349- then true
350- else (pmtAssetIdB != assetIdB))
351- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
352- else if ((shareInitialSupply == 0))
353- then throw("Too small amount to replenish")
354- else if (!(hasEnoughBalance))
355- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
356- else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
357- }
358- }
359- else {
360- let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
361- let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
362- let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
363- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
364- if (!(isActive))
365- then throw("DApp is inactive at this moment")
366- 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))
367422 then true
368- else (slippageTolerance > slippageToleranceDelimiter))
369- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
370- else if ((size(i.payments) != 2))
371- then throw("Two attached assets expected")
372- else if (if ((pmtAssetIdA != assetIdA))
373- then true
374- else (pmtAssetIdB != assetIdB))
375- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
376- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
377- then true
378- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
379- then throw("Incorrect assets amount: amounts must have the contract ratio")
380- else if ((shareTokenToPayAmount == 0))
381- then throw("Too small amount to replenish")
382- else if (!(hasEnoughBalance))
383- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
384- else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
385- }
386- }
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+ })
387445
388446
389447
390448 @Callable(i)
391-func withdraw () = {
392- let $t01665916809 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
393- let pmtAmount = $t01665916809._1
394- let pmtAssetId = $t01665916809._2
395- let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
396- let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
397- if (!(isActive))
398- then throw("DApp is inactive at this moment")
399- else if ((size(i.payments) != 1))
400- then throw("One attached payment expected")
401- else if ((pmtAssetId != shareAssetId))
402- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
403- else if (!(hasEnoughBalance))
404- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
405- else if (if ((amountToPayA > availableBalanceA))
406- then true
407- else (amountToPayB > availableBalanceB))
408- then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
409- else [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)]
410- }
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
453+ let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
454+ let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
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+ })
411477
412478
413479
414480 @Callable(i)
415-func exchange (minAmountToReceive) = {
416- let $t01801518090 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
417- let pmtAmount = $t01801518090._1
418- let pmtAssetId = $t01801518090._2
419- func calculateFees (tokenFrom,tokenTo) = {
420- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
421- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
422- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
423- if ((minAmountToReceive > amountWithFee))
424- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
425- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
426- }
427-
428- if (!(isActive))
429- then throw("DApp is inactive at this moment")
430- else if (if ((balanceA == 0))
431- then true
432- else (balanceB == 0))
433- then throw("Can't exchange with zero balance")
434- else if ((0 >= minAmountToReceive))
435- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
436- else if ((size(i.payments) != 1))
437- then throw("One attached payment expected")
438- else if (!(hasEnoughBalance))
439- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
440- else if ((pmtAssetId == assetIdA))
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")
493+ else if (!(hasEnoughBalance))
494+ then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
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)
504+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
505+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
506+ else 0
507+ if ((stake1 == stake1))
508+ then {
509+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
510+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
511+ else 0
512+ if ((stake2 == stake2))
513+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
514+ else throw("Strict value is not equal to itself.")
515+ }
516+ else throw("Strict value is not equal to itself.")
517+ }
518+ else if ((pmtAssetId == assetIdB))
441519 then {
442- let assetIdSend = assetIdB
443- let $t01936419455 = calculateFees(balanceA, balanceB)
444- let amountWithoutFee = $t01936419455._1
445- let amountWithFee = $t01936419455._2
446- let governanceReward = $t01936419455._3
447- let newBalanceA = (balanceA + pmtAmount)
448- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
449- if (if (if ((assetIdA == EURN))
450- then (stakedAmountEURN >= newBalanceA)
451- else false)
452- then true
453- else if ((assetIdB == EURN))
454- then (stakedAmountEURN >= newBalanceB)
455- else false)
456- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
457- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
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)
527+ let stake1 = if (containsElement(stakingAssets, strAssetIdA))
528+ then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
529+ else 0
530+ if ((stake1 == stake1))
531+ then {
532+ let stake2 = if (containsElement(stakingAssets, strAssetIdB))
533+ then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
534+ else 0
535+ if ((stake2 == stake2))
536+ then [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
537+ else throw("Strict value is not equal to itself.")
538+ }
539+ else throw("Strict value is not equal to itself.")
458540 }
459- else if ((pmtAssetId == assetIdB))
460- then {
461- let assetIdSend = assetIdA
462- let $t02032420415 = calculateFees(balanceB, balanceA)
463- let amountWithoutFee = $t02032420415._1
464- let amountWithFee = $t02032420415._2
465- let governanceReward = $t02032420415._3
466- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
467- let newBalanceB = (balanceB + pmtAmount)
468- if (if (if ((assetIdA == EURN))
469- then (stakedAmountEURN >= newBalanceA)
470- else false)
471- then true
472- else if ((assetIdB == EURN))
473- then (stakedAmountEURN >= newBalanceB)
474- else false)
475- then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
476- else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
477- }
478- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
479- }
541+ else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
542+ })
480543
481544
482545
483546 @Callable(i)
484-func shutdown () = if (!(isActive))
547+func shutdown () = if (!(active))
485548 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
486549 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
487550 then throw("Only admin can call this function")
488551 else suspend("Paused by admin")
489552
490553
491554
492555 @Callable(i)
493-func activate () = if (isActive)
556+func activate () = if (active)
494557 then throw("DApp is already active")
495558 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
496559 then throw("Only admin can call this function")
497560 else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
498561
499562
500563
501564 @Callable(i)
502-func takeIntoAccountExtraFunds (amountLeave) = {
565+func takeIntoAccountExtraFunds (amountLeave) = valueOrElse(isActive(), {
503566 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
504567 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
505568 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
506569 then amountLeave
507570 else 0))
508571 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
509572 then amountLeave
510573 else 0))
511- if (!(isActive))
512- then throw("DApp is inactive at this moment")
513- else if ((i.caller != this))
514- then throw("Only the DApp itself can call this function")
515- else if ((0 > amountLeave))
516- then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
517- 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))
518583 then true
519- else (0 > uncountableAmountEnrollAssetB))
520- then suspend("Enroll amount negative")
521- else if (if ((0 > amountEnrollA))
522- then true
523- else (0 > amountEnrollB))
524- then throw("Too large amountLeave")
525- else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
526- }
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+ })
606+
607+
608+
609+@Callable(i)
610+func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
611+ then throw("Only contract itself can invoke this function")
612+ else if ((assetIdString == "WAVES"))
613+ then {
614+ let pool = addressFromStringValue(valueOrErrorMessage(getString(oracle, keyLeasingPool), "No leasing pool in oracle"))
615+ let leasingId = getBinary(this, keyLeasingId)
616+ let leasingAmount = valueOrElse(getInteger(this, keyLeasingAmount), 0)
617+ let newLeaseAmount = if (stake)
618+ then (leasingAmount + amount)
619+ else (leasingAmount - amount)
620+ let newLease = Lease(pool, newLeaseAmount)
621+ let newLeaseId = calculateLeaseId(newLease)
622+ let baseEtry = [newLease, BinaryEntry(keyLeasingId, newLeaseId), IntegerEntry(keyLeasingAmount, newLeaseAmount)]
623+ match leasingId {
624+ case lId: ByteVector =>
625+ ([LeaseCancel(lId)] ++ baseEtry)
626+ case _ =>
627+ baseEtry
628+ }
629+ }
630+ else {
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
636+ let inv = invoke(addr, call, params, payments)
637+ if ((inv == inv))
638+ then nil
639+ else throw("Strict value is not equal to itself.")
640+ }
641+
642+
643+
644+@Callable(i)
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+ })
527672
528673
529674 @Verifier(tx)
530-func verify () = match tx {
531- case inv: InvokeScriptTransaction =>
532- let callTakeIntoAccount = if ((inv.dApp == this))
533- then (inv.function == "takeIntoAccountExtraFunds")
534- else false
535- let callStaking = if ((inv.dApp == stakingAddress))
536- then if (if (if ((inv.function == "startStaking"))
537- then (size(inv.payments) == 1)
538- else false)
539- then (inv.payments[0].assetId == EURN)
540- else false)
541- then true
542- else if ((inv.function == "stopStaking"))
543- then (size(inv.payments) == 0)
544- else false
545- else false
546- let exchangeToWaves = if (if (if ((inv.dApp == EURNToWavesExchanger))
547- then (inv.function == "exchange")
548- else false)
549- then (assetIdA == EURN)
550- else false)
551- then true
552- else if ((assetIdB == EURN))
553- then (inv.payments[0].assetId == EURN)
554- else false
555- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
556- then true
557- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
558- then true
559- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
560- then true
561- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
562- if (if (if (callTakeIntoAccount)
563- then true
564- else callStaking)
565- then true
566- else exchangeToWaves)
567- then signedByAdmin
568- else false
569- case _ =>
675+func verify () = {
676+ let multiSignedByAdmins = {
570677 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
571678 then 1
572679 else 0
573680 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
574681 then 1
575682 else 0
576683 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
577684 then 1
578685 else 0
579686 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
580-}
687+ }
688+ match tx {
689+ case inv: InvokeScriptTransaction =>
690+ let callTakeIntoAccount = if ((inv.dApp == this))
691+ then (inv.function == "takeIntoAccountExtraFunds")
692+ else false
693+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
694+ then (inv.function == "exchange")
695+ else false)
696+ then (assetIdA == USDN)
697+ else false)
698+ then true
699+ else if (if ((assetIdB == USDN))
700+ then (size(inv.payments) == 1)
701+ else false)
702+ then (inv.payments[0].assetId == USDN)
703+ else false
704+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
705+ then (inv.function == "exchange")
706+ else false)
707+ then (assetIdA == NSBT)
708+ else false)
709+ then true
710+ else if (if ((assetIdB == NSBT))
711+ then (size(inv.payments) == 1)
712+ else false)
713+ then (inv.payments[0].assetId == USDN)
714+ else false
715+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
716+ then true
717+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
718+ then true
719+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
720+ then true
721+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
722+ if (if (if (if (callTakeIntoAccount)
723+ then true
724+ else exchangeToWaves)
725+ then true
726+ else exchangeToNSBTs)
727+ then signedByAdmin
728+ else false)
729+ then true
730+ else multiSignedByAdmins
731+ case _ =>
732+ multiSignedByAdmins
733+ }
734+ }
581735

github/deemru/w8io/169f3d6 
88.07 ms