tx · CuGGqapPFeU7UsoYotR6KXQysujmV3EH6vJFmRahzd6E

3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1:  -0.01400000 Waves

2020.11.25 19:15 [2344881] smart account 3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1 > SELF 0.00000000 Waves

{ "type": 13, "id": "CuGGqapPFeU7UsoYotR6KXQysujmV3EH6vJFmRahzd6E", "fee": 1400000, "feeAssetId": null, "timestamp": 1606319863818, "version": 2, "chainId": 87, "sender": "3PPH7x7iqobW5ziyiRCic19rQqKr6nPYaK1", "senderPublicKey": "5aTg4oxM77iRmUGy3y8Zavn5fhVbgtUciAuSGfCJAYjn", "proofs": [ "", "2SPjvZi7SBaozH6bH6FQqnChzhejshctWknhjy4Lg8xW7y3wRXHS1U7CWySDtfoFXNgsXnHrMMLE3WfAuhShRoPu", "53rTi7LoRBttkAKo2sQd6t2LAUDz9htxBWLfAX51wCVbRopEoDfQr1UUcF8V4x254bBR7QCW1NsQwsNHAMuf3bsy" ], "script": "base64:AAIEAAAAAAAAACAIAhIAEgMKAQESBAoCAQESABIECgIBARIAEgASAwoBAQAAAEoAAAAAB3ZlcnNpb24CAAAABTIuMC4wAAAAAAprZXlWZXJzaW9uAgAAAAd2ZXJzaW9uAAAAAAlrZXlBY3RpdmUCAAAABmFjdGl2ZQAAAAALa2V5QXNzZXRJZEECAAAACkFfYXNzZXRfaWQAAAAAC2tleUFzc2V0SWRCAgAAAApCX2Fzc2V0X2lkAAAAAAtrZXlCYWxhbmNlQQIAAAAPQV9hc3NldF9iYWxhbmNlAAAAAAtrZXlCYWxhbmNlQgIAAAAPQl9hc3NldF9iYWxhbmNlAAAAAA9rZXlTaGFyZUFzc2V0SWQCAAAADnNoYXJlX2Fzc2V0X2lkAAAAABNrZXlTaGFyZUFzc2V0U3VwcGx5AgAAABJzaGFyZV9hc3NldF9zdXBwbHkAAAAADWtleUNvbW1pc3Npb24CAAAACmNvbW1pc3Npb24AAAAAFGtleWZlZVNjYWxlRGVsaW1pdGVyAgAAABpjb21taXNzaW9uX3NjYWxlX2RlbGltaXRlcgAAAAAXa2V5Q29tbWlzc2lvbkdvdmVybmFuY2UCAAAAFWNvbW1pc3Npb25fZ292ZXJuYW5jZQAAAAAMa2V5SW52YXJpYW50AgAAAAlpbnZhcmlhbnQAAAAACGtleUNhdXNlAgAAAA5zaHV0ZG93bl9jYXVzZQAAAAAMYWRtaW5QdWJLZXkxAQAAACC6Cdc7iVmk0V2g//G7M9Cq4TlpD8vivZHWO+5PXqjgEwAAAAAMYWRtaW5QdWJLZXkyAQAAACDCkUSZs9KwtA0ipZFYvYi8oTe7CMv/3YzmlO9bFg5+QAAAAAAMYWRtaW5QdWJLZXkzAQAAACCOHhcueLEHO/RITnozKGB2KHf8meWSMKMgws+oq+kOVQAAAAAUYWRtaW5QdWJLZXlTdGFydFN0b3ABAAAAIM5ZDtzqs16jrhv9V17n63kRNSl0RjKbPBVfPAUbKGF7AAAAABJhZG1pblB1YktleVN0YWtpbmcBAAAAILI9nx2GN5pXheYjUfThN3sjj2pYAd0+6A1owI50e1goAAAAABFnb3Zlcm5hbmNlQWRkcmVzcwkBAAAAB0FkZHJlc3MAAAABAQAAABoBVy/kXyChDk0K0DSxrx6s2TL7zcR9Ux8M8QAAAAAOc3Rha2luZ0FkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVfkDqc2T5IL15fPpB0/NRvPQ2rrqjzzcZ0AAAAABFVTRE4BAAAAILYmKcME9c5TkaQOS3UkL2SMUbH6369UKb1I0h0qsqrRAAAAABBzdGFraW5nRmVlSW5VU0ROCQAAaAAAAAIAAAAAAAAAAAkJAQAAAAV2YWx1ZQAAAAEICQEAAAAFdmFsdWUAAAABCQAD7AAAAAEFAAAABFVTRE4AAAAPbWluU3BvbnNvcmVkRmVlAAAAAAhpc0FjdGl2ZQkBAAAAEUBleHRyTmF0aXZlKDEwNTEpAAAAAgUAAAAEdGhpcwUAAAAJa2V5QWN0aXZlAAAAAAtzdHJBc3NldElkQQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAEdGhpcwUAAAALa2V5QXNzZXRJZEEAAAAAC3N0ckFzc2V0SWRCCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAAtrZXlBc3NldElkQgAAAAAIYXNzZXRJZEEDCQAAAAAAAAIFAAAAC3N0ckFzc2V0SWRBAgAAAAVXQVZFUwUAAAAEdW5pdAkAAlkAAAABBQAAAAtzdHJBc3NldElkQQAAAAAIYXNzZXRJZEIDCQAAAAAAAAIFAAAAC3N0ckFzc2V0SWRCAgAAAAVXQVZFUwUAAAAEdW5pdAkAAlkAAAABBQAAAAtzdHJBc3NldElkQgAAAAAKYXNzZXROYW1lQQQAAAAHJG1hdGNoMAUAAAAIYXNzZXRJZEEDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAmlkBQAAAAckbWF0Y2gwCAkBAAAABXZhbHVlAAAAAQkAA+wAAAABBQAAAAJpZAAAAARuYW1lAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0BAAAAAV3YXZlcwUAAAAHJG1hdGNoMAIAAAAFV0FWRVMJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IAAAAACmFzc2V0TmFtZUIEAAAAByRtYXRjaDAFAAAACGFzc2V0SWRCAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJpZAUAAAAHJG1hdGNoMAgJAQAAAAV2YWx1ZQAAAAEJAAPsAAAAAQUAAAACaWQAAAAEbmFtZQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAQAAAAFd2F2ZXMFAAAAByRtYXRjaDACAAAABVdBVkVTCQAAAgAAAAECAAAAC01hdGNoIGVycm9yAAAAAAhiYWxhbmNlQQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAALa2V5QmFsYW5jZUEAAAAACGJhbGFuY2VCCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAAtrZXlCYWxhbmNlQgAAAAAMc2hhcmVBc3NldElkCQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAD2tleVNoYXJlQXNzZXRJZAAAAAAQc2hhcmVBc3NldFN1cHBseQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAATa2V5U2hhcmVBc3NldFN1cHBseQAAAAAJaW52YXJpYW50CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAAxrZXlJbnZhcmlhbnQAAAAACmNvbW1pc3Npb24AAAAAAAAAAfQAAAAAFGNvbW1pc3Npb25Hb3Zlcm5hbmNlAAAAAAAAAADIAAAAABFmZWVTY2FsZURlbGltaXRlcgAAAAAAAA9CQAAAAAALc2NhbGVWYWx1ZTMAAAAAAAAAA+gAAAAAC3NjYWxlVmFsdWU4AAAAAAAF9eEAAAAAAAxzY2FsZVZhbHVlMTIAAAAA6NSlEAAAAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyAAAAAAAAAAPoAAAAABFzY2FsZVZhbHVlOERpZ2l0cwAAAAAAAAAACAAAAAASc2NhbGVWYWx1ZTEyRGlnaXRzAAAAAAAAAAAMAAAAAA1kQXBwVGhyZXNob2xkAAAAAAAAAAAyAAAAABZkQXBwVGhyZXNob2xkRGVsaW1pdGVyAAAAAAAAAABkAAAAABFyYXRpb1RocmVzaG9sZE1heAAAAAAABfXhAAAAAAARcmF0aW9UaHJlc2hvbGRNaW4AAAAAAAX13RgAAAAABWFscGhhAAAAAAAAAAAyAAAAAAthbHBo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BQAAAARET1dOBQAAAAtzY2FsZVZhbHVlOAEAAAAaY2FsY3VsYXRlSG93TWFueVNlbmRUb2tlbkEAAAAFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAAAABVtaW5Ub2tlblJlY2VpdmVBbW91bnQAAAAHYW1vdW50QQAAAAdhbW91bnRCAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAANc2xpcHBhZ2VWYWx1ZQkAAGUAAAACBQAAAAtzY2FsZVZhbHVlOAkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWU4AAAAAAAAAAABAAAAAAAAmJaABAAAABdkZWx0YU1heEFuZE1pblNlbmRWYWx1ZQkAAGUAAAACBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQFAAAAFW1pblRva2VuUmVjZWl2ZUFtb3VudAQAAAARYW1vdW50VG9TZW5kU3RlcDEJAABlAAAAAgUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkCQAAaQAAAAIJAABoAAAAAgAAAAAAAAAAAQUAAAAXZGVsdGFNYXhBbmRNaW5TZW5kVmFsdWUAAAAAAAAAAAUEAAAAEWFtb3VudFRvU2VuZFN0ZXAyCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIAAAAAAAAAAAIFAAAAF2RlbHRhTWF4QW5kTWluU2VuZFZhbHVlAAAAAAAAAAAFBAAAABFhbW91bnRUb1NlbmRTdGVwMwkAAGUAAAACBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQJAABpAAAAAgkAAGgAAAACAAAAAAAAAAADBQAAABdkZWx0YU1heEFuZE1pblNlbmRWYWx1ZQAAAAAAAAAABQQAAAARYW1vdW50VG9TZW5kU3RlcDQJAABlAAAAAgUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkCQAAaQAAAAIJAABoAAAAAgAAAAAAAAAABAUAAAAXZGVsdGFNYXhBbmRNaW5TZW5kVmFsdWUAAAAAAAAAAAUEAAAAEWFtb3VudFRvU2VuZFN0ZXA1CQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIAAAAAAAAAAAUFAAAAF2RlbHRhTWF4QW5kTWluU2VuZFZhbHVlAAAAAAAAAAAFBAAAAAF5CQAAZAAAAAIFAAAAB2Ftb3VudEIFAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAAMaW52YXJpYW50TmV3CQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkBQAAAAF5BAAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwkAAGsAAAADBQAAAAlpbnZhcmlhbnQFAAAAC3NjYWxlVmFsdWU4BQAAAAxpbnZhcmlhbnROZXcDCQAAZwAAAAIAAAAAAAAAAAAJAABlAAAAAgkBAAAADWludmFyaWFudENhbGMAAAACCQAAZQAAAAIFAAAAB2Ftb3VudEEFAAAAEWFtb3VudFRvU2VuZFN0ZXA1BQAAAAF5BQAAAAlpbnZhcmlhbnQJAAACAAAAAQIAAAAkbWluVG9rZW5SZWNlaXZlQW1vdW50IHRvbyBsYXJnZS5lcnIxAwMJAABmAAAAAgUAAAAXaW52YXJpYW50RXN0aW1hdGVkUmF0aW8FAAAADXNsaXBwYWdlVmFsdWUJAABmAAAAAgkAAGUAAAACBQAAAAxpbnZhcmlhbnROZXcFAAAACWludmFyaWFudAAAAAAAAAAAAAcFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAARYW1vdW50VG9TZW5kU3RlcDEFAAAAAXkFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAxCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAARYW1vdW50VG9TZW5kU3RlcDIFAAAAAXkFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAyCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAARYW1vdW50VG9TZW5kU3RlcDMFAAAAAXkFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAzCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAARYW1vdW50VG9TZW5kU3RlcDQFAAAAAXkFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXA0CQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgUAAAAHYW1vdW50QQUAAAARYW1vdW50VG9TZW5kU3RlcDUFAAAAAXkFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXA1CQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgkAAAIAAAABAgAAAD5zb21ldGhpbmcgd2VudCB3cm9uZyB3aGlsZSB3b3JraW5nIHdpdGggYW1vdW50VG9TZW5kU3RlcC4gZXJyMgEAAAAaY2FsY3VsYXRlSG93TWFueVNlbmRUb2tlbkIAAAAFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAAAABVtaW5Ub2tlblJlY2VpdmVBbW91bnQAAAAHYW1vdW50QQAAAAdhbW91bnRCAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAANc2xpcHBhZ2VWYWx1ZQkAAGUAAAACBQAAAAtzY2FsZVZhbHVlOAkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWU4AAAAAAAAAAABAAAAAAAAmJaABAAAABdkZWx0YU1heEFuZE1pblNlbmRWYWx1ZQkAAGUAAAACBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQFAAAAFW1pblRva2VuUmVjZWl2ZUFtb3VudAQAAAARYW1vdW50VG9TZW5kU3RlcDEJAABlAAAAAgUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkCQAAaQAAAAIJAABoAAAAAgAAAAAAAAAAAQUAAAAXZGVsdGFNYXhBbmRNaW5TZW5kVmFsdWUAAAAAAAAAAAUEAAAAEWFtb3VudFRvU2VuZFN0ZXAyCQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIAAAAAAAAAAAIFAAAAF2RlbHRhTWF4QW5kTWluU2VuZFZhbHVlAAAAAAAAAAAFBAAAABFhbW91bnRUb1NlbmRTdGVwMwkAAGUAAAACBQAAABVhbW91bnRUb1NlbmRFc3RpbWF0ZWQJAABpAAAAAgkAAGgAAAACAAAAAAAAAAADBQAAABdkZWx0YU1heEFuZE1pblNlbmRWYWx1ZQAAAAAAAAAABQQAAAARYW1vdW50VG9TZW5kU3RlcDQJAABlAAAAAgUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkCQAAaQAAAAIJAABoAAAAAgAAAAAAAAAABAUAAAAXZGVsdGFNYXhBbmRNaW5TZW5kVmFsdWUAAAAAAAAAAAUEAAAAEWFtb3VudFRvU2VuZFN0ZXA1CQAAZQAAAAIFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAkAAGkAAAACCQAAaAAAAAIAAAAAAAAAAAUFAAAAF2RlbHRhTWF4QW5kTWluU2VuZFZhbHVlAAAAAAAAAAAFBAAAAAF4CQAAZAAAAAIFAAAAB2Ftb3VudEEFAAAAEnRva2VuUmVjZWl2ZUFtb3VudAQAAAAMaW52YXJpYW50TmV3CQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAAVYW1vdW50VG9TZW5kRXN0aW1hdGVkBAAAABdpbnZhcmlhbnRFc3RpbWF0ZWRSYXRpbwkAAGsAAAADBQAAAAlpbnZhcmlhbnQFAAAAC3NjYWxlVmFsdWU4BQAAAAxpbnZhcmlhbnROZXcDCQAAZwAAAAIAAAAAAAAAAAAJAABlAAAAAgkBAAAADWludmFyaWFudENhbGMAAAACBQAAAAF4CQAAZQAAAAIFAAAAB2Ftb3VudEIFAAAAEWFtb3VudFRvU2VuZFN0ZXA1BQAAAAlpbnZhcmlhbnQJAAACAAAAAQIAAAAkbWluVG9rZW5SZWNlaXZlQW1vdW50IHRvbyBsYXJnZS5lcnIxAwMJAABmAAAAAgUAAAAXaW52YXJpYW50RXN0aW1hdGVkUmF0aW8FAAAADXNsaXBwYWdlVmFsdWUJAABmAAAAAgkAAGUAAAACBQAAAAxpbnZhcmlhbnROZXcFAAAACWludmFyaWFudAAAAAAAAAAAAAcFAAAAFWFtb3VudFRvU2VuZEVzdGltYXRlZAMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAARYW1vdW50VG9TZW5kU3RlcDEFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAxCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAARYW1vdW50VG9TZW5kU3RlcDIFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAyCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAARYW1vdW50VG9TZW5kU3RlcDMFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXAzCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAARYW1vdW50VG9TZW5kU3RlcDQFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXA0CQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgMJAABmAAAAAgkAAGUAAAACCQEAAAANaW52YXJpYW50Q2FsYwAAAAIFAAAAAXgJAABlAAAAAgUAAAAHYW1vdW50QgUAAAARYW1vdW50VG9TZW5kU3RlcDUFAAAACWludmFyaWFudAAAAAAAAAAAAAkAAGkAAAACCQAAaAAAAAIFAAAAEWFtb3VudFRvU2VuZFN0ZXA1CQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgkAAAIAAAABAgAAAD5zb21ldGhpbmcgd2VudCB3cm9uZyB3aGlsZSB3b3JraW5nIHdpdGggYW1vdW50VG9TZW5kU3RlcC4gZXJyMgEAAAAMZ2V0QXNzZXRJbmZvAAAAAQAAAAdhc3NldElkBAAAAAckbWF0Y2gwBQAAAAdhc3NldElkAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJpZAUAAAAHJG1hdGNoMAQAAAAIc3RyaW5nSWQJAAJYAAAAAQUAAAACaWQEAAAABGluZm8JAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkAA+wAAAABBQAAAAJpZAkAASwAAAACCQABLAAAAAICAAAABkFzc2V0IAUA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AARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAKa2V5VmVyc2lvbgUAAAAHdmVyc2lvbgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAJa2V5QWN0aXZlBgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAtrZXlBc3NldElkQQUAAAAOcG10U3RyQXNzZXRJZEEJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAALa2V5QXNzZXRJZEIFAAAADnBtdFN0ckFzc2V0SWRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAAKcG10QW1vdW50QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAACnBtdEFtb3VudEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADGtleUludmFyaWFudAUAAAATaW52YXJpYW50Q2FsY3VsYXRlZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANa2V5Q29tbWlzc2lvbgUAAAAKY29tbWlzc2lvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAUa2V5ZmVlU2NhbGVEZWxpbWl0ZXIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyCQAETAAAAAIFAAAACnNoYXJlSXNzdWUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAPa2V5U2hhcmVBc3NldElkCQACWAAAAAEFAAAADHNoYXJlSXNzdWVJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAATa2V5U2hhcmVBc3NldFN1cHBseQUAAAASc2hhcmVJbml0aWFsU3VwcGx5CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAASc2hhcmVJbml0aWFsU3VwcGx5BQAAAAxzaGFyZUlzc3VlSWQFAAAAA25pbAAAAAFpAQAAABZyZXBsZW5pc2hXaXRoVHdvVG9rZW5zAAAAAQAAABFzbGlwcGFnZVRvbGVyYW5jZQQAAAALcG10QXNzZXRJZEEICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAAC3BtdEFzc2V0SWRCCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQAAAAdhc3NldElkBAAAAApwbXRBbW91bnRBCQEAAAAQZGVkdWN0U3Rha2luZ0ZlZQAAAAIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAUAAAALcG10QXNzZXRJZEEEAAAACnBtdEFtb3VudEIJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEAAAAGYW1vdW50BQAAAAtwbXRBc3NldElkQgQAAAAKdG9rZW5SYXRpbwkAAGsAAAADCQAAawAAAAMFAAAACGJhbGFuY2VBBQAAAAtzY2FsZVZhbHVlOAUAAAAKcG10QW1vdW50QQUAAAALc2NhbGVWYWx1ZTMJAABrAAAAAwUAAAAIYmFsYW5jZUIFAAAAC3NjYWxlVmFsdWU4BQAAAApwbXRBbW91bnRCBAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMFAAAACnBtdEFtb3VudEEFAAAAC3NjYWxlVmFsdWU4BQAAAAhiYWxhbmNlQQQAAAATcmF0aW9TaGFyZVRva2Vuc0luQgkAAGsAAAADBQAAAApwbXRBbW91bnRCBQAAAAtzY2FsZVZhbHVlOAUAAAAIYmFsYW5jZUIEAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAkAAGsAAAADCQABlwAAAAEJAARMAAAAAgUAAAATcmF0aW9TaGFyZVRva2Vuc0luQQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5CBQAAAANuaWwFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAAC3NjYWxlVmFsdWU4BAAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACnBtdEFtb3VudEIDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQEAAAAPdGhyb3dJc0luYWN0aXZlAAAAAAMDCQAAZgAAAAIAAAAAAAAAAAAFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBgkAAGYAAAACBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAApU2xpcHBhZ2UgdG9sZXJhbmNlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAJAAGkAAAAAQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXICAAAAFiBpbmNsdXNpdmVseS4gQWN0dWFsOiAJAAGkAAAAAQUAAAARc2xpcHBhZ2VUb2xlcmFuY2UDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAACCQAAAgAAAAECAAAAHFR3byBhdHRhY2hlZCBhc3NldHMgZXhwZWN0ZWQDAwkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEEFAAAACGFzc2V0SWRBBgkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEIFAAAACGFzc2V0SWRCCQEAAAALdGhyb3dBc3NldHMAAAAAAwMJAABmAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWUzCQAAZQAAAAIFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAACnRva2VuUmF0aW8GCQAAZgAAAAIFAAAACnRva2VuUmF0aW8JAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlMwkAAGQAAAACBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyCQAAAgAAAAECAAAAPUluY29ycmVjdCBhc3NldHMgYW1vdW50OiBhbW91bnRzIG11c3QgaGF2ZSB0aGUgY29udHJhY3QgcmF0aW8DCQAAAAAAAAIFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAAAAAAAAAAAAAkAAAIAAAABAgAAAB1Ub28gc21hbGwgYW1vdW50IHRvIHJlcGxlbmlzaAMJAQAAAAEhAAAAAQUAAAAQaGFzRW5vdWdoQmFsYW5jZQkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAApwbXRBbW91bnRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5CQAAZAAAAAIFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAMa2V5SW52YXJpYW50BQAAABNpbnZhcmlhbnRDYWxjdWxhdGVkCQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAMc2hhcmVBc3NldElkBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQGCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQFAAAAA25pbAAAAAFpAQAAABVyZXBsZW5pc2hXaXRoT25lVG9rZW4AAAACAAAAE3ZpcnR1YWxTd2FwVG9rZW5QYXkAAAATdmlydHVhbFN3YXBUb2tlbkdldAQAAAANJHQwMTYxMzIxNjIwNwkABRQAAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAACXBtdEFtb3VudAgFAAAADSR0MDE2MTMyMTYyMDcAAAACXzEEAAAACnBtdEFzc2V0SWQIBQAAAA0kdDAxNjEzMjE2MjA3AAAAAl8yBAAAAA9wbXRNaW5UaHJlc2hvbGQAAAAAAABMS0AEAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlAAAAAAAC+vCABAAAAAl0b2xlcmFuY2UDCQAAZgAAAAIFAAAAHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlBQAAAAlwbXRBbW91bnQAAAAAAAABhqAAAAAAAAAAAAEEAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gJAABlAAAAAgUAAAALc2NhbGVWYWx1ZTgJAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlOAUAAAAJdG9sZXJhbmNlAAAAAAAAmJaABAAAABxzbGlwcGFnZVZhbHVlTWF4Rm9yUmVwbGVuaXNoCQAAZAAAAAIFAAAAC3NjYWxlVmFsdWU4CQAAaQAAAAIJAABoAAAAAgUAAAALc2NhbGVWYWx1ZTgFAAAACXRvbGVyYW5jZQAAAAAAAJiWgAQAAAAXc2xpcHBhZ2VWYWx1ZU1pbkZvclN3YXAJAABlAAAAAgUAAAALc2NhbGVWYWx1ZTgJAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlOAAAAAAAAAAAAQAAAAAAAJiWgAQAAAAXc2xpcHBhZ2VWYWx1ZU1heEZvclN3YXAJAABkAAAAAgUAAAALc2NhbGVWYWx1ZTgJAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlOAAAAAAAAAAAAQAAAAAAAJiWgAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAQAAAA90aHJvd0lzSW5hY3RpdmUAAAAAAwkAAGYAAAACBQAAAA9wbXRNaW5UaHJlc2hvbGQFAAAACXBtdEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAD1BheW1lbnQgYW1vdW50IAkAAaQAAAABBQAAAAlwbXRBbW91bnQCAAAAJyBkb2VzIG5vdCBleGNlZWQgdGhlIG1pbmltdW0gYW1vdW50IG9mIAkAAaQAAAABBQAAAA9wbXRNaW5UaHJlc2hvbGQCAAAAByB0b2tlbnMDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQEAAAARc3VzcGVuZFN1c3BpY2lvdXMAAAAAAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQQQAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQQkAAGUAAAACBQAAAAlwbXRBbW91bnQFAAAAE3ZpcnR1YWxTd2FwVG9rZW5QYXkEAAAAHGFtb3VudFZpcnR1YWxSZXBsZW5pc2hUb2tlbkIFAAAAE3ZpcnR1YWxTd2FwVG9rZW5HZXQEAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQQkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAATdmlydHVhbFN3YXBUb2tlblBheQQAAAAYYmFsYW5jZUFmdGVyVmlydHVhbFN3YXBCCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAABN2aXJ0dWFsU3dhcFRva2VuR2V0BAAAAAxpbnZhcmlhbnROZXcJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgUAAAAYYmFsYW5jZUFmdGVyVmlydHVhbFN3YXBBBQAAABhiYWxhbmNlQWZ0ZXJWaXJ0dWFsU3dhcEIEAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvCQAAawAAAAMFAAAACWludmFyaWFudAUAAAALc2NhbGVWYWx1ZTgFAAAADGludmFyaWFudE5ldwMDCQAAZgAAAAIFAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvBQAAABdzbGlwcGFnZVZhbHVlTWluRm9yU3dhcAkAAGYAAAACCQAAZQAAAAIFAAAADGludmFyaWFudE5ldwUAAAAJaW52YXJpYW50AAAAAAAAAAAABwQAAAAlcmF0aW9WaXJ0dWFsQmFsYW5jZVRvVmlydHVhbFJlcGxlbmlzaAkAAGkAAAACCQAAawAAAAMFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQQkAAGgAAAACBQAAAAtzY2FsZVZhbHVlOAUAAAALc2NhbGVWYWx1ZTgFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQgkAAGsAAAADBQAAABxhbW91bnRWaXJ0dWFsUmVwbGVuaXNoVG9rZW5BBQAAAAtzY2FsZVZhbHVlOAUAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQgMDCQAAZgAAAAIFAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gGCQAAZgAAAAIFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gFAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAAACAAAAAQIAAABmc3dvcCB3aXRoIHZpcnR1YWxTd2FwVG9rZW5QYXkgYW5kIHZpcnR1YWxTd2FwVG9rZW5HZXQgcG9zc2libGUsIGJ1dCByYXRpbyBhZnRlciB2aXJ0dWFsIHN3YXAgaW5jb3JyZWN0BAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAgUAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQQUAAAAIYXNzZXRJZEEFAAAAC3NjYWxlVmFsdWU4BQAAABhiYWxhbmNlQWZ0ZXJWaXJ0dWFsU3dhcEEEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIJAABrAAAAAwkBAAAAEGRlZHVjdFN0YWtpbmdGZWUAAAACBQAAABxhbW91bnRWaXJ0dWFsUmVwbGVuaXNoVG9rZW5CBQAAAAhhc3NldElkQgUAAAALc2NhbGVWYWx1ZTgFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQgQAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAAawAAAAMJAAGXAAAAAQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIFAAAAA25pbAUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAALc2NhbGVWYWx1ZTgEAAAAE2ludmFyaWFudENhbGN1bGF0ZWQJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAAJcG10QW1vdW50BQAAAAhiYWxhbmNlQgQAAAALbmV3QmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACXBtdEFtb3VudAQAAAALbmV3QmFsYW5jZUIFAAAACGJhbGFuY2VCBAAAABNkQXBwVGhyZXNob2xkQW1vdW50CQAAawAAAAMJAABkAAAAAgUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCBQAAAA1kQXBwVGhyZXNob2xkCQAAaAAAAAIAAAAAAAAAAAIFAAAAFmRBcHBUaHJlc2hvbGREZWxpbWl0ZXIDAwkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQYJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUIJAQAAAA50aHJvd1RocmVzaG9sZAAAAAMFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAHUmVpc3N1ZQAAAAMFAAAADHNoYXJlQXNzZXRJZAUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAUAAAAMc2hhcmVBc3NldElkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5CQAAZAAAAAIFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAxrZXlJbnZhcmlhbnQFAAAAE2ludmFyaWFudENhbGN1bGF0ZWQFAAAAA25pbAkAAAIAAAABAgAAADppbmNvcnJlY3QgdmlydHVhbFN3YXBUb2tlblBheSBvciB2aXJ0dWFsU3dhcFRva2VuR2V0IHZhbHVlAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQgQAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQgkAAGUAAAACBQAAAAlwbXRBbW91bnQFAAAAE3ZpcnR1YWxTd2FwVG9rZW5QYXkEAAAAHGFtb3VudFZpcnR1YWxSZXBsZW5pc2hUb2tlbkEFAAAAE3ZpcnR1YWxTd2FwVG9rZW5HZXQEAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQQkAAGUAAAACBQAAAAhiYWxhbmNlQQUAAAATdmlydHVhbFN3YXBUb2tlbkdldAQAAAAYYmFsYW5jZUFmdGVyVmlydHVhbFN3YXBCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAABN2aXJ0dWFsU3dhcFRva2VuUGF5BAAAAAxpbnZhcmlhbnROZXcJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgUAAAAYYmFsYW5jZUFmdGVyVmlydHVhbFN3YXBBBQAAABhiYWxhbmNlQWZ0ZXJWaXJ0dWFsU3dhcEIEAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvCQAAawAAAAMFAAAACWludmFyaWFudAUAAAALc2NhbGVWYWx1ZTgFAAAADGludmFyaWFudE5ldwMDCQAAZgAAAAIFAAAAF2ludmFyaWFudEVzdGltYXRlZFJhdGlvBQAAABdzbGlwcGFnZVZhbHVlTWluRm9yU3dhcAkAAGYAAAACCQAAZQAAAAIFAAAADGludmFyaWFudE5ldwUAAAAJaW52YXJpYW50AAAAAAAAAAAABwQAAAAlcmF0aW9WaXJ0dWFsQmFsYW5jZVRvVmlydHVhbFJlcGxlbmlzaAkAAGkAAAACCQAAawAAAAMFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQQkAAGgAAAACBQAAAAtzY2FsZVZhbHVlOAUAAAALc2NhbGVWYWx1ZTgFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQgkAAGsAAAADBQAAABxhbW91bnRWaXJ0dWFsUmVwbGVuaXNoVG9rZW5BBQAAAAtzY2FsZVZhbHVlOAUAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQgMDCQAAZgAAAAIFAAAAHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gGCQAAZgAAAAIFAAAAJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gFAAAAHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gJAAACAAAAAQIAAABmc3dvcCB3aXRoIHZpcnR1YWxTd2FwVG9rZW5QYXkgYW5kIHZpcnR1YWxTd2FwVG9rZW5HZXQgcG9zc2libGUsIGJ1dCByYXRpbyBhZnRlciB2aXJ0dWFsIHN3YXAgaW5jb3JyZWN0BAAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAAawAAAAMJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAgUAAAAcYW1vdW50VmlydHVhbFJlcGxlbmlzaFRva2VuQQUAAAAIYXNzZXRJZEEFAAAAC3NjYWxlVmFsdWU4BQAAABhiYWxhbmNlQWZ0ZXJWaXJ0dWFsU3dhcEEEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIJAABrAAAAAwkBAAAAEGRlZHVjdFN0YWtpbmdGZWUAAAACBQAAABxhbW91bnRWaXJ0dWFsUmVwbGVuaXNoVG9rZW5CBQAAAAhhc3NldElkQgUAAAALc2NhbGVWYWx1ZTgFAAAAGGJhbGFuY2VBZnRlclZpcnR1YWxTd2FwQgQAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50CQAAawAAAAMJAAGXAAAAAQkABEwAAAACBQAAABNyYXRpb1NoYXJlVG9rZW5zSW5BCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIFAAAAA25pbAUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAALc2NhbGVWYWx1ZTgEAAAAE2ludmFyaWFudENhbGN1bGF0ZWQJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgUAAAAIYmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACXBtdEFtb3VudAQAAAALbmV3QmFsYW5jZUEFAAAACGJhbGFuY2VBBAAAAAtuZXdCYWxhbmNlQgkAAGQAAAACBQAAAAhiYWxhbmNlQgUAAAAJcG10QW1vdW50BAAAABNkQXBwVGhyZXNob2xkQW1vdW50CQAAawAAAAMJAABkAAAAAgUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCBQAAAA1kQXBwVGhyZXNob2xkCQAAaAAAAAIAAAAAAAAAAAIFAAAAFmRBcHBUaHJlc2hvbGREZWxpbWl0ZXIDAwkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQQYJAABmAAAAAgUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUIJAQAAAA50aHJvd1RocmVzaG9sZAAAAAMFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAHUmVpc3N1ZQAAAAMFAAAADHNoYXJlQXNzZXRJZAUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50BgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAUAAAAMc2hhcmVBc3NldElkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrZXlTaGFyZUFzc2V0U3VwcGx5CQAAZAAAAAIFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAAC25ld0JhbGFuY2VCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAxrZXlJbnZhcmlhbnQFAAAAE2ludmFyaWFudENhbGN1bGF0ZWQFAAAAA25pbAkAAAIAAAABAgAAADppbmNvcnJlY3QgdmlydHVhbFN3YXBUb2tlblBheSBvciB2aXJ0dWFsU3dhcFRva2VuR2V0IHZhbHVlCQEAAAALdGhyb3dBc3NldHMAAAAAAAAAAWkBAAAACHdpdGhkcmF3AAAAAAQAAAANJHQwMjI1NjYyMjcxNgkABRQAAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAACXBtdEFtb3VudAgFAAAADSR0MDIyNTY2MjI3MTYAAAACXzEEAAAACnBtdEFzc2V0SWQIBQAAAA0kdDAyMjU2NjIyNzE2AAAAAl8yBAAAAAxhbW91bnRUb1BheUEJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAgkAAGsAAAADBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VBBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAhhc3NldElkQQQAAAAMYW1vdW50VG9QYXlCCQEAAAAQZGVkdWN0U3Rha2luZ0ZlZQAAAAIJAABrAAAAAwUAAAAJcG10QW1vdW50BQAAAAhiYWxhbmNlQgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAIYXNzZXRJZEIEAAAAE2ludmFyaWFudENhbGN1bGF0ZWQJAQAAAA1pbnZhcmlhbnRDYWxjAAAAAgkAAGUAAAACBQAAAAhiYWxhbmNlQQUAAAAMYW1vdW50VG9QYXlBCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAAxhbW91bnRUb1BheUIDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQEAAAAPdGhyb3dJc0luYWN0aXZlAAAAAAMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAdT25lIGF0dGFjaGVkIHBheW1lbnQgZXhwZWN0ZWQDCQEAAAACIT0AAAACBQAAAApwbXRBc3NldElkBQAAAAxzaGFyZUFzc2V0SWQJAAACAAAAAQkAASwAAAACAgAAACRJbmNvcnJlY3QgYXNzZXQgYXR0YWNoZWQuIEV4cGVjdGVkOiAJAAJYAAAAAQUAAAAMc2hhcmVBc3NldElkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQEAAAARc3VzcGVuZFN1c3BpY2lvdXMAAAAAAwMJAABmAAAAAgUAAAAMYW1vdW50VG9QYXlBBQAAABFhdmFpbGFibGVCYWxhbmNlQQYJAABmAAAAAgUAAAAMYW1vdW50VG9QYXlCBQAAABFhdmFpbGFibGVCYWxhbmNlQgkBAAAAInRocm93SW5zdWZmaWNpZW50QXZhaWxhYmxlQmFsYW5jZXMAAAACBQAAAAxhbW91bnRUb1BheUEFAAAADGFtb3VudFRvUGF5QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADGFtb3VudFRvUGF5QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIJAABlAAAAAgUAAAAIYmFsYW5jZUIFAAAADGFtb3VudFRvUGF5QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAATa2V5U2hhcmVBc3NldFN1cHBseQkAAGUAAAACBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAlwbXRBbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADGtleUludmFyaWFudAUAAAATaW52YXJpYW50Q2FsY3VsYXRlZAkABEwAAAACCQEAAAAEQnVybgAAAAIFAAAADHNoYXJlQXNzZXRJZAUAAAAJcG10QW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAMYW1vdW50VG9QYXlBBQAAAAhhc3NldElkQQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADGFtb3VudFRvUGF5QgUAAAAIYXNzZXRJZEIFAAAAA25pbAAAAAFpAQAAAAhleGNoYW5nZQAAAAIAAAAYZXN0aW1hdGVkQW1vdW50VG9SZWNlaXZlAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQQAAAANJHQwMjQwMDcyNDA4MgkABRQAAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAACXBtdEFtb3VudAgFAAAADSR0MDI0MDA3MjQwODIAAAACXzEEAAAACnBtdEFzc2V0SWQIBQAAAA0kdDAyNDAwNzI0MDgyAAAAAl8yAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkBAAAAD3Rocm93SXNJbmFjdGl2ZQAAAAADCQAAZwAAAAIAAAAAAAAAAAAFAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQkAAAIAAAABCQABLAAAAAICAAAAK0VzdGltYXRlZCBhbW91bnQgbXVzdCBiZSBwb3NpdGl2ZS4gQWN0dWFsOiAJAAGkAAAAAQUAAAAYZXN0aW1hdGVkQW1vdW50VG9SZWNlaXZlAwkAAGYAAAACBQAAABJtaW5BbW91bnRUb1JlY2VpdmUFAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAADtNaW5pbWFsIGFtb3VudCBjYW4ndCBiZSBncmVhdGVyIHRoYW4gZXN0aW1hdGVkLiBFc3RpbWF0ZWQ6IAkAAaQAAAABBQAAABhlc3RpbWF0ZWRBbW91bnRUb1JlY2VpdmUCAAAACy4gTWluaW1hbDogCQABpAAAAAEFAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAdT25lIGF0dGFjaGVkIHBheW1lbnQgZXhwZWN0ZWQDCQEAAAABIQAAAAEFAAAAEGhhc0Vub3VnaEJhbGFuY2UJAQAAABFzdXNwZW5kU3VzcGljaW91cwAAAAADCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRBBAAAAAthc3NldElkU2VuZAUAAAAIYXNzZXRJZEIEAAAAEGFtb3VudFdpdGhvdXRGZWUJAQAAABpjYWxjdWxhdGVIb3dNYW55U2VuZFRva2VuQgAAAAUFAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAAhiYWxhbmNlQQUAAAAIYmFsYW5jZUIFAAAACXBtdEFtb3VudAQAAAANYW1vdW50V2l0aEZlZQkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgQAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlBQAAABRjb21taXNzaW9uR292ZXJuYW5jZQUAAAARZmVlU2NhbGVEZWxpbWl0ZXIEAAAAC25ld0JhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQEAAAAC25ld0JhbGFuY2VCCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUIFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQEAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQJAABrAAAAAwkAAGQAAAACBQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIFAAAADWRBcHBUaHJlc2hvbGQJAABoAAAAAgAAAAAAAAAAAgUAAAAWZEFwcFRocmVzaG9sZERlbGltaXRlcgMDCQAAZgAAAAIFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBgkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQgkBAAAADnRocm93VGhyZXNob2xkAAAAAwUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCAwMDCQAAAAAAAAIFAAAACGFzc2V0SWRBBQAAAARVU0ROCQAAZwAAAAIFAAAAEHN0YWtlZEFtb3VudFVTRE4FAAAAC25ld0JhbGFuY2VBBwYDCQAAAAAAAAIFAAAACGFzc2V0SWRCBQAAAARVU0ROCQAAZwAAAAIFAAAAEHN0YWtlZEFtb3VudFVTRE4FAAAAC25ld0JhbGFuY2VCBwkBAAAAIXRocm93SW5zdWZmaWNpZW50QXZhaWxhYmxlQmFsYW5jZQAAAAMFAAAADWFtb3VudFdpdGhGZWUFAAAAEWF2YWlsYWJsZUJhbGFuY2VCBQAAAAphc3NldE5hbWVCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAMa2V5SW52YXJpYW50CQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAACXBtdEFtb3VudAkAAGUAAAACCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAA1hbW91bnRXaXRoRmVlBQAAABBnb3Zlcm5hbmNlUmV3YXJkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAANYW1vdW50V2l0aEZlZQUAAAALYXNzZXRJZFNlbmQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAARZ292ZXJuYW5jZUFkZHJlc3MFAAAAEGdvdmVybmFuY2VSZXdhcmQFAAAAC2Fzc2V0SWRTZW5kBQAAAANuaWwDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAACGFzc2V0SWRCBAAAAAthc3NldElkU2VuZAUAAAAIYXNzZXRJZEEEAAAAEGFtb3VudFdpdGhvdXRGZWUJAQAAABpjYWxjdWxhdGVIb3dNYW55U2VuZFRva2VuQQAAAAUFAAAAGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZQUAAAASbWluQW1vdW50VG9SZWNlaXZlBQAAAAhiYWxhbmNlQQUAAAAIYmFsYW5jZUIFAAAACXBtdEFtb3VudAQAAAANYW1vdW50V2l0aEZlZQkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlCQAAZQAAAAIFAAAAEWZlZVNjYWxlRGVsaW1pdGVyBQAAAApjb21taXNzaW9uBQAAABFmZWVTY2FsZURlbGltaXRlcgQAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlBQAAABRjb21taXNzaW9uR292ZXJuYW5jZQUAAAARZmVlU2NhbGVEZWxpbWl0ZXIEAAAAC25ld0JhbGFuY2VBCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUEFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQEAAAAC25ld0JhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAAlwbXRBbW91bnQEAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQJAABrAAAAAwkAAGQAAAACBQAAAAtuZXdCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUIFAAAADWRBcHBUaHJlc2hvbGQJAABoAAAAAgAAAAAAAAAAAgUAAAAWZEFwcFRocmVzaG9sZERlbGltaXRlcgMDCQAAZgAAAAIFAAAAE2RBcHBUaHJlc2hvbGRBbW91bnQFAAAAC25ld0JhbGFuY2VBBgkAAGYAAAACBQAAABNkQXBwVGhyZXNob2xkQW1vdW50BQAAAAtuZXdCYWxhbmNlQgkBAAAADnRocm93VGhyZXNob2xkAAAAAwUAAAATZEFwcFRocmVzaG9sZEFtb3VudAUAAAALbmV3QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VCAwMDCQAAAAAAAAIFAAAACGFzc2V0SWRBBQAAAARVU0ROCQAAZwAAAAIFAAAAEHN0YWtlZEFtb3VudFVTRE4FAAAAC25ld0JhbGFuY2VBBwYDCQAAAAAAAAIFAAAACGFzc2V0SWRCBQAAAARVU0ROCQAAZwAAAAIFAAAAEHN0YWtlZEFtb3VudFVTRE4FAAAAC25ld0JhbGFuY2VCBwkBAAAAIXRocm93SW5zdWZmaWNpZW50QXZhaWxhYmxlQmFsYW5jZQAAAAMFAAAADWFtb3VudFdpdGhGZWUFAAAAEWF2YWlsYWJsZUJhbGFuY2VBBQAAAAphc3NldE5hbWVBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAMa2V5SW52YXJpYW50CQEAAAANaW52YXJpYW50Q2FsYwAAAAIJAABlAAAAAgkAAGUAAAACBQAAAAhiYWxhbmNlQQUAAAANYW1vdW50V2l0aEZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAkAAGQAAAACBQAAAAhiYWxhbmNlQgUAAAAJcG10QW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAANYW1vdW50V2l0aEZlZQUAAAALYXNzZXRJZFNlbmQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAARZ292ZXJuYW5jZUFkZHJlc3MFAAAAEGdvdmVybmFuY2VSZXdhcmQFAAAAC2Fzc2V0SWRTZW5kBQAAAANuaWwJAQAAAAt0aHJvd0Fzc2V0cwAAAAAAAAABaQEAAAAIc2h1dGRvd24AAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABCQABLAAAAAICAAAAIkRBcHAgaXMgYWxyZWFkeSBzdXNwZW5kZWQuIENhdXNlOiAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAIa2V5Q2F1c2UCAAAAGnRoZSBjYXVzZSB3YXNuJ3Qgc3BlY2lmaWVkAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABRhZG1pblB1YktleVN0YXJ0U3RvcAUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAQAAAA50aHJvd09ubHlBZG1pbgAAAAAJAQAAAAdzdXNwZW5kAAAAAQIAAAAPUGF1c2VkIGJ5IGFkbWluAAAAAWkBAAAACGFjdGl2YXRlAAAAAAMFAAAACGlzQWN0aXZlCQEAAAANdGhyb3dJc0FjdGl2ZQAAAAADCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzCQAETAAAAAIFAAAAFGFkbWluUHViS2V5U3RhcnRTdG9wBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAADnRocm93T25seUFkbWluAAAAAAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAJa2V5QWN0aXZlBgkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABBQAAAAhrZXlDYXVzZQUAAAADbmlsAAAAAWkBAAAAGXRha2VJbnRvQWNjb3VudEV4dHJhRnVuZHMAAAABAAAAC2Ftb3VudExlYXZlBAAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QQkAAGUAAAACBQAAABlhY2NvdW50QmFsYW5jZVdpdGhTdGFrZWRBBQAAAAhiYWxhbmNlQQQAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEIJAABlAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIEAAAADWFtb3VudEVucm9sbEEJAABlAAAAAgUAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEEDCQAAAAAAAAIFAAAACGFzc2V0SWRBBQAAAARVU0ROBQAAAAthbW91bnRMZWF2ZQAAAAAAAAAAAAQAAAANYW1vdW50RW5yb2xsQgkAAGUAAAACBQAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QgMJAAAAAAAAAgUAAAAIYXNzZXRJZEIFAAAABFVTRE4FAAAAC2Ftb3VudExlYXZlAAAAAAAAAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkBAAAAD3Rocm93SXNJbmFjdGl2ZQAAAAADCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzCQAETAAAAAIFAAAAEmFkbWluUHViS2V5U3Rha2luZwUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAQAAAA50aHJvd09ubHlBZG1pbgAAAAADCQAAZgAAAAIAAAAAAAAAAAAFAAAAC2Ftb3VudExlYXZlCQAAAgAAAAEJAAEsAAAAAgIAAAAzQXJndW1lbnQgJ2Ftb3VudExlYXZlJyBjYW5ub3QgYmUgbmVnYXRpdmUuIEFjdHVhbDogCQABpAAAAAEFAAAAC2Ftb3VudExlYXZlAwMJAABmAAAAAgAAAAAAAAAAAAUAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEEGCQAAZgAAAAIAAAAAAAAAAAAFAAAAHXVuY291bnRhYmxlQW1vdW50RW5yb2xsQXNzZXRCCQEAAAAHc3VzcGVuZAAAAAECAAAAFkVucm9sbCBhbW91bnQgbmVnYXRpdmUDAwkAAGYAAAACAAAAAAAAAAAABQAAAA1hbW91bnRFbnJvbGxBBgkAAGYAAAACAAAAAAAAAAAABQAAAA1hbW91bnRFbnJvbGxCCQAAAgAAAAECAAAAFVRvbyBsYXJnZSBhbW91bnRMZWF2ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEJAABkAAAAAgUAAAAIYmFsYW5jZUEFAAAADWFtb3VudEVucm9sbEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCCQAAZAAAAAIFAAAACGJhbGFuY2VCBQAAAA1hbW91bnRFbnJvbGxCBQAAAANuaWwAAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAABAAAAAckbWF0Y2gwBQAAAAJ0eAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXSW52b2tlU2NyaXB0VHJhbnNhY3Rpb24EAAAABmludm9rZQUAAAAHJG1hdGNoMAMJAAH0AAAAAwgFAAAABmludm9rZQAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAABmludm9rZQAAAAZwcm9vZnMAAAAAAAAAAAAFAAAAEmFkbWluUHViS2V5U3Rha2luZwkAAAAAAAACCAUAAAAGaW52b2tlAAAABGRBcHAFAAAADnN0YWtpbmdBZGRyZXNzBwQAAAASYWRtaW5QdWJLZXkxU2lnbmVkAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAADGFkbWluUHViS2V5MQAAAAAAAAAAAQAAAAAAAAAAAAQAAAASYWRtaW5QdWJLZXkyU2lnbmVkAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAEFAAAADGFkbWluUHViS2V5MgAAAAAAAAAAAQAAAAAAAAAAAAQAAAASYWRtaW5QdWJLZXkzU2lnbmVkAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAIFAAAADGFkbWluUHViS2V5MwAAAAAAAAAAAQAAAAAAAAAAAAkAAGcAAAACCQAAZAAAAAIJAABkAAAAAgUAAAASYWRtaW5QdWJLZXkxU2lnbmVkBQAAABJhZG1pblB1YktleTJTaWduZWQFAAAAEmFkbWluUHViS2V5M1NpZ25lZAAAAAAAAAAAArCQ/gw=", "height": 2344881, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: FA6XKs86d6SD2kuYgN3yUKZGdoZqtd6Pj38JK6nQDJ9K Next: D7A5pQWs11BLu5aSPC1UHtbZLyEMwhHEMiFSMVw3Upmk Diff:
OldNewDifferences
2121
2222 let keyCommission = "commission"
2323
24-let keyCommissionScaleDelimiter = "commission_scale_delimiter"
24+let keyfeeScaleDelimiter = "commission_scale_delimiter"
2525
2626 let keyCommissionGovernance = "commission_governance"
2727
3535
3636 let adminPubKey3 = base58'AZmWJtuy4GeVrMmJH4hfFBRApe1StvhJSk4jcbT6bArQ'
3737
38-let adminPubKey4startStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
38+let adminPubKeyStartStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
39+
40+let adminPubKeyStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
3941
4042 let governanceAddress = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
43+
44+let stakingAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ')
45+
46+let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
47+
48+let stakingFeeInUSDN = (9 * value(value(assetInfo(USDN)).minSponsoredFee))
4149
4250 let isActive = getBooleanValue(this, keyActive)
4351
8593
8694 let commissionGovernance = 200
8795
88-let commissionScaleDelimiter = 1000000
96+let feeScaleDelimiter = 1000000
8997
9098 let scaleValue3 = 1000
9199
125133 }
126134
127135
128-let hasEnoughBalance = if ((accountBalance(assetIdA) >= balanceA))
129- then (accountBalance(assetIdB) >= balanceB)
136+let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
137+ case staked: Int =>
138+ staked
139+ case nothing: Unit =>
140+ 0
141+ case _ =>
142+ throw("Match error")
143+}
144+
145+let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
146+ then stakedAmountUSDN
147+ else 0))
148+
149+let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
150+ then stakedAmountUSDN
151+ else 0))
152+
153+let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
154+ then stakedAmountUSDN
155+ else 0))
156+
157+let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
158+ then stakedAmountUSDN
159+ else 0))
160+
161+let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
162+ then (accountBalanceWithStakedB >= balanceB)
130163 else false
131164
132165 func skewness (x,y) = (((fraction(scaleValue12, x, y) + fraction(scaleValue12, y, x)) / 2) / 10000)
138171 }
139172
140173
141-func calculateHowManySendTokenA (amountToSendEstimated,minTokenReceiveAmount,amountTokenA,amountTokenB,tokenReceiveAmount) = {
174+func calculateHowManySendTokenA (amountToSendEstimated,minTokenReceiveAmount,amountA,amountB,tokenReceiveAmount) = {
142175 let slippageValue = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
143- let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
144- let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaBetweenMaxAndMinSendValue) / 5))
145- let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaBetweenMaxAndMinSendValue) / 5))
146- let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaBetweenMaxAndMinSendValue) / 5))
147- let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaBetweenMaxAndMinSendValue) / 5))
148- let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaBetweenMaxAndMinSendValue) / 5))
149- let y = (amountTokenB + tokenReceiveAmount)
150- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc((amountTokenA - amountToSendEstimated), y))
151- if ((0 > (invariantCalc((amountTokenA - amountToSendStep5), y) - invariant)))
176+ let deltaMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
177+ let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaMaxAndMinSendValue) / 5))
178+ let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaMaxAndMinSendValue) / 5))
179+ let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaMaxAndMinSendValue) / 5))
180+ let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaMaxAndMinSendValue) / 5))
181+ let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaMaxAndMinSendValue) / 5))
182+ let y = (amountB + tokenReceiveAmount)
183+ let invariantNew = invariantCalc((amountA - amountToSendEstimated), y)
184+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
185+ if ((0 >= (invariantCalc((amountA - amountToSendStep5), y) - invariant)))
152186 then throw("minTokenReceiveAmount too large.err1")
153187 else if (if ((invariantEstimatedRatio > slippageValue))
154- then (scaleValue8 > invariantEstimatedRatio)
188+ then ((invariantNew - invariant) > 0)
155189 else false)
156190 then amountToSendEstimated
157- else if (((invariantCalc((amountTokenA - amountToSendStep1), y) - invariant) > 0))
158- then ((amountToSendStep1 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
159- else if (((invariantCalc((amountTokenA - amountToSendStep2), y) - invariant) > 0))
160- then ((amountToSendStep2 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
161- else if (((invariantCalc((amountTokenA - amountToSendStep3), y) - invariant) > 0))
162- then ((amountToSendStep3 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
163- else if (((invariantCalc((amountTokenA - amountToSendStep4), y) - invariant) > 0))
164- then ((amountToSendStep4 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
165- else if (((invariantCalc((amountTokenA - amountToSendStep5), y) - invariant) > 0))
166- then ((amountToSendStep5 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
191+ else if (((invariantCalc((amountA - amountToSendStep1), y) - invariant) > 0))
192+ then ((amountToSendStep1 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
193+ else if (((invariantCalc((amountA - amountToSendStep2), y) - invariant) > 0))
194+ then ((amountToSendStep2 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
195+ else if (((invariantCalc((amountA - amountToSendStep3), y) - invariant) > 0))
196+ then ((amountToSendStep3 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
197+ else if (((invariantCalc((amountA - amountToSendStep4), y) - invariant) > 0))
198+ then ((amountToSendStep4 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
199+ else if (((invariantCalc((amountA - amountToSendStep5), y) - invariant) > 0))
200+ then ((amountToSendStep5 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
167201 else throw("something went wrong while working with amountToSendStep. err2")
168202 }
169203
170204
171-func calculateHowManySendTokenB (amountToSendEstimated,minTokenReceiveAmount,amountTokenA,amountTokenB,tokenReceiveAmount) = {
205+func calculateHowManySendTokenB (amountToSendEstimated,minTokenReceiveAmount,amountA,amountB,tokenReceiveAmount) = {
172206 let slippageValue = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
173- let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
174- let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaBetweenMaxAndMinSendValue) / 5))
175- let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaBetweenMaxAndMinSendValue) / 5))
176- let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaBetweenMaxAndMinSendValue) / 5))
177- let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaBetweenMaxAndMinSendValue) / 5))
178- let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaBetweenMaxAndMinSendValue) / 5))
179- let x = (amountTokenA + tokenReceiveAmount)
180- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(x, (amountTokenB - amountToSendEstimated)))
181- if ((0 > (invariantCalc(x, (amountTokenB - amountToSendStep5)) - invariant)))
207+ let deltaMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
208+ let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaMaxAndMinSendValue) / 5))
209+ let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaMaxAndMinSendValue) / 5))
210+ let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaMaxAndMinSendValue) / 5))
211+ let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaMaxAndMinSendValue) / 5))
212+ let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaMaxAndMinSendValue) / 5))
213+ let x = (amountA + tokenReceiveAmount)
214+ let invariantNew = invariantCalc(x, (amountB - amountToSendEstimated))
215+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
216+ if ((0 >= (invariantCalc(x, (amountB - amountToSendStep5)) - invariant)))
182217 then throw("minTokenReceiveAmount too large.err1")
183218 else if (if ((invariantEstimatedRatio > slippageValue))
184- then (scaleValue8 > invariantEstimatedRatio)
219+ then ((invariantNew - invariant) > 0)
185220 else false)
186221 then amountToSendEstimated
187- else if (((invariantCalc(x, (amountTokenB - amountToSendStep1)) - invariant) > 0))
188- then ((amountToSendStep1 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
189- else if (((invariantCalc(x, (amountTokenB - amountToSendStep2)) - invariant) > 0))
190- then ((amountToSendStep2 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
191- else if (((invariantCalc(x, (amountTokenB - amountToSendStep3)) - invariant) > 0))
192- then ((amountToSendStep3 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
193- else if (((invariantCalc(x, (amountTokenB - amountToSendStep4)) - invariant) > 0))
194- then ((amountToSendStep4 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
195- else if (((invariantCalc(x, (amountTokenB - amountToSendStep5)) - invariant) > 0))
196- then ((amountToSendStep5 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
222+ else if (((invariantCalc(x, (amountB - amountToSendStep1)) - invariant) > 0))
223+ then ((amountToSendStep1 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
224+ else if (((invariantCalc(x, (amountB - amountToSendStep2)) - invariant) > 0))
225+ then ((amountToSendStep2 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
226+ else if (((invariantCalc(x, (amountB - amountToSendStep3)) - invariant) > 0))
227+ then ((amountToSendStep3 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
228+ else if (((invariantCalc(x, (amountB - amountToSendStep4)) - invariant) > 0))
229+ then ((amountToSendStep4 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
230+ else if (((invariantCalc(x, (amountB - amountToSendStep5)) - invariant) > 0))
231+ then ((amountToSendStep5 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
197232 else throw("something went wrong while working with amountToSendStep. err2")
198233 }
199234
213248 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
214249
215250
251+func deductStakingFee (amount,assetId) = if ((assetId == USDN))
252+ then {
253+ let result = (amount - stakingFeeInUSDN)
254+ if ((0 >= result))
255+ then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakedAmountUSDN)) + " USD-N"))
256+ else result
257+ }
258+ else amount
259+
260+
261+func throwIsActive () = throw("DApp is already active")
262+
263+
264+func throwIsInactive () = throw("DApp is inactive at this moment")
265+
266+
267+func throwOnlyAdmin () = throw("Only admin can call this function")
268+
269+
270+func throwAssets () = throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
271+
272+
273+func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
274+
275+
276+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"))
277+
278+
279+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"))
280+
281+
282+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
283+
284+
216285 @Callable(i)
217286 func init () = {
218- let $t087088785 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
219- let pmtAmountA = $t087088785._1
220- let pmtAssetIdA = $t087088785._2
221- let $t087908867 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
222- let pmtAmountB = $t087908867._1
223- let pmtAssetIdB = $t087908867._2
224- let $t088728949 = getAssetInfo(pmtAssetIdA)
225- let pmtStrAssetIdA = $t088728949._1
226- let pmtAssetNameA = $t088728949._2
227- let pmtDecimalsA = $t088728949._3
228- let $t089549031 = getAssetInfo(pmtAssetIdB)
229- let pmtStrAssetIdB = $t089549031._1
230- let pmtAssetNameB = $t089549031._2
231- let pmtDecimalsB = $t089549031._3
287+ let $t01129611373 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
288+ let pmtAmountA = $t01129611373._1
289+ let pmtAssetIdA = $t01129611373._2
290+ let $t01137811455 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
291+ let pmtAmountB = $t01137811455._1
292+ let pmtAssetIdB = $t01137811455._2
293+ let $t01146011537 = getAssetInfo(pmtAssetIdA)
294+ let pmtStrAssetIdA = $t01146011537._1
295+ let pmtAssetNameA = $t01146011537._2
296+ let pmtDecimalsA = $t01146011537._3
297+ let $t01154211619 = getAssetInfo(pmtAssetIdB)
298+ let pmtStrAssetIdB = $t01154211619._1
299+ let pmtAssetNameB = $t01154211619._2
300+ let pmtDecimalsB = $t01154211619._3
232301 if (isDefined(getBoolean(this, keyActive)))
233- then throw("DApp is already active")
302+ then throwIsActive()
234303 else if ((pmtAssetIdA == pmtAssetIdB))
235304 then throw("Assets must be different")
236305 else {
241310 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
242311 let shareIssueId = calculateAssetId(shareIssue)
243312 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
244-[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyInvariant, invariantCalculated), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
313+[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyInvariant, invariantCalculated), IntegerEntry(keyCommission, commission), IntegerEntry(keyfeeScaleDelimiter, feeScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
245314 }
246315 }
247316
249318
250319 @Callable(i)
251320 func replenishWithTwoTokens (slippageTolerance) = {
252- let $t01113711214 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
253- let pmtAmountA = $t01113711214._1
254- let pmtAssetIdA = $t01113711214._2
255- let $t01121911413 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
256- let pmtAmountB = $t01121911413._1
257- let pmtAssetIdB = $t01121911413._2
321+ let pmtAssetIdA = i.payments[0].assetId
322+ let pmtAssetIdB = i.payments[1].assetId
323+ let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
324+ let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
258325 let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
259326 let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
260327 let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
261328 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
262329 let invariantCalculated = invariantCalc((balanceA + pmtAmountA), (balanceB + pmtAmountB))
263330 if (!(isActive))
264- then throw("DApp is inactive at this moment")
331+ then throwIsInactive()
265332 else if (if ((0 > slippageTolerance))
266333 then true
267334 else (slippageTolerance > slippageToleranceDelimiter))
271338 else if (if ((pmtAssetIdA != assetIdA))
272339 then true
273340 else (pmtAssetIdB != assetIdB))
274- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
341+ then throwAssets()
275342 else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
276343 then true
277344 else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
279346 else if ((shareTokenToPayAmount == 0))
280347 then throw("Too small amount to replenish")
281348 else if (!(hasEnoughBalance))
282- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
349+ then suspendSuspicious()
283350 else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
284351 }
285352
287354
288355 @Callable(i)
289356 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
290- let $t01376213837 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
291- let pmtAmount = $t01376213837._1
292- let pmtAssetId = $t01376213837._2
357+ let $t01613216207 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
358+ let pmtAmount = $t01613216207._1
359+ let pmtAssetId = $t01613216207._2
360+ let pmtMinThreshold = 5000000
293361 let thresholdValueForMinTolerance = 50000000
294362 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
295363 then 100000
298366 let slippageValueMaxForReplenish = (scaleValue8 + ((scaleValue8 * tolerance) / 10000000))
299367 let slippageValueMinForSwap = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
300368 let slippageValueMaxForSwap = (scaleValue8 + ((scaleValue8 * 1) / 10000000))
301- if ((1000 > pmtAmount))
302- then throw("The exchange amount does not exceed the minimum amount of 0.001")
303- else if (!(isActive))
304- then throw("DApp is inactive at this moment")
369+ if (!(isActive))
370+ then throwIsInactive()
371+ else if ((pmtMinThreshold > pmtAmount))
372+ then throw((((("Payment amount " + toString(pmtAmount)) + " does not exceed the minimum amount of ") + toString(pmtMinThreshold)) + " tokens"))
305373 else if ((size(i.payments) != 1))
306374 then throw("One attached payment expected")
307375 else if (!(hasEnoughBalance))
308- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
376+ then suspendSuspicious()
309377 else if ((pmtAssetId == assetIdA))
310378 then {
311379 let amountVirtualReplenishTokenA = (pmtAmount - virtualSwapTokenPay)
312380 let amountVirtualReplenishTokenB = virtualSwapTokenGet
313381 let balanceAfterVirtualSwapA = (balanceA + virtualSwapTokenPay)
314382 let balanceAfterVirtualSwapB = (balanceB - virtualSwapTokenGet)
315- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB))
383+ let invariantNew = invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB)
384+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
316385 if (if ((invariantEstimatedRatio > slippageValueMinForSwap))
317- then (scaleValue8 >= invariantEstimatedRatio)
386+ then ((invariantNew - invariant) > 0)
318387 else false)
319388 then {
320389 let ratioVirtualBalanceToVirtualReplenish = (fraction(balanceAfterVirtualSwapA, (scaleValue8 * scaleValue8), balanceAfterVirtualSwapB) / fraction(amountVirtualReplenishTokenA, scaleValue8, amountVirtualReplenishTokenB))
323392 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
324393 then throw("swop with virtualSwapTokenPay and virtualSwapTokenGet possible, but ratio after virtual swap incorrect")
325394 else {
326- let ratioShareTokensInA = fraction(amountVirtualReplenishTokenA, scaleValue8, balanceAfterVirtualSwapA)
327- let ratioShareTokensInB = fraction(amountVirtualReplenishTokenB, scaleValue8, balanceAfterVirtualSwapB)
395+ let ratioShareTokensInA = fraction(deductStakingFee(amountVirtualReplenishTokenA, assetIdA), scaleValue8, balanceAfterVirtualSwapA)
396+ let ratioShareTokensInB = fraction(deductStakingFee(amountVirtualReplenishTokenB, assetIdB), scaleValue8, balanceAfterVirtualSwapB)
328397 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
329398 let invariantCalculated = invariantCalc((balanceA + pmtAmount), balanceB)
330- let newAmountTokenA = (balanceA + pmtAmount)
331- let newAmountTokenB = balanceB
332- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
333- if (if ((dAppThresholdAmount > newAmountTokenA))
399+ let newBalanceA = (balanceA + pmtAmount)
400+ let newBalanceB = balanceB
401+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
402+ if (if ((dAppThresholdAmount > newBalanceA))
334403 then true
335- else (dAppThresholdAmount > newAmountTokenB))
336- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
337- else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyInvariant, invariantCalculated)]
404+ else (dAppThresholdAmount > newBalanceB))
405+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
406+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyInvariant, invariantCalculated)]
338407 }
339408 }
340409 else throw("incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
345414 let amountVirtualReplenishTokenA = virtualSwapTokenGet
346415 let balanceAfterVirtualSwapA = (balanceA - virtualSwapTokenGet)
347416 let balanceAfterVirtualSwapB = (balanceB + virtualSwapTokenPay)
348- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB))
417+ let invariantNew = invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB)
418+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
349419 if (if ((invariantEstimatedRatio > slippageValueMinForSwap))
350- then (scaleValue8 >= invariantEstimatedRatio)
420+ then ((invariantNew - invariant) > 0)
351421 else false)
352422 then {
353423 let ratioVirtualBalanceToVirtualReplenish = (fraction(balanceAfterVirtualSwapA, (scaleValue8 * scaleValue8), balanceAfterVirtualSwapB) / fraction(amountVirtualReplenishTokenA, scaleValue8, amountVirtualReplenishTokenB))
356426 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
357427 then throw("swop with virtualSwapTokenPay and virtualSwapTokenGet possible, but ratio after virtual swap incorrect")
358428 else {
359- let ratioShareTokensInA = fraction(amountVirtualReplenishTokenA, scaleValue8, balanceAfterVirtualSwapA)
360- let ratioShareTokensInB = fraction(amountVirtualReplenishTokenB, scaleValue8, balanceAfterVirtualSwapB)
429+ let ratioShareTokensInA = fraction(deductStakingFee(amountVirtualReplenishTokenA, assetIdA), scaleValue8, balanceAfterVirtualSwapA)
430+ let ratioShareTokensInB = fraction(deductStakingFee(amountVirtualReplenishTokenB, assetIdB), scaleValue8, balanceAfterVirtualSwapB)
361431 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
362432 let invariantCalculated = invariantCalc(balanceA, (balanceB + pmtAmount))
363- let newAmountTokenA = balanceA
364- let newAmountTokenB = (balanceB + pmtAmount)
365- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
366- if (if ((dAppThresholdAmount > newAmountTokenA))
433+ let newBalanceA = balanceA
434+ let newBalanceB = (balanceB + pmtAmount)
435+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
436+ if (if ((dAppThresholdAmount > newBalanceA))
367437 then true
368- else (dAppThresholdAmount > newAmountTokenB))
369- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
370- else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalculated)]
438+ else (dAppThresholdAmount > newBalanceB))
439+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
440+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalculated)]
371441 }
372442 }
373443 else throw("incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
374444 }
375- else throw("incorrect assets in payment")
445+ else throwAssets()
376446 }
377447
378448
379449
380450 @Callable(i)
381451 func withdraw () = {
382- let $t02059420669 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
383- let pmtAmount = $t02059420669._1
384- let pmtAssetId = $t02059420669._2
385- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
386- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
452+ let $t02256622716 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
453+ let pmtAmount = $t02256622716._1
454+ let pmtAssetId = $t02256622716._2
455+ let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
456+ let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
387457 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
388458 if (!(isActive))
389- then throw("DApp is inactive at this moment")
459+ then throwIsInactive()
390460 else if ((size(i.payments) != 1))
391461 then throw("One attached payment expected")
392462 else if ((pmtAssetId != shareAssetId))
393463 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
394464 else if (!(hasEnoughBalance))
395- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
396- else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(keyInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
465+ then suspendSuspicious()
466+ else if (if ((amountToPayA > availableBalanceA))
467+ then true
468+ else (amountToPayB > availableBalanceB))
469+ then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
470+ else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(keyInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
397471 }
398472
399473
400474
401475 @Callable(i)
402476 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
403- let $t02203422109 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
404- let pmtAmount = $t02203422109._1
405- let pmtAssetId = $t02203422109._2
477+ let $t02400724082 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
478+ let pmtAmount = $t02400724082._1
479+ let pmtAssetId = $t02400724082._2
406480 if (!(isActive))
407- then throw("DApp is inactive at this moment")
481+ then throwIsInactive()
408482 else if ((0 >= estimatedAmountToReceive))
409483 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
410484 else if ((minAmountToReceive > estimatedAmountToReceive))
412486 else if ((size(i.payments) != 1))
413487 then throw("One attached payment expected")
414488 else if (!(hasEnoughBalance))
415- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
489+ then suspendSuspicious()
416490 else if ((pmtAssetId == assetIdA))
417491 then {
418492 let assetIdSend = assetIdB
419493 let amountWithoutFee = calculateHowManySendTokenB(estimatedAmountToReceive, minAmountToReceive, balanceA, balanceB, pmtAmount)
420- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
421- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
422- let newAmountTokenA = (balanceA + pmtAmount)
423- let newAmountTokenB = ((balanceB - amountWithFee) - governanceReward)
424- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
425- if (if ((dAppThresholdAmount > newAmountTokenA))
494+ let amountWithFee = fraction(amountWithoutFee, (feeScaleDelimiter - commission), feeScaleDelimiter)
495+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, feeScaleDelimiter)
496+ let newBalanceA = (balanceA + pmtAmount)
497+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
498+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
499+ if (if ((dAppThresholdAmount > newBalanceA))
426500 then true
427- else (dAppThresholdAmount > newAmountTokenB))
428- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
429- else [IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalc((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
501+ else (dAppThresholdAmount > newBalanceB))
502+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
503+ else if (if (if ((assetIdA == USDN))
504+ then (stakedAmountUSDN >= newBalanceA)
505+ else false)
506+ then true
507+ else if ((assetIdB == USDN))
508+ then (stakedAmountUSDN >= newBalanceB)
509+ else false)
510+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
511+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalc((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
430512 }
431513 else if ((pmtAssetId == assetIdB))
432514 then {
433515 let assetIdSend = assetIdA
434516 let amountWithoutFee = calculateHowManySendTokenA(estimatedAmountToReceive, minAmountToReceive, balanceA, balanceB, pmtAmount)
435- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
436- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
437- let newAmountTokenA = ((balanceA - amountWithFee) - governanceReward)
438- let newAmountTokenB = (balanceB + pmtAmount)
439- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
440- if (if ((dAppThresholdAmount > newAmountTokenA))
517+ let amountWithFee = fraction(amountWithoutFee, (feeScaleDelimiter - commission), feeScaleDelimiter)
518+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, feeScaleDelimiter)
519+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
520+ let newBalanceB = (balanceB + pmtAmount)
521+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
522+ if (if ((dAppThresholdAmount > newBalanceA))
441523 then true
442- else (dAppThresholdAmount > newAmountTokenB))
443- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
444- else [IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalc(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
524+ else (dAppThresholdAmount > newBalanceB))
525+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
526+ else if (if (if ((assetIdA == USDN))
527+ then (stakedAmountUSDN >= newBalanceA)
528+ else false)
529+ then true
530+ else if ((assetIdB == USDN))
531+ then (stakedAmountUSDN >= newBalanceB)
532+ else false)
533+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
534+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalc(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
445535 }
446- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
536+ else throwAssets()
447537 }
448538
449539
450540
451541 @Callable(i)
452-func shutdown () = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKey4startStop], i.callerPublicKey))
453- then suspend("Paused by admin")
454- else throw("Only admin can call this function")
542+func shutdown () = if (!(isActive))
543+ then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
544+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
545+ then throwOnlyAdmin()
546+ else suspend("Paused by admin")
455547
456548
457549
458550 @Callable(i)
459-func activate () = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKey4startStop], i.callerPublicKey))
460- then [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
461- else throw("Only admin can call this function")
551+func activate () = if (isActive)
552+ then throwIsActive()
553+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
554+ then throwOnlyAdmin()
555+ else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
556+
557+
558+
559+@Callable(i)
560+func takeIntoAccountExtraFunds (amountLeave) = {
561+ let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
562+ let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
563+ let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == USDN))
564+ then amountLeave
565+ else 0))
566+ let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == USDN))
567+ then amountLeave
568+ else 0))
569+ if (!(isActive))
570+ then throwIsInactive()
571+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
572+ then throwOnlyAdmin()
573+ else if ((0 > amountLeave))
574+ then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
575+ else if (if ((0 > uncountableAmountEnrollAssetA))
576+ then true
577+ else (0 > uncountableAmountEnrollAssetB))
578+ then suspend("Enroll amount negative")
579+ else if (if ((0 > amountEnrollA))
580+ then true
581+ else (0 > amountEnrollB))
582+ then throw("Too large amountLeave")
583+ else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB))]
584+ }
462585
463586
464587 @Verifier(tx)
465-func verify () = {
466- let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
467- then 1
468- else 0
469- let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
470- then 1
471- else 0
472- let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
473- then 1
474- else 0
475- (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
476- }
588+func verify () = match tx {
589+ case invoke: InvokeScriptTransaction =>
590+ if (sigVerify(invoke.bodyBytes, invoke.proofs[0], adminPubKeyStaking))
591+ then (invoke.dApp == stakingAddress)
592+ else false
593+ case _ =>
594+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
595+ then 1
596+ else 0
597+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
598+ then 1
599+ else 0
600+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
601+ then 1
602+ else 0
603+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
604+}
477605
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "2.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 keyShareAssetId = "share_asset_id"
1919
2020 let keyShareAssetSupply = "share_asset_supply"
2121
2222 let keyCommission = "commission"
2323
24-let keyCommissionScaleDelimiter = "commission_scale_delimiter"
24+let keyfeeScaleDelimiter = "commission_scale_delimiter"
2525
2626 let keyCommissionGovernance = "commission_governance"
2727
2828 let keyInvariant = "invariant"
2929
3030 let keyCause = "shutdown_cause"
3131
3232 let adminPubKey1 = base58'DXDY2itiEcYBtGkVLnkpHtDFyWQUkoLJz79uJ7ECbMrA'
3333
3434 let adminPubKey2 = base58'E6Wa1SGoktYcjHjsKrvjMiqJY3SWmGKcD8Q5L8kxSPS7'
3535
3636 let adminPubKey3 = base58'AZmWJtuy4GeVrMmJH4hfFBRApe1StvhJSk4jcbT6bArQ'
3737
38-let adminPubKey4startStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
38+let adminPubKeyStartStop = base58'EtVkT6ed8GtbUiVVEqdmEqsp2J4qbb3rre2HFgxeVYdg'
39+
40+let adminPubKeyStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
3941
4042 let governanceAddress = Address(base58'3P6J84oH51DzY6xk2mT5TheXRbrCwBMxonp')
43+
44+let stakingAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ')
45+
46+let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
47+
48+let stakingFeeInUSDN = (9 * value(value(assetInfo(USDN)).minSponsoredFee))
4149
4250 let isActive = getBooleanValue(this, keyActive)
4351
4452 let strAssetIdA = getStringValue(this, keyAssetIdA)
4553
4654 let strAssetIdB = getStringValue(this, keyAssetIdB)
4755
4856 let assetIdA = if ((strAssetIdA == "WAVES"))
4957 then unit
5058 else fromBase58String(strAssetIdA)
5159
5260 let assetIdB = if ((strAssetIdB == "WAVES"))
5361 then unit
5462 else fromBase58String(strAssetIdB)
5563
5664 let assetNameA = match assetIdA {
5765 case id: ByteVector =>
5866 value(assetInfo(id)).name
5967 case waves: Unit =>
6068 "WAVES"
6169 case _ =>
6270 throw("Match error")
6371 }
6472
6573 let assetNameB = match assetIdB {
6674 case id: ByteVector =>
6775 value(assetInfo(id)).name
6876 case waves: Unit =>
6977 "WAVES"
7078 case _ =>
7179 throw("Match error")
7280 }
7381
7482 let balanceA = getIntegerValue(this, keyBalanceA)
7583
7684 let balanceB = getIntegerValue(this, keyBalanceB)
7785
7886 let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId))
7987
8088 let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply)
8189
8290 let invariant = getIntegerValue(this, keyInvariant)
8391
8492 let commission = 500
8593
8694 let commissionGovernance = 200
8795
88-let commissionScaleDelimiter = 1000000
96+let feeScaleDelimiter = 1000000
8997
9098 let scaleValue3 = 1000
9199
92100 let scaleValue8 = 100000000
93101
94102 let scaleValue12 = 1000000000000
95103
96104 let slippageToleranceDelimiter = 1000
97105
98106 let scaleValue8Digits = 8
99107
100108 let scaleValue12Digits = 12
101109
102110 let dAppThreshold = 50
103111
104112 let dAppThresholdDelimiter = 100
105113
106114 let ratioThresholdMax = 100000000
107115
108116 let ratioThresholdMin = 99999000
109117
110118 let alpha = 50
111119
112120 let alphaDigits = 2
113121
114122 let beta = 46000000
115123
116124 let betaDigits = 8
117125
118126 func accountBalance (assetId) = match assetId {
119127 case id: ByteVector =>
120128 assetBalance(this, id)
121129 case waves: Unit =>
122130 wavesBalance(this).available
123131 case _ =>
124132 throw("Match error")
125133 }
126134
127135
128-let hasEnoughBalance = if ((accountBalance(assetIdA) >= balanceA))
129- then (accountBalance(assetIdB) >= balanceB)
136+let stakedAmountUSDN = match getInteger(stakingAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))) {
137+ case staked: Int =>
138+ staked
139+ case nothing: Unit =>
140+ 0
141+ case _ =>
142+ throw("Match error")
143+}
144+
145+let availableBalanceA = (balanceA - (if ((assetIdA == USDN))
146+ then stakedAmountUSDN
147+ else 0))
148+
149+let availableBalanceB = (balanceB - (if ((assetIdB == USDN))
150+ then stakedAmountUSDN
151+ else 0))
152+
153+let accountBalanceWithStakedA = (accountBalance(assetIdA) + (if ((assetIdA == USDN))
154+ then stakedAmountUSDN
155+ else 0))
156+
157+let accountBalanceWithStakedB = (accountBalance(assetIdB) + (if ((assetIdB == USDN))
158+ then stakedAmountUSDN
159+ else 0))
160+
161+let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
162+ then (accountBalanceWithStakedB >= balanceB)
130163 else false
131164
132165 func skewness (x,y) = (((fraction(scaleValue12, x, y) + fraction(scaleValue12, y, x)) / 2) / 10000)
133166
134167
135168 func invariantCalc (x,y) = {
136169 let sk = skewness(x, y)
137170 (fraction((x + y), scaleValue8, pow(sk, scaleValue8Digits, alpha, alphaDigits, scaleValue8Digits, UP)) + (2 * fraction(pow(fraction(x, y, scaleValue8), 0, 5, 1, (scaleValue8Digits / 2), DOWN), pow((sk - beta), scaleValue8Digits, alpha, alphaDigits, scaleValue8Digits, DOWN), scaleValue8)))
138171 }
139172
140173
141-func calculateHowManySendTokenA (amountToSendEstimated,minTokenReceiveAmount,amountTokenA,amountTokenB,tokenReceiveAmount) = {
174+func calculateHowManySendTokenA (amountToSendEstimated,minTokenReceiveAmount,amountA,amountB,tokenReceiveAmount) = {
142175 let slippageValue = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
143- let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
144- let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaBetweenMaxAndMinSendValue) / 5))
145- let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaBetweenMaxAndMinSendValue) / 5))
146- let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaBetweenMaxAndMinSendValue) / 5))
147- let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaBetweenMaxAndMinSendValue) / 5))
148- let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaBetweenMaxAndMinSendValue) / 5))
149- let y = (amountTokenB + tokenReceiveAmount)
150- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc((amountTokenA - amountToSendEstimated), y))
151- if ((0 > (invariantCalc((amountTokenA - amountToSendStep5), y) - invariant)))
176+ let deltaMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
177+ let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaMaxAndMinSendValue) / 5))
178+ let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaMaxAndMinSendValue) / 5))
179+ let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaMaxAndMinSendValue) / 5))
180+ let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaMaxAndMinSendValue) / 5))
181+ let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaMaxAndMinSendValue) / 5))
182+ let y = (amountB + tokenReceiveAmount)
183+ let invariantNew = invariantCalc((amountA - amountToSendEstimated), y)
184+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
185+ if ((0 >= (invariantCalc((amountA - amountToSendStep5), y) - invariant)))
152186 then throw("minTokenReceiveAmount too large.err1")
153187 else if (if ((invariantEstimatedRatio > slippageValue))
154- then (scaleValue8 > invariantEstimatedRatio)
188+ then ((invariantNew - invariant) > 0)
155189 else false)
156190 then amountToSendEstimated
157- else if (((invariantCalc((amountTokenA - amountToSendStep1), y) - invariant) > 0))
158- then ((amountToSendStep1 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
159- else if (((invariantCalc((amountTokenA - amountToSendStep2), y) - invariant) > 0))
160- then ((amountToSendStep2 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
161- else if (((invariantCalc((amountTokenA - amountToSendStep3), y) - invariant) > 0))
162- then ((amountToSendStep3 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
163- else if (((invariantCalc((amountTokenA - amountToSendStep4), y) - invariant) > 0))
164- then ((amountToSendStep4 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
165- else if (((invariantCalc((amountTokenA - amountToSendStep5), y) - invariant) > 0))
166- then ((amountToSendStep5 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
191+ else if (((invariantCalc((amountA - amountToSendStep1), y) - invariant) > 0))
192+ then ((amountToSendStep1 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
193+ else if (((invariantCalc((amountA - amountToSendStep2), y) - invariant) > 0))
194+ then ((amountToSendStep2 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
195+ else if (((invariantCalc((amountA - amountToSendStep3), y) - invariant) > 0))
196+ then ((amountToSendStep3 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
197+ else if (((invariantCalc((amountA - amountToSendStep4), y) - invariant) > 0))
198+ then ((amountToSendStep4 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
199+ else if (((invariantCalc((amountA - amountToSendStep5), y) - invariant) > 0))
200+ then ((amountToSendStep5 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
167201 else throw("something went wrong while working with amountToSendStep. err2")
168202 }
169203
170204
171-func calculateHowManySendTokenB (amountToSendEstimated,minTokenReceiveAmount,amountTokenA,amountTokenB,tokenReceiveAmount) = {
205+func calculateHowManySendTokenB (amountToSendEstimated,minTokenReceiveAmount,amountA,amountB,tokenReceiveAmount) = {
172206 let slippageValue = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
173- let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
174- let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaBetweenMaxAndMinSendValue) / 5))
175- let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaBetweenMaxAndMinSendValue) / 5))
176- let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaBetweenMaxAndMinSendValue) / 5))
177- let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaBetweenMaxAndMinSendValue) / 5))
178- let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaBetweenMaxAndMinSendValue) / 5))
179- let x = (amountTokenA + tokenReceiveAmount)
180- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(x, (amountTokenB - amountToSendEstimated)))
181- if ((0 > (invariantCalc(x, (amountTokenB - amountToSendStep5)) - invariant)))
207+ let deltaMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
208+ let amountToSendStep1 = (amountToSendEstimated - ((1 * deltaMaxAndMinSendValue) / 5))
209+ let amountToSendStep2 = (amountToSendEstimated - ((2 * deltaMaxAndMinSendValue) / 5))
210+ let amountToSendStep3 = (amountToSendEstimated - ((3 * deltaMaxAndMinSendValue) / 5))
211+ let amountToSendStep4 = (amountToSendEstimated - ((4 * deltaMaxAndMinSendValue) / 5))
212+ let amountToSendStep5 = (amountToSendEstimated - ((5 * deltaMaxAndMinSendValue) / 5))
213+ let x = (amountA + tokenReceiveAmount)
214+ let invariantNew = invariantCalc(x, (amountB - amountToSendEstimated))
215+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
216+ if ((0 >= (invariantCalc(x, (amountB - amountToSendStep5)) - invariant)))
182217 then throw("minTokenReceiveAmount too large.err1")
183218 else if (if ((invariantEstimatedRatio > slippageValue))
184- then (scaleValue8 > invariantEstimatedRatio)
219+ then ((invariantNew - invariant) > 0)
185220 else false)
186221 then amountToSendEstimated
187- else if (((invariantCalc(x, (amountTokenB - amountToSendStep1)) - invariant) > 0))
188- then ((amountToSendStep1 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
189- else if (((invariantCalc(x, (amountTokenB - amountToSendStep2)) - invariant) > 0))
190- then ((amountToSendStep2 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
191- else if (((invariantCalc(x, (amountTokenB - amountToSendStep3)) - invariant) > 0))
192- then ((amountToSendStep3 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
193- else if (((invariantCalc(x, (amountTokenB - amountToSendStep4)) - invariant) > 0))
194- then ((amountToSendStep4 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
195- else if (((invariantCalc(x, (amountTokenB - amountToSendStep5)) - invariant) > 0))
196- then ((amountToSendStep5 * (commissionScaleDelimiter - commission)) / commissionScaleDelimiter)
222+ else if (((invariantCalc(x, (amountB - amountToSendStep1)) - invariant) > 0))
223+ then ((amountToSendStep1 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
224+ else if (((invariantCalc(x, (amountB - amountToSendStep2)) - invariant) > 0))
225+ then ((amountToSendStep2 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
226+ else if (((invariantCalc(x, (amountB - amountToSendStep3)) - invariant) > 0))
227+ then ((amountToSendStep3 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
228+ else if (((invariantCalc(x, (amountB - amountToSendStep4)) - invariant) > 0))
229+ then ((amountToSendStep4 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
230+ else if (((invariantCalc(x, (amountB - amountToSendStep5)) - invariant) > 0))
231+ then ((amountToSendStep5 * (feeScaleDelimiter - commission)) / feeScaleDelimiter)
197232 else throw("something went wrong while working with amountToSendStep. err2")
198233 }
199234
200235
201236 func getAssetInfo (assetId) = match assetId {
202237 case id: ByteVector =>
203238 let stringId = toBase58String(id)
204239 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
205240 $Tuple3(stringId, info.name, info.decimals)
206241 case waves: Unit =>
207242 $Tuple3("WAVES", "WAVES", 8)
208243 case _ =>
209244 throw("Match error")
210245 }
211246
212247
213248 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
214249
215250
251+func deductStakingFee (amount,assetId) = if ((assetId == USDN))
252+ then {
253+ let result = (amount - stakingFeeInUSDN)
254+ if ((0 >= result))
255+ then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakedAmountUSDN)) + " USD-N"))
256+ else result
257+ }
258+ else amount
259+
260+
261+func throwIsActive () = throw("DApp is already active")
262+
263+
264+func throwIsInactive () = throw("DApp is inactive at this moment")
265+
266+
267+func throwOnlyAdmin () = throw("Only admin can call this function")
268+
269+
270+func throwAssets () = throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
271+
272+
273+func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
274+
275+
276+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"))
277+
278+
279+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"))
280+
281+
282+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
283+
284+
216285 @Callable(i)
217286 func init () = {
218- let $t087088785 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
219- let pmtAmountA = $t087088785._1
220- let pmtAssetIdA = $t087088785._2
221- let $t087908867 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
222- let pmtAmountB = $t087908867._1
223- let pmtAssetIdB = $t087908867._2
224- let $t088728949 = getAssetInfo(pmtAssetIdA)
225- let pmtStrAssetIdA = $t088728949._1
226- let pmtAssetNameA = $t088728949._2
227- let pmtDecimalsA = $t088728949._3
228- let $t089549031 = getAssetInfo(pmtAssetIdB)
229- let pmtStrAssetIdB = $t089549031._1
230- let pmtAssetNameB = $t089549031._2
231- let pmtDecimalsB = $t089549031._3
287+ let $t01129611373 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
288+ let pmtAmountA = $t01129611373._1
289+ let pmtAssetIdA = $t01129611373._2
290+ let $t01137811455 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
291+ let pmtAmountB = $t01137811455._1
292+ let pmtAssetIdB = $t01137811455._2
293+ let $t01146011537 = getAssetInfo(pmtAssetIdA)
294+ let pmtStrAssetIdA = $t01146011537._1
295+ let pmtAssetNameA = $t01146011537._2
296+ let pmtDecimalsA = $t01146011537._3
297+ let $t01154211619 = getAssetInfo(pmtAssetIdB)
298+ let pmtStrAssetIdB = $t01154211619._1
299+ let pmtAssetNameB = $t01154211619._2
300+ let pmtDecimalsB = $t01154211619._3
232301 if (isDefined(getBoolean(this, keyActive)))
233- then throw("DApp is already active")
302+ then throwIsActive()
234303 else if ((pmtAssetIdA == pmtAssetIdB))
235304 then throw("Assets must be different")
236305 else {
237306 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
238307 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
239308 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
240309 let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, HALFDOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, HALFDOWN), pow(10, 0, shareDecimals, 0, 0, HALFDOWN))
241310 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
242311 let shareIssueId = calculateAssetId(shareIssue)
243312 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
244-[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyInvariant, invariantCalculated), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
313+[StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyInvariant, invariantCalculated), IntegerEntry(keyCommission, commission), IntegerEntry(keyfeeScaleDelimiter, feeScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
245314 }
246315 }
247316
248317
249318
250319 @Callable(i)
251320 func replenishWithTwoTokens (slippageTolerance) = {
252- let $t01113711214 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
253- let pmtAmountA = $t01113711214._1
254- let pmtAssetIdA = $t01113711214._2
255- let $t01121911413 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
256- let pmtAmountB = $t01121911413._1
257- let pmtAssetIdB = $t01121911413._2
321+ let pmtAssetIdA = i.payments[0].assetId
322+ let pmtAssetIdB = i.payments[1].assetId
323+ let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA)
324+ let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB)
258325 let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
259326 let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
260327 let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
261328 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
262329 let invariantCalculated = invariantCalc((balanceA + pmtAmountA), (balanceB + pmtAmountB))
263330 if (!(isActive))
264- then throw("DApp is inactive at this moment")
331+ then throwIsInactive()
265332 else if (if ((0 > slippageTolerance))
266333 then true
267334 else (slippageTolerance > slippageToleranceDelimiter))
268335 then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
269336 else if ((size(i.payments) != 2))
270337 then throw("Two attached assets expected")
271338 else if (if ((pmtAssetIdA != assetIdA))
272339 then true
273340 else (pmtAssetIdB != assetIdB))
274- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
341+ then throwAssets()
275342 else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
276343 then true
277344 else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
278345 then throw("Incorrect assets amount: amounts must have the contract ratio")
279346 else if ((shareTokenToPayAmount == 0))
280347 then throw("Too small amount to replenish")
281348 else if (!(hasEnoughBalance))
282- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
349+ then suspendSuspicious()
283350 else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyInvariant, invariantCalculated), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
284351 }
285352
286353
287354
288355 @Callable(i)
289356 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = {
290- let $t01376213837 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
291- let pmtAmount = $t01376213837._1
292- let pmtAssetId = $t01376213837._2
357+ let $t01613216207 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
358+ let pmtAmount = $t01613216207._1
359+ let pmtAssetId = $t01613216207._2
360+ let pmtMinThreshold = 5000000
293361 let thresholdValueForMinTolerance = 50000000
294362 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
295363 then 100000
296364 else 1
297365 let slippageValueMinForReplenish = (scaleValue8 - ((scaleValue8 * tolerance) / 10000000))
298366 let slippageValueMaxForReplenish = (scaleValue8 + ((scaleValue8 * tolerance) / 10000000))
299367 let slippageValueMinForSwap = (scaleValue8 - ((scaleValue8 * 1) / 10000000))
300368 let slippageValueMaxForSwap = (scaleValue8 + ((scaleValue8 * 1) / 10000000))
301- if ((1000 > pmtAmount))
302- then throw("The exchange amount does not exceed the minimum amount of 0.001")
303- else if (!(isActive))
304- then throw("DApp is inactive at this moment")
369+ if (!(isActive))
370+ then throwIsInactive()
371+ else if ((pmtMinThreshold > pmtAmount))
372+ then throw((((("Payment amount " + toString(pmtAmount)) + " does not exceed the minimum amount of ") + toString(pmtMinThreshold)) + " tokens"))
305373 else if ((size(i.payments) != 1))
306374 then throw("One attached payment expected")
307375 else if (!(hasEnoughBalance))
308- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
376+ then suspendSuspicious()
309377 else if ((pmtAssetId == assetIdA))
310378 then {
311379 let amountVirtualReplenishTokenA = (pmtAmount - virtualSwapTokenPay)
312380 let amountVirtualReplenishTokenB = virtualSwapTokenGet
313381 let balanceAfterVirtualSwapA = (balanceA + virtualSwapTokenPay)
314382 let balanceAfterVirtualSwapB = (balanceB - virtualSwapTokenGet)
315- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB))
383+ let invariantNew = invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB)
384+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
316385 if (if ((invariantEstimatedRatio > slippageValueMinForSwap))
317- then (scaleValue8 >= invariantEstimatedRatio)
386+ then ((invariantNew - invariant) > 0)
318387 else false)
319388 then {
320389 let ratioVirtualBalanceToVirtualReplenish = (fraction(balanceAfterVirtualSwapA, (scaleValue8 * scaleValue8), balanceAfterVirtualSwapB) / fraction(amountVirtualReplenishTokenA, scaleValue8, amountVirtualReplenishTokenB))
321390 if (if ((slippageValueMinForReplenish > ratioVirtualBalanceToVirtualReplenish))
322391 then true
323392 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
324393 then throw("swop with virtualSwapTokenPay and virtualSwapTokenGet possible, but ratio after virtual swap incorrect")
325394 else {
326- let ratioShareTokensInA = fraction(amountVirtualReplenishTokenA, scaleValue8, balanceAfterVirtualSwapA)
327- let ratioShareTokensInB = fraction(amountVirtualReplenishTokenB, scaleValue8, balanceAfterVirtualSwapB)
395+ let ratioShareTokensInA = fraction(deductStakingFee(amountVirtualReplenishTokenA, assetIdA), scaleValue8, balanceAfterVirtualSwapA)
396+ let ratioShareTokensInB = fraction(deductStakingFee(amountVirtualReplenishTokenB, assetIdB), scaleValue8, balanceAfterVirtualSwapB)
328397 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
329398 let invariantCalculated = invariantCalc((balanceA + pmtAmount), balanceB)
330- let newAmountTokenA = (balanceA + pmtAmount)
331- let newAmountTokenB = balanceB
332- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
333- if (if ((dAppThresholdAmount > newAmountTokenA))
399+ let newBalanceA = (balanceA + pmtAmount)
400+ let newBalanceB = balanceB
401+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
402+ if (if ((dAppThresholdAmount > newBalanceA))
334403 then true
335- else (dAppThresholdAmount > newAmountTokenB))
336- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
337- else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyInvariant, invariantCalculated)]
404+ else (dAppThresholdAmount > newBalanceB))
405+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
406+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyInvariant, invariantCalculated)]
338407 }
339408 }
340409 else throw("incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
341410 }
342411 else if ((pmtAssetId == assetIdB))
343412 then {
344413 let amountVirtualReplenishTokenB = (pmtAmount - virtualSwapTokenPay)
345414 let amountVirtualReplenishTokenA = virtualSwapTokenGet
346415 let balanceAfterVirtualSwapA = (balanceA - virtualSwapTokenGet)
347416 let balanceAfterVirtualSwapB = (balanceB + virtualSwapTokenPay)
348- let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB))
417+ let invariantNew = invariantCalc(balanceAfterVirtualSwapA, balanceAfterVirtualSwapB)
418+ let invariantEstimatedRatio = fraction(invariant, scaleValue8, invariantNew)
349419 if (if ((invariantEstimatedRatio > slippageValueMinForSwap))
350- then (scaleValue8 >= invariantEstimatedRatio)
420+ then ((invariantNew - invariant) > 0)
351421 else false)
352422 then {
353423 let ratioVirtualBalanceToVirtualReplenish = (fraction(balanceAfterVirtualSwapA, (scaleValue8 * scaleValue8), balanceAfterVirtualSwapB) / fraction(amountVirtualReplenishTokenA, scaleValue8, amountVirtualReplenishTokenB))
354424 if (if ((slippageValueMinForReplenish > ratioVirtualBalanceToVirtualReplenish))
355425 then true
356426 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
357427 then throw("swop with virtualSwapTokenPay and virtualSwapTokenGet possible, but ratio after virtual swap incorrect")
358428 else {
359- let ratioShareTokensInA = fraction(amountVirtualReplenishTokenA, scaleValue8, balanceAfterVirtualSwapA)
360- let ratioShareTokensInB = fraction(amountVirtualReplenishTokenB, scaleValue8, balanceAfterVirtualSwapB)
429+ let ratioShareTokensInA = fraction(deductStakingFee(amountVirtualReplenishTokenA, assetIdA), scaleValue8, balanceAfterVirtualSwapA)
430+ let ratioShareTokensInB = fraction(deductStakingFee(amountVirtualReplenishTokenB, assetIdB), scaleValue8, balanceAfterVirtualSwapB)
361431 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
362432 let invariantCalculated = invariantCalc(balanceA, (balanceB + pmtAmount))
363- let newAmountTokenA = balanceA
364- let newAmountTokenB = (balanceB + pmtAmount)
365- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
366- if (if ((dAppThresholdAmount > newAmountTokenA))
433+ let newBalanceA = balanceA
434+ let newBalanceB = (balanceB + pmtAmount)
435+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
436+ if (if ((dAppThresholdAmount > newBalanceA))
367437 then true
368- else (dAppThresholdAmount > newAmountTokenB))
369- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
370- else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalculated)]
438+ else (dAppThresholdAmount > newBalanceB))
439+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
440+ else [Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalculated)]
371441 }
372442 }
373443 else throw("incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
374444 }
375- else throw("incorrect assets in payment")
445+ else throwAssets()
376446 }
377447
378448
379449
380450 @Callable(i)
381451 func withdraw () = {
382- let $t02059420669 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
383- let pmtAmount = $t02059420669._1
384- let pmtAssetId = $t02059420669._2
385- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
386- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
452+ let $t02256622716 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
453+ let pmtAmount = $t02256622716._1
454+ let pmtAssetId = $t02256622716._2
455+ let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA)
456+ let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB)
387457 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
388458 if (!(isActive))
389- then throw("DApp is inactive at this moment")
459+ then throwIsInactive()
390460 else if ((size(i.payments) != 1))
391461 then throw("One attached payment expected")
392462 else if ((pmtAssetId != shareAssetId))
393463 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
394464 else if (!(hasEnoughBalance))
395- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
396- else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(keyInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
465+ then suspendSuspicious()
466+ else if (if ((amountToPayA > availableBalanceA))
467+ then true
468+ else (amountToPayB > availableBalanceB))
469+ then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
470+ else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(keyInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
397471 }
398472
399473
400474
401475 @Callable(i)
402476 func exchange (estimatedAmountToReceive,minAmountToReceive) = {
403- let $t02203422109 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
404- let pmtAmount = $t02203422109._1
405- let pmtAssetId = $t02203422109._2
477+ let $t02400724082 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
478+ let pmtAmount = $t02400724082._1
479+ let pmtAssetId = $t02400724082._2
406480 if (!(isActive))
407- then throw("DApp is inactive at this moment")
481+ then throwIsInactive()
408482 else if ((0 >= estimatedAmountToReceive))
409483 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
410484 else if ((minAmountToReceive > estimatedAmountToReceive))
411485 then throw(((("Minimal amount can't be greater than estimated. Estimated: " + toString(estimatedAmountToReceive)) + ". Minimal: ") + toString(minAmountToReceive)))
412486 else if ((size(i.payments) != 1))
413487 then throw("One attached payment expected")
414488 else if (!(hasEnoughBalance))
415- then suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
489+ then suspendSuspicious()
416490 else if ((pmtAssetId == assetIdA))
417491 then {
418492 let assetIdSend = assetIdB
419493 let amountWithoutFee = calculateHowManySendTokenB(estimatedAmountToReceive, minAmountToReceive, balanceA, balanceB, pmtAmount)
420- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
421- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
422- let newAmountTokenA = (balanceA + pmtAmount)
423- let newAmountTokenB = ((balanceB - amountWithFee) - governanceReward)
424- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
425- if (if ((dAppThresholdAmount > newAmountTokenA))
494+ let amountWithFee = fraction(amountWithoutFee, (feeScaleDelimiter - commission), feeScaleDelimiter)
495+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, feeScaleDelimiter)
496+ let newBalanceA = (balanceA + pmtAmount)
497+ let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
498+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
499+ if (if ((dAppThresholdAmount > newBalanceA))
426500 then true
427- else (dAppThresholdAmount > newAmountTokenB))
428- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
429- else [IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalc((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
501+ else (dAppThresholdAmount > newBalanceB))
502+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
503+ else if (if (if ((assetIdA == USDN))
504+ then (stakedAmountUSDN >= newBalanceA)
505+ else false)
506+ then true
507+ else if ((assetIdB == USDN))
508+ then (stakedAmountUSDN >= newBalanceB)
509+ else false)
510+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
511+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalc((balanceA + pmtAmount), ((balanceB - amountWithFee) - governanceReward))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
430512 }
431513 else if ((pmtAssetId == assetIdB))
432514 then {
433515 let assetIdSend = assetIdA
434516 let amountWithoutFee = calculateHowManySendTokenA(estimatedAmountToReceive, minAmountToReceive, balanceA, balanceB, pmtAmount)
435- let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
436- let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
437- let newAmountTokenA = ((balanceA - amountWithFee) - governanceReward)
438- let newAmountTokenB = (balanceB + pmtAmount)
439- let dAppThresholdAmount = fraction((newAmountTokenA + newAmountTokenB), dAppThreshold, (2 * dAppThresholdDelimiter))
440- if (if ((dAppThresholdAmount > newAmountTokenA))
517+ let amountWithFee = fraction(amountWithoutFee, (feeScaleDelimiter - commission), feeScaleDelimiter)
518+ let governanceReward = fraction(amountWithoutFee, commissionGovernance, feeScaleDelimiter)
519+ let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
520+ let newBalanceB = (balanceB + pmtAmount)
521+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdDelimiter))
522+ if (if ((dAppThresholdAmount > newBalanceA))
441523 then true
442- else (dAppThresholdAmount > newAmountTokenB))
443- then throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(dAppThresholdAmount)) + ". ") + assetNameA) + ": ") + toString(newAmountTokenA)) + ", ") + assetNameB) + ": ") + toString(newAmountTokenB)))
444- else [IntegerEntry(keyBalanceA, newAmountTokenA), IntegerEntry(keyBalanceB, newAmountTokenB), IntegerEntry(keyInvariant, invariantCalc(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
524+ else (dAppThresholdAmount > newBalanceB))
525+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
526+ else if (if (if ((assetIdA == USDN))
527+ then (stakedAmountUSDN >= newBalanceA)
528+ else false)
529+ then true
530+ else if ((assetIdB == USDN))
531+ then (stakedAmountUSDN >= newBalanceB)
532+ else false)
533+ then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
534+ else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), IntegerEntry(keyInvariant, invariantCalc(((balanceA - amountWithFee) - governanceReward), (balanceB + pmtAmount))), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(governanceAddress, governanceReward, assetIdSend)]
445535 }
446- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
536+ else throwAssets()
447537 }
448538
449539
450540
451541 @Callable(i)
452-func shutdown () = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKey4startStop], i.callerPublicKey))
453- then suspend("Paused by admin")
454- else throw("Only admin can call this function")
542+func shutdown () = if (!(isActive))
543+ then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
544+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
545+ then throwOnlyAdmin()
546+ else suspend("Paused by admin")
455547
456548
457549
458550 @Callable(i)
459-func activate () = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKey4startStop], i.callerPublicKey))
460- then [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
461- else throw("Only admin can call this function")
551+func activate () = if (isActive)
552+ then throwIsActive()
553+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
554+ then throwOnlyAdmin()
555+ else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
556+
557+
558+
559+@Callable(i)
560+func takeIntoAccountExtraFunds (amountLeave) = {
561+ let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
562+ let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
563+ let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == USDN))
564+ then amountLeave
565+ else 0))
566+ let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == USDN))
567+ then amountLeave
568+ else 0))
569+ if (!(isActive))
570+ then throwIsInactive()
571+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
572+ then throwOnlyAdmin()
573+ else if ((0 > amountLeave))
574+ then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
575+ else if (if ((0 > uncountableAmountEnrollAssetA))
576+ then true
577+ else (0 > uncountableAmountEnrollAssetB))
578+ then suspend("Enroll amount negative")
579+ else if (if ((0 > amountEnrollA))
580+ then true
581+ else (0 > amountEnrollB))
582+ then throw("Too large amountLeave")
583+ else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB))]
584+ }
462585
463586
464587 @Verifier(tx)
465-func verify () = {
466- let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
467- then 1
468- else 0
469- let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
470- then 1
471- else 0
472- let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
473- then 1
474- else 0
475- (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
476- }
588+func verify () = match tx {
589+ case invoke: InvokeScriptTransaction =>
590+ if (sigVerify(invoke.bodyBytes, invoke.proofs[0], adminPubKeyStaking))
591+ then (invoke.dApp == stakingAddress)
592+ else false
593+ case _ =>
594+ let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
595+ then 1
596+ else 0
597+ let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
598+ then 1
599+ else 0
600+ let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
601+ then 1
602+ else 0
603+ (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
604+}
477605

github/deemru/w8io/6500d08 
210.46 ms