2021.03.28 13:12 [2522088] smart account 3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp > SELF 0.00000000 Waves

{ "type": 13, "id": "78rdPnjXLm4fYKaXMQYyoQYZPnbQ56XtR1Svvg9BCZQP", "fee": 1400000, "feeAssetId": null, "timestamp": 1616926164247, "version": 1, "sender": "3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp", "senderPublicKey": "7ziFsWp9eo6kUB6ovqQzJfjgQarifNfpCGNW9DZi8YhN", "proofs": [ "2nCw4Xt8Lgzg6NHEJWgsAbXGcqsQmcCnsBPVjmQebjau8aPkBFNfgdPcdJv9sUthqLRW1dososjCSQQETTVZrU1", "3A4EkVEL933t7VWjccnHe4219XCMwN918sDzmgo6tGHMUAescywvxZYMYQQsALDiBGw6UBuBn6w4tZjXhVwu1RKD" ], "script": "base64:AAIEAAAAAAAAACsIAhIDCgEBEgASAwoBARIDCgEIEgQKAggBEgASAwoBARIAEgMKAQESABIAAAAAbwEAAAACU0UAAAACAAAAAWsAAAABdgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAABawUAAAABdgEAAAACSUUAAAACAAAAAWsAAAABdgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAAWsFAAAAAXYBAAAAAlNUAAAAAwAAAAFhAAAAA2FtdAAAAAF0CQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAFhBQAAAANhbXQFAAAAAXQAAAAABHRlbjYAAAAAAAAPQkAAAAAABHRlbjgAAAAAAAX14QAAAAAAA01BWAB//////////wAAAAARY29uZmlnUHJvdmlkZXJLZXkCAAAADmNvbmZpZ1Byb3ZpZGVyAAAAAA5jb25maWdQcm92aWRlcgQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzBQAAABFjb25maWdQcm92aWRlcktleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAFzBQAAAAckbWF0Y2gwCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAFzBQAAAAR0aGlzAQAAAAZsb2NhbEkAAAACAAAAAWsAAAABZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAAWsFAAAAAWUBAAAABmxvY2FsUwAAAAIAAAABawAAAAFlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAABawUAAAABZQEAAAAFY29uZkkAAAACAAAAAWsAAAABZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADmNvbmZpZ1Byb3ZpZGVyBQAAAAFrBQAAAAFlAQAAAAVjb25mUwAAAAIAAAABawAAAAFlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAOY29uZmlnUHJvdmlkZXIFAAAAAWsFAAAAAWUAAAAABUJVTExLAgAAAAZCVUxMSWQAAAAABUJFQVJLAgAAAAZCRUFSSWQAAAAABVVTRE5LAgAAAAttYWluVG9rZW5JZAAAAAAIQlVMTENPTEsCAAAADmJ1bGxDb2xsYXRlcmFsAAAAAAhCRUFSQ09MSwIAAAAOYmVhckNvbGxhdGVyYWwAAAAACUJVTExDSVJDSwIAAAAPYnVsbENpcmN1bGF0aW9uAAAAAAlCRUFSQ0lSQ0sCAAAAD2JlYXJDaXJjdWxhdGlvbgAAAAAISVNTUEVSQ0sCAAAAD2lzc3VlUGVyY2VudGlsZQAAAAAIUkVEUEVSQ0sCAAAAEHJlZGVlbVBlcmNlbnRpbGUAAAAAB01JTklTU0sCAAAACG1pbklzc3VlAAAAAAdNSU5SRURLAgAAAAltaW5SZWRlZW0AAAAACE1JTlBPT0xLAgAAAAdtaW5Qb29sAAAAAAdGRUVBQ0NLAgAAAA9mZWVzQWNjdW11bGF0ZWQAAAAABldMSVNUSwIAAAAOaXNzdWVXaGl0ZUxpc3QAAAAACFJFQlBFUkNLAgAAABNyZWJhbGFuY2VQZXJjZW50aWxlAAAAAAdSRUJJRFhLAgAAABVsYXN0U2V0dGxlbWVudFByaWNlSWQAAAAABUhFQURLAgAAAAtoZWFkUG9pbnRlcgAAAAAFVEFJTEsCAAAAC3RhaWxQb2ludGVyAAAAAAZRU0laRUsCAAAACXF1ZXVlU2l6ZQAAAAAJUE9PTFVTRE5LAgAAABJwb29sTWFpblRva2VuVmFsdWUAAAAAB1BPT0xVUEsCAAAABnBvb2xVcAAAAAAIUE9PTERXTksCAAAAB3Bvb2xEd24AAAAACVBPT0xDSVJDSwIAAAAUcG9vbFRva2VuQ2lyY3VsYXRpb24AAAAABVBPT0xLAgAAAAlwb29sVG9rZW4AAAAACEFTU05BTUVLAgAAAA1kZWZvQXNzZXROYW1lAAAAAARMRVZLAgAAAAhsZXZlcmFnZQAAAAAJV0FWRVNGRUVLAgAAABF3YXZlc1BhY2VtYWtlckZlZQAAAAAIVVNETkZFRUsCAAAAEHVzZG5QYWNlbWFrZXJGZWUAAAAAC29yYWNsZVBLS2V5AgAAAAZvcmFjbGUAAAAADG1heERldmlhdGlvbgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgkAASwAAAACCQAEJQAAAAEFAAAABHRoaXMCAAAAFF9kZXZp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AAAACVBPT0xDSVJDSwIAAAAFbm8gMTMAAAAAEHBvb2xCdWxsRXhwb3N1cmUJAABrAAAAAwUAAAAHYnVsbENvbAUAAAAGcG9vbFVwBQAAAAhidWxsQ2lyYwAAAAAQcG9vbEJlYXJFeHBvc3VyZQkAAGsAAAADBQAAAAdiZWFyQ29sBQAAAAdwb29sRHduBQAAAAhiZWFyQ2lyYwAAAAAJcG9vbFZhbHVlCQAAZAAAAAIJAABkAAAAAgUAAAAIcG9vbE1haW4FAAAAEHBvb2xCdWxsRXhwb3N1cmUFAAAAEHBvb2xCZWFyRXhwb3N1cmUAAAAABm9yYWNsZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQEAAAAUYWRkcmVzc0Zyb21QdWJsaWNLZXkAAAABCQACWQAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAtvcmFjbGVQS0tleQIAAAAObm8gb3JhY2xlUEtLZXkCAAAAEmJhZCBvcmFjbGUgYWRkcmVzcwAAAAARc2V0dGxlZFByaWNlSW5kZXgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAdSRUJJRFhLAgAAABdubyBsYXN0IHJlYmFsYW5jZSBwcmljZQAAAAAQb3JhY2xlUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkBAAAAEWxhc3RQcmljZUluZGV4S2V5AAAAAQUAAAAJYXNzZXROYW1lCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABNiYWQgb3JhY2xlIGRhdGEgYXQgCQAEJQAAAAEFAAAABm9yYWNsZQIAAAAQOiBubyBpbnRlZ2VyIGF0IAkBAAAAEWxhc3RQcmljZUluZGV4S2V5AAAAAQUAAAAJYXNzZXROYW1lAAAAAAhsZXZlcmFnZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAARMRVZLAAAAAAAAAAADAQAAAA1oZWlnaHRCeUluZGV4AAAAAQAAAApwcmljZUluZGV4CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAGb3JhY2xlCQABLAAAAAIJAQAAABBwcmljZUluZGV4UHJlZml4AAAAAQUAAAAJYXNzZXROYW1lCQABpAAAAAEFAAAACnByaWNlSW5kZXgJAAEsAAAAAgIAAAARbm8gZGF0YSBhdCBpbmRleCAJAAGkAAAAAQUAAAAKcHJpY2VJbmRleAEAAAANcHJpY2VCeUhlaWdodAAAAAEAAAALcHJpY2VIZWlnaHQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZvcmFjbGUJAAEsAAAAAgkBAAAAEXByaWNlSGVpZ2h0UHJlZml4AAAAAQUAAAAJYXNzZXROYW1lCQABpAAAAAEFAAAAC3ByaWNlSGVpZ2h0CQABLAAAAAICAAAAE25vIGRhdGEgZm9yIGhlaWdodCAJAAGkAAAAAQUAAAALcHJpY2VIZWlnaHQBAAAADHByaWNlQnlJbmRleAAAAAEAAAAKcHJpY2VJbmRleAkBAAAADXByaWNlQnlIZWlnaHQAAAABCQEAAAANaGVpZ2h0QnlJbmRleAAAAAEFAAAACnByaWNlSW5kZXgAAAAACXF1ZXVlU2l6ZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAZRU0laRUsAAAAAAAAAAAAAAAAAC2hlYWRQb2ludGVyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAABUhFQURLAgAAAAAAAAAAC3RhaWxQb2ludGVyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAABVRBSUxLAgAAAAAAAAAAD2ZlZXNBY2N1bXVsYXRlZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAdGRUVBQ0NLAAAAAAAAAAAAAAAAAAVJU1NVRQIAAAAFSVNTVUUAAAAABlJFREVFTQIAAAAGUkVERUVNAAAAAARQT09MAgAAAARQT09MAAAAAAZVTlBPT0wCAAAABlVOUE9PTAAAAAAKZmVlQWRkcktleQIAAAAKZmVlQWRkcmVzcwAAAAAOc3Rha2luZ0FkZHJLZXkCAAAADnN0YWtpbmdBZGRyZXNzAAAAAA9kYWVtb25QdWJLZXlLZXkCAAAAD2RhZW1vblB1YmxpY0tleQAAAAAKZmVlQWRkcmVzcwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAAAVjb25mUwAAAAIFAAAACmZlZUFkZHJLZXkCAAAADW5vIGZlZUFkZHJlc3MCAAAADmJhZCBmZWVBZGRyZXNzAAAAAA5zdGFraW5nQWRkcmVzcwkBAAAABWNvbmZTAAAAAgUAAAAOc3Rha2luZ0FkZHJLZXkCAAAAEW5vIHN0YWtpbmdBZGRyZXNzAAAAAA9kYWVtb25QdWJsaWNLZXkJAAJZAAAAAQkBAAAABWNvbmZTAAAAAgUAAAAPZGFlbW9uUHViS2V5S2V5AgAAABJubyBkYWVtb25QdWJsaWNLZXkAAAAACnJwZEFkZHJlc3MJAAQmAAAAAQIAAAAjM1BOaWtNNnlwNE5xY1NVOGd1eFF0bVI1b25yMkQ0ZTh5VEoAAAAABmFkbWlucwkABEwAAAACAgAAACwySEhxVjhXOURKYXlWNVI2dEJEMlNiOHNycGhwb2JvRGk3cjF0MWFQaXVtQwkABEwAAAACAgAAACw1WlhlODJSUkFTVTdxc2hYTTJKOUpOWWhxSjlHV1lqalZxMmd3VVY1TmF6OQkABEwAAAACAgAAACw1V1JYRlNqd2NUYk5mS2NKczhacVhtU1NXWXNTVkpVdE12TXFaajVoSDROYwUAAAADbmlsAAAAAANvcG4JAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgUAAAAGb3JhY2xlCQABLAAAAAICAAAAFiVzJXNfX2lzTWFya2V0T3BlbmVkX18FAAAACWFzc2V0TmFtZQYBAAAADGJ1aWxkTmV3SXRlbQAAAAcAAAAGYWN0aW9uAAAAA2FtdAAAAAV0b2tlbgAAAApwcmljZUluZGV4AAAAB2ludm9rZXIAAAAJbWluUGF5b3V0AAAACW1heFBheW91dAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAZhY3Rpb24CAAAAAXwJAAGkAAAAAQUAAAADYW10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YXRlcmFsCQAAZQAAAAIFAAAAA2FtdAUAAAAHZmVlU2l6ZQQAAAASZGVmYXVsdEFkZGVkVG9rZW5zAwkAAAAAAAACBQAAAAV0b2tlbgUAAAAEQlVMTAkAAGsAAAADBQAAAAhidWxsQ2lyYwUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAdidWxsQ29sAwkAAAAAAAACBQAAAAV0b2tlbgUAAAAEQkVBUgkAAGsAAAADBQAAAAhiZWFyQ2lyYwUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAdiZWFyQ29sCQAAAgAAAAECAAAADGJhZCB0b2tlbiBpZAQAAAANJHQwMTM5NTkxNDAzMgkBAAAAAnNwAAAAAgUAAAASZGVmYXVsdEFkZGVkVG9rZW5zBQAAAAltYXhQYXlvdXQEAAAAEmFkZGVkVG9DaXJjdWxhdGlvbggFAAAADSR0MDEzOTU5MTQwMzIAAAACXzEEAAAAC2V4dHJhVG9rZW5zCAUAAAANJHQwMTM5NTkxNDAzMgAAAAJfMgQAAAANJHQwMTQwNDkxNDIyMAMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJVTEwJAAUWAAAABAUAAAASZGVmYXVsdEFkZGVkVG9rZW5zBQAAAA9hZGRlZENvbGxhdGVyYWwAAAAAAAAAAAAAAAAAAAAAAAAJAAUWAAAABAAAAAAAAAAAAAAAAAAAAAAAAAUAAAASZGVmYXVsdEFkZGVkVG9rZW5zBQAAAA9hZGRlZENvbGxhdGVyYWwEAAAACXBsdXNCdWxscwgFAAAADSR0MDE0MDQ5MTQyMjAAAAACXzEEAAAAC3BsdXNCdWxsQ29sCAUAAAANJHQwMTQwNDkxNDIyMAAAAAJfMgQAAAAJcGx1c0JlYXJzCAUAAAANJHQwMTQwNDkxNDIyMAAAAAJfMwQAAAALcGx1c0JlYXJDb2wIBQAAAA0kdDAxNDA0OTE0MjIwAAAAAl80AwkAAGYAAAACBQAAAAltaW5QYXlvdXQFAAAAEmFkZGVkVG9DaXJjdWxhdGlvbgkBAAAAB3BheWJhY2sAAAABBQAAAAltYWluVG9rZW4JAAROAAAAAgkBAAAAB3Bvb2xTdXAAAAAECQAAZAAAAAIFAAAAB2J1bGxDb2wFAAAAC3BsdXNCdWxsQ29sCQAAZAAAAAIFAAAAB2JlYXJD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bmV4dFByaWNlCQEAAAAMcHJpY2VCeUluZGV4AAAAAQUAAAATdW5zZXR0bGVkUHJpY2VJbmRleAQAAAAGbWluVm9sAwkAAGYAAAACBQAAAAdiZWFyQ29sBQAAAAdidWxsQ29sBQAAAAdidWxsQ29sBQAAAAdiZWFyQ29sBAAAAAZyZWRpc3QJAQAAAAJMVgAAAAQFAAAABm1pblZvbAUAAAAMc2V0dGxlZFByaWNlBQAAAAluZXh0UHJpY2UFAAAACGxldmVyYWdlBAAAABNwcmljZVVwR29vZEZvckJ1bGxzCQAAAAAAAAIFAAAACWFzc2V0TmFtZQIAAAAABAAAAAtwcmljZUdvZXNVcAkAAGYAAAACBQAAAAluZXh0UHJpY2UFAAAADHNldHRsZWRQcmljZQQAAAAJYnVsbHNFYXJuCQAAAAAAAAIFAAAAE3ByaWNlVXBHb29kRm9yQnVsbHMFAAAAC3ByaWNlR29lc1VwBAAAAApuZXdCdWxsQ29sAwUAAAAJYnVsbHNFYXJuCQAAZAAAAAIFAAAAB2J1bGxDb2wFAAAABnJlZGlzdAkAAGUAAAACBQAAAAdidWxsQ29sBQAAAAZyZWRpc3QEAAAACm5ld0JlYXJDb2wDBQAAAAlidWxsc0Vhcm4JAABlAAAAAgUAAAAHYmVhckNvbAUAAAAGcmVkaXN0CQAAZAAAAAIFAAAAB2JlYXJDb2wFAAAABnJlZGlzdAQAAAANJHQwMTk0NTIxOTY1MAkBAAAAC3Bvb2xTdXBwb3J0AAAACAUAAAAKbmV3QnVsbENvbAUAAAAKbmV3QmVhckNvbAUAAAAIYnVsbENpcmMFAAAACGJlYXJDaXJjBQAAAAhwb29sTWFpbgUAAAAGcG9vbFVwBQAAAAdwb29sRHduBQAAAAZvZmZzZXQEAAAACnVwZEJ1bGxDb2wIBQAAAA0kdDAxOTQ1MjE5NjUwAAAAAl8xBAAAAAp1cGRCZWFyQ29sCAUAAAANJHQwMTk0NTIxOTY1MAAAAAJfMgQAAAALdXBkQnVsbENpcmMIBQAAAA0kdDAxOTQ1MjE5NjUwAAAAAl8zBAAAAAt1cGRCZWFyQ2lyYwgFAAAADSR0MDE5NDUyMTk2NTAAAAACXzQEAAAAC3VwZFBvb2xNYWluCAUAAAANJHQwMTk0NTIxOTY1MAAAAAJfNQQA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MjkAAAAAAAAAAAUDCQAAAAAAAAIFAAAADyRzaXplMjY4NzQyNjkyOQAAAAAAAAAABgUAAAAPJGFjYzYyNjg3NDI2OTI5BAAAAA8kYWNjNzI2ODc0MjY5MjkJAQAAAAFmAAAAAgUAAAAPJGFjYzYyNjg3NDI2OTI5CQABkQAAAAIFAAAADyRsaXN0MjY4NzQyNjkyOQAAAAAAAAAABgMJAAAAAAAAAgUAAAAPJHNpemUyNjg3NDI2OTI5AAAAAAAAAAAHBQAAAA8kYWNjNzI2ODc0MjY5MjkEAAAADyRhY2M4MjY4NzQyNjkyOQkBAAAAAWYAAAACBQAAAA8kYWNjNzI2ODc0MjY5MjkJAAGRAAAAAgUAAAAPJGxpc3QyNjg3NDI2OTI5AAAAAAAAAAAHCQAAAgAAAAECAAAAEkxpc3Qgc2l6ZSBleGNlZWQgNwQAAAAHb2tTaGlmdAgFAAAADSR0MDI2ODMwMjY5MjkAAAACXzEEAAAAGmZvcmNlZEJ5RGV2aWF0aW9uT3JUaW1lb3V0CAUAAAANJHQwMjY4MzAyNjkyOQAAAAJfMgQAAAAKcXVldWVXYWl0cwkAAGcAAAACBQAAABBvcmFjbGVQcmljZUluZGV4BQAAAA9xdWV1ZVByaWNlSW5kZXgDCQAAZgAAAAIFAAAAEXNldHRsZWRQcmljZUluZGV4BQAAAA9xdWV1ZVByaWNlSW5kZXgJAAACAAAAAQIAAAAwc2V0dGxlMjogZnV0dXJlIHByaWNlIGFscmVhZHkgc2V0dGxlZC9yZWJhbGFuY2VkAwkAAAAAAAACBQAAABFzZXR0bGVkUHJpY2VJbmRleAUAAAAPcXVldWVQcmljZUluZGV4CQEAAAAHZGVxdWV1ZQAAAAADAwkAAGYAAAACBQAAAAdva1NoaWZ0AAAAAAAAAAAAAwUAAAAaZm9yY2VkQnlEZXZpYXRpb25PclRpbWVvdXQGBQAAAApxdWV1ZVdhaXRzBwkBAAAACXJlYmFsYW5jZQAAAAEFAAAAB29rU2hpZnQJAAACAAAAAQkAASwAAAACAgAAADNzZXR0bGUyOiBbT0tdIGFsbCBkb25lLCBjYXJyeSBvbi4gYXZhaWxhYmxlIHNoaWZ0OiAJAAGkAAAAAQUAAAAHb2tTaGlmdAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAC2FkbWluQWN0aW9uCQAAZgAAAAIJAABkAAAAAgkAAGQAAAACAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAJAAJZAAAAAQkAAZEAAAACBQAAAAZhZG1pbnMAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAADCQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAQkAAlkAAAABCQABkQAAAAIFAAAABmFkbWlucwAAAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAACAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABBAAAAA1zdGFraW5nQWN0aW9uBAAAAAckbWF0Y2gwBQAAAAJ0eAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXSW52b2tlU2NyaXB0VHJhbnNhY3Rpb24EAAAAAnR4BQAAAAckbWF0Y2gwBAAAAA9zaWduZWRDb3JyZWN0bHkJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAABQAAAA9kYWVtb25QdWJsaWNLZXkEAAAAC2ZlZXNDb3JyZWN0AwkAAAAAAAACCAUAAAACdHgAAAAKZmVlQXNzZXRJZAUAAAAEdW5pdAkAAGcAAAACCQAAaAAAAAIAAAAAAAAAA+gAAAAAAAAAA+gIBQAAAAJ0eAAAAANmZWUHBAAAAAtkYXBwQ29ycmVjdAkAAAAAAAACCAUAAAACdHgAAAAEZEFwcAUAAAAKcnBkQWRkcmVzcwQAAAAGdW5sb2NrCQAAAAAAAAIIBQAAAAJ0eAAAAAhmdW5jdGlvbgIAAAAOdW5sb2NrTmV1dHJpbm8EAAAABGxvY2sDAwkAAAAAAAACCAUAAAACdHgAAAAIZnVuY3Rpb24CAAAADmxvY2tOZXV0cmlub1NQCQAAAAAAAAIJAAGRAAAAAggFAAAAAnR4AAAABGFyZ3MAAAAAAAAAAAAFAAAADnN0YWtpbmdBZGRyZXNzBwkAAGcAAAACCAkAA+8AAAABBQAAAAR0aGlzAAAACWF2YWlsYWJsZQUAAAAEdGVuOAcEAAAAC2Z1bmNDb3JyZWN0AwUAAAAEbG9jawYFAAAABnVubG9jawMDAwUAAAAPc2lnbmVkQ29ycmVjdGx5BQAAAAtmZWVzQ29ycmVjdAcFAAAAC2RhcHBDb3JyZWN0BwUAAAALZnVuY0NvcnJlY3QHBwMFAAAAC2FkbWluQWN0aW9uBgUAAAANc3Rha2luZ0FjdGlvbsHrZwk=", "chainId": 87, "height": 2522088, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: FME1ftFJS9X58ARtT2mSb19qHiAZf6Y7HYhDKVbNxNbc Next: AGAB6Z113NVtBHZhBYoTkWdHXp8uWTmdW2TmVykmUYT7 Diff:
OldNewDifferences
9595
9696 let oraclePKKey = "oracle"
9797
98+let maxDeviation = valueOrElse(getInteger(configProvider, (toString(this) + "_deviationPercentile")), 0)
99+
98100 func lastPriceIndexKey (assetId) = if ((assetId == ""))
99101 then "price_index"
100102 else ("%s%s__idxCurrent__" + assetId)
167169
168170 let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
169171
170-let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
172+let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
171173
172174 let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey(assetName)), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey(assetName)))
173175
174176 let leverage = valueOrElse(getInteger(this, LEVK), 3)
175177
176-func heightByIndex (assetName,priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
178+func heightByIndex (priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
177179
178180
179-func priceByHeight (assetName,priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
181+func priceByHeight (priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
180182
181183
182-func priceByIndex (assetName,priceIndex) = priceByHeight(assetName, heightByIndex(assetName, priceIndex))
184+func priceByIndex (priceIndex) = priceByHeight(heightByIndex(priceIndex))
183185
184186
185187 let queueSize = valueOrElse(getInteger(this, QSIZEK), 0)
219221 func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|")
220222
221223
222-func userDiffAbs () = {
223- let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure))
224- let userBullCol = $t058835972._1
225- let userBearCol = $t058835972._2
226- let diff = (userBullCol - userBearCol)
224+func diffAbs (a1,a2) = {
225+ let diff = (a1 - a2)
227226 if ((diff > 0))
228227 then diff
229228 else (0 - diff)
230229 }
230+
231+
232+func userDiffAbs () = diffAbs((bullCol - poolBullExposure), (bearCol - poolBearExposure))
231233
232234
233235 func maxIssue (tokenId) = {
300302 }
301303
302304
303-func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
305+func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0,steps) = {
304306 func closeUp (c1,c2,a0,a1,c0,pu,pd) = {
305307 let diff = (c1 - c2)
306308 let exp = fraction(c1, pu, a0)
343345 $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd)
344346 }
345347
346- let $t01034111376 = if ((curBullCol0 > curBearCol0))
348+ let $t01030211337 = if ((curBullCol0 > curBearCol0))
347349 then {
348350 let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
349- let $t01056710704 = afterCloseUp
350- let a = $t01056710704._1
351- let b = $t01056710704._2
352- let c = $t01056710704._3
353- let d = $t01056710704._4
354- let e = $t01056710704._5
355- let f = $t01056710704._6
356- let g = $t01056710704._7
351+ let $t01052810665 = afterCloseUp
352+ let a = $t01052810665._1
353+ let b = $t01052810665._2
354+ let c = $t01052810665._3
355+ let d = $t01052810665._4
356+ let e = $t01052810665._5
357+ let f = $t01052810665._6
358+ let g = $t01052810665._7
357359 if ((f > 0))
358360 then afterCloseUp
359361 else if ((f == 0))
362364 }
363365 else {
364366 let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
365- let $t01105511195 = afterCloseDwn
366- let a = $t01105511195._1
367- let b = $t01105511195._2
368- let c = $t01105511195._3
369- let d = $t01105511195._4
370- let e = $t01105511195._5
371- let f = $t01105511195._6
372- let g = $t01105511195._7
367+ let $t01101611156 = afterCloseDwn
368+ let a = $t01101611156._1
369+ let b = $t01101611156._2
370+ let c = $t01101611156._3
371+ let d = $t01101611156._4
372+ let e = $t01101611156._5
373+ let f = $t01101611156._6
374+ let g = $t01101611156._7
373375 if ((g > 0))
374376 then afterCloseDwn
375377 else if ((g == 0))
376378 then openUp(a, b, c, d, e, f, g)
377379 else throw("poolDwn < 0")
378380 }
379- let c1 = $t01034111376._1
380- let c2 = $t01034111376._2
381- let a0 = $t01034111376._3
382- let a1 = $t01034111376._4
383- let c0 = $t01034111376._5
384- let pu = $t01034111376._6
385- let pd = $t01034111376._7
386- let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100))
387- let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000))
388- let c1SplitP = if (if (percentileActivated)
389- then (pd > 0)
390- else false)
381+ let c1 = $t01030211337._1
382+ let c2 = $t01030211337._2
383+ let a0 = $t01030211337._3
384+ let a1 = $t01030211337._4
385+ let c0 = $t01030211337._5
386+ let pu = $t01030211337._6
387+ let pd = $t01030211337._7
388+ let charge = fraction(userDiffAbs(), (rebalancePercentile * steps), ((1440 * 100) * 100))
389+ let c1SplitP = if ((pd > 0))
391390 then charge
392391 else 0
393- let c2SplitP = if (if (percentileActivated)
394- then (pu > 0)
395- else false)
392+ let c2SplitP = if ((pu > 0))
396393 then charge
397394 else 0
398395 $Tuple7((c1 - c1SplitP), (c2 - c2SplitP), a0, a1, ((c0 + c1SplitP) + c2SplitP), pu, pd)
400397
401398
402399 func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
403- let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
404- let bullCol1 = $t01195712139._1
405- let bearCol1 = $t01195712139._2
406- let bullCic1 = $t01195712139._3
407- let bearCirc1 = $t01195712139._4
408- let poolMain1 = $t01195712139._5
409- let poolUp1 = $t01195712139._6
410- let poolDwn1 = $t01195712139._7
400+ let $t01176211947 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn, 0)
401+ let bullCol1 = $t01176211947._1
402+ let bearCol1 = $t01176211947._2
403+ let bullCic1 = $t01176211947._3
404+ let bearCirc1 = $t01176211947._4
405+ let poolMain1 = $t01176211947._5
406+ let poolUp1 = $t01176211947._6
407+ let poolDwn1 = $t01176211947._7
411408 [IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)]
412409 }
413410
441438 let next = data[(size(data) - 1)]
442439 func payback (tkn) = [SE(HEADK, next), decreaseQueueSize, ST(invoker, amt, fromBase58String(tkn))]
443440
444- let items = if ((rebalancedPriceIndex > priceIndex))
445- then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
446- else if ((priceIndex > rebalancedPriceIndex))
447- then throw("can't dequeue, too early, rebalance first")
448- else if ((action == ISSUE))
441+ let items = if ((settledPriceIndex != priceIndex))
442+ then throw(((("corrupt state, settledPriceIndex=" + toString(settledPriceIndex)) + ", request price id=") + toString(priceIndex)))
443+ else if ((action == ISSUE))
444+ then {
445+ let feeSize = fraction(amt, issuePercentile, 10000)
446+ let addedCollateral = (amt - feeSize)
447+ let defaultAddedTokens = if ((token == BULL))
448+ then fraction(bullCirc, addedCollateral, bullCol)
449+ else if ((token == BEAR))
450+ then fraction(bearCirc, addedCollateral, bearCol)
451+ else throw("bad token id")
452+ let $t01395914032 = sp(defaultAddedTokens, maxPayout)
453+ let addedToCirculation = $t01395914032._1
454+ let extraTokens = $t01395914032._2
455+ let $t01404914220 = if ((token == BULL))
456+ then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0)
457+ else $Tuple4(0, 0, defaultAddedTokens, addedCollateral)
458+ let plusBulls = $t01404914220._1
459+ let plusBullCol = $t01404914220._2
460+ let plusBears = $t01404914220._3
461+ let plusBearCol = $t01404914220._4
462+ if ((minPayout > addedToCirculation))
463+ then payback(mainToken)
464+ else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
465+ }
466+ else if ((action == REDEEM))
449467 then {
450- let feeSize = fraction(amt, issuePercentile, 10000)
451- let addedCollateral = (amt - feeSize)
452- let defaultAddedTokens = if ((token == BULL))
453- then fraction(bullCirc, addedCollateral, bullCol)
468+ let removedTokens = amt
469+ let estimatedPayout = if ((token == BULL))
470+ then fraction(bullCol, removedTokens, bullCirc)
454471 else if ((token == BEAR))
455- then fraction(bearCirc, addedCollateral, bearCol)
472+ then fraction(bearCol, removedTokens, bearCirc)
456473 else throw("bad token id")
457- let $t01427014343 = sp(defaultAddedTokens, maxPayout)
458- let addedToCirculation = $t01427014343._1
459- let extraTokens = $t01427014343._2
460- let $t01436014531 = if ((token == BULL))
461- then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0)
462- else $Tuple4(0, 0, defaultAddedTokens, addedCollateral)
463- let plusBulls = $t01436014531._1
464- let plusBullCol = $t01436014531._2
465- let plusBears = $t01436014531._3
466- let plusBearCol = $t01436014531._4
467- if ((minPayout > addedToCirculation))
468- then payback(mainToken)
469- else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
474+ let feeSize = fraction(estimatedPayout, redeemPercentile, 10000)
475+ let defaultPayout = (estimatedPayout - feeSize)
476+ let $t01528715341 = sp(defaultPayout, maxPayout)
477+ let userPayout = $t01528715341._1
478+ let extra = $t01528715341._2
479+ let $t01535815523 = if ((token == BULL))
480+ then $Tuple4(removedTokens, estimatedPayout, 0, 0)
481+ else $Tuple4(0, 0, removedTokens, estimatedPayout)
482+ let minusBulls = $t01535815523._1
483+ let minusBullCol = $t01535815523._2
484+ let minusBears = $t01535815523._3
485+ let minusBearCol = $t01535815523._4
486+ if ((minPayout > userPayout))
487+ then payback(token)
488+ else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
470489 }
471- else if ((action == REDEEM))
490+ else if ((action == POOL))
472491 then {
473- let removedTokens = amt
474- let estimatedPayout = if ((token == BULL))
475- then fraction(bullCol, removedTokens, bullCirc)
476- else if ((token == BEAR))
477- then fraction(bearCol, removedTokens, bearCirc)
478- else throw("bad token id")
479- let feeSize = fraction(estimatedPayout, redeemPercentile, 10000)
480- let defaultPayout = (estimatedPayout - feeSize)
481- let $t01559815652 = sp(defaultPayout, maxPayout)
482- let userPayout = $t01559815652._1
483- let extra = $t01559815652._2
484- let $t01566915834 = if ((token == BULL))
485- then $Tuple4(removedTokens, estimatedPayout, 0, 0)
486- else $Tuple4(0, 0, removedTokens, estimatedPayout)
487- let minusBulls = $t01566915834._1
488- let minusBullCol = $t01566915834._2
489- let minusBears = $t01566915834._3
490- let minusBearCol = $t01566915834._4
491- if ((minPayout > userPayout))
492- then payback(token)
493- else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
492+ let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
493+ if ((minPayout > issueTokens))
494+ then payback(mainToken)
495+ else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
494496 }
495- else if ((action == POOL))
497+ else if ((action == UNPOOL))
496498 then {
497- let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
498- if ((minPayout > issueTokens))
499- then payback(mainToken)
500- else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
499+ func share (a) = fraction(a, amt, poolTokenCirculation)
500+
501+ let unpooledMain = share(poolMain)
502+ let unpooledUp = share(poolUp)
503+ let unpooledDwn = share(poolDwn)
504+ let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
505+ let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
506+ let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
507+ if ((minPayout > totalUnpooledValue))
508+ then payback(poolToken)
509+ else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
501510 }
502- else if ((action == UNPOOL))
503- then {
504- func share (a) = fraction(a, amt, poolTokenCirculation)
505-
506- let unpooledMain = share(poolMain)
507- let unpooledUp = share(poolUp)
508- let unpooledDwn = share(poolDwn)
509- let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
510- let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
511- let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
512- if ((minPayout > totalUnpooledValue))
513- then payback(poolToken)
514- else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
515- }
516- else throw(("bad action: " + action))
511+ else throw(("bad action: " + action))
517512 if (isLastElement)
518513 then overwriteTail :: items
519514 else items
521516 }
522517
523518
524-func rebalance () = {
525- func LV (v,p0,p1,m) = {
526- let denom = {
527- let md = (((2 * (if ((p1 > p0))
519+func rebalance (offset) = if ((offset == 0))
520+ then throw("[OK] offset=0")
521+ else {
522+ func LV (v,p0,p1,m) = {
523+ let denom = {
524+ let md = (((2 * (if ((p1 > p0))
525+ then p1
526+ else p0)) * m) / 3037000499)
527+ if ((10 > md))
528+ then 10
529+ else if ((100 > md))
530+ then 100
531+ else 1000
532+ }
533+ let pmax = ((if ((p1 > p0))
528534 then p1
529- else p0)) * m) / 3037000499)
530- if ((10 > md))
531- then 10
532- else if ((100 > md))
533- then 100
534- else 1000
535+ else p0) / denom)
536+ let pmin = ((if ((p0 > p1))
537+ then p1
538+ else p0) / denom)
539+ let a = (pmin * pmin)
540+ let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
541+ let ma = ((m * m) - m)
542+ fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
535543 }
536- let pmax = ((if ((p1 > p0))
537- then p1
538- else p0) / denom)
539- let pmin = ((if ((p0 > p1))
540- then p1
541- else p0) / denom)
542- let a = (pmin * pmin)
543- let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
544- let ma = ((m * m) - m)
545- fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
544+
545+ let unsettledPriceIndex = (settledPriceIndex + offset)
546+ if (!(opn))
547+ then [IE(REBIDXK, unsettledPriceIndex)]
548+ else {
549+ let settledPrice = priceByIndex(settledPriceIndex)
550+ let nextPrice = priceByIndex(unsettledPriceIndex)
551+ let minVol = if ((bearCol > bullCol))
552+ then bullCol
553+ else bearCol
554+ let redist = LV(minVol, settledPrice, nextPrice, leverage)
555+ let priceUpGoodForBulls = (assetName == "")
556+ let priceGoesUp = (nextPrice > settledPrice)
557+ let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
558+ let newBullCol = if (bullsEarn)
559+ then (bullCol + redist)
560+ else (bullCol - redist)
561+ let newBearCol = if (bullsEarn)
562+ then (bearCol - redist)
563+ else (bearCol + redist)
564+ let $t01945219650 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn, offset)
565+ let updBullCol = $t01945219650._1
566+ let updBearCol = $t01945219650._2
567+ let updBullCirc = $t01945219650._3
568+ let updBearCirc = $t01945219650._4
569+ let updPoolMain = $t01945219650._5
570+ let updPoolUp = $t01945219650._6
571+ let updPoolDwn = $t01945219650._7
572+[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
573+ }
546574 }
547-
548- let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data")
549- let unsettledPriceIndex = (settledPriceIndex + 1)
550- if (!(opn))
551- then [IE(REBIDXK, unsettledPriceIndex)]
552- else {
553- let settledPrice = priceByIndex(assetName, settledPriceIndex)
554- let nextPrice = priceByIndex(assetName, unsettledPriceIndex)
555- let minVol = if ((bearCol > bullCol))
556- then bullCol
557- else bearCol
558- let redist = LV(minVol, settledPrice, nextPrice, leverage)
559- let priceUpGoodForBulls = (assetName == "")
560- let priceGoesUp = (nextPrice > settledPrice)
561- let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
562- let newBullCol = if (bullsEarn)
563- then (bullCol + redist)
564- else (bullCol - redist)
565- let newBearCol = if (bullsEarn)
566- then (bearCol - redist)
567- else (bearCol + redist)
568- let $t01982820018 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
569- let updBullCol = $t01982820018._1
570- let updBearCol = $t01982820018._2
571- let updBullCirc = $t01982820018._3
572- let updBearCirc = $t01982820018._4
573- let updPoolMain = $t01982820018._5
574- let updPoolUp = $t01982820018._6
575- let updPoolDwn = $t01982820018._7
576-[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
577- }
578- }
579575
580576
581577 func calcMax (min,avg) = if ((min > avg))
599595 then throw("bad token att")
600596 else {
601597 let amt = inv.payments[0].amount
602- let $t02110921287 = if ((tokenId == BULL))
598+ let $t02074720925 = if ((tokenId == BULL))
603599 then $Tuple2(bullCol, bullCirc)
604600 else if ((tokenId == BEAR))
605601 then $Tuple2(bearCol, bearCirc)
606602 else throw(errorMessage)
607- let col = $t02110921287._1
608- let circ = $t02110921287._2
603+ let col = $t02074720925._1
604+ let circ = $t02074720925._2
609605 let est = fraction(amt, circ, col)
610- let $t02132921423 = if ((minPayout == 0))
606+ let $t02096721061 = if ((minPayout == 0))
611607 then $Tuple2(0, MAX)
612608 else $Tuple2(minPayout, calcMax(minPayout, est))
613- let minP = $t02132921423._1
614- let maxP = $t02132921423._2
609+ let minP = $t02096721061._1
610+ let maxP = $t02096721061._2
615611 if ((minIssue > amt))
616612 then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
617613 else {
634630 else false)
635631 then throw("bad token req")
636632 else {
637- let $t02238522524 = if ((tokenId == BULL))
633+ let $t02202322162 = if ((tokenId == BULL))
638634 then $Tuple2(bullCol, bullCirc)
639635 else if ((tokenId == BEAR))
640636 then $Tuple2(bearCol, bearCirc)
641637 else throw("bad token req")
642- let col = $t02238522524._1
643- let circ = $t02238522524._2
638+ let col = $t02202322162._1
639+ let circ = $t02202322162._2
644640 let est = fraction(amt, col, circ)
645- let $t02257222666 = if ((minPayout == 0))
641+ let $t02221022304 = if ((minPayout == 0))
646642 then $Tuple2(0, MAX)
647643 else $Tuple2(minPayout, calcMax(minPayout, est))
648- let minP = $t02257222666._1
649- let maxP = $t02257222666._2
644+ let minP = $t02221022304._1
645+ let maxP = $t02221022304._2
650646 if ((validateRequestRedeem(inv) == unit))
651647 then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
652648 else throw("doesn't happen")
665661 then throw(("pool min: " + toString(minPool)))
666662 else {
667663 let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue)
668- let $t02345923558 = if ((minPayout == 0))
664+ let $t02309723196 = if ((minPayout == 0))
669665 then $Tuple2(0, MAX)
670666 else $Tuple2(minPayout, calcMax(minPayout, estimate))
671- let minP = $t02345923558._1
672- let maxP = $t02345923558._2
667+ let minP = $t02309723196._1
668+ let maxP = $t02309723196._2
673669 enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
674670 }
675671 }
685681 if ((minPool > estimate))
686682 then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
687683 else {
688- let $t02421524314 = if ((minPayout == 0))
684+ let $t02385323952 = if ((minPayout == 0))
689685 then $Tuple2(0, MAX)
690686 else $Tuple2(minPayout, calcMax(minPayout, estimate))
691- let minP = $t02421524314._1
692- let maxP = $t02421524314._2
687+ let minP = $t02385323952._1
688+ let maxP = $t02385323952._2
693689 enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
694690 }
695691 }
696692 }
697-
698-
699-@Callable(inv)
700-func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,defoAssetName,denom,lev) = if (isDefined(getString(this, BULLK)))
701- then throw("already initialized")
702- else {
703- let totalOwnedMainToken = inv.payments[0].amount
704- let bulls = (totalOwnedMainToken / 3)
705- let bears = bulls
706- let pools = ((totalOwnedMainToken - bulls) - bears)
707- if (if (if ((bears == 0))
708- then true
709- else (bulls == 0))
710- then true
711- else (pools == 0))
712- then throw("can't init balances")
713- else {
714- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index")
715- let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
716- let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
717- let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
718- let buid = calculateAssetId(bull)
719- let beid = calculateAssetId(bear)
720- let poid = calculateAssetId(pool)
721-[bull, bear, pool, SE(BULLK, toBase58String(buid)), SE(BEARK, toBase58String(beid)), SE(USDNK, toBase58String(value(inv.payments[0].assetId))), SE(POOLK, toBase58String(poid)), SE(ASSNAMEK, defoAssetName), SE(oraclePKKey, oraclePK), IE(REBIDXK, oracleCurrentPriceIndex), IE(BULLCOLK, bulls), IE(BEARCOLK, bears), IE(BULLCIRCK, (bulls / denom)), IE(BEARCIRCK, (bears / denom)), IE(POOLCIRCK, (pools / denom)), IE(POOLDWNK, 0), IE(POOLUPK, 0), IE(POOLUSDNK, pools), SE(configProviderKey, config), IE(LEVK, lev), ST(inv.caller, (bulls / denom), buid), ST(inv.caller, (bears / denom), beid), ST(inv.caller, (pools / denom), poid)]
722- }
723- }
724-
725693
726694
727695 @Callable(i)
782750 @Callable(inv)
783751 func settle () = {
784752 let queueEmpty = (headPointer == "")
785- let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
753+ let canRebalance = (oraclePriceIndex > settledPriceIndex)
786754 if (queueEmpty)
787755 then if (canRebalance)
788- then rebalance()
756+ then rebalance(1)
789757 else throw("[OK] all done, carry on")
790758 else {
791759 let data = split(valueOrErrorMessage(getString(this, headPointer), ("bad head pointer(settle): " + headPointer)), "|")
792- let priceIndex = parseIntValue(data[3])
793- if ((priceIndex > rebalancedPriceIndex))
760+ let queuePriceIndex = parseIntValue(data[3])
761+ if ((queuePriceIndex > settledPriceIndex))
794762 then if (canRebalance)
795- then rebalance()
763+ then rebalance(1)
796764 else throw("[OK] need to wait")
797- else if ((priceIndex == rebalancedPriceIndex))
765+ else if ((queuePriceIndex == settledPriceIndex))
798766 then dequeue()
799767 else throw("future price already rebalanced")
800768 }
801769 }
802770
803771
772+
773+@Callable(inv)
774+func settle2 () = {
775+ let queueEmpty = (headPointer == "")
776+ let queuePriceIndex = if (queueEmpty)
777+ then MAX
778+ else {
779+ let data = split(localS(headPointer, "settle2: bad head pointer"), "|")
780+ parseIntValue(data[3])
781+ }
782+ let settledPrice = priceByIndex(settledPriceIndex)
783+ func hasDeviation (priceIndex) = {
784+ let p = priceByIndex(priceIndex)
785+ (fraction(diffAbs(settledPrice, p), 1000000, settledPrice) >= maxDeviation)
786+ }
787+
788+ let maxPossibleShift = (min([queuePriceIndex, oraclePriceIndex]) - settledPriceIndex)
789+ func f (acc,shift) = if (if (acc._2)
790+ then true
791+ else (shift > maxPossibleShift))
792+ then acc
793+ else $Tuple2(shift, if ((shift == 7))
794+ then true
795+ else hasDeviation((settledPriceIndex + shift)))
796+
797+ let $t02683026929 = {
798+ let $list2687426929 = [1, 2, 3, 4, 5, 6, 7]
799+ let $size2687426929 = size($list2687426929)
800+ let $acc02687426929 = $Tuple2(settledPriceIndex, false)
801+ if (($size2687426929 == 0))
802+ then $acc02687426929
803+ else {
804+ let $acc12687426929 = f($acc02687426929, $list2687426929[0])
805+ if (($size2687426929 == 1))
806+ then $acc12687426929
807+ else {
808+ let $acc22687426929 = f($acc12687426929, $list2687426929[1])
809+ if (($size2687426929 == 2))
810+ then $acc22687426929
811+ else {
812+ let $acc32687426929 = f($acc22687426929, $list2687426929[2])
813+ if (($size2687426929 == 3))
814+ then $acc32687426929
815+ else {
816+ let $acc42687426929 = f($acc32687426929, $list2687426929[3])
817+ if (($size2687426929 == 4))
818+ then $acc42687426929
819+ else {
820+ let $acc52687426929 = f($acc42687426929, $list2687426929[4])
821+ if (($size2687426929 == 5))
822+ then $acc52687426929
823+ else {
824+ let $acc62687426929 = f($acc52687426929, $list2687426929[5])
825+ if (($size2687426929 == 6))
826+ then $acc62687426929
827+ else {
828+ let $acc72687426929 = f($acc62687426929, $list2687426929[6])
829+ if (($size2687426929 == 7))
830+ then $acc72687426929
831+ else {
832+ let $acc82687426929 = f($acc72687426929, $list2687426929[7])
833+ throw("List size exceed 7")
834+ }
835+ }
836+ }
837+ }
838+ }
839+ }
840+ }
841+ }
842+ }
843+ let okShift = $t02683026929._1
844+ let forcedByDeviationOrTimeout = $t02683026929._2
845+ let queueWaits = (oraclePriceIndex >= queuePriceIndex)
846+ if ((settledPriceIndex > queuePriceIndex))
847+ then throw("settle2: future price already settled/rebalanced")
848+ else if ((settledPriceIndex == queuePriceIndex))
849+ then dequeue()
850+ else if (if ((okShift > 0))
851+ then if (forcedByDeviationOrTimeout)
852+ then true
853+ else queueWaits
854+ else false)
855+ then rebalance(okShift)
856+ else throw(("settle2: [OK] all done, carry on. available shift: " + toString(okShift)))
857+ }
858+
859+
804860 @Verifier(tx)
805861 func verify () = {
806- let initial = if (!(isDefined(getString(this, BULLK))))
807- then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
808- else false
809862 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(admins[0])))
810863 then 1
811864 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(admins[1])))
839892 case _ =>
840893 false
841894 }
842- if (if (initial)
843- then true
844- else adminAction)
895+ if (adminAction)
845896 then true
846897 else stakingAction
847898 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func SE (k,v) = StringEntry(k, v)
55
66
77 func IE (k,v) = IntegerEntry(k, v)
88
99
1010 func ST (a,amt,t) = ScriptTransfer(a, amt, t)
1111
1212
1313 let ten6 = 1000000
1414
1515 let ten8 = 100000000
1616
1717 let MAX = 9223372036854775807
1818
1919 let configProviderKey = "configProvider"
2020
2121 let configProvider = match getString(this, configProviderKey) {
2222 case s: String =>
2323 addressFromStringValue(s)
2424 case _ =>
2525 this
2626 }
2727
2828 func localI (k,e) = valueOrErrorMessage(getInteger(this, k), e)
2929
3030
3131 func localS (k,e) = valueOrErrorMessage(getString(this, k), e)
3232
3333
3434 func confI (k,e) = valueOrErrorMessage(getInteger(configProvider, k), e)
3535
3636
3737 func confS (k,e) = valueOrErrorMessage(getString(configProvider, k), e)
3838
3939
4040 let BULLK = "BULLId"
4141
4242 let BEARK = "BEARId"
4343
4444 let USDNK = "mainTokenId"
4545
4646 let BULLCOLK = "bullCollateral"
4747
4848 let BEARCOLK = "bearCollateral"
4949
5050 let BULLCIRCK = "bullCirculation"
5151
5252 let BEARCIRCK = "bearCirculation"
5353
5454 let ISSPERCK = "issuePercentile"
5555
5656 let REDPERCK = "redeemPercentile"
5757
5858 let MINISSK = "minIssue"
5959
6060 let MINREDK = "minRedeem"
6161
6262 let MINPOOLK = "minPool"
6363
6464 let FEEACCK = "feesAccumulated"
6565
6666 let WLISTK = "issueWhiteList"
6767
6868 let REBPERCK = "rebalancePercentile"
6969
7070 let REBIDXK = "lastSettlementPriceId"
7171
7272 let HEADK = "headPointer"
7373
7474 let TAILK = "tailPointer"
7575
7676 let QSIZEK = "queueSize"
7777
7878 let POOLUSDNK = "poolMainTokenValue"
7979
8080 let POOLUPK = "poolUp"
8181
8282 let POOLDWNK = "poolDwn"
8383
8484 let POOLCIRCK = "poolTokenCirculation"
8585
8686 let POOLK = "poolToken"
8787
8888 let ASSNAMEK = "defoAssetName"
8989
9090 let LEVK = "leverage"
9191
9292 let WAVESFEEK = "wavesPacemakerFee"
9393
9494 let USDNFEEK = "usdnPacemakerFee"
9595
9696 let oraclePKKey = "oracle"
9797
98+let maxDeviation = valueOrElse(getInteger(configProvider, (toString(this) + "_deviationPercentile")), 0)
99+
98100 func lastPriceIndexKey (assetId) = if ((assetId == ""))
99101 then "price_index"
100102 else ("%s%s__idxCurrent__" + assetId)
101103
102104
103105 func priceIndexPrefix (assetId) = if ((assetId == ""))
104106 then "price_index_"
105107 else (("%s%s%d__idx2Height__" + assetId) + "__")
106108
107109
108110 func priceHeightPrefix (assetId) = if ((assetId == ""))
109111 then "price_"
110112 else (("%s%s%d__priceByHeight__" + assetId) + "__")
111113
112114
113115 let minUsdnFee = valueOrElse(getInteger(configProvider, USDNFEEK), 0)
114116
115117 let minWavesFee = valueOrElse(getInteger(configProvider, WAVESFEEK), 0)
116118
117119 let assetName = valueOrElse(getString(this, ASSNAMEK), "")
118120
119121 let bullCol = localI(BULLCOLK, "no 0")
120122
121123 let bearCol = localI(BEARCOLK, "no 1")
122124
123125 let bullCirc = localI(BULLCIRCK, "no 2")
124126
125127 let bearCirc = localI(BEARCIRCK, "no 3")
126128
127129 let BULL = localS(BULLK, "no 14")
128130
129131 let BEAR = localS(BEARK, "no 15")
130132
131133 let mainToken = localS(USDNK, "no 16")
132134
133135 let issuePercentile = confI(ISSPERCK, "no 4")
134136
135137 let redeemPercentile = confI(REDPERCK, "no 5")
136138
137139 let minIssue = confI(MINISSK, "no 6")
138140
139141 let minRedeem = confI(MINREDK, "no 7")
140142
141143 let minPool = confI(MINPOOLK, "no 8")
142144
143145 let rebalancePercentile = valueOrElse(getInteger(configProvider, ((toString(this) + "_") + REBPERCK)), 0)
144146
145147 let whitelist = confS(WLISTK, "no 9")
146148
147149 func allowed (a) = if ((whitelist == ""))
148150 then true
149151 else isDefined(indexOf(whitelist, toString(a)))
150152
151153
152154 let poolMain = localI(POOLUSDNK, "no")
153155
154156 let poolUp = localI(POOLUPK, "no 10")
155157
156158 let poolDwn = localI(POOLDWNK, "no 11")
157159
158160 let poolToken = localS(POOLK, "no 12")
159161
160162 let poolTokenCirculation = localI(POOLCIRCK, "no 13")
161163
162164 let poolBullExposure = fraction(bullCol, poolUp, bullCirc)
163165
164166 let poolBearExposure = fraction(bearCol, poolDwn, bearCirc)
165167
166168 let poolValue = ((poolMain + poolBullExposure) + poolBearExposure)
167169
168170 let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
169171
170-let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
172+let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
171173
172174 let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey(assetName)), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey(assetName)))
173175
174176 let leverage = valueOrElse(getInteger(this, LEVK), 3)
175177
176-func heightByIndex (assetName,priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
178+func heightByIndex (priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
177179
178180
179-func priceByHeight (assetName,priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
181+func priceByHeight (priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
180182
181183
182-func priceByIndex (assetName,priceIndex) = priceByHeight(assetName, heightByIndex(assetName, priceIndex))
184+func priceByIndex (priceIndex) = priceByHeight(heightByIndex(priceIndex))
183185
184186
185187 let queueSize = valueOrElse(getInteger(this, QSIZEK), 0)
186188
187189 let headPointer = valueOrElse(getString(this, HEADK), "")
188190
189191 let tailPointer = valueOrElse(getString(this, TAILK), "")
190192
191193 let feesAccumulated = valueOrElse(getInteger(this, FEEACCK), 0)
192194
193195 let ISSUE = "ISSUE"
194196
195197 let REDEEM = "REDEEM"
196198
197199 let POOL = "POOL"
198200
199201 let UNPOOL = "UNPOOL"
200202
201203 let feeAddrKey = "feeAddress"
202204
203205 let stakingAddrKey = "stakingAddress"
204206
205207 let daemonPubKeyKey = "daemonPublicKey"
206208
207209 let feeAddress = valueOrErrorMessage(addressFromString(confS(feeAddrKey, "no feeAddress")), "bad feeAddress")
208210
209211 let stakingAddress = confS(stakingAddrKey, "no stakingAddress")
210212
211213 let daemonPublicKey = fromBase58String(confS(daemonPubKeyKey, "no daemonPublicKey"))
212214
213215 let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
214216
215217 let admins = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
216218
217219 let opn = valueOrElse(getBoolean(oracle, ("%s%s__isMarketOpened__" + assetName)), true)
218220
219221 func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|")
220222
221223
222-func userDiffAbs () = {
223- let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure))
224- let userBullCol = $t058835972._1
225- let userBearCol = $t058835972._2
226- let diff = (userBullCol - userBearCol)
224+func diffAbs (a1,a2) = {
225+ let diff = (a1 - a2)
227226 if ((diff > 0))
228227 then diff
229228 else (0 - diff)
230229 }
230+
231+
232+func userDiffAbs () = diffAbs((bullCol - poolBullExposure), (bearCol - poolBearExposure))
231233
232234
233235 func maxIssue (tokenId) = {
234236 let poolInvestment = if ((poolUp > 0))
235237 then BULL
236238 else BEAR
237239 if ((tokenId != poolInvestment))
238240 then poolMain
239241 else (userDiffAbs() + poolValue)
240242 }
241243
242244
243245 func validatePMFee (i,minPayout) = if ((0 > minPayout))
244246 then throw("negative min payout")
245247 else {
246248 let p = i.payments[1]
247249 let ok = match p.assetId {
248250 case bv: ByteVector =>
249251 if ((toBase58String(bv) == mainToken))
250252 then (p.amount >= minUsdnFee)
251253 else false
252254 case waves: Unit =>
253255 (p.amount >= minWavesFee)
254256 case _ =>
255257 throw("Match error")
256258 }
257259 if (!(ok))
258260 then throw("incorrect pacemaker fee")
259261 else true
260262 }
261263
262264
263265 func validateRequestRedeem (inv) = if ((inv.caller == this))
264266 then throw("can't do")
265267 else {
266268 func errorMessage (got) = throw(((((("bad token att: only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
267269
268270 let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "bad token att"))
269271 if (if ((assetId != BEAR))
270272 then (assetId != BULL)
271273 else false)
272274 then errorMessage(assetId)
273275 else {
274276 let attachedAmount = inv.payments[0].amount
275277 let col = if ((assetId == BEAR))
276278 then bearCol
277279 else bullCol
278280 let circ = if ((assetId == BEAR))
279281 then bearCirc
280282 else bullCirc
281283 let estimated = fraction(col, attachedAmount, circ)
282284 if ((minRedeem > estimated))
283285 then throw((((((((((("Attached payment too small. Min redeem amount is " + toString((minRedeem / 1000000))) + " USDN, ") + "attached amount: ") + toString(attachedAmount)) + ", col: ") + toString(col)) + ", circ: ") + toString(circ)) + ", estimated: ") + toString(estimated)))
284286 else unit
285287 }
286288 }
287289
288290
289291 func enqueue (id,action,amt,token,priceIndex,invoker,minPayout,maxPayout) = {
290292 let increaseQueueSize = IE(QSIZEK, (queueSize + 1))
291293 let itm = buildNewItem(action, amt, token, priceIndex, invoker, minPayout, maxPayout)
292294 if ((queueSize == 0))
293295 then [SE(HEADK, id), SE(TAILK, id), SE(id, itm), increaseQueueSize]
294296 else {
295297 let prevId = localS(TAILK, "can't get tail pointer")
296298 let prevItm = localS(prevId, "can't resolve pointer")
297299 let updatedPrevItm = (prevItm + id)
298300 [SE(prevId, updatedPrevItm), SE(id, itm), SE(TAILK, id), increaseQueueSize]
299301 }
300302 }
301303
302304
303-func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
305+func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0,steps) = {
304306 func closeUp (c1,c2,a0,a1,c0,pu,pd) = {
305307 let diff = (c1 - c2)
306308 let exp = fraction(c1, pu, a0)
307309 let liquidatedTokens = if ((diff > exp))
308310 then pu
309311 else fraction(diff, a0, c1)
310312 let liquidatedValue = if ((diff > exp))
311313 then exp
312314 else fraction(liquidatedTokens, c1, a0)
313315 $Tuple7((c1 - liquidatedValue), c2, (a0 - liquidatedTokens), a1, (c0 + liquidatedValue), (pu - liquidatedTokens), pd)
314316 }
315317
316318 func closeDwn (c1,c2,a0,a1,c0,pu,pd) = {
317319 let diff = (c2 - c1)
318320 let exp = fraction(c2, pd, a1)
319321 let liquidatedTokens = if ((diff > exp))
320322 then pd
321323 else fraction(diff, a1, c2)
322324 let liquidatedValue = if ((diff > exp))
323325 then exp
324326 else fraction(liquidatedTokens, c2, a1)
325327 $Tuple7(c1, (c2 - liquidatedValue), a0, (a1 - liquidatedTokens), (c0 + liquidatedValue), pu, (pd - liquidatedTokens))
326328 }
327329
328330 func openDwn (c1,c2,a0,a1,c0,pu,pd) = {
329331 let diff = (c1 - c2)
330332 let spentPoolValue = if ((c0 > diff))
331333 then diff
332334 else c0
333335 let acquiredTokens = fraction(spentPoolValue, a1, c2)
334336 $Tuple7(c1, (c2 + spentPoolValue), a0, (a1 + acquiredTokens), (c0 - spentPoolValue), pu, (pd + acquiredTokens))
335337 }
336338
337339 func openUp (c1,c2,a0,a1,c0,pu,pd) = {
338340 let diff = (c2 - c1)
339341 let spentPoolValue = if ((c0 > diff))
340342 then diff
341343 else c0
342344 let acquiredTokens = fraction(spentPoolValue, a0, c1)
343345 $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd)
344346 }
345347
346- let $t01034111376 = if ((curBullCol0 > curBearCol0))
348+ let $t01030211337 = if ((curBullCol0 > curBearCol0))
347349 then {
348350 let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
349- let $t01056710704 = afterCloseUp
350- let a = $t01056710704._1
351- let b = $t01056710704._2
352- let c = $t01056710704._3
353- let d = $t01056710704._4
354- let e = $t01056710704._5
355- let f = $t01056710704._6
356- let g = $t01056710704._7
351+ let $t01052810665 = afterCloseUp
352+ let a = $t01052810665._1
353+ let b = $t01052810665._2
354+ let c = $t01052810665._3
355+ let d = $t01052810665._4
356+ let e = $t01052810665._5
357+ let f = $t01052810665._6
358+ let g = $t01052810665._7
357359 if ((f > 0))
358360 then afterCloseUp
359361 else if ((f == 0))
360362 then openDwn(a, b, c, d, e, f, g)
361363 else throw("poolUp < 0")
362364 }
363365 else {
364366 let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
365- let $t01105511195 = afterCloseDwn
366- let a = $t01105511195._1
367- let b = $t01105511195._2
368- let c = $t01105511195._3
369- let d = $t01105511195._4
370- let e = $t01105511195._5
371- let f = $t01105511195._6
372- let g = $t01105511195._7
367+ let $t01101611156 = afterCloseDwn
368+ let a = $t01101611156._1
369+ let b = $t01101611156._2
370+ let c = $t01101611156._3
371+ let d = $t01101611156._4
372+ let e = $t01101611156._5
373+ let f = $t01101611156._6
374+ let g = $t01101611156._7
373375 if ((g > 0))
374376 then afterCloseDwn
375377 else if ((g == 0))
376378 then openUp(a, b, c, d, e, f, g)
377379 else throw("poolDwn < 0")
378380 }
379- let c1 = $t01034111376._1
380- let c2 = $t01034111376._2
381- let a0 = $t01034111376._3
382- let a1 = $t01034111376._4
383- let c0 = $t01034111376._5
384- let pu = $t01034111376._6
385- let pd = $t01034111376._7
386- let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100))
387- let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000))
388- let c1SplitP = if (if (percentileActivated)
389- then (pd > 0)
390- else false)
381+ let c1 = $t01030211337._1
382+ let c2 = $t01030211337._2
383+ let a0 = $t01030211337._3
384+ let a1 = $t01030211337._4
385+ let c0 = $t01030211337._5
386+ let pu = $t01030211337._6
387+ let pd = $t01030211337._7
388+ let charge = fraction(userDiffAbs(), (rebalancePercentile * steps), ((1440 * 100) * 100))
389+ let c1SplitP = if ((pd > 0))
391390 then charge
392391 else 0
393- let c2SplitP = if (if (percentileActivated)
394- then (pu > 0)
395- else false)
392+ let c2SplitP = if ((pu > 0))
396393 then charge
397394 else 0
398395 $Tuple7((c1 - c1SplitP), (c2 - c2SplitP), a0, a1, ((c0 + c1SplitP) + c2SplitP), pu, pd)
399396 }
400397
401398
402399 func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
403- let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
404- let bullCol1 = $t01195712139._1
405- let bearCol1 = $t01195712139._2
406- let bullCic1 = $t01195712139._3
407- let bearCirc1 = $t01195712139._4
408- let poolMain1 = $t01195712139._5
409- let poolUp1 = $t01195712139._6
410- let poolDwn1 = $t01195712139._7
400+ let $t01176211947 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn, 0)
401+ let bullCol1 = $t01176211947._1
402+ let bearCol1 = $t01176211947._2
403+ let bullCic1 = $t01176211947._3
404+ let bearCirc1 = $t01176211947._4
405+ let poolMain1 = $t01176211947._5
406+ let poolUp1 = $t01176211947._6
407+ let poolDwn1 = $t01176211947._7
411408 [IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)]
412409 }
413410
414411
415412 func dequeue () = {
416413 func sp (a,mx) = if ((mx >= a))
417414 then $Tuple2(a, 0)
418415 else $Tuple2(mx, (a - mx))
419416
420417 if ((queueSize == 0))
421418 then throw("nothing to settle")
422419 else {
423420 func collectFee (fees) = IE(FEEACCK, (feesAccumulated + fees))
424421
425422 let decreaseQueueSize = IE(QSIZEK, (queueSize - 1))
426423 let isLastElement = (headPointer == tailPointer)
427424 let overwriteTail = SE(TAILK, "")
428425 let dataStr = localS(headPointer, "bad head pointer(dequeue)")
429426 let data = split(dataStr, "|")
430427 let action = data[0]
431428 let amt = parseIntValue(data[1])
432429 let token = data[2]
433430 let priceIndex = parseIntValue(data[3])
434431 let invoker = addressFromStringValue(data[4])
435432 let minPayout = if ((8 > size(data)))
436433 then 0
437434 else parseIntValue(data[5])
438435 let maxPayout = if ((8 > size(data)))
439436 then MAX
440437 else parseIntValue(data[6])
441438 let next = data[(size(data) - 1)]
442439 func payback (tkn) = [SE(HEADK, next), decreaseQueueSize, ST(invoker, amt, fromBase58String(tkn))]
443440
444- let items = if ((rebalancedPriceIndex > priceIndex))
445- then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
446- else if ((priceIndex > rebalancedPriceIndex))
447- then throw("can't dequeue, too early, rebalance first")
448- else if ((action == ISSUE))
441+ let items = if ((settledPriceIndex != priceIndex))
442+ then throw(((("corrupt state, settledPriceIndex=" + toString(settledPriceIndex)) + ", request price id=") + toString(priceIndex)))
443+ else if ((action == ISSUE))
444+ then {
445+ let feeSize = fraction(amt, issuePercentile, 10000)
446+ let addedCollateral = (amt - feeSize)
447+ let defaultAddedTokens = if ((token == BULL))
448+ then fraction(bullCirc, addedCollateral, bullCol)
449+ else if ((token == BEAR))
450+ then fraction(bearCirc, addedCollateral, bearCol)
451+ else throw("bad token id")
452+ let $t01395914032 = sp(defaultAddedTokens, maxPayout)
453+ let addedToCirculation = $t01395914032._1
454+ let extraTokens = $t01395914032._2
455+ let $t01404914220 = if ((token == BULL))
456+ then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0)
457+ else $Tuple4(0, 0, defaultAddedTokens, addedCollateral)
458+ let plusBulls = $t01404914220._1
459+ let plusBullCol = $t01404914220._2
460+ let plusBears = $t01404914220._3
461+ let plusBearCol = $t01404914220._4
462+ if ((minPayout > addedToCirculation))
463+ then payback(mainToken)
464+ else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
465+ }
466+ else if ((action == REDEEM))
449467 then {
450- let feeSize = fraction(amt, issuePercentile, 10000)
451- let addedCollateral = (amt - feeSize)
452- let defaultAddedTokens = if ((token == BULL))
453- then fraction(bullCirc, addedCollateral, bullCol)
468+ let removedTokens = amt
469+ let estimatedPayout = if ((token == BULL))
470+ then fraction(bullCol, removedTokens, bullCirc)
454471 else if ((token == BEAR))
455- then fraction(bearCirc, addedCollateral, bearCol)
472+ then fraction(bearCol, removedTokens, bearCirc)
456473 else throw("bad token id")
457- let $t01427014343 = sp(defaultAddedTokens, maxPayout)
458- let addedToCirculation = $t01427014343._1
459- let extraTokens = $t01427014343._2
460- let $t01436014531 = if ((token == BULL))
461- then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0)
462- else $Tuple4(0, 0, defaultAddedTokens, addedCollateral)
463- let plusBulls = $t01436014531._1
464- let plusBullCol = $t01436014531._2
465- let plusBears = $t01436014531._3
466- let plusBearCol = $t01436014531._4
467- if ((minPayout > addedToCirculation))
468- then payback(mainToken)
469- else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
474+ let feeSize = fraction(estimatedPayout, redeemPercentile, 10000)
475+ let defaultPayout = (estimatedPayout - feeSize)
476+ let $t01528715341 = sp(defaultPayout, maxPayout)
477+ let userPayout = $t01528715341._1
478+ let extra = $t01528715341._2
479+ let $t01535815523 = if ((token == BULL))
480+ then $Tuple4(removedTokens, estimatedPayout, 0, 0)
481+ else $Tuple4(0, 0, removedTokens, estimatedPayout)
482+ let minusBulls = $t01535815523._1
483+ let minusBullCol = $t01535815523._2
484+ let minusBears = $t01535815523._3
485+ let minusBearCol = $t01535815523._4
486+ if ((minPayout > userPayout))
487+ then payback(token)
488+ else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
470489 }
471- else if ((action == REDEEM))
490+ else if ((action == POOL))
472491 then {
473- let removedTokens = amt
474- let estimatedPayout = if ((token == BULL))
475- then fraction(bullCol, removedTokens, bullCirc)
476- else if ((token == BEAR))
477- then fraction(bearCol, removedTokens, bearCirc)
478- else throw("bad token id")
479- let feeSize = fraction(estimatedPayout, redeemPercentile, 10000)
480- let defaultPayout = (estimatedPayout - feeSize)
481- let $t01559815652 = sp(defaultPayout, maxPayout)
482- let userPayout = $t01559815652._1
483- let extra = $t01559815652._2
484- let $t01566915834 = if ((token == BULL))
485- then $Tuple4(removedTokens, estimatedPayout, 0, 0)
486- else $Tuple4(0, 0, removedTokens, estimatedPayout)
487- let minusBulls = $t01566915834._1
488- let minusBullCol = $t01566915834._2
489- let minusBears = $t01566915834._3
490- let minusBearCol = $t01566915834._4
491- if ((minPayout > userPayout))
492- then payback(token)
493- else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
492+ let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
493+ if ((minPayout > issueTokens))
494+ then payback(mainToken)
495+ else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
494496 }
495- else if ((action == POOL))
497+ else if ((action == UNPOOL))
496498 then {
497- let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
498- if ((minPayout > issueTokens))
499- then payback(mainToken)
500- else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
499+ func share (a) = fraction(a, amt, poolTokenCirculation)
500+
501+ let unpooledMain = share(poolMain)
502+ let unpooledUp = share(poolUp)
503+ let unpooledDwn = share(poolDwn)
504+ let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
505+ let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
506+ let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
507+ if ((minPayout > totalUnpooledValue))
508+ then payback(poolToken)
509+ else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
501510 }
502- else if ((action == UNPOOL))
503- then {
504- func share (a) = fraction(a, amt, poolTokenCirculation)
505-
506- let unpooledMain = share(poolMain)
507- let unpooledUp = share(poolUp)
508- let unpooledDwn = share(poolDwn)
509- let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
510- let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
511- let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
512- if ((minPayout > totalUnpooledValue))
513- then payback(poolToken)
514- else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
515- }
516- else throw(("bad action: " + action))
511+ else throw(("bad action: " + action))
517512 if (isLastElement)
518513 then overwriteTail :: items
519514 else items
520515 }
521516 }
522517
523518
524-func rebalance () = {
525- func LV (v,p0,p1,m) = {
526- let denom = {
527- let md = (((2 * (if ((p1 > p0))
519+func rebalance (offset) = if ((offset == 0))
520+ then throw("[OK] offset=0")
521+ else {
522+ func LV (v,p0,p1,m) = {
523+ let denom = {
524+ let md = (((2 * (if ((p1 > p0))
525+ then p1
526+ else p0)) * m) / 3037000499)
527+ if ((10 > md))
528+ then 10
529+ else if ((100 > md))
530+ then 100
531+ else 1000
532+ }
533+ let pmax = ((if ((p1 > p0))
528534 then p1
529- else p0)) * m) / 3037000499)
530- if ((10 > md))
531- then 10
532- else if ((100 > md))
533- then 100
534- else 1000
535+ else p0) / denom)
536+ let pmin = ((if ((p0 > p1))
537+ then p1
538+ else p0) / denom)
539+ let a = (pmin * pmin)
540+ let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
541+ let ma = ((m * m) - m)
542+ fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
535543 }
536- let pmax = ((if ((p1 > p0))
537- then p1
538- else p0) / denom)
539- let pmin = ((if ((p0 > p1))
540- then p1
541- else p0) / denom)
542- let a = (pmin * pmin)
543- let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
544- let ma = ((m * m) - m)
545- fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
544+
545+ let unsettledPriceIndex = (settledPriceIndex + offset)
546+ if (!(opn))
547+ then [IE(REBIDXK, unsettledPriceIndex)]
548+ else {
549+ let settledPrice = priceByIndex(settledPriceIndex)
550+ let nextPrice = priceByIndex(unsettledPriceIndex)
551+ let minVol = if ((bearCol > bullCol))
552+ then bullCol
553+ else bearCol
554+ let redist = LV(minVol, settledPrice, nextPrice, leverage)
555+ let priceUpGoodForBulls = (assetName == "")
556+ let priceGoesUp = (nextPrice > settledPrice)
557+ let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
558+ let newBullCol = if (bullsEarn)
559+ then (bullCol + redist)
560+ else (bullCol - redist)
561+ let newBearCol = if (bullsEarn)
562+ then (bearCol - redist)
563+ else (bearCol + redist)
564+ let $t01945219650 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn, offset)
565+ let updBullCol = $t01945219650._1
566+ let updBearCol = $t01945219650._2
567+ let updBullCirc = $t01945219650._3
568+ let updBearCirc = $t01945219650._4
569+ let updPoolMain = $t01945219650._5
570+ let updPoolUp = $t01945219650._6
571+ let updPoolDwn = $t01945219650._7
572+[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
573+ }
546574 }
547-
548- let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data")
549- let unsettledPriceIndex = (settledPriceIndex + 1)
550- if (!(opn))
551- then [IE(REBIDXK, unsettledPriceIndex)]
552- else {
553- let settledPrice = priceByIndex(assetName, settledPriceIndex)
554- let nextPrice = priceByIndex(assetName, unsettledPriceIndex)
555- let minVol = if ((bearCol > bullCol))
556- then bullCol
557- else bearCol
558- let redist = LV(minVol, settledPrice, nextPrice, leverage)
559- let priceUpGoodForBulls = (assetName == "")
560- let priceGoesUp = (nextPrice > settledPrice)
561- let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
562- let newBullCol = if (bullsEarn)
563- then (bullCol + redist)
564- else (bullCol - redist)
565- let newBearCol = if (bullsEarn)
566- then (bearCol - redist)
567- else (bearCol + redist)
568- let $t01982820018 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
569- let updBullCol = $t01982820018._1
570- let updBearCol = $t01982820018._2
571- let updBullCirc = $t01982820018._3
572- let updBearCirc = $t01982820018._4
573- let updPoolMain = $t01982820018._5
574- let updPoolUp = $t01982820018._6
575- let updPoolDwn = $t01982820018._7
576-[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
577- }
578- }
579575
580576
581577 func calcMax (min,avg) = if ((min > avg))
582578 then throw(((("price too old: minPayout " + toString(min)) + " > avg = ") + toString(avg)))
583579 else ((avg + avg) - min)
584580
585581
586582 func requestIssueInternal (inv,tokenId,minPayout) = if (!(opn))
587583 then throw("markets closed")
588584 else if (if ((tokenId != BULL))
589585 then (tokenId != BEAR)
590586 else false)
591587 then throw("bad token req")
592588 else if ((inv.caller == this))
593589 then throw("can't do")
594590 else if (!(allowed(inv.caller)))
595591 then throw("only whitelisted can do")
596592 else {
597593 let errorMessage = (((("bad token req, only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") allowed")
598594 if ((inv.payments[0].assetId != fromBase58String(mainToken)))
599595 then throw("bad token att")
600596 else {
601597 let amt = inv.payments[0].amount
602- let $t02110921287 = if ((tokenId == BULL))
598+ let $t02074720925 = if ((tokenId == BULL))
603599 then $Tuple2(bullCol, bullCirc)
604600 else if ((tokenId == BEAR))
605601 then $Tuple2(bearCol, bearCirc)
606602 else throw(errorMessage)
607- let col = $t02110921287._1
608- let circ = $t02110921287._2
603+ let col = $t02074720925._1
604+ let circ = $t02074720925._2
609605 let est = fraction(amt, circ, col)
610- let $t02132921423 = if ((minPayout == 0))
606+ let $t02096721061 = if ((minPayout == 0))
611607 then $Tuple2(0, MAX)
612608 else $Tuple2(minPayout, calcMax(minPayout, est))
613- let minP = $t02132921423._1
614- let maxP = $t02132921423._2
609+ let minP = $t02096721061._1
610+ let maxP = $t02096721061._2
615611 if ((minIssue > amt))
616612 then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
617613 else {
618614 let maxAllowed = maxIssue(tokenId)
619615 if (if ((whitelist == ""))
620616 then (inv.payments[0].amount > maxAllowed)
621617 else false)
622618 then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN"))
623619 else enqueue(toBase58String(inv.transactionId), ISSUE, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
624620 }
625621 }
626622 }
627623
628624
629625 func requestRedeemInternal (inv,minPayout) = {
630626 let amt = inv.payments[0].amount
631627 let tokenId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "bad token att"))
632628 if (if ((tokenId != BULL))
633629 then (tokenId != BEAR)
634630 else false)
635631 then throw("bad token req")
636632 else {
637- let $t02238522524 = if ((tokenId == BULL))
633+ let $t02202322162 = if ((tokenId == BULL))
638634 then $Tuple2(bullCol, bullCirc)
639635 else if ((tokenId == BEAR))
640636 then $Tuple2(bearCol, bearCirc)
641637 else throw("bad token req")
642- let col = $t02238522524._1
643- let circ = $t02238522524._2
638+ let col = $t02202322162._1
639+ let circ = $t02202322162._2
644640 let est = fraction(amt, col, circ)
645- let $t02257222666 = if ((minPayout == 0))
641+ let $t02221022304 = if ((minPayout == 0))
646642 then $Tuple2(0, MAX)
647643 else $Tuple2(minPayout, calcMax(minPayout, est))
648- let minP = $t02257222666._1
649- let maxP = $t02257222666._2
644+ let minP = $t02221022304._1
645+ let maxP = $t02221022304._2
650646 if ((validateRequestRedeem(inv) == unit))
651647 then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
652648 else throw("doesn't happen")
653649 }
654650 }
655651
656652
657653 func requestPoolInternal (inv,minPayout) = if (!(allowed(inv.caller)))
658654 then throw("only whitelisted can do")
659655 else {
660656 let errMessage = "USDN required"
661657 let pmt = inv.payments[0]
662658 if ((pmt.assetId != fromBase58String(mainToken)))
663659 then throw(errMessage)
664660 else if ((minPool > pmt.amount))
665661 then throw(("pool min: " + toString(minPool)))
666662 else {
667663 let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue)
668- let $t02345923558 = if ((minPayout == 0))
664+ let $t02309723196 = if ((minPayout == 0))
669665 then $Tuple2(0, MAX)
670666 else $Tuple2(minPayout, calcMax(minPayout, estimate))
671- let minP = $t02345923558._1
672- let maxP = $t02345923558._2
667+ let minP = $t02309723196._1
668+ let maxP = $t02309723196._2
673669 enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
674670 }
675671 }
676672
677673
678674 func requestUnpoolInternal (inv,minPayout) = {
679675 let errMessage = (("only pool token allowed(" + poolToken) + ")")
680676 let pmt = inv.payments[0]
681677 if ((pmt.assetId != fromBase58String(poolToken)))
682678 then throw(errMessage)
683679 else {
684680 let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
685681 if ((minPool > estimate))
686682 then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
687683 else {
688- let $t02421524314 = if ((minPayout == 0))
684+ let $t02385323952 = if ((minPayout == 0))
689685 then $Tuple2(0, MAX)
690686 else $Tuple2(minPayout, calcMax(minPayout, estimate))
691- let minP = $t02421524314._1
692- let maxP = $t02421524314._2
687+ let minP = $t02385323952._1
688+ let maxP = $t02385323952._2
693689 enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
694690 }
695691 }
696692 }
697-
698-
699-@Callable(inv)
700-func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,defoAssetName,denom,lev) = if (isDefined(getString(this, BULLK)))
701- then throw("already initialized")
702- else {
703- let totalOwnedMainToken = inv.payments[0].amount
704- let bulls = (totalOwnedMainToken / 3)
705- let bears = bulls
706- let pools = ((totalOwnedMainToken - bulls) - bears)
707- if (if (if ((bears == 0))
708- then true
709- else (bulls == 0))
710- then true
711- else (pools == 0))
712- then throw("can't init balances")
713- else {
714- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index")
715- let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
716- let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
717- let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
718- let buid = calculateAssetId(bull)
719- let beid = calculateAssetId(bear)
720- let poid = calculateAssetId(pool)
721-[bull, bear, pool, SE(BULLK, toBase58String(buid)), SE(BEARK, toBase58String(beid)), SE(USDNK, toBase58String(value(inv.payments[0].assetId))), SE(POOLK, toBase58String(poid)), SE(ASSNAMEK, defoAssetName), SE(oraclePKKey, oraclePK), IE(REBIDXK, oracleCurrentPriceIndex), IE(BULLCOLK, bulls), IE(BEARCOLK, bears), IE(BULLCIRCK, (bulls / denom)), IE(BEARCIRCK, (bears / denom)), IE(POOLCIRCK, (pools / denom)), IE(POOLDWNK, 0), IE(POOLUPK, 0), IE(POOLUSDNK, pools), SE(configProviderKey, config), IE(LEVK, lev), ST(inv.caller, (bulls / denom), buid), ST(inv.caller, (bears / denom), beid), ST(inv.caller, (pools / denom), poid)]
722- }
723- }
724-
725693
726694
727695 @Callable(i)
728696 func withdrawFee (amount) = if ((amount > feesAccumulated))
729697 then throw(("too much. available: " + toString(feesAccumulated)))
730698 else [IE(FEEACCK, (feesAccumulated - amount)), ST(feeAddress, amount, fromBase58String(mainToken))]
731699
732700
733701
734702 @Callable(inv)
735703 func requestRedeem () = requestRedeemInternal(inv, 0)
736704
737705
738706
739707 @Callable(inv)
740708 func requestRedeemSl (sl) = if (validatePMFee(inv, sl))
741709 then requestRedeemInternal(inv, sl)
742710 else throw()
743711
744712
745713
746714 @Callable(inv)
747715 func requestIssue (tokenId) = requestIssueInternal(inv, tokenId, 0)
748716
749717
750718
751719 @Callable(inv)
752720 func requestIssueSl (tokenId,sl) = if (validatePMFee(inv, sl))
753721 then requestIssueInternal(inv, tokenId, sl)
754722 else throw()
755723
756724
757725
758726 @Callable(inv)
759727 func requestPool () = requestPoolInternal(inv, 0)
760728
761729
762730
763731 @Callable(inv)
764732 func requestPoolSl (sl) = if (validatePMFee(inv, sl))
765733 then requestPoolInternal(inv, sl)
766734 else throw()
767735
768736
769737
770738 @Callable(inv)
771739 func requestUnpool () = requestUnpoolInternal(inv, 0)
772740
773741
774742
775743 @Callable(inv)
776744 func requestUnpoolSl (sl) = if (validatePMFee(inv, sl))
777745 then requestUnpoolInternal(inv, sl)
778746 else throw()
779747
780748
781749
782750 @Callable(inv)
783751 func settle () = {
784752 let queueEmpty = (headPointer == "")
785- let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
753+ let canRebalance = (oraclePriceIndex > settledPriceIndex)
786754 if (queueEmpty)
787755 then if (canRebalance)
788- then rebalance()
756+ then rebalance(1)
789757 else throw("[OK] all done, carry on")
790758 else {
791759 let data = split(valueOrErrorMessage(getString(this, headPointer), ("bad head pointer(settle): " + headPointer)), "|")
792- let priceIndex = parseIntValue(data[3])
793- if ((priceIndex > rebalancedPriceIndex))
760+ let queuePriceIndex = parseIntValue(data[3])
761+ if ((queuePriceIndex > settledPriceIndex))
794762 then if (canRebalance)
795- then rebalance()
763+ then rebalance(1)
796764 else throw("[OK] need to wait")
797- else if ((priceIndex == rebalancedPriceIndex))
765+ else if ((queuePriceIndex == settledPriceIndex))
798766 then dequeue()
799767 else throw("future price already rebalanced")
800768 }
801769 }
802770
803771
772+
773+@Callable(inv)
774+func settle2 () = {
775+ let queueEmpty = (headPointer == "")
776+ let queuePriceIndex = if (queueEmpty)
777+ then MAX
778+ else {
779+ let data = split(localS(headPointer, "settle2: bad head pointer"), "|")
780+ parseIntValue(data[3])
781+ }
782+ let settledPrice = priceByIndex(settledPriceIndex)
783+ func hasDeviation (priceIndex) = {
784+ let p = priceByIndex(priceIndex)
785+ (fraction(diffAbs(settledPrice, p), 1000000, settledPrice) >= maxDeviation)
786+ }
787+
788+ let maxPossibleShift = (min([queuePriceIndex, oraclePriceIndex]) - settledPriceIndex)
789+ func f (acc,shift) = if (if (acc._2)
790+ then true
791+ else (shift > maxPossibleShift))
792+ then acc
793+ else $Tuple2(shift, if ((shift == 7))
794+ then true
795+ else hasDeviation((settledPriceIndex + shift)))
796+
797+ let $t02683026929 = {
798+ let $list2687426929 = [1, 2, 3, 4, 5, 6, 7]
799+ let $size2687426929 = size($list2687426929)
800+ let $acc02687426929 = $Tuple2(settledPriceIndex, false)
801+ if (($size2687426929 == 0))
802+ then $acc02687426929
803+ else {
804+ let $acc12687426929 = f($acc02687426929, $list2687426929[0])
805+ if (($size2687426929 == 1))
806+ then $acc12687426929
807+ else {
808+ let $acc22687426929 = f($acc12687426929, $list2687426929[1])
809+ if (($size2687426929 == 2))
810+ then $acc22687426929
811+ else {
812+ let $acc32687426929 = f($acc22687426929, $list2687426929[2])
813+ if (($size2687426929 == 3))
814+ then $acc32687426929
815+ else {
816+ let $acc42687426929 = f($acc32687426929, $list2687426929[3])
817+ if (($size2687426929 == 4))
818+ then $acc42687426929
819+ else {
820+ let $acc52687426929 = f($acc42687426929, $list2687426929[4])
821+ if (($size2687426929 == 5))
822+ then $acc52687426929
823+ else {
824+ let $acc62687426929 = f($acc52687426929, $list2687426929[5])
825+ if (($size2687426929 == 6))
826+ then $acc62687426929
827+ else {
828+ let $acc72687426929 = f($acc62687426929, $list2687426929[6])
829+ if (($size2687426929 == 7))
830+ then $acc72687426929
831+ else {
832+ let $acc82687426929 = f($acc72687426929, $list2687426929[7])
833+ throw("List size exceed 7")
834+ }
835+ }
836+ }
837+ }
838+ }
839+ }
840+ }
841+ }
842+ }
843+ let okShift = $t02683026929._1
844+ let forcedByDeviationOrTimeout = $t02683026929._2
845+ let queueWaits = (oraclePriceIndex >= queuePriceIndex)
846+ if ((settledPriceIndex > queuePriceIndex))
847+ then throw("settle2: future price already settled/rebalanced")
848+ else if ((settledPriceIndex == queuePriceIndex))
849+ then dequeue()
850+ else if (if ((okShift > 0))
851+ then if (forcedByDeviationOrTimeout)
852+ then true
853+ else queueWaits
854+ else false)
855+ then rebalance(okShift)
856+ else throw(("settle2: [OK] all done, carry on. available shift: " + toString(okShift)))
857+ }
858+
859+
804860 @Verifier(tx)
805861 func verify () = {
806- let initial = if (!(isDefined(getString(this, BULLK))))
807- then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
808- else false
809862 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(admins[0])))
810863 then 1
811864 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(admins[1])))
812865 then 1
813866 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(admins[2])))
814867 then 1
815868 else 0)) > 1)
816869 let stakingAction = match tx {
817870 case tx: InvokeScriptTransaction =>
818871 let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey)
819872 let feesCorrect = if ((tx.feeAssetId == unit))
820873 then ((1000 * 1000) >= tx.fee)
821874 else false
822875 let dappCorrect = (tx.dApp == rpdAddress)
823876 let unlock = (tx.function == "unlockNeutrino")
824877 let lock = if (if ((tx.function == "lockNeutrinoSP"))
825878 then (tx.args[0] == stakingAddress)
826879 else false)
827880 then (wavesBalance(this).available >= ten8)
828881 else false
829882 let funcCorrect = if (lock)
830883 then true
831884 else unlock
832885 if (if (if (signedCorrectly)
833886 then feesCorrect
834887 else false)
835888 then dappCorrect
836889 else false)
837890 then funcCorrect
838891 else false
839892 case _ =>
840893 false
841894 }
842- if (if (initial)
843- then true
844- else adminAction)
895+ if (adminAction)
845896 then true
846897 else stakingAction
847898 }
848899

github/deemru/w8io/786bc32 
154.92 ms