tx · 88GZgHh8B3tXQXd7u5tT99MrpbkAxt5Chsk9JVqd27iF

3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg:  -0.01400000 Waves

2022.01.19 15:58 [1885841] smart account 3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg > SELF 0.00000000 Waves

{ "type": 13, "id": "88GZgHh8B3tXQXd7u5tT99MrpbkAxt5Chsk9JVqd27iF", "fee": 1400000, "feeAssetId": null, "timestamp": 1642597070197, "version": 2, "chainId": 84, "sender": "3MzDGFvPnXVbA4wCacqcVnfVJPwG952KVAg", "senderPublicKey": "CViCXhHrygDDAtVc1uFczxe6ANj9tBz5PGQDS1yWZqgy", "proofs": [ "3yMEbjBbuPKCnQH3zn7dR7bUL1iooarGChZXvd3TGEUmGKKNTqNkqSMgPAJhxK9oH6WXLThhQzbtF5v1qcdbGSw9", "5xFxT9jNKGYPfkp5yp2etb3ruXoQ1PVXQaEqQfGJtm5c14jGbaavLSxAkUpwWYiffpmGR6bSUyWEFRLcCuCiMkqF" ], "script": "base64:AAIFAAAAAAAAFIIIAhIECgIBCBIDCgEIEhQKEggBAQgBAQEBAQEBARgEAQEEGBIECgIBCBIECgIBCBIECgIBCBIFCgMBAQgSAwoBARIDCgEBEgQKAgEBEgASABoQCgFBEgtrZXlEdXJhdGlvbhohCgFCEhxrZXlBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGioKAUMSJWtleUFtb3VudEJ1eUFzc2V0SW5NYXJrZXRpbmdGaW5hbGl6ZWQaGAoBRBITa2V5VHJhbnNmZXJCdXlBc3NldBoZCgFFEhRrZXlGcmVlelN3b3BEdXJhdGlvbhodCgFGEhhrZXlGcmVlemVBZGRpdGlvbmFsVG9rZW4aFQoBRxIQa2V5RnJlZXplVG9rZW5JZBobCgFIEhZrZXlGcmVlemVUb2tlbkR1cmF0aW9uGhwKAUkSF2tleUZyZWV6ZVRva2VuUGVyVGlja2V0GhAKAUoSC2tleUJ1eVRva2VuGhMKAUsSDmtleUNsYWltUGFyYW1zGiAKAUwSG2tleUhpZ2hDb21wZXRpdGlvbkNvbWlzc2lvbhobCgFNEhZrZXlIaWdoQ29tcGV0aXRpb25TYWxlGhoKAU4SFWtleUhDVGlja2V0TGFzdE51bWJlchodCgFPEhhrZXlIaWdoQ29tcGV0aXRpb25BbW91bnQaIQoBUBIca2V5VG90YWxBbW91bnRCdXlBc3NldFNvbGRIQxoZCgFREhRrZXlVc2VyQ2xhaW1lZFRva2VucxocCgFSEhdrZXlVc2VyQ2xhaW1lZEJ1eVRva2VucxofCgFTEhprZXlVc2VyQm91Z2h0VGlja2V0c0Ftb3VudBoTCgFUEg5rZXlVc2VyVGlja2V0cxoVCgFVEhBrZXlVc2VySENUaWNrZXRzGiEKAVYSHGtleVVzZXJIQ0JvdWdodFRpY2tldHNBbW91bnQaIAoBVxIba2V5VXNlckF2YWlsYWJsZUFsbG9jYXRpb25zGiUKAVgSIGtleVVzZXJBbW91bnRCdXlBc3NldEluTWFya2V0aW5nGh0KAVkSGGtleVVzZXJCb3VnaHRBbGxvY2F0aW9ucxoXCgFaEhJrZXlVc2VyQ2xhaW1TdGF0dXMaDgoBYRIJa2V5QWN0aXZlGgwKAmFBEgZhY3RpdmUaDgoCYUISCGlzQWN0aXZlGhEKAmFDEgtpc0FkbWluQ2FsbBoHCgJhRBIBaRocCgJhRRIWZ2V0QXNzZXRJbmZvRnJvbVN0cmluZxoOCgJhRhIIYXNzZXRTdHIaEQoCYUcSC2xhdW5jaHBhZElkGgoKAmFIEgRoYXNoGg0KAmFJEgdhZGRyZXNzGhQKAmFKEg5wcm9qZWN0QWRkcmVzcxoRCgJhSxILc3RhcnRIZWlnaHQaDgoCYUwSCGR1cmF0aW9uGg4KAmFNEghidXlUb2tlbhoQCgJhThIKY29tbWlzc2lvbhoVCgJhTxIPdG9rZW5zUGVyVGlja2V0GhMKAmFQEg1wcmljZVBlclRva2VuGhkKAmFREhNzd29wZmlUaWNrZXRzQW1vdW50GhoKAmFSEhRjYW1wYWlnblRva2Vuc0Ftb3VudBoZCgJhUxITdG9rZW5zUGVyQWxsb2NhdGlvbhoTCgJhVBINc3dvcFBlclRpY2tldBoYCgJhVRISc3dvcEZyZWV6ZUR1cmF0aW9uGhEKAmFWEgtjbGFpbVBhcmFtcxoZCgJhVxITSGlnaENvbXBldGl0aW9uU2FsZRoeCgJhWBIYaGlnaENvbXBldGl0aW9uQ29taXNzaW9uGiIKAmFZEhxoaWdoQ29tcGV0aXRpb25UaWNrZXRzQW1vdW50GhsKAmFaEhVmcmVlemVBZGRpdGlvbmFsVG9rZW4aIAoCYWESGmtleVVzZXJXaW5uZWRUaWNrZXRzQW1vdW50Gi8KAmFiEilrZXlVc2VyV2lubmVkSGlnaENvbXBldGl0aW9uVGlja2V0c0Ftb3VudBoYCgJhYxISa2V5VXNlckZyZWV6ZVRva2VuGgwKAmFkEgZvcmFjbGUaEAoCYWUSCmdvdmVybmFuY2UaFgoCYWYSEGNvbW1pc3Npb25XYWxsZXQaGAoCYWcSEnN0YWtpbmdVU0ROQWRkcmVzcxoKCgJhaBIEVVNEThoYCgJhaRISYWRtaW5QdWJLZXlTdGFraW5nGhoKAmFqEhRtYXhBbGxvY2F0aW9uc0Ftb3VudBoXCgJhaxIRYWN0aXZlTGF1bmNocGFkSWQaEQoCYWwSC2dldEFkbWluUHViGhEKAmFtEgtrZXlBZG1pblB1YhoNCgJhbhIHJG1hdGNoMBoMCgJhbxIGc3RyaW5nGg0KAmFwEgdub3RoaW5nGhIKAmFxEgxhZG1pblB1YktleTEaEgoCYXISDGFkbWluUHViS2V5MhoSCgJhcxIMYWRtaW5QdWJLZXkzGhIKAmF0EgxnZXRBc3NldEluZm8aDQoCYXUSB2Fzc2V0SWQaCAoCYXYSAmlkGg4KAmF3EghzdHJpbmdJZBoKCgJheBIEaW5mbxoLCgJheRIFd2F2ZXMaGAoCYXoSEmdldExhdW5jaHBhZE5leHRJZBoUCgFiEg9rZXlBZG1pblB1YktleTEaFAoCYkESDnRva2VuQXNzZXROYW1lGhMKAmJCEg10b2tlbkRlY2ltYWxzGhEKAmJDEgt0aWNrZXRQcmljZRoZCgJiRBITY29tbWlzc2lvblBlclRpY2tldBoVCgJiRRIPYnV5VGlja2V0QW1vdW50GhwKAmJGEhZhbGxvd2VkQnV5VGlja2V0QW1vdW50GiIKAmJHEhxhbGxvd2VkQnV5UHJpY2VXaXRoQ29taXNzaW9uGgwKAmJIEgZjaGFuZ2UaGgoCYkkSFGZyZWV6ZVRva2VuUGVyVGlja2V0GhMKAmJKEg0kdDAxMjUxMDEyNTk3GhUKAmJLEg9wbXRBbW91bnRGcmVlemUaFgoCYkwSEHBtdEFzc2V0SWRGcmVlemUaEwoCYk0SDSR0MDEyNjE0MTI3MDUaGQoCYk4SE3BtdEZyZWV6ZVN0ckFzc2V0SWQaGAoCYk8SEnBtdEZyZWV6ZUFzc2V0TmFtZRoXCgJiUBIRcG10RnJlZXplRGVjaW1hbHMaFgoCYlESEG5lZWRGcmVlemVUb2tlbnMaHgoCYlISGHVzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxocCgJiUxIWbGFzdEJvdWdodFRpY2tldE51bWJlchoRCgJiVBILYm91Z2h0UmFuZ2UaIQoCYlUSG25ld1VzZXJCb3VnaHRUaWNrZXRzTnVtYmVycxoJCgJiVhIDaW52Gg8KAmJXEgliYXNlRW50cnkaEwoCYlgSDSR0MDE0Nzc2MTQ4NTEaEwoCYlkSDSR0MDE0ODU2MTUwMDYaGQoCYloSE3VzZXJVc2RuSW5NYXJrZXRpbmcaEgoCYmESDGZyZWV6ZVBhcmFtcxoUCgJiYhIObGF1bmNocGFkSWRTdHIaEQoCYmMSCyR0MDYzOTc2NDcyGg8KAmJkEglwbXRBbW91bnQaEAoCYmUSCnBtdEFzc2V0SWQaEQoCYmYSCyR0MDY0ODE2NTU0GhMKAmJnEg1wbXRTdHJBc3NldElkGhIKAmJoEgxwbXRBc3NldE5hbWUaEQoCYmkSC3BtdERlY2ltYWxzGhsKAmJqEhVmcmVlemVBZGRpdGlvbmFsRW50cnkaCwoCYmsSBXJlZklkGhEKAmJsEgskdDA5MTYwOTIzNRoRCgJibRILJHQwOTI0MDkzOTAaEAoCYm4SCmJ1eUFzc2V0SWQaEwoCYm8SDWJ1eUFzc2V0U3RySWQaEgoCYnASDGJ1eUFzc2V0TmFtZRoWCgJicRIQYnV5QXNzZXREZWNpbWFscxoRCgJichILc3Rha2VkU3dvcHMaHQoCYnMSF2FsbG93ZWRUaWNrZXRzQW1vdW50QWxsGhkKAmJ0EhNib3VnaHRUaWNrZXRzQW1vdW50GhoKAmJ1EhRhbGxvd2VkVGlja2V0c0Ftb3VudBoTCgJidhINZnJlZXplVG9rZW5JZBoQCgJidxIKdG9rZW5QcmljZRoTCgJieBINJHQwMTEyMDIxMTM0NhoNCgJieRIHdG9rZW5JZBoVCgJiehIPdG9rZW5TdHJBc3NldElkGhQKAWMSD2tleUFkbWluUHViS2V5MhoVCgJjQRIPYm91Z2h0SENUaWNrZXRzGhUKAmNCEg91c2VyQ2xhaW1TdGF0dXMaFAoCY0MSDmZpbmFsaXplSGVpZ2h0GhMKAmNEEg0kdDAyNTQwNzI1NTU3GhMKAmNFEg13b25uZWRUaWNrZXRzGhUKAmNGEg93b25uZWRIQ1RpY2tldHMaGgoCY0cSFGF3YWlsYWJsZUFsbG9jYXRpb25zGhgKAmNIEhJhbGxvd2VkQWxsb2NhdGlvbnMaEwoCY0kSDSR0MDI2NDYzMjY2MDcaGgoCY0oSFHRyYW5zZmVyVG9rZW5zQW1vdW50GiEKAmNLEhtub3RBbGxvd2VkQWxsb2NhdGlvbnNUb2tlbnMaHAoCY0wSFmJ1eUFzc2V0Rm9yQWxsb2NhdGlvbnMaIAoCY00SGmJ1eUFzc2V0Rm9yVW53b25uZWRUaWNrZXRzGiIKAmNOEhxidXlBc3NldEZvckhDVW53b25uZWRUaWNrZXRzGhUKAmNPEg9jbGFpbWVkQnV5VG9rZW4aHAoCY1ASFnJldHVybmVkQnV5QXNzZXRBbW91bnQaFgoCY1ESEHRyYW5zZmVyQnV5QXNzZXQaEwoCY1ISDWNsYWltZWRQYXJhbXMaFAoCY1MSDnRyYW5zZmVyVG9rZW5zGhMKAmNUEg1jbGFpbWVkVG9rZW5zGhIKAmNVEgx1bmxvY2tQZXJpb2QaEQoCY1YSC2Jsb2NrSGVpZ2h0GhIKAmNXEgx1bmxvY2tIZWlnaHQaGQoCY1gSE2FsbG93ZWRUb2tlbnNBbW91bnQaFgoCY1kSEGNsYWltU3RhdHVzRW50cnkaFwoCY1oSEXVzZXJUb2tlbnNGcmVlemVkGhUKAmNhEg91c2RuSW5NYXJrZXRpbmcaFwoCY2ISEWJvdWdodEFsbG9jYXRpb25zGhMKAmNjEg0kdDAxNTY3NTE1ODE5GiIKAmNkEhxhbGxvY2F0aW9uUHJpY2VXaXRoQ29taXNzaW9uGhoKAmNlEhRidXlBbGxvY2F0aW9uc0Ftb3VudBoTCgJjZhINJHQwMTgwNzcxODE1MhoTCgJjZxINJHQwMTgxNTcxODMwNxobCgJjaBIVYm91Z2h0SENUaWNrZXRzQW1vdW50GhkKAmNpEhNoaWdoQ29tcGV0aXRpb25TYWxlGhMKAmNqEg0kdDAxOTQ4MDE5NjI0GhsKAmNrEhVidXlQcmljZVdpdGhDb21pc3Npb24aDwoCY2wSCXZyZkhlaWdodBoQCgJjbRIKc2VjcmV0V29yZBoPCgJjbhIJc2F2ZWRIYXNoGg4KAmNvEghjYWxjSGFzaBoTCgJjcBINJHQwMjIyMzcyMjM4NxoSCgJjcRIMY29tbWlzc2lvbkhDGhgKAmNyEhJ0cmFuc2ZlcmVkQnV5QXNzZXQaIQoCY3MSG3N3b3BmaU1lbWJlcnNCdXlBc3NldEFtb3VudBocCgJjdBIWc3dvcGZpSENCdXlBc3NldEFtb3VudBocCgJjdRIWc3dvcGZpTWVtYmVyc0NvbWlzc2lvbhoXCgJjdhIRc3dvcGZpSENDb21pc3Npb24aJAoCY3cSHnRvdGFsQW1vdW50QnV5QXNzZXRJbk1hcmtldGluZxoYCgJjeBISbWFya2V0aW5nQ29taXNzaW9uGhMKAmN5Eg11bnN0YWtlQW1vdW50GhMKAmN6Eg1ib3VnaHRUaWNrZXRzGhQKAWQSD2tleUFkbWluUHViS2V5MxoZCgJkYRITZnJlZXplVG9rZW5EdXJhdGlvbhoUCgJkYhIOYmxvY2tFbmRIZWlnaHQaDAoCZGMSBmFtb3VudBoTCgJkZBINJHQwMzI3MzQzMjg4NBoICgJkZRICdHgaDAoCZGYSBnZlcmlmeRoZCgJkZxITbXVsdGlTaWduZWRCeUFkbWlucxoYCgJkaBISYWRtaW5QdWJLZXkxU2lnbmVkGhgKAmRpEhJhZG1pblB1YktleTJTaWduZWQaGAoCZGoSEmFkbWluUHViS2V5M1NpZ25lZBoTCgJkaxINc2lnbmVkQnlBZG1pbhoJCgJkbBIDZHR4GiYKAWUSIWtleUxhdW5jaHBhZERhdGFUcmFuc2FjdGlvblN0YXR1cxoXCgFmEhJrZXlMYXVuY2hwYWROZXh0SWQaGQoBZxIUa2V5TGF1bmNocGFkQWN0aXZlSWQaEgoBaBINa2V5SW5pdENhbGxlchoPCgFpEgprZXlBZGRyZXNzGhIKAWoSDWtleUluaXRIZWlnaHQaEwoBaxIOa2V5U3RhcnRIZWlnaHQaFgoBbBIRa2V5RmluYWxpc2VIZWlnaHQaEQoBbRIMa2V5Q29taXNzaW9uGg8KAW4SCmtleUFzc2V0SWQaGAoBbxITa2V5VG90YWxUb2tlbkFtb3VudBofCgFwEhprZXlUb3RhbEFtb3VudEJ1eUFzc2V0U29sZBoXCgFxEhJrZXlUb2tlbnNQZXJUaWNrZXQaFQoBchIQa2V5UHJpY2VQZXJUb2tlbhoVCgFzEhBrZXlTd29wUGVyVGlja2V0GhsKAXQSFmtleVN3b3BmaVRpY2tldHNBbW91bnQaHAoBdRIXa2V5Q2FtcGFpZ25Ub2tlbnNBbW91bnQaGwoBdhIWa2V5VG9rZW5zUGVyQWxsb2NhdGlvbhoYCgF3EhNrZXlUaWNrZXRMYXN0TnVtYmVyGhgKAXgSE2tleUdvdmVybmFuY2VTdGFrZWQaEQoBeRIMa2V5VXNlclJlZklkGhIKAXoSDWtleVZlcmlmeUhhc2gAAABJAAAAAAFhAgAAAAZhY3RpdmUAAAAAAWICAAAAC2FkbWluX3B1Yl8xAAAAAAFjAgAAAAthZG1pbl9wdWJfMgAAAAABZAIAAAALYWRtaW5fcHViXzMAAAAAAWUCAAAAIWxhdW5jaHBhZF9kYXRhX3RyYW5zYWN0aW9uX3N0YXR1cwAAAAABZgIAAAARbGF1bmNocGFkX25leHRfaWQAAAAAAWcCAAAAE2xhdW5jaHBhZF9hY3RpdmVfaWQAAAAAAWgCAAAAC2luaXRfY2FsbGVyAAAAAAFpAgAAAAhfYWRkcmVzcwAAAAABagIAAAAMX2luaXRfaGVpZ2h0AAAAAAFrAgAAAA1fc3RhcnRfaGVpZ2h0AAAAAAFsAgAAABBfZmluYWxpc2VfaGVpZ2h0AAAAAAFtAgAAAApfY29taXNzaW9uAAAAAAFuAgAAAAlfYXNzZXRfaWQAAAAAAW8CAAAAE190b3RhbF90b2tlbl9hbW91bnQAAAAAAXACAAAAFV90b3RhbF9idXlfYXNzZXRfc29sZAAAAAABcQIAAAASX3Rva2Vuc19wZXJfdGlja2V0AAAAAAFyAgAAABBfcHJpY2VfcGVyX3Rva2VuAAAAAAFzAgAAABBfc3dvcF9wZXJfdGlja2V0AAAAAAF0AgAAABdfdGlja2V0c19zd29wZmlfbWVtYmVycwAAAAABdQIAAAATX3Rva2Vuc19hY2Nlc3NfbGlzdAAAAAABdgIAAAAWX3Rva2Vuc19wZXJfYWxsb2NhdGlvbgAAAAABdwIAAAATX3RpY2tldF9sYXN0X251bWJlcgAAAAABeAIAAAAMX1NXT1BfYW1vdW50AAAAAAF5AgAAAAdfcmVmX2lkAAAAAAF6AgAAAAxfdmVyaWZ5X2hhc2gAAAAAAUECAAAACV9kdXJhdGlvbgAAAAABQgIAAAAnX3RvdGFsX3B1cmNoYXNlZF9idXlfYXNzZXRfaW5fbWFya2V0aW5nAAAAAAFDAgAAADFfdG90YWxfcHVyY2hhc2VkX2J1eV9hc3NldF9pbl9tYXJrZXRpbmdfZmluYWxpemVkAAAAAAFEAgAAABNfdHJhbnNmZXJfYnV5X2Fzc2V0AAAAAAFFAgAAABVfZnJlZXplX3N3b3BfZHVyYXRpb24AAAAAAUYCAAAAGF9mcmVlemVfYWRkaXRpb25hbF90b2tlbgAAAAABRwIAAAAQX2ZyZWV6ZV90b2tlbl9pZAAAAAABSAIAAAAWX2ZyZWV6ZV90b2tlbl9kdXJhdGlvbgAAAAABSQIAAAAYX2ZyZWV6ZV90b2tlbl9wZXJfdGlja2V0AAAAAAFKAgAAAApfYnV5X3Rva2VuAAAAAAFLAgAAAA1fY2xhaW1fcGFyYW1zAAAAAAFMAgAAABtfaGlnaF9jb21wZXRpdGlvbl9jb21pc3Npb24AAAAAAU0CAAAAFl9oaWdoX2NvbXBldGl0aW9uX3NhbGUAAAAAAU4CAAAAJF9oaWdoX2NvbXBldGl0aW9uX3RpY2tldF9sYXN0X251bWJlcgAAAAABTwIAAAAZX3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABUAIAAAAmX3RvdGFsX2J1eV9hc3NldF9zb2xkX2hpZ2hfY29tcGV0aXRpb24AAAAAAVECAAAAD19jbGFpbWVkX3Rva2VucwAAAAABUgIAAAATX2NsYWltZWRfYnV5X3Rva2VucwAAAAABUwIAAAAPX2JvdWdodF90aWNrZXRzAAAAAAFUAgAAAA9fdGlja2V0c19udW1iZXIAAAAAAVUCAAAAIF90aWNrZXRzX251bWJlcl9oaWdoX2NvbXBldGl0aW9uAAAAAAFWAgAAACBfYm91Z2h0X3RpY2tldHNfaGlnaF9jb21wZXRpdGlvbgAAAAABVwIAAAAdX2F2YWlsYWJsZV9wdXJjaGFzZV9tYXJrZXRpbmcAAAAAAVgCAAAAIV9wdXJjaGFzZWRfYnV5X2Fzc2V0X2luX21hcmtldGluZwAAAAABWQIAAAATX2JvdWdodF9hbGxvY2F0aW9ucwAAAAABWgIAAAANX2NsYWltX3N0YXR1cwAAAAACYWECAAAAD190aWNrZXRzX3Jlc3VsdAAAAAACYWICAAAAIF90aWNrZXRzX3Jlc3VsdF9oaWdoX2NvbXBldGl0aW9uAAAAAAJhYwIAAAAUX2ZyZWV6ZV90b2tlbl9hbW91bnQAAAAAAmFkCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFU6UWqHpAvOq7xug7mLpqSXxqYhOHzYrMIAAAAAAJhZQkBAAAAB0FkZHJlc3MAAAABAQAAABoBVKr6ad6B9BNShco/LjqIUbMZ6pgcWfINLQAAAAACYWYJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVSMKR35sXlSywl+Wp/a1y8GBxSD7AzdEUkAAAAAAmFnCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFUuYnNz0dxupdy7LhFDzOwqkmF0Q14MgJtAAAAAAJhaAEAAAAgbySjyqsw3FIpmOgsYVruWn8jTcIt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", "height": 1885841, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5dpDgWbW6VuyZtNmYDGnaLiYg9Hf2n52SzjKihJmw1dY Next: FBP9UFGFGbCKJj19JPfYhQ3BSADmAH23DDPs9urYLnoG Diff:
OldNewDifferences
3131
3232 let keyTotalTokenAmount = "_total_token_amount"
3333
34-let keyTotalAmountUsdnSold = "_total_usdn_sold"
34+let keyTotalAmountBuyAssetSold = "_total_buy_asset_sold"
3535
3636 let keyTokensPerTicket = "_tokens_per_ticket"
3737
5555
5656 let keyDuration = "_duration"
5757
58-let keyAmountUSDNInMarketing = "_total_purchased_usdn_in_marketing"
58+let keyAmountBuyAssetInMarketing = "_total_purchased_buy_asset_in_marketing"
5959
60-let keyAmountUSDNInMarketingFinalized = "_total_purchased_usdn_in_marketing_finalized"
60+let keyAmountBuyAssetInMarketingFinalized = "_total_purchased_buy_asset_in_marketing_finalized"
6161
62-let keyTransferUsd = "_transfer_usd"
62+let keyTransferBuyAsset = "_transfer_buy_asset"
6363
6464 let keyFreezSwopDuration = "_freeze_swop_duration"
6565
7171
7272 let keyFreezeTokenPerTicket = "_freeze_token_per_ticket"
7373
74+let keyBuyToken = "_buy_token"
75+
76+let keyClaimParams = "_claim_params"
77+
78+let keyHighCompetitionComission = "_high_competition_comission"
79+
80+let keyHighCompetitionSale = "_high_competition_sale"
81+
82+let keyHCTicketLastNumber = "_high_competition_ticket_last_number"
83+
84+let keyHighCompetitionAmount = "_tickets_high_competition"
85+
86+let keyTotalAmountBuyAssetSoldHC = "_total_buy_asset_sold_high_competition"
87+
88+let keyUserClaimedTokens = "_claimed_tokens"
89+
90+let keyUserClaimedBuyTokens = "_claimed_buy_tokens"
91+
7492 let keyUserBoughtTicketsAmount = "_bought_tickets"
7593
7694 let keyUserTickets = "_tickets_number"
7795
96+let keyUserHCTickets = "_tickets_number_high_competition"
97+
98+let keyUserHCBoughtTicketsAmount = "_bought_tickets_high_competition"
99+
78100 let keyUserAvailableAllocations = "_available_purchase_marketing"
79101
80-let keyUserAmountUSDNInMarketing = "_purchased_usdn_in_marketing"
102+let keyUserAmountBuyAssetInMarketing = "_purchased_buy_asset_in_marketing"
81103
82104 let keyUserBoughtAllocations = "_bought_allocations"
83105
85107
86108 let keyUserWinnedTicketsAmount = "_tickets_result"
87109
110+let keyUserWinnedHighCompetitionTicketsAmount = "_tickets_result_high_competition"
111+
88112 let keyUserFreezeToken = "_freeze_token_amount"
89-
90-let lauchpadDuration = 10000
91113
92114 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
93115
102124 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
103125
104126 let maxAllocationsAmount = 2
105-
106-let isActive = valueOrElse(getBoolean(this, keyActive), true)
107127
108128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
109129
136156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
137157
138158
139-func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
159+let active = valueOrElse(getBoolean(this, keyActive), true)
160+
161+func isActive () = if (active)
162+ then unit
163+ else throw("DApp is inactive at this moment")
164+
165+
166+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
167+ then unit
168+ else throw("Only admin can call this function")
169+
170+
171+func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
172+ then $Tuple4(unit, "WAVES", "WAVES", 8)
173+ else {
174+ let stringId = assetStr
175+ let id = fromBase58String(assetStr)
176+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
177+ $Tuple4(id, stringId, info.name, info.decimals)
178+ }
140179
141180
142181 @Callable(i)
143-func hashingRandom (launchpadId,hash) = if (!(isActive))
144- then throw("DApp is inactive at this moment")
145- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
146- then throw("Only admin can call this function")
147- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
148183
149184
150185
151186 @Callable(i)
152-func initCaller (address) = if (!(isActive))
153- then throw("DApp is inactive at this moment")
154- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
155- then throw("Only admin can call this function")
156- else [StringEntry(keyInitCaller, address)]
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
157188
158189
159190
160191 @Callable(i)
161-func init (projectAddress,startHeight,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,freezeAdditionalToken,freezeParams) = if (!(isActive))
162- then throw("DApp is inactive at this moment")
163- else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
164- then throw("Only project admin can call init function")
165- else if ((size(i.payments) != 1))
166- then throw("One attached payment expected")
167- else if ((height > startHeight))
168- then throw("Start height must be greater than blockchain height")
169- else if (if (freezeAdditionalToken)
170- then (size(freezeParams) != 3)
171- else false)
172- then throw("Freeze params list must have 3 items")
173- else {
174- let launchpadId = getLaunchpadNextId()
175- let launchpadIdStr = toString(launchpadId)
176- let $t053095384 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
177- let pmtAmount = $t053095384._1
178- let pmtAssetId = $t053095384._2
179- let $t053935466 = getAssetInfo(pmtAssetId)
180- let pmtStrAssetId = $t053935466._1
181- let pmtAssetName = $t053935466._2
182- let pmtDecimals = $t053935466._3
183- let freezeAdditionalEntry = if (freezeAdditionalToken)
184- then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
185- else nil
186- ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), lauchpadDuration), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 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), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
187- }
192+func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = valueOrElse(isActive(), if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
193+ then throw("Only project admin can call init function")
194+ else if ((size(i.payments) != 1))
195+ then throw("One attached payment expected")
196+ else if ((height > startHeight))
197+ then throw("Start height must be greater than blockchain height")
198+ else if (if (freezeAdditionalToken)
199+ then (size(freezeParams) != 3)
200+ else false)
201+ then throw("Freeze params list must have 3 items")
202+ else {
203+ let launchpadId = getLaunchpadNextId()
204+ let launchpadIdStr = toString(launchpadId)
205+ let $t063976472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063976472._1
207+ let pmtAssetId = $t063976472._2
208+ let $t064816554 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064816554._1
210+ let pmtAssetName = $t064816554._2
211+ let pmtDecimals = $t064816554._3
212+ let freezeAdditionalEntry = if (freezeAdditionalToken)
213+ then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
214+ else nil
215+ ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), duration), StringEntry((launchpadIdStr + keyBuyToken), buyToken), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyHCTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyTokensPerTicket), tokensPerTicket), IntegerEntry((launchpadIdStr + keyPricePerToken), pricePerToken), IntegerEntry((launchpadIdStr + keySwopPerTicket), swopPerTicket), IntegerEntry((launchpadIdStr + keySwopfiTicketsAmount), swopfiTicketsAmount), IntegerEntry((launchpadIdStr + keyCampaignTokensAmount), campaignTokensAmount), IntegerEntry((launchpadIdStr + keyTokensPerAllocation), tokensPerAllocation), StringEntry((launchpadIdStr + keyClaimParams), makeString(claimParams, ",")), BooleanEntry((launchpadIdStr + keyHighCompetitionSale), HighCompetitionSale), IntegerEntry((launchpadIdStr + keyHighCompetitionComission), highCompetitionComission), IntegerEntry((launchpadIdStr + keyHighCompetitionAmount), highCompetitionTicketsAmount), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
216+ })
188217
189218
190219
191220 @Callable(i)
192-func commitSwopfiSale (launchpadId,refId) = {
193- let $t075377612 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
194- let pmtAmount = $t075377612._1
195- let pmtAssetId = $t075377612._2
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091609235 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091609235._1
224+ let pmtAssetId = $t091609235._2
225+ let $t092409390 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092409390._1
227+ let buyAssetStrId = $t092409390._2
228+ let buyAssetName = $t092409390._3
229+ let buyAssetDecimals = $t092409390._4
196230 let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
197231 let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
198232 let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
200234 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
201235 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
202236 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
203- if (!(isActive))
204- then throw("DApp is inactive at this moment")
205- else if ((activeLaunchpadId != launchpadId))
206- then throw("There is no active launchpad or this launchpad is ended")
207- else if ((startHeight > height))
208- then throw("Launchpad sale not started yet")
209- else if ((height > (startHeight + duration)))
210- then throw("Launchpad sale ended")
211- else if (if (!(freezeAdditionalToken))
212- 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))
213251 then true
214- else (pmtAssetId != USDN)
252+ else (pmtAssetId != buyAssetId)
215253 else false)
216- then throw("One attached payment in USDN expected")
217- else if (if (freezeAdditionalToken)
218- then if ((size(i.payments) != 2))
219- then true
220- else (pmtAssetId != USDN)
221- else false)
222- then {
223- let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
224- throw(("Two attached payments expected: First in USDN, 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 $t01120211346 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01120211346._1
267+ let tokenStrAssetId = $t01120211346._2
268+ let tokenAssetName = $t01120211346._3
269+ let tokenDecimals = $t01120211346._4
270+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
271+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
272+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
273+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
274+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
275+ let change = (pmtAmount - allowedBuyPriceWithComission)
276+ if ((buyTicketAmount == 0))
277+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
278+ else if ((change != 0))
279+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + buyAssetName))
280+ else {
281+ let freezeAdditionalEntry = if (freezeAdditionalToken)
282+ then {
283+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
284+ let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
285+ let $t01251012597 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01251012597._1
287+ let pmtAssetIdFreeze = $t01251012597._2
288+ let $t01261412705 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01261412705._1
290+ let pmtFreezeAssetName = $t01261412705._2
291+ let pmtFreezeDecimals = $t01261412705._3
292+ let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
293+ if (if ((pmtFreezeStrAssetId != freezeTokenId))
294+ then true
295+ else (needFreezeTokens != pmtAmountFreeze))
296+ then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
297+ else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
298+ }
299+ else nil
300+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
301+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
302+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
303+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
304+ then ("," + boughtRange)
305+ else ("" + boughtRange)))
306+ let inv = if ((buyAssetId == USDN))
307+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
308+ else 0
309+ if ((inv == inv))
310+ then {
311+ let baseEntry = ([IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount), (boughtTicketsAmount + allowedBuyTicketAmount)), IntegerEntry((toString(launchpadId) + keyTicketLastNumber), (lastBoughtTicketNumber + allowedBuyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets), newUserBoughtTicketsNumbers)] ++ freezeAdditionalEntry)
312+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
313+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
314+ else baseEntry
315+ }
316+ else throw("Strict value is not equal to itself.")
317+ }
225318 }
226- else if (if ((0 >= allowedTicketsAmountAll))
227- then true
228- else (0 >= allowedTicketsAmount))
229- then throw("Not enought SWOP in staking to buy tickets")
230- else {
231- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
232- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
233- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
234- let $t095549630 = getAssetInfo(tokenId)
235- let tokenStrAssetId = $t095549630._1
236- let tokenAssetName = $t095549630._2
237- let tokenDecimals = $t095549630._3
238- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
239- let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
240- let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
241- let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
242- let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
243- let change = (pmtAmount - allowedBuyPriceWithComission)
244- if ((buyTicketAmount == 0))
245- then throw("Not enought USDN to buy tickets")
246- else if ((change != 0))
247- then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + "USDN"))
248- else {
249- let freezeAdditionalEntry = if (freezeAdditionalToken)
250- then {
251- let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
252- let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
253- let $t01077210859 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
254- let pmtAmountFreeze = $t01077210859._1
255- let pmtAssetIdFreeze = $t01077210859._2
256- let $t01087610967 = getAssetInfo(pmtAssetId)
257- let pmtFreezeStrAssetId = $t01087610967._1
258- let pmtFreezeAssetName = $t01087610967._2
259- let pmtFreezeDecimals = $t01087610967._3
260- let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
261- if (if ((pmtFreezeStrAssetId != freezeTokenId))
262- then true
263- else (needFreezeTokens != pmtAmountFreeze))
264- then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
265- else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
266- }
267- else nil
268- let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
269- let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
270- let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
271- let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
272- then ("," + boughtRange)
273- else ("" + boughtRange)))
274- let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
275- if ((inv == inv))
276- then {
277- 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)
278- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
279- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
280- else baseEntry
281- }
282- else throw("Strict value is not equal to itself.")
283- }
284- }
285- }
319+ })
286320
287321
288322
289323 @Callable(i)
290-func commitAccessListSale (launchpadId,refId) = {
291- let $t01295413029 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
292- let pmtAmount = $t01295413029._1
293- let pmtAssetId = $t01295413029._2
294- let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing)), 0)
295- let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountUSDNInMarketing)), 0)
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01477614851 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01477614851._1
327+ let pmtAssetId = $t01477614851._2
328+ let $t01485615006 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01485615006._1
330+ let buyAssetStrId = $t01485615006._2
331+ let buyAssetName = $t01485615006._3
332+ let buyAssetDecimals = $t01485615006._4
333+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
296335 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
297336 let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
298337 let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
299338 let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
300- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
301- let $t01378413860 = getAssetInfo(tokenId)
302- let tokenStrAssetId = $t01378413860._1
303- let tokenAssetName = $t01378413860._2
304- let tokenDecimals = $t01378413860._3
339+ let $t01567515819 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01567515819._1
341+ let tokenStrAssetId = $t01567515819._2
342+ let tokenAssetName = $t01567515819._3
343+ let tokenDecimals = $t01567515819._4
305344 let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
306345 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
307346 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
308- if (!(isActive))
309- then throw("DApp is inactive at this moment")
310- else if ((activeLaunchpadId != launchpadId))
311- 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 $t01807718152 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01807718152._1
385+ let pmtAssetId = $t01807718152._2
386+ let $t01815718307 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01815718307._1
388+ let buyAssetStrId = $t01815718307._2
389+ let buyAssetName = $t01815718307._3
390+ let buyAssetDecimals = $t01815718307._4
391+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
392+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
393+ let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
394+ let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
395+ if ((activeLaunchpadId != launchpadId))
396+ then throw("There is no active launchpad or this launchpad is ended")
397+ else if (!(highCompetitionSale))
398+ then throw("There is no high competition sale for this launchpad")
312399 else if ((startHeight > height))
313400 then throw("Launchpad sale not started yet")
314401 else if ((height > (startHeight + duration)))
315402 then throw("Launchpad sale ended")
316403 else if (if ((size(i.payments) != 1))
317404 then true
318- else (pmtAssetId != USDN))
319- then throw("One attached payment in USDN expected")
320- else if ((boughtAllocations >= maxAllocationsAmount))
321- then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
322- else if (if ((allocationPriceWithComission != pmtAmount))
323- then ((allocationPriceWithComission * 2) != pmtAmount)
324- else false)
325- then throw((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + " USDN per allocation"))
326- else {
327- let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
328- let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
329- if ((inv == inv))
330- then {
331- let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations), (boughtAllocations + buyAllocationsAmount)), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing), (userUsdnInMarketing + pmtAmount)), IntegerEntry((toString(launchpadId) + keyAmountUSDNInMarketing), (usdnInMarketing + pmtAmount))]
332- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
333- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
334- else baseEntry
335- }
336- else throw("Strict value is not equal to itself.")
337- }
338- }
405+ else (pmtAssetId != buyAssetId))
406+ then throw((("One attached payment in " + buyAssetName) + " expected"))
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01948019624 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01948019624._1
412+ let tokenStrAssetId = $t01948019624._2
413+ let tokenAssetName = $t01948019624._3
414+ let tokenDecimals = $t01948019624._4
415+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
416+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
417+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
418+ let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
419+ let change = (pmtAmount - buyPriceWithComission)
420+ if ((buyTicketAmount == 0))
421+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
422+ else if ((change != 0))
423+ then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
424+ else {
425+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
426+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
427+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
428+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
429+ then ("," + boughtRange)
430+ else ("" + boughtRange)))
431+ let inv = if ((buyAssetId == USDN))
432+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
433+ else 0
434+ if ((inv == inv))
435+ then {
436+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount), (boughtHCTicketsAmount + buyTicketAmount)), IntegerEntry((toString(launchpadId) + keyHCTicketLastNumber), (lastBoughtTicketNumber + buyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets), newUserBoughtTicketsNumbers)]
437+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
438+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
439+ else baseEntry
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ }
444+ })
339445
340446
341447
342448 @Callable(i)
343-func finalise (launchpadId,vrfHeight,secretWord) = {
449+func finalise (launchpadId,vrfHeight,secretWord) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
344450 let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
345451 let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
346- if (!(isActive))
347- then throw("DApp is inactive at this moment")
348- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
349- then throw("Only admin can call this function")
350- else if ((calcHash != savedHash))
351- then throw("vrf Height hash not matching")
452+ if ((calcHash != savedHash))
453+ then throw("vrf Height hash not matching")
454+ else {
455+ let $t02223722387 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02223722387._1
457+ let buyAssetStrId = $t02223722387._2
458+ let buyAssetName = $t02223722387._3
459+ let buyAssetDecimals = $t02223722387._4
460+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
461+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
462+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
463+ let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
464+ let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
465+ let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
466+ let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
467+ let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
468+ let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
469+ let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
470+ let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
471+ if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
472+ then throw("Can't transfer negative value to project")
352473 else {
353- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
354- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
355- let transferedUsdn = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferUsd)), 0)
356- let swopfiMembersUsdnAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountUsdnSold))
357- let swopfiMembersComission = fraction(swopfiMembersUsdnAmount, commission, 100)
358- let totalAmountUsdnInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountUSDNInMarketingFinalized))
359- let marketingComission = fraction(totalAmountUsdnInMarketing, commission, 100)
360- let unstakeAmount = (((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) + swopfiMembersComission) + marketingComission)
361- if ((transferedUsdn > (swopfiMembersUsdnAmount + totalAmountUsdnInMarketing)))
362- then throw("Can't transfer negative value to project")
363- else {
364- let inv = invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
365- if ((inv == inv))
366- then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) - transferedUsdn), USDN), ScriptTransfer(commissionWallet, (swopfiMembersComission + marketingComission), USDN)]
367- else throw("Strict value is not equal to itself.")
368- }
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.")
369480 }
370- }
481+ }
482+ }))
371483
372484
373485
374486 @Callable(i)
375-func claim (launchpadId) = {
487+func claim (launchpadId) = valueOrElse(isActive(), {
488+ let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
489+ let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
490+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
376491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
377- let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
378- let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
379- if (!(isActive))
380- then throw("DApp is inactive at this moment")
381- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
382- then throw("You can't claim because results are not finalized")
383- else if (userClaimStatus)
384- then throw("You are already claimed")
385- else if (if ((boughtTickets == 0))
386- then (boughtAllocations == 0)
387- else false)
388- then throw("You can't claim because you don't buy anything")
389- else {
390- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
391- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
392- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
393- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
394- let allowedAllocations = min([boughtAllocations, awailableAllocations])
395- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
396- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
397- let $t01963419710 = getAssetInfo(tokenId)
398- let tokenStrAssetId = $t01963419710._1
399- let tokenAssetName = $t01963419710._2
400- let tokenDecimals = $t01963419710._3
401- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
402- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
403- let transferTokensAmount = ((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation))
404- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
405- let usdnForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
406- let usdnForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
407- if (if ((0 > usdnForAllocations))
408- then true
409- else (0 > usdnForUnwonnedTickets))
410- then throw("Error with allowed allocation param or wonned tickets param please contact support")
411- else {
412- let returnedUsdnAmount = (usdnForAllocations + usdnForUnwonnedTickets)
413- let transferUsdn = if ((returnedUsdnAmount > 0))
414- then [ScriptTransfer(i.caller, returnedUsdnAmount, USDN)]
415- else nil
416- let transferTokens = if ((transferTokensAmount > 0))
417- then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
418- else nil
419- let inv = if ((returnedUsdnAmount > 0))
420- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedUsdnAmount, toBase58String(USDN)], nil)
421- else 0
422- if ((inv == inv))
423- then (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)] ++ transferTokens) ++ transferUsdn)
424- else throw("Strict value is not equal to itself.")
425- }
426- }
427- }
492+ let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
493+ if ((finalizeHeight == 0))
494+ then throw("You can't claim because results are not finalized")
495+ else if (userClaimStatus)
496+ then throw("You are already claimed")
497+ else if (if (if ((boughtTickets == 0))
498+ then (boughtAllocations == 0)
499+ else false)
500+ then (boughtHCTickets == 0)
501+ else false)
502+ then throw("You can't claim because you don't buy anything")
503+ else {
504+ let $t02540725557 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02540725557._1
506+ let buyAssetStrId = $t02540725557._2
507+ let buyAssetName = $t02540725557._3
508+ let buyAssetDecimals = $t02540725557._4
509+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
510+ let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
511+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
512+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
513+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
514+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
515+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
516+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
517+ let $t02646326607 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02646326607._1
519+ let tokenStrAssetId = $t02646326607._2
520+ let tokenAssetName = $t02646326607._3
521+ let tokenDecimals = $t02646326607._4
522+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
523+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
524+ let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
525+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
526+ let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
527+ let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
528+ let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commissionHC), 100)
529+ let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
530+ if (if (if ((0 > buyAssetForAllocations))
531+ then true
532+ else (0 > buyAssetForUnwonnedTickets))
533+ then true
534+ else (0 > buyAssetForHCUnwonnedTickets))
535+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
536+ else {
537+ let returnedBuyAssetAmount = (((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) + buyAssetForAllocations) - claimedBuyToken)
538+ let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
539+ then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
540+ else nil
541+ let inv = if (if ((returnedBuyAssetAmount > 0))
542+ then (buyAssetId == USDN)
543+ else false)
544+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
545+ else 0
546+ if ((inv == inv))
547+ then {
548+ let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
549+ if (if ((size(claimedParams) == 0))
550+ then true
551+ else (claimedParams[0] == "claimAll"))
552+ then {
553+ let transferTokens = if ((transferTokensAmount > 0))
554+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
555+ else nil
556+ (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
557+ }
558+ else if ((claimedParams[0] == "claimPeriod"))
559+ then {
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)]
569+ else nil
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")
580+ }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
428587
429588
430589
431590 @Callable(i)
432-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
433592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
434- if (!(isActive))
435- then throw("DApp is inactive at this moment")
436- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
437- then throw("You can't claim because results are not finalized")
438- else if (!(freezeAdditionalToken))
439- then throw("There are no additional token freezing for this launchpad")
440- else {
441- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
442- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
443- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
444- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
445- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
446- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
447- if ((userTokensFreezed == 0))
448- then throw("You are already claimed your tokens or not paid anything")
449- else if ((blockEndHeight > height))
450- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
451- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
452- }
453- }
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+ })
454611
455612
456613
457614 @Callable(i)
458-func transferUsd (launchpadId,amountUsdn) = if (!(isActive))
459- then throw("DApp is inactive")
460- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
461- then throw("Only admin can call this function")
462- else {
463- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
464-[IntegerEntry((toString(launchpadId) + keyTransferUsd), amountUsdn), ScriptTransfer(projectAddress, amountUsdn, USDN)]
465- }
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03273432884 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03273432884._1
619+ let buyAssetStrId = $t03273432884._2
620+ let buyAssetName = $t03273432884._3
621+ let buyAssetDecimals = $t03273432884._4
622+[IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
623+ }))
466624
467625
468626
469627 @Callable(i)
470-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
471629 then throw("DApp already inactive")
472- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
473- then throw("Only admin can call this function")
474- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
475631
476632
477633
478634 @Callable(i)
479-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
480636 then throw("DApp already active")
481- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
482- then throw("Only admin can call this function")
483- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
484638
485639
486640 @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
34-let keyTotalAmountUsdnSold = "_total_usdn_sold"
34+let keyTotalAmountBuyAssetSold = "_total_buy_asset_sold"
3535
3636 let keyTokensPerTicket = "_tokens_per_ticket"
3737
3838 let keyPricePerToken = "_price_per_token"
3939
4040 let keySwopPerTicket = "_swop_per_ticket"
4141
4242 let keySwopfiTicketsAmount = "_tickets_swopfi_members"
4343
4444 let keyCampaignTokensAmount = "_tokens_access_list"
4545
4646 let keyTokensPerAllocation = "_tokens_per_allocation"
4747
4848 let keyTicketLastNumber = "_ticket_last_number"
4949
5050 let keyGovernanceStaked = "_SWOP_amount"
5151
5252 let keyUserRefId = "_ref_id"
5353
5454 let keyVerifyHash = "_verify_hash"
5555
5656 let keyDuration = "_duration"
5757
58-let keyAmountUSDNInMarketing = "_total_purchased_usdn_in_marketing"
58+let keyAmountBuyAssetInMarketing = "_total_purchased_buy_asset_in_marketing"
5959
60-let keyAmountUSDNInMarketingFinalized = "_total_purchased_usdn_in_marketing_finalized"
60+let keyAmountBuyAssetInMarketingFinalized = "_total_purchased_buy_asset_in_marketing_finalized"
6161
62-let keyTransferUsd = "_transfer_usd"
62+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
74+let keyBuyToken = "_buy_token"
75+
76+let keyClaimParams = "_claim_params"
77+
78+let keyHighCompetitionComission = "_high_competition_comission"
79+
80+let keyHighCompetitionSale = "_high_competition_sale"
81+
82+let keyHCTicketLastNumber = "_high_competition_ticket_last_number"
83+
84+let keyHighCompetitionAmount = "_tickets_high_competition"
85+
86+let keyTotalAmountBuyAssetSoldHC = "_total_buy_asset_sold_high_competition"
87+
88+let keyUserClaimedTokens = "_claimed_tokens"
89+
90+let keyUserClaimedBuyTokens = "_claimed_buy_tokens"
91+
7492 let keyUserBoughtTicketsAmount = "_bought_tickets"
7593
7694 let keyUserTickets = "_tickets_number"
7795
96+let keyUserHCTickets = "_tickets_number_high_competition"
97+
98+let keyUserHCBoughtTicketsAmount = "_bought_tickets_high_competition"
99+
78100 let keyUserAvailableAllocations = "_available_purchase_marketing"
79101
80-let keyUserAmountUSDNInMarketing = "_purchased_usdn_in_marketing"
102+let keyUserAmountBuyAssetInMarketing = "_purchased_buy_asset_in_marketing"
81103
82104 let keyUserBoughtAllocations = "_bought_allocations"
83105
84106 let keyUserClaimStatus = "_claim_status"
85107
86108 let keyUserWinnedTicketsAmount = "_tickets_result"
87109
110+let keyUserWinnedHighCompetitionTicketsAmount = "_tickets_result_high_competition"
111+
88112 let keyUserFreezeToken = "_freeze_token_amount"
89-
90-let lauchpadDuration = 10000
91113
92114 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
93115
94116 let governance = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
95117
96118 let commissionWallet = Address(base58'3N2hBdeDEs7wCNA9EY8qv3B6drjgKD64xQG')
97119
98120 let stakingUSDNAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
99121
100122 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
101123
102124 let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
103125
104126 let maxAllocationsAmount = 2
105-
106-let isActive = valueOrElse(getBoolean(this, keyActive), true)
107127
108128 let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
109129
110130 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
111131 case string: String =>
112132 fromBase58String(string)
113133 case nothing =>
114134 throw("Admin public key is empty")
115135 }
116136
117137
118138 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
119139
120140 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
121141
122142 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
123143
124144 func getAssetInfo (assetId) = match assetId {
125145 case id: ByteVector =>
126146 let stringId = toBase58String(id)
127147 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
128148 $Tuple3(stringId, info.name, info.decimals)
129149 case waves: Unit =>
130150 $Tuple3("WAVES", "WAVES", 8)
131151 case _ =>
132152 throw("Match error")
133153 }
134154
135155
136156 func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
137157
138158
139-func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
159+let active = valueOrElse(getBoolean(this, keyActive), true)
160+
161+func isActive () = if (active)
162+ then unit
163+ else throw("DApp is inactive at this moment")
164+
165+
166+func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
167+ then unit
168+ else throw("Only admin can call this function")
169+
170+
171+func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
172+ then $Tuple4(unit, "WAVES", "WAVES", 8)
173+ else {
174+ let stringId = assetStr
175+ let id = fromBase58String(assetStr)
176+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
177+ $Tuple4(id, stringId, info.name, info.decimals)
178+ }
140179
141180
142181 @Callable(i)
143-func hashingRandom (launchpadId,hash) = if (!(isActive))
144- then throw("DApp is inactive at this moment")
145- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
146- then throw("Only admin can call this function")
147- else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
182+func hashingRandom (launchpadId,hash) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]))
148183
149184
150185
151186 @Callable(i)
152-func initCaller (address) = if (!(isActive))
153- then throw("DApp is inactive at this moment")
154- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
155- then throw("Only admin can call this function")
156- else [StringEntry(keyInitCaller, address)]
187+func initCaller (address) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), [StringEntry(keyInitCaller, address)]))
157188
158189
159190
160191 @Callable(i)
161-func init (projectAddress,startHeight,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,freezeAdditionalToken,freezeParams) = if (!(isActive))
162- then throw("DApp is inactive at this moment")
163- else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
164- then throw("Only project admin can call init function")
165- else if ((size(i.payments) != 1))
166- then throw("One attached payment expected")
167- else if ((height > startHeight))
168- then throw("Start height must be greater than blockchain height")
169- else if (if (freezeAdditionalToken)
170- then (size(freezeParams) != 3)
171- else false)
172- then throw("Freeze params list must have 3 items")
173- else {
174- let launchpadId = getLaunchpadNextId()
175- let launchpadIdStr = toString(launchpadId)
176- let $t053095384 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
177- let pmtAmount = $t053095384._1
178- let pmtAssetId = $t053095384._2
179- let $t053935466 = getAssetInfo(pmtAssetId)
180- let pmtStrAssetId = $t053935466._1
181- let pmtAssetName = $t053935466._2
182- let pmtDecimals = $t053935466._3
183- let freezeAdditionalEntry = if (freezeAdditionalToken)
184- then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
185- else nil
186- ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), lauchpadDuration), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 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), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
187- }
192+func init (projectAddress,startHeight,duration,buyToken,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket,swopFreezeDuration,claimParams,HighCompetitionSale,highCompetitionComission,highCompetitionTicketsAmount,freezeAdditionalToken,freezeParams) = valueOrElse(isActive(), if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
193+ then throw("Only project admin can call init function")
194+ else if ((size(i.payments) != 1))
195+ then throw("One attached payment expected")
196+ else if ((height > startHeight))
197+ then throw("Start height must be greater than blockchain height")
198+ else if (if (freezeAdditionalToken)
199+ then (size(freezeParams) != 3)
200+ else false)
201+ then throw("Freeze params list must have 3 items")
202+ else {
203+ let launchpadId = getLaunchpadNextId()
204+ let launchpadIdStr = toString(launchpadId)
205+ let $t063976472 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
206+ let pmtAmount = $t063976472._1
207+ let pmtAssetId = $t063976472._2
208+ let $t064816554 = getAssetInfo(pmtAssetId)
209+ let pmtStrAssetId = $t064816554._1
210+ let pmtAssetName = $t064816554._2
211+ let pmtDecimals = $t064816554._3
212+ let freezeAdditionalEntry = if (freezeAdditionalToken)
213+ then [BooleanEntry((launchpadIdStr + keyFreezeAdditionalToken), true), StringEntry((launchpadIdStr + keyFreezeTokenId), freezeParams[0]), IntegerEntry((launchpadIdStr + keyFreezeTokenDuration), parseIntValue(freezeParams[1])), IntegerEntry((launchpadIdStr + keyFreezeTokenPerTicket), parseIntValue(freezeParams[2]))]
214+ else nil
215+ ([IntegerEntry((pmtStrAssetId + "_launchpad"), launchpadId), IntegerEntry(keyLaunchpadNextId, (launchpadId + 1)), StringEntry((launchpadIdStr + keyAddress), projectAddress), IntegerEntry((launchpadIdStr + keyInitHeight), height), IntegerEntry((launchpadIdStr + keyStartHeight), startHeight), IntegerEntry((launchpadIdStr + keyDuration), duration), StringEntry((launchpadIdStr + keyBuyToken), buyToken), IntegerEntry((launchpadIdStr + keyFreezSwopDuration), swopFreezeDuration), IntegerEntry((launchpadIdStr + keyTotalTokenAmount), pmtAmount), StringEntry((launchpadIdStr + keyAssetId), pmtStrAssetId), IntegerEntry((launchpadIdStr + keyComission), commission), IntegerEntry((launchpadIdStr + keyTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyHCTicketLastNumber), 0), IntegerEntry((launchpadIdStr + keyTokensPerTicket), tokensPerTicket), IntegerEntry((launchpadIdStr + keyPricePerToken), pricePerToken), IntegerEntry((launchpadIdStr + keySwopPerTicket), swopPerTicket), IntegerEntry((launchpadIdStr + keySwopfiTicketsAmount), swopfiTicketsAmount), IntegerEntry((launchpadIdStr + keyCampaignTokensAmount), campaignTokensAmount), IntegerEntry((launchpadIdStr + keyTokensPerAllocation), tokensPerAllocation), StringEntry((launchpadIdStr + keyClaimParams), makeString(claimParams, ",")), BooleanEntry((launchpadIdStr + keyHighCompetitionSale), HighCompetitionSale), IntegerEntry((launchpadIdStr + keyHighCompetitionComission), highCompetitionComission), IntegerEntry((launchpadIdStr + keyHighCompetitionAmount), highCompetitionTicketsAmount), IntegerEntry(keyLaunchpadActiveId, launchpadId), StringEntry(keyInitCaller, "")] ++ freezeAdditionalEntry)
216+ })
188217
189218
190219
191220 @Callable(i)
192-func commitSwopfiSale (launchpadId,refId) = {
193- let $t075377612 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
194- let pmtAmount = $t075377612._1
195- let pmtAssetId = $t075377612._2
221+func commitSwopfiSale (launchpadId,refId) = valueOrElse(isActive(), {
222+ let $t091609235 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
223+ let pmtAmount = $t091609235._1
224+ let pmtAssetId = $t091609235._2
225+ let $t092409390 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
226+ let buyAssetId = $t092409390._1
227+ let buyAssetStrId = $t092409390._2
228+ let buyAssetName = $t092409390._3
229+ let buyAssetDecimals = $t092409390._4
196230 let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
197231 let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
198232 let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
199233 let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
200234 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
201235 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
202236 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
203- if (!(isActive))
204- then throw("DApp is inactive at this moment")
205- else if ((activeLaunchpadId != launchpadId))
206- then throw("There is no active launchpad or this launchpad is ended")
207- else if ((startHeight > height))
208- then throw("Launchpad sale not started yet")
209- else if ((height > (startHeight + duration)))
210- then throw("Launchpad sale ended")
211- else if (if (!(freezeAdditionalToken))
212- 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))
213251 then true
214- else (pmtAssetId != USDN)
252+ else (pmtAssetId != buyAssetId)
215253 else false)
216- then throw("One attached payment in USDN expected")
217- else if (if (freezeAdditionalToken)
218- then if ((size(i.payments) != 2))
219- then true
220- else (pmtAssetId != USDN)
221- else false)
222- then {
223- let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
224- throw(("Two attached payments expected: First in USDN, 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 $t01120211346 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
266+ let tokenId = $t01120211346._1
267+ let tokenStrAssetId = $t01120211346._2
268+ let tokenAssetName = $t01120211346._3
269+ let tokenDecimals = $t01120211346._4
270+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
271+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
272+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
273+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
274+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
275+ let change = (pmtAmount - allowedBuyPriceWithComission)
276+ if ((buyTicketAmount == 0))
277+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
278+ else if ((change != 0))
279+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + buyAssetName))
280+ else {
281+ let freezeAdditionalEntry = if (freezeAdditionalToken)
282+ then {
283+ let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
284+ let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
285+ let $t01251012597 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
286+ let pmtAmountFreeze = $t01251012597._1
287+ let pmtAssetIdFreeze = $t01251012597._2
288+ let $t01261412705 = getAssetInfo(pmtAssetId)
289+ let pmtFreezeStrAssetId = $t01261412705._1
290+ let pmtFreezeAssetName = $t01261412705._2
291+ let pmtFreezeDecimals = $t01261412705._3
292+ let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
293+ if (if ((pmtFreezeStrAssetId != freezeTokenId))
294+ then true
295+ else (needFreezeTokens != pmtAmountFreeze))
296+ then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
297+ else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
298+ }
299+ else nil
300+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
301+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
302+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
303+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
304+ then ("," + boughtRange)
305+ else ("" + boughtRange)))
306+ let inv = if ((buyAssetId == USDN))
307+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
308+ else 0
309+ if ((inv == inv))
310+ then {
311+ let baseEntry = ([IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount), (boughtTicketsAmount + allowedBuyTicketAmount)), IntegerEntry((toString(launchpadId) + keyTicketLastNumber), (lastBoughtTicketNumber + allowedBuyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets), newUserBoughtTicketsNumbers)] ++ freezeAdditionalEntry)
312+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
313+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
314+ else baseEntry
315+ }
316+ else throw("Strict value is not equal to itself.")
317+ }
225318 }
226- else if (if ((0 >= allowedTicketsAmountAll))
227- then true
228- else (0 >= allowedTicketsAmount))
229- then throw("Not enought SWOP in staking to buy tickets")
230- else {
231- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
232- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
233- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
234- let $t095549630 = getAssetInfo(tokenId)
235- let tokenStrAssetId = $t095549630._1
236- let tokenAssetName = $t095549630._2
237- let tokenDecimals = $t095549630._3
238- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
239- let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
240- let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
241- let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
242- let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
243- let change = (pmtAmount - allowedBuyPriceWithComission)
244- if ((buyTicketAmount == 0))
245- then throw("Not enought USDN to buy tickets")
246- else if ((change != 0))
247- then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + "USDN"))
248- else {
249- let freezeAdditionalEntry = if (freezeAdditionalToken)
250- then {
251- let freezeTokenId = getStringValue(this, (toString(launchpadId) + keyFreezeTokenId))
252- let freezeTokenPerTicket = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenPerTicket))
253- let $t01077210859 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
254- let pmtAmountFreeze = $t01077210859._1
255- let pmtAssetIdFreeze = $t01077210859._2
256- let $t01087610967 = getAssetInfo(pmtAssetId)
257- let pmtFreezeStrAssetId = $t01087610967._1
258- let pmtFreezeAssetName = $t01087610967._2
259- let pmtFreezeDecimals = $t01087610967._3
260- let needFreezeTokens = (freezeTokenPerTicket * buyTicketAmount)
261- if (if ((pmtFreezeStrAssetId != freezeTokenId))
262- then true
263- else (needFreezeTokens != pmtAmountFreeze))
264- then throw((((("You need to add " + toString(needFreezeTokens)) + " ") + pmtFreezeAssetName) + " as a second payment"))
265- else [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), pmtAmountFreeze)]
266- }
267- else nil
268- let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
269- let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
270- let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
271- let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
272- then ("," + boughtRange)
273- else ("" + boughtRange)))
274- let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
275- if ((inv == inv))
276- then {
277- 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)
278- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
279- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
280- else baseEntry
281- }
282- else throw("Strict value is not equal to itself.")
283- }
284- }
285- }
319+ })
286320
287321
288322
289323 @Callable(i)
290-func commitAccessListSale (launchpadId,refId) = {
291- let $t01295413029 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
292- let pmtAmount = $t01295413029._1
293- let pmtAssetId = $t01295413029._2
294- let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing)), 0)
295- let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountUSDNInMarketing)), 0)
324+func commitAccessListSale (launchpadId,refId) = valueOrElse(isActive(), {
325+ let $t01477614851 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
326+ let pmtAmount = $t01477614851._1
327+ let pmtAssetId = $t01477614851._2
328+ let $t01485615006 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
329+ let buyAssetId = $t01485615006._1
330+ let buyAssetStrId = $t01485615006._2
331+ let buyAssetName = $t01485615006._3
332+ let buyAssetDecimals = $t01485615006._4
333+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountBuyAssetInMarketing)), 0)
334+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountBuyAssetInMarketing)), 0)
296335 let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
297336 let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
298337 let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
299338 let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
300- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
301- let $t01378413860 = getAssetInfo(tokenId)
302- let tokenStrAssetId = $t01378413860._1
303- let tokenAssetName = $t01378413860._2
304- let tokenDecimals = $t01378413860._3
339+ let $t01567515819 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
340+ let tokenId = $t01567515819._1
341+ let tokenStrAssetId = $t01567515819._2
342+ let tokenAssetName = $t01567515819._3
343+ let tokenDecimals = $t01567515819._4
305344 let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
306345 let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
307346 let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
308- if (!(isActive))
309- then throw("DApp is inactive at this moment")
310- else if ((activeLaunchpadId != launchpadId))
311- 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 $t01807718152 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
384+ let pmtAmount = $t01807718152._1
385+ let pmtAssetId = $t01807718152._2
386+ let $t01815718307 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
387+ let buyAssetId = $t01815718307._1
388+ let buyAssetStrId = $t01815718307._2
389+ let buyAssetName = $t01815718307._3
390+ let buyAssetDecimals = $t01815718307._4
391+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
392+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
393+ let boughtHCTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
394+ let highCompetitionSale = valueOrElse(getBoolean(this, (toString(launchpadId) + keyHighCompetitionSale)), false)
395+ if ((activeLaunchpadId != launchpadId))
396+ then throw("There is no active launchpad or this launchpad is ended")
397+ else if (!(highCompetitionSale))
398+ then throw("There is no high competition sale for this launchpad")
312399 else if ((startHeight > height))
313400 then throw("Launchpad sale not started yet")
314401 else if ((height > (startHeight + duration)))
315402 then throw("Launchpad sale ended")
316403 else if (if ((size(i.payments) != 1))
317404 then true
318- else (pmtAssetId != USDN))
319- then throw("One attached payment in USDN expected")
320- else if ((boughtAllocations >= maxAllocationsAmount))
321- then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
322- else if (if ((allocationPriceWithComission != pmtAmount))
323- then ((allocationPriceWithComission * 2) != pmtAmount)
324- else false)
325- then throw((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + " USDN per allocation"))
326- else {
327- let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
328- let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
329- if ((inv == inv))
330- then {
331- let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations), (boughtAllocations + buyAllocationsAmount)), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing), (userUsdnInMarketing + pmtAmount)), IntegerEntry((toString(launchpadId) + keyAmountUSDNInMarketing), (usdnInMarketing + pmtAmount))]
332- if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
333- then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
334- else baseEntry
335- }
336- else throw("Strict value is not equal to itself.")
337- }
338- }
405+ else (pmtAssetId != buyAssetId))
406+ then throw((("One attached payment in " + buyAssetName) + " expected"))
407+ else {
408+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
409+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
410+ let $t01948019624 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
411+ let tokenId = $t01948019624._1
412+ let tokenStrAssetId = $t01948019624._2
413+ let tokenAssetName = $t01948019624._3
414+ let tokenDecimals = $t01948019624._4
415+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
416+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission)), 100)
417+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
418+ let buyPriceWithComission = (buyTicketAmount * (ticketPrice + commissionPerTicket))
419+ let change = (pmtAmount - buyPriceWithComission)
420+ if ((buyTicketAmount == 0))
421+ then throw((("Not enought " + buyAssetName) + " to buy tickets"))
422+ else if ((change != 0))
423+ then throw((((("Wrong payment. To buy " + toString(buyTicketAmount)) + "tickets you need to pay ") + toString(buyPriceWithComission)) + buyAssetName))
424+ else {
425+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets)), "")
426+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyHCTicketLastNumber))
427+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + buyTicketAmount)))
428+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
429+ then ("," + boughtRange)
430+ else ("" + boughtRange)))
431+ let inv = if ((buyAssetId == USDN))
432+ then invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
433+ else 0
434+ if ((inv == inv))
435+ then {
436+ let baseEntry = [IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount), (boughtHCTicketsAmount + buyTicketAmount)), IntegerEntry((toString(launchpadId) + keyHCTicketLastNumber), (lastBoughtTicketNumber + buyTicketAmount)), StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCTickets), newUserBoughtTicketsNumbers)]
437+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
438+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
439+ else baseEntry
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ }
444+ })
339445
340446
341447
342448 @Callable(i)
343-func finalise (launchpadId,vrfHeight,secretWord) = {
449+func finalise (launchpadId,vrfHeight,secretWord) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
344450 let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
345451 let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
346- if (!(isActive))
347- then throw("DApp is inactive at this moment")
348- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
349- then throw("Only admin can call this function")
350- else if ((calcHash != savedHash))
351- then throw("vrf Height hash not matching")
452+ if ((calcHash != savedHash))
453+ then throw("vrf Height hash not matching")
454+ else {
455+ let $t02223722387 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
456+ let buyAssetId = $t02223722387._1
457+ let buyAssetStrId = $t02223722387._2
458+ let buyAssetName = $t02223722387._3
459+ let buyAssetDecimals = $t02223722387._4
460+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
461+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
462+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
463+ let transferedBuyAsset = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferBuyAsset)), 0)
464+ let swopfiMembersBuyAssetAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSold))
465+ let swopfiHCBuyAssetAmount = valueOrElse(getIntegerValue(this, (toString(launchpadId) + keyTotalAmountBuyAssetSoldHC)), 0)
466+ let swopfiMembersComission = fraction(swopfiMembersBuyAssetAmount, commission, 100)
467+ let swopfiHCComission = fraction(swopfiHCBuyAssetAmount, commissionHC, 100)
468+ let totalAmountBuyAssetInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountBuyAssetInMarketingFinalized))
469+ let marketingComission = fraction(totalAmountBuyAssetInMarketing, commission, 100)
470+ let unstakeAmount = (((((swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing) + swopfiMembersComission) + marketingComission) + swopfiHCBuyAssetAmount) + swopfiHCComission)
471+ if ((transferedBuyAsset > (swopfiMembersBuyAssetAmount + totalAmountBuyAssetInMarketing)))
472+ then throw("Can't transfer negative value to project")
352473 else {
353- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
354- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
355- let transferedUsdn = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferUsd)), 0)
356- let swopfiMembersUsdnAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountUsdnSold))
357- let swopfiMembersComission = fraction(swopfiMembersUsdnAmount, commission, 100)
358- let totalAmountUsdnInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountUSDNInMarketingFinalized))
359- let marketingComission = fraction(totalAmountUsdnInMarketing, commission, 100)
360- let unstakeAmount = (((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) + swopfiMembersComission) + marketingComission)
361- if ((transferedUsdn > (swopfiMembersUsdnAmount + totalAmountUsdnInMarketing)))
362- then throw("Can't transfer negative value to project")
363- else {
364- let inv = invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
365- if ((inv == inv))
366- then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) - transferedUsdn), USDN), ScriptTransfer(commissionWallet, (swopfiMembersComission + marketingComission), USDN)]
367- else throw("Strict value is not equal to itself.")
368- }
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.")
369480 }
370- }
481+ }
482+ }))
371483
372484
373485
374486 @Callable(i)
375-func claim (launchpadId) = {
487+func claim (launchpadId) = valueOrElse(isActive(), {
488+ let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
489+ let boughtHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserHCBoughtTicketsAmount)), 0)
490+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
376491 let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
377- let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
378- let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
379- if (!(isActive))
380- then throw("DApp is inactive at this moment")
381- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
382- then throw("You can't claim because results are not finalized")
383- else if (userClaimStatus)
384- then throw("You are already claimed")
385- else if (if ((boughtTickets == 0))
386- then (boughtAllocations == 0)
387- else false)
388- then throw("You can't claim because you don't buy anything")
389- else {
390- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
391- let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
392- let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
393- let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
394- let allowedAllocations = min([boughtAllocations, awailableAllocations])
395- let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
396- let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
397- let $t01963419710 = getAssetInfo(tokenId)
398- let tokenStrAssetId = $t01963419710._1
399- let tokenAssetName = $t01963419710._2
400- let tokenDecimals = $t01963419710._3
401- let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
402- let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
403- let transferTokensAmount = ((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation))
404- let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
405- let usdnForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
406- let usdnForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
407- if (if ((0 > usdnForAllocations))
408- then true
409- else (0 > usdnForUnwonnedTickets))
410- then throw("Error with allowed allocation param or wonned tickets param please contact support")
411- else {
412- let returnedUsdnAmount = (usdnForAllocations + usdnForUnwonnedTickets)
413- let transferUsdn = if ((returnedUsdnAmount > 0))
414- then [ScriptTransfer(i.caller, returnedUsdnAmount, USDN)]
415- else nil
416- let transferTokens = if ((transferTokensAmount > 0))
417- then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
418- else nil
419- let inv = if ((returnedUsdnAmount > 0))
420- then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedUsdnAmount, toBase58String(USDN)], nil)
421- else 0
422- if ((inv == inv))
423- then (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)] ++ transferTokens) ++ transferUsdn)
424- else throw("Strict value is not equal to itself.")
425- }
426- }
427- }
492+ let finalizeHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)), 0)
493+ if ((finalizeHeight == 0))
494+ then throw("You can't claim because results are not finalized")
495+ else if (userClaimStatus)
496+ then throw("You are already claimed")
497+ else if (if (if ((boughtTickets == 0))
498+ then (boughtAllocations == 0)
499+ else false)
500+ then (boughtHCTickets == 0)
501+ else false)
502+ then throw("You can't claim because you don't buy anything")
503+ else {
504+ let $t02540725557 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
505+ let buyAssetId = $t02540725557._1
506+ let buyAssetStrId = $t02540725557._2
507+ let buyAssetName = $t02540725557._3
508+ let buyAssetDecimals = $t02540725557._4
509+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
510+ let wonnedHCTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedHighCompetitionTicketsAmount)), 0)
511+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
512+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
513+ let commissionHC = getIntegerValue(this, (toString(launchpadId) + keyHighCompetitionComission))
514+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
515+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
516+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
517+ let $t02646326607 = getAssetInfoFromString(getStringValue(this, (toString(launchpadId) + keyAssetId)))
518+ let tokenId = $t02646326607._1
519+ let tokenStrAssetId = $t02646326607._2
520+ let tokenAssetName = $t02646326607._3
521+ let tokenDecimals = $t02646326607._4
522+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
523+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
524+ let transferTokensAmount = (((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation)) + (wonnedHCTickets * tokensPerTicket))
525+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
526+ let buyAssetForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
527+ let buyAssetForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
528+ let buyAssetForHCUnwonnedTickets = fraction(((boughtHCTickets - wonnedHCTickets) * ticketPrice), (100 + commissionHC), 100)
529+ let claimedBuyToken = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens)), 0)
530+ if (if (if ((0 > buyAssetForAllocations))
531+ then true
532+ else (0 > buyAssetForUnwonnedTickets))
533+ then true
534+ else (0 > buyAssetForHCUnwonnedTickets))
535+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
536+ else {
537+ let returnedBuyAssetAmount = (((buyAssetForUnwonnedTickets + buyAssetForHCUnwonnedTickets) + buyAssetForAllocations) - claimedBuyToken)
538+ let transferBuyAsset = if ((returnedBuyAssetAmount > 0))
539+ then [ScriptTransfer(i.caller, returnedBuyAssetAmount, buyAssetId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedBuyTokens), returnedBuyAssetAmount)]
540+ else nil
541+ let inv = if (if ((returnedBuyAssetAmount > 0))
542+ then (buyAssetId == USDN)
543+ else false)
544+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedBuyAssetAmount, toBase58String(USDN)], nil)
545+ else 0
546+ if ((inv == inv))
547+ then {
548+ let claimedParams = split(valueOrElse(getString(this, (toString(launchpadId) + keyClaimParams)), ""), ",")
549+ if (if ((size(claimedParams) == 0))
550+ then true
551+ else (claimedParams[0] == "claimAll"))
552+ then {
553+ let transferTokens = if ((transferTokensAmount > 0))
554+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
555+ else nil
556+ (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimedTokens), transferTokensAmount)] ++ transferTokens) ++ transferBuyAsset)
557+ }
558+ else if ((claimedParams[0] == "claimPeriod"))
559+ then {
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)]
569+ else nil
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")
580+ }
581+ else throw("Unknown claim function")
582+ }
583+ else throw("Strict value is not equal to itself.")
584+ }
585+ }
586+ })
428587
429588
430589
431590 @Callable(i)
432-func claimFreezeToken (launchpadId) = {
591+func claimFreezeToken (launchpadId) = valueOrElse(isActive(), {
433592 let freezeAdditionalToken = valueOrElse(getBoolean(this, (toString(launchpadId) + keyFreezeAdditionalToken)), false)
434- if (!(isActive))
435- then throw("DApp is inactive at this moment")
436- else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
437- then throw("You can't claim because results are not finalized")
438- else if (!(freezeAdditionalToken))
439- then throw("There are no additional token freezing for this launchpad")
440- else {
441- let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyFreezeTokenId)))
442- let userTokensFreezed = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken)), 0)
443- let startHeight = valueOrElse(getInteger(this, (toString(launchpadId) + keyStartHeight)), 0)
444- let duration = valueOrElse(getInteger(this, (toString(launchpadId) + keyDuration)), 0)
445- let freezeTokenDuration = getIntegerValue(this, (toString(launchpadId) + keyFreezeTokenDuration))
446- let blockEndHeight = ((startHeight + duration) + freezeTokenDuration)
447- if ((userTokensFreezed == 0))
448- then throw("You are already claimed your tokens or not paid anything")
449- else if ((blockEndHeight > height))
450- then throw(("Your tokens freezed teel " + toString(blockEndHeight)))
451- else [ScriptTransfer(i.caller, userTokensFreezed, tokenId), IntegerEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserFreezeToken), 0)]
452- }
453- }
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+ })
454611
455612
456613
457614 @Callable(i)
458-func transferUsd (launchpadId,amountUsdn) = if (!(isActive))
459- then throw("DApp is inactive")
460- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
461- then throw("Only admin can call this function")
462- else {
463- let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
464-[IntegerEntry((toString(launchpadId) + keyTransferUsd), amountUsdn), ScriptTransfer(projectAddress, amountUsdn, USDN)]
465- }
615+func transferBuyAsset (launchpadId,amount) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
616+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
617+ let $t03273432884 = getAssetInfoFromString(value(getString(this, (toString(launchpadId) + keyBuyToken))))
618+ let buyAssetId = $t03273432884._1
619+ let buyAssetStrId = $t03273432884._2
620+ let buyAssetName = $t03273432884._3
621+ let buyAssetDecimals = $t03273432884._4
622+[IntegerEntry((toString(launchpadId) + keyTransferBuyAsset), amount), ScriptTransfer(projectAddress, amount, buyAssetId)]
623+ }))
466624
467625
468626
469627 @Callable(i)
470-func shutdown () = if (!(isActive))
628+func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
471629 then throw("DApp already inactive")
472- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
473- then throw("Only admin can call this function")
474- else [BooleanEntry(keyActive, false)]
630+ else [BooleanEntry(keyActive, false)])
475631
476632
477633
478634 @Callable(i)
479-func activate () = if (isActive)
635+func activate () = valueOrElse(isAdminCall(i), if (active)
480636 then throw("DApp already active")
481- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
482- then throw("Only admin can call this function")
483- else [BooleanEntry(keyActive, true)]
637+ else [BooleanEntry(keyActive, true)])
484638
485639
486640 @Verifier(tx)
487641 func verify () = {
488642 let multiSignedByAdmins = {
489643 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
490644 then 1
491645 else 0
492646 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
493647 then 1
494648 else 0
495649 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
496650 then 1
497651 else 0
498652 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
499653 }
500654 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
501655 then true
502656 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
503657 then true
504658 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
505659 then true
506660 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
507661 match tx {
508662 case dtx: DataTransaction =>
509663 if (valueOrElse(getBoolean(oracle, keyLaunchpadDataTransactionStatus), false))
510664 then signedByAdmin
511665 else false
512666 case _ =>
513667 multiSignedByAdmins
514668 }
515669 }
516670

github/deemru/w8io/c3f4982 
114.17 ms