tx · 2eoK9GQgWW5K2imh8paCwLr9nMsCQKbtXd2rCrUEzMBH

3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37:  -0.01400000 Waves

2021.08.06 16:41 [1646539] smart account 3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37 > SELF 0.00000000 Waves

{ "type": 13, "id": "2eoK9GQgWW5K2imh8paCwLr9nMsCQKbtXd2rCrUEzMBH", "fee": 1400000, "feeAssetId": null, "timestamp": 1628257313301, "version": 2, "chainId": 84, "sender": "3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37", "senderPublicKey": "4bwUHdA4vTBJ1k43dYKiPYTDqm3QqiZXNGXoQstGAD1k", "proofs": [ "4Z5KTSeD9pAjZwyjmzbYVL182iPvEDN9CfM2hwQsoAgjwMspq43S7cbCCjuG8ibu5rkv1KDcv3rJ3bMQ8xewu1tP", "4iqazUaGdrskgCwAYXXVseicLG3qrZVKimzoBjyu4TAvQGQxUNuG9JK7MTyuf1AsLKYikv1Sxk7gDyLvgxHH6wQm" ], "script": "base64:AAIFAAAAAAAAACMIAhIDCgEEEgMKAQESAwoBARIAEgMKAQESABIAEgMKAQESAAAAAFkAAAAAB3ZlcnNpb24CAAAABTEuMC4wAAAAAAprZXlWZXJzaW9uAgAAAAd2ZXJzaW9uAAAAAAlrZXlBY3RpdmUCAAAABmFjdGl2ZQAAAAALa2V5QXNzZXRJZEECAAAACkFfYXNzZXRfaWQAAAAAC2tleUFzc2V0SWRCAgAAAApCX2Fzc2V0X2lkAAAAAAtrZXlCYWxhbmNlQQIAAAAPQV9hc3NldF9iYWxhbmNlAAAAAAtrZXlCYWxhbmNlQgIAAAAPQl9hc3NldF9iYWxhbmNlAAAAAA9rZXlCYWxhbmNlSW5pdEECAAAADEFfYXNzZXRfaW5pdAAAAAAPa2V5QmFsYW5jZUluaXRCAgAAAAxCX2Fzc2V0X2luaXQAAAAAD2tleVNoYXJlQXNzZXRJZAIAAAAOc2hhcmVfYXNzZXRfaWQAAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkCAAAAEnNoYXJlX2Fzc2V0X3N1cHBseQAAAAANa2V5Q29tbWlzc2lvbgIAAAAKY29tbWlzc2lvbgAAAAAba2V5Q29tbWlzc2lvblNjYWxlRGVsaW1pdGVyAgAAABpjb21taXNzaW9uX3NjYWxlX2RlbGltaXRlcgAAAAAIa2V5Q2F1c2UCAAAADnNodXRkb3duX2NhdXNlAAAAAA9rZXlGaXJzdEhhcnZlc3QCAAAADWZpcnN0X2hhcnZlc3QAAAAAFWtleUZpcnN0SGFydmVzdEhlaWdodAIAAAAUZmlyc3RfaGFydmVzdF9oZWlnaHQAAAAAC2tTaGFyZUxpbWl0AgAAABxzaGFyZV9saW1pdF9vbl9maXJzdF9oYXJ2ZXN0AAAAAAtrQmFzZVBlcmlvZAIAAAALYmFzZV9wZXJpb2QAAAAADWtQZXJpb2RMZW5ndGgCAAAADXBlcmlvZF9sZW5ndGgAAAAADGtTdGFydEhlaWdodAIAAAAMc3RhcnRfaGVpZ2h0AAAAABNrRmlyc3RIYXJ2ZXN0SGVpZ2h0AgAAABRmaXJzdF9oYXJ2ZXN0X2hlaWdodAAAAAAWa2V5T3JhY2xlQXNzZXRQcmlvcml0eQIAAAAPYXNzZXRfcHJpb3JpdHlfAAAAABNrZXlPcmFjbGVTY3Jp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eHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAALa2V5QmFsYW5jZUEAAAAACGJhbGFuY2VCCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAAtrZXlCYWxhbmNlQgAAAAAMc2hhcmVBc3NldElkCQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAD2tleVNoYXJlQXNzZXRJZAAAAAAQc2hhcmVBc3NldFN1cHBseQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAATa2V5U2hhcmVBc3NldFN1cHBseQAAAAAKY29tbWlzc2lvbgAAAAAAAAALuAAAAAAUY29tbWlzc2lvbkdvdmVybmFuY2UAAAAAAAAABLAAAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgAAAAAAAA9CQAAAAAALc2NhbGVWYWx1ZTMAAAAAAAAAA+gAAAAAC3NjYWxlVmFsdWU4AAAAAAAF9eEAAAAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgAAAAAAAAAD6AAAAAARc2NhbGVWYWx1ZThEaWdpdHMAAAAAAAAAAAgAAAAAGWNvbWlzc2lvbkZvckluaXRhbGl6YXRpb24AAAAAADuaygABAAAADmFjY291bnRCYWxhbmNlAAAAAQAAAAdhc3NldElkBAAAAAckbWF0Y2gwBQAAAAdhc3NldElkAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJpZAUAAAAHJG1hdGNoMAkAA/AAAAACBQAAAAR0aGlzBQAAAAJpZAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAQAAAAFd2F2ZXMFAAAAByRtYXRjaDAICQAD7wAAAAEFAAAABHRoaXMAAAAJYXZhaWxhYmxlCQAAAgAAAAECAAAAC01hdGNoIGVycm9yAQAAAAxzdGFrZWRBbW91bnQAAAABAAAAB2Fzc2V0SWQEAAAAFnN0YWtlZEFtb3VudENhbGN1bGF0ZWQEAAAAByRtYXRjaDAFAAAAB2Fzc2V0SWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAA2FJZAUAAAAHJG1hdGNoMAMDCQAAAAAAAAIFAAAAA2FJZAUAAAAEVVNETgYJAAAAAAAAAgUAAAADYUlkBQAAAAROU0JUCQAEGgAAAAIFAAAAFnN0YWtpbmdVU0ROTlNCVEFkZHJlc3MJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAADHJwZF9iYWxhbmNlXwkAAlgAAAABBQAAAANhSWQCAAAAAV8JAAQlAAAAAQUAAAAEdGhpcwMJAAAAAAAAAgUAAAADYUlkBQAAAARFVVJOCQAEGgAAAAIFAAAAEnN0YWtpbmdFVVJOQWRkcmVzcwkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAYJXMlcyVzX19zdGFraW5nQmFsYW5jZV9fCQACWAAAAAEFAAAAA2FJZAIAAAACX18JAAQlAAAAAQUAAAAEdGhpcwAAAAAAAAAAAAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAAAAAAAAAAAAAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgQAAAAHJG1hdGNoMAUAAAAWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFpBQAAAAckbWF0Y2gwBQAAAAFpAAAAAAAAAAAAAQAAAA5pc0FsbG93ZWRBc3NldAAAAAEAAAAHYXNzZXRJZAQAAAAHJG1hdGNoMAUAAAAHYXNzZXRJZAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAKQnl0ZVZlY3RvcgQAAAACaWQFAAAAByRtYXRjaDADAwkAAAAAAAACBQAAAAJpZAUAAAAEVVNETgYJAAAAAAAAAgUAAAACaWQFAAAABFNXT1AGBwMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAQAAAAFd2F2ZXMFAAAAByRtYXRjaDAGCQAAAgAAAAECAAAAC01hdGNoIGVycm9yAAAAAA1zdGFrZWRBbW91bnRBCQEAAAAMc3Rha2VkQW1vdW50AAAAAQUAAAAIYXNzZXRJZEEAAAAADXN0YWtlZEFtb3VudEIJAQAAAAxzdGFrZWRBbW91bnQAAAABBQAAAAhhc3NldElkQgAAAAAKYXNzZXRJbml0QQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAAPa2V5QmFsYW5jZUluaXRBAAAAAAphc3NldEluaXRCCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAA9rZXlCYWxhbmNlSW5pdEIAAAAAEWF2YWlsYWJsZUJhbGFuY2VBCQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAAA1zdGFrZWRBbW91bnRBAAAAABFhdmFpbGFibGVCYWxhbmNlQgkAAGUAAAACBQAAAAhiYWxhbmNlQgUAAAANc3Rha2VkQW1vdW50QgAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQQUAAAANc3Rha2VkQW1vdW50QQAAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgkAAGQAAAACCQEAAAAOYWNjb3VudEJhbGFuY2UAAAABBQAAAAhhc3NldElkQgUAAAANc3Rha2VkQW1vdW50QgAAAAAQaGFzRW5vdWdoQmFsYW5jZQMJAABnAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQQUAAAAIYmFsYW5jZUEJAABnAAAAAgUAAAAZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQgUAAAAIYmFsYW5jZUIHAQAAAAxnZXRBc3NldEluZm8AAAABAAAAB2Fzc2V0SWQEAAAAByRtYXRjaDAFAAAAB2Fzc2V0SWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAmlkBQAAAAckbWF0Y2gwBAAAAAhzdHJpbmdJZAkAAlgAAAABBQAAAAJpZAQAAAAEaW5mbwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAD7AAAAAEFAAAAAmlkCQABLAAAAAIJAAEsAAAAAgIAAAAGQXNzZXQgBQAAAAhzdHJpbmdJZAIAAAAOIGRvZXNuJ3QgZXhpc3QJAAUVAAAAAwUAAAAIc3RyaW5nSWQIBQAAAARpbmZvAAAABG5hbWUIBQAAAARpbmZvAAAACGRlY2ltYWxzAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0BAAAAAV3YXZlcwUAAAAHJG1hdGNoMAkABRUAAAADAgAA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AAAAAgIAAAAWa2V5T3JhY2xlQXNzZXRQcmlvcml0eQUAAAAOcG10U3RyQXNzZXRJZDEAAAAAAAAPQj8EAAAADmFzc2V0MlByaW9yaXR5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkAASwAAAACAgAAABZrZXlPcmFjbGVBc3NldFByaW9yaXR5BQAAAA5wbXRTdHJBc3NldElkMgAAAAAAAA9CPwQAAAAMJHQwOTkzMzEwMTYwAwkAAGYAAAACBQAAAA5hc3NldDJQcmlvcml0eQUAAAAOYXNzZXQxUHJpb3JpdHkJAAUWAAAABAUAAAAKcG10QW1vdW50MgUAAAALcG10QXNzZXRJZDIFAAAACnBtdEFtb3VudDEFAAAAC3BtdEFzc2V0SWQxCQAFFgAAAAQFAAAACnBtdEFtb3VudDEFAAAAC3BtdEFzc2V0SWQxBQAAAApwbXRBbW91bnQyBQAAAAtwbXRBc3NldElkMgQAAAAKcG10QW1vdW50QQgFAAAADCR0MDk5MzMxMDE2MAAAAAJfMQQAAAALcG10QXNzZXRJZEEIBQAAAAwkdDA5OTMzMTAxNjAAAAACXzIEAAAACnBtdEFtb3VudEIIBQAAAAwkdDA5OTMzMTAxNjAAAAACXzMEAAAAC3BtdEFzc2V0SWRCCAUAAAAMJHQwOTkzMzEwMTYwAAAAAl80BAAAAA0kdDAxMDE2OTEwMjQ2CQEAAAAMZ2V0QXNzZXRJbmZvAAAAAQUAAAALcG10QXNzZXRJZEEEAAAADnBtdFN0ckFzc2V0SWRBCAUAAAANJHQwMTAxNjkxMDI0NgAAAAJfMQQAAAANcG10QXNzZXROYW1lQQgFAAAADSR0MDEwMTY5MTAyNDYAAAACXzIEAAAADHBtdERlY2ltYWxzQQgFAAAADSR0MDEwMTY5MTAyNDYAAAACXzMEAAAADSR0MDEwMjU1MTAzMzIJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtwbXRBc3NldElkQgQAAAAOcG10U3RyQXNzZXRJZEIIBQAAAA0kdDAxMDI1NTEwMzMyAAAAAl8xBAAAAA1wbXRBc3NldE5hbWVCCAUAAAANJHQwMTAyNTUxMDMzMgAAAAJfMgQAAAAMcG10RGVjaW1hbHNCCAUAAAANJHQwMTAyNTUxMDMzMgAAAAJfMwQAAAAHYWRkUG9vbAkAA/wAAAAEBQAAAAZvcmFjbGUCAAAAB2FkZFBvb2wJAARMAAAAAgUAAAAEdGhpcwkABEwAAAACCQABLAAAAAIJAAEsAAAAAgUAAAANcG10QXNzZXROYW1lQQIAAAABXwUAAAANcG10QXNzZXROYW1lQgUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAB2FkZFBvb2wFAAAAB2FkZFBvb2wDCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABCQAEHQAAAAIFAAAABm9yYWNsZQkAASwAAAACAgAAAAVwb29sXwkABCUAAAABBQAAAAR0aGlzCQAAAgAAAAECAAAAEVBvb2wgaXMgbm90IGFkZGVkBAAAAAlzaGFyZU5hbWUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAAXMJAAEvAAAAAgUAAAANcG10QXNzZXROYW1lQQAAAAAAAAAABwIAAAABXwkAAS8AAAACBQAAAA1wbXRBc3NldE5hbWVCAAAAAAAAAAAHBAAAABBzaGFyZURlc2NyaXB0aW9uCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAiU2hhcmVUb2tlbiBvZiBTd29wRmkgcHJvdG9jb2wgZm9yIAUAAAANcG10QXNzZXROYW1lQQIAAAAFIGFuZCAFAAAADXBtdEFzc2V0TmFtZUICAAAADCBhdCBhZGRyZXNzIAkABCUAAAABBQAAAAR0aGlzBAAAAA1zaGFyZURlY2ltYWxzCQAAaQAAAAIJAABkAAAAAgUAAAAMcG10RGVjaW1hbHNBBQAAAAxwbXREZWNpbWFsc0IAAAAAAAAAAAIEAAAABGFyZzEJAABsAAAABgUAAAAKcG10QW1vdW50QQUAAAAMcG10RGVjaW1hbHNBAAAAAAAAAAAFAAAAAAAAAAABBQAAAAxwbXREZWNpbWFsc0EFAAAABERPV04EAAAABGFyZzIJAABsAAAABgUAAAAKcG10QW1vdW50QgUAAAAMcG10RGVjaW1hbHNCAAAAAAAAAAAFAAAAAAAAAAABBQAAAAxwbXREZWNpbWFsc0IFAAAABERPV04EAAAABGFyZzMJAABsAAAABgAAAAAAAAAACgAAAAAAAAAAAAUAAAANc2hhcmVEZWNpbWFscwAAAAAAAAAAAAAAAAAAAAAAAAUAAAAERE9XTgQAAAASc2hhcmVJbml0aWFsU3VwcGx5CQAAawAAAAMFAAAABGFyZzEFAAAABGFyZzIFAAAABGFyZzMEAAAACnNoYXJlSXNzdWUJAARCAAAABQUAAAAJc2hhcmVOYW1lBQAAABBzaGFyZURlc2NyaXB0aW9uBQAAABJzaGFyZUluaXRpYWxTdXBwbHkFAAAADXNoYXJlRGVjaW1hbHMGBAAAAAxzaGFyZUlzc3VlSWQJAAQ4AAAAAQUAAAAKc2hhcmVJc3N1ZQQAAAAJYmFzZUVudHJ5CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAACmtleVZlcnNpb24FAAAAB3ZlcnNpb24JAARMAAAAAgkBAAAADEJvb2xlYW5FbnRyeQAAAAIFAAAACWtleUFjdGl2ZQYJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAALa2V5QXNzZXRJZEEFAAAADnBtdFN0ckFzc2V0SWRBCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAC2tleUFzc2V0SWRCBQAAAA5wbXRTdHJBc3NldElkQgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAACnBtdEFtb3VudEEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAApwbXRBbW91bnRCCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1rZXlDb21taXNzaW9uBQAAAApjb21taXNzaW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABtrZXlDb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIFAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgkABEwAAAACBQAAAApzaGFyZUlzc3VlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAD2tleVNoYXJlQXNzZXRJZAkAAlgAAAABBQAAAAxzaGFyZUlzc3VlSWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa2V5SW5pdFBvb2xIZWlnaHQFAAAABmhlaWdodAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAA13YWxsZXRBZGRyZXNzBQAAABJzaGFyZUluaXRpYWxTdXBwbHkFAAAADHNoYXJlSXNzdWVJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAGWNvbWlzc2lvbkZvckluaXRhbGl6YXRpb24FAAAABFNXT1AFAAAAA25pbAUAAAAJYmFzZUVudHJ5CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAABhrZWVwTGltaXRGb3JGaXJzdEhhcnZlc3QAAAABAAAACnNoYXJlTGltaXQDCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDCQEAAAABIQAAAAEJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzCQAETAAAAAIFAAAAEmFkbWluUHViS2V5U3Rha2luZwUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAAACAAAAAQIAAAAhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrU2hhcmVMaW1pdAUAAAAKc2hhcmVMaW1pdAUAAAADbmlsAAAAAWkBAAAAFnJlcGxlbmlzaFdpdGhUd29Ub2tlbnMAAAABAAAAEXNsaXBwYWdlVG9sZXJhbmNlBAAAAAtwbXRBc3NldElkQQgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAQAAAALcG10QXNzZXRJZEIICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABAAAAB2Fzc2V0SWQEAAAACnBtdEFtb3VudEEJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAwgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50BQAAAAtwbXRBc3NldElkQQUAAAALcG10QXNzZXRJZEIEAAAACnBtdEFtb3VudEIJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAwgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEAAAAGYW1vdW50BQAAAAtwbXRBc3NldElkQgUAAAALcG10QXNzZXRJZEEDAwkAAAAAAAACBQAAAAhiYWxhbmNlQQAAAAAAAAAAAAkAAAAAAAACBQAAAAhiYWxhbmNlQgAAAAAAAAAAAAcEAAAADSR0MDEzMTIwMTMxOTcJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAtwbXRBc3NldElkQQQAAAAOcG10U3RyQXNzZXRJZEEIBQAAAA0kdDAxMzEyMDEzMTk3AAAAAl8xBAAAAA1wbXRBc3NldE5hbWVBCAUAAAANJHQwMTMxMjAxMzE5NwAAAAJfMgQAAAAMcG10RGVjaW1hbHNBCAUAAAANJHQwMTMxMjAxMzE5NwAAAAJfMwQAAAANJHQwMTMyMDYxMzI4MwkBAAAADGdldEFzc2V0SW5mbwAAAAEFAAAAC3BtdEFzc2V0SWRCBAAAAA5wbXRTdHJBc3NldElkQggFAAAADSR0MDEzMjA2MTMyODMAAAACXzEEAAAADXBtdEFzc2V0TmFtZUIIBQAAAA0kdDAxMzIwNjEzMjgzAAAAAl8yBAAAAAxwbXREZWNpbWFsc0IIBQAAAA0kdDAxMzIwNjEzMjgzAAAAAl8zBAAAAAp0b2tlblJhdGlvCQAAawAAAAMJAABrAAAAAwUAAAAKYXNzZXRJbml0QQUAAAALc2NhbGVWYWx1ZTgFAAAACnBtdEFtb3VudEEFAAAAC3NjYWxlVmFsdWUzCQAAawAAAAMFAAAACmFzc2V0SW5pdEIFAAAAC3NjYWxlVmFsdWU4BQAAAApwbXRBbW91bnRCAwkAAAAAAAACBQAAAAtwbXRBc3NldElkQQUAAAALcG10QXNzZXRJZEIJAAACAAAAAQIAAAAYQXNzZXRzIG11c3QgYmUgZGlmZmVyZW50BAAAAA1zaGFyZURlY2ltYWxzCQAAaQAAAAIJAABkAAAAAgUAAAAMcG10RGVjaW1hbHNBBQAAAAxwbXREZWNpbWFsc0IAAAAAAAAAAAIEAAAAEnNoYXJlSW5pdGlhbFN1cHBseQkAAGsAAAADCQAAbAAAAAYFAAAACnBtdEFtb3VudEEFAAAADHBtdERlY2ltYWxzQQAAAAAAAAAABQAAAAAAAAAAAQUAAAAMcG10RGVjaW1hbHNBBQAAAARET1dOCQAAbAAAAAYFAAAACnBtdEFtb3VudEIFAAAADHBtdERlY2ltYWxzQgAAAAAAAAAABQAAAAAAAAAAAQUAAAAMcG10RGVjaW1hbHNCBQAAAARET1dOCQAAbAAAAAYAAAAAAAAAAAoAAAAAAAAAAAAFAAAADXNoYXJlRGVjaW1hbHMAAAAAAAAAAAAAAAAAAAAAAAAFAAAABERPV04DCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDAwkAAGYAAAACAAAAAAAAAAAABQAAABFzbGlwcGFnZVRvbGVyYW5jZQYJAABmAAAAAgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAKVNsaXBwYWdlIHRvbGVyYW5jZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgCQABpAAAAAEFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyAgAAABYgaW5jbHVzaXZlbHkuIEFjdHVhbDogCQABpAAAAAEFAAAAEXNsaXBwYWdlVG9sZXJhbmNlAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAgkAAAIAAAABAgAAABxUd28gYXR0YWNoZWQgYXNzZXRzIGV4cGVjdGVkAwMJAABmAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWUzCQAAZQAAAAIFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAACnRva2VuUmF0aW8GCQAAZgAAAAIFAAAACnRva2VuUmF0aW8JAABpAAAAAgkAAGgAAAACBQAAAAtzY2FsZVZhbHVlMwkAAGQAAAACBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyCQAAAgAAAAECAAAAPUluY29ycmVjdCBhc3NldHMgYW1vdW50OiBhbW91bnRzIG11c3QgaGF2ZSB0aGUgY29udHJhY3QgcmF0aW8DAwkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEEFAAAACGFzc2V0SWRBBgkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEIFAAAACGFzc2V0SWRCCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJUluY29ycmVjdCBhc3NldHMgYXR0YWNoZWQuIEV4cGVjdGVkOiAFAAAAC3N0ckFzc2V0SWRBAgAAAAUgYW5kIAUAAAALc3RyQXNzZXRJZEIDCQAAAAAAAAIFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQAAAAAAAAAAAAkAAAIAAAABAgAAAB1Ub28gc21hbGwgYW1vdW50IHRvIHJlcGxlbmlzaAMJAQAAAAEhAAAAAQUAAAAQaGFzRW5vdWdoQmFsYW5jZQkABE4AAAACCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAKcG10QW1vdW50QQUAAAALcG10QXNzZXRJZEEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAApwbXRBbW91bnRCBQAAAAtwbXRBc3NldElkQgUAAAADbmlsCQEAAAARc3VzcGVuZFN1c3BpY2lvdXMAAAAACQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAMc2hhcmVBc3NldElkBQAAABJzaGFyZUluaXRpYWxTdXBwbHkGCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAAKcG10QW1vdW50QQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIFAAAACnBtdEFtb3VudEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAEnNoYXJlSW5pdGlhbFN1cHBseQUAAAAMc2hhcmVBc3NldElkBQAAAANuaWwEAAAACnRva2VuUmF0aW8JAABrAAAAAwkAAGsAAAADBQAAAAhiYWxhbmNlQQUAAAALc2NhbGVWYWx1ZTgFAAAACnBtdEFtb3VudEEFAAAAC3NjYWxlVmFsdWUzCQAAawAAAAMFAAAACGJhbGFuY2VCBQAAAAtzY2FsZVZhbHVlOAUAAAAKcG10QW1vdW50QgQAAAATcmF0aW9TaGFyZVRva2Vuc0luQQkAAGsAAAADBQAAAApwbXRBbW91bnRBBQAAAAtzY2FsZVZhbHVlOAUAAAAIYmFsYW5jZUEEAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkIJAABrAAAAAwUAAAAKcG10QW1vdW50QgUAAAALc2NhbGVWYWx1ZTgFAAAACGJhbGFuY2VCBAAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQJAABrAAAAAwkAAZcAAAABCQAETAAAAAIFAAAAE3JhdGlvU2hhcmVUb2tlbnNJbkEJAARMAAAAAgUAAAATcmF0aW9TaGFyZVRva2Vuc0luQgUAAAADbmlsBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAtzY2FsZVZhbHVlOAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAAACAAAAAQIAAAAfREFwcCBpcyBpbmFjdGl2ZSBhdCB0aGlzIG1vbWVudAMDCQAAZgAAAAIAAAAAAAAAAAAFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBgkAAGYAAAACBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAApU2xpcHBhZ2UgdG9sZXJhbmNlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAJAAGkAAAAAQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXICAAAAFiBpbmNsdXNpdmVseS4gQWN0dWFsOiAJAAGkAAAAAQUAAAARc2xpcHBhZ2VUb2xlcmFuY2UDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAACCQAAAgAAAAECAAAAHFR3byBhdHRhY2hlZCBhc3NldHMgZXhwZWN0ZWQDAwkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEEFAAAACGFzc2V0SWRBBgkBAAAAAiE9AAAAAgUAAAALcG10QXNzZXRJZEIFAAAACGFzc2V0SWRCCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJUluY29ycmVjdCBhc3NldHMgYXR0YWNoZWQuIEV4cGVjdGVkOiAFAAAAC3N0ckFzc2V0SWRBAgAAAAUgYW5kIAUAAAALc3RyQXNzZXRJZEIDAwkAAGYAAAACCQAAaQAAAAIJAABoAAAAAgUAAAALc2NhbGVWYWx1ZTMJAABlAAAAAgUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABpzbGlwcGFnZVRvbGVyYW5jZURlbGltaXRlcgUAAAAKdG9rZW5SYXRpbwYJAABmAAAAAgUAAAAKdG9rZW5SYXRpbwkAAGkAAAACCQAAaAAAAAIFAAAAC3NjYWxlVmFsdWUzCQAAZAAAAAIFAAAAGnNsaXBwYWdlVG9sZXJhbmNlRGVsaW1pdGVyBQAAABFzbGlwcGFnZVRvbGVyYW5jZQUAAAAac2xpcHBhZ2VUb2xlcmFuY2VEZWxpbWl0ZXIJAAACAAAAAQIAAAA9SW5jb3JyZWN0IGFzc2V0cyBhbW91bnQ6IGFtb3VudHMgbXVzdCBoYXZlIHRoZSBjb250cmFjdCByYXRpbwMJAAAAAAAAAgUAAAAVc2hhcmVUb2tlblRvUGF5QW1vdW50AAAAAAAAAAAACQAAAgAAAAECAAAAHVRvbyBzbWFsbCBhbW91bnQgdG8gcmVwbGVuaXNoAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAApwbXRBbW91bnRBBQAAAAtwbXRBc3NldElkQQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACnBtdEFtb3VudEIFAAAAC3BtdEFzc2V0SWRCBQAAAANuaWwJAQAAABFzdXNwZW5kU3VzcGljaW91cwAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAApwbXRBbW91bnRBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQgkAAGQAAAACBQAAAAhiYWxhbmNlQgUAAAAKcG10QW1vdW50QgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAATa2V5U2hhcmVBc3NldFN1cHBseQkAAGQAAAACBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQJAARMAAAAAgkBAAAAB1JlaXNzdWUAAAADBQAAAAxzaGFyZUFzc2V0SWQFAAAAFXNoYXJlVG9rZW5Ub1BheUFtb3VudAYJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAABVzaGFyZVRva2VuVG9QYXlBbW91bnQFAAAADHNoYXJlQXNzZXRJZAUAAAADbmlsAAAAAWkBAAAACHdpdGhkcmF3AAAAAAQAAAANJHQwMTc2ODIxNzgzMgkABRQAAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQEAAAACXBtdEFtb3VudAgFAAAADSR0MDE3NjgyMTc4MzIAAAACXzEEAAAACnBtdEFzc2V0SWQIBQAAAA0kdDAxNzY4MjE3ODMyAAAAAl8yBAAAAAxhbW91bnRUb1BheUEJAQAAABBkZWR1Y3RTdGFraW5nRmVlAAAAAwkAAGsAAAADBQAAAAlwbXRBbW91bnQFAAAACGJhbGFuY2VBBQAAABBzaGFyZUFzc2V0U3VwcGx5BQAAAAhhc3NldElkQQUAAAAIYXNzZXRJZEIEAAAADGFtb3VudFRvUGF5QgkBAAAAEGRlZHVjdFN0YWtpbmdGZWUAAAADCQAAawAAAAMFAAAACXBtdEFtb3VudAUAAAAIYmFsYW5jZUIFAAAAEHNoYXJlQXNzZXRTdXBwbHkFAAAACGFzc2V0SWRCBQAAAAhhc3NldElkQQMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAAACAAAAAQIAAAAfREFwcCBpcyBpbmFjdGl2ZSBhdCB0aGlzIG1vbWVudAMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAdT25lIGF0dGFjaGVkIHBheW1lbnQgZXhwZWN0ZWQDCQEAAAACIT0AAAACBQAAAApwbXRBc3NldElkBQAAAAxzaGFyZUFzc2V0SWQJAAACAAAAAQkAASwAAAACAgAAACRJbmNvcnJlY3QgYXNzZXQgYXR0YWNoZWQuIEV4cGVjdGVkOiAJAAJYAAAAAQUAAAAMc2hhcmVBc3NldElkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAlwbXRBbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAMDCQAAZgAAAAIFAAAADGFtb3VudFRvUGF5QQUAAAARYXZhaWxhYmxlQmFsYW5jZUEGCQAAZgAAAAIFAAAADGFtb3VudFRvUGF5QgUAAAARYXZhaWxhYmxlQmFsYW5jZUIJAQAAACJ0aHJvd0luc3VmZmljaWVudEF2YWlsYWJsZUJhbGFuY2VzAAAAAgUAAAAMYW1vdW50VG9QYXlBBQAAAAxhbW91bnRUb1BheUIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VBCQAAZQAAAAIFAAAACGJhbGFuY2VBBQAAAAxhbW91bnRUb1BheUEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCCQAAZQAAAAIFAAAACGJhbGFuY2VCBQAAAAxhbW91bnRUb1BheUIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tleVNoYXJlQXNzZXRTdXBwbHkJAABlAAAAAgUAAAAQc2hhcmVBc3NldFN1cHBseQUAAAAJcG10QW1vdW50CQAETAAAAAIJAQAAAARCdXJuAAAAAgUAAAAMc2hhcmVBc3NldElkBQAAAAlwbXRBbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAxhbW91bnRUb1BheUEFAAAACGFzc2V0SWRBCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAMYW1vdW50VG9QYXlCBQAAAAhhc3NldElkQgUAAAADbmlsAAAAAWkBAAAACGV4Y2hhbmdlAAAAAQAAABJtaW5BbW91bnRUb1JlY2VpdmUEAAAADSR0MDE5MDU4MTkxMzMJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAA0kdDAxOTA1ODE5MTMzAAAAAl8xBAAAAApwbXRBc3NldElkCAUAAAANJHQwMTkwNTgxOTEzMwAAAAJfMgoBAAAADWNhbGN1bGF0ZUZlZXMAAAACAAAACXRva2VuRnJvbQAAAAd0b2tlblRvBAAAABBhbW91bnRXaXRob3V0RmVlCQAAawAAAAMFAAAAB3Rva2VuVG8FAAAACXBtdEFtb3VudAkAAGQAAAACBQAAAAlwbXRBbW91bnQFAAAACXRva2VuRnJvbQQAAAANYW1vdW50V2l0aEZlZQkAAGsAAAADBQAAABBhbW91bnRXaXRob3V0RmVlCQAAZQAAAAIFAAAAGGNvbW1pc3Npb25TY2FsZURlbGltaXRlcgUAAAAKY29tbWlzc2lvbgUAAAAYY29tbWlzc2lvblNjYWxlRGVsaW1pdGVyBAAAABBnb3Zlcm5hbmNlUmV3YXJkCQAAawAAAAMFAAAAEGFtb3VudFdpdGhvdXRGZWUFAAAAFGNvbW1pc3Npb25Hb3Zlcm5hbmNlBQAAABhjb21taXNzaW9uU2NhbGVEZWxpbWl0ZXIDCQAAZgAAAAIFAAAAEm1pbkFtb3VudFRvUmVjZWl2ZQUAAAANYW1vdW50V2l0aEZlZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAB1DYWxjdWxhdGVkIGFtb3VudCB0byByZWNlaXZlIAkAAaQAAAABBQAAAA1hbW91bnRXaXRoRmVlAgAAACAgaXMgbGVzcyB0aGFuIHNwZWNpZmllZCBtaW5pbXVtIAkAAaQAAAABBQAAABJtaW5BbW91bnRUb1JlY2VpdmUJAAUVAAAAAwUAAAAQYW1vdW50V2l0aG91dEZlZQUAAAANYW1vdW50V2l0aEZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAAACAAAAAQIAAAAfREFwcCBpcyBpbmFjdGl2ZSBhdCB0aGlzIG1vbWVudAMDCQAAAAAAAAIFAAAACGJhbGFuY2VBAAAAAAAAAAAABgkAAAAAAAACBQAAAAhiYWxhbmNlQgAAAAAAAAAAAAkAAAIAAAABAgAAACBDYW4ndCBleGNoYW5nZSB3aXRoIHplcm8gYmFsYW5jZQMJAABnAAAAAgAAAAAAAAAAAAUAAAASbWluQW1vdW50VG9SZWNlaXZlCQAAAgAAAAEJAAEsAAAAAgIAAAA0TWluaW1hbCBhbW91bnQgdG8gcmVjZWl2ZSBtdXN0IGJlIHBvc2l0aXZlLiBBY3R1YWw6IAkAAaQAAAABBQAAABJtaW5BbW91bnRUb1JlY2VpdmUDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAHU9uZSBhdHRhY2hlZCBwYXltZW50IGV4cGVjdGVkAwkBAAAAASEAAAABBQAAABBoYXNFbm91Z2hCYWxhbmNlCQAETgAAAAIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAlwbXRBbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAA25pbAkBAAAAEXN1c3BlbmRTdXNwaWNpb3VzAAAAAAMJAAAAAAAAAgUAAAAKcG10QXNzZXRJZAUAAAAIYXNzZXRJZEEEAAAAC2Fzc2V0SWRTZW5kBQAAAAhhc3NldElkQgQAAAANJHQwMjA0MDcyMDQ5OAkBAAAADWNhbGN1bGF0ZUZlZXMAAAACBQAAAAhiYWxhbmNlQQUAAAAIYmFsYW5jZUIEAAAAEGFtb3VudFdpdGhvdXRGZWUIBQAAAA0kdDAyMDQwNzIwNDk4AAAAAl8xBAAAAA1hbW91bnRXaXRoRmVlCAUAAAANJHQwMjA0MDcyMDQ5OAAAAAJfMgQAAAAQZ292ZXJuYW5jZVJld2FyZAgFAAAADSR0MDIwNDA3MjA0OTgAAAACXzMEAAAAC25ld0JhbGFuY2VBCQAAZAAAAAIFAAAACGJhbGFuY2VBBQAAAAlwbXRBbW91bnQEAAAAC25ld0JhbGFuY2VCCQAAZQAAAAIJAABlAAAAAgUAAAAIYmFsYW5jZUIFAAAADWFtb3VudFdpdGhGZWUFAAAAEGdvdmVybmFuY2VSZXdhcmQDAwkAAGcAAAACBQAAAA1zdGFrZWRBbW91bnRBBQAAAAtuZXdCYWxhbmNlQQYJAABnAAAAAgUAAAANc3Rha2VkQW1vdW50QgUAAAALbmV3QmFsYW5jZUIJAQAAACF0aHJvd0luc3VmZmljaWVudEF2YWlsYWJsZUJhbGFuY2UAAAADBQAAAA1hbW91bnRXaXRoRmVlBQAAABFhdmFpbGFibGVCYWxhbmNlQgUAAAAKYXNzZXROYW1lQgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUEFAAAAC25ld0JhbGFuY2VBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQgUAAAALbmV3QmFsYW5jZUIJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAA1hbW91bnRXaXRoRmVlBQAAAAthc3NldElkU2VuZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAA13YWxsZXRBZGRyZXNzBQAAABBnb3Zlcm5hbmNlUmV3YXJkBQAAAAthc3NldElkU2VuZAUAAAADbmlsAwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAAhhc3NldElkQgQAAAALYXNzZXRJZFNlbmQFAAAACGFzc2V0SWRBBAAAAA0kdDAyMTMxNzIxNDA4CQEAAAANY2FsY3VsYXRlRmVlcwAAAAIFAAAACGJhbGFuY2VCBQAAAAhiYWxhbmNlQQQAAAAQYW1vdW50V2l0aG91dEZlZQgFAAAADSR0MDIxMzE3MjE0MDgAAAACXzEEAAAADWFtb3VudFdpdGhGZWUIBQAAAA0kdDAyMTMxNzIxNDA4AAAAAl8yBAAAABBnb3Zlcm5hbmNlUmV3YXJkCAUAAAANJHQwMjEzMTcyMTQwOAAAAAJfMwQAAAALbmV3QmFsYW5jZUEJAABlAAAAAgkAAGUAAAACBQAAAAhiYWxhbmNlQQUAAAANYW1vdW50V2l0aEZlZQUAAAAQZ292ZXJuYW5jZVJld2FyZAQAAAALbmV3QmFsYW5jZUIJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAACXBtdEFtb3VudAMDCQAAZwAAAAIFAAAADXN0YWtlZEFtb3VudEEFAAAAC25ld0JhbGFuY2VBBgkAAGcAAAACBQAAAA1zdGFrZWRBbW91bnRCBQAAAAtuZXdCYWxhbmNlQgkBAAAAIXRocm93SW5zdWZmaWNpZW50QXZhaWxhYmxlQmFsYW5jZQAAAAMFAAAADWFtb3VudFdpdGhGZWUFAAAAEWF2YWlsYWJsZUJhbGFuY2VBBQAAAAphc3NldE5hbWVBCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQUAAAALbmV3QmFsYW5jZUEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tleUJhbGFuY2VCBQAAAAtuZXdCYWxhbmNlQgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADWFtb3VudFdpdGhGZWUFAAAAC2Fzc2V0SWRTZW5kCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAADXdhbGxldEFkZHJlc3MFAAAAEGdvdmVybmFuY2VSZXdhcmQFAAAAC2Fzc2V0SWRTZW5kBQAAAANuaWwJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAkSW5jb3JyZWN0IGFzc2V0IGF0dGFjaGVkLiBFeHBlY3RlZDogBQAAAAtzdHJBc3NldElkQQIAAAAEIG9yIAUAAAALc3RyQXNzZXRJZEIAAAABaQEAAAAIc2h1dGRvd24AAAAAAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABCQABLAAAAAICAAAAIkRBcHAgaXMgYWxyZWFkeSBzdXNwZW5kZWQuIENhdXNlOiAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAIa2V5Q2F1c2UCAAAAGnRoZSBjYXVzZSB3YXNuJ3Qgc3BlY2lmaWVkAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABRhZG1pblB1YktleVN0YXJ0U3RvcAUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAAACAAAAAQIAAAAhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uCQEAAAAHc3VzcGVuZAAAAAECAAAAD1BhdXNlZCBieSBhZG1pbgAAAAFpAQAAAAhhY3RpdmF0ZQAAAAADBQAAAAhpc0FjdGl2ZQkAAAIAAAABAgAAABZEQXBwIGlzIGFscmVhZHkgYWN0aXZlAwkBAAAAASEAAAABCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgkABEwAAAACBQAAAAxhZG1pblB1YktleTEJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkyCQAETAAAAAIFAAAADGFkbWluUHViS2V5MwkABEwAAAACBQAAABRhZG1pblB1YktleVN0YXJ0U3RvcAUAAAADbmlsCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAAACAAAAAQIAAAAhT25seSBhZG1pbiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAAlrZXlBY3RpdmUGCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAACGtleUNhdXNlBQAAAANuaWwAAAABaQEAAAAZdGFrZUludG9BY2NvdW50RXh0cmFGdW5kcwAAAAEAAAALYW1vdW50TGVhdmUEAAAAHXVuY291bnRhYmxlQW1vdW50RW5yb2xsQXNzZXRBCQAAZQAAAAIFAAAAGWFjY291bnRCYWxhbmNlV2l0aFN0YWtlZEEFAAAACGJhbGFuY2VBBAAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QgkAAGUAAAACBQAAABlhY2NvdW50QmFsYW5jZVdpdGhTdGFrZWRCBQAAAAhiYWxhbmNlQgQAAAANYW1vdW50RW5yb2xsQQkAAGUAAAACBQAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QQMJAAAAAAAAAgUAAAAIYXNzZXRJZEEFAAAABHVuaXQFAAAAC2Ftb3VudExlYXZlAAAAAAAAAAAABAAAAA1hbW91bnRFbnJvbGxCCQAAZQAAAAIFAAAAHXVuY291bnRhYmxlQW1vdW50RW5yb2xsQXNzZXRCAwkAAAAAAAACBQAAAAhhc3NldElkQgUAAAAEdW5pdAUAAAALYW1vdW50TGVhdmUAAAAAAAAAAAADCQEAAAABIQAAAAEFAAAACGlzQWN0aXZlCQAAAgAAAAECAAAAH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQDCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAABHRoaXMJAAACAAAAAQIAAAArT25seSB0aGUgREFwcCBpdHNlbGYgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgMJAABmAAAAAgAAAAAAAAAAAAUAAAALYW1vdW50TGVhdmUJAAACAAAAAQkAASwAAAACAgAAADNBcmd1bWVudCAnYW1vdW50TGVhdmUnIGNhbm5vdCBiZSBuZWdhdGl2ZS4gQWN0dWFsOiAJAAGkAAAAAQUAAAALYW1vdW50TGVhdmUDAwkAAGYAAAACAAAAAAAAAAAABQAAAB11bmNvdW50YWJsZUFtb3VudEVucm9sbEFzc2V0QQYJAABmAAAAAgAAAAAAAAAAAAUAAAAddW5jb3VudGFibGVBbW91bnRFbnJvbGxBc3NldEIJAQAAAAdzdXNwZW5kAAAAAQIAAAAWRW5yb2xsIGFtb3VudCBuZWdhdGl2ZQMDCQAAZgAAAAIAAAAAAAAAAAAFAAAADWFtb3VudEVucm9sbEEGCQAAZgAAAAIAAAAAAAAAAAAFAAAADWFtb3VudEVucm9sbEIJAAACAAAAAQIAAAAVVG9vIGxhcmdlIGFtb3VudExlYXZlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlCYWxhbmNlQQkAAGQAAAACBQAAAAhiYWxhbmNlQQUAAAANYW1vdW50RW5yb2xsQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa2V5QmFsYW5jZUIJAABkAAAAAgUAAAAIYmFsYW5jZUIFAAAADWFtb3VudEVucm9sbEIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgIAAAAMbGFzdF9pbmNvbWVfBQAAAAtzdHJBc3NldElkQQUAAAANYW1vdW50RW5yb2xsQQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkAASwAAAACAgAAAAxsYXN0X2luY29tZV8FAAAAC3N0ckFzc2V0SWRCBQAAAA1hbW91bnRFbnJvbGxCBQAAAANuaWwAAAABaQEAAAASZW5hYmxlRmlyc3RIYXJ2ZXN0AAAAAAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAPa2V5Rmlyc3RIYXJ2ZXN0BgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAVa2V5Rmlyc3RIYXJ2ZXN0SGVpZ2h0CQAAZAAAAAIFAAAAC3N0YXJ0SGVpZ2h0CQAAaAAAAAIFAAAAFWZpcnN0SGFydmVzdEVuZFBlcmlvZAUAAAAMcGVyaW9kTGVuZ3RoBQAAAANuaWwAAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAABAAAABNtdWx0aVNpZ25lZEJ5QWRtaW5zBAAAABJh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", "height": 1646539, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DbHL2yWygMe7517Buhf8LkGTo1EDgzATCZNkZPhMt4f8 Next: C3ZFD5MvuhYXhGkZXn3KvJLy7UXnf2XtpkP3wN4itE2X Diff:
OldNewDifferences
4242 let kStartHeight = "start_height"
4343
4444 let kFirstHarvestHeight = "first_harvest_height"
45+
46+let keyOracleAssetPriority = "asset_priority_"
47+
48+let keyOracleScriptHash = "script_hash_cpmm"
49+
50+let keyInitPoolHeight = "init_pool_height_"
4551
4652 let keyAdminPubKey1 = "admin_pub_1"
4753
155161
156162 let scaleValue8Digits = 8
157163
164+let comissionForInitalization = 1000000000
165+
158166 func accountBalance (assetId) = match assetId {
159167 case id: ByteVector =>
160168 assetBalance(this, id)
187195 0
188196 }
189197 }
198+
199+
200+func isAllowedAsset (assetId) = match assetId {
201+ case id: ByteVector =>
202+ if (if ((id == USDN))
203+ then true
204+ else (id == SWOP))
205+ then true
206+ else false
207+ case waves: Unit =>
208+ true
209+ case _ =>
210+ throw("Match error")
211+}
190212
191213
192214 let stakedAmountA = stakedAmount(assetIdA)
272294
273295
274296 @Callable(i)
275-func init (firstHarvest) = {
276- let $t080018078 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277- let pmtAmountA = $t080018078._1
278- let pmtAssetIdA = $t080018078._2
279- let $t080838160 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280- let pmtAmountB = $t080838160._1
281- let pmtAssetIdB = $t080838160._2
282- let $t081658242 = getAssetInfo(pmtAssetIdA)
283- let pmtStrAssetIdA = $t081658242._1
284- let pmtAssetNameA = $t081658242._2
285- let pmtDecimalsA = $t081658242._3
286- let $t082478324 = getAssetInfo(pmtAssetIdB)
287- let pmtStrAssetIdB = $t082478324._1
288- let pmtAssetNameB = $t082478324._2
289- let pmtDecimalsB = $t082478324._3
290- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291- then throw("Only admin can call this function")
292- else if (isDefined(getBoolean(this, keyActive)))
293- then throw("DApp is already active")
294- else if ((pmtAssetIdA == pmtAssetIdB))
295- then throw("Assets must be different")
296- else {
297- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
298- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
299- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
300- let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
301- let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
302- let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
303- let shareInitialSupply = fraction(arg1, arg2, arg3)
304- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
305- let shareIssueId = calculateAssetId(shareIssue)
306- let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
307- if (firstHarvest)
308- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
309- else baseEntry
310- }
311- }
312-
313-
314-
315-@Callable(i)
316-func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
317- let $t01056910656 = getAssetInfoFromString(strAssetIdA)
318- let pmtStrAssetIdA = $t01056910656._1
319- let pmtAssetNameA = $t01056910656._2
320- let pmtDecimalsA = $t01056910656._3
321- let $t01066110748 = getAssetInfoFromString(strAssetIdB)
322- let pmtStrAssetIdB = $t01066110748._1
323- let pmtAssetNameB = $t01066110748._2
324- let pmtDecimalsB = $t01066110748._3
325- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
326- then throw("Only admin can call this function")
327- else if (isDefined(getBoolean(this, keyActive)))
328- then throw("DApp is already active")
329- else if ((strAssetIdA == strAssetIdB))
330- then throw("Assets must be different")
331- else {
332- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
333- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
334- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335- let shareInitialSupply = 0
336- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
337- let shareIssueId = calculateAssetId(shareIssue)
338- let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)]
339- if (firstHarvest)
340- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
341- else baseEntry
342- }
297+func init (userAdress) = {
298+ let $t083878464 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
299+ let pmtAmount1 = $t083878464._1
300+ let pmtAssetId1 = $t083878464._2
301+ let $t084698546 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
302+ let pmtAmount2 = $t084698546._1
303+ let pmtAssetId2 = $t084698546._2
304+ let $t085518634 = $Tuple2(i.payments[2].amount, i.payments[2].assetId)
305+ let pmtAmountSWOP = $t085518634._1
306+ let pmtAssetIdSWOP = $t085518634._2
307+ let check = isDataStorageUntouched(this)
308+ let userScriptHash = scriptHash(this)
309+ if ((i.caller == this))
310+ then throw("You can't call yourself")
311+ else if (if ((pmtAssetIdSWOP != SWOP))
312+ then true
313+ else (pmtAmountSWOP != comissionForInitalization))
314+ then throw("You need to attach 10 SWOP tokens")
315+ else if (if (!(isAllowedAsset(pmtAssetId1)))
316+ then !(isAllowedAsset(pmtAssetId2))
317+ else false)
318+ then throw("One of assets must be USDN, WAVES or SWOP")
319+ else if (if ((userScriptHash == value(getBinary(oracle, keyOracleScriptHash))))
320+ then true
321+ else !(check))
322+ then throw("Unexpected script was found.")
323+ else if (isDefined(getBoolean(this, keyActive)))
324+ then throw("DApp is already active")
325+ else if ((pmtAssetId1 == pmtAssetId2))
326+ then throw("Assets must be different")
327+ else {
328+ let pmtStrAssetId1 = match pmtAssetId1 {
329+ case id: ByteVector =>
330+ toBase58String(id)
331+ case waves: Unit =>
332+ "WAVES"
333+ case _ =>
334+ throw("Match error")
335+ }
336+ let pmtStrAssetId2 = match pmtAssetId2 {
337+ case id: ByteVector =>
338+ toBase58String(id)
339+ case waves: Unit =>
340+ "WAVES"
341+ case _ =>
342+ throw("Match error")
343+ }
344+ let asset1Priority = valueOrElse(getInteger(oracle, ("keyOracleAssetPriority" + pmtStrAssetId1)), 999999)
345+ let asset2Priority = valueOrElse(getInteger(oracle, ("keyOracleAssetPriority" + pmtStrAssetId2)), 999999)
346+ let $t0993310160 = if ((asset2Priority > asset1Priority))
347+ then $Tuple4(pmtAmount2, pmtAssetId2, pmtAmount1, pmtAssetId1)
348+ else $Tuple4(pmtAmount1, pmtAssetId1, pmtAmount2, pmtAssetId2)
349+ let pmtAmountA = $t0993310160._1
350+ let pmtAssetIdA = $t0993310160._2
351+ let pmtAmountB = $t0993310160._3
352+ let pmtAssetIdB = $t0993310160._4
353+ let $t01016910246 = getAssetInfo(pmtAssetIdA)
354+ let pmtStrAssetIdA = $t01016910246._1
355+ let pmtAssetNameA = $t01016910246._2
356+ let pmtDecimalsA = $t01016910246._3
357+ let $t01025510332 = getAssetInfo(pmtAssetIdB)
358+ let pmtStrAssetIdB = $t01025510332._1
359+ let pmtAssetNameB = $t01025510332._2
360+ let pmtDecimalsB = $t01025510332._3
361+ let addPool = invoke(oracle, "addPool", [this, ((pmtAssetNameA + "_") + pmtAssetNameB)], nil)
362+ if ((addPool == addPool))
363+ then if (!(isDefined(getString(oracle, ("pool_" + toString(this))))))
364+ then throw("Pool is not added")
365+ else {
366+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
367+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
368+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
369+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
370+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
371+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
372+ let shareInitialSupply = fraction(arg1, arg2, arg3)
373+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
374+ let shareIssueId = calculateAssetId(shareIssue)
375+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), IntegerEntry(keyInitPoolHeight, height), ScriptTransfer(walletAddress, shareInitialSupply, shareIssueId), ScriptTransfer(i.caller, comissionForInitalization, SWOP)]
376+ baseEntry
377+ }
378+ else throw("Strict value is not equal to itself.")
379+ }
343380 }
344381
345382
363400 then (balanceB == 0)
364401 else false)
365402 then {
366- let $t01345913536 = getAssetInfo(pmtAssetIdA)
367- let pmtStrAssetIdA = $t01345913536._1
368- let pmtAssetNameA = $t01345913536._2
369- let pmtDecimalsA = $t01345913536._3
370- let $t01354513622 = getAssetInfo(pmtAssetIdB)
371- let pmtStrAssetIdB = $t01354513622._1
372- let pmtAssetNameB = $t01354513622._2
373- let pmtDecimalsB = $t01354513622._3
403+ let $t01312013197 = getAssetInfo(pmtAssetIdA)
404+ let pmtStrAssetIdA = $t01312013197._1
405+ let pmtAssetNameA = $t01312013197._2
406+ let pmtDecimalsA = $t01312013197._3
407+ let $t01320613283 = getAssetInfo(pmtAssetIdB)
408+ let pmtStrAssetIdB = $t01320613283._1
409+ let pmtAssetNameB = $t01320613283._2
410+ let pmtDecimalsB = $t01320613283._3
374411 let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
375412 if ((pmtAssetIdA == pmtAssetIdB))
376413 then throw("Assets must be different")
433470
434471 @Callable(i)
435472 func withdraw () = {
436- let $t01802118171 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437- let pmtAmount = $t01802118171._1
438- let pmtAssetId = $t01802118171._2
473+ let $t01768217832 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
474+ let pmtAmount = $t01768217832._1
475+ let pmtAssetId = $t01768217832._2
439476 let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA, assetIdB)
440477 let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB, assetIdA)
441478 if (!(isActive))
457494
458495 @Callable(i)
459496 func exchange (minAmountToReceive) = {
460- let $t01939719472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
461- let pmtAmount = $t01939719472._1
462- let pmtAssetId = $t01939719472._2
497+ let $t01905819133 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
498+ let pmtAmount = $t01905819133._1
499+ let pmtAssetId = $t01905819133._2
463500 func calculateFees (tokenFrom,tokenTo) = {
464501 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
465502 let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
484521 else if ((pmtAssetId == assetIdA))
485522 then {
486523 let assetIdSend = assetIdB
487- let $t02074620837 = calculateFees(balanceA, balanceB)
488- let amountWithoutFee = $t02074620837._1
489- let amountWithFee = $t02074620837._2
490- let governanceReward = $t02074620837._3
524+ let $t02040720498 = calculateFees(balanceA, balanceB)
525+ let amountWithoutFee = $t02040720498._1
526+ let amountWithFee = $t02040720498._2
527+ let governanceReward = $t02040720498._3
491528 let newBalanceA = (balanceA + pmtAmount)
492529 let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
493530 if (if ((stakedAmountA >= newBalanceA))
499536 else if ((pmtAssetId == assetIdB))
500537 then {
501538 let assetIdSend = assetIdA
502- let $t02165621747 = calculateFees(balanceB, balanceA)
503- let amountWithoutFee = $t02165621747._1
504- let amountWithFee = $t02165621747._2
505- let governanceReward = $t02165621747._3
539+ let $t02131721408 = calculateFees(balanceB, balanceA)
540+ let amountWithoutFee = $t02131721408._1
541+ let amountWithFee = $t02131721408._2
542+ let governanceReward = $t02131721408._3
506543 let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
507544 let newBalanceB = (balanceB + pmtAmount)
508545 if (if ((stakedAmountA >= newBalanceA))
562599 }
563600
564601
602+
603+@Callable(i)
604+func enableFirstHarvest () = [BooleanEntry(keyFirstHarvest, true), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]
605+
606+
565607 @Verifier(tx)
566-func verify () = match tx {
567- case inv: InvokeScriptTransaction =>
568- let callTakeIntoAccount = if ((inv.dApp == this))
569- then (inv.function == "takeIntoAccountExtraFunds")
570- else false
571- let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
572- then if (if (if ((inv.function == "lockNeutrino"))
573- then (size(inv.payments) == 1)
574- else false)
575- then if ((inv.payments[0].assetId == USDN))
576- then true
577- else (inv.payments[0].assetId == NSBT)
578- else false)
579- then true
580- else if ((inv.function == "unlockNeutrino"))
581- then (size(inv.payments) == 0)
582- else false
583- else false)
584- then true
585- else if ((inv.dApp == stakingEURNAddress))
586- then if (if (if ((inv.function == "startStaking"))
587- then (size(inv.payments) == 1)
588- else false)
589- then (inv.payments[0].assetId == EURN)
590- else false)
591- then true
592- else if ((inv.function == "stopStaking"))
593- then (size(inv.payments) == 0)
594- else false
595- else false
596- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
597- then (inv.function == "exchange")
598- else false)
599- then (assetIdA == USDN)
600- else false)
601- then true
602- else if (if ((assetIdB == USDN))
603- then (size(inv.payments) == 1)
604- else false)
605- then (inv.payments[0].assetId == USDN)
606- else false
607- let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
608- then (inv.function == "exchange")
609- else false)
610- then (assetIdA == NSBT)
611- else false)
612- then true
613- else if (if ((assetIdB == NSBT))
614- then (size(inv.payments) == 1)
615- else false)
616- then (inv.payments[0].assetId == USDN)
617- else false
618- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
619- then true
620- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
621- then true
622- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
623- then true
624- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
625- if (if (if (if (callTakeIntoAccount)
626- then true
627- else callStaking)
628- then true
629- else exchangeToWaves)
630- then true
631- else exchangeToNSBTs)
632- then signedByAdmin
633- else false
634- case _ =>
608+func verify () = {
609+ let multiSignedByAdmins = {
635610 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
636611 then 1
637612 else 0
642617 then 1
643618 else 0
644619 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
645-}
620+ }
621+ match tx {
622+ case inv: InvokeScriptTransaction =>
623+ let callTakeIntoAccount = if ((inv.dApp == this))
624+ then (inv.function == "takeIntoAccountExtraFunds")
625+ else false
626+ let callEnableFirstHarvest = if ((inv.dApp == this))
627+ then (inv.function == "enableFirstHarvest")
628+ else false
629+ let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
630+ then if (if (if ((inv.function == "lockNeutrino"))
631+ then (size(inv.payments) == 1)
632+ else false)
633+ then if ((inv.payments[0].assetId == USDN))
634+ then true
635+ else (inv.payments[0].assetId == NSBT)
636+ else false)
637+ then true
638+ else if ((inv.function == "unlockNeutrino"))
639+ then (size(inv.payments) == 0)
640+ else false
641+ else false)
642+ then true
643+ else if ((inv.dApp == stakingEURNAddress))
644+ then if (if (if ((inv.function == "startStaking"))
645+ then (size(inv.payments) == 1)
646+ else false)
647+ then (inv.payments[0].assetId == EURN)
648+ else false)
649+ then true
650+ else if ((inv.function == "stopStaking"))
651+ then (size(inv.payments) == 0)
652+ else false
653+ else false
654+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
655+ then (inv.function == "exchange")
656+ else false)
657+ then (assetIdA == USDN)
658+ else false)
659+ then true
660+ else if (if ((assetIdB == USDN))
661+ then (size(inv.payments) == 1)
662+ else false)
663+ then (inv.payments[0].assetId == USDN)
664+ else false
665+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
666+ then (inv.function == "exchange")
667+ else false)
668+ then (assetIdA == NSBT)
669+ else false)
670+ then true
671+ else if (if ((assetIdB == NSBT))
672+ then (size(inv.payments) == 1)
673+ else false)
674+ then (inv.payments[0].assetId == USDN)
675+ else false
676+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
677+ then true
678+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
679+ then true
680+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
681+ then true
682+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
683+ if (if (if (if (if (if (callTakeIntoAccount)
684+ then true
685+ else callEnableFirstHarvest)
686+ then true
687+ else callStaking)
688+ then true
689+ else exchangeToWaves)
690+ then true
691+ else exchangeToNSBTs)
692+ then signedByAdmin
693+ else false)
694+ then true
695+ else multiSignedByAdmins
696+ case _ =>
697+ multiSignedByAdmins
698+ }
699+ }
646700
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "1.0.0"
55
66 let keyVersion = "version"
77
88 let keyActive = "active"
99
1010 let keyAssetIdA = "A_asset_id"
1111
1212 let keyAssetIdB = "B_asset_id"
1313
1414 let keyBalanceA = "A_asset_balance"
1515
1616 let keyBalanceB = "B_asset_balance"
1717
1818 let keyBalanceInitA = "A_asset_init"
1919
2020 let keyBalanceInitB = "B_asset_init"
2121
2222 let keyShareAssetId = "share_asset_id"
2323
2424 let keyShareAssetSupply = "share_asset_supply"
2525
2626 let keyCommission = "commission"
2727
2828 let keyCommissionScaleDelimiter = "commission_scale_delimiter"
2929
3030 let keyCause = "shutdown_cause"
3131
3232 let keyFirstHarvest = "first_harvest"
3333
3434 let keyFirstHarvestHeight = "first_harvest_height"
3535
3636 let kShareLimit = "share_limit_on_first_harvest"
3737
3838 let kBasePeriod = "base_period"
3939
4040 let kPeriodLength = "period_length"
4141
4242 let kStartHeight = "start_height"
4343
4444 let kFirstHarvestHeight = "first_harvest_height"
45+
46+let keyOracleAssetPriority = "asset_priority_"
47+
48+let keyOracleScriptHash = "script_hash_cpmm"
49+
50+let keyInitPoolHeight = "init_pool_height_"
4551
4652 let keyAdminPubKey1 = "admin_pub_1"
4753
4854 let keyAdminPubKey2 = "admin_pub_2"
4955
5056 let keyAdminPubKey3 = "admin_pub_3"
5157
5258 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
5359
5460 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
5561 case string: String =>
5662 fromBase58String(string)
5763 case nothing =>
5864 throw("Admin public key is empty")
5965 }
6066
6167
6268 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
6369
6470 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
6571
6672 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
6773
6874 let adminPubKeyStartStop = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
6975
7076 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
7177
7278 let walletAddress = Address(base58'3NAGTtZz6WpupSN89NZD5rMZwwziZEg4Kx4')
7379
7480 let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
7581
7682 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
7783
7884 let NSBT = base58'36mg8NZTaFRDygiVwb8uBnLR51hetJruUCZcxhaVcHj9'
7985
8086 let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
8187
8288 let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
8389
8490 let stakingUSDNNSBTAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
8591
8692 let stakingEURNAddress = Address(base58'3MyVqAbmKWh339gF6hy8faWw1jGeTV2wnGE')
8793
8894 let USDNToWavesExchanger = Address(base58'3N77kfPbQyjXWpDALX3xjKw3iEGMWEctV37')
8995
9096 let USDNToNSBTExchanger = Address(base58'3Mye9wVR7d2mc6Y5ZJTu11svzgUQ7o8H9dA')
9197
9298 let stakingFeeInUSDN = 270000
9399
94100 let stakingFeeInEURN = 234000
95101
96102 let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
97103
98104 let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
99105
100106 let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
101107
102108 let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
103109
104110 let isActive = getBooleanValue(this, keyActive)
105111
106112 let strAssetIdA = getStringValue(this, keyAssetIdA)
107113
108114 let strAssetIdB = getStringValue(this, keyAssetIdB)
109115
110116 let assetIdA = if ((strAssetIdA == "WAVES"))
111117 then unit
112118 else fromBase58String(strAssetIdA)
113119
114120 let assetIdB = if ((strAssetIdB == "WAVES"))
115121 then unit
116122 else fromBase58String(strAssetIdB)
117123
118124 let assetNameA = match assetIdA {
119125 case id: ByteVector =>
120126 value(assetInfo(id)).name
121127 case waves: Unit =>
122128 "WAVES"
123129 case _ =>
124130 throw("Match error")
125131 }
126132
127133 let assetNameB = match assetIdB {
128134 case id: ByteVector =>
129135 value(assetInfo(id)).name
130136 case waves: Unit =>
131137 "WAVES"
132138 case _ =>
133139 throw("Match error")
134140 }
135141
136142 let balanceA = getIntegerValue(this, keyBalanceA)
137143
138144 let balanceB = getIntegerValue(this, keyBalanceB)
139145
140146 let shareAssetId = fromBase58String(getStringValue(this, keyShareAssetId))
141147
142148 let shareAssetSupply = getIntegerValue(this, keyShareAssetSupply)
143149
144150 let commission = 3000
145151
146152 let commissionGovernance = 1200
147153
148154 let commissionScaleDelimiter = 1000000
149155
150156 let scaleValue3 = 1000
151157
152158 let scaleValue8 = 100000000
153159
154160 let slippageToleranceDelimiter = 1000
155161
156162 let scaleValue8Digits = 8
157163
164+let comissionForInitalization = 1000000000
165+
158166 func accountBalance (assetId) = match assetId {
159167 case id: ByteVector =>
160168 assetBalance(this, id)
161169 case waves: Unit =>
162170 wavesBalance(this).available
163171 case _ =>
164172 throw("Match error")
165173 }
166174
167175
168176 func stakedAmount (assetId) = {
169177 let stakedAmountCalculated = match assetId {
170178 case aId: ByteVector =>
171179 if (if ((aId == USDN))
172180 then true
173181 else (aId == NSBT))
174182 then getInteger(stakingUSDNNSBTAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
175183 else if ((aId == EURN))
176184 then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
177185 else 0
178186 case _: Unit =>
179187 0
180188 case _ =>
181189 throw("Match error")
182190 }
183191 match stakedAmountCalculated {
184192 case i: Int =>
185193 i
186194 case _ =>
187195 0
188196 }
189197 }
198+
199+
200+func isAllowedAsset (assetId) = match assetId {
201+ case id: ByteVector =>
202+ if (if ((id == USDN))
203+ then true
204+ else (id == SWOP))
205+ then true
206+ else false
207+ case waves: Unit =>
208+ true
209+ case _ =>
210+ throw("Match error")
211+}
190212
191213
192214 let stakedAmountA = stakedAmount(assetIdA)
193215
194216 let stakedAmountB = stakedAmount(assetIdB)
195217
196218 let assetInitA = getIntegerValue(this, keyBalanceInitA)
197219
198220 let assetInitB = getIntegerValue(this, keyBalanceInitB)
199221
200222 let availableBalanceA = (balanceA - stakedAmountA)
201223
202224 let availableBalanceB = (balanceB - stakedAmountB)
203225
204226 let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
205227
206228 let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
207229
208230 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
209231 then (accountBalanceWithStakedB >= balanceB)
210232 else false
211233
212234 func getAssetInfo (assetId) = match assetId {
213235 case id: ByteVector =>
214236 let stringId = toBase58String(id)
215237 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
216238 $Tuple3(stringId, info.name, info.decimals)
217239 case waves: Unit =>
218240 $Tuple3("WAVES", "WAVES", 8)
219241 case _ =>
220242 throw("Match error")
221243 }
222244
223245
224246 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
225247 then $Tuple3("WAVES", "WAVES", 8)
226248 else {
227249 let stringId = assetStr
228250 let id = fromBase58String(assetStr)
229251 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
230252 $Tuple3(stringId, info.name, info.decimals)
231253 }
232254
233255
234256 func suspend (cause) = [BooleanEntry(keyActive, false), StringEntry(keyCause, cause)]
235257
236258
237259 func deductStakingFee (amount,assetId,secondAssetId) = if (if ((assetId == USDN))
238260 then true
239261 else (assetId == EURN))
240262 then {
241263 let stakinFee = if ((assetId == USDN))
242264 then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
243265 then 2
244266 else 1))
245267 else if ((assetId == EURN))
246268 then stakingFeeInEURN
247269 else 0
248270 let result = (amount - stakinFee)
249271 if ((0 >= result))
250272 then throw((((("Insufficient amount " + toString(amount)) + " to deduct staking fee ") + toString(stakinFee)) + "USDN/EURN"))
251273 else result
252274 }
253275 else amount
254276
255277
256278 func getStakingFee (assetId,secondAssetId) = if ((assetId == USDN))
257279 then (stakingFeeInUSDN * (if ((secondAssetId == NSBT))
258280 then 2
259281 else 1))
260282 else if ((assetId == EURN))
261283 then stakingFeeInEURN
262284 else 0
263285
264286
265287 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"))
266288
267289
268290 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"))
269291
270292
271293 func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
272294
273295
274296 @Callable(i)
275-func init (firstHarvest) = {
276- let $t080018078 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
277- let pmtAmountA = $t080018078._1
278- let pmtAssetIdA = $t080018078._2
279- let $t080838160 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
280- let pmtAmountB = $t080838160._1
281- let pmtAssetIdB = $t080838160._2
282- let $t081658242 = getAssetInfo(pmtAssetIdA)
283- let pmtStrAssetIdA = $t081658242._1
284- let pmtAssetNameA = $t081658242._2
285- let pmtDecimalsA = $t081658242._3
286- let $t082478324 = getAssetInfo(pmtAssetIdB)
287- let pmtStrAssetIdB = $t082478324._1
288- let pmtAssetNameB = $t082478324._2
289- let pmtDecimalsB = $t082478324._3
290- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
291- then throw("Only admin can call this function")
292- else if (isDefined(getBoolean(this, keyActive)))
293- then throw("DApp is already active")
294- else if ((pmtAssetIdA == pmtAssetIdB))
295- then throw("Assets must be different")
296- else {
297- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
298- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
299- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
300- let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
301- let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
302- let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
303- let shareInitialSupply = fraction(arg1, arg2, arg3)
304- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
305- let shareIssueId = calculateAssetId(shareIssue)
306- let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
307- if (firstHarvest)
308- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
309- else baseEntry
310- }
311- }
312-
313-
314-
315-@Callable(i)
316-func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
317- let $t01056910656 = getAssetInfoFromString(strAssetIdA)
318- let pmtStrAssetIdA = $t01056910656._1
319- let pmtAssetNameA = $t01056910656._2
320- let pmtDecimalsA = $t01056910656._3
321- let $t01066110748 = getAssetInfoFromString(strAssetIdB)
322- let pmtStrAssetIdB = $t01066110748._1
323- let pmtAssetNameB = $t01066110748._2
324- let pmtDecimalsB = $t01066110748._3
325- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
326- then throw("Only admin can call this function")
327- else if (isDefined(getBoolean(this, keyActive)))
328- then throw("DApp is already active")
329- else if ((strAssetIdA == strAssetIdB))
330- then throw("Assets must be different")
331- else {
332- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
333- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
334- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
335- let shareInitialSupply = 0
336- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
337- let shareIssueId = calculateAssetId(shareIssue)
338- let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceInitA, amtAssetA), IntegerEntry(keyBalanceInitB, amtAssetB), IntegerEntry(keyBalanceA, 0), IntegerEntry(keyBalanceB, 0), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply)]
339- if (firstHarvest)
340- then (baseEntry ++ [BooleanEntry(keyFirstHarvest, firstHarvest), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
341- else baseEntry
342- }
297+func init (userAdress) = {
298+ let $t083878464 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
299+ let pmtAmount1 = $t083878464._1
300+ let pmtAssetId1 = $t083878464._2
301+ let $t084698546 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
302+ let pmtAmount2 = $t084698546._1
303+ let pmtAssetId2 = $t084698546._2
304+ let $t085518634 = $Tuple2(i.payments[2].amount, i.payments[2].assetId)
305+ let pmtAmountSWOP = $t085518634._1
306+ let pmtAssetIdSWOP = $t085518634._2
307+ let check = isDataStorageUntouched(this)
308+ let userScriptHash = scriptHash(this)
309+ if ((i.caller == this))
310+ then throw("You can't call yourself")
311+ else if (if ((pmtAssetIdSWOP != SWOP))
312+ then true
313+ else (pmtAmountSWOP != comissionForInitalization))
314+ then throw("You need to attach 10 SWOP tokens")
315+ else if (if (!(isAllowedAsset(pmtAssetId1)))
316+ then !(isAllowedAsset(pmtAssetId2))
317+ else false)
318+ then throw("One of assets must be USDN, WAVES or SWOP")
319+ else if (if ((userScriptHash == value(getBinary(oracle, keyOracleScriptHash))))
320+ then true
321+ else !(check))
322+ then throw("Unexpected script was found.")
323+ else if (isDefined(getBoolean(this, keyActive)))
324+ then throw("DApp is already active")
325+ else if ((pmtAssetId1 == pmtAssetId2))
326+ then throw("Assets must be different")
327+ else {
328+ let pmtStrAssetId1 = match pmtAssetId1 {
329+ case id: ByteVector =>
330+ toBase58String(id)
331+ case waves: Unit =>
332+ "WAVES"
333+ case _ =>
334+ throw("Match error")
335+ }
336+ let pmtStrAssetId2 = match pmtAssetId2 {
337+ case id: ByteVector =>
338+ toBase58String(id)
339+ case waves: Unit =>
340+ "WAVES"
341+ case _ =>
342+ throw("Match error")
343+ }
344+ let asset1Priority = valueOrElse(getInteger(oracle, ("keyOracleAssetPriority" + pmtStrAssetId1)), 999999)
345+ let asset2Priority = valueOrElse(getInteger(oracle, ("keyOracleAssetPriority" + pmtStrAssetId2)), 999999)
346+ let $t0993310160 = if ((asset2Priority > asset1Priority))
347+ then $Tuple4(pmtAmount2, pmtAssetId2, pmtAmount1, pmtAssetId1)
348+ else $Tuple4(pmtAmount1, pmtAssetId1, pmtAmount2, pmtAssetId2)
349+ let pmtAmountA = $t0993310160._1
350+ let pmtAssetIdA = $t0993310160._2
351+ let pmtAmountB = $t0993310160._3
352+ let pmtAssetIdB = $t0993310160._4
353+ let $t01016910246 = getAssetInfo(pmtAssetIdA)
354+ let pmtStrAssetIdA = $t01016910246._1
355+ let pmtAssetNameA = $t01016910246._2
356+ let pmtDecimalsA = $t01016910246._3
357+ let $t01025510332 = getAssetInfo(pmtAssetIdB)
358+ let pmtStrAssetIdB = $t01025510332._1
359+ let pmtAssetNameB = $t01025510332._2
360+ let pmtDecimalsB = $t01025510332._3
361+ let addPool = invoke(oracle, "addPool", [this, ((pmtAssetNameA + "_") + pmtAssetNameB)], nil)
362+ if ((addPool == addPool))
363+ then if (!(isDefined(getString(oracle, ("pool_" + toString(this))))))
364+ then throw("Pool is not added")
365+ else {
366+ let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
367+ let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
368+ let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
369+ let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
370+ let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
371+ let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
372+ let shareInitialSupply = fraction(arg1, arg2, arg3)
373+ let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
374+ let shareIssueId = calculateAssetId(shareIssue)
375+ let baseEntry = [StringEntry(keyVersion, version), BooleanEntry(keyActive, true), StringEntry(keyAssetIdA, pmtStrAssetIdA), StringEntry(keyAssetIdB, pmtStrAssetIdB), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyCommission, commission), IntegerEntry(keyCommissionScaleDelimiter, commissionScaleDelimiter), shareIssue, StringEntry(keyShareAssetId, toBase58String(shareIssueId)), IntegerEntry(keyShareAssetSupply, shareInitialSupply), IntegerEntry(keyInitPoolHeight, height), ScriptTransfer(walletAddress, shareInitialSupply, shareIssueId), ScriptTransfer(i.caller, comissionForInitalization, SWOP)]
376+ baseEntry
377+ }
378+ else throw("Strict value is not equal to itself.")
379+ }
343380 }
344381
345382
346383
347384 @Callable(i)
348385 func keepLimitForFirstHarvest (shareLimit) = if (!(isActive))
349386 then throw("DApp is inactive at this moment")
350387 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStaking], i.callerPublicKey)))
351388 then throw("Only admin can call this function")
352389 else [IntegerEntry(kShareLimit, shareLimit)]
353390
354391
355392
356393 @Callable(i)
357394 func replenishWithTwoTokens (slippageTolerance) = {
358395 let pmtAssetIdA = i.payments[0].assetId
359396 let pmtAssetIdB = i.payments[1].assetId
360397 let pmtAmountA = deductStakingFee(i.payments[0].amount, pmtAssetIdA, pmtAssetIdB)
361398 let pmtAmountB = deductStakingFee(i.payments[1].amount, pmtAssetIdB, pmtAssetIdA)
362399 if (if ((balanceA == 0))
363400 then (balanceB == 0)
364401 else false)
365402 then {
366- let $t01345913536 = getAssetInfo(pmtAssetIdA)
367- let pmtStrAssetIdA = $t01345913536._1
368- let pmtAssetNameA = $t01345913536._2
369- let pmtDecimalsA = $t01345913536._3
370- let $t01354513622 = getAssetInfo(pmtAssetIdB)
371- let pmtStrAssetIdB = $t01354513622._1
372- let pmtAssetNameB = $t01354513622._2
373- let pmtDecimalsB = $t01354513622._3
403+ let $t01312013197 = getAssetInfo(pmtAssetIdA)
404+ let pmtStrAssetIdA = $t01312013197._1
405+ let pmtAssetNameA = $t01312013197._2
406+ let pmtDecimalsA = $t01312013197._3
407+ let $t01320613283 = getAssetInfo(pmtAssetIdB)
408+ let pmtStrAssetIdB = $t01320613283._1
409+ let pmtAssetNameB = $t01320613283._2
410+ let pmtDecimalsB = $t01320613283._3
374411 let tokenRatio = fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
375412 if ((pmtAssetIdA == pmtAssetIdB))
376413 then throw("Assets must be different")
377414 else {
378415 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
379416 let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
380417 if (!(isActive))
381418 then throw("DApp is inactive at this moment")
382419 else if (if ((0 > slippageTolerance))
383420 then true
384421 else (slippageTolerance > slippageToleranceDelimiter))
385422 then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
386423 else if ((size(i.payments) != 2))
387424 then throw("Two attached assets expected")
388425 else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
389426 then true
390427 else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
391428 then throw("Incorrect assets amount: amounts must have the contract ratio")
392429 else if (if ((pmtAssetIdA != assetIdA))
393430 then true
394431 else (pmtAssetIdB != assetIdB))
395432 then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
396433 else if ((shareInitialSupply == 0))
397434 then throw("Too small amount to replenish")
398435 else if (!(hasEnoughBalance))
399436 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
400437 else [Reissue(shareAssetId, shareInitialSupply, true), IntegerEntry(keyBalanceA, pmtAmountA), IntegerEntry(keyBalanceB, pmtAmountB), IntegerEntry(keyShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareAssetId)]
401438 }
402439 }
403440 else {
404441 let tokenRatio = fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
405442 let ratioShareTokensInA = fraction(pmtAmountA, scaleValue8, balanceA)
406443 let ratioShareTokensInB = fraction(pmtAmountB, scaleValue8, balanceB)
407444 let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scaleValue8)
408445 if (!(isActive))
409446 then throw("DApp is inactive at this moment")
410447 else if (if ((0 > slippageTolerance))
411448 then true
412449 else (slippageTolerance > slippageToleranceDelimiter))
413450 then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
414451 else if ((size(i.payments) != 2))
415452 then throw("Two attached assets expected")
416453 else if (if ((pmtAssetIdA != assetIdA))
417454 then true
418455 else (pmtAssetIdB != assetIdB))
419456 then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
420457 else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
421458 then true
422459 else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
423460 then throw("Incorrect assets amount: amounts must have the contract ratio")
424461 else if ((shareTokenToPayAmount == 0))
425462 then throw("Too small amount to replenish")
426463 else if (!(hasEnoughBalance))
427464 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
428465 else [IntegerEntry(keyBalanceA, (balanceA + pmtAmountA)), IntegerEntry(keyBalanceB, (balanceB + pmtAmountB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
429466 }
430467 }
431468
432469
433470
434471 @Callable(i)
435472 func withdraw () = {
436- let $t01802118171 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437- let pmtAmount = $t01802118171._1
438- let pmtAssetId = $t01802118171._2
473+ let $t01768217832 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
474+ let pmtAmount = $t01768217832._1
475+ let pmtAssetId = $t01768217832._2
439476 let amountToPayA = deductStakingFee(fraction(pmtAmount, balanceA, shareAssetSupply), assetIdA, assetIdB)
440477 let amountToPayB = deductStakingFee(fraction(pmtAmount, balanceB, shareAssetSupply), assetIdB, assetIdA)
441478 if (!(isActive))
442479 then throw("DApp is inactive at this moment")
443480 else if ((size(i.payments) != 1))
444481 then throw("One attached payment expected")
445482 else if ((pmtAssetId != shareAssetId))
446483 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
447484 else if (!(hasEnoughBalance))
448485 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
449486 else if (if ((amountToPayA > availableBalanceA))
450487 then true
451488 else (amountToPayB > availableBalanceB))
452489 then throwInsufficientAvailableBalances(amountToPayA, amountToPayB)
453490 else [IntegerEntry(keyBalanceA, (balanceA - amountToPayA)), IntegerEntry(keyBalanceB, (balanceB - amountToPayB)), IntegerEntry(keyShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
454491 }
455492
456493
457494
458495 @Callable(i)
459496 func exchange (minAmountToReceive) = {
460- let $t01939719472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
461- let pmtAmount = $t01939719472._1
462- let pmtAssetId = $t01939719472._2
497+ let $t01905819133 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
498+ let pmtAmount = $t01905819133._1
499+ let pmtAssetId = $t01905819133._2
463500 func calculateFees (tokenFrom,tokenTo) = {
464501 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
465502 let amountWithFee = fraction(amountWithoutFee, (commissionScaleDelimiter - commission), commissionScaleDelimiter)
466503 let governanceReward = fraction(amountWithoutFee, commissionGovernance, commissionScaleDelimiter)
467504 if ((minAmountToReceive > amountWithFee))
468505 then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
469506 else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
470507 }
471508
472509 if (!(isActive))
473510 then throw("DApp is inactive at this moment")
474511 else if (if ((balanceA == 0))
475512 then true
476513 else (balanceB == 0))
477514 then throw("Can't exchange with zero balance")
478515 else if ((0 >= minAmountToReceive))
479516 then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
480517 else if ((size(i.payments) != 1))
481518 then throw("One attached payment expected")
482519 else if (!(hasEnoughBalance))
483520 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
484521 else if ((pmtAssetId == assetIdA))
485522 then {
486523 let assetIdSend = assetIdB
487- let $t02074620837 = calculateFees(balanceA, balanceB)
488- let amountWithoutFee = $t02074620837._1
489- let amountWithFee = $t02074620837._2
490- let governanceReward = $t02074620837._3
524+ let $t02040720498 = calculateFees(balanceA, balanceB)
525+ let amountWithoutFee = $t02040720498._1
526+ let amountWithFee = $t02040720498._2
527+ let governanceReward = $t02040720498._3
491528 let newBalanceA = (balanceA + pmtAmount)
492529 let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
493530 if (if ((stakedAmountA >= newBalanceA))
494531 then true
495532 else (stakedAmountB >= newBalanceB))
496533 then throwInsufficientAvailableBalance(amountWithFee, availableBalanceB, assetNameB)
497534 else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
498535 }
499536 else if ((pmtAssetId == assetIdB))
500537 then {
501538 let assetIdSend = assetIdA
502- let $t02165621747 = calculateFees(balanceB, balanceA)
503- let amountWithoutFee = $t02165621747._1
504- let amountWithFee = $t02165621747._2
505- let governanceReward = $t02165621747._3
539+ let $t02131721408 = calculateFees(balanceB, balanceA)
540+ let amountWithoutFee = $t02131721408._1
541+ let amountWithFee = $t02131721408._2
542+ let governanceReward = $t02131721408._3
506543 let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
507544 let newBalanceB = (balanceB + pmtAmount)
508545 if (if ((stakedAmountA >= newBalanceA))
509546 then true
510547 else (stakedAmountB >= newBalanceB))
511548 then throwInsufficientAvailableBalance(amountWithFee, availableBalanceA, assetNameA)
512549 else [IntegerEntry(keyBalanceA, newBalanceA), IntegerEntry(keyBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(walletAddress, governanceReward, assetIdSend)]
513550 }
514551 else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
515552 }
516553
517554
518555
519556 @Callable(i)
520557 func shutdown () = if (!(isActive))
521558 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, keyCause), "the cause wasn't specified")))
522559 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
523560 then throw("Only admin can call this function")
524561 else suspend("Paused by admin")
525562
526563
527564
528565 @Callable(i)
529566 func activate () = if (isActive)
530567 then throw("DApp is already active")
531568 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminPubKeyStartStop], i.callerPublicKey)))
532569 then throw("Only admin can call this function")
533570 else [BooleanEntry(keyActive, true), DeleteEntry(keyCause)]
534571
535572
536573
537574 @Callable(i)
538575 func takeIntoAccountExtraFunds (amountLeave) = {
539576 let uncountableAmountEnrollAssetA = (accountBalanceWithStakedA - balanceA)
540577 let uncountableAmountEnrollAssetB = (accountBalanceWithStakedB - balanceB)
541578 let amountEnrollA = (uncountableAmountEnrollAssetA - (if ((assetIdA == unit))
542579 then amountLeave
543580 else 0))
544581 let amountEnrollB = (uncountableAmountEnrollAssetB - (if ((assetIdB == unit))
545582 then amountLeave
546583 else 0))
547584 if (!(isActive))
548585 then throw("DApp is inactive at this moment")
549586 else if ((i.caller != this))
550587 then throw("Only the DApp itself can call this function")
551588 else if ((0 > amountLeave))
552589 then throw(("Argument 'amountLeave' cannot be negative. Actual: " + toString(amountLeave)))
553590 else if (if ((0 > uncountableAmountEnrollAssetA))
554591 then true
555592 else (0 > uncountableAmountEnrollAssetB))
556593 then suspend("Enroll amount negative")
557594 else if (if ((0 > amountEnrollA))
558595 then true
559596 else (0 > amountEnrollB))
560597 then throw("Too large amountLeave")
561598 else [IntegerEntry(keyBalanceA, (balanceA + amountEnrollA)), IntegerEntry(keyBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
562599 }
563600
564601
602+
603+@Callable(i)
604+func enableFirstHarvest () = [BooleanEntry(keyFirstHarvest, true), IntegerEntry(keyFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))]
605+
606+
565607 @Verifier(tx)
566-func verify () = match tx {
567- case inv: InvokeScriptTransaction =>
568- let callTakeIntoAccount = if ((inv.dApp == this))
569- then (inv.function == "takeIntoAccountExtraFunds")
570- else false
571- let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
572- then if (if (if ((inv.function == "lockNeutrino"))
573- then (size(inv.payments) == 1)
574- else false)
575- then if ((inv.payments[0].assetId == USDN))
576- then true
577- else (inv.payments[0].assetId == NSBT)
578- else false)
579- then true
580- else if ((inv.function == "unlockNeutrino"))
581- then (size(inv.payments) == 0)
582- else false
583- else false)
584- then true
585- else if ((inv.dApp == stakingEURNAddress))
586- then if (if (if ((inv.function == "startStaking"))
587- then (size(inv.payments) == 1)
588- else false)
589- then (inv.payments[0].assetId == EURN)
590- else false)
591- then true
592- else if ((inv.function == "stopStaking"))
593- then (size(inv.payments) == 0)
594- else false
595- else false
596- let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
597- then (inv.function == "exchange")
598- else false)
599- then (assetIdA == USDN)
600- else false)
601- then true
602- else if (if ((assetIdB == USDN))
603- then (size(inv.payments) == 1)
604- else false)
605- then (inv.payments[0].assetId == USDN)
606- else false
607- let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
608- then (inv.function == "exchange")
609- else false)
610- then (assetIdA == NSBT)
611- else false)
612- then true
613- else if (if ((assetIdB == NSBT))
614- then (size(inv.payments) == 1)
615- else false)
616- then (inv.payments[0].assetId == USDN)
617- else false
618- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
619- then true
620- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
621- then true
622- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
623- then true
624- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
625- if (if (if (if (callTakeIntoAccount)
626- then true
627- else callStaking)
628- then true
629- else exchangeToWaves)
630- then true
631- else exchangeToNSBTs)
632- then signedByAdmin
633- else false
634- case _ =>
608+func verify () = {
609+ let multiSignedByAdmins = {
635610 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
636611 then 1
637612 else 0
638613 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
639614 then 1
640615 else 0
641616 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
642617 then 1
643618 else 0
644619 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
645-}
620+ }
621+ match tx {
622+ case inv: InvokeScriptTransaction =>
623+ let callTakeIntoAccount = if ((inv.dApp == this))
624+ then (inv.function == "takeIntoAccountExtraFunds")
625+ else false
626+ let callEnableFirstHarvest = if ((inv.dApp == this))
627+ then (inv.function == "enableFirstHarvest")
628+ else false
629+ let callStaking = if (if ((inv.dApp == stakingUSDNNSBTAddress))
630+ then if (if (if ((inv.function == "lockNeutrino"))
631+ then (size(inv.payments) == 1)
632+ else false)
633+ then if ((inv.payments[0].assetId == USDN))
634+ then true
635+ else (inv.payments[0].assetId == NSBT)
636+ else false)
637+ then true
638+ else if ((inv.function == "unlockNeutrino"))
639+ then (size(inv.payments) == 0)
640+ else false
641+ else false)
642+ then true
643+ else if ((inv.dApp == stakingEURNAddress))
644+ then if (if (if ((inv.function == "startStaking"))
645+ then (size(inv.payments) == 1)
646+ else false)
647+ then (inv.payments[0].assetId == EURN)
648+ else false)
649+ then true
650+ else if ((inv.function == "stopStaking"))
651+ then (size(inv.payments) == 0)
652+ else false
653+ else false
654+ let exchangeToWaves = if (if (if ((inv.dApp == USDNToWavesExchanger))
655+ then (inv.function == "exchange")
656+ else false)
657+ then (assetIdA == USDN)
658+ else false)
659+ then true
660+ else if (if ((assetIdB == USDN))
661+ then (size(inv.payments) == 1)
662+ else false)
663+ then (inv.payments[0].assetId == USDN)
664+ else false
665+ let exchangeToNSBTs = if (if (if ((inv.dApp == USDNToNSBTExchanger))
666+ then (inv.function == "exchange")
667+ else false)
668+ then (assetIdA == NSBT)
669+ else false)
670+ then true
671+ else if (if ((assetIdB == NSBT))
672+ then (size(inv.payments) == 1)
673+ else false)
674+ then (inv.payments[0].assetId == USDN)
675+ else false
676+ let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
677+ then true
678+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
679+ then true
680+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
681+ then true
682+ else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
683+ if (if (if (if (if (if (callTakeIntoAccount)
684+ then true
685+ else callEnableFirstHarvest)
686+ then true
687+ else callStaking)
688+ then true
689+ else exchangeToWaves)
690+ then true
691+ else exchangeToNSBTs)
692+ then signedByAdmin
693+ else false)
694+ then true
695+ else multiSignedByAdmins
696+ case _ =>
697+ multiSignedByAdmins
698+ }
699+ }
646700

github/deemru/w8io/873ac7e 
101.70 ms