tx · 68XDz2f2mYmKWsG6TzHzqmmEvJ3CrxeVubbizUd1NFip

3P6YGPihPiF81VELikoV1myU55iwTvmcQaQ:  -0.01400000 Waves

2021.12.22 17:14 [2910566] smart account 3P6YGPihPiF81VELikoV1myU55iwTvmcQaQ > SELF 0.00000000 Waves

{ "type": 13, "id": "68XDz2f2mYmKWsG6TzHzqmmEvJ3CrxeVubbizUd1NFip", "fee": 1400000, "feeAssetId": null, "timestamp": 1640182477568, "version": 2, "chainId": 87, "sender": "3P6YGPihPiF81VELikoV1myU55iwTvmcQaQ", "senderPublicKey": "BWnMC6WjWvjJRc2jc1XibbL3RSvL2mFekrvRxpJGdtp1", "proofs": [ "", "7yH3ByM6BmPmZvSm3otXRYHLBewsXF3pk2SbA8qKF6jGaZYALf36emGG2kD2ujbhwLrXJJvdQELfWAAuGDnVfHS", "57KXdSEKWYRgi7Av4T9i59n9W8oQgMXVkXskTmH2FFPRqT4M7E5pGWP1byEPqhqEzeZrmExRNBzwLrKfeaxQ9Cjf" ], "script": "base64:AAIFAAAAAAAAFIIIAhIECgIBCBIDCgEIEhQKEggBAQgBAQEBAQEBARgEAQEEGBIECgIBCBIECgIBCBIECgIBCBIFCgMBAQgSAwoBARIDCgEBEgQKAgEBEgASABoQCgFBEgtrZXlEdXJhdGlvbhohCgFCEhxrZXlBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGioKAUMSJWtleUFtb3VudEJ1eUFzc2V0SW5NYXJrZXRpbmdGaW5hbGl6ZWQaGAoBRBITa2V5VHJhbnNmZXJCdXlBc3NldBoZCgFFEhRrZXlGcmVlelN3b3BEdXJhdGlvbhodCgFGEhhrZXlGcmVlemVBZGRpdGlvbmFsVG9rZW4aFQoBRxIQa2V5RnJlZXplVG9rZW5JZBobCgFIEhZrZXlGcmVlemVUb2tlbkR1cmF0aW9uGhwKAUkSF2tleUZyZWV6ZVRva2VuUGVyVGlja2V0GhAKAUoSC2tleUJ1eVRva2VuGhMKAUsSDmtleUNsYWltUGFyYW1zGiAKAUwSG2tleUhpZ2hDb21wZXRpdGlvbkNvbWlzc2lvbhobCgFNEhZrZXlIaWdoQ29tcGV0aXRpb25TYWxlGhoKAU4SFWtleUhDVGlja2V0TGFzdE51bWJlchodCgFPEhhrZXlIaWdoQ29tcGV0aXRpb25BbW91bnQaIQoBUBIca2V5VG90YWxBbW91bnRCdXlBc3NldFNvbGRIQxoZCgFREhRrZXlVc2VyQ2xhaW1lZFRva2VucxocCgFSEhdrZXlVc2VyQ2xhaW1lZEJ1eVRva2VucxofCgFTEhprZXlVc2VyQm91Z2h0VGlja2V0c0Ftb3VudBoTCgFUEg5rZXlVc2VyVGlja2V0cxoVCgFVEhBrZXlVc2VySENUaWNrZXRzGiEKAVYSHGtleVVzZXJIQ0JvdWdodFRpY2tldHNBbW91bnQaIAoBVxIba2V5VXNlckF2YWlsYWJsZUFsbG9jYXRpb25zGiUKAVgSIGtleVVzZXJBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGh0KAVkSGGtleVVzZXJCb3VnaHRBbGxvY2F0aW9ucxoXCgFaEhJrZXlVc2VyQ2xhaW1TdGF0dXMaDgoBYRIJa2V5QWN0aXZlGgwKAmFBEgZhY3RpdmUaDgoCYUISCGlzQWN0aXZlGhEKAmFDEgtpc0FkbWluQ2FsbBoHCgJhRBIBaRocCgJhRRIWZ2V0QXNzZXRJbmZvRnJvbVN0cmluZxoOCgJhRhIIYXNzZXRTdHIaEQoCYUcSC2xhdW5jaHBhZElkGgoKAmFIEgRoYXNoGg0KAmFJEgdhZGRyZXNzGhQKAmFKEg5wcm9qZWN0QWRkcmVzcxoRCgJhSxILc3RhcnRIZWlnaHQaDgoCYUwSCGR1cmF0aW9uGg4KAmFNEghidXlUb2tlbhoQCgJhThIKY29tbWlzc2lvbhoVCgJhTxIPdG9rZW5zUGVyVGlja2V0GhMKAmFQEg1wcmljZVBlclRva2VuGhkKAmFREhNzd29wZmlUaWNrZXRzQW1vdW50GhoKAmFSEhRjYW1wYWlnblRva2Vuc0Ftb3VudBoZCgJhUxITdG9rZW5zUGVyQWxsb2NhdGlvbhoTCgJhVBINc3dvcFBlclRpY2tldBoYCgJhVRISc3dvcEZyZWV6ZUR1cmF0aW9uGhEKAmFWEgtjbGFpbVBhcmFtcxoZCgJhVxITSGlnaENvbXBldGl0aW9uU2FsZRoeCgJhWBIYaGlnaENvbXBldGl0aW9uQ29taXNzaW9uGiIKAmFZEhxoaWdoQ29tcGV0aXRpb25UaWNrZXRzQW1vdW50GhsKAmFaEhVmcmVlemVBZGRpdGlvbmFsVG9rZW4aIAoCYWESGmtleVVzZXJXaW5uZWRUaWNrZXRzQW1vdW50Gi8KAmFiEilrZXlVc2VyV2lubmVkSGlnaENvbXBldGl0aW9uVGlja2V0c0Ftb3VudBoYCgJhYxISa2V5VXNlckZyZWV6ZVRva2VuGgwKAmFkEgZvcmFjbGUaEAoCYWUSCmdvdmVybmFuY2UaFgoCYWYSEGNvbW1pc3Npb25XYWxsZXQaGAoCYWcSEnN0YWtpbmdVU0ROQWRkcmVzcxoKCgJhaBIEVVNEThoYCgJhaRISYWRtaW5QdWJLZXlTdGFraW5nGhoKAmFqEhRtYXhBbGxvY2F0aW9uc0Ftb3VudBoXCgJhaxIRYWN0aXZlTGF1bmNocGFkSWQaEQoCYWwSC2dldEFkbWluUHViGhEKAmFtEgtrZXlBZG1pblB1YhoNCgJhbhIHJG1hdGNoMBoMCgJhbxIGc3RyaW5nGg0KAmFwEgdub3RoaW5nGhIKAmFxEgxhZG1pblB1YktleTEaEgoCYXISDGFkbWluUHViS2V5MhoSCgJhcxIMYWRtaW5QdWJLZXkzGhIKAmF0EgxnZXRBc3NldEluZm8aDQoCYXUSB2Fzc2V0SWQaCAoCYXYSAmlkGg4KAmF3EghzdHJpbmdJZBoKCgJheBIEaW5mbxoLCgJheRIFd2F2ZXMaGAoCYXoSEmdldExhdW5jaHBhZE5leHRJZBoUCgFiEg9rZXlBZG1pblB1YktleTEaFAoCYkESDnRva2VuQXNzZXROYW1lGhMKAmJCEg10b2tlbkRlY2ltYWxzGhEKAmJDEgt0aWNrZXRQcmljZRoZCgJiRBITY29tbWlzc2lvblBlclRpY2tldBoVCgJiRRIPYnV5VGlja2V0QW1vdW50GhwKAmJGEhZhbGxvd2VkQnV5VGlja2V0QW1vdW50GiIKAmJHEhxhbGxvd2VkQnV5UHJpY2VXaXRoQ29taXNzaW9uGgwKAmJIEgZjaGFuZ2UaGgoCYkkSFGZyZWV6ZVRva2VuUGVyVGlja2V0GhMKAmJKEg0kdDAxMjQ5MTEyNTc4GhUKAmJLEg9wbXRBbW91bnRGcmVlemUaFgoCYkwSEHBtdEFzc2V0SWRGcmVlemUaEwoCYk0SDSR0MDEyNTk1MTI2ODYaGQoCYk4SE3BtdEZyZWV6ZVN0ckFzc2V0SWQaGAoCYk8SEnBtdEZyZWV6ZUFzc2V0TmFtZRoXCgJiUBIRcG10RnJlZXplRGVjaW1hbHMaFgoCYlESEG5lZWRGcmVlemVUb2tlbnMaHgoCYlISGHVzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxocCgJiUxIWbGFzdEJvdWdodFRpY2tldE51bWJlchoRCgJiVBILYm91Z2h0UmFuZ2UaIQoCYlUSG25ld1VzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxoJCgJiVhIDaW52Gg8KAmJXEgliYXNlRW50cnkaEwoCYlgSDSR0MDE0NzU3MTQ4MzIaEwoCYlkSDSR0MDE0ODM3MTQ5ODcaGQoCYloSE3VzZXJVc2RuSW5NYXJrZXRpbmcaEgoCYmESDGZyZWV6ZVBhcmFtcxoUCgJiYhIObGF1bmNocGFkSWRTdHIaEQoCYmMSCyR0MDYzNzg2NDUzGg8KAmJkEglwbXRBbW91bnQaEAoCYmUSCnBtdEFzc2V0SWQaEQoCYmYSCyR0MDY0NjI2NTM1GhMKAmJnEg1wbXRTdHJBc3NldElkGhIKAmJoEgxwbXRBc3NldE5hbWUaEQoCYmkSC3BtdERlY2ltYWxzGhsKAmJqEhVmcmVlemVBZGRpdGlvbmFsRW50cnkaCwoCYmsSBXJlZklkGhEKAmJsEgskdDA5MTQxOTIxNhoRCgJibRILJHQwOTIyMTkzNzEaEAoCYm4SCmJ1eUFzc2V0SWQaEwoCYm8SDWJ1eUFzc2V0U3RySWQaEgoCYnASDGJ1eUFzc2V0TmFtZRoWCgJicRIQYnV5QXNzZXREZWNpbWFscxoRCgJichILc3Rha2VkU3dvcHMaHQoCYnMSF2FsbG93ZWRUaWNrZXRzQW1vdW50QWxsGhkKAmJ0EhNib3VnaHRUaWNrZXRzQW1vdW50GhoKAmJ1EhRhbGxvd2VkVGlja2V0c0Ftb3VudBoTCgJidhINZnJlZXplVG9rZW5JZBoQCgJidxIKdG9rZW5QcmljZRoTCgJieBINJHQwMTExODMxMTMyNxoNCgJieRIHdG9rZW5JZBoVCgJiehIPdG9rZW5TdHJBc3NldElkGhQKAWMSD2tleUFkbWluUHViS2V5MhoVCgJjQRIPYm91Z2h0SENUaWNrZXRzGhUKAmNCEg91c2VyQ2xhaW1TdGF0dXMaFAoCY0MSDmZpbmFsaXplSGVpZ2h0GhMKAmNEEg0kdDAyNTM4ODI1NTM4GhMKAmNFEg13b25uZWRUaWNrZXRzGhUKAmNGEg93b25uZWRIQ1RpY2tldHMaGgoCY0cSFGF3YWlsYWJsZUFsbG9jYXRpb25zGhgKAmNIEhJhbGxvd2VkQWxsb2NhdGlvbnMaEwoCY0kSDSR0MDI2NDQ0MjY1ODgaGgoCY0oSFHRyYW5zZmVyVG9rZW5zQW1vdW50GiEKAmNLEhtub3RBbGxvd2VkQWxsb2NhdGlvbnNUb2tlbnMaHAoCY0wSFmJ1eUFzc2V0Rm9yQWxsb2NhdGlvbnMaIAoCY00SGmJ1eUFzc2V0Rm9yVW53b25uZWRUaWNrZXRzGiIKAmNOEhxidXlBc3NldEZvckhDVW53b25uZWRUaWNrZXRzGhUKAmNPEg9jbGFpbWVkQnV5VG9rZW4aHAoCY1ASFnJldHVybmVkQnV5QXNzZXRBbW91bnQaFgoCY1ESEHRyYW5zZmVyQnV5QXNzZXQaEwoCY1ISDWNsYWltZWRQYXJhbXMaFAoCY1MSDnRyYW5zZmVyVG9rZW5zGhMKAmNUEg1jbGFpbWVkVG9rZW5zGhIKAmNVEgx1bmxvY2tQZXJpb2QaEQoCY1YSC2Jsb2NrSGVpZ2h0GhIKAmNXEgx1bmxvY2tIZWlnaHQaGQoCY1gSE2FsbG93ZWRUb2tlbnNBbW91bnQaFgoCY1kSEGNsYWltU3RhdHVzRW50cnkaFwoCY1oSEXVzZXJUb2tlbnNGcmVlemVkGhUKAmNhEg91c2RuSW5NYXJrZXRpbmcaFwoCY2ISEWJvdWdodEFsbG9jYXRpb25zGhMKAmNjEg0kdDAxNTY1NjE1ODAwGiIKAmNkEhxhbGxvY2F0aW9uUHJpY2VXaXRoQ29taXNzaW9uGhoKAmNlEhRidXlBbGxvY2F0aW9uc0Ftb3VudBoTCgJjZhINJHQwMTgwNTgxODEzMxoTCgJjZxINJHQwMTgxMzgxODI4OBobCgJjaBIVYm91Z2h0SENUaWNrZXRzQW1vdW50GhkKAmNpEhNoaWdoQ29tcGV0aXRpb25TYWxlGhMKAmNqEg0kdDAxOTQ2MTE5NjA1GhsKAmNrEhVidXlQcmljZVdpdGhDb21pc3Npb24aDwoCY2wSCXZyZkhlaWdodBoQCgJjbRIKc2VjcmV0V29yZBoPCgJjbhIJc2F2ZWRIYXNoGg4KAmNvEghjYWxjSGFzaBoTCgJjcBINJHQwMjIyMTgyMjM2OBoSCgJjcRIMY29tbWlzc2lvbkhDGhgKAmNyEhJ0cmFuc2ZlcmVkQnV5QXNzZXQaIQoCY3MSG3N3b3BmaU1lbWJlcnNCdXlBc3NldEFtb3VudBocCgJjdBIWc3dvcGZpSENCdXlBc3NldEFtb3VudBocCgJjdRIWc3dvcGZpTWVtYmVyc0NvbWlzc2lvbhoXCgJjdhIRc3dvcGZpSENDb21pc3Npb24aJAoCY3cSHnRvdGFsQW1vdW50QnV5QXNzZXRJbk1hcmtldGluZxoYCgJjeBISbWFya2V0aW5nQ29taXNzaW9uGhMKAmN5Eg11bnN0YWtlQW1vdW50GhMKAmN6Eg1ib3VnaHRUaWNrZXRzGhQKAWQSD2tleUFkbWluUHViS2V5MxoZCgJkYRITZnJlZXplVG9rZW5EdXJhdGlvbhoUCgJkYhIOYmxvY2tFbmRIZWlnaHQaDAoCZGMSBmFtb3VudBoTCgJkZBINJHQwMzI3MTUzMjg2NRoICgJkZRICdHgaDAoCZGYSBnZlcmlmeRoZCgJkZxITbXVsdGlTaWduZWRCeUFkbWlucxoYCgJkaBISYWRtaW5QdWJLZXkxU2lnbmVkGhgKAmRpEhJhZG1pblB1YktleTJTaWduZWQaGAoCZGoSEmFkbWluUHViS2V5M1NpZ25lZBoTCgJkaxINc2lnbmVkQnlBZG1pbhoJCgJkbBIDZHR4GiYKAWUSIWtleUxhdW5jaHBhZERhdGFUcmFuc2FjdGlvblN0YXR1cxoXCgFmEhJrZXlMYXVuY2hwYWROZXh0SWQaGQoBZxIUa2V5TGF1bmNocGFkQWN0aXZlSWQaEgoBaBINa2V5SW5pdENhbGxlchoPCgFpEgprZXlBZGRyZXNzGhIKAWoSDWtleUluaXRIZWlnaHQaEwoBaxIOa2V5U3RhcnRIZWlnaHQaFgoBbBIRa2V5RmluYWxpc2VIZWlnaHQaEQoBbRIMa2V5Q29taXNzaW9uGg8KAW4SCmtleUFzc2V0SWQaGAoBbxITa2V5VG90YWxUb2tlbkFtb3VudBofCgFwEhprZXlUb3RhbEFtb3VudEJ1eUFzc2V0U29sZBoXCgFxEhJrZXlUb2tlbnNQZXJUaWNrZXQaFQoBchIQa2V5UHJpY2VQZXJUb2tlbhoVCgFzEhBrZXlTd29wUGVyVGlja2V0GhsKAXQSFmtleVN3b3BmaVRpY2tldHNBbW91bnQaHAoBdRIXa2V5Q2FtcGFpZ25Ub2tlbnNBbW91bnQaGwoBdhIWa2V5VG9rZW5zUGVyQWxsb2NhdGlvbhoYCgF3EhNrZXlUaWNrZXRMYXN0TnVtYmVyGhgKAXgSE2tleUdvdmVybmFuY2VTdGFrZWQaEQoBeRIMa2V5VXNlclJlZklkGhIKAXoSDWtleVZlcmlmeUhhc2gAAABJAAAAAAFhAgAAAAZhY3RpdmUAAAAAAWICAAAAC2FkbWluX3B1Yl8xAAAAAAFjAgAAAAthZG1pbl9wdWJfMgAAAAABZAIAAAALYWRtaW5fcHViXzMAAAAAAWUCAAAAIWxhdW5jaHBhZF9kYXRhX3RyYW5zYWN0aW9uX3N0YXR1cwAAAAABZgIAAAARbGF1bmNocGFkX25leHRfaWQAAAAAAWcCAAAAE2xhdW5jaHBhZF9hY3RpdmVfaWQAAAAAAWgCAAAAC2luaXRfY2FsbGVyAAAAAAFpAgAAAAhfYWRkcmVzcwAAAAABagIAAAAMX2luaXRfaGVpZ2h0AAAAAAFrAgAAAA1fc3RhcnRfaGVpZ2h0AAAAAAFsAgAAABBfZmluYWxpc2VfaGVpZ2h0AAAAAAFtAgAAAApfY29taXNzaW9uAAAAAAFuAgAAAAlfYXNzZXRfaWQAAAAAAW8CAAAAE190b3RhbF90b2tlbl9hbW91bnQAAAAAAXACAAAAFV90b3RhbF9idXlfYXNzZXRfc29sZAAAAAABcQIAAAASX3Rva2Vuc19wZXJfdGlja2V0AAAAAAFyAgAAABBfcHJpY2VfcGVyX3Rva2VuAAAAAAFzAgAAABBfc3dvcF9wZXJfdGlja2V0AAAAAAF0AgAAABdfdGlja2V0c19zd29wZmlfbWVtYmVycwAAAAABdQIAAAATX3Rva2Vuc19hY2Nlc3NfbGlzdAAAAAABdgIAAAAWX3Rva2Vuc19wZXJfYWxsb2NhdGlvbgAAAAABdwIAAAATX3RpY2tldF9sYXN0X251bWJlcgAAAAABeAIAAAAMX1NXT1BfYW1vdW50AAAAAAF5AgAAAAdfcmVmX2lkAAAAAAF6AgAAAAxfdmVyaWZ5X2hhc2gAAAAAAUECAAAACV9kdXJhdGlvbgAAAAABQgIAAAAnX3RvdGFsX3B1cmNoYXNlZF9idXlfYXNzZXRfaW5fbWFya2V0aW5nAAAAAAFDAgAAADFfdG90YWxfcHVyY2hhc2VkX2J1eV9hc3NldF9pbl9tYXJrZXRpbmdfZmluYWxpemVkAAAAAAFEAgAAABNfdHJhbnNmZXJfYnV5X2Fzc2V0AAAAAAFFAgAAABVfZnJlZXplX3N3b3BfZHVyYXRpb24AAAAAAUYCAAAAGF9mcmVlemVfYWRkaXRpb25hbF90b2tlbgAAAAABRwIAAAAQX2ZyZWV6ZV90b2tlbl9pZAAAAAABSAIAAAAWX2ZyZWV6ZV90b2tlbl9kdXJhdGlvbgAAAAABSQIAAAAYX2ZyZWV6ZV90b2tlbl9wZXJfdGlja2V0AAAAAAFKAgAAAApfYnV5X3Rva2VuAAAAAAFLAgAAAA1fY2xhaW1fcGFyYW1zAAAAAAFMAgAAABtfaGlnaF9jb21wZXRpdGlvbl9jb21pc3Npb24AAAAAAU0CAAAAFl9oaWdoX2NvbXBldGl0aW9uX3NhbGUAAAAAAU4CAAAAJF9oaWdoX2NvbXBldGl0aW9uX3RpY2tldF9sYXN0X251bWJlcgAAAAABTwIAAAAZX3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABUAIAAAAmX3RvdGFsX2J1eV9hc3NldF9zb2xkX2hpZ2hfY29tcGV0aXRpb24AAAAAAVECAAAAD19jbGFpbWVkX3Rva2VucwAAAAABUgIAAAATX2NsYWltZWRfYnV5X3Rva2VucwAAAAABUwIAAAAPX2JvdWdodF90aWNrZXRzAAAAAAFUAgAAAA9fdGlja2V0c19udW1iZXIAAAAAAVUCAAAAIF90aWNrZXRzX251bWJlcl9oaWdoX2NvbXBldGl0aW9uAAAAAAFWAgAAACBfYm91Z2h0X3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABVwIAAAAdX2F2YWlsYWJsZV9wdXJjaGFzZV9tYXJrZXRpbmcAAAAAAVgCAAAAIV9wdXJjaGFzZWRfYnV5X2Fzc2V0X2luX21hcmtldGluZwAAAAABWQIAAAATX2JvdWdodF9hbGxvY2F0aW9ucwAAAAABWgIAAAANX2NsYWltX3N0YXR1cwAAAAACYWECAAAAD190aWNrZXRzX3Jlc3VsdAAAAAACYWICAAAAIF90aWNrZXRzX3Jlc3VsdF9oaWdoX2NvbXBldGl0aW9uAAAAAAJhYwIAAAAUX2ZyZWV6ZV90b2tlbl9hbW91bnQAAAAAAmFkCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFXiv8IaJo1ukDNYXTyEjfepjfw+jjO6B44AAAAAAJhZQkBAAAAB0FkZHJlc3MAAAABAQAAABoBV8lXnLdvepYMywgiOQ98homAomzcs7cW7QAAAAACYWYJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVegUacv8D0ifMW13zGCSpt04Dz5KjCC4WcAAAAAAmFnCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFX5A6nNk+SC9eXz6QdPzUbz0Nq66o883GdAAAAAAJhaAEAAAAgtiYpwwT1zlORpA5LdSQvZIxRsfrf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", "height": 2910566, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3P5pp2hbwwejNCocneUzaq4gPkJ65pU145bCrLXfQtMG Next: 8SSa5rfA5Hsayc7PUVDwxEGJdwD4VKeKfNAj7cZ4QiiF Diff:
OldNewDifferences
4545
4646 let keyTokensPerAllocation = "_tokens_per_allocation"
4747
48-let keyTicketLastNumber = "_ticket_last_number_high_competition"
48+let keyTicketLastNumber = "_ticket_last_number"
4949
5050 let keyGovernanceStaked = "_SWOP_amount"
5151
107107
108108 let keyUserWinnedTicketsAmount = "_tickets_result"
109109
110+let keyUserWinnedHighCompetitionTicketsAmount = "_tickets_result_high_competition"
111+
110112 let keyUserFreezeToken = "_freeze_token_amount"
111113
112114 let oracle = Address(base58'3PEbqViERCoKnmcSULh6n2aiMvUdSQdCsom')
122124 let adminPubKeyStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
123125
124126 let maxAllocationsAmount = 2
125-
126-let isActive = valueOrElse(getBoolean(this, keyActive), true)
127127
128128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
129129
156156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
157157
158158
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")
169+
170+
159171 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
160172 then $Tuple4(unit, "WAVES", "WAVES", 8)
161173 else {
167179
168180
169181 @Callable(i)
170-func hashingRandom (launchpadId,hash) = if (!(isActive))
171- then throw("DApp is inactive at this moment")
172- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
173- then throw("Only admin can call this function")
174- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
175183
176184
177185
178186 @Callable(i)
179-func initCaller (address) = if (!(isActive))
180- then throw("DApp is inactive at this moment")
181- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
182- then throw("Only admin can call this function")
183- else [StringEntry(keyInitCaller, address)]
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
184188
185189
186190
187191 @Callable(i)
188-func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = if (!(isActive))
189- then throw("DApp is inactive at this moment")
190- else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
191- then throw("Only project admin can call init function")
192- else if ((size(i.payments) != 1))
193- then throw("One attached payment expected")
194- else if ((height > startHeight))
195- then throw("Start height must be greater than blockchain height")
196- else if (if (freezeAdditionalToken)
197- then (size(freezeParams) != 3)
198- else false)
199- then throw("Freeze params list must have 3 items")
200- else {
201- let launchpadId = getLaunchpadNextId()
202- let launchpadIdStr = toString(launchpadId)
203- let $t065486623 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
204- let pmtAmount = $t065486623._1
205- let pmtAssetId = $t065486623._2
206- let $t066326705 = getAssetInfo(pmtAssetId)
207- let pmtStrAssetId = $t066326705._1
208- let pmtAssetName = $t066326705._2
209- let pmtDecimals = $t066326705._3
210- let freezeAdditionalEntry = if (freezeAdditionalToken)
211- then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
212- else nil
213- ([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)
214- }
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 $t063786453 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063786453._1
207+ let pmtAssetId = $t063786453._2
208+ let $t064626535 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064626535._1
210+ let pmtAssetName = $t064626535._2
211+ let pmtDecimals = $t064626535._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+ })
215217
216218
217219
218220 @Callable(i)
219-func commitSwopfiSale (launchpadId,refId) = {
220- let $t092879362 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
221- let pmtAmount = $t092879362._1
222- let pmtAssetId = $t092879362._2
223- let $t093679517 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
224- let buyAssetId = $t093679517._1
225- let buyAssetStrId = $t093679517._2
226- let buyAssetName = $t093679517._3
227- let buyAssetDecimals = $t093679517._4
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091419216 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091419216._1
224+ let pmtAssetId = $t091419216._2
225+ let $t092219371 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092219371._1
227+ let buyAssetStrId = $t092219371._2
228+ let buyAssetName = $t092219371._3
229+ let buyAssetDecimals = $t092219371._4
228230 let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
229231 let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
230232 let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
232234 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
233235 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
234236 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
235- if (!(isActive))
236- then throw("DApp is inactive at this moment")
237- else 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))
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))
245251 then true
246252 else (pmtAssetId != buyAssetId)
247253 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))
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 $t01118311327 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01118311327._1
267+ let tokenStrAssetId = $t01118311327._2
268+ let tokenAssetName = $t01118311327._3
269+ let tokenDecimals = $t01118311327._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 $t01249112578 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01249112578._1
287+ let pmtAssetIdFreeze = $t01249112578._2
288+ let $t01259512686 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01259512686._1
290+ let pmtFreezeAssetName = $t01259512686._2
291+ let pmtFreezeDecimals = $t01259512686._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+ }
257318 }
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 $t01140511549 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266- let tokenId = $t01140511549._1
267- let tokenStrAssetId = $t01140511549._2
268- let tokenAssetName = $t01140511549._3
269- let tokenDecimals = $t01140511549._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 $t01271312800 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286- let pmtAmountFreeze = $t01271312800._1
287- let pmtAssetIdFreeze = $t01271312800._2
288- let $t01281712908 = getAssetInfo(pmtAssetId)
289- let pmtFreezeStrAssetId = $t01281712908._1
290- let pmtFreezeAssetName = $t01281712908._2
291- let pmtFreezeDecimals = $t01281712908._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- }
319+ })
320320
321321
322322
323323 @Callable(i)
324-func commitAccessListSale (launchpadId,refId) = {
325- let $t01495515030 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326- let pmtAmount = $t01495515030._1
327- let pmtAssetId = $t01495515030._2
328- let $t01503515185 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329- let buyAssetId = $t01503515185._1
330- let buyAssetStrId = $t01503515185._2
331- let buyAssetName = $t01503515185._3
332- let buyAssetDecimals = $t01503515185._4
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01475714832 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01475714832._1
327+ let pmtAssetId = $t01475714832._2
328+ let $t01483714987 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01483714987._1
330+ let buyAssetStrId = $t01483714987._2
331+ let buyAssetName = $t01483714987._3
332+ let buyAssetDecimals = $t01483714987._4
333333 let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334334 let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
335335 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
336336 let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
337337 let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
338338 let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
339- let $t01585415998 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340- let tokenId = $t01585415998._1
341- let tokenStrAssetId = $t01585415998._2
342- let tokenAssetName = $t01585415998._3
343- let tokenDecimals = $t01585415998._4
339+ let $t01565615800 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01565615800._1
341+ let tokenStrAssetId = $t01565615800._2
342+ let tokenAssetName = $t01565615800._3
343+ let tokenDecimals = $t01565615800._4
344344 let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
345345 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
346346 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
347- if (!(isActive))
348- then throw("DApp is inactive at this moment")
349- else if ((activeLaunchpadId != launchpadId))
350- then throw("There is no active launchpad or this launchpad is ended")
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 $t01805818133 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01805818133._1
385+ let pmtAssetId = $t01805818133._2
386+ let $t01813818288 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01813818288._1
388+ let buyAssetStrId = $t01813818288._2
389+ let buyAssetName = $t01813818288._3
390+ let buyAssetDecimals = $t01813818288._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")
351399 else if ((startHeight > height))
352400 then throw("Launchpad sale not started yet")
353401 else if ((height > (startHeight + duration)))
356404 then true
357405 else (pmtAssetId != buyAssetId))
358406 then throw((("One attached payment in " + buyAssetName) + " expected"))
359- else if ((boughtAllocations >= maxAllocationsAmount))
360- then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
361- else if (if ((allocationPriceWithComission != pmtAmount))
362- then ((allocationPriceWithComission * 2) != pmtAmount)
363- else false)
364- then throw(((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + buyAssetName) + " per allocation"))
365- else {
366- let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
367- let inv = if ((buyAssetId == USDN))
368- then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
369- else 0
370- if ((inv == inv))
371- then {
372- 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))]
373- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
374- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
375- else baseEntry
376- }
377- else throw("Strict value is not equal to itself.")
378- }
379- }
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01946119605 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01946119605._1
412+ let tokenStrAssetId = $t01946119605._2
413+ let tokenAssetName = $t01946119605._3
414+ let tokenDecimals = $t01946119605._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+ })
380445
381446
382447
383448 @Callable(i)
384-func commitHighCompetitionSale (launchpadId,refId) = {
385- let $t01830718382 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
386- let pmtAmount = $t01830718382._1
387- let pmtAssetId = $t01830718382._2
388- let $t01838718537 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
389- let buyAssetId = $t01838718537._1
390- let buyAssetStrId = $t01838718537._2
391- let buyAssetName = $t01838718537._3
392- let buyAssetDecimals = $t01838718537._4
393- let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
394- let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
395- let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
396- let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
397- if (!(isActive))
398- then throw("DApp is inactive at this moment")
399- else if ((activeLaunchpadId != launchpadId))
400- then throw("There is no active launchpad or this launchpad is ended")
401- else if (!(highCompetitionSale))
402- then throw("There is no high competition sale for this launchpad")
403- else if ((startHeight > height))
404- then throw("Launchpad sale not started yet")
405- else if ((height > (startHeight + duration)))
406- then throw("Launchpad sale ended")
407- else if (if ((size(i.payments) != 1))
408- then true
409- else (pmtAssetId != buyAssetId))
410- then throw((("One attached payment in " + buyAssetName) + " expected"))
411- else {
412- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
413- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
414- let $t01978619930 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
415- let tokenId = $t01978619930._1
416- let tokenStrAssetId = $t01978619930._2
417- let tokenAssetName = $t01978619930._3
418- let tokenDecimals = $t01978619930._4
419- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
420- let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
421- let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
422- let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
423- let change = (pmtAmount - buyPriceWithComission)
424- if ((buyTicketAmount == 0))
425- then throw((("Not enought " + buyAssetName) + " to buy tickets"))
426- else if ((change != 0))
427- then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
428- else {
429- let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
430- let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
431- let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
432- let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
433- then ("," + boughtRange)
434- else ("" + boughtRange)))
435- let inv = if ((buyAssetId == USDN))
436- then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
437- else 0
438- if ((inv == inv))
439- then {
440- 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)]
441- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
442- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
443- else baseEntry
444- }
445- else throw("Strict value is not equal to itself.")
446- }
447- }
448- }
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 $t02221822368 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02221822368._1
457+ let buyAssetStrId = $t02221822368._2
458+ let buyAssetName = $t02221822368._3
459+ let buyAssetDecimals = $t02221822368._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+ }))
449483
450484
451485
452486 @Callable(i)
453-func finalise (launchpadId,vrfHeight,secretWord) = {
454- let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
455- let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
456- if (!(isActive))
457- then throw("DApp is inactive at this moment")
458- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
459- then throw("Only admin can call this function")
460- else if ((calcHash != savedHash))
461- then throw("vrf Height hash not matching")
462- else {
463- let $t02271522865 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
464- let buyAssetId = $t02271522865._1
465- let buyAssetStrId = $t02271522865._2
466- let buyAssetName = $t02271522865._3
467- let buyAssetDecimals = $t02271522865._4
468- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
469- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
470- let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
471- let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
472- let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
473- let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
474- let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
475- let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
476- let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
477- let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
478- let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
479- if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
480- then throw("Can't transfer negative value to project")
481- else {
482- let inv = if ((buyAssetId == USDN))
483- then invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
484- else 0
485- if ((inv == inv))
486- then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) - transferedBuyAsset), buyAssetId), ScriptTransfer(commissionWallet, ((swopfiMembersComission + marketingComission) + swopfiHCComission), buyAssetId)]
487- else throw("Strict value is not equal to itself.")
488- }
489- }
490- }
491-
492-
493-
494-@Callable(i)
495-func claim (launchpadId) = {
487+func claim (launchpadId) = valueOrElse(isActive(), {
496488 let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
497489 let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
498490 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
499491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
500492 let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
501- if (!(isActive))
502- then throw("DApp is inactive at this moment")
503- else if ((finalizeHeight == 0))
504- then throw("You can't claim because results are not finalized")
505- else if (userClaimStatus)
506- then throw("You are already claimed")
507- else if (if (if ((boughtTickets == 0))
508- then (boughtAllocations == 0)
509- else false)
510- then (boughtHCTickets == 0)
511- else false)
512- then throw("You can't claim because you don't buy anything")
513- else {
514- let $t02593526085 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
515- let buyAssetId = $t02593526085._1
516- let buyAssetStrId = $t02593526085._2
517- let buyAssetName = $t02593526085._3
518- let buyAssetDecimals = $t02593526085._4
519- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
520- let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
521- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
522- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
523- let allowedAllocations = min([boughtAllocations, awailableAllocations])
524- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
525- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
526- let $t02687427018 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
527- let tokenId = $t02687427018._1
528- let tokenStrAssetId = $t02687427018._2
529- let tokenAssetName = $t02687427018._3
530- let tokenDecimals = $t02687427018._4
531- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
532- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
533- let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
534- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
535- let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
536- let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
537- let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commission), 100)
538- let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
539- if (if (if ((0 > buyAssetForAllocations))
540- then true
541- else (0 > buyAssetForUnwonnedTickets))
542- then true
543- else (0 > buyAssetForHCUnwonnedTickets))
544- then throw("Error with allowed allocation param or wonned tickets param please contact support")
545- else {
546- let returnedBuyAssetAmount = ((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) - claimedBuyToken)
547- let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
548- then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
549- else nil
550- let inv = if (if ((returnedBuyAssetAmount > 0))
551- then (buyAssetId == USDN)
552- else false)
553- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
554- else 0
555- if ((inv == inv))
556- then {
557- let claimedParams = split(valueOrElse(getString(this, keyClaimParams), ""), ",")
558- if (if ((size(claimedParams) == 0))
559- then true
560- 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 $t02538825538 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02538825538._1
506+ let buyAssetStrId = $t02538825538._2
507+ let buyAssetName = $t02538825538._3
508+ let buyAssetDecimals = $t02538825538._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 $t02644426588 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02644426588._1
519+ let tokenStrAssetId = $t02644426588._2
520+ let tokenAssetName = $t02644426588._3
521+ let tokenDecimals = $t02644426588._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"))
561559 then {
562- let transferTokens = if ((transferTokensAmount > 0))
563- 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)]
564569 else nil
565- (([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")
566580 }
567- else if ((claimedParams[0] == "claimPeriod"))
568- then {
569- let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
570- let startAmount = value(parseInt(claimedParams[0]))
571- let unlockPeriod = value(parseInt(claimedParams[0]))
572- let blockHeight = (value(parseInt(claimedParams[0])) + finalizeHeight)
573- let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
574- let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[0])), 100) + (if ((height > blockHeight))
575- then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
576- else (0 - claimedTokens)))
577- let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
578- then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
579- else nil
580- if (if ((allowedTokensAmount > 0))
581- then true
582- else (returnedBuyAssetAmount > 0))
583- then {
584- let transferTokens = if ((allowedTokensAmount > 0))
585- then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
586- else nil
587- (transferBuyAsset ++ transferTokens)
588- }
589- else throw("Nothing to claim")
590- }
591- else throw("Error whith claim params: unknown function")
592- }
593- else throw("Strict value is not equal to itself.")
594- }
595- }
596- }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
597587
598588
599589
600590 @Callable(i)
601-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
602592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
603- if (!(isActive))
604- then throw("DApp is inactive at this moment")
605- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
606- then throw("You can't claim because results are not finalized")
607- else if (!(freezeAdditionalToken))
608- then throw("There are no additional token freezing for this launchpad")
609- else {
610- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
611- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
612- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
613- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
614- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
615- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
616- if ((userTokensFreezed == 0))
617- then throw("You are already claimed your tokens or not paid anything")
618- else if ((blockEndHeight > height))
619- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
620- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
621- }
622- }
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+ })
623611
624612
625613
626614 @Callable(i)
627-func transferBuyAsset (launchpadId,amount) = if (!(isActive))
628- then throw("DApp is inactive")
629- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
630- then throw("Only admin can call this function")
631- else {
632- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
633- let $t03341433564 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
634- let buyAssetId = $t03341433564._1
635- let buyAssetStrId = $t03341433564._2
636- let buyAssetName = $t03341433564._3
637- let buyAssetDecimals = $t03341433564._4
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03271532865 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03271532865._1
619+ let buyAssetStrId = $t03271532865._2
620+ let buyAssetName = $t03271532865._3
621+ let buyAssetDecimals = $t03271532865._4
638622 [IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
639- }
623+ }))
640624
641625
642626
643627 @Callable(i)
644-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
645629 then throw("DApp already inactive")
646- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
647- then throw("Only admin can call this function")
648- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
649631
650632
651633
652634 @Callable(i)
653-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
654636 then throw("DApp already active")
655- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
656- then throw("Only admin can call this function")
657- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
658638
659639
660640 @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
48-let keyTicketLastNumber = "_ticket_last_number_high_competition"
48+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
110+let keyUserWinnedHighCompetitionTicketsAmount = "_tickets_result_high_competition"
111+
110112 let keyUserFreezeToken = "_freeze_token_amount"
111113
112114 let oracle = Address(base58'3PEbqViERCoKnmcSULh6n2aiMvUdSQdCsom')
113115
114116 let governance = Address(base58'3PLHVWCqA9DJPDbadUofTohnCULLauiDWhS')
115117
116118 let commissionWallet = Address(base58'3PGYafJ2GuqPckmZNywet8moiPnBHz51Xdg')
117119
118120 let stakingUSDNAddress = Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ')
119121
120122 let USDN = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
121123
122124 let adminPubKeyStaking = base58'Czn4yoAuUZCVCLJDRfskn8URfkwpknwBTZDbs1wFrY7h'
123125
124126 let maxAllocationsAmount = 2
125-
126-let isActive = valueOrElse(getBoolean(this, keyActive), true)
127127
128128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
129129
130130 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
131131 case string: String =>
132132 fromBase58String(string)
133133 case nothing =>
134134 throw("Admin public key is empty")
135135 }
136136
137137
138138 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
139139
140140 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
141141
142142 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
143143
144144 func getAssetInfo (assetId) = match assetId {
145145 case id: ByteVector =>
146146 let stringId = toBase58String(id)
147147 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
148148 $Tuple3(stringId, info.name, info.decimals)
149149 case waves: Unit =>
150150 $Tuple3("WAVES", "WAVES", 8)
151151 case _ =>
152152 throw("Match error")
153153 }
154154
155155
156156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
157157
158158
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")
169+
170+
159171 func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
160172 then $Tuple4(unit, "WAVES", "WAVES", 8)
161173 else {
162174 let stringId = assetStr
163175 let id = fromBase58String(assetStr)
164176 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
165177 $Tuple4(id, stringId, info.name, info.decimals)
166178 }
167179
168180
169181 @Callable(i)
170-func hashingRandom (launchpadId,hash) = if (!(isActive))
171- then throw("DApp is inactive at this moment")
172- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
173- then throw("Only admin can call this function")
174- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
175183
176184
177185
178186 @Callable(i)
179-func initCaller (address) = if (!(isActive))
180- then throw("DApp is inactive at this moment")
181- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
182- then throw("Only admin can call this function")
183- else [StringEntry(keyInitCaller, address)]
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
184188
185189
186190
187191 @Callable(i)
188-func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = if (!(isActive))
189- then throw("DApp is inactive at this moment")
190- else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
191- then throw("Only project admin can call init function")
192- else if ((size(i.payments) != 1))
193- then throw("One attached payment expected")
194- else if ((height > startHeight))
195- then throw("Start height must be greater than blockchain height")
196- else if (if (freezeAdditionalToken)
197- then (size(freezeParams) != 3)
198- else false)
199- then throw("Freeze params list must have 3 items")
200- else {
201- let launchpadId = getLaunchpadNextId()
202- let launchpadIdStr = toString(launchpadId)
203- let $t065486623 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
204- let pmtAmount = $t065486623._1
205- let pmtAssetId = $t065486623._2
206- let $t066326705 = getAssetInfo(pmtAssetId)
207- let pmtStrAssetId = $t066326705._1
208- let pmtAssetName = $t066326705._2
209- let pmtDecimals = $t066326705._3
210- let freezeAdditionalEntry = if (freezeAdditionalToken)
211- then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
212- else nil
213- ([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)
214- }
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 $t063786453 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063786453._1
207+ let pmtAssetId = $t063786453._2
208+ let $t064626535 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064626535._1
210+ let pmtAssetName = $t064626535._2
211+ let pmtDecimals = $t064626535._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+ })
215217
216218
217219
218220 @Callable(i)
219-func commitSwopfiSale (launchpadId,refId) = {
220- let $t092879362 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
221- let pmtAmount = $t092879362._1
222- let pmtAssetId = $t092879362._2
223- let $t093679517 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
224- let buyAssetId = $t093679517._1
225- let buyAssetStrId = $t093679517._2
226- let buyAssetName = $t093679517._3
227- let buyAssetDecimals = $t093679517._4
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091419216 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091419216._1
224+ let pmtAssetId = $t091419216._2
225+ let $t092219371 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092219371._1
227+ let buyAssetStrId = $t092219371._2
228+ let buyAssetName = $t092219371._3
229+ let buyAssetDecimals = $t092219371._4
228230 let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
229231 let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
230232 let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
231233 let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
232234 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
233235 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
234236 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
235- if (!(isActive))
236- then throw("DApp is inactive at this moment")
237- else 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))
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))
245251 then true
246252 else (pmtAssetId != buyAssetId)
247253 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))
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 $t01118311327 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01118311327._1
267+ let tokenStrAssetId = $t01118311327._2
268+ let tokenAssetName = $t01118311327._3
269+ let tokenDecimals = $t01118311327._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 $t01249112578 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01249112578._1
287+ let pmtAssetIdFreeze = $t01249112578._2
288+ let $t01259512686 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01259512686._1
290+ let pmtFreezeAssetName = $t01259512686._2
291+ let pmtFreezeDecimals = $t01259512686._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+ }
257318 }
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 $t01140511549 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266- let tokenId = $t01140511549._1
267- let tokenStrAssetId = $t01140511549._2
268- let tokenAssetName = $t01140511549._3
269- let tokenDecimals = $t01140511549._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 $t01271312800 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286- let pmtAmountFreeze = $t01271312800._1
287- let pmtAssetIdFreeze = $t01271312800._2
288- let $t01281712908 = getAssetInfo(pmtAssetId)
289- let pmtFreezeStrAssetId = $t01281712908._1
290- let pmtFreezeAssetName = $t01281712908._2
291- let pmtFreezeDecimals = $t01281712908._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- }
319+ })
320320
321321
322322
323323 @Callable(i)
324-func commitAccessListSale (launchpadId,refId) = {
325- let $t01495515030 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326- let pmtAmount = $t01495515030._1
327- let pmtAssetId = $t01495515030._2
328- let $t01503515185 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329- let buyAssetId = $t01503515185._1
330- let buyAssetStrId = $t01503515185._2
331- let buyAssetName = $t01503515185._3
332- let buyAssetDecimals = $t01503515185._4
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01475714832 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01475714832._1
327+ let pmtAssetId = $t01475714832._2
328+ let $t01483714987 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01483714987._1
330+ let buyAssetStrId = $t01483714987._2
331+ let buyAssetName = $t01483714987._3
332+ let buyAssetDecimals = $t01483714987._4
333333 let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334334 let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
335335 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
336336 let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
337337 let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
338338 let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
339- let $t01585415998 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340- let tokenId = $t01585415998._1
341- let tokenStrAssetId = $t01585415998._2
342- let tokenAssetName = $t01585415998._3
343- let tokenDecimals = $t01585415998._4
339+ let $t01565615800 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01565615800._1
341+ let tokenStrAssetId = $t01565615800._2
342+ let tokenAssetName = $t01565615800._3
343+ let tokenDecimals = $t01565615800._4
344344 let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
345345 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
346346 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
347- if (!(isActive))
348- then throw("DApp is inactive at this moment")
349- else if ((activeLaunchpadId != launchpadId))
350- then throw("There is no active launchpad or this launchpad is ended")
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 $t01805818133 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01805818133._1
385+ let pmtAssetId = $t01805818133._2
386+ let $t01813818288 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01813818288._1
388+ let buyAssetStrId = $t01813818288._2
389+ let buyAssetName = $t01813818288._3
390+ let buyAssetDecimals = $t01813818288._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")
351399 else if ((startHeight > height))
352400 then throw("Launchpad sale not started yet")
353401 else if ((height > (startHeight + duration)))
354402 then throw("Launchpad sale ended")
355403 else if (if ((size(i.payments) != 1))
356404 then true
357405 else (pmtAssetId != buyAssetId))
358406 then throw((("One attached payment in " + buyAssetName) + " expected"))
359- else if ((boughtAllocations >= maxAllocationsAmount))
360- then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
361- else if (if ((allocationPriceWithComission != pmtAmount))
362- then ((allocationPriceWithComission * 2) != pmtAmount)
363- else false)
364- then throw(((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + buyAssetName) + " per allocation"))
365- else {
366- let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
367- let inv = if ((buyAssetId == USDN))
368- then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
369- else 0
370- if ((inv == inv))
371- then {
372- 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))]
373- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
374- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
375- else baseEntry
376- }
377- else throw("Strict value is not equal to itself.")
378- }
379- }
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01946119605 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01946119605._1
412+ let tokenStrAssetId = $t01946119605._2
413+ let tokenAssetName = $t01946119605._3
414+ let tokenDecimals = $t01946119605._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+ })
380445
381446
382447
383448 @Callable(i)
384-func commitHighCompetitionSale (launchpadId,refId) = {
385- let $t01830718382 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
386- let pmtAmount = $t01830718382._1
387- let pmtAssetId = $t01830718382._2
388- let $t01838718537 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
389- let buyAssetId = $t01838718537._1
390- let buyAssetStrId = $t01838718537._2
391- let buyAssetName = $t01838718537._3
392- let buyAssetDecimals = $t01838718537._4
393- let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
394- let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
395- let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
396- let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
397- if (!(isActive))
398- then throw("DApp is inactive at this moment")
399- else if ((activeLaunchpadId != launchpadId))
400- then throw("There is no active launchpad or this launchpad is ended")
401- else if (!(highCompetitionSale))
402- then throw("There is no high competition sale for this launchpad")
403- else if ((startHeight > height))
404- then throw("Launchpad sale not started yet")
405- else if ((height > (startHeight + duration)))
406- then throw("Launchpad sale ended")
407- else if (if ((size(i.payments) != 1))
408- then true
409- else (pmtAssetId != buyAssetId))
410- then throw((("One attached payment in " + buyAssetName) + " expected"))
411- else {
412- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
413- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
414- let $t01978619930 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
415- let tokenId = $t01978619930._1
416- let tokenStrAssetId = $t01978619930._2
417- let tokenAssetName = $t01978619930._3
418- let tokenDecimals = $t01978619930._4
419- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
420- let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
421- let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
422- let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
423- let change = (pmtAmount - buyPriceWithComission)
424- if ((buyTicketAmount == 0))
425- then throw((("Not enought " + buyAssetName) + " to buy tickets"))
426- else if ((change != 0))
427- then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
428- else {
429- let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
430- let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
431- let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
432- let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
433- then ("," + boughtRange)
434- else ("" + boughtRange)))
435- let inv = if ((buyAssetId == USDN))
436- then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
437- else 0
438- if ((inv == inv))
439- then {
440- 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)]
441- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
442- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
443- else baseEntry
444- }
445- else throw("Strict value is not equal to itself.")
446- }
447- }
448- }
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 $t02221822368 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02221822368._1
457+ let buyAssetStrId = $t02221822368._2
458+ let buyAssetName = $t02221822368._3
459+ let buyAssetDecimals = $t02221822368._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+ }))
449483
450484
451485
452486 @Callable(i)
453-func finalise (launchpadId,vrfHeight,secretWord) = {
454- let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
455- let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
456- if (!(isActive))
457- then throw("DApp is inactive at this moment")
458- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
459- then throw("Only admin can call this function")
460- else if ((calcHash != savedHash))
461- then throw("vrf Height hash not matching")
462- else {
463- let $t02271522865 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
464- let buyAssetId = $t02271522865._1
465- let buyAssetStrId = $t02271522865._2
466- let buyAssetName = $t02271522865._3
467- let buyAssetDecimals = $t02271522865._4
468- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
469- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
470- let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
471- let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
472- let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
473- let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
474- let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
475- let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
476- let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
477- let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
478- let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
479- if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
480- then throw("Can't transfer negative value to project")
481- else {
482- let inv = if ((buyAssetId == USDN))
483- then invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
484- else 0
485- if ((inv == inv))
486- then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) - transferedBuyAsset), buyAssetId), ScriptTransfer(commissionWallet, ((swopfiMembersComission + marketingComission) + swopfiHCComission), buyAssetId)]
487- else throw("Strict value is not equal to itself.")
488- }
489- }
490- }
491-
492-
493-
494-@Callable(i)
495-func claim (launchpadId) = {
487+func claim (launchpadId) = valueOrElse(isActive(), {
496488 let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
497489 let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
498490 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
499491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
500492 let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
501- if (!(isActive))
502- then throw("DApp is inactive at this moment")
503- else if ((finalizeHeight == 0))
504- then throw("You can't claim because results are not finalized")
505- else if (userClaimStatus)
506- then throw("You are already claimed")
507- else if (if (if ((boughtTickets == 0))
508- then (boughtAllocations == 0)
509- else false)
510- then (boughtHCTickets == 0)
511- else false)
512- then throw("You can't claim because you don't buy anything")
513- else {
514- let $t02593526085 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
515- let buyAssetId = $t02593526085._1
516- let buyAssetStrId = $t02593526085._2
517- let buyAssetName = $t02593526085._3
518- let buyAssetDecimals = $t02593526085._4
519- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
520- let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
521- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
522- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
523- let allowedAllocations = min([boughtAllocations, awailableAllocations])
524- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
525- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
526- let $t02687427018 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
527- let tokenId = $t02687427018._1
528- let tokenStrAssetId = $t02687427018._2
529- let tokenAssetName = $t02687427018._3
530- let tokenDecimals = $t02687427018._4
531- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
532- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
533- let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
534- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
535- let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
536- let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
537- let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commission), 100)
538- let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
539- if (if (if ((0 > buyAssetForAllocations))
540- then true
541- else (0 > buyAssetForUnwonnedTickets))
542- then true
543- else (0 > buyAssetForHCUnwonnedTickets))
544- then throw("Error with allowed allocation param or wonned tickets param please contact support")
545- else {
546- let returnedBuyAssetAmount = ((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) - claimedBuyToken)
547- let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
548- then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
549- else nil
550- let inv = if (if ((returnedBuyAssetAmount > 0))
551- then (buyAssetId == USDN)
552- else false)
553- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
554- else 0
555- if ((inv == inv))
556- then {
557- let claimedParams = split(valueOrElse(getString(this, keyClaimParams), ""), ",")
558- if (if ((size(claimedParams) == 0))
559- then true
560- 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 $t02538825538 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02538825538._1
506+ let buyAssetStrId = $t02538825538._2
507+ let buyAssetName = $t02538825538._3
508+ let buyAssetDecimals = $t02538825538._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 $t02644426588 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02644426588._1
519+ let tokenStrAssetId = $t02644426588._2
520+ let tokenAssetName = $t02644426588._3
521+ let tokenDecimals = $t02644426588._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"))
561559 then {
562- let transferTokens = if ((transferTokensAmount > 0))
563- 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)]
564569 else nil
565- (([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")
566580 }
567- else if ((claimedParams[0] == "claimPeriod"))
568- then {
569- let claimedTokens = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens)), 0)
570- let startAmount = value(parseInt(claimedParams[0]))
571- let unlockPeriod = value(parseInt(claimedParams[0]))
572- let blockHeight = (value(parseInt(claimedParams[0])) + finalizeHeight)
573- let unlockHeight = ((unlockPeriod + finalizeHeight) + blockHeight)
574- let allowedTokensAmount = (fraction(transferTokensAmount, value(parseInt(claimedParams[0])), 100) + (if ((height > blockHeight))
575- then fraction(transferTokensAmount, (height - blockHeight), unlockPeriod)
576- else (0 - claimedTokens)))
577- let claimStatusEntry = if ((transferTokensAmount >= (claimedTokens + allowedTokensAmount)))
578- then [BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)]
579- else nil
580- if (if ((allowedTokensAmount > 0))
581- then true
582- else (returnedBuyAssetAmount > 0))
583- then {
584- let transferTokens = if ((allowedTokensAmount > 0))
585- then [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), (claimedTokens + allowedTokensAmount)), ScriptTransfer(i.caller, allowedTokensAmount, tokenId)]
586- else nil
587- (transferBuyAsset ++ transferTokens)
588- }
589- else throw("Nothing to claim")
590- }
591- else throw("Error whith claim params: unknown function")
592- }
593- else throw("Strict value is not equal to itself.")
594- }
595- }
596- }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
597587
598588
599589
600590 @Callable(i)
601-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
602592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
603- if (!(isActive))
604- then throw("DApp is inactive at this moment")
605- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
606- then throw("You can't claim because results are not finalized")
607- else if (!(freezeAdditionalToken))
608- then throw("There are no additional token freezing for this launchpad")
609- else {
610- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
611- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
612- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
613- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
614- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
615- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
616- if ((userTokensFreezed == 0))
617- then throw("You are already claimed your tokens or not paid anything")
618- else if ((blockEndHeight > height))
619- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
620- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
621- }
622- }
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+ })
623611
624612
625613
626614 @Callable(i)
627-func transferBuyAsset (launchpadId,amount) = if (!(isActive))
628- then throw("DApp is inactive")
629- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
630- then throw("Only admin can call this function")
631- else {
632- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
633- let $t03341433564 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
634- let buyAssetId = $t03341433564._1
635- let buyAssetStrId = $t03341433564._2
636- let buyAssetName = $t03341433564._3
637- let buyAssetDecimals = $t03341433564._4
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03271532865 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03271532865._1
619+ let buyAssetStrId = $t03271532865._2
620+ let buyAssetName = $t03271532865._3
621+ let buyAssetDecimals = $t03271532865._4
638622 [IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
639- }
623+ }))
640624
641625
642626
643627 @Callable(i)
644-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
645629 then throw("DApp already inactive")
646- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
647- then throw("Only admin can call this function")
648- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
649631
650632
651633
652634 @Callable(i)
653-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
654636 then throw("DApp already active")
655- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
656- then throw("Only admin can call this function")
657- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
658638
659639
660640 @Verifier(tx)
661641 func verify () = {
662642 let multiSignedByAdmins = {
663643 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
664644 then 1
665645 else 0
666646 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
667647 then 1
668648 else 0
669649 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
670650 then 1
671651 else 0
672652 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
673653 }
674654 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
675655 then true
676656 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
677657 then true
678658 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
679659 then true
680660 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
681661 match tx {
682662 case dtx: DataTransaction =>
683663 if (valueOrElse(getBoolean(oracle, keyLaunchpadDataTransactionStatus), false))
684664 then signedByAdmin
685665 else false
686666 case _ =>
687667 multiSignedByAdmins
688668 }
689669 }
690670

github/deemru/w8io/6500d08 
121.51 ms