tx · 2Y8UoeoSppMRwT3DVT2aFy2n8MS9Px27UVXifkR4gsYG

3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg:  -0.01400000 Waves

2021.12.22 10:55 [1845199] smart account 3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg > SELF 0.00000000 Waves

{ "type": 13, "id": "2Y8UoeoSppMRwT3DVT2aFy2n8MS9Px27UVXifkR4gsYG", "fee": 1400000, "feeAssetId": null, "timestamp": 1640159792453, "version": 2, "chainId": 84, "sender": "3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg", "senderPublicKey": "CViCXhHrygDDAtVc1uFczxe6ANj9tBz5PGQDS1yWZqgy", "proofs": [ "4YsgmQsHxevEP9yX1A11MUzEwBfnHMDEgj4qxfJoN9FYxKZLZivFNdnPDrLufipG7nfH17JUxwJ81t1JFKcwRE1o", "34UQqZyPRJgxyKLhw3WvUscVeDV6bSeQ81FMAfeATmP9zLHBodxkrJmUi8ePuaTjkxayZon7RAh4U6fk9HsuGsUA" ], "script": "base64:AAIFAAAAAAAAFIIIAhIECgIBCBIDCgEIEhQKEggBAQgBAQEBAQEBARgEAQEEGBIECgIBCBIECgIBCBIECgIBCBIFCgMBAQgSAwoBARIDCgEBEgQKAgEBEgASABoQCgFBEgtrZXlEdXJhdGlvbhohCgFCEhxrZXlBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGioKAUMSJWtleUFtb3VudEJ1eUFzc2V0SW5NYXJrZXRpbmdGaW5hbGl6ZWQaGAoBRBITa2V5VHJhbnNmZXJCdXlBc3NldBoZCgFFEhRrZXlGcmVlelN3b3BEdXJhdGlvbhodCgFGEhhrZXlGcmVlemVBZGRpdGlvbmFsVG9rZW4aFQoBRxIQa2V5RnJlZXplVG9rZW5JZBobCgFIEhZrZXlGcmVlemVUb2tlbkR1cmF0aW9uGhwKAUkSF2tleUZyZWV6ZVRva2VuUGVyVGlja2V0GhAKAUoSC2tleUJ1eVRva2VuGhMKAUsSDmtleUNsYWltUGFyYW1zGiAKAUwSG2tleUhpZ2hDb21wZXRpdGlvbkNvbWlzc2lvbhobCgFNEhZrZXlIaWdoQ29tcGV0aXRpb25TYWxlGhoKAU4SFWtleUhDVGlja2V0TGFzdE51bWJlchodCgFPEhhrZXlIaWdoQ29tcGV0aXRpb25BbW91bnQaIQoBUBIca2V5VG90YWxBbW91bnRCdXlBc3NldFNvbGRIQxoZCgFREhRrZXlVc2VyQ2xhaW1lZFRva2VucxocCgFSEhdrZXlVc2VyQ2xhaW1lZEJ1eVRva2VucxofCgFTEhprZXlVc2VyQm91Z2h0VGlja2V0c0Ftb3VudBoTCgFUEg5rZXlVc2VyVGlja2V0cxoVCgFVEhBrZXlVc2VySENUaWNrZXRzGiEKAVYSHGtleVVzZXJIQ0JvdWdodFRpY2tldHNBbW91bnQaIAoBVxIba2V5VXNlckF2YWlsYWJsZUFsbG9jYXRpb25zGiUKAVgSIGtleVVzZXJBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGh0KAVkSGGtleVVzZXJCb3VnaHRBbGxvY2F0aW9ucxoXCgFaEhJrZXlVc2VyQ2xhaW1TdGF0dXMaDgoBYRIJa2V5QWN0aXZlGgwKAmFBEgZhY3RpdmUaDgoCYUISCGlzQWN0aXZlGhEKAmFDEgtpc0FkbWluQ2FsbBoHCgJhRBIBaRocCgJhRRIWZ2V0QXNzZXRJbmZvRnJvbVN0cmluZxoOCgJhRhIIYXNzZXRTdHIaEQoCYUcSC2xhdW5jaHBhZElkGgoKAmFIEgRoYXNoGg0KAmFJEgdhZGRyZXNzGhQKAmFKEg5wcm9qZWN0QWRkcmVzcxoRCgJhSxILc3RhcnRIZWlnaHQaDgoCYUwSCGR1cmF0aW9uGg4KAmFNEghidXlUb2tlbhoQCgJhThIKY29tbWlzc2lvbhoVCgJhTxIPdG9rZW5zUGVyVGlja2V0GhMKAmFQEg1wcmljZVBlclRva2VuGhkKAmFREhNzd29wZmlUaWNrZXRzQW1vdW50GhoKAmFSEhRjYW1wYWlnblRva2Vuc0Ftb3VudBoZCgJhUxITdG9rZW5zUGVyQWxsb2NhdGlvbhoTCgJhVBINc3dvcFBlclRpY2tldBoYCgJhVRISc3dvcEZyZWV6ZUR1cmF0aW9uGhEKAmFWEgtjbGFpbVBhcmFtcxoZCgJhVxITSGlnaENvbXBldGl0aW9uU2FsZRoeCgJhWBIYaGlnaENvbXBldGl0aW9uQ29taXNzaW9uGiIKAmFZEhxoaWdoQ29tcGV0aXRpb25UaWNrZXRzQW1vdW50GhsKAmFaEhVmcmVlemVBZGRpdGlvbmFsVG9rZW4aIAoCYWESGmtleVVzZXJXaW5uZWRUaWNrZXRzQW1vdW50Gi8KAmFiEilrZXlVc2VyV2lubmVkSGlnaENvbXBldGl0aW9uVGlja2V0c0Ftb3VudBoYCgJhYxISa2V5VXNlckZyZWV6ZVRva2VuGgwKAmFkEgZvcmFjbGUaEAoCYWUSCmdvdmVybmFuY2UaFgoCYWYSEGNvbW1pc3Npb25XYWxsZXQaGAoCYWcSEnN0YWtpbmdVU0ROQWRkcmVzcxoKCgJhaBIEVVNEThoYCgJhaRISYWRtaW5QdWJLZXlTdGFraW5nGhoKAmFqEhRtYXhBbGxvY2F0aW9uc0Ftb3VudBoXCgJhaxIRYWN0aXZlTGF1bmNocGFkSWQaEQoCYWwSC2dldEFkbWluUHViGhEKAmFtEgtrZXlBZG1pblB1YhoNCgJhbhIHJG1hdGNoMBoMCgJhbxIGc3RyaW5nGg0KAmFwEgdub3RoaW5nGhIKAmFxEgxhZG1pblB1YktleTEaEgoCYXISDGFkbWluUHViS2V5MhoSCgJhcxIMYWRtaW5QdWJLZXkzGhIKAmF0EgxnZXRBc3NldEluZm8aDQoCYXUSB2Fzc2V0SWQaCAoCYXYSAmlkGg4KAmF3EghzdHJpbmdJZBoKCgJheBIEaW5mbxoLCgJheRIFd2F2ZXMaGAoCYXoSEmdldExhdW5jaHBhZE5leHRJZBoUCgFiEg9rZXlBZG1pblB1YktleTEaFAoCYkESDnRva2VuQXNzZXROYW1lGhMKAmJCEg10b2tlbkRlY2ltYWxzGhEKAmJDEgt0aWNrZXRQcmljZRoZCgJiRBITY29tbWlzc2lvblBlclRpY2tldBoVCgJiRRIPYnV5VGlja2V0QW1vdW50GhwKAmJGEhZhbGxvd2VkQnV5VGlja2V0QW1vdW50GiIKAmJHEhxhbGxvd2VkQnV5UHJpY2VXaXRoQ29taXNzaW9uGgwKAmJIEgZjaGFuZ2UaGgoCYkkSFGZyZWV6ZVRva2VuUGVyVGlja2V0GhMKAmJKEg0kdDAxMjUxMDEyNTk3GhUKAmJLEg9wbXRBbW91bnRGcmVlemUaFgoCYkwSEHBtdEFzc2V0SWRGcmVlemUaEwoCYk0SDSR0MDEyNjE0MTI3MDUaGQoCYk4SE3BtdEZyZWV6ZVN0ckFzc2V0SWQaGAoCYk8SEnBtdEZyZWV6ZUFzc2V0TmFtZRoXCgJiUBIRcG10RnJlZXplRGVjaW1hbHMaFgoCYlESEG5lZWRGcmVlemVUb2tlbnMaHgoCYlISGHVzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxocCgJiUxIWbGFzdEJvdWdodFRpY2tldE51bWJlchoRCgJiVBILYm91Z2h0UmFuZ2UaIQoCYlUSG25ld1VzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxoJCgJiVhIDaW52Gg8KAmJXEgliYXNlRW50cnkaEwoCYlgSDSR0MDE0Nzc2MTQ4NTEaEwoCYlkSDSR0MDE0ODU2MTUwMDYaGQoCYloSE3VzZXJVc2RuSW5NYXJrZXRpbmcaEgoCYmESDGZyZWV6ZVBhcmFtcxoUCgJiYhIObGF1bmNocGFkSWRTdHIaEQoCYmMSCyR0MDYzOTc2NDcyGg8KAmJkEglwbXRBbW91bnQaEAoCYmUSCnBtdEFzc2V0SWQaEQoCYmYSCyR0MDY0ODE2NTU0GhMKAmJnEg1wbXRTdHJBc3NldElkGhIKAmJoEgxwbXRBc3NldE5hbWUaEQoCYmkSC3BtdERlY2ltYWxzGhsKAmJqEhVmcmVlemVBZGRpdGlvbmFsRW50cnkaCwoCYmsSBXJlZklkGhEKAmJsEgskdDA5MTYwOTIzNRoRCgJibRILJHQwOTI0MDkzOTAaEAoCYm4SCmJ1eUFzc2V0SWQaEwoCYm8SDWJ1eUFzc2V0U3RySWQaEgoCYnASDGJ1eUFzc2V0TmFtZRoWCgJicRIQYnV5QXNzZXREZWNpbWFscxoRCgJichILc3Rha2VkU3dvcHMaHQoCYnMSF2FsbG93ZWRUaWNrZXRzQW1vdW50QWxsGhkKAmJ0EhNib3VnaHRUaWNrZXRzQW1vdW50GhoKAmJ1EhRhbGxvd2VkVGlja2V0c0Ftb3VudBoTCgJidhINZnJlZXplVG9rZW5JZBoQCgJidxIKdG9rZW5QcmljZRoTCgJieBINJHQwMTEyMDIxMTM0NhoNCgJieRIHdG9rZW5JZBoVCgJiehIPdG9rZW5TdHJBc3NldElkGhQKAWMSD2tleUFkbWluUHViS2V5MhoVCgJjQRIPYm91Z2h0SENUaWNrZXRzGhUKAmNCEg91c2VyQ2xhaW1TdGF0dXMaFAoCY0MSDmZpbmFsaXplSGVpZ2h0GhMKAmNEEg0kdDAyNTQwNzI1NTU3GhMKAmNFEg13b25uZWRUaWNrZXRzGhUKAmNGEg93b25uZWRIQ1RpY2tldHMaGgoCY0cSFGF3YWlsYWJsZUFsbG9jYXRpb25zGhgKAmNIEhJhbGxvd2VkQWxsb2NhdGlvbnMaEwoCY0kSDSR0MDI2NDYzMjY2MDcaGgoCY0oSFHRyYW5zZmVyVG9rZW5zQW1vdW50GiEKAmNLEhtub3RBbGxvd2VkQWxsb2NhdGlvbnNUb2tlbnMaHAoCY0wSFmJ1eUFzc2V0Rm9yQWxsb2NhdGlvbnMaIAoCY00SGmJ1eUFzc2V0Rm9yVW53b25uZWRUaWNrZXRzGiIKAmNOEhxidXlBc3NldEZvckhDVW53b25uZWRUaWNrZXRzGhUKAmNPEg9jbGFpbWVkQnV5VG9rZW4aHAoCY1ASFnJldHVybmVkQnV5QXNzZXRBbW91bnQaFgoCY1ESEHRyYW5zZmVyQnV5QXNzZXQaEwoCY1ISDWNsYWltZWRQYXJhbXMaFAoCY1MSDnRyYW5zZmVyVG9rZW5zGhMKAmNUEg1jbGFpbWVkVG9rZW5zGhIKAmNVEgx1bmxvY2tQZXJpb2QaEQoCY1YSC2Jsb2NrSGVpZ2h0GhIKAmNXEgx1bmxvY2tIZWlnaHQaGQoCY1gSE2FsbG93ZWRUb2tlbnNBbW91bnQaFgoCY1kSEGNsYWltU3RhdHVzRW50cnkaFwoCY1oSEXVzZXJUb2tlbnNGcmVlemVkGhUKAmNhEg91c2RuSW5NYXJrZXRpbmcaFwoCY2ISEWJvdWdodEFsbG9jYXRpb25zGhMKAmNjEg0kdDAxNTY3NTE1ODE5GiIKAmNkEhxhbGxvY2F0aW9uUHJpY2VXaXRoQ29taXNzaW9uGhoKAmNlEhRidXlBbGxvY2F0aW9uc0Ftb3VudBoTCgJjZhINJHQwMTgwNzcxODE1MhoTCgJjZxINJHQwMTgxNTcxODMwNxobCgJjaBIVYm91Z2h0SENUaWNrZXRzQW1vdW50GhkKAmNpEhNoaWdoQ29tcGV0aXRpb25TYWxlGhMKAmNqEg0kdDAxOTQ4MDE5NjI0GhsKAmNrEhVidXlQcmljZVdpdGhDb21pc3Npb24aDwoCY2wSCXZyZkhlaWdodBoQCgJjbRIKc2VjcmV0V29yZBoPCgJjbhIJc2F2ZWRIYXNoGg4KAmNvEghjYWxjSGFzaBoTCgJjcBINJHQwMjIyMzcyMjM4NxoSCgJjcRIMY29tbWlzc2lvbkhDGhgKAmNyEhJ0cmFuc2ZlcmVkQnV5QXNzZXQaIQoCY3MSG3N3b3BmaU1lbWJlcnNCdXlBc3NldEFtb3VudBocCgJjdBIWc3dvcGZpSENCdXlBc3NldEFtb3VudBocCgJjdRIWc3dvcGZpTWVtYmVyc0NvbWlzc2lvbhoXCgJjdhIRc3dvcGZpSENDb21pc3Npb24aJAoCY3cSHnRvdGFsQW1vdW50QnV5QXNzZXRJbk1hcmtldGluZxoYCgJjeBISbWFya2V0aW5nQ29taXNzaW9uGhMKAmN5Eg11bnN0YWtlQW1vdW50GhMKAmN6Eg1ib3VnaHRUaWNrZXRzGhQKAWQSD2tleUFkbWluUHViS2V5MxoZCgJkYRITZnJlZXplVG9rZW5EdXJhdGlvbhoUCgJkYhIOYmxvY2tFbmRIZWlnaHQaDAoCZGMSBmFtb3VudBoTCgJkZBINJHQwMzI3MzQzMjg4NBoICgJkZRICdHgaDAoCZGYSBnZlcmlmeRoZCgJkZxITbXVsdGlTaWduZWRCeUFkbWlucxoYCgJkaBISYWRtaW5QdWJLZXkxU2lnbmVkGhgKAmRpEhJhZG1pblB1YktleTJTaWduZWQaGAoCZGoSEmFkbWluUHViS2V5M1NpZ25lZBoTCgJkaxINc2lnbmVkQnlBZG1pbhoJCgJkbBIDZHR4GiYKAWUSIWtleUxhdW5jaHBhZERhdGFUcmFuc2FjdGlvblN0YXR1cxoXCgFmEhJrZXlMYXVuY2hwYWROZXh0SWQaGQoBZxIUa2V5TGF1bmNocGFkQWN0aXZlSWQaEgoBaBINa2V5SW5pdENhbGxlchoPCgFpEgprZXlBZGRyZXNzGhIKAWoSDWtleUluaXRIZWlnaHQaEwoBaxIOa2V5U3RhcnRIZWlnaHQaFgoBbBIRa2V5RmluYWxpc2VIZWlnaHQaEQoBbRIMa2V5Q29taXNzaW9uGg8KAW4SCmtleUFzc2V0SWQaGAoBbxITa2V5VG90YWxUb2tlbkFtb3VudBofCgFwEhprZXlUb3RhbEFtb3VudEJ1eUFzc2V0U29sZBoXCgFxEhJrZXlUb2tlbnNQZXJUaWNrZXQaFQoBchIQa2V5UHJpY2VQZXJUb2tlbhoVCgFzEhBrZXlTd29wUGVyVGlja2V0GhsKAXQSFmtleVN3b3BmaVRpY2tldHNBbW91bnQaHAoBdRIXa2V5Q2FtcGFpZ25Ub2tlbnNBbW91bnQaGwoBdhIWa2V5VG9rZW5zUGVyQWxsb2NhdGlvbhoYCgF3EhNrZXlUaWNrZXRMYXN0TnVtYmVyGhgKAXgSE2tleUdvdmVybmFuY2VTdGFrZWQaEQoBeRIMa2V5VXNlclJlZklkGhIKAXoSDWtleVZlcmlmeUhhc2gAAABJAAAAAAFhAgAAAAZhY3RpdmUAAAAAAWICAAAAC2FkbWluX3B1Yl8xAAAAAAFjAgAAAAthZG1pbl9wdWJfMgAAAAABZAIAAAALYWRtaW5fcHViXzMAAAAAAWUCAAAAIWxhdW5jaHBhZF9kYXRhX3RyYW5zYWN0aW9uX3N0YXR1cwAAAAABZgIAAAARbGF1bmNocGFkX25leHRfaWQAAAAAAWcCAAAAE2xhdW5jaHBhZF9hY3RpdmVfaWQAAAAAAWgCAAAAC2luaXRfY2FsbGVyAAAAAAFpAgAAAAhfYWRkcmVzcwAAAAABagIAAAAMX2luaXRfaGVpZ2h0AAAAAAFrAgAAAA1fc3RhcnRfaGVpZ2h0AAAAAAFsAgAAABBfZmluYWxpc2VfaGVpZ2h0AAAAAAFtAgAAAApfY29taXNzaW9uAAAAAAFuAgAAAAlfYXNzZXRfaWQAAAAAAW8CAAAAE190b3RhbF90b2tlbl9hbW91bnQAAAAAAXACAAAAFV90b3RhbF9idXlfYXNzZXRfc29sZAAAAAABcQIAAAASX3Rva2Vuc19wZXJfdGlja2V0AAAAAAFyAgAAABBfcHJpY2VfcGVyX3Rva2VuAAAAAAFzAgAAABBfc3dvcF9wZXJfdGlja2V0AAAAAAF0AgAAABdfdGlja2V0c19zd29wZmlfbWVtYmVycwAAAAABdQIAAAATX3Rva2Vuc19hY2Nlc3NfbGlzdAAAAAABdgIAAAAWX3Rva2Vuc19wZXJfYWxsb2NhdGlvbgAAAAABdwIAAAATX3RpY2tldF9sYXN0X251bWJlcgAAAAABeAIAAAAMX1NXT1BfYW1vdW50AAAAAAF5AgAAAAdfcmVmX2lkAAAAAAF6AgAAAAxfdmVyaWZ5X2hhc2gAAAAAAUECAAAACV9kdXJhdGlvbgAAAAABQgIAAAAnX3RvdGFsX3B1cmNoYXNlZF9idXlfYXNzZXRfaW5fbWFya2V0aW5nAAAAAAFDAgAAADFfdG90YWxfcHVyY2hhc2VkX2J1eV9hc3NldF9pbl9tYXJrZXRpbmdfZmluYWxpemVkAAAAAAFEAgAAABNfdHJhbnNmZXJfYnV5X2Fzc2V0AAAAAAFFAgAAABVfZnJlZXplX3N3b3BfZHVyYXRpb24AAAAAAUYCAAAAGF9mcmVlemVfYWRkaXRpb25hbF90b2tlbgAAAAABRwIAAAAQX2ZyZWV6ZV90b2tlbl9pZAAAAAABSAIAAAAWX2ZyZWV6ZV90b2tlbl9kdXJhdGlvbgAAAAABSQIAAAAYX2ZyZWV6ZV90b2tlbl9wZXJfdGlja2V0AAAAAAFKAgAAAApfYnV5X3Rva2VuAAAAAAFLAgAAAA1fY2xhaW1fcGFyYW1zAAAAAAFMAgAAABtfaGlnaF9jb21wZXRpdGlvbl9jb21pc3Npb24AAAAAAU0CAAAAFl9oaWdoX2NvbXBldGl0aW9uX3NhbGUAAAAAAU4CAAAAJF9oaWdoX2NvbXBldGl0aW9uX3RpY2tldF9sYXN0X251bWJlcgAAAAABTwIAAAAZX3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABUAIAAAAmX3RvdGFsX2J1eV9hc3NldF9zb2xkX2hpZ2hfY29tcGV0aXRpb24AAAAAAVECAAAAD19jbGFpbWVkX3Rva2VucwAAAAABUgIAAAATX2NsYWltZWRfYnV5X3Rva2VucwAAAAABUwIAAAAPX2JvdWdodF90aWNrZXRzAAAAAAFUAgAAAA9fdGlja2V0c19udW1iZXIAAAAAAVUCAAAAIF90aWNrZXRzX251bWJlcl9oaWdoX2NvbXBldGl0aW9uAAAAAAFWAgAAACBfYm91Z2h0X3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABVwIAAAAdX2F2YWlsYWJsZV9wdXJjaGFzZV9tYXJrZXRpbmcAAAAAAVgCAAAAIV9wdXJjaGFzZWRfYnV5X2Fzc2V0X2luX21hcmtldGluZwAAAAABWQIAAAATX2JvdWdodF9hbGxvY2F0aW9ucwAAAAABWgIAAAANX2NsYWltX3N0YXR1cwAAAAACYWECAAAAD190aWNrZXRzX3Jlc3VsdAAAAAACYWICAAAAIF90aWNrZXRzX3Jlc3VsdF9oaWdoX2NvbXBldGl0aW9uAAAAAAJhYwIAAAAUX2ZyZWV6ZV90b2tlbl9hbW91bnQAAAAAAmFkCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFU6UWqHpAvOq7xug7mLpqSXxqYhOHzYrMIAAAAAAJhZQkBAAAAB0FkZHJlc3MAAAABAQAAABoBVKr6ad6B9BNShco/LjqIUbMZ6pgcWfINLQAAAAACYWYJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVSMKR35sXlSywl+Wp/a1y8GBxSD7AzdEUkAAAAAAmFnCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFUuYnNz0dxupdy7LhFDzOwqkmF0Q14MgJtAAAAAAJhaAEAAAAgbySjyqsw3FIpmOgsYVruWn8jTcIt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", "height": 1845199, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6pKcdJdFiJwkFWiJLrW4R2z8BkJUTag7ogm1aFWtXmHS Next: 3cvkTrToEvZvGRr9PsjwQgCDiEBNddD8EnEoPgBoVg4d Diff:
OldNewDifferences
125125
126126 let maxAllocationsAmount = 2
127127
128-let isActive = valueOrElse(getBoolean(this, keyActive), true)
129-
130128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
131129
132130 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
158156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
159157
160158
161-func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
159+let active = valueOrElse(getBoolean(this, keyActive), true)
160+
161+func isActive () = if (active)
162+ then unit
163+ else throw("DApp is inactive at this moment")
164+
165+
166+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
167+ then unit
168+ else throw("Only admin can call this function")
162169
163170
164171 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
172179
173180
174181 @Callable(i)
175-func hashingRandom (launchpadId,hash) = if (!(isActive))
176- then throw("DApp is inactive at this moment")
177- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
178- then throw("Only admin can call this function")
179- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
180183
181184
182185
183186 @Callable(i)
184-func claim (launchpadId) = {
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
188+
189+
190+
191+@Callable(i)
192+func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = valueOrElse(isActive(), if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
193+ then throw("Only project admin can call init function")
194+ else if ((size(i.payments) != 1))
195+ then throw("One attached payment expected")
196+ else if ((height > startHeight))
197+ then throw("Start height must be greater than blockchain height")
198+ else if (if (freezeAdditionalToken)
199+ then (size(freezeParams) != 3)
200+ else false)
201+ then throw("Freeze params list must have 3 items")
202+ else {
203+ let launchpadId = getLaunchpadNextId()
204+ let launchpadIdStr = toString(launchpadId)
205+ let $t063976472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063976472._1
207+ let pmtAssetId = $t063976472._2
208+ let $t064816554 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064816554._1
210+ let pmtAssetName = $t064816554._2
211+ let pmtDecimals = $t064816554._3
212+ let freezeAdditionalEntry = if (freezeAdditionalToken)
213+ then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
214+ else nil
215+ ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), duration), StringEntry((launchpadIdStr + keyBuyToken), buyToken), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyHCTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyTokensPerTicket), tokensPerTicket), IntegerEntry((launchpadIdStr + keyPricePerToken), pricePerToken), IntegerEntry((launchpadIdStr + keySwopPerTicket), swopPerTicket), IntegerEntry((launchpadIdStr + keySwopfiTicketsAmount), swopfiTicketsAmount), IntegerEntry((launchpadIdStr + keyCampaignTokensAmount), campaignTokensAmount), IntegerEntry((launchpadIdStr + keyTokensPerAllocation), tokensPerAllocation), StringEntry((launchpadIdStr + keyClaimParams), makeString(claimParams, ",")), BooleanEntry((launchpadIdStr + keyHighCompetitionSale), HighCompetitionSale), IntegerEntry((launchpadIdStr + keyHighCompetitionComission), highCompetitionComission), IntegerEntry((launchpadIdStr + keyHighCompetitionAmount), highCompetitionTicketsAmount), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
216+ })
217+
218+
219+
220+@Callable(i)
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091609235 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091609235._1
224+ let pmtAssetId = $t091609235._2
225+ let $t092409390 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092409390._1
227+ let buyAssetStrId = $t092409390._2
228+ let buyAssetName = $t092409390._3
229+ let buyAssetDecimals = $t092409390._4
230+ let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
231+ let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
232+ let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
233+ let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
234+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
235+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
236+ let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
237+ if ((activeLaunchpadId != launchpadId))
238+ then throw("There is no active launchpad or this launchpad is ended")
239+ else if ((startHeight > height))
240+ then throw("Launchpad sale not started yet")
241+ else if ((height > (startHeight + duration)))
242+ then throw("Launchpad sale ended")
243+ else if (if (!(freezeAdditionalToken))
244+ then if ((size(i.payments) != 1))
245+ then true
246+ else (pmtAssetId != buyAssetId)
247+ else false)
248+ then throw((("One attached payment in " + buyAssetName) + " expected"))
249+ else if (if (freezeAdditionalToken)
250+ then if ((size(i.payments) != 2))
251+ then true
252+ else (pmtAssetId != buyAssetId)
253+ else false)
254+ then {
255+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
256+ throw(((("Two attached payments expected: First in " + buyAssetName) + ", second in ") + freezeTokenId))
257+ }
258+ else if (if ((0 >= allowedTicketsAmountAll))
259+ then true
260+ else (0 >= allowedTicketsAmount))
261+ then throw("Not enought SWOP in staking to buy tickets")
262+ else {
263+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
264+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
265+ let $t01120211346 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01120211346._1
267+ let tokenStrAssetId = $t01120211346._2
268+ let tokenAssetName = $t01120211346._3
269+ let tokenDecimals = $t01120211346._4
270+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
271+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
272+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
273+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
274+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
275+ let change = (pmtAmount - allowedBuyPriceWithComission)
276+ if ((buyTicketAmount == 0))
277+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
278+ else if ((change != 0))
279+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + buyAssetName))
280+ else {
281+ let freezeAdditionalEntry = if (freezeAdditionalToken)
282+ then {
283+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
284+ let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
285+ let $t01251012597 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01251012597._1
287+ let pmtAssetIdFreeze = $t01251012597._2
288+ let $t01261412705 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01261412705._1
290+ let pmtFreezeAssetName = $t01261412705._2
291+ let pmtFreezeDecimals = $t01261412705._3
292+ let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
293+ if (if ((pmtFreezeStrAssetId != freezeTokenId))
294+ then true
295+ else (needFreezeTokens != pmtAmountFreeze))
296+ then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
297+ else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
298+ }
299+ else nil
300+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
301+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
302+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
303+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
304+ then ("," + boughtRange)
305+ else ("" + boughtRange)))
306+ let inv = if ((buyAssetId == USDN))
307+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
308+ else 0
309+ if ((inv == inv))
310+ then {
311+ let baseEntry = ([IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount), (boughtTicketsAmount + allowedBuyTicketAmount)), IntegerEntry((toString(launchpadId) + keyTicketLastNumber), (lastBoughtTicketNumber + allowedBuyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets), newUserBoughtTicketsNumbers)] ++ freezeAdditionalEntry)
312+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
313+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
314+ else baseEntry
315+ }
316+ else throw("Strict value is not equal to itself.")
317+ }
318+ }
319+ })
320+
321+
322+
323+@Callable(i)
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01477614851 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01477614851._1
327+ let pmtAssetId = $t01477614851._2
328+ let $t01485615006 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01485615006._1
330+ let buyAssetStrId = $t01485615006._2
331+ let buyAssetName = $t01485615006._3
332+ let buyAssetDecimals = $t01485615006._4
333+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
335+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
336+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
337+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
338+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
339+ let $t01567515819 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01567515819._1
341+ let tokenStrAssetId = $t01567515819._2
342+ let tokenAssetName = $t01567515819._3
343+ let tokenDecimals = $t01567515819._4
344+ let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
345+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
346+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
347+ if ((activeLaunchpadId != launchpadId))
348+ then throw("There is no active launchpad or this launchpad is ended")
349+ else if ((startHeight > height))
350+ then throw("Launchpad sale not started yet")
351+ else if ((height > (startHeight + duration)))
352+ then throw("Launchpad sale ended")
353+ else if (if ((size(i.payments) != 1))
354+ then true
355+ else (pmtAssetId != buyAssetId))
356+ then throw((("One attached payment in " + buyAssetName) + " expected"))
357+ else if ((boughtAllocations >= maxAllocationsAmount))
358+ then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
359+ else if (if ((allocationPriceWithComission != pmtAmount))
360+ then ((allocationPriceWithComission * 2) != pmtAmount)
361+ else false)
362+ then throw(((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + buyAssetName) + " per allocation"))
363+ else {
364+ let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
365+ let inv = if ((buyAssetId == USDN))
366+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
367+ else 0
368+ if ((inv == inv))
369+ then {
370+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations), (boughtAllocations + buyAllocationsAmount)), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing), (userUsdnInMarketing + pmtAmount)), IntegerEntry((toString(launchpadId) + keyAmountBuyAssetInMarketing), (usdnInMarketing + pmtAmount))]
371+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
372+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
373+ else baseEntry
374+ }
375+ else throw("Strict value is not equal to itself.")
376+ }
377+ })
378+
379+
380+
381+@Callable(i)
382+func commitHighCompetitionSale (launchpadId,refId) = valueOrElse(isActive(), {
383+ let $t01807718152 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01807718152._1
385+ let pmtAssetId = $t01807718152._2
386+ let $t01815718307 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01815718307._1
388+ let buyAssetStrId = $t01815718307._2
389+ let buyAssetName = $t01815718307._3
390+ let buyAssetDecimals = $t01815718307._4
391+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
392+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
393+ let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
394+ let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
395+ if ((activeLaunchpadId != launchpadId))
396+ then throw("There is no active launchpad or this launchpad is ended")
397+ else if (!(highCompetitionSale))
398+ then throw("There is no high competition sale for this launchpad")
399+ else if ((startHeight > height))
400+ then throw("Launchpad sale not started yet")
401+ else if ((height > (startHeight + duration)))
402+ then throw("Launchpad sale ended")
403+ else if (if ((size(i.payments) != 1))
404+ then true
405+ else (pmtAssetId != buyAssetId))
406+ then throw((("One attached payment in " + buyAssetName) + " expected"))
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01948019624 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01948019624._1
412+ let tokenStrAssetId = $t01948019624._2
413+ let tokenAssetName = $t01948019624._3
414+ let tokenDecimals = $t01948019624._4
415+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
416+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
417+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
418+ let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
419+ let change = (pmtAmount - buyPriceWithComission)
420+ if ((buyTicketAmount == 0))
421+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
422+ else if ((change != 0))
423+ then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
424+ else {
425+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
426+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
427+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
428+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
429+ then ("," + boughtRange)
430+ else ("" + boughtRange)))
431+ let inv = if ((buyAssetId == USDN))
432+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
433+ else 0
434+ if ((inv == inv))
435+ then {
436+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount), (boughtHCTicketsAmount + buyTicketAmount)), IntegerEntry((toString(launchpadId) + keyHCTicketLastNumber), (lastBoughtTicketNumber + buyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets), newUserBoughtTicketsNumbers)]
437+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
438+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
439+ else baseEntry
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ }
444+ })
445+
446+
447+
448+@Callable(i)
449+func finalise (launchpadId,vrfHeight,secretWord) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
450+ let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
451+ let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
452+ if ((calcHash != savedHash))
453+ then throw("vrf Height hash not matching")
454+ else {
455+ let $t02223722387 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02223722387._1
457+ let buyAssetStrId = $t02223722387._2
458+ let buyAssetName = $t02223722387._3
459+ let buyAssetDecimals = $t02223722387._4
460+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
461+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
462+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
463+ let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
464+ let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
465+ let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
466+ let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
467+ let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
468+ let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
469+ let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
470+ let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
471+ if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
472+ then throw("Can't transfer negative value to project")
473+ else {
474+ let inv = if ((buyAssetId == USDN))
475+ then invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
476+ else 0
477+ if ((inv == inv))
478+ then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) - transferedBuyAsset), buyAssetId), ScriptTransfer(commissionWallet, ((swopfiMembersComission + marketingComission) + swopfiHCComission), buyAssetId)]
479+ else throw("Strict value is not equal to itself.")
480+ }
481+ }
482+ }))
483+
484+
485+
486+@Callable(i)
487+func claim (launchpadId) = valueOrElse(isActive(), {
185488 let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
186489 let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
187490 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
188491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
189492 let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
190- if (!(isActive))
191- then throw("DApp is inactive at this moment")
192- else if ((finalizeHeight == 0))
193- then throw("You can't claim because results are not finalized")
194- else if (userClaimStatus)
195- then throw("You are already claimed")
196- else if (if (if ((boughtTickets == 0))
197- then (boughtAllocations == 0)
198- else false)
199- then (boughtHCTickets == 0)
200- else false)
201- then throw("You can't claim because you don't buy anything")
202- else {
203- let $t061266276 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
204- let buyAssetId = $t061266276._1
205- let buyAssetStrId = $t061266276._2
206- let buyAssetName = $t061266276._3
207- let buyAssetDecimals = $t061266276._4
208- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
209- let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
210- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
211- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
212- let allowedAllocations = min([boughtAllocations, awailableAllocations])
213- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
214- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
215- let $t070807224 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
216- let tokenId = $t070807224._1
217- let tokenStrAssetId = $t070807224._2
218- let tokenAssetName = $t070807224._3
219- let tokenDecimals = $t070807224._4
220- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
221- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
222- let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
223- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
224- let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
225- let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
226- let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commission), 100)
227- let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
228- if (if (if ((0 > buyAssetForAllocations))
229- then true
230- else (0 > buyAssetForUnwonnedTickets))
231- then true
232- else (0 > buyAssetForHCUnwonnedTickets))
233- then throw("Error with allowed allocation param or wonned tickets param please contact support")
234- else {
235- let returnedBuyAssetAmount = ((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) - claimedBuyToken)
236- let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
237- then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
238- else nil
239- let inv = if (if ((returnedBuyAssetAmount > 0))
240- then (buyAssetId == USDN)
241- else false)
242- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
243- else 0
244- if ((inv == inv))
245- then {
246- let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
247- if (if ((size(claimedParams) == 0))
248- then true
249- else (claimedParams[0] == "claimAll"))
493+ if ((finalizeHeight == 0))
494+ then throw("You can't claim because results are not finalized")
495+ else if (userClaimStatus)
496+ then throw("You are already claimed")
497+ else if (if (if ((boughtTickets == 0))
498+ then (boughtAllocations == 0)
499+ else false)
500+ then (boughtHCTickets == 0)
501+ else false)
502+ then throw("You can't claim because you don't buy anything")
503+ else {
504+ let $t02540725557 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02540725557._1
506+ let buyAssetStrId = $t02540725557._2
507+ let buyAssetName = $t02540725557._3
508+ let buyAssetDecimals = $t02540725557._4
509+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
510+ let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
511+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
512+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
513+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
514+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
515+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
516+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
517+ let $t02646326607 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02646326607._1
519+ let tokenStrAssetId = $t02646326607._2
520+ let tokenAssetName = $t02646326607._3
521+ let tokenDecimals = $t02646326607._4
522+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
523+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
524+ let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
525+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
526+ let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
527+ let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
528+ let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commissionHC), 100)
529+ let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
530+ if (if (if ((0 > buyAssetForAllocations))
531+ then true
532+ else (0 > buyAssetForUnwonnedTickets))
533+ then true
534+ else (0 > buyAssetForHCUnwonnedTickets))
535+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
536+ else {
537+ let returnedBuyAssetAmount = (((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) + buyAssetForAllocations) - claimedBuyToken)
538+ let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
539+ then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
540+ else nil
541+ let inv = if (if ((returnedBuyAssetAmount > 0))
542+ then (buyAssetId == USDN)
543+ else false)
544+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
545+ else 0
546+ if ((inv == inv))
547+ then {
548+ let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
549+ if (if ((size(claimedParams) == 0))
550+ then true
551+ else (claimedParams[0] == "claimAll"))
552+ then {
553+ let transferTokens = if ((transferTokensAmount > 0))
554+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
555+ else nil
556+ (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
557+ }
558+ else if ((claimedParams[0] == "claimPeriod"))
250559 then {
251- let transferTokens = if ((transferTokensAmount > 0))
252- then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
560+ let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
561+ let unlockPeriod = value(parseInt(claimedParams[2]))
562+ let blockHeight = (value(parseInt(claimedParams[3])) + finalizeHeight)
563+ let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
564+ let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[1])), 100) + (if ((height > blockHeight))
565+ then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
566+ else (0 - claimedTokens)))
567+ let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
568+ then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
253569 else nil
254- (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
570+ if (if ((allowedTokensAmount > 0))
571+ then true
572+ else (returnedBuyAssetAmount > 0))
573+ then {
574+ let transferTokens = if ((allowedTokensAmount > 0))
575+ then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
576+ else nil
577+ (transferBuyAsset ++ transferTokens)
578+ }
579+ else throw("Nothing to claim")
255580 }
256- else if ((claimedParams[0] == "claimPeriod"))
257- then {
258- let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
259- let startAmount = value(parseInt(claimedParams[1]))
260- let unlockPeriod = value(parseInt(claimedParams[2]))
261- let blockHeight = (value(parseInt(claimedParams[3])) + finalizeHeight)
262- let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
263- let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[1])), 100) + (if ((height > blockHeight))
264- then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
265- else (0 - claimedTokens)))
266- let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
267- then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
268- else nil
269- if (if ((allowedTokensAmount > 0))
270- then true
271- else (returnedBuyAssetAmount > 0))
272- then {
273- let transferTokens = if ((allowedTokensAmount > 0))
274- then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
275- else nil
276- (transferBuyAsset ++ transferTokens)
277- }
278- else throw("Nothing to claim")
279- }
280- else throw("Error whith claim params: unknown function")
281- }
282- else throw("Strict value is not equal to itself.")
283- }
284- }
285- }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
286587
287588
288589
289590 @Callable(i)
290-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
291592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
292- if (!(isActive))
293- then throw("DApp is inactive at this moment")
294- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
295- then throw("You can't claim because results are not finalized")
296- else if (!(freezeAdditionalToken))
297- then throw("There are no additional token freezing for this launchpad")
298- else {
299- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
300- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
301- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
302- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
303- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
304- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
305- if ((userTokensFreezed == 0))
306- then throw("You are already claimed your tokens or not paid anything")
307- else if ((blockEndHeight > height))
308- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
309- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
310- }
311- }
593+ if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
594+ then throw("You can't claim because results are not finalized")
595+ else if (!(freezeAdditionalToken))
596+ then throw("There are no additional token freezing for this launchpad")
597+ else {
598+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
599+ let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
600+ let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
601+ let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
602+ let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
603+ let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
604+ if ((userTokensFreezed == 0))
605+ then throw("You are already claimed your tokens or not paid anything")
606+ else if ((blockEndHeight > height))
607+ then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
608+ else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
609+ }
610+ })
312611
313612
314613
315614 @Callable(i)
316-func transferBuyAsset (launchpadId,amount) = if (!(isActive))
317- then throw("DApp is inactive")
318- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
319- then throw("Only admin can call this function")
320- else {
321- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
322- let $t01364513795 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
323- let buyAssetId = $t01364513795._1
324- let buyAssetStrId = $t01364513795._2
325- let buyAssetName = $t01364513795._3
326- let buyAssetDecimals = $t01364513795._4
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03273432884 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03273432884._1
619+ let buyAssetStrId = $t03273432884._2
620+ let buyAssetName = $t03273432884._3
621+ let buyAssetDecimals = $t03273432884._4
327622 [IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
328- }
623+ }))
329624
330625
331626
332627 @Callable(i)
333-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
334629 then throw("DApp already inactive")
335- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
336- then throw("Only admin can call this function")
337- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
338631
339632
340633
341634 @Callable(i)
342-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
343636 then throw("DApp already active")
344- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
345- then throw("Only admin can call this function")
346- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
347638
348639
349640 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let keyActive = "active"
55
66 let keyAdminPubKey1 = "admin_pub_1"
77
88 let keyAdminPubKey2 = "admin_pub_2"
99
1010 let keyAdminPubKey3 = "admin_pub_3"
1111
1212 let keyLaunchpadDataTransactionStatus = "launchpad_data_transaction_status"
1313
1414 let keyLaunchpadNextId = "launchpad_next_id"
1515
1616 let keyLaunchpadActiveId = "launchpad_active_id"
1717
1818 let keyInitCaller = "init_caller"
1919
2020 let keyAddress = "_address"
2121
2222 let keyInitHeight = "_init_height"
2323
2424 let keyStartHeight = "_start_height"
2525
2626 let keyFinaliseHeight = "_finalise_height"
2727
2828 let keyComission = "_comission"
2929
3030 let keyAssetId = "_asset_id"
3131
3232 let keyTotalTokenAmount = "_total_token_amount"
3333
3434 let keyTotalAmountBuyAssetSold = "_total_buy_asset_sold"
3535
3636 let keyTokensPerTicket = "_tokens_per_ticket"
3737
3838 let keyPricePerToken = "_price_per_token"
3939
4040 let keySwopPerTicket = "_swop_per_ticket"
4141
4242 let keySwopfiTicketsAmount = "_tickets_swopfi_members"
4343
4444 let keyCampaignTokensAmount = "_tokens_access_list"
4545
4646 let keyTokensPerAllocation = "_tokens_per_allocation"
4747
4848 let keyTicketLastNumber = "_ticket_last_number"
4949
5050 let keyGovernanceStaked = "_SWOP_amount"
5151
5252 let keyUserRefId = "_ref_id"
5353
5454 let keyVerifyHash = "_verify_hash"
5555
5656 let keyDuration = "_duration"
5757
5858 let keyAmountBuyAssetInMarketing = "_total_purchased_buy_asset_in_marketing"
5959
6060 let keyAmountBuyAssetInMarketingFinalized = "_total_purchased_buy_asset_in_marketing_finalized"
6161
6262 let keyTransferBuyAsset = "_transfer_buy_asset"
6363
6464 let keyFreezSwopDuration = "_freeze_swop_duration"
6565
6666 let keyFreezeAdditionalToken = "_freeze_additional_token"
6767
6868 let keyFreezeTokenId = "_freeze_token_id"
6969
7070 let keyFreezeTokenDuration = "_freeze_token_duration"
7171
7272 let keyFreezeTokenPerTicket = "_freeze_token_per_ticket"
7373
7474 let keyBuyToken = "_buy_token"
7575
7676 let keyClaimParams = "_claim_params"
7777
7878 let keyHighCompetitionComission = "_high_competition_comission"
7979
8080 let keyHighCompetitionSale = "_high_competition_sale"
8181
8282 let keyHCTicketLastNumber = "_high_competition_ticket_last_number"
8383
8484 let keyHighCompetitionAmount = "_tickets_high_competition"
8585
8686 let keyTotalAmountBuyAssetSoldHC = "_total_buy_asset_sold_high_competition"
8787
8888 let keyUserClaimedTokens = "_claimed_tokens"
8989
9090 let keyUserClaimedBuyTokens = "_claimed_buy_tokens"
9191
9292 let keyUserBoughtTicketsAmount = "_bought_tickets"
9393
9494 let keyUserTickets = "_tickets_number"
9595
9696 let keyUserHCTickets = "_tickets_number_high_competition"
9797
9898 let keyUserHCBoughtTicketsAmount = "_bought_tickets_high_competition"
9999
100100 let keyUserAvailableAllocations = "_available_purchase_marketing"
101101
102102 let keyUserAmountBuyAssetInMarketing = "_purchased_buy_asset_in_marketing"
103103
104104 let keyUserBoughtAllocations = "_bought_allocations"
105105
106106 let keyUserClaimStatus = "_claim_status"
107107
108108 let keyUserWinnedTicketsAmount = "_tickets_result"
109109
110110 let keyUserWinnedHighCompetitionTicketsAmount = "_tickets_result_high_competition"
111111
112112 let keyUserFreezeToken = "_freeze_token_amount"
113113
114114 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
115115
116116 let governance = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
117117
118118 let commissionWallet = Address(base58'3N2hBdeDEs7wCNA9EY8qv3B6drjgKD64xQG')
119119
120120 let stakingUSDNAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
121121
122122 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
123123
124124 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
125125
126126 let maxAllocationsAmount = 2
127127
128-let isActive = valueOrElse(getBoolean(this, keyActive), true)
129-
130128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
131129
132130 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
133131 case string: String =>
134132 fromBase58String(string)
135133 case nothing =>
136134 throw("Admin public key is empty")
137135 }
138136
139137
140138 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
141139
142140 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
143141
144142 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
145143
146144 func getAssetInfo (assetId) = match assetId {
147145 case id: ByteVector =>
148146 let stringId = toBase58String(id)
149147 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
150148 $Tuple3(stringId, info.name, info.decimals)
151149 case waves: Unit =>
152150 $Tuple3("WAVES", "WAVES", 8)
153151 case _ =>
154152 throw("Match error")
155153 }
156154
157155
158156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
159157
160158
161-func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
159+let active = valueOrElse(getBoolean(this, keyActive), true)
160+
161+func isActive () = if (active)
162+ then unit
163+ else throw("DApp is inactive at this moment")
164+
165+
166+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
167+ then unit
168+ else throw("Only admin can call this function")
162169
163170
164171 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
165172 then $Tuple4(unit, "WAVES", "WAVES", 8)
166173 else {
167174 let stringId = assetStr
168175 let id = fromBase58String(assetStr)
169176 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
170177 $Tuple4(id, stringId, info.name, info.decimals)
171178 }
172179
173180
174181 @Callable(i)
175-func hashingRandom (launchpadId,hash) = if (!(isActive))
176- then throw("DApp is inactive at this moment")
177- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
178- then throw("Only admin can call this function")
179- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
180183
181184
182185
183186 @Callable(i)
184-func claim (launchpadId) = {
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
188+
189+
190+
191+@Callable(i)
192+func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = valueOrElse(isActive(), if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
193+ then throw("Only project admin can call init function")
194+ else if ((size(i.payments) != 1))
195+ then throw("One attached payment expected")
196+ else if ((height > startHeight))
197+ then throw("Start height must be greater than blockchain height")
198+ else if (if (freezeAdditionalToken)
199+ then (size(freezeParams) != 3)
200+ else false)
201+ then throw("Freeze params list must have 3 items")
202+ else {
203+ let launchpadId = getLaunchpadNextId()
204+ let launchpadIdStr = toString(launchpadId)
205+ let $t063976472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063976472._1
207+ let pmtAssetId = $t063976472._2
208+ let $t064816554 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064816554._1
210+ let pmtAssetName = $t064816554._2
211+ let pmtDecimals = $t064816554._3
212+ let freezeAdditionalEntry = if (freezeAdditionalToken)
213+ then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
214+ else nil
215+ ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), duration), StringEntry((launchpadIdStr + keyBuyToken), buyToken), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyHCTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyTokensPerTicket), tokensPerTicket), IntegerEntry((launchpadIdStr + keyPricePerToken), pricePerToken), IntegerEntry((launchpadIdStr + keySwopPerTicket), swopPerTicket), IntegerEntry((launchpadIdStr + keySwopfiTicketsAmount), swopfiTicketsAmount), IntegerEntry((launchpadIdStr + keyCampaignTokensAmount), campaignTokensAmount), IntegerEntry((launchpadIdStr + keyTokensPerAllocation), tokensPerAllocation), StringEntry((launchpadIdStr + keyClaimParams), makeString(claimParams, ",")), BooleanEntry((launchpadIdStr + keyHighCompetitionSale), HighCompetitionSale), IntegerEntry((launchpadIdStr + keyHighCompetitionComission), highCompetitionComission), IntegerEntry((launchpadIdStr + keyHighCompetitionAmount), highCompetitionTicketsAmount), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
216+ })
217+
218+
219+
220+@Callable(i)
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091609235 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091609235._1
224+ let pmtAssetId = $t091609235._2
225+ let $t092409390 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092409390._1
227+ let buyAssetStrId = $t092409390._2
228+ let buyAssetName = $t092409390._3
229+ let buyAssetDecimals = $t092409390._4
230+ let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
231+ let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
232+ let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
233+ let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
234+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
235+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
236+ let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
237+ if ((activeLaunchpadId != launchpadId))
238+ then throw("There is no active launchpad or this launchpad is ended")
239+ else if ((startHeight > height))
240+ then throw("Launchpad sale not started yet")
241+ else if ((height > (startHeight + duration)))
242+ then throw("Launchpad sale ended")
243+ else if (if (!(freezeAdditionalToken))
244+ then if ((size(i.payments) != 1))
245+ then true
246+ else (pmtAssetId != buyAssetId)
247+ else false)
248+ then throw((("One attached payment in " + buyAssetName) + " expected"))
249+ else if (if (freezeAdditionalToken)
250+ then if ((size(i.payments) != 2))
251+ then true
252+ else (pmtAssetId != buyAssetId)
253+ else false)
254+ then {
255+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
256+ throw(((("Two attached payments expected: First in " + buyAssetName) + ", second in ") + freezeTokenId))
257+ }
258+ else if (if ((0 >= allowedTicketsAmountAll))
259+ then true
260+ else (0 >= allowedTicketsAmount))
261+ then throw("Not enought SWOP in staking to buy tickets")
262+ else {
263+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
264+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
265+ let $t01120211346 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01120211346._1
267+ let tokenStrAssetId = $t01120211346._2
268+ let tokenAssetName = $t01120211346._3
269+ let tokenDecimals = $t01120211346._4
270+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
271+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
272+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
273+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
274+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
275+ let change = (pmtAmount - allowedBuyPriceWithComission)
276+ if ((buyTicketAmount == 0))
277+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
278+ else if ((change != 0))
279+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + buyAssetName))
280+ else {
281+ let freezeAdditionalEntry = if (freezeAdditionalToken)
282+ then {
283+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
284+ let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
285+ let $t01251012597 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01251012597._1
287+ let pmtAssetIdFreeze = $t01251012597._2
288+ let $t01261412705 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01261412705._1
290+ let pmtFreezeAssetName = $t01261412705._2
291+ let pmtFreezeDecimals = $t01261412705._3
292+ let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
293+ if (if ((pmtFreezeStrAssetId != freezeTokenId))
294+ then true
295+ else (needFreezeTokens != pmtAmountFreeze))
296+ then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
297+ else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
298+ }
299+ else nil
300+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
301+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
302+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
303+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
304+ then ("," + boughtRange)
305+ else ("" + boughtRange)))
306+ let inv = if ((buyAssetId == USDN))
307+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
308+ else 0
309+ if ((inv == inv))
310+ then {
311+ let baseEntry = ([IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount), (boughtTicketsAmount + allowedBuyTicketAmount)), IntegerEntry((toString(launchpadId) + keyTicketLastNumber), (lastBoughtTicketNumber + allowedBuyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets), newUserBoughtTicketsNumbers)] ++ freezeAdditionalEntry)
312+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
313+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
314+ else baseEntry
315+ }
316+ else throw("Strict value is not equal to itself.")
317+ }
318+ }
319+ })
320+
321+
322+
323+@Callable(i)
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01477614851 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01477614851._1
327+ let pmtAssetId = $t01477614851._2
328+ let $t01485615006 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01485615006._1
330+ let buyAssetStrId = $t01485615006._2
331+ let buyAssetName = $t01485615006._3
332+ let buyAssetDecimals = $t01485615006._4
333+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
335+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
336+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
337+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
338+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
339+ let $t01567515819 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01567515819._1
341+ let tokenStrAssetId = $t01567515819._2
342+ let tokenAssetName = $t01567515819._3
343+ let tokenDecimals = $t01567515819._4
344+ let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
345+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
346+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
347+ if ((activeLaunchpadId != launchpadId))
348+ then throw("There is no active launchpad or this launchpad is ended")
349+ else if ((startHeight > height))
350+ then throw("Launchpad sale not started yet")
351+ else if ((height > (startHeight + duration)))
352+ then throw("Launchpad sale ended")
353+ else if (if ((size(i.payments) != 1))
354+ then true
355+ else (pmtAssetId != buyAssetId))
356+ then throw((("One attached payment in " + buyAssetName) + " expected"))
357+ else if ((boughtAllocations >= maxAllocationsAmount))
358+ then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
359+ else if (if ((allocationPriceWithComission != pmtAmount))
360+ then ((allocationPriceWithComission * 2) != pmtAmount)
361+ else false)
362+ then throw(((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + buyAssetName) + " per allocation"))
363+ else {
364+ let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
365+ let inv = if ((buyAssetId == USDN))
366+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
367+ else 0
368+ if ((inv == inv))
369+ then {
370+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations), (boughtAllocations + buyAllocationsAmount)), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing), (userUsdnInMarketing + pmtAmount)), IntegerEntry((toString(launchpadId) + keyAmountBuyAssetInMarketing), (usdnInMarketing + pmtAmount))]
371+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
372+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
373+ else baseEntry
374+ }
375+ else throw("Strict value is not equal to itself.")
376+ }
377+ })
378+
379+
380+
381+@Callable(i)
382+func commitHighCompetitionSale (launchpadId,refId) = valueOrElse(isActive(), {
383+ let $t01807718152 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01807718152._1
385+ let pmtAssetId = $t01807718152._2
386+ let $t01815718307 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01815718307._1
388+ let buyAssetStrId = $t01815718307._2
389+ let buyAssetName = $t01815718307._3
390+ let buyAssetDecimals = $t01815718307._4
391+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
392+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
393+ let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
394+ let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
395+ if ((activeLaunchpadId != launchpadId))
396+ then throw("There is no active launchpad or this launchpad is ended")
397+ else if (!(highCompetitionSale))
398+ then throw("There is no high competition sale for this launchpad")
399+ else if ((startHeight > height))
400+ then throw("Launchpad sale not started yet")
401+ else if ((height > (startHeight + duration)))
402+ then throw("Launchpad sale ended")
403+ else if (if ((size(i.payments) != 1))
404+ then true
405+ else (pmtAssetId != buyAssetId))
406+ then throw((("One attached payment in " + buyAssetName) + " expected"))
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01948019624 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01948019624._1
412+ let tokenStrAssetId = $t01948019624._2
413+ let tokenAssetName = $t01948019624._3
414+ let tokenDecimals = $t01948019624._4
415+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
416+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
417+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
418+ let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
419+ let change = (pmtAmount - buyPriceWithComission)
420+ if ((buyTicketAmount == 0))
421+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
422+ else if ((change != 0))
423+ then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
424+ else {
425+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
426+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
427+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
428+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
429+ then ("," + boughtRange)
430+ else ("" + boughtRange)))
431+ let inv = if ((buyAssetId == USDN))
432+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
433+ else 0
434+ if ((inv == inv))
435+ then {
436+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount), (boughtHCTicketsAmount + buyTicketAmount)), IntegerEntry((toString(launchpadId) + keyHCTicketLastNumber), (lastBoughtTicketNumber + buyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets), newUserBoughtTicketsNumbers)]
437+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
438+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
439+ else baseEntry
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ }
444+ })
445+
446+
447+
448+@Callable(i)
449+func finalise (launchpadId,vrfHeight,secretWord) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
450+ let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
451+ let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
452+ if ((calcHash != savedHash))
453+ then throw("vrf Height hash not matching")
454+ else {
455+ let $t02223722387 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02223722387._1
457+ let buyAssetStrId = $t02223722387._2
458+ let buyAssetName = $t02223722387._3
459+ let buyAssetDecimals = $t02223722387._4
460+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
461+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
462+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
463+ let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
464+ let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
465+ let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
466+ let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
467+ let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
468+ let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
469+ let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
470+ let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
471+ if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
472+ then throw("Can't transfer negative value to project")
473+ else {
474+ let inv = if ((buyAssetId == USDN))
475+ then invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
476+ else 0
477+ if ((inv == inv))
478+ then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) - transferedBuyAsset), buyAssetId), ScriptTransfer(commissionWallet, ((swopfiMembersComission + marketingComission) + swopfiHCComission), buyAssetId)]
479+ else throw("Strict value is not equal to itself.")
480+ }
481+ }
482+ }))
483+
484+
485+
486+@Callable(i)
487+func claim (launchpadId) = valueOrElse(isActive(), {
185488 let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
186489 let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
187490 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
188491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
189492 let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
190- if (!(isActive))
191- then throw("DApp is inactive at this moment")
192- else if ((finalizeHeight == 0))
193- then throw("You can't claim because results are not finalized")
194- else if (userClaimStatus)
195- then throw("You are already claimed")
196- else if (if (if ((boughtTickets == 0))
197- then (boughtAllocations == 0)
198- else false)
199- then (boughtHCTickets == 0)
200- else false)
201- then throw("You can't claim because you don't buy anything")
202- else {
203- let $t061266276 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
204- let buyAssetId = $t061266276._1
205- let buyAssetStrId = $t061266276._2
206- let buyAssetName = $t061266276._3
207- let buyAssetDecimals = $t061266276._4
208- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
209- let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
210- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
211- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
212- let allowedAllocations = min([boughtAllocations, awailableAllocations])
213- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
214- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
215- let $t070807224 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
216- let tokenId = $t070807224._1
217- let tokenStrAssetId = $t070807224._2
218- let tokenAssetName = $t070807224._3
219- let tokenDecimals = $t070807224._4
220- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
221- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
222- let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
223- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
224- let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
225- let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
226- let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commission), 100)
227- let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
228- if (if (if ((0 > buyAssetForAllocations))
229- then true
230- else (0 > buyAssetForUnwonnedTickets))
231- then true
232- else (0 > buyAssetForHCUnwonnedTickets))
233- then throw("Error with allowed allocation param or wonned tickets param please contact support")
234- else {
235- let returnedBuyAssetAmount = ((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) - claimedBuyToken)
236- let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
237- then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
238- else nil
239- let inv = if (if ((returnedBuyAssetAmount > 0))
240- then (buyAssetId == USDN)
241- else false)
242- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
243- else 0
244- if ((inv == inv))
245- then {
246- let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
247- if (if ((size(claimedParams) == 0))
248- then true
249- else (claimedParams[0] == "claimAll"))
493+ if ((finalizeHeight == 0))
494+ then throw("You can't claim because results are not finalized")
495+ else if (userClaimStatus)
496+ then throw("You are already claimed")
497+ else if (if (if ((boughtTickets == 0))
498+ then (boughtAllocations == 0)
499+ else false)
500+ then (boughtHCTickets == 0)
501+ else false)
502+ then throw("You can't claim because you don't buy anything")
503+ else {
504+ let $t02540725557 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02540725557._1
506+ let buyAssetStrId = $t02540725557._2
507+ let buyAssetName = $t02540725557._3
508+ let buyAssetDecimals = $t02540725557._4
509+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
510+ let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
511+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
512+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
513+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
514+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
515+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
516+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
517+ let $t02646326607 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02646326607._1
519+ let tokenStrAssetId = $t02646326607._2
520+ let tokenAssetName = $t02646326607._3
521+ let tokenDecimals = $t02646326607._4
522+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
523+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
524+ let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
525+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
526+ let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
527+ let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
528+ let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commissionHC), 100)
529+ let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
530+ if (if (if ((0 > buyAssetForAllocations))
531+ then true
532+ else (0 > buyAssetForUnwonnedTickets))
533+ then true
534+ else (0 > buyAssetForHCUnwonnedTickets))
535+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
536+ else {
537+ let returnedBuyAssetAmount = (((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) + buyAssetForAllocations) - claimedBuyToken)
538+ let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
539+ then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
540+ else nil
541+ let inv = if (if ((returnedBuyAssetAmount > 0))
542+ then (buyAssetId == USDN)
543+ else false)
544+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
545+ else 0
546+ if ((inv == inv))
547+ then {
548+ let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
549+ if (if ((size(claimedParams) == 0))
550+ then true
551+ else (claimedParams[0] == "claimAll"))
552+ then {
553+ let transferTokens = if ((transferTokensAmount > 0))
554+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
555+ else nil
556+ (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
557+ }
558+ else if ((claimedParams[0] == "claimPeriod"))
250559 then {
251- let transferTokens = if ((transferTokensAmount > 0))
252- then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
560+ let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
561+ let unlockPeriod = value(parseInt(claimedParams[2]))
562+ let blockHeight = (value(parseInt(claimedParams[3])) + finalizeHeight)
563+ let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
564+ let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[1])), 100) + (if ((height > blockHeight))
565+ then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
566+ else (0 - claimedTokens)))
567+ let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
568+ then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
253569 else nil
254- (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
570+ if (if ((allowedTokensAmount > 0))
571+ then true
572+ else (returnedBuyAssetAmount > 0))
573+ then {
574+ let transferTokens = if ((allowedTokensAmount > 0))
575+ then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
576+ else nil
577+ (transferBuyAsset ++ transferTokens)
578+ }
579+ else throw("Nothing to claim")
255580 }
256- else if ((claimedParams[0] == "claimPeriod"))
257- then {
258- let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
259- let startAmount = value(parseInt(claimedParams[1]))
260- let unlockPeriod = value(parseInt(claimedParams[2]))
261- let blockHeight = (value(parseInt(claimedParams[3])) + finalizeHeight)
262- let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
263- let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[1])), 100) + (if ((height > blockHeight))
264- then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
265- else (0 - claimedTokens)))
266- let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
267- then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
268- else nil
269- if (if ((allowedTokensAmount > 0))
270- then true
271- else (returnedBuyAssetAmount > 0))
272- then {
273- let transferTokens = if ((allowedTokensAmount > 0))
274- then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
275- else nil
276- (transferBuyAsset ++ transferTokens)
277- }
278- else throw("Nothing to claim")
279- }
280- else throw("Error whith claim params: unknown function")
281- }
282- else throw("Strict value is not equal to itself.")
283- }
284- }
285- }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
286587
287588
288589
289590 @Callable(i)
290-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
291592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
292- if (!(isActive))
293- then throw("DApp is inactive at this moment")
294- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
295- then throw("You can't claim because results are not finalized")
296- else if (!(freezeAdditionalToken))
297- then throw("There are no additional token freezing for this launchpad")
298- else {
299- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
300- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
301- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
302- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
303- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
304- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
305- if ((userTokensFreezed == 0))
306- then throw("You are already claimed your tokens or not paid anything")
307- else if ((blockEndHeight > height))
308- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
309- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
310- }
311- }
593+ if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
594+ then throw("You can't claim because results are not finalized")
595+ else if (!(freezeAdditionalToken))
596+ then throw("There are no additional token freezing for this launchpad")
597+ else {
598+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
599+ let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
600+ let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
601+ let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
602+ let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
603+ let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
604+ if ((userTokensFreezed == 0))
605+ then throw("You are already claimed your tokens or not paid anything")
606+ else if ((blockEndHeight > height))
607+ then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
608+ else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
609+ }
610+ })
312611
313612
314613
315614 @Callable(i)
316-func transferBuyAsset (launchpadId,amount) = if (!(isActive))
317- then throw("DApp is inactive")
318- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
319- then throw("Only admin can call this function")
320- else {
321- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
322- let $t01364513795 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
323- let buyAssetId = $t01364513795._1
324- let buyAssetStrId = $t01364513795._2
325- let buyAssetName = $t01364513795._3
326- let buyAssetDecimals = $t01364513795._4
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03273432884 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03273432884._1
619+ let buyAssetStrId = $t03273432884._2
620+ let buyAssetName = $t03273432884._3
621+ let buyAssetDecimals = $t03273432884._4
327622 [IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
328- }
623+ }))
329624
330625
331626
332627 @Callable(i)
333-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
334629 then throw("DApp already inactive")
335- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
336- then throw("Only admin can call this function")
337- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
338631
339632
340633
341634 @Callable(i)
342-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
343636 then throw("DApp already active")
344- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
345- then throw("Only admin can call this function")
346- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
347638
348639
349640 @Verifier(tx)
350641 func verify () = {
351642 let multiSignedByAdmins = {
352643 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
353644 then 1
354645 else 0
355646 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
356647 then 1
357648 else 0
358649 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
359650 then 1
360651 else 0
361652 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
362653 }
363654 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
364655 then true
365656 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
366657 then true
367658 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
368659 then true
369660 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
370661 match tx {
371662 case dtx: DataTransaction =>
372663 if (valueOrElse(getBoolean(oracle, keyLaunchpadDataTransactionStatus), false))
373664 then signedByAdmin
374665 else false
375666 case _ =>
376667 multiSignedByAdmins
377668 }
378669 }
379670

github/deemru/w8io/873ac7e 
88.92 ms