2022.08.09 20:59 [3242746] smart account 3PG2vMhK5CPqsCDodvLGzQ84QkoHXCJ3oNP > SELF 0.00000000 Waves

{ "type": 13, "id": "7Wf7d6yzqwj2VXbcsNLcSWSzBd6XGKQxuV8ZgEFkbWHp", "fee": 2500000, "feeAssetId": null, "timestamp": 1660069863279, "version": 1, "sender": "3PG2vMhK5CPqsCDodvLGzQ84QkoHXCJ3oNP", "senderPublicKey": "5RM3w4ysmDbtgfswnVNPx7DQkNwVAG3RoxNFHgt6ToNU", "proofs": [ "", "4mDM1xCbUXDmHnuTd82v64BzK2dEsg7g7bKSMBypFQnjWcBgBE7skeCG66Kw5ELbALWXdGzN1SqzJkogGH23bFGL", "", "5Au5RVXaoJ1Z4mpw6Q3ZjhzAojzBadrtRidSoHgUQJGNCQs4xFMn4JzePxJ1rABBuTzivxQJLE6dYCwToDYRNuTn" ], "script": "base64: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eQAAAAAAAAAACgAAAAAUbk1ldHJpY0lkeFN1cmZTdXBwbHkAAAAAAAAAAAsAAAAADGJGdW5jSWR4U3VyZgAAAAAAAAAAAAAAAAANYkZ1bmNJZHhXYXZlcwAAAAAAAAAAAQAAAAAMYkZ1bmNJZHhVc2RuAAAAAAAAAAACAAAAABRiRnVuY0lkeFJlc2VydmVTdGFydAAAAAAAAAAAAwAAAAATYkZ1bmNJZHhTdXBwbHlTdGFydAAAAAAAAAAABAAAAAAPYkZ1bmNJZHhCUlN0YXJ0AAAAAAAAAAAFAAAAABJiRnVuY0lkeFJlc2VydmVFbmQAAAAAAAAAAAYAAAAAEWJGdW5jSWR4U3VwcGx5RW5kAAAAAAAAAAAHAAAAAA1iRnVuY0lkeEJSRW5kAAAAAAAAAAAIAAAAAAxiRnVuY0lkeFJlc3QAAAAAAAAAAAkAAAAAEmJGdW5jSWR4V2F2ZXNQcmljZQAAAAAAAAAACgAAAAAZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAAAAAAAAAAAQAAAAAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAAAAAAAAAACAAAAABRJZHhDb250cm9sQ2ZnUnBkRGFwcAAAAAAAAAAAAwAAAAAVSWR4Q29udHJvbENmZ01hdGhEYXBwAAAAAAAAAAAEAAAAABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAAAAAAAAAAFAAAAABVJZHhDb250cm9sQ2ZnUmVzdERhcHAAAAAAAAAAAAYAAAAAHUlkeENvbnRyb2xDZmdOb2RlUmVnaXN0cnlEYXBwAAAAAAAAAAAHAAAAABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAAAAAAAAAAIAAAAABlJZHhDb250cm9sQ2ZnTWVkaWF0b3JEYXBwAAAAAAAAAAAJAAAAABxJZHhDb250cm9sQ2ZnU3VyZlN0YWtpbmdEYXBwAAAAAAAAAAAKAAAAACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAAAAAAAAAAACwEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAptYW5kYXRvcnkgCQAEJQAAAAEFAAAAB2FkZHJlc3MCAAAAAS4FAAAAA2tleQIAAAAPIGlzIG5vdCBkZWZpbmVkAQAAABFrZXlDb250cm9sQWRkcmVzcwAAAAACAAAAHCVzJXNfX2NvbmZpZ19fY29udHJvbEFkZHJlc3MBAAAADWtleUNvbnRyb2xDZmcAAAAAAgAAABElc19fY29udHJvbENvbmZpZwEAAAAUcmVhZENvbnRyb2xDZmdPckZhaWwAAAABAAAAB2NvbnRyb2wJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAAB2NvbnRyb2wJAQAAAA1rZXlDb250cm9sQ2ZnAAAAAAUAAAADU0VQAQAAABhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwAAAACAAAACmNvbnRyb2xDZmcAAAADaWR4CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkAAZEAAAACBQAAAApjb250cm9sQ2ZnBQAAAANpZHgJAAEsAAAAAgIAAAAtQ29udHJvbCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQABpAAAAAEFAAAAA2lkeAAAAAAPY29udHJvbENvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMJAQAAABFrZXlDb250cm9sQWRkcmVzcwAAAAACAAAAIzNQNUJmZDU4UFBmTnZCTTJIeThRZmJjRHFNZU50emc3S2ZQAAAAAApjb250cm9sQ2ZnCQEAAAAUcmVhZENvbnRyb2xDZmdPckZhaWwAAAABBQAAAA9jb250cm9sQ29udHJhY3QAAAAADG1hdGhDb250cmFjdAkBAAAAGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAAAAAIFAAAACmNvbnRyb2xDZmcFAAAAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAAAAAQbmV1dHJpbm9Db250cmFjdAkBAAAAGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAAAAAIFAAAACmNvbnRyb2xDZmcFAAAAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAAAAE3N1cmZTdGFraW5nQ29udHJhY3QJAQAAABhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwAAAACBQAAAApjb250cm9sQ2ZnBQAAABxJZHhDb250cm9sQ2ZnU3VyZlN0YWtpbmdEYXBwAAAAAAhQcmljZUtleQIAAAAFcHJpY2UAAAAADk5zYnRBc3NldElkS2V5AgAAAA1ib25kX2Fzc2V0X2lkAAAAABJOZXV0cmlub0Fzc2V0SWRLZXkCAAAAEW5ldXRyaW5vX2Fzc2V0X2lkAAAAAA5TdXJmQXNzZXRJZEtleQIAAAANc3VyZl9hc3NldF9pZAAAAAARQmFsYW5jZUxvY2tlZGtLZXkCAAAADWJhbGFuY2VfbG9ja18AAAAAFVdhdmVzTG9ja2VkQmFsYW5jZUtleQkAASwAAAACBQAAABFCYWxhbmNlTG9ja2Vka0tleQIAAAAFd2F2ZXMAAAAAGE5ldXRyaW5vTG9ja2VkQmFsYW5jZUtleQkAASwAAAACBQAAABFCYWxhbmNlTG9ja2Vka0tleQIAAAAIbmV1dHJpbm8AAAAADUZpcnN0T3JkZXJLZXkCAAAAC29yZGVyX2ZpcnN0AAAAAA9NYXRoQ29udHJhY3RLZXkCAAAADW1hdGhfY29udHJhY3QAAAAAFU1pbldhdmVzRm9yTnNidEJ1eUtleQIAAAASbWluX3dhdmVzX25zYnRfYnV5AAAAAA5NaW5Oc2J0U2VsbEtleQIAAAANbWluX25zYnRfc2VsbAAAAAAVTWluV2F2ZXNGb3JTdXJmQnV5S2V5AgAAABJtaW5fd2F2ZXNfc3VyZl9idXkAAAAAFE1pblVzZG5Gb3JTdXJmQnV5S2V5AgAAABFtaW5fdXNkbl9zdXJmX2J1eQEAAAASZ2V0Um9pQnlPcmRlcklkS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAAEGRlYnVnX29yZGVyX3JvaV8FAAAAB29yZGVySWQBAAAAEGdldE9yZGVyUHJpY2VLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAAMb3JkZXJfcHJpY2VfBQAAAAdvcmRlcklkAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAADG9yZGVyX3RvdGFsXwUAAAAHb3JkZXJJZAEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAAxvcmRlcl9vd25lcl8FAAAAB29yZGVySWQBAAAAEWdldE9yZGVySGVpZ2h0S2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAADW9yZGVyX2hlaWdodF8FAAAAB29yZGVySWQBAAAAEWdldE9yZGVyU3RhdHVzS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAADW9yZGVyX3N0YXR1c18FAAAAB29yZGVySWQBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAATb3JkZXJfZmlsbGVkX3RvdGFsXwUAAAAHb3JkZXJJZAEAAAAPZ2V0UHJldk9yZGVyS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAAC29yZGVyX3ByZXZfBQAAAAdvcmRlcklkAQAAAA9nZXROZXh0T3JkZXJLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAALb3JkZXJfbmV4dF8FAAAAB29yZGVySWQBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAACAAAABmFtb3VudAAAAAVwcmljZQkAAGsAAAADBQAAAAZhbW91bnQFAAAABU1VTFQ4BQAAAAVwcmljZQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIAAAAGYW1vdW50AAAABXByaWNlCQAAawAAAAMFAAAABmFtb3VudAUAAAAFcHJpY2UFAAAABU1VTFQ4AQAAAAV0b1gxNgAAAAIAAAAHb3JpZ1ZhbAAAAA1vcmlnU2NhbGVNdWx0CQABPAAAAAMJAAE2AAAAAQUAAAAHb3JpZ1ZhbAUAAAAHTVVMVFgxNgkAATYAAAABBQAAAA1vcmlnU2NhbGVNdWx0AQAAAAdmcm9tWDE2AAAAAgAAAAN2YWwAAAAPcmVzdWx0U2NhbGVNdWx0CQABoAAAAAEJAAE8AAAAAwUAAAADdmFsCQABNgAAAAEFAAAAD3Jlc3VsdFNjYWxlTXVsdAUAAAAHTVVMVFgxNgAAAAAPbmV1dHJpbm9Bc3NldElkAQAAACC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QAAAAALbnNidEFzc2V0SWQBAAAAIFXuw76qC/BQ6HHIG6pucJ6kscj+Si65wfHMxWsPeJdLAAAAAAlpc0Jsb2NrZWQJAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0AgAAAAppc19ibG9ja2VkAAAAABVtaW5XYXZlc0Ftb3VudE5zYnRCdXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAVTWluV2F2ZXNGb3JOc2J0QnV5S2V5AAAAAAA7msoAAAAAAAttaW5Oc2J0U2VsbAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAA5NaW5Oc2J0U2VsbEtleQAAAAAAAA9CQAAAAAAVbWluV2F2ZXNBbW91bnRTdXJmQnV5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAFU1pbldhdmVzRm9yU3VyZkJ1eUtleQAAAAAABfXhAAAAAAAUbWluVXNkbkFtb3VudFN1cmZCdXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAUTWluVXNkbkZvclN1cmZCdXlLZXkAAAAAAACYloAAAAAACmZpcnN0T3JkZXIJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAADUZpcnN0T3JkZXJLZXkBAAAADWdldE9yZGVyUHJpY2UAAAABAAAAAmlkCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJQcmljZUtleQAAAAEFAAAAAmlkAQAAAA1nZXRPcmRlclRvdGFsAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEGdldE9yZGVyVG90YWxLZXkAAAABBQAAAAJpZAEAAAANZ2V0T3JkZXJPd25lcgAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQUAAAACaWQBAAAADmdldE9yZGVyU3RhdHVzAAAAAQAAAAJpZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAEWdldE9yZGVyU3RhdHVzS2V5AAAAAQUAAAACaWQBAAAAE2dldE9yZGVyRmlsbGVkVG90YWwAAAABAAAAAmlkCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEFAAAAAmlkAQAAAAxnZXRQcmV2T3JkZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAPZ2V0UHJldk9yZGVyS2V5AAAAAQUAAAACaWQBAAAADGdldE5leHRPcmRlcgAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAAA9nZXROZXh0T3JkZXJLZXkAAAABBQAAAAJpZAEAAAAPZ2V0UmV2ZXJzZVByaWNlAAAAAQAAAAVwcmljZQkAAGkAAAACCQAAaAAAAAIFAAAABU1VTFQ2BQAAAAVNVUxUNgUAAAAFcHJpY2UBAAAAFmNhbGNOc2J0MldhdmVzUHJpY2VSYXcAAAACAAAADXNwZW50V2F2ZXNSYXcAAAAPcmVjZWl2ZWROc2J0UmF3CQABPAAAAAMJAAE2AAAAAQUAAAANc3BlbnRXYXZlc1JhdwkAATYAAAABCQAAaAAAAAIFAAAABU1VTFQ2BQAAAAVNVUxUNgkAATYAAAABBQAAAA9yZWNlaXZlZE5zYnRSYXcBAAAACW9yZGVyRGF0YQAAAAgAAAAHb3JkZXJJZAAAAA10b3RhbFdhdmVsZXRzAAAADmZpbGxlZFdhdmVsZXRzAAAABW93bmVyAAAABnN0YXR1cwAAAANyb2kAAAAFcHJpY2UAAAAMY3VycmVudFByaWNlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABBnZXRPcmRlclByaWNlS2V5AAAAAQUAAAAHb3JkZXJJZAkAAaYAAAABBQAAAAVwcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAEGdldE9yZGVyVG90YWxLZXkAAAABBQAAAAdvcmRlcklkBQAAAA10b3RhbFdhdmVsZXRzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEFAAAAB29yZGVySWQFAAAADmZpbGxlZFdhdmVsZXRzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAAFb3duZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABFnZXRPcmRlckhlaWdodEtleQAAAAEFAAAAB29yZGVySWQFAAAABmhlaWdodAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAdvcmRlcklkBQAAAAZzdGF0dXMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgIAAAAZZGVidWdfb3JkZXJfY3VycmVudFByaWNlXwUAAAAHb3JkZXJJZAUAAAAMY3VycmVudFByaWNlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAASZ2V0Um9pQnlPcmRlcklkS2V5AAAAAQUAAAAHb3JkZXJJZAUAAAADcm9pBQAAAANuaWwBAAAABXRvU3RyAAAAAgAAAARuYW1lAAAAC2N1cnZlUmVzdWx0CQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgUAAAAEbmFtZQIAAAAPW25zYnRBbW91bnRSYXc9CQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAALY3VydmVSZXN1bHQAAAAAAAAAAAACAAAADSB1c2RuUGF5bWVudD0JAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAAtjdXJ2ZVJlc3VsdAAAAAAAAAAAAQIAAAAGIHdSYXc9CQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAALY3VydmVSZXN1bHQAAAAAAAAAAAICAAAABiB1UmF3PQkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAADAgAAAAYgbVJhdz0JAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAAtjdXJ2ZVJlc3VsdAAAAAAAAAAABAIAAAAGIHNSYXc9CQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAALY3VydmVSZXN1bHQAAAAAAAAAAAUCAAAAEiBuc2J0Q3VydmVQYXJhbV9hPQkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAGAgAAABIgbnNidEN1cnZlUGFyYW1fYj0JAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAAtjdXJ2ZVJlc3VsdAAAAAAAAAAABwIAAAARIHdSZXNlcnZlc0luVXNkbj0JAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAAtjdXJ2ZVJlc3VsdAAAAAAAAAAACAIAAAAHIHByaWNlPQkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAJAgAAAAggbXVsdEJSPQkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAKAgAAAAsgbXVsdFBvd2VyPQkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAALAgAAABAgbXVsdEV4cEluUG93ZXI9CQEAAAAIYXNTdHJpbmcAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAMAgAAAAcgbXVsdEs9CQEAAAAIYXNTdHJpbmcAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAANAgAAAAcgc3RlcDE9CQEAAAAIYXNTdHJpbmcAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAOAgAAAAcgc3RlcDI9CQEAAAAIYXNTdHJpbmcAAAABCQABkQAAAAIFAAAAC2N1cnZlUmVzdWx0AAAAAAAAAAAPAgAAAAcgc3RlcDM9CQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAALY3VydmVSZXN1bHQAAAAAAAAAABACAAAAAV0BAAAACHN1cmZEYXRhAAAAAQAAAApzdXJmUmVzdWx0CQEAAAALU3RyaW5nRW50cnkAAAACAgAAABBkZWJ1Z19zdXJmUmVzdWx0CQAEuQAAAAIJAARMAAAAAgIAAAAWJWQlZCVkJWQlZCVkJWQlZCVkJWQlZAkABEwAAAACCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAAKc3VyZlJlc3VsdAUAAAAMYkZ1bmNJZHhTdXJmCQAETAAAAAIJAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAApzdXJmUmVzdWx0BQAAAA1iRnVuY0lkeFdhdmVzCQAETAAAAAIJAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAApzdXJmUmVzdWx0BQAAAAxiRnVuY0lkeFVzZG4JAARMAAAAAgkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAACnN1cmZSZXN1bHQFAAAAFGJGdW5jSWR4UmVzZXJ2ZVN0YXJ0CQAETAAAAAIJAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAApzdXJmUmVzdWx0BQAAABNiRnVuY0lkeFN1cHBseVN0YXJ0CQAETAAAAAIJAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAApzdXJmUmVzdWx0BQAAAA9iRnVuY0lkeEJSU3RhcnQJAARMAAAAAgkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAACnN1cmZSZXN1bHQFAAAAEmJGdW5jSWR4UmVzZXJ2ZUVuZAkABEwAAAACCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAAKc3VyZlJlc3VsdAUAAAARYkZ1bmNJZHhTdXBwbHlFbmQJAARMAAAAAgkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAACnN1cmZSZXN1bHQFAAAADWJGdW5jSWR4QlJFbmQJAARMAAAAAgkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAACnN1cmZSZXN1bHQFAAAADGJGdW5jSWR4UmVzdAkABEwAAAACCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAAKc3VyZlJlc3VsdAUAAAASYkZ1bmNJZHhXYXZlc1ByaWNlBQAAAANuaWwFAAAAA1NFUAAAAAsAAAABaQEAAAALY29uc3RydWN0b3IAAAADAAAAE21hdGhDb250cmFjdEFkZHJlc3MAAAASbWluV2F2ZXNGb3JOc2J0QnV5AAAAC21pbk5zYnRTZWxsAwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAAR0aGlzCQAAAgAAAAECAAAAEVBlcm1pc3Npb24gZGVuaWVkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAD01hdGhDb250cmFjdEtleQUAAAATbWF0aENvbnRyYWN0QWRkcmVzcwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAOTWluTnNidFNlbGxLZXkFAAAAC21pbk5zYnRTZWxsCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVNaW5XYXZlc0Zvck5zYnRCdXlLZXkFAAAAEm1pbldhdmVzRm9yTnNidEJ1eQUAAAADbmlsAAAAAWkBAAAADWNvbnN0cnVjdG9yVjIAAAADAAAAFW1pbldhdmVzRm9yU3VyZkJ1eUtleQAAABRtaW5Vc2RuRm9yU3VyZkJ1eUtleQAAAAtkZXNjcmlwdGlvbgMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAQAAAAFaXNzdWUJAARDAAAABwIAAAAEU1VSRgUAAAALZGVzY3JpcHRpb24AAAAAAAAAAAAAAAAAAAAAAAYGBQAAAAR1bml0AAAAAAAAAAAABAAAAAdhc3NldElkCQAEOAAAAAEFAAAABWlzc3VlCQAETAAAAAIFAAAABWlzc3VlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADlN1cmZBc3NldElkS2V5CQACWAAAAAEFAAAAB2Fzc2V0SWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFU1pbldhdmVzRm9yU3VyZkJ1eUtleQUAAAAVbWluV2F2ZXNGb3JTdXJmQnV5S2V5CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABRNaW5Vc2RuRm9yU3VyZkJ1eUtleQUAAAAUbWluVXNkbkZvclN1cmZCdXlLZXkFAAAAA25pbAAAAAFpAQAAAAdidXlOc2J0AAAAAAQAAAADcG10CQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAlwbXRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50BAAAAAh3YXZlc1BheQUAAAAJcG10QW1vdW50AwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAWWNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAwkBAAAACWlzRGVmaW5lZAAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAkAAAIAAAABAgAAABJjYW4gdXNlIHdhdmVzIG9ubHkDCQAAZgAAAAIFAAAAFW1pbldhdmVzQW1vdW50TnNidEJ1eQUAAAAJcG10QW1vdW50CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAARtaW4gCQABpAAAAAEJAABpAAAAAgUAAAAVbWluV2F2ZXNBbW91bnROc2J0QnV5BQAAAAVNVUxUOAIAAAAPIHdhdmVzIGV4cGVjdGVkBAAAAAxvd25lckFkZHJlc3MIBQAAAAFpAAAABmNhbGxlcgQAAAAPbmV1dHJpbm9NZXRyaWNzCQEAAAAJYXNBbnlMaXN0AAAAAQkAA/wAAAAEBQAAAAxtYXRoQ29udHJhY3QCAAAAGmNhbGNOZXV0aW5vTWV0cmljc1JFQURPTkxZBQAAAANuaWwFAAAAA25pbAQAAAAMY3VycmVudFByaWNlCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAD25ldXRyaW5vTWV0cmljcwAAAAAAAAAAAAQAAAALY3VydmVSZXN1bHQJAQAAAAlhc0FueUxpc3QAAAABCQAD/AAAAAQFAAAADG1hdGhDb250cmFjdAIAAAAVY3VydmVGdW5jdGlvblJFQURPTkxZCQAETAAAAAIFAAAACHdhdmVzUGF5BQAAAANuaWwFAAAAA25pbAQAAAAKbnNidEFtb3VudAkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAAAtjdXJ2ZVJlc3VsdAAAAAAAAAAAAAMJAABnAAAAAgAAAAAAAAAAAAUAAAAKbnNidEFtb3VudAkAAAIAAAABAgAAAA9uc2J0QW1vdW50IDw9IDAEAAAAEm5zYnQyV2F2ZXNQcmljZVJhdwkBAAAAFmNhbGNOc2J0MldhdmVzUHJpY2VSYXcAAAACBQAAAAh3YXZlc1BheQUAAAAKbnNidEFtb3VudAQAAAADcm9pAAAAAAAAAAAABAAAAAxhbW91bnRMZWFzZWQJAAP8AAAABAUAAAAQbmV1dHJpbm9Db250cmFjdAIAAAALYWNjZXB0V2F2ZXMFAAAAA25pbAgFAAAAAWkAAAAIcGF5bWVudHMDCQAAAAAAAAIFAAAADGFtb3VudExlYXNlZAUAAAAMYW1vdW50TGVhc2VkCQAFFAAAAAIJAAROAAAAAgkBAAAACW9yZGVyRGF0YQAAAAgJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAAJcG10QW1vdW50BQAAAAlwbXRBbW91bnQJAAQlAAAAAQUAAAAMb3duZXJBZGRyZXNzBQAAAAZGSUxMRUQFAAAAA3JvaQUAAAASbnNidDJXYXZlc1ByaWNlUmF3BQAAAAxjdXJyZW50UHJpY2UJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAMb3duZXJBZGRyZXNzBQAAAApuc2J0QW1vdW50BQAAAAtuc2J0QXNzZXRJZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACAgAAABFkZWJ1Z19jdXJ2ZVJlc3VsdAkBAAAABXRvU3RyAAAAAgIAAAALY3VydmVSZXN1bHQFAAAAC2N1cnZlUmVzdWx0BQAAAANuaWwFAAAACm5zYnRBbW91bnQJAAACAAAAAQIAAAAkU3Ry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bnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAABmFtb3VudAUAAAAEdW5pdAUAAAADbmlsAAAAAWkBAAAAIG1pbldhdmVzQW1vdW50TnNidEJ1eVNZU1JFQURPTkxZAAAAAAkABRQAAAACBQAAAANuaWwFAAAAFW1pbldhdmVzQW1vdW50TnNidEJ1eQAAAAFpAQAAAB9taW5Oc2J0QW1vdW50Rm9yU2VsbFNZU1JFQURPTkxZAAAAAAkABRQAAAACBQAAAANuaWwFAAAAC21pbk5zYnRTZWxsAAAAAWkBAAAAIG1pbldhdmVzQW1vdW50U3VyZkJ1eVNZU1JFQURPTkxZAAAAAAkABRQAAAACBQAAAANuaWwFAAAAFW1pbldhdmVzQW1vdW50U3VyZkJ1eQAAAAFpAQAAAB9taW5Vc2RuQW1vdW50U3VyZkJ1eVNZU1JFQURPTkxZAAAAAAkABRQAAAACBQAAAANuaWwFAAAAFG1pblVzZG5BbW91bnRTdXJmQnV5AAAAAWkBAAAAB2J1eVN1cmYAAAADAAAAEmF2ZXJhZ2VQcmljZVdhbnRlZAAAABBtYXhUb2xlcmFuY2VQZXJjAAAACWF1dG9TdGFrZQQAAAAMdGVzdEFjY291bnRzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMCAAAADHRlc3RBY2NvdW50cwIAAAAAAwMJAQAAAAIhPQAAAAIFAAAADHRlc3RBY2NvdW50cwIAAAAACQEAAAABIQAAAAEJAQAAAAhjb250YWlucwAAAAIFAAAADHRlc3RBY2NvdW50cwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIHCQAAAgAAAAECAAAAMkJlIHBhdGllbnQhIE5lZWQgdG8gdGVzdCBpbiBtYWlubmV0IGJlZm9yZSBsYXVuY2guAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQkAAAIAAAABAgAAACJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkAwkAAGcAAAACAAAAAAAAAAAABQAAABJhdmVyYWdlUHJpY2VXYW50ZWQJAAACAAAAAQIAAAAlYXZlcmFnZVByaWNlV2FudGVkIHNob3VsZCBiZSBwb3Np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AAAKc3Rha2luZ0ludgkAA/wAAAAEBQAAABNzdXJmU3Rha2luZ0NvbnRyYWN0AgAAABNzdGFrZUJ5T3JpZ2luQ2FsbGVyBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAAC3N1cmZBc3NldElkBQAAAApzdXJmQW1vdW50BQAAAANuaWwDCQAAAAAAAAIFAAAACnN0YWtpbmdJbnYFAAAACnN0YWtpbmdJbnYFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAApzdXJmQW1vdW50BQAAAAtzdXJmQXNzZXRJZAUAAAADbmlsCQAETgAAAAIJAAROAAAAAgUAAAAIdHJhbnNmZXIJAARMAAAAAgkBAAAACHN1cmZEYXRhAAAAAQUAAAAKc3VyZlJlc3VsdAUAAAADbmlsBQAAAApzdXJmQWN0aW9uAAAAAWkBAAAACWlzc3VlU3VyZgAAAAEAAAAKc3VyZkFtb3VudAQAAAALc3VyZkFzc2V0SWQJAAJZAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTgpAAAAAQUAAAAOU3VyZkFzc2V0SWRLZXkDCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAABHRoaXMJAAACAAAAAQIAAAAdaXNzdWVTdXJmIC0gcGVybWlzc2lvbiBkZW5pZWQJAAUUAAAAAgkABEwAAAACCQEAAAAHUmVpc3N1ZQAAAAMFAAAAC3N1cmZBc3NldElkBQAAAApzdXJmQW1vdW50BgUAAAADbmlsBQAAAAtzdXJmQXNzZXRJZAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAE3B1YktleUFkbWluc0xpc3RTdHIJAAS5AAAAAgkABEwAAAACAgAAACxHSmRMU2FMaXY1Szd4dWVqYWM4bWNSY0hveW8zZFByRVNydmt0RzNhNk1BUgkABEwAAAACAgAAACxFWXdabVVSZDVLS2FRUkJqc1ZhNmc4RFBpc0ZvUzZTb3ZSSnRGaUw1Z01IVQkABEwAAAACAgAAACxEdG1BZnVEZENySEs4c3BkQWVBWXpxNk1zWmVnZUQ5Z25zcnB1VFJrQ2JWQQkABEwAAAACAgAAACw1V1JYRlNqd2NUYk5mS2NKczhacVhtU1NXWXNTVkpVdE12TXFaajVoSDROYwUAAAADbmlsBQAAAANTRVAEAAAAEHB1YktleUFkbWluc0xpc3QJAAS1AAAAAgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAA9jb250cm9sQ29udHJhY3QCAAAADCVzX19tdWx0aXNpZwUAAAATcHViS2V5QWRtaW5zTGlzdFN0cgUAAAADU0VQBAAAAAVjb3VudAkAAGQAAAACCQAAZAAAAAIJAABkAAAAAgMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAgAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAADCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAwAAAAAAAAAAAgAAAAAAAAAAAAkAAGcAAAACBQAAAAVjb3VudAAAAAAAAAAAA8cE9Ik=", "chainId": 87, "height": 3242746, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3tpZgRYUYK6YJFLPSpadCRBRZ1zSAocVHPiuLzpJEDiV Next: 3t2bviu8ud1sLgjme86Z8dMQ6thbTUiF4Dcow9PMJ8Ch Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "cbd0bdc8bbba91db64066b16a84913a4c965e23e"
4+let revisionNum = "467d69db0b60c6aac0508e687248cd588338fb34"
55
66 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
77
404404 then throw("averagePriceWanted should be positive")
405405 else if ((0 >= maxTolerancePerc))
406406 then throw("maxTolerancePerc should be positive")
407- else {
408- let pmt = i.payments[0]
409- let amt = pmt.amount
410- let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
411- if (if ((pmtAssetId != neutrinoAssetId))
412- then (pmtAssetId != WAVESID)
413- else false)
414- then throw("Unsupported payment asset")
415- else if (if ((pmtAssetId == neutrinoAssetId))
416- then (minUsdnAmountSurfBuy > amt)
407+ else if (isBlocked)
408+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
409+ else {
410+ let pmt = i.payments[0]
411+ let amt = pmt.amount
412+ let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
413+ if (if ((pmtAssetId != neutrinoAssetId))
414+ then (pmtAssetId != WAVESID)
417415 else false)
418- then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
419- else if (if ((pmtAssetId == WAVESID))
420- then (minWavesAmountSurfBuy > amt)
416+ then throw("Unsupported payment asset")
417+ else if (if ((pmtAssetId == neutrinoAssetId))
418+ then (minUsdnAmountSurfBuy > amt)
421419 else false)
422- then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
423- else {
424- let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
425- let spentWaves = asInt(surfResult[bFuncIdxWaves])
426- let spentUsdn = asInt(surfResult[bFuncIdxUsdn])
427- let surfAmount = asInt(surfResult[bFuncIdxSurf])
428- let surfAmountX6 = toBigInt(surfAmount)
429- let spentActualX18 = if ((pmtAssetId == WAVESID))
430- then (toBigInt(spentWaves) * MULTX10)
431- else (toBigInt(spentUsdn) * MULTX12)
432- if ((spentActualX18 > ((toBigInt((maxTolerancePerc + MULT6)) * toBigInt(averagePriceWanted)) * surfAmountX6)))
433- then throw((((((("Tolerance " + toString(maxTolerancePerc)) + " exceeded: spent ") + (if ((pmtAssetId == WAVESID))
434- then (toString(spentWaves) + " WAVES")
435- else (toString(spentUsdn) + " USDN"))) + " for ") + toString(surfAmount)) + " SURF"))
436- else {
437- let rest = asInt(surfResult[bFuncIdxRest])
438- let transfer = if ((pmtAssetId == WAVESID))
439- then {
440- let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - rest))])
441- if ((wavesAmt == wavesAmt))
442- then if ((rest > 0))
443- then [ScriptTransfer(i.caller, rest, unit)]
444- else nil
445- else throw("Strict value is not equal to itself.")
446- }
447- else if ((rest > 0))
448- then [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId), ScriptTransfer(i.caller, rest, neutrinoAssetId)]
449- else [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId)]
450- let surfAssetId = asBytes(invoke(this, "issueSurf", [surfAmount], nil))
451- let surfAction = if (autoStake)
452- then {
453- let stakingInv = invoke(surfStakingContract, "stakeByOriginCaller", nil, [AttachedPayment(surfAssetId, surfAmount)])
454- if ((stakingInv == stakingInv))
455- then nil
456- else throw("Strict value is not equal to itself.")
457- }
458- else [ScriptTransfer(i.caller, surfAmount, surfAssetId)]
459- ((transfer ++ [surfData(surfResult)]) ++ surfAction)
460- }
461- }
462- }
420+ then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
421+ else if (if ((pmtAssetId == WAVESID))
422+ then (minWavesAmountSurfBuy > amt)
423+ else false)
424+ then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
425+ else {
426+ let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
427+ let spentWaves = asInt(surfResult[bFuncIdxWaves])
428+ let spentUsdn = asInt(surfResult[bFuncIdxUsdn])
429+ let surfAmount = asInt(surfResult[bFuncIdxSurf])
430+ let surfAmountX6 = toBigInt(surfAmount)
431+ let spentActualX18 = if ((pmtAssetId == WAVESID))
432+ then (toBigInt(spentWaves) * MULTX10)
433+ else (toBigInt(spentUsdn) * MULTX12)
434+ if ((spentActualX18 > ((toBigInt((maxTolerancePerc + MULT6)) * toBigInt(averagePriceWanted)) * surfAmountX6)))
435+ then throw((((((("Tolerance " + toString(maxTolerancePerc)) + " exceeded: spent ") + (if ((pmtAssetId == WAVESID))
436+ then (toString(spentWaves) + " WAVES")
437+ else (toString(spentUsdn) + " USDN"))) + " for ") + toString(surfAmount)) + " SURF"))
438+ else {
439+ let rest = asInt(surfResult[bFuncIdxRest])
440+ let transfer = if ((pmtAssetId == WAVESID))
441+ then {
442+ let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - rest))])
443+ if ((wavesAmt == wavesAmt))
444+ then if ((rest > 0))
445+ then [ScriptTransfer(i.caller, rest, unit)]
446+ else nil
447+ else throw("Strict value is not equal to itself.")
448+ }
449+ else if ((rest > 0))
450+ then [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId), ScriptTransfer(i.caller, rest, neutrinoAssetId)]
451+ else [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId)]
452+ let surfAssetId = asBytes(invoke(this, "issueSurf", [surfAmount], nil))
453+ let surfAction = if (autoStake)
454+ then {
455+ let stakingInv = invoke(surfStakingContract, "stakeByOriginCaller", nil, [AttachedPayment(surfAssetId, surfAmount)])
456+ if ((stakingInv == stakingInv))
457+ then nil
458+ else throw("Strict value is not equal to itself.")
459+ }
460+ else [ScriptTransfer(i.caller, surfAmount, surfAssetId)]
461+ ((transfer ++ [surfData(surfResult)]) ++ surfAction)
462+ }
463+ }
464+ }
463465 }
464466
465467
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = "cbd0bdc8bbba91db64066b16a84913a4c965e23e"
4+let revisionNum = "467d69db0b60c6aac0508e687248cd588338fb34"
55
66 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
77
88
99 func getStringByKey (key) = valueOrElse(getString(this, key), "")
1010
1111
1212 func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(address, key), false)
1313
1414
1515 func getStringByAddressAndKey (address,key) = valueOrElse(getString(address, key), "")
1616
1717
1818 func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(address, key), 0)
1919
2020
2121 func asAnyList (val) = match val {
2222 case valAnyLyst: List[Any] =>
2323 valAnyLyst
2424 case _ =>
2525 throw("fail to cast into List[Any]")
2626 }
2727
2828
2929 func asString (val) = match val {
3030 case valStr: String =>
3131 valStr
3232 case _ =>
3333 throw("fail to cast into String")
3434 }
3535
3636
3737 func asInt (val) = match val {
3838 case valInt: Int =>
3939 valInt
4040 case _ =>
4141 throw("fail to cast into Int")
4242 }
4343
4444
4545 func asBytes (val) = match val {
4646 case valByte: ByteVector =>
4747 valByte
4848 case _ =>
4949 throw("fail to cast into Int")
5050 }
5151
5252
5353 let SEP = "__"
5454
5555 let MULT6 = 1000000
5656
5757 let MULT8 = 100000000
5858
5959 let MULTX10 = toBigInt(10000000000)
6060
6161 let MULTX12 = toBigInt(1000000000000)
6262
6363 let MULTX16 = toBigInt(10000000000000000)
6464
6565 let CANCELED = "canceled"
6666
6767 let NEW = "new"
6868
6969 let FILLED = "filled"
7070
7171 let WAVESID = fromBase58String("WAVES")
7272
7373 let nMetricIdxPrice = 0
7474
7575 let nMetricIdxUsdnLockedBalance = 1
7676
7777 let nMetricIdxWavesLockedBalance = 2
7878
7979 let nMetricIdxReserve = 3
8080
8181 let nMetricIdxReserveInUsdn = 4
8282
8383 let nMetricIdxUsdnSupply = 5
8484
8585 let nMetricIdxSurplus = 6
8686
8787 let nMetricIdxSurplusPercent = 7
8888
8989 let nMetricIdxBR = 8
9090
9191 let nMetricIdxNsbtSupply = 9
9292
9393 let nMetricIdxMaxNsbtSupply = 10
9494
9595 let nMetricIdxSurfSupply = 11
9696
9797 let bFuncIdxSurf = 0
9898
9999 let bFuncIdxWaves = 1
100100
101101 let bFuncIdxUsdn = 2
102102
103103 let bFuncIdxReserveStart = 3
104104
105105 let bFuncIdxSupplyStart = 4
106106
107107 let bFuncIdxBRStart = 5
108108
109109 let bFuncIdxReserveEnd = 6
110110
111111 let bFuncIdxSupplyEnd = 7
112112
113113 let bFuncIdxBREnd = 8
114114
115115 let bFuncIdxRest = 9
116116
117117 let bFuncIdxWavesPrice = 10
118118
119119 let IdxControlCfgNeutrinoDapp = 1
120120
121121 let IdxControlCfgAuctionDapp = 2
122122
123123 let IdxControlCfgRpdDapp = 3
124124
125125 let IdxControlCfgMathDapp = 4
126126
127127 let IdxControlCfgLiquidationDapp = 5
128128
129129 let IdxControlCfgRestDapp = 6
130130
131131 let IdxControlCfgNodeRegistryDapp = 7
132132
133133 let IdxControlCfgNsbtStakingDapp = 8
134134
135135 let IdxControlCfgMediatorDapp = 9
136136
137137 let IdxControlCfgSurfStakingDapp = 10
138138
139139 let IdxControlCfgGnsbtControllerDapp = 11
140140
141141 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
142142
143143
144144 func keyControlAddress () = "%s%s__config__controlAddress"
145145
146146
147147 func keyControlCfg () = "%s__controlConfig"
148148
149149
150150 func readControlCfgOrFail (control) = split(getStringOrFail(control, keyControlCfg()), SEP)
151151
152152
153153 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
154154
155155
156156 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
157157
158158 let controlCfg = readControlCfgOrFail(controlContract)
159159
160160 let mathContract = getContractAddressOrFail(controlCfg, IdxControlCfgMathDapp)
161161
162162 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
163163
164164 let surfStakingContract = getContractAddressOrFail(controlCfg, IdxControlCfgSurfStakingDapp)
165165
166166 let PriceKey = "price"
167167
168168 let NsbtAssetIdKey = "bond_asset_id"
169169
170170 let NeutrinoAssetIdKey = "neutrino_asset_id"
171171
172172 let SurfAssetIdKey = "surf_asset_id"
173173
174174 let BalanceLockedkKey = "balance_lock_"
175175
176176 let WavesLockedBalanceKey = (BalanceLockedkKey + "waves")
177177
178178 let NeutrinoLockedBalanceKey = (BalanceLockedkKey + "neutrino")
179179
180180 let FirstOrderKey = "order_first"
181181
182182 let MathContractKey = "math_contract"
183183
184184 let MinWavesForNsbtBuyKey = "min_waves_nsbt_buy"
185185
186186 let MinNsbtSellKey = "min_nsbt_sell"
187187
188188 let MinWavesForSurfBuyKey = "min_waves_surf_buy"
189189
190190 let MinUsdnForSurfBuyKey = "min_usdn_surf_buy"
191191
192192 func getRoiByOrderIdKey (orderId) = ("debug_order_roi_" + orderId)
193193
194194
195195 func getOrderPriceKey (orderId) = ("order_price_" + orderId)
196196
197197
198198 func getOrderTotalKey (orderId) = ("order_total_" + orderId)
199199
200200
201201 func getOrderOwnerKey (orderId) = ("order_owner_" + orderId)
202202
203203
204204 func getOrderHeightKey (orderId) = ("order_height_" + orderId)
205205
206206
207207 func getOrderStatusKey (orderId) = ("order_status_" + orderId)
208208
209209
210210 func getOrderFilledTotalKey (orderId) = ("order_filled_total_" + orderId)
211211
212212
213213 func getPrevOrderKey (orderId) = ("order_prev_" + orderId)
214214
215215
216216 func getNextOrderKey (orderId) = ("order_next_" + orderId)
217217
218218
219219 func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
220220
221221
222222 func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
223223
224224
225225 func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULTX16, toBigInt(origScaleMult))
226226
227227
228228 func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULTX16))
229229
230230
231231 let neutrinoAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
232232
233233 let nsbtAssetId = base58'6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g'
234234
235235 let isBlocked = getBoolByAddressAndKey(controlContract, "is_blocked")
236236
237237 let minWavesAmountNsbtBuy = valueOrElse(getInteger(this, MinWavesForNsbtBuyKey), 1000000000)
238238
239239 let minNsbtSell = valueOrElse(getInteger(this, MinNsbtSellKey), 1000000)
240240
241241 let minWavesAmountSurfBuy = valueOrElse(getInteger(this, MinWavesForSurfBuyKey), 100000000)
242242
243243 let minUsdnAmountSurfBuy = valueOrElse(getInteger(this, MinUsdnForSurfBuyKey), 10000000)
244244
245245 let firstOrder = getStringByKey(FirstOrderKey)
246246
247247 func getOrderPrice (id) = getNumberByKey(getOrderPriceKey(id))
248248
249249
250250 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
251251
252252
253253 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
254254
255255
256256 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
257257
258258
259259 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
260260
261261
262262 func getPrevOrder (id) = getStringByKey(getPrevOrderKey(id))
263263
264264
265265 func getNextOrder (id) = getStringByKey(getNextOrderKey(id))
266266
267267
268268 func getReversePrice (price) = ((MULT6 * MULT6) / price)
269269
270270
271271 func calcNsbt2WavesPriceRaw (spentWavesRaw,receivedNsbtRaw) = fraction(toBigInt(spentWavesRaw), toBigInt((MULT6 * MULT6)), toBigInt(receivedNsbtRaw))
272272
273273
274274 func orderData (orderId,totalWavelets,filledWavelets,owner,status,roi,price,currentPrice) = [StringEntry(getOrderPriceKey(orderId), toString(price)), IntegerEntry(getOrderTotalKey(orderId), totalWavelets), IntegerEntry(getOrderFilledTotalKey(orderId), filledWavelets), StringEntry(getOrderOwnerKey(orderId), owner), IntegerEntry(getOrderHeightKey(orderId), height), StringEntry(getOrderStatusKey(orderId), status), IntegerEntry(("debug_order_currentPrice_" + orderId), currentPrice), IntegerEntry(getRoiByOrderIdKey(orderId), roi)]
275275
276276
277277 func toStr (name,curveResult) = (((((((((((((((((((((((((((((((((((name + "[nsbtAmountRaw=") + toString(asInt(curveResult[0]))) + " usdnPayment=") + toString(asInt(curveResult[1]))) + " wRaw=") + toString(asInt(curveResult[2]))) + " uRaw=") + toString(asInt(curveResult[3]))) + " mRaw=") + toString(asInt(curveResult[4]))) + " sRaw=") + toString(asInt(curveResult[5]))) + " nsbtCurveParam_a=") + toString(asInt(curveResult[6]))) + " nsbtCurveParam_b=") + toString(asInt(curveResult[7]))) + " wReservesInUsdn=") + toString(asInt(curveResult[8]))) + " price=") + toString(asInt(curveResult[9]))) + " multBR=") + toString(asInt(curveResult[10]))) + " multPower=") + toString(asInt(curveResult[11]))) + " multExpInPower=") + asString(curveResult[12])) + " multK=") + asString(curveResult[13])) + " step1=") + asString(curveResult[14])) + " step2=") + asString(curveResult[15])) + " step3=") + toString(asInt(curveResult[16]))) + "]")
278278
279279
280280 func surfData (surfResult) = StringEntry("debug_surfResult", makeString(["%d%d%d%d%d%d%d%d%d%d%d", toString(asInt(surfResult[bFuncIdxSurf])), toString(asInt(surfResult[bFuncIdxWaves])), toString(asInt(surfResult[bFuncIdxUsdn])), toString(asInt(surfResult[bFuncIdxReserveStart])), toString(asInt(surfResult[bFuncIdxSupplyStart])), toString(asInt(surfResult[bFuncIdxBRStart])), toString(asInt(surfResult[bFuncIdxReserveEnd])), toString(asInt(surfResult[bFuncIdxSupplyEnd])), toString(asInt(surfResult[bFuncIdxBREnd])), toString(asInt(surfResult[bFuncIdxRest])), toString(asInt(surfResult[bFuncIdxWavesPrice]))], SEP))
281281
282282
283283 @Callable(i)
284284 func constructor (mathContractAddress,minWavesForNsbtBuy,minNsbtSell) = if ((i.caller != this))
285285 then throw("Permission denied")
286286 else [StringEntry(MathContractKey, mathContractAddress), IntegerEntry(MinNsbtSellKey, minNsbtSell), IntegerEntry(MinWavesForNsbtBuyKey, minWavesForNsbtBuy)]
287287
288288
289289
290290 @Callable(i)
291291 func constructorV2 (minWavesForSurfBuyKey,minUsdnForSurfBuyKey,description) = if ((i.caller != this))
292292 then throw("Permission denied")
293293 else {
294294 let issue = Issue("SURF", description, 0, 6, true, unit, 0)
295295 let assetId = calculateAssetId(issue)
296296 [issue, StringEntry(SurfAssetIdKey, toBase58String(assetId)), IntegerEntry(MinWavesForSurfBuyKey, minWavesForSurfBuyKey), IntegerEntry(MinUsdnForSurfBuyKey, minUsdnForSurfBuyKey)]
297297 }
298298
299299
300300
301301 @Callable(i)
302302 func buyNsbt () = {
303303 let pmt = value(i.payments[0])
304304 let pmtAmount = pmt.amount
305305 let wavesPay = pmtAmount
306306 if (isBlocked)
307307 then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
308308 else if (isDefined(pmt.assetId))
309309 then throw("can use waves only")
310310 else if ((minWavesAmountNsbtBuy > pmtAmount))
311311 then throw((("min " + toString((minWavesAmountNsbtBuy / MULT8))) + " waves expected"))
312312 else {
313313 let ownerAddress = i.caller
314314 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
315315 let currentPrice = asInt(neutrinoMetrics[0])
316316 let curveResult = asAnyList(invoke(mathContract, "curveFunctionREADONLY", [wavesPay], nil))
317317 let nsbtAmount = asInt(curveResult[0])
318318 if ((0 >= nsbtAmount))
319319 then throw("nsbtAmount <= 0")
320320 else {
321321 let nsbt2WavesPriceRaw = calcNsbt2WavesPriceRaw(wavesPay, nsbtAmount)
322322 let roi = 0
323323 let amountLeased = invoke(neutrinoContract, "acceptWaves", nil, i.payments)
324324 if ((amountLeased == amountLeased))
325325 then $Tuple2((orderData(toBase58String(i.transactionId), pmtAmount, pmtAmount, toString(ownerAddress), FILLED, roi, nsbt2WavesPriceRaw, currentPrice) ++ [ScriptTransfer(ownerAddress, nsbtAmount, nsbtAssetId), StringEntry("debug_curveResult", toStr("curveResult", curveResult))]), nsbtAmount)
326326 else throw("Strict value is not equal to itself.")
327327 }
328328 }
329329 }
330330
331331
332332
333333 @Callable(i)
334334 func sellNsbt () = if (isBlocked)
335335 then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
336336 else {
337337 let pmt = value(i.payments[0])
338338 let pmtAmount = pmt.amount
339339 if ((pmt.assetId != nsbtAssetId))
340340 then throw("can use NSBT only")
341341 else if ((minNsbtSell > pmtAmount))
342342 then throw((("min " + toString((minNsbtSell / MULT6))) + " nsbt expected"))
343343 else {
344344 let newPrice = asInt(asAnyList(invoke(mathContract, "calcContractNsbtPriceSYSREADONLY", [-(pmtAmount)], nil))[0])
345345 if ((MULT6 > newPrice))
346346 then throw((("resulting nsbt price would be < 1 (" + toString(newPrice)) + " usdn)"))
347347 else {
348348 let transf = invoke(neutrinoContract, "transferUsdnToUser", [pmtAmount, toString(i.caller)], nil)
349349 if ((transf == transf))
350350 then $Tuple2(nil, newPrice)
351351 else throw("Strict value is not equal to itself.")
352352 }
353353 }
354354 }
355355
356356
357357
358358 @Callable(i)
359359 func cancelOrder (orderId) = {
360360 let owner = getOrderOwner(orderId)
361361 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
362362 let caller = toString(i.caller)
363363 let nextOrder = getNextOrder(orderId)
364364 let prevOrder = getPrevOrder(orderId)
365365 if ((getOrderStatus(orderId) != NEW))
366366 then throw("invalid order status")
367367 else [StringEntry(FirstOrderKey, if ((firstOrder == orderId))
368368 then nextOrder
369369 else firstOrder), StringEntry(getNextOrderKey(prevOrder), nextOrder), StringEntry(getPrevOrderKey(nextOrder), prevOrder), StringEntry(getOrderStatusKey(orderId), CANCELED), ScriptTransfer(i.caller, amount, unit)]
370370 }
371371
372372
373373
374374 @Callable(i)
375375 func minWavesAmountNsbtBuySYSREADONLY () = $Tuple2(nil, minWavesAmountNsbtBuy)
376376
377377
378378
379379 @Callable(i)
380380 func minNsbtAmountForSellSYSREADONLY () = $Tuple2(nil, minNsbtSell)
381381
382382
383383
384384 @Callable(i)
385385 func minWavesAmountSurfBuySYSREADONLY () = $Tuple2(nil, minWavesAmountSurfBuy)
386386
387387
388388
389389 @Callable(i)
390390 func minUsdnAmountSurfBuySYSREADONLY () = $Tuple2(nil, minUsdnAmountSurfBuy)
391391
392392
393393
394394 @Callable(i)
395395 func buySurf (averagePriceWanted,maxTolerancePerc,autoStake) = {
396396 let testAccounts = valueOrElse(getString(this, "testAccounts"), "")
397397 if (if ((testAccounts != ""))
398398 then !(contains(testAccounts, toString(i.caller)))
399399 else false)
400400 then throw("Be patient! Need to test in mainnet before launch.")
401401 else if ((size(i.payments) != 1))
402402 then throw("exactly 1 payment must be attached")
403403 else if ((0 >= averagePriceWanted))
404404 then throw("averagePriceWanted should be positive")
405405 else if ((0 >= maxTolerancePerc))
406406 then throw("maxTolerancePerc should be positive")
407- else {
408- let pmt = i.payments[0]
409- let amt = pmt.amount
410- let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
411- if (if ((pmtAssetId != neutrinoAssetId))
412- then (pmtAssetId != WAVESID)
413- else false)
414- then throw("Unsupported payment asset")
415- else if (if ((pmtAssetId == neutrinoAssetId))
416- then (minUsdnAmountSurfBuy > amt)
407+ else if (isBlocked)
408+ then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
409+ else {
410+ let pmt = i.payments[0]
411+ let amt = pmt.amount
412+ let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
413+ if (if ((pmtAssetId != neutrinoAssetId))
414+ then (pmtAssetId != WAVESID)
417415 else false)
418- then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
419- else if (if ((pmtAssetId == WAVESID))
420- then (minWavesAmountSurfBuy > amt)
416+ then throw("Unsupported payment asset")
417+ else if (if ((pmtAssetId == neutrinoAssetId))
418+ then (minUsdnAmountSurfBuy > amt)
421419 else false)
422- then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
423- else {
424- let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
425- let spentWaves = asInt(surfResult[bFuncIdxWaves])
426- let spentUsdn = asInt(surfResult[bFuncIdxUsdn])
427- let surfAmount = asInt(surfResult[bFuncIdxSurf])
428- let surfAmountX6 = toBigInt(surfAmount)
429- let spentActualX18 = if ((pmtAssetId == WAVESID))
430- then (toBigInt(spentWaves) * MULTX10)
431- else (toBigInt(spentUsdn) * MULTX12)
432- if ((spentActualX18 > ((toBigInt((maxTolerancePerc + MULT6)) * toBigInt(averagePriceWanted)) * surfAmountX6)))
433- then throw((((((("Tolerance " + toString(maxTolerancePerc)) + " exceeded: spent ") + (if ((pmtAssetId == WAVESID))
434- then (toString(spentWaves) + " WAVES")
435- else (toString(spentUsdn) + " USDN"))) + " for ") + toString(surfAmount)) + " SURF"))
436- else {
437- let rest = asInt(surfResult[bFuncIdxRest])
438- let transfer = if ((pmtAssetId == WAVESID))
439- then {
440- let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - rest))])
441- if ((wavesAmt == wavesAmt))
442- then if ((rest > 0))
443- then [ScriptTransfer(i.caller, rest, unit)]
444- else nil
445- else throw("Strict value is not equal to itself.")
446- }
447- else if ((rest > 0))
448- then [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId), ScriptTransfer(i.caller, rest, neutrinoAssetId)]
449- else [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId)]
450- let surfAssetId = asBytes(invoke(this, "issueSurf", [surfAmount], nil))
451- let surfAction = if (autoStake)
452- then {
453- let stakingInv = invoke(surfStakingContract, "stakeByOriginCaller", nil, [AttachedPayment(surfAssetId, surfAmount)])
454- if ((stakingInv == stakingInv))
455- then nil
456- else throw("Strict value is not equal to itself.")
457- }
458- else [ScriptTransfer(i.caller, surfAmount, surfAssetId)]
459- ((transfer ++ [surfData(surfResult)]) ++ surfAction)
460- }
461- }
462- }
420+ then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
421+ else if (if ((pmtAssetId == WAVESID))
422+ then (minWavesAmountSurfBuy > amt)
423+ else false)
424+ then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
425+ else {
426+ let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
427+ let spentWaves = asInt(surfResult[bFuncIdxWaves])
428+ let spentUsdn = asInt(surfResult[bFuncIdxUsdn])
429+ let surfAmount = asInt(surfResult[bFuncIdxSurf])
430+ let surfAmountX6 = toBigInt(surfAmount)
431+ let spentActualX18 = if ((pmtAssetId == WAVESID))
432+ then (toBigInt(spentWaves) * MULTX10)
433+ else (toBigInt(spentUsdn) * MULTX12)
434+ if ((spentActualX18 > ((toBigInt((maxTolerancePerc + MULT6)) * toBigInt(averagePriceWanted)) * surfAmountX6)))
435+ then throw((((((("Tolerance " + toString(maxTolerancePerc)) + " exceeded: spent ") + (if ((pmtAssetId == WAVESID))
436+ then (toString(spentWaves) + " WAVES")
437+ else (toString(spentUsdn) + " USDN"))) + " for ") + toString(surfAmount)) + " SURF"))
438+ else {
439+ let rest = asInt(surfResult[bFuncIdxRest])
440+ let transfer = if ((pmtAssetId == WAVESID))
441+ then {
442+ let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - rest))])
443+ if ((wavesAmt == wavesAmt))
444+ then if ((rest > 0))
445+ then [ScriptTransfer(i.caller, rest, unit)]
446+ else nil
447+ else throw("Strict value is not equal to itself.")
448+ }
449+ else if ((rest > 0))
450+ then [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId), ScriptTransfer(i.caller, rest, neutrinoAssetId)]
451+ else [ScriptTransfer(neutrinoContract, (amt - rest), neutrinoAssetId)]
452+ let surfAssetId = asBytes(invoke(this, "issueSurf", [surfAmount], nil))
453+ let surfAction = if (autoStake)
454+ then {
455+ let stakingInv = invoke(surfStakingContract, "stakeByOriginCaller", nil, [AttachedPayment(surfAssetId, surfAmount)])
456+ if ((stakingInv == stakingInv))
457+ then nil
458+ else throw("Strict value is not equal to itself.")
459+ }
460+ else [ScriptTransfer(i.caller, surfAmount, surfAssetId)]
461+ ((transfer ++ [surfData(surfResult)]) ++ surfAction)
462+ }
463+ }
464+ }
463465 }
464466
465467
466468
467469 @Callable(i)
468470 func issueSurf (surfAmount) = {
469471 let surfAssetId = fromBase58String(getStringValue(SurfAssetIdKey))
470472 if ((i.caller != this))
471473 then throw("issueSurf - permission denied")
472474 else $Tuple2([Reissue(surfAssetId, surfAmount, true)], surfAssetId)
473475 }
474476
475477
476478 @Verifier(tx)
477479 func verify () = {
478480 let pubKeyAdminsListStr = makeString(["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "EYwZmURd5KKaQRBjsVa6g8DPisFoS6SovRJtFiL5gMHU", "DtmAfuDdCrHK8spdAeAYzq6MsZegeD9gnsrpuTRkCbVA", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
479481 let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
480482 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
481483 then 1
482484 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
483485 then 1
484486 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
485487 then 1
486488 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
487489 then 2
488490 else 0))
489491 (count >= 3)
490492 }
491493

github/deemru/w8io/786bc32 
72.59 ms