tx · 72X4sHx16affzyHvvNdt4qZEYHcfEp45XZHQbHMUhN5X

3PCq2VqxGMmEyB8gLoUi8KuV9tYSD3VMC74:  -0.01400000 Waves

2022.05.18 21:21 [3122948] smart account 3PCq2VqxGMmEyB8gLoUi8KuV9tYSD3VMC74 > SELF 0.00000000 Waves

{ "type": 13, "id": "72X4sHx16affzyHvvNdt4qZEYHcfEp45XZHQbHMUhN5X", "fee": 1400000, "feeAssetId": null, "timestamp": 1652898142345, "version": 2, "chainId": 87, "sender": "3PCq2VqxGMmEyB8gLoUi8KuV9tYSD3VMC74", "senderPublicKey": "AgEaeJWmKzbxoJ1uBK5S4nbSdPPPeYKWktd6MhFM2MGY", "proofs": [ "SM96RXE6nhKHeCtno7BFu61SWFaLughrUURdHzU4D67Fh3jKmjg5ycuLtTSM9cP2S78PtBzH4XizsacZDemgRSC" ], "script": "base64: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dG9rZW5FYXJuaW5nc0xhc3RDaGVjawQAAAATY3VycmVudEJhbGFuY2VEZWx0YQkAAGUAAAACCQEAAAAPZ2V0VG9rZW5CYWxhbmNlAAAAAQUAAAAHYXNzZXRJZAUAAAAIYUJhbGFuY2UEAAAAFGN1cnJlbnRUb2tlbkVhcm5pbmdzAwkAAGYAAAACBQAAABNjdXJyZW50QmFsYW5jZURlbHRhBQAAABV0b2tlbkJhbGFuY2VMYXN0Q2hlY2sFAAAAE2N1cnJlbnRCYWxhbmNlRGVsdGEFAAAAFXRva2VuQmFsYW5jZUxhc3RDaGVjawQAAAALbmV3RWFybmluZ3MJAABlAAAAAgUAAAAUY3VycmVudFRva2VuRWFybmluZ3MFAAAAFXRva2VuQmFsYW5jZUxhc3RDaGVjawQAAAALbmV3SW50ZXJlc3QDCQAAAAAAAAIFAAAAC3RvdGFsU3Rha2VkAAAAAAAAAAAAAAAAAAAAAAAACQAAawAAAAMFAAAAC25ld0Vhcm5pbmdzBQAAAAZTY2FsZTgFAAAAC3RvdGFsU3Rha2VkBAAAABFsYXN0Q2hlY2tJbnRlcmVzdAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAARZ2xvYmFsX2xhc3RDaGVja18FAAAACmFzc2V0SWRTdHICAAAACV9pbnRlcmVzdAkAAGQAAAACBQAAABFsYXN0Q2hlY2tJbnRlcmVzdAUAAAALbmV3SW50ZXJlc3QBAAAAC2NsYWltUmVzdWx0AAAAAQAAAAdhZGRyZXNzBAAAAAphZGRyZXNzU3RyCQAEJQAAAAEFAAAAB2FkZHJlc3MEAAAADHB1enpsZUFtb3VudAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIFAAAACmFkZHJlc3NTdHICAAAADF9pbmRleFN0YWtlZAoBAAAAB2hhbmRsZXIAAAACAAAABWFjY3VtAAAAB2Fzc2V0SWQEAAAACmFzc2V0SWRTdHIJAQAAAA5nZXRBc3NldFN0cmluZwAAAAEFAAAAB2Fzc2V0SWQEAAAACGFCYWxhbmNlCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAdnbG9iYWxfCQEAAAAOZ2V0QXNzZXRTdHJpbmcAAAABBQAAAAdhc3NldElkAgAAAAhfYmFsYW5jZQQAAAAWdG9rZW5FYXJuaW5nc0xhc3RDaGVjawkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAARZ2xvYmFsX2xhc3RDaGVja18FAAAACmFzc2V0SWRTdHICAAAACV9lYXJuaW5ncwQAAAAUY3VycmVudFRva2VuSW50ZXJlc3QJAQAAAB1jYWxjdWxhdGVDdXJyZW50QXNzZXRJbnRlcmVzdAAAAAQFAAAAB2Fzc2V0SWQFAAAACmFzc2V0SWRTdHIFAAAACGFCYWxhbmNlBQAAABZ0b2tlbkVhcm5pbmdzTGFzdENoZWNrBAAAABRjdXJyZW50VG9rZW5FYXJuaW5ncwkAAZYAAAABCQAETAAAAAIFAAAAFnRva2VuRWFybmluZ3NMYXN0Q2hlY2sJAARMAAAAAgkAAGUAAAACCQEAAAAPZ2V0VG9rZW5CYWxhbmNlAAAAAQUAAAAHYXNzZXRJZAUAAAAIYUJhbGFuY2UFAAAAA25pbAQAAAAMcmV3YXJkQW1vdW50CQAAawAAAAMFAAAADHB1enpsZUFtb3VudAkAAGUAAAACBQAAABRjdXJyZW50VG9rZW5JbnRlcmVzdAkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAphZGRyZXNzU3RyAgAAAAtfbGFzdENoZWNrXwUAAAAKYXNzZXRJZFN0cgIAAAAJX2ludGVyZXN0BQAAAAZTY2FsZTgEAAAACHRyYW5zZmVyAwkAAAAAAAACBQAAAAxyZXdhcmRBbW91bnQAAAAAAAAAAAAFAAAAA25pbAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdhZGRyZXNzBQAAAAxyZXdhcmRBbW91bnQFAAAAB2Fzc2V0SWQFAAAAA25pbAkABRQAAAACCQAETgAAAAIJAAROAAAAAggFAAAABWFjY3VtAAAAAl8xBQAAAAh0cmFuc2ZlcgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkAASwAAAACCQABLAAAAAICAAAAEWdsb2JhbF9sYXN0Q2hlY2tfBQAAAAphc3NldElkU3RyAgAAAAlfZWFybmluZ3MJ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ZWQgYSBiaWdnZXIgdG9rZW5zIGFtb3VudCB0byBsYXVuY2ggdGhlIHBvb2wEAAAADnBvb2xUb2tlbklzc3VlCQAEQwAAAAcJAAEsAAAAAgIAAAADUFogCQEAAAAMdHJ5R2V0U3RyaW5nAAAAAQIAAAARc3RhdGljX3Bvb2xEb21haW4CAAAAHVB1enpsZSBTd2FwOiBwb29sIGluZGV4IHRva2VuBQAAABFpbml0aWFsUG9vbFRva2VucwUAAAARUG9vbFRva2VuRGVjaW1hbHMGBQAAAAR1bml0AAAAAAAAAAAABAAAAAtwb29sVG9rZW5JZAkABDgAAAABBQAAAA5wb29sVG9rZW5Jc3N1ZQkABE4AAAACCQEAAAALcHJlcGFyZUxpc3QAAAAACQAETAAAAAIFAAAADnBvb2xUb2tlbklzc3VlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAUAAAARaW5pdGlhbFBvb2xUb2tlbnMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAEGdsb2JhbF93YXNJbml0ZWQAAAAAAAAAAAEJAARMAAAAAgkBAAAAC0JpbmFyeUVudHJ5AAAAAgIAAAATZ2xvYmFsX3Bvb2xUb2tlbl9pZAUAAAALcG9vbFRva2VuSWQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgIAAAAWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgkBAAAADmdldEFzc2V0U3RyaW5nAAAAAQUAAAALcG9vbFRva2VuSWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXICAAAADF9pbmRleFN0YWtlZAUAAAARaW5pdGlhbFBvb2xUb2tlbnMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAEmdsb2JhbF9pbmRleFN0YWtlZAUAAAARaW5pdGlhbFBvb2xUb2tlbnMFAAAAA25pbAAAAAFpAQAAAA1nZW5lcmF0ZUluZGV4AAAAAQAAAApuZWVkQ2hhbmdlAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwUAAAABVAkAAAIAAAABCQABLAAAAAICAAAAO3lvdSBuZWVkIHRvIGF0dGFjaCBhbGwgcG9vbCB0b2tlbnMuIGFtb3VudCBvZiBwb29sIHRva2VuczogCQABpAAAAAEFAAAAAVQDCQEAAAABIQAAAAEJAQAAABNjaGVja1Rva2Vuc1ZhbGlkaXR5AAAAAQgFAAAAAWkAAAAIcGF5bWVudHMJAAACAAAAAQIAAAAVd3JvbmcgYXNzZXRzIGF0dGFjaGVkBAAAAAdQSXNzdWVkCQEAAAANZ2V0TWluUElzc3VlZAAAAAEIBQAAAAFpAAAACHBheW1lbnRzBAAAAAdyZWlzc3VlCQEAAAAHUmVpc3N1ZQAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDU3KQAAAAECAAAAE2dsb2JhbF9wb29sVG9rZW5faWQFAAAAB1BJc3N1ZWQGBAAAAAZyZXN1bHQJAQAAABNoYW5kbGVQb29sVG9rZW5zQWRkAAAABAUAAAAHUElzc3VlZAgFAAAAAWkAAAAIcGF5bWVudHMIBQAAAAFpAAAADG9yaWdpbkNhbGxlcgUAAAAKbmVlZENoYW5nZQkABRQAAAACCQAETgAAAAIFAAAABnJlc3VsdAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAB1BJc3N1ZWQJAQAAAAx0cnlHZXRCaW5hcnkAAAABAgAAABNnbG9iYWxfcG9vbFRva2VuX2lkCQAETAAAAAIFAAAAB3JlaXNzdWUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQAAZAAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAAXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFAAAAB1BJc3N1ZWQFAAAAA25pbAUAAAAHUElzc3VlZAAAAAFpAQAAAApzdGFrZUluZGV4AAAAAAQAAAAKYWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAxvcmlnaW5DYWxsZXIEAAAAA3BtdAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAMJAQAAAAIhPQAAAAIJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAkBAAAADHRyeUdldEJpbmFyeQAAAAECAAAAE2dsb2JhbF9wb29sVG9rZW5faWQJAAACAAAAAQIAAAAUd3JvbmcgYXNzZXQgYXR0YWNoZWQJAQAAABBpbmRleFN0YWtlUmVzdWx0AAAAAgUAAAAKYWRkcmVzc1N0cggFAAAAA3BtdAAAAAZhbW91bnQAAAABaQEAAAAMdW5zdGFrZUluZGV4AAAAAQAAAAxwdXp6bGVBbW91bnQEAAAACmFkZHJlc3NTdHIJAAQlAAAAAQgFAAAAAWkAAAAMb3JpZ2luQ2FsbGVyBAAAAA9wdXp6bGVBdmFpbGFibGUJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkAASwAAAACBQAAAAphZGRyZXNzU3RyAgAAAAxfaW5kZXhTdGFrZWQDCQAAZgAAAAIFAAAADHB1enpsZUFtb3VudAUAAAAPcHV6emxlQXZhaWxhYmxlCQAAAgAAAAECAAAAJXlvdSBkb24ndCBoYXZlIGluZGV4IHRva2VucyBhdmFpbGFibGUDCQEAAAAKaXNTaHV0ZG93bgAAAAAJAAACAAAAAQIAAAATY29udHJhY3QgaXMgb24gc3RvcAkABE4AAAACCQEAAAALY2xhaW1SZXN1bHQAAAABCAUAAAABaQAAAAxvcmlnaW5DYWxsZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAKYWRkcmVzc1N0cgIAAAAMX2luZGV4U3Rha2VkCQAAZQAAAAIFAAAAD3B1enpsZUF2YWlsYWJsZQUAAAAMcHV6emxlQW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABJnbG9iYWxfaW5kZXhTdGFrZWQJAABlAAAAAgkBAAAADXRyeUdldEludGVnZXIAAAABAgAAABJnbG9iYWxfaW5kZXhTdGFrZWQFAAAADHB1enpsZUFtb3VudAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAADHB1enpsZUFtb3VudAkBAAAAEUBleHRyTmF0aXZlKDEwNTcpAAAAAQIAAAATZ2xvYmFsX3Bvb2xUb2tlbl9pZAUAAAADbmlsAAAAAWkBAAAAEWNsYWltSW5kZXhSZXdhcmRzAAAAAAMJAQAAAAppc1NodXRkb3duAAAAAAkAAAIAAAABAgAAABNjb250cmFjdCBpcyBvbiBzdG9wCQEAAAALY2xhaW1SZXN1bHQAAAABCAUAAAABaQAAAAZjYWxsZXIAAAABaQEAAAALcmVkZWVtSW5kZXgAAAABAAAADHNlbmRUb09yaWdpbgQAAAADcG10CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAwkBAAAAAiE9AAAAAggFAAAAA3BtdAAAAAdhc3NldElkCQEAAAAMdHJ5R2V0QmluYXJ5AAAAAQIAAAATZ2xvYmFsX3Bvb2xUb2tlbl9pZAkAAAIAAAABAgAAAB5wbGVhc2UgYXR0YWNoIHBvb2wgc2hhcmUgdG9rZW4DCQEAAAAKaXNTaHV0ZG93bgAAAAAJAAACAAAAAQIAAAATY29udHJhY3QgaXMgb24gc3RvcAQAAAAJUFJlZGVlbWVkCAUAAAADcG10AAAABmFtb3VudAQAAAAGcmVzdWx0CQEAAAAWaGFuZGxlUG9vbFRva2Vuc1JlZGVlbQAAAAIFAAAACVBSZWRlZW1lZAMFAAAADHNlbmRUb09yaWdpbggFAAAAAWkAAAAMb3JpZ2luQ2FsbGVyCAUAAAABaQAAAAZjYWxsZXIJAAROAAAAAgUAAAAGcmVzdWx0CQAETAAAAAIJAQAAAARCdXJuAAAAAgkBAAAADHRyeUdldEJpbmFyeQAAAAECAAAAE2dsb2JhbF9wb29sVG9rZW5faWQFAAAACVBSZWRlZW1lZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAABlAAAAAgkBAAAADXRyeUdldEludGVnZXIAAAABAgAAABdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAUAAAAJUFJlZGVlbWVkBQAAAANuaWwAAAABaQEAAAAEc3dhcAAAAAIAAAAIYXNzZXRPdXQAAAAHbWluaW11bQQAAAADcG10CQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAhBbW91bnRJbgkBAAAABXZhbHVlAAAAAQgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50BAAAAAdBc3NldEluCAUAAAADcG10AAAAB2Fzc2V0SWQEAAAACEFzc2V0T3V0CQEAAAANZ2V0QXNzZXRCeXRlcwAAAAEFAAAACGFzc2V0T3V0BAAAAApmZWVBc3NldEluBQAAAAdBc3NldEluBAAAAAtmZWVBc3NldE91dAUAAAALdXNkbkFzc2V0SWQEAAAADkFzc2V0SW5CYWxhbmNlCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAdnbG9iYWxfCQEAAAAOZ2V0QXNzZXRTdHJpbmcAAAABBQAAAAdBc3NldEluAgAAAAhfYmFsYW5jZQQAAAAPQXNzZXRPdXRCYWxhbmNlCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAdnbG9iYWxfBQAAAAhhc3NldE91dAIAAAAIX2JhbGFuY2UEAAAAEmZlZUFzc2V0T3V0QmFsYW5jZQkBAAAADXRyeUdldEludGVnZXIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAHZ2xvYmFsXwkBAAAADmdldEFzc2V0U3RyaW5nAAAAAQUAAAALZmVlQXNzZXRPdXQCAAAACF9iYWxhbmNlBAAAAAtmZWVBbW91bnRJbgkAAGsAAAADBQAAAAhBbW91bnRJbgUAAAADRmVlBQAAAAhGZWVTY2FsZQQAAAANY2xlYW5BbW91bnRJbgkAAGUAAAACBQAAAAhBbW91bnRJbgUAAAALZmVlQW1vdW50SW4EAAAACUFtb3VudE91dAkBAAAAEmNhbGN1bGF0ZU91dEFtb3VudAAAAAUFAAAADWNsZWFuQW1vdW50SW4FAAAAB0Fzc2V0SW4FAAAACEFzc2V0T3V0BQAAAA5Bc3NldEluQmFsYW5jZQUAAAAPQXNzZXRPdXRCYWxhbmNlBAAAAAxmZWVBbW91bnRPdXQJAQAAABJjYWxjdWxhdGVPdXRBbW91bnQAAAAFBQAAAAtmZWVBbW91bnRJbgUAAAAHQXNzZXRJbgUAAAALZmVlQXNzZXRPdXQFAAAADkFzc2V0SW5CYWxhbmNlBQAAABJmZWVBc3NldE91dEJhbGFuY2UEAAAACmNyZWF0b3JGZWUJAABrAAAAAwUAAAAMZmVlQW1vdW50T3V0AAAAAAAAAAABAAAAAAAAAAAKBAAAAAtwcm90b2NvbEZlZQkAAGsAAAADBQAAAAxmZWVBbW91bnRPdXQAAAAAAAAAAAQAAAAAAAAAAAoEAAAADHN0YWtpbmdUb3BVcAkAA/0AAAAECQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFXlGiM+e6iuaqf1vWOvKmPZxqcBvQWKYm7AgAAAAt0b3BVcFJld2FyZAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACBQAAAAtmZWVBc3NldE91dAUAAAALcHJvdG9jb2xGZWUFAAAAA25pbAMJAAAAAAAAAgUAAAAMc3Rha2luZ1RvcFVwBQAAAAxzdGFraW5nVG9wVXADCQAAZgAAAAIFAAAAB21pbmltdW0FAAAACUFtb3VudE91dAkAAAIAAAABCQABLAAAAAICAAAAK2Ftb3VudCB0byByZWNpZXZlIGlzIGxvd2VyIHRoYW4gZ2l2ZW4gb25lOiAJAAGkAAAAAQUAAAAJQW1vdW50T3V0AwkAAGYAAAACAAAAAAAAAAAACQAAZQAAAAIFAAAAD0Fzc2V0T3V0QmFsYW5jZQUAAAAJQW1vdW50T3V0CQAAAgAAAAECAAAAG2NvbnRyYWN0IGlzIG91dCBvZiByZXNlcnZlcwMJAQAAAAppc1NodXRkb3duAAAAAAkAAAIAAAABAgAAABNjb250cmFjdCBpcyBvbiBzdG9wBAAAAAxuZXdCYWxhbmNlSW4JAABkAAAAAgUAAAAOQXNzZXRJbkJhbGFuY2UFAAAACEFtb3VudEluBAAAAA1uZXdCYWxhbmNlT3V0CQAAZQAAAAIFAAAAD0Fzc2V0T3V0QmFsYW5jZQUAAAAJQW1vdW50T3V0BAAAABJuZXdCYWxhbmNlRmVlQXNzZXQDAwkBAAAAAiE9AAAAAgUAAAALZmVlQXNzZXRPdXQFAAAAB0Fzc2V0SW4JAQAAAAIhPQAAAAIFAAAAC2ZlZUFzc2V0T3V0BQAAAAhBc3NldE91dAcJAABlAAAAAgUAAAASZmVlQXNzZXRPdXRCYWxhbmNlBQAAAAxmZWVBbW91bnRPdXQFAAAABHVuaXQEAAAADWFzc2V0SW5DaGFuZ2UJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAHZ2xvYmFsXwkBAAAADmdldEFzc2V0U3RyaW5nAAAAAQUAAAAHQXNzZXRJbgIAAAAIX2JhbGFuY2UFAAAADG5ld0JhbGFuY2VJbgQAAAAOYXNzZXRPdXRDaGFuZ2UJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAHZ2xvYmFsXwUAAAAIYXNzZXRPdXQCAAAACF9iYWxhbmNlBQAAAA1uZXdCYWxhbmNlT3V0BAAAABFmZWVBc3NldE91dENoYW5nZQMJAQAAAAIhPQAAAAIFAAAAEm5ld0JhbGFuY2VGZWVBc3NldAUAAAAEdW5pdAkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAdnbG9iYWxfCQEAAAAOZ2V0QXNzZXRTdHJpbmcAAAABBQAAAAtmZWVBc3NldE91dAIAAAAIX2JhbGFuY2UFAAAAEmZlZUFzc2V0T3V0QmFsYW5jZQkBAAAAC1N0cmluZ0VudHJ5AAAAAgIAAAAFaGVsbG8CAAAABXdvcmxkCQAFFAAAAAIJAARMAAAAAgUAAAANYXNzZXRJbkNoYW5nZQkABEwAAAACBQAAAA5hc3NldE91dENoYW5nZQkABEwAAAACBQAAABFmZWVBc3NldE91dENoYW5nZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACUFtb3VudE91dAUAAAAIQXNzZXRPdXQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAADHRyeUdldFN0cmluZwAAAAECAAAAEHN0YXRpY19wb29sT3duZXIFAAAACmNyZWF0b3JGZWUFAAAAC2ZlZUFzc2V0T3V0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABRnbG9iYWxfZWFybmVkQnlPd25lcgkAAGQAAAACCQEAAAANdHJ5R2V0SW50ZWdlcgAAAAECAAAAFGdsb2JhbF9lYXJuZWRCeU93bmVyBQAAAApjcmVhdG9yRmVlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAAA1nbG9iYWxfdm9sdW1lCQAAZAAAAAIJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQIAAAANZ2xvYmFsX3ZvbHVtZQkBAAAAEmNhbGN1bGF0ZVVzZG5WYWx1ZQAAAAQFAAAAB0Fzc2V0SW4FAAAACEFtb3VudEluBQAAAA5Bc3NldEluQmFsYW5jZQUAAAASZmVlQXNzZXRPdXRCYWxhbmNlBQAAAANuaWwFAAAACUFtb3VudE91dAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAAAwkBAAAACmlzU2h1dGRvd24AAAAABwMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V5BgkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAADG1hc3RlclB1YktleaECHGY=", "height": 3122948, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EiRjPBcNHQ2QzBUTGeM6tiUHUW86Aj3zfBjXdtSWujXv Next: 9yMrUotRGh4pHC8ykKude1oAi3aGG5TrsxajBppwma5M Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let usdnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
5+
6+let puzzleAssetId = base58'HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS'
7+
8+let masterAddress = Address(base58'3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf')
9+
10+let masterPubKey = base58'4z8CKSYQBKkzx7PBb5uBP1YPa6YAHRNTApW1sQVHT5eU'
11+
412 func tryGetInteger (key) = match getInteger(this, key) {
513 case b: Int =>
614 b
117125
118126 let Fee = tryGetInteger("static_fee")
119127
120-let AssetsWeightsDecimals = 2
128+let AssetsWeightsDecimals = 4
121129
122130 let Scale = 10000
123131
182190 }
183191
184192
185-func calculateUsdnValue (assetId,amount,aBalance) = {
186- let usdnId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
187- let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnId))]
193+func calculateUsdnValue (assetId,amount,aBalance,givenUsdnBalance) = {
194+ let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnAssetId))]
188195 let assetWeight = AssetsWeights[value(indexOf(assetIds, assetId))]
189- let usdnBalance = tryGetInteger((("global_" + getAssetString(usdnId)) + "_balance"))
190- fraction(amount, (usdnBalance / usdnWeight), (aBalance / assetWeight))
196+ let usdnBalance = match givenUsdnBalance {
197+ case x: Int =>
198+ givenUsdnBalance
199+ case _ =>
200+ tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
201+ }
202+ fraction(amount, (value(usdnBalance) / usdnWeight), (aBalance / assetWeight))
191203 }
192204
193205
316328 let IndexIn = value(indexOf(assetIds, assetIn))
317329 let IndexOut = value(indexOf(assetIds, assetOut))
318330 if ((IndexIn == IndexOut))
319- then throw("wrong tokens pair")
331+ then AmountIn
320332 else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(BalanceIn), toBigInt((Scale8 * Scale8)), toBigInt((BalanceIn + AmountIn)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 10000, AssetsWeights[IndexOut])), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
321333 }
322334
358370 let transfer = if ((rewardAmount == 0))
359371 then nil
360372 else [ScriptTransfer(address, rewardAmount, assetId)]
361- $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdnValue(assetId, rewardAmount, aBalance)))
373+ $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdnValue(assetId, rewardAmount, aBalance, unit)))
362374 }
363375
364376 let accum = {
389401
390402
391403 @Callable(i)
392-func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain) = if ((this != i.caller))
393- then throw("admin only")
394- else if ((size(poolDomain) > 13))
395- then throw("too large pool domain")
396- else {
397- let assetIdsStrLi = split(assetIdsStr, ",")
398- let assetIdsLi = {
399- let $l = assetIdsStrLi
400- let $s = size($l)
401- let $acc0 = nil
402- func $f4_1 ($a,$i) = if (($i >= $s))
403- then $a
404- else addAssetBytesToList($a, $l[$i])
404+func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
405+ let poolOwnerAddress = Address(fromBase58String(poolOwner))
406+ if ((this != i.caller))
407+ then throw("admin only")
408+ else if ((size(poolDomain) > 13))
409+ then throw("too large pool domain")
410+ else if (if ((fee > 500))
411+ then true
412+ else (50 > fee))
413+ then throw("fee value must be between 50 and 500 (0.5-5%)")
414+ else {
415+ let assetIdsStrLi = split(assetIdsStr, ",")
416+ let assetIdsLi = {
417+ let $l = assetIdsStrLi
418+ let $s = size($l)
419+ let $acc0 = nil
420+ func $f4_1 ($a,$i) = if (($i >= $s))
421+ then $a
422+ else addAssetBytesToList($a, $l[$i])
405423
406- func $f4_2 ($a,$i) = if (($i >= $s))
407- then $a
408- else throw("List size exceeds 10")
424+ func $f4_2 ($a,$i) = if (($i >= $s))
425+ then $a
426+ else throw("List size exceeds 10")
409427
410- $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
411- }
412- let assetWeightsStrLi = split(assetWeightsStr, ",")
413- let assetWeightsSum = {
414- let $l = assetWeightsStrLi
415- let $s = size($l)
416- let $acc0 = 0
417- func $f5_1 ($a,$i) = if (($i >= $s))
418- then $a
419- else sum($a, $l[$i])
428+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
429+ }
430+ let assetWeightsStrLi = split(assetWeightsStr, ",")
431+ let assetWeightsSum = {
432+ let $l = assetWeightsStrLi
433+ let $s = size($l)
434+ let $acc0 = 0
435+ func $f5_1 ($a,$i) = if (($i >= $s))
436+ then $a
437+ else sum($a, $l[$i])
420438
421- func $f5_2 ($a,$i) = if (($i >= $s))
422- then $a
423- else throw("List size exceeds 10")
439+ func $f5_2 ($a,$i) = if (($i >= $s))
440+ then $a
441+ else throw("List size exceeds 10")
424442
425- $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
426- }
427- func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
428- then accum
429- else {
430- let assetDecimals = match assetIdsLi[assetNum] {
431- case x: ByteVector =>
432- value(assetInfo(x)).decimals
433- case _ =>
434- 8
443+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
444+ }
445+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
446+ then accum
447+ else {
448+ let assetDecimals = match assetIdsLi[assetNum] {
449+ case x: ByteVector =>
450+ value(assetInfo(x)).decimals
451+ case _ =>
452+ 8
453+ }
454+ (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
455+ }
456+
457+ if ((assetWeightsSum != 10000))
458+ then throw("sum of token weights must be equal to 10000")
459+ else ({
460+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
461+ let $s = size($l)
462+ let $acc0 = nil
463+ func $f6_1 ($a,$i) = if (($i >= $s))
464+ then $a
465+ else addTokenDataEntries($a, $l[$i])
466+
467+ func $f6_2 ($a,$i) = if (($i >= $s))
468+ then $a
469+ else throw("List size exceeds 10")
470+
471+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
472+ } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee)])
435473 }
436- (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
437- }
438-
439- if ((assetWeightsSum != 100))
440- then throw("sum of token weights must be equal to 100")
441- else ({
442- let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
443- let $s = size($l)
444- let $acc0 = nil
445- func $f6_1 ($a,$i) = if (($i >= $s))
446- then $a
447- else addTokenDataEntries($a, $l[$i])
448-
449- func $f6_2 ($a,$i) = if (($i >= $s))
450- then $a
451- else throw("List size exceeds 10")
452-
453- $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
454- } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), IntegerEntry("static_fee", 200)])
455- }
474+ }
456475
457476
458477
529548 else {
530549 let poolTokenIssue = Issue(("PZ " + tryGetString("static_poolDomain")), "Puzzle Swap: pool index token", initialPoolTokens, PoolTokenDecimals, true, unit, 0)
531550 let poolTokenId = calculateAssetId(poolTokenIssue)
532- (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), ScriptTransfer(i.caller, initialPoolTokens, poolTokenId)])
551+ (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
533552 }
534553 }
535554 }
567586 let puzzleAvailable = tryGetInteger((addressStr + "_indexStaked"))
568587 if ((puzzleAmount > puzzleAvailable))
569588 then throw("you don't have index tokens available")
570- else (claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (puzzleAvailable - puzzleAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - puzzleAmount)), ScriptTransfer(i.caller, puzzleAmount, getBinaryValue("global_poolToken_id"))])
589+ else if (isShutdown())
590+ then throw("contract is on stop")
591+ else (claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (puzzleAvailable - puzzleAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - puzzleAmount)), ScriptTransfer(i.caller, puzzleAmount, getBinaryValue("global_poolToken_id"))])
571592 }
572593
573594
574595
575596 @Callable(i)
576-func claimIndexRewards () = claimResult(i.caller)
597+func claimIndexRewards () = if (isShutdown())
598+ then throw("contract is on stop")
599+ else claimResult(i.caller)
577600
578601
579602
582605 let pmt = i.payments[0]
583606 if ((pmt.assetId != tryGetBinary("global_poolToken_id")))
584607 then throw("please attach pool share token")
585- else {
586- let PRedeemed = pmt.amount
587- let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
588- then i.originCaller
589- else i.caller)
590- (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
591- }
608+ else if (isShutdown())
609+ then throw("contract is on stop")
610+ else {
611+ let PRedeemed = pmt.amount
612+ let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
613+ then i.originCaller
614+ else i.caller)
615+ (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
616+ }
592617 }
593618
594619
599624 let AmountIn = value(i.payments[0].amount)
600625 let AssetIn = pmt.assetId
601626 let AssetOut = getAssetBytes(assetOut)
627+ let feeAssetIn = AssetIn
628+ let feeAssetOut = usdnAssetId
602629 let AssetInBalance = tryGetInteger((("global_" + getAssetString(AssetIn)) + "_balance"))
603630 let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
604- let AmountOut = calculateOutAmount(AmountIn, AssetIn, AssetOut, AssetInBalance, AssetOutBalance)
605- let feeAmount = fraction(AmountOut, Fee, FeeScale)
606- let cleanAmountOut = (AmountOut - feeAmount)
607- if ((minimum > cleanAmountOut))
608- then throw(("amount to recieve is lower than given one: " + toString(cleanAmountOut)))
609- else if ((0 > (AssetOutBalance - AmountOut)))
610- then throw("contract is out of reserves")
611- else {
612- let newBalanceIn = (AssetInBalance + AmountIn)
613- let newBalanceOut = (AssetOutBalance - AmountOut)
614- let usdnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
615- if ((usdnAssetId == AssetOut))
616- then {
617- let usdnFeeAmount = feeAmount
618- let protocolUsdnFee = fraction(usdnFeeAmount, 4, 10)
619- let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(usdnAssetId, protocolUsdnFee)])
620- if ((stakingTopUp == stakingTopUp))
621- then $Tuple2([IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut), IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn), ScriptTransfer(i.caller, cleanAmountOut, AssetOut), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance)))], cleanAmountOut)
622- else throw("Strict value is not equal to itself.")
631+ let feeAssetOutBalance = tryGetInteger((("global_" + getAssetString(feeAssetOut)) + "_balance"))
632+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
633+ let cleanAmountIn = (AmountIn - feeAmountIn)
634+ let AmountOut = calculateOutAmount(cleanAmountIn, AssetIn, AssetOut, AssetInBalance, AssetOutBalance)
635+ let feeAmountOut = calculateOutAmount(feeAmountIn, AssetIn, feeAssetOut, AssetInBalance, feeAssetOutBalance)
636+ let creatorFee = fraction(feeAmountOut, 1, 10)
637+ let protocolFee = fraction(feeAmountOut, 4, 10)
638+ let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(feeAssetOut, protocolFee)])
639+ if ((stakingTopUp == stakingTopUp))
640+ then if ((minimum > AmountOut))
641+ then throw(("amount to recieve is lower than given one: " + toString(AmountOut)))
642+ else if ((0 > (AssetOutBalance - AmountOut)))
643+ then throw("contract is out of reserves")
644+ else if (isShutdown())
645+ then throw("contract is on stop")
646+ else {
647+ let newBalanceIn = (AssetInBalance + AmountIn)
648+ let newBalanceOut = (AssetOutBalance - AmountOut)
649+ let newBalanceFeeAsset = if (if ((feeAssetOut != AssetIn))
650+ then (feeAssetOut != AssetOut)
651+ else false)
652+ then (feeAssetOutBalance - feeAmountOut)
653+ else unit
654+ let assetInChange = IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)
655+ let assetOutChange = IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut)
656+ let feeAssetOutChange = if ((newBalanceFeeAsset != unit))
657+ then IntegerEntry((("global_" + getAssetString(feeAssetOut)) + "_balance"), feeAssetOutBalance)
658+ else StringEntry("hello", "world")
659+ $Tuple2([assetInChange, assetOutChange, feeAssetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), ScriptTransfer(addressFromStringValue(tryGetString("static_poolOwner")), creatorFee, feeAssetOut), IntegerEntry("global_earnedByOwner", (tryGetInteger("global_earnedByOwner") + creatorFee)), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance, feeAssetOutBalance)))], AmountOut)
623660 }
624- else {
625- let usdnBalance = if ((AssetIn == usdnAssetId))
626- then newBalanceIn
627- else tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
628- let usdnFeeAmount = calculateOutAmount(feeAmount, AssetOut, usdnAssetId, newBalanceOut, usdnBalance)
629- let protocolUsdnFee = fraction(usdnFeeAmount, 4, 10)
630- let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(usdnAssetId, protocolUsdnFee)])
631- if ((stakingTopUp == stakingTopUp))
632- then {
633- let usdnBalanceChangeEntry = IntegerEntry((("global_" + toBase58String(usdnAssetId)) + "_balance"), (usdnBalance - usdnFeeAmount))
634- let balanceChanges = if ((AssetIn == usdnAssetId))
635- then [usdnBalanceChangeEntry]
636- else [usdnBalanceChangeEntry, IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)]
637- $Tuple2(([IntegerEntry((("global_" + assetOut) + "_balance"), (newBalanceOut + feeAmount)), ScriptTransfer(i.caller, cleanAmountOut, AssetOut), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance)))] ++ balanceChanges), cleanAmountOut)
638- }
639- else throw("Strict value is not equal to itself.")
640- }
641- }
642- }
643-
644-
645-
646-@Callable(i)
647-func flashLoan (assetIdStr,amount,actionsStr) = {
648- let actions = split(actionsStr, "|")
649- nil
661+ else throw("Strict value is not equal to itself.")
650662 }
651663
652664
653665 @Verifier(tx)
654666 func verify () = if (isShutdown())
655667 then false
656- else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
668+ else if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
669+ then true
670+ else sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
657671
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let usdnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
5+
6+let puzzleAssetId = base58'HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS'
7+
8+let masterAddress = Address(base58'3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf')
9+
10+let masterPubKey = base58'4z8CKSYQBKkzx7PBb5uBP1YPa6YAHRNTApW1sQVHT5eU'
11+
412 func tryGetInteger (key) = match getInteger(this, key) {
513 case b: Int =>
614 b
715 case _ =>
816 0
917 }
1018
1119
1220 func tryGetBinary (key) = match getBinary(this, key) {
1321 case b: ByteVector =>
1422 b
1523 case _ =>
1624 base58''
1725 }
1826
1927
2028 func tryGetString (key) = match getString(this, key) {
2129 case b: String =>
2230 b
2331 case _ =>
2432 ""
2533 }
2634
2735
2836 func getAssetString (assetId) = match assetId {
2937 case b: ByteVector =>
3038 toBase58String(b)
3139 case _ =>
3240 "WAVES"
3341 }
3442
3543
3644 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
3745 then unit
3846 else fromBase58String(assetIdStr)
3947
4048
4149 func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
4250
4351
4452 func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
4553
4654
4755 func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
4856
4957
5058 func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
5159
5260
5361 func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
5462
5563
5664 let T = tryGetInteger("static_tokensAmount")
5765
5866 let assetIds = {
5967 let $l = split(tryGetString("static_tokenIds"), ",")
6068 let $s = size($l)
6169 let $acc0 = nil
6270 func $f0_1 ($a,$i) = if (($i >= $s))
6371 then $a
6472 else addAssetBytesToList($a, $l[$i])
6573
6674 func $f0_2 ($a,$i) = if (($i >= $s))
6775 then $a
6876 else throw("List size exceeds 10")
6977
7078 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
7179 }
7280
7381 let AssetsWeights = {
7482 let $l = assetIds
7583 let $s = size($l)
7684 let $acc0 = nil
7785 func $f1_1 ($a,$i) = if (($i >= $s))
7886 then $a
7987 else addAssetWeightToList($a, $l[$i])
8088
8189 func $f1_2 ($a,$i) = if (($i >= $s))
8290 then $a
8391 else throw("List size exceeds 10")
8492
8593 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
8694 }
8795
8896 let Decimals = {
8997 let $l = assetIds
9098 let $s = size($l)
9199 let $acc0 = nil
92100 func $f2_1 ($a,$i) = if (($i >= $s))
93101 then $a
94102 else addAssetDecimalsToList($a, $l[$i])
95103
96104 func $f2_2 ($a,$i) = if (($i >= $s))
97105 then $a
98106 else throw("List size exceeds 10")
99107
100108 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
101109 }
102110
103111 let Scales = {
104112 let $l = assetIds
105113 let $s = size($l)
106114 let $acc0 = nil
107115 func $f3_1 ($a,$i) = if (($i >= $s))
108116 then $a
109117 else addAssetScaleToList($a, $l[$i])
110118
111119 func $f3_2 ($a,$i) = if (($i >= $s))
112120 then $a
113121 else throw("List size exceeds 10")
114122
115123 $f3_2($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
116124 }
117125
118126 let Fee = tryGetInteger("static_fee")
119127
120-let AssetsWeightsDecimals = 2
128+let AssetsWeightsDecimals = 4
121129
122130 let Scale = 10000
123131
124132 let Scale8 = 100000000
125133
126134 let FeeScale = 10000
127135
128136 let PoolTokenDecimals = 8
129137
130138 let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
131139
132140 let earnedAssets = assetIds
133141
134142 func isShutdown () = match getBoolean(Address(base58'3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o'), "is_shutdown") {
135143 case x: Boolean =>
136144 x
137145 case _ =>
138146 false
139147 }
140148
141149
142150 func getCurrentTokenBalance (tokenType) = {
143151 let tokenId = getAssetString(assetIds[tokenType])
144152 tryGetInteger((("global_" + tokenId) + "_balance"))
145153 }
146154
147155
148156 func calculatePIssued (amount,tokenId) = {
149157 let Psupply = tryGetInteger("global_poolToken_amount")
150158 let Balance = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
151159 fraction(amount, Psupply, Balance, DOWN)
152160 }
153161
154162
155163 func getMinPIssued (payments) = {
156164 func handler (accum,current) = {
157165 let PIssued = calculatePIssued(current.amount, current.assetId)
158166 if ((PIssued == 0))
159167 then throw("one of the tokens amounts is too low")
160168 else if (if ((accum == 0))
161169 then true
162170 else (accum > PIssued))
163171 then PIssued
164172 else accum
165173 }
166174
167175 let minPIssed = {
168176 let $l = payments
169177 let $s = size($l)
170178 let $acc0 = 0
171179 func $f4_1 ($a,$i) = if (($i >= $s))
172180 then $a
173181 else handler($a, $l[$i])
174182
175183 func $f4_2 ($a,$i) = if (($i >= $s))
176184 then $a
177185 else throw("List size exceeds 10")
178186
179187 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
180188 }
181189 minPIssed
182190 }
183191
184192
185-func calculateUsdnValue (assetId,amount,aBalance) = {
186- let usdnId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
187- let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnId))]
193+func calculateUsdnValue (assetId,amount,aBalance,givenUsdnBalance) = {
194+ let usdnWeight = AssetsWeights[value(indexOf(assetIds, usdnAssetId))]
188195 let assetWeight = AssetsWeights[value(indexOf(assetIds, assetId))]
189- let usdnBalance = tryGetInteger((("global_" + getAssetString(usdnId)) + "_balance"))
190- fraction(amount, (usdnBalance / usdnWeight), (aBalance / assetWeight))
196+ let usdnBalance = match givenUsdnBalance {
197+ case x: Int =>
198+ givenUsdnBalance
199+ case _ =>
200+ tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
201+ }
202+ fraction(amount, (value(usdnBalance) / usdnWeight), (aBalance / assetWeight))
191203 }
192204
193205
194206 func checkTokensValidity (payments) = {
195207 func handler1 (accum,payment) = (accum ++ [payment.assetId])
196208
197209 let ids = {
198210 let $l = payments
199211 let $s = size($l)
200212 let $acc0 = nil
201213 func $f4_1 ($a,$i) = if (($i >= $s))
202214 then $a
203215 else handler1($a, $l[$i])
204216
205217 func $f4_2 ($a,$i) = if (($i >= $s))
206218 then $a
207219 else throw("List size exceeds 10")
208220
209221 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
210222 }
211223 if ((ids == ids))
212224 then {
213225 func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
214226 then (accum + 1)
215227 else throw(("asset not attached: " + getAssetString(assetId)))
216228
217229 let checks = {
218230 let $l = assetIds
219231 let $s = size($l)
220232 let $acc0 = 0
221233 func $f5_1 ($a,$i) = if (($i >= $s))
222234 then $a
223235 else handler2($a, $l[$i])
224236
225237 func $f5_2 ($a,$i) = if (($i >= $s))
226238 then $a
227239 else throw("List size exceeds 10")
228240
229241 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
230242 }
231243 if ((checks == checks))
232244 then true
233245 else throw("Strict value is not equal to itself.")
234246 }
235247 else throw("Strict value is not equal to itself.")
236248 }
237249
238250
239251 func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
240252 func getTokenPaymentAmount (tokenId) = {
241253 func handler (accum,payment) = if ((payment.assetId == tokenId))
242254 then payment.amount
243255 else accum
244256
245257 let $l = payments
246258 let $s = size($l)
247259 let $acc0 = 0
248260 func $f4_1 ($a,$i) = if (($i >= $s))
249261 then $a
250262 else handler($a, $l[$i])
251263
252264 func $f4_2 ($a,$i) = if (($i >= $s))
253265 then $a
254266 else throw("List size exceeds 10")
255267
256268 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
257269 }
258270
259271 func handleTokenChange (accum,tokenId) = {
260272 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
261273 let PSupply = tryGetInteger("global_poolToken_amount")
262274 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
263275 let Dk = fraction((fraction((PSupply + PIssued), tokenDecimals, PSupply, CEILING) - tokenDecimals), Bk, tokenDecimals, CEILING)
264276 let paymentAmount = getTokenPaymentAmount(tokenId)
265277 let toReturn = ((if ((paymentAmount != 0))
266278 then paymentAmount
267279 else 0) - Dk)
268280 let t = if (if (needChange)
269281 then (toReturn > 0)
270282 else false)
271283 then [ScriptTransfer(userAddress, toReturn, tokenId)]
272284 else nil
273285 ((accum ++ t) ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk + Dk))])
274286 }
275287
276288 let $l = assetIds
277289 let $s = size($l)
278290 let $acc0 = nil
279291 func $f4_1 ($a,$i) = if (($i >= $s))
280292 then $a
281293 else handleTokenChange($a, $l[$i])
282294
283295 func $f4_2 ($a,$i) = if (($i >= $s))
284296 then $a
285297 else throw("List size exceeds 10")
286298
287299 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
288300 }
289301
290302
291303 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
292304 func handleTokenRedeem (accum,tokenId) = {
293305 let Bk = tryGetInteger((("global_" + getAssetString(tokenId)) + "_balance"))
294306 let PSupply = tryGetInteger("global_poolToken_amount")
295307 let tokenDecimals = tryGetInteger((("static_" + getAssetString(tokenId)) + "_scale"))
296308 let amount = toInt(fraction((toBigInt(Scale8) - fraction(toBigInt((PSupply - PRedeemed)), toBigInt(Scale8), toBigInt(PSupply), CEILING)), toBigInt(Bk), toBigInt(Scale8), DOWN))
297309 (accum ++ [IntegerEntry((("global_" + getAssetString(tokenId)) + "_balance"), (Bk - amount)), ScriptTransfer(userAddress, amount, tokenId)])
298310 }
299311
300312 let $l = assetIds
301313 let $s = size($l)
302314 let $acc0 = nil
303315 func $f4_1 ($a,$i) = if (($i >= $s))
304316 then $a
305317 else handleTokenRedeem($a, $l[$i])
306318
307319 func $f4_2 ($a,$i) = if (($i >= $s))
308320 then $a
309321 else throw("List size exceeds 10")
310322
311323 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
312324 }
313325
314326
315327 func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
316328 let IndexIn = value(indexOf(assetIds, assetIn))
317329 let IndexOut = value(indexOf(assetIds, assetOut))
318330 if ((IndexIn == IndexOut))
319- then throw("wrong tokens pair")
331+ then AmountIn
320332 else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction(toBigInt(BalanceIn), toBigInt((Scale8 * Scale8)), toBigInt((BalanceIn + AmountIn)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 10000, AssetsWeights[IndexOut])), 4, 16, CEILING))), (Scale8 * Scale8), DOWN)
321333 }
322334
323335
324336 func getTokenBalance (assetId) = match assetId {
325337 case t: ByteVector =>
326338 assetBalance(this, t)
327339 case _ =>
328340 wavesBalance(this).available
329341 }
330342
331343
332344 func calculateCurrentAssetInterest (assetId,assetIdStr,aBalance,tokenEarningsLastCheck) = {
333345 let totalStaked = tryGetInteger("global_indexStaked")
334346 let tokenBalanceLastCheck = tokenEarningsLastCheck
335347 let currentBalanceDelta = (getTokenBalance(assetId) - aBalance)
336348 let currentTokenEarnings = if ((currentBalanceDelta > tokenBalanceLastCheck))
337349 then currentBalanceDelta
338350 else tokenBalanceLastCheck
339351 let newEarnings = (currentTokenEarnings - tokenBalanceLastCheck)
340352 let newInterest = if ((totalStaked == 0))
341353 then 0
342354 else fraction(newEarnings, Scale8, totalStaked)
343355 let lastCheckInterest = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_interest"))
344356 (lastCheckInterest + newInterest)
345357 }
346358
347359
348360 func claimResult (address) = {
349361 let addressStr = toString(address)
350362 let puzzleAmount = tryGetInteger((addressStr + "_indexStaked"))
351363 func handler (accum,assetId) = {
352364 let assetIdStr = getAssetString(assetId)
353365 let aBalance = tryGetInteger((("global_" + getAssetString(assetId)) + "_balance"))
354366 let tokenEarningsLastCheck = tryGetInteger((("global_lastCheck_" + assetIdStr) + "_earnings"))
355367 let currentTokenInterest = calculateCurrentAssetInterest(assetId, assetIdStr, aBalance, tokenEarningsLastCheck)
356368 let currentTokenEarnings = max([tokenEarningsLastCheck, (getTokenBalance(assetId) - aBalance)])
357369 let rewardAmount = fraction(puzzleAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale8)
358370 let transfer = if ((rewardAmount == 0))
359371 then nil
360372 else [ScriptTransfer(address, rewardAmount, assetId)]
361- $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdnValue(assetId, rewardAmount, aBalance)))
373+ $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((("global_lastCheck_" + assetIdStr) + "_earnings"), (currentTokenEarnings - rewardAmount)), IntegerEntry((("global_lastCheck_" + assetIdStr) + "_interest"), currentTokenInterest), IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdnValue(assetId, rewardAmount, aBalance, unit)))
362374 }
363375
364376 let accum = {
365377 let $l = earnedAssets
366378 let $s = size($l)
367379 let $acc0 = $Tuple2(nil, 0)
368380 func $f4_1 ($a,$i) = if (($i >= $s))
369381 then $a
370382 else handler($a, $l[$i])
371383
372384 func $f4_2 ($a,$i) = if (($i >= $s))
373385 then $a
374386 else throw("List size exceeds 10")
375387
376388 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
377389 }
378390 (accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardValue"), (tryGetInteger((addressStr + "_claimedRewardValue")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)])
379391 }
380392
381393
382394 func indexStakeResult (addressStr,amount) = {
383395 let li = claimResult(addressFromStringValue(addressStr))
384396 (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
385397 }
386398
387399
388400 func sum (accum,n) = (accum + parseIntValue(n))
389401
390402
391403 @Callable(i)
392-func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain) = if ((this != i.caller))
393- then throw("admin only")
394- else if ((size(poolDomain) > 13))
395- then throw("too large pool domain")
396- else {
397- let assetIdsStrLi = split(assetIdsStr, ",")
398- let assetIdsLi = {
399- let $l = assetIdsStrLi
400- let $s = size($l)
401- let $acc0 = nil
402- func $f4_1 ($a,$i) = if (($i >= $s))
403- then $a
404- else addAssetBytesToList($a, $l[$i])
404+func preInit (assetIdsStr,assetWeightsStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
405+ let poolOwnerAddress = Address(fromBase58String(poolOwner))
406+ if ((this != i.caller))
407+ then throw("admin only")
408+ else if ((size(poolDomain) > 13))
409+ then throw("too large pool domain")
410+ else if (if ((fee > 500))
411+ then true
412+ else (50 > fee))
413+ then throw("fee value must be between 50 and 500 (0.5-5%)")
414+ else {
415+ let assetIdsStrLi = split(assetIdsStr, ",")
416+ let assetIdsLi = {
417+ let $l = assetIdsStrLi
418+ let $s = size($l)
419+ let $acc0 = nil
420+ func $f4_1 ($a,$i) = if (($i >= $s))
421+ then $a
422+ else addAssetBytesToList($a, $l[$i])
405423
406- func $f4_2 ($a,$i) = if (($i >= $s))
407- then $a
408- else throw("List size exceeds 10")
424+ func $f4_2 ($a,$i) = if (($i >= $s))
425+ then $a
426+ else throw("List size exceeds 10")
409427
410- $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
411- }
412- let assetWeightsStrLi = split(assetWeightsStr, ",")
413- let assetWeightsSum = {
414- let $l = assetWeightsStrLi
415- let $s = size($l)
416- let $acc0 = 0
417- func $f5_1 ($a,$i) = if (($i >= $s))
418- then $a
419- else sum($a, $l[$i])
428+ $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
429+ }
430+ let assetWeightsStrLi = split(assetWeightsStr, ",")
431+ let assetWeightsSum = {
432+ let $l = assetWeightsStrLi
433+ let $s = size($l)
434+ let $acc0 = 0
435+ func $f5_1 ($a,$i) = if (($i >= $s))
436+ then $a
437+ else sum($a, $l[$i])
420438
421- func $f5_2 ($a,$i) = if (($i >= $s))
422- then $a
423- else throw("List size exceeds 10")
439+ func $f5_2 ($a,$i) = if (($i >= $s))
440+ then $a
441+ else throw("List size exceeds 10")
424442
425- $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
426- }
427- func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
428- then accum
429- else {
430- let assetDecimals = match assetIdsLi[assetNum] {
431- case x: ByteVector =>
432- value(assetInfo(x)).decimals
433- case _ =>
434- 8
443+ $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
444+ }
445+ func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
446+ then accum
447+ else {
448+ let assetDecimals = match assetIdsLi[assetNum] {
449+ case x: ByteVector =>
450+ value(assetInfo(x)).decimals
451+ case _ =>
452+ 8
453+ }
454+ (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
455+ }
456+
457+ if ((assetWeightsSum != 10000))
458+ then throw("sum of token weights must be equal to 10000")
459+ else ({
460+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
461+ let $s = size($l)
462+ let $acc0 = nil
463+ func $f6_1 ($a,$i) = if (($i >= $s))
464+ then $a
465+ else addTokenDataEntries($a, $l[$i])
466+
467+ func $f6_2 ($a,$i) = if (($i >= $s))
468+ then $a
469+ else throw("List size exceeds 10")
470+
471+ $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
472+ } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee)])
435473 }
436- (accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum])))])
437- }
438-
439- if ((assetWeightsSum != 100))
440- then throw("sum of token weights must be equal to 100")
441- else ({
442- let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
443- let $s = size($l)
444- let $acc0 = nil
445- func $f6_1 ($a,$i) = if (($i >= $s))
446- then $a
447- else addTokenDataEntries($a, $l[$i])
448-
449- func $f6_2 ($a,$i) = if (($i >= $s))
450- then $a
451- else throw("List size exceeds 10")
452-
453- $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
454- } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_baseTokenId", baseTokenIdStr), IntegerEntry("static_fee", 200)])
455- }
474+ }
456475
457476
458477
459478 @Callable(i)
460479 func deInit () = if ((i.caller != this))
461480 then throw("admin only")
462481 else [IntegerEntry("global_wasInited", 0)]
463482
464483
465484
466485 @Callable(i)
467486 func init () = {
468487 func prepareList () = {
469488 func handler (accum,n) = (accum ++ [IntegerEntry((("global_" + getAssetString(n.assetId)) + "_balance"), n.amount)])
470489
471490 let $l = i.payments
472491 let $s = size($l)
473492 let $acc0 = nil
474493 func $f4_1 ($a,$i) = if (($i >= $s))
475494 then $a
476495 else handler($a, $l[$i])
477496
478497 func $f4_2 ($a,$i) = if (($i >= $s))
479498 then $a
480499 else throw("List size exceeds 10")
481500
482501 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
483502 }
484503
485504 func calculatePoolTokensAmount (payments) = {
486505 func handler (accum,pmt) = {
487506 let assetId = pmt.assetId
488507 func handler2 (accum,n) = if ((n == assetId))
489508 then value(indexOf(assetIds, n))
490509 else accum
491510
492511 let Token = {
493512 let $l = assetIds
494513 let $s = size($l)
495514 let $acc0 = 1
496515 func $f4_1 ($a,$i) = if (($i >= $s))
497516 then $a
498517 else handler2($a, $l[$i])
499518
500519 func $f4_2 ($a,$i) = if (($i >= $s))
501520 then $a
502521 else throw("List size exceeds 10")
503522
504523 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
505524 }
506525 fraction(accum, pow(pmt.amount, Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
507526 }
508527
509528 let $l = payments
510529 let $s = size($l)
511530 let $acc0 = PoolTokenScale
512531 func $f4_1 ($a,$i) = if (($i >= $s))
513532 then $a
514533 else handler($a, $l[$i])
515534
516535 func $f4_2 ($a,$i) = if (($i >= $s))
517536 then $a
518537 else throw("List size exceeds 10")
519538
520539 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
521540 }
522541
523542 if ((tryGetInteger("global_wasInited") > 0))
524543 then throw("pool already inited")
525544 else {
526545 let initialPoolTokens = calculatePoolTokensAmount(i.payments)
527546 if ((initialPoolTokens == 0))
528547 then throw("you need a bigger tokens amount to launch the pool")
529548 else {
530549 let poolTokenIssue = Issue(("PZ " + tryGetString("static_poolDomain")), "Puzzle Swap: pool index token", initialPoolTokens, PoolTokenDecimals, true, unit, 0)
531550 let poolTokenId = calculateAssetId(poolTokenIssue)
532- (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), ScriptTransfer(i.caller, initialPoolTokens, poolTokenId)])
551+ (prepareList() ++ [poolTokenIssue, IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), BinaryEntry("global_poolToken_id", poolTokenId), StringEntry("static_poolToken_idStr", getAssetString(poolTokenId)), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
533552 }
534553 }
535554 }
536555
537556
538557
539558 @Callable(i)
540559 func generateIndex (needChange) = if ((size(i.payments) != T))
541560 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
542561 else if (!(checkTokensValidity(i.payments)))
543562 then throw("wrong assets attached")
544563 else {
545564 let PIssued = getMinPIssued(i.payments)
546565 let reissue = Reissue(getBinaryValue("global_poolToken_id"), PIssued, true)
547566 let result = handlePoolTokensAdd(PIssued, i.payments, i.originCaller, needChange)
548567 $Tuple2((result ++ [ScriptTransfer(i.caller, PIssued, tryGetBinary("global_poolToken_id")), reissue, IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssued))]), PIssued)
549568 }
550569
551570
552571
553572 @Callable(i)
554573 func stakeIndex () = {
555574 let addressStr = toString(i.originCaller)
556575 let pmt = i.payments[0]
557576 if ((value(pmt.assetId) != tryGetBinary("global_poolToken_id")))
558577 then throw("wrong asset attached")
559578 else indexStakeResult(addressStr, pmt.amount)
560579 }
561580
562581
563582
564583 @Callable(i)
565584 func unstakeIndex (puzzleAmount) = {
566585 let addressStr = toString(i.originCaller)
567586 let puzzleAvailable = tryGetInteger((addressStr + "_indexStaked"))
568587 if ((puzzleAmount > puzzleAvailable))
569588 then throw("you don't have index tokens available")
570- else (claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (puzzleAvailable - puzzleAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - puzzleAmount)), ScriptTransfer(i.caller, puzzleAmount, getBinaryValue("global_poolToken_id"))])
589+ else if (isShutdown())
590+ then throw("contract is on stop")
591+ else (claimResult(i.originCaller) ++ [IntegerEntry((addressStr + "_indexStaked"), (puzzleAvailable - puzzleAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - puzzleAmount)), ScriptTransfer(i.caller, puzzleAmount, getBinaryValue("global_poolToken_id"))])
571592 }
572593
573594
574595
575596 @Callable(i)
576-func claimIndexRewards () = claimResult(i.caller)
597+func claimIndexRewards () = if (isShutdown())
598+ then throw("contract is on stop")
599+ else claimResult(i.caller)
577600
578601
579602
580603 @Callable(i)
581604 func redeemIndex (sendToOrigin) = {
582605 let pmt = i.payments[0]
583606 if ((pmt.assetId != tryGetBinary("global_poolToken_id")))
584607 then throw("please attach pool share token")
585- else {
586- let PRedeemed = pmt.amount
587- let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
588- then i.originCaller
589- else i.caller)
590- (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
591- }
608+ else if (isShutdown())
609+ then throw("contract is on stop")
610+ else {
611+ let PRedeemed = pmt.amount
612+ let result = handlePoolTokensRedeem(PRedeemed, if (sendToOrigin)
613+ then i.originCaller
614+ else i.caller)
615+ (result ++ [Burn(tryGetBinary("global_poolToken_id"), PRedeemed), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemed))])
616+ }
592617 }
593618
594619
595620
596621 @Callable(i)
597622 func swap (assetOut,minimum) = {
598623 let pmt = value(i.payments[0])
599624 let AmountIn = value(i.payments[0].amount)
600625 let AssetIn = pmt.assetId
601626 let AssetOut = getAssetBytes(assetOut)
627+ let feeAssetIn = AssetIn
628+ let feeAssetOut = usdnAssetId
602629 let AssetInBalance = tryGetInteger((("global_" + getAssetString(AssetIn)) + "_balance"))
603630 let AssetOutBalance = tryGetInteger((("global_" + assetOut) + "_balance"))
604- let AmountOut = calculateOutAmount(AmountIn, AssetIn, AssetOut, AssetInBalance, AssetOutBalance)
605- let feeAmount = fraction(AmountOut, Fee, FeeScale)
606- let cleanAmountOut = (AmountOut - feeAmount)
607- if ((minimum > cleanAmountOut))
608- then throw(("amount to recieve is lower than given one: " + toString(cleanAmountOut)))
609- else if ((0 > (AssetOutBalance - AmountOut)))
610- then throw("contract is out of reserves")
611- else {
612- let newBalanceIn = (AssetInBalance + AmountIn)
613- let newBalanceOut = (AssetOutBalance - AmountOut)
614- let usdnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
615- if ((usdnAssetId == AssetOut))
616- then {
617- let usdnFeeAmount = feeAmount
618- let protocolUsdnFee = fraction(usdnFeeAmount, 4, 10)
619- let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(usdnAssetId, protocolUsdnFee)])
620- if ((stakingTopUp == stakingTopUp))
621- then $Tuple2([IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut), IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn), ScriptTransfer(i.caller, cleanAmountOut, AssetOut), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance)))], cleanAmountOut)
622- else throw("Strict value is not equal to itself.")
631+ let feeAssetOutBalance = tryGetInteger((("global_" + getAssetString(feeAssetOut)) + "_balance"))
632+ let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
633+ let cleanAmountIn = (AmountIn - feeAmountIn)
634+ let AmountOut = calculateOutAmount(cleanAmountIn, AssetIn, AssetOut, AssetInBalance, AssetOutBalance)
635+ let feeAmountOut = calculateOutAmount(feeAmountIn, AssetIn, feeAssetOut, AssetInBalance, feeAssetOutBalance)
636+ let creatorFee = fraction(feeAmountOut, 1, 10)
637+ let protocolFee = fraction(feeAmountOut, 4, 10)
638+ let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(feeAssetOut, protocolFee)])
639+ if ((stakingTopUp == stakingTopUp))
640+ then if ((minimum > AmountOut))
641+ then throw(("amount to recieve is lower than given one: " + toString(AmountOut)))
642+ else if ((0 > (AssetOutBalance - AmountOut)))
643+ then throw("contract is out of reserves")
644+ else if (isShutdown())
645+ then throw("contract is on stop")
646+ else {
647+ let newBalanceIn = (AssetInBalance + AmountIn)
648+ let newBalanceOut = (AssetOutBalance - AmountOut)
649+ let newBalanceFeeAsset = if (if ((feeAssetOut != AssetIn))
650+ then (feeAssetOut != AssetOut)
651+ else false)
652+ then (feeAssetOutBalance - feeAmountOut)
653+ else unit
654+ let assetInChange = IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)
655+ let assetOutChange = IntegerEntry((("global_" + assetOut) + "_balance"), newBalanceOut)
656+ let feeAssetOutChange = if ((newBalanceFeeAsset != unit))
657+ then IntegerEntry((("global_" + getAssetString(feeAssetOut)) + "_balance"), feeAssetOutBalance)
658+ else StringEntry("hello", "world")
659+ $Tuple2([assetInChange, assetOutChange, feeAssetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), ScriptTransfer(addressFromStringValue(tryGetString("static_poolOwner")), creatorFee, feeAssetOut), IntegerEntry("global_earnedByOwner", (tryGetInteger("global_earnedByOwner") + creatorFee)), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance, feeAssetOutBalance)))], AmountOut)
623660 }
624- else {
625- let usdnBalance = if ((AssetIn == usdnAssetId))
626- then newBalanceIn
627- else tryGetInteger((("global_" + getAssetString(usdnAssetId)) + "_balance"))
628- let usdnFeeAmount = calculateOutAmount(feeAmount, AssetOut, usdnAssetId, newBalanceOut, usdnBalance)
629- let protocolUsdnFee = fraction(usdnFeeAmount, 4, 10)
630- let stakingTopUp = reentrantInvoke(Address(base58'3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS'), "topUpReward", nil, [AttachedPayment(usdnAssetId, protocolUsdnFee)])
631- if ((stakingTopUp == stakingTopUp))
632- then {
633- let usdnBalanceChangeEntry = IntegerEntry((("global_" + toBase58String(usdnAssetId)) + "_balance"), (usdnBalance - usdnFeeAmount))
634- let balanceChanges = if ((AssetIn == usdnAssetId))
635- then [usdnBalanceChangeEntry]
636- else [usdnBalanceChangeEntry, IntegerEntry((("global_" + getAssetString(AssetIn)) + "_balance"), newBalanceIn)]
637- $Tuple2(([IntegerEntry((("global_" + assetOut) + "_balance"), (newBalanceOut + feeAmount)), ScriptTransfer(i.caller, cleanAmountOut, AssetOut), IntegerEntry("global_volume", (tryGetInteger("global_volume") + calculateUsdnValue(AssetIn, AmountIn, AssetInBalance)))] ++ balanceChanges), cleanAmountOut)
638- }
639- else throw("Strict value is not equal to itself.")
640- }
641- }
642- }
643-
644-
645-
646-@Callable(i)
647-func flashLoan (assetIdStr,amount,actionsStr) = {
648- let actions = split(actionsStr, "|")
649- nil
661+ else throw("Strict value is not equal to itself.")
650662 }
651663
652664
653665 @Verifier(tx)
654666 func verify () = if (isShutdown())
655667 then false
656- else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
668+ else if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
669+ then true
670+ else sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
657671

github/deemru/w8io/3ef1775 
91.45 ms