tx · H4hTfBNTa542YFxbMpo1gQ9EAKFy2h8BWmvXF1S7PuuD

3MwkjgDrsm5k73WJU9Nbxbx4y2iy3zjQzMi:  -0.01400000 Waves

2021.11.30 16:55 [1813860] smart account 3MwkjgDrsm5k73WJU9Nbxbx4y2iy3zjQzMi > SELF 0.00000000 Waves

{ "type": 13, "id": "H4hTfBNTa542YFxbMpo1gQ9EAKFy2h8BWmvXF1S7PuuD", "fee": 1400000, "feeAssetId": null, "timestamp": 1638280530381, "version": 2, "chainId": 84, "sender": "3MwkjgDrsm5k73WJU9Nbxbx4y2iy3zjQzMi", "senderPublicKey": "FRotxVW1MhTQRDvVbMM4yvYGWzBFvHqvMsonvGeEXQUy", "proofs": [ "3uA4aENoqKmZvy3yQHEnMiQiN431gws4HAsm1wS4qNTnUAw2kdPUJvSt4dEPTmSnYaPBTr9b5mGpmbTQMzCTCdTQ", "5K6x96qXxPo4z6Wcb2UShoq7nDTBkKgvVADzkcf7JDuc1n5DRmF6GecsqjBu5Lhzj2qNULfbmJSVYCSk53hjsd9w" ], "script": "base64:AAIFAAAAAAAAADwIAhIECgIBCBIDCgEIEgsKCQgBAQEBAQEBARIECgIBCBIECgIBCBIFCgMBAQgSAwoBARIECgIBARIAEgAAAAA2AAAAAAlrZXlBY3RpdmUCAAAABmFjdGl2ZQAAAAAPa2V5QWRtaW5QdWJLZXkxAgAAAAthZG1pbl9wdWJfMQAAAAAPa2V5QWRtaW5QdWJLZXkyAgAAAAthZG1pbl9wdWJfMgAAAAAPa2V5QWRtaW5QdWJLZXkzAgAAAAthZG1pbl9wdWJfMwAAAAAha2V5TGF1bmNocGFkRGF0YVRyYW5zYWN0aW9uU3RhdHVzAgAAACFsYXVuY2hwYWRfZGF0YV90cmFuc2FjdGlvbl9zdGF0dXMAAAAAEmtleUxhdW5jaHBhZE5leHRJZAIAAAARbGF1bmNocGFkX25leHRfaWQAAAAAFGtleUxhdW5jaHBhZEFjdGl2ZUlkAgAAABNsYXVuY2hwYWRfYWN0aXZlX2lkAAAAAA1rZXlJbml0Q2FsbGVyAgAAAAtpbml0X2NhbGxlcgAAAAAKa2V5QWRkcmVzcwIAAAAIX2FkZHJlc3MAAAAADWtleUluaXRIZWlnaHQCAAAADF9pbml0X2hlaWdodAAAAAAOa2V5U3RhcnRIZWlnaHQCAAAADV9zdGFydF9oZWlnaHQAAAAAEWtleUZpbmFsaXNlSGVpZ2h0AgAAABBfZmluYWxpc2VfaGVpZ2h0AAAAAAxrZXlDb21pc3Npb24CAAAACl9jb21pc3Npb24AAAAACmtleUFzc2V0SWQCAAAACV9hc3NldF9pZAAAAAATa2V5VG90YWxUb2tlbkFtb3VudAIAAAATX3RvdGFsX3Rva2VuX2Ftb3VudAAAAAAWa2V5VG90YWxBbW91bnRVc2RuU29sZAIAAAAQX3RvdGFsX3VzZG5fc29sZAAAAAASa2V5VG9rZW5zUGVyVGlja2V0AgAAABJfdG9rZW5zX3Blcl90aWNrZXQAAAAAEGtleVByaWNlUGVyVG9rZW4CAAAAEF9wcmljZV9wZXJfdG9rZW4AAAAAEGtleVN3b3BQZXJUaWNrZXQCAAAAEF9zd29wX3Blcl90aWNrZXQAAAAAFmtleVN3b3BmaVRpY2tldHNBbW91bnQCAAAAF190aWNrZXRzX3N3b3BmaV9tZW1iZXJzAAAAABdrZXlDYW1wYWlnblRva2Vuc0Ftb3VudAIAAAATX3Rva2Vuc19hY2Nlc3NfbGlzdAAAAAAWa2V5VG9rZW5zUGVyQWxsb2NhdGlvbgIAAAAWX3Rva2Vuc19wZXJfYWxsb2NhdGlvbgAAAAATa2V5VGlja2V0TGFzdE51bWJlcgIAAAATX3RpY2tldF9sYXN0X251bWJlcgAAAAATa2V5R292ZXJuYW5jZVN0YWtlZAIAAAAMX1NXT1BfYW1vdW50AAAAAAxrZXlVc2VyUmVmSWQCAAAAB19yZWZfaWQAAAAADWtleVZlcmlmeUhhc2gCAAAADF92ZXJpZnlfaGFzaAAAAAALa2V5RHVyYXRpb24CAAAACV9kdXJhdGlvbgAAAAAYa2V5QW1vdW50VVNETkluTWFya2V0aW5nAgAAACJfdG90YWxfcHVyY2hhc2VkX3VzZG5faW5fbWFya2V0aW5nAAAAACFrZXlBbW91bnRVU0ROSW5NYXJrZXRpbmdGaW5hbGl6ZWQCAAAALF90b3RhbF9wdXJjaGFzZWRfdXNkbl9pbl9tYXJrZXRpbmdfZmluYWxpemVkAAAAAA5rZXlUcmFuc2ZlclVzZAIAAAANX3RyYW5zZmVyX3VzZAAAAAAaa2V5VXNlckJvdWdodFRpY2tldHNBbW91bnQCAAAAD19ib3VnaHRfdGlja2V0cwAAAAAOa2V5VXNlclRpY2tldHMCAAAAD190aWNrZXRzX251bWJlcgAAAAAba2V5VXNlckF2YWlsYWJsZUFsbG9jYXRpb25zAgAAAB1fYXZhaWxhYmxlX3B1cmNoYXNlX21hcmtldGluZwAAAAAca2V5VXNlckFtb3VudFVTRE5Jbk1hcmtldGluZwIAAAAcX3B1cmNoYXNlZF91c2RuX2luX21hcmtldGluZwAAAAAYa2V5VXNlckJvdWdodEFsbG9jYXRpb25zAgAAABNfYm91Z2h0X2FsbG9jYXRpb25zAAAAABJrZXlVc2VyQ2xhaW1TdGF0dXMCAAAADV9jbGFpbV9zdGF0dXMAAAAAGmtleVVzZXJXaW5uZWRUaWNrZXRzQW1vdW50AgAAAA9fdGlja2V0c19yZXN1bHQAAAAAEGxhdWNocGFkRHVyYXRpb24AAAAAAAAAAGQAAAAABm9yYWNsZQkBAAAAB0FkZHJlc3MA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TAAAAAIFAAAADGFkbWluUHViS2V5MQkABEwAAAACBQAAAAxhZG1pblB1YktleTIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkzBQAAAANuaWwIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkAAAIAAAABAgAAACFPbmx5IGFkbWluIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkAASwAAAACCQABpAAAAAEFAAAAC2xhdW5jaHBhZElkBQAAAA1rZXlWZXJpZnlIYXNoBQAAAARoYXNoBQAAAANuaWwAAAABaQEAAAAKaW5pdENhbGxlcgAAAAEAAAAHYWRkcmVzcwMJAQAAAAEhAAAAAQUAAAAIaXNBY3RpdmUJAAACAAAAAQIAAAAfREFwcCBpcyBpbmFjdGl2ZSBhdCB0aGlzIG1vbWVudAMJAQAAAAEhAAAAAQkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAARMAAAAAgUAAAAMYWRtaW5QdWJLZXkxCQAETAAAAAIFAAAADGFkbWluUHViS2V5MgkABEwAAAACBQAAAAxhZG1pblB1YktleTMFAAAAA25pbAgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAIU9ubHkgYWRtaW4gY2FuIGNhbGwgdGhpcyBmdW5jdGlvbgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA1rZXlJbml0Q2FsbGVyBQAAAAdhZGRyZXNzBQAAAANuaWwAAAABaQEAAAAEaW5pdAAAAAkAAAAOcHJvamVjdEFkZHJlc3MAAAALc3RhcnRIZWlnaHQAAAAKY29tbWlzc2lvbgAAAA90b2tlbnNQZXJUaWNrZXQAAAANcHJpY2VQZXJUb2tlbgAAABNzd29wZmlUaWNrZXRzQW1vdW50AAAAFGNhbXBhaWduVG9rZW5zQW1vdW50AAAAE3Rva2Vuc1BlckFsbG9jYXRpb24AAAANc3dvcFBlclRpY2tldAQAAAALJHQwNDIwMDQyNzUJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAAskdDA0MjAwNDI3NQAAAAJfMQQAAAAKcG10QXNzZXRJZAgFAAAACyR0MDQyMDA0Mjc1AAAAAl8yAwkBAAAAASEAAAABBQAAAAhpc0FjdGl2ZQkAAAIAAAABAgAAAB9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAANa2V5SW5pdENhbGxlcgIAAAAACQAAAgAAAAECAAAAKU9ubHkgcHJvamVjdCBhZG1pbiBjYW4gY2FsbCBpbml0IGZ1bmN0aW9uAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQkAAAIAAAABAgAAAB1PbmUgYXR0YWNoZWQgcGF5bWVudCBleHBlY3RlZAMJAABmAAAAAgUAAAAGaGVpZ2h0BQAAAAtzdGFydEhlaWdodAkAAAIAAAABAgAAADNTdGFydCBoZWlnaHQgbXVzdCBiZSBncmVhdGVyIHRoYW4gYmxvY2tjaGFpbiBoZWlnaHQEAAAACyR0MDQ3MDM0Nzc2CQEAAAAMZ2V0QXNzZXRJbmZvAAAAAQUAAAAKcG10QXNzZXRJZAQAAAANcG10U3RyQXNzZXRJZAgFAAAACyR0MDQ3MDM0Nzc2AAAAAl8xBAAAAAxwbXRBc3NldE5hbWUIBQAAAAskdDA0NzAzNDc3NgAAAAJfMgQAAAALcG10RGVjaW1hbHMIBQAAAAskdDA0NzAzNDc3NgAAAAJfMwQAAAALbGF1bmNocGFkSWQJAQAAABJnZXRMYXVuY2hwYWROZXh0SWQAAAAABAAAAA5sYXVuY2hwYWRJZFN0cgkAAaQAAAABBQAAAAtsYXVuY2hwYWRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkAASwAAAACBQAAAA1wbXRTdHJBc3NldElkAgAAAApfbGF1bmNocGFkBQAAAAtsYXVuY2hwYWRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASa2V5TGF1bmNocGFkTmV4dElkCQAAZAAAAAIFAAAAC2xhdW5jaHBhZElkAAAAAAAAAAABCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAACmtleUFkZHJlc3MFAAAADnByb2plY3RBZGRyZXNzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAAA1rZXlJbml0SGVpZ2h0BQAAAAZoZWlnaHQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAADmtleVN0YXJ0SGVpZ2h0BQAAAAtzdGFydEhlaWdodAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkAASwAAAACBQAAAA5sYXVuY2hwYWRJZFN0cgUAAAALa2V5RHVyYXRpb24FAAAAEGxhdWNocGFkRHVyYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAAE2tleVRvdGFsVG9rZW5BbW91bnQFAAAACXBtdEFtb3VudAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAAAprZXlBc3NldElkBQAAAA1wbXRTdHJBc3NldElkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAAAxrZXlDb21pc3Npb24FAAAACmNvbW1pc3Npb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAAE2tleVRpY2tldExhc3ROdW1iZXIAAAAAAAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAAEmtleVRva2Vuc1BlclRpY2tldAUAAAAPdG9rZW5zUGVyVGlja2V0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAABBrZXlQcmljZVBlclRva2VuBQAAAA1wcmljZVBlclRva2VuCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAABBrZXlTd29wUGVyVGlja2V0BQAAAA1zd29wUGVyVGlja2V0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAABZrZXlTd29wZmlUaWNrZXRzQW1vdW50BQAAABNzd29wZmlUaWNrZXRzQW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIFAAAADmxhdW5jaHBhZElkU3RyBQAAABdrZXlDYW1wYWlnblRva2Vuc0Ftb3VudAUAAAAUY2FtcGFpZ25Ub2tlbnNBbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgUAAAAObGF1bmNocGFkSWRTdHIFAAAAFmtleVRva2Vuc1BlckFsbG9jYXRpb24FAAAAE3Rva2Vuc1BlckFsbG9jYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFGtleUxhdW5jaHBhZEFjdGl2ZUlkBQAAAAtsYXVuY2hwYWRJZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA1rZXlJbml0Q2FsbGVyAgAAAAAFAAAAA25pbAAAAAFpAQAAABBjb21taXRTd29wZmlTYWxlAAAAAgAAAAtsYXVuY2hwYWRJZAAAAAVyZWZJZAQAAAALJHQwNjI3MDYzNDUJAAUUAAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkBAAAAAlwbXRBbW91bnQIBQAAAAskdDA2MjcwNjM0NQAAAAJfMQQAAAAKcG10QXNzZXRJZAgFAAAACyR0MDYyNzA2MzQ1AAAAAl8yBAAAAAtzdGFrZWRTd29wcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkA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bgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkAASwAAAACCQABpAAAAAEFAAAAC2xhdW5jaHBhZElkBQAAAAxrZXlDb21pc3Npb24EAAAADnRyYW5zZmVyZWRVc2RuCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAAEsAAAAAgkAAaQAAAABBQAAAAtsYXVuY2hwYWRJZAUAAAAOa2V5VHJhbnNmZXJVc2QAAAAAAAAAAAAEAAAAF3N3b3BmaU1lbWJlcnNVc2RuQW1vdW50CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzCQABLAAAAAIJAAGkAAAAAQUAAAALbGF1bmNocGFkSWQFAAAAFmtleVRvdGFsQW1vdW50VXNkblNvbGQEAAAAFnN3b3BmaU1lbWJlcnNDb21pc3Npb24JAABrAAAAAwUAAAAXc3dvcGZpTWVtYmVyc1VzZG5BbW91bnQFAAAACmNvbW1pc3Npb24AAAAAAAAAAGQEAAAAGnRvdGFsQW1vdW50VXNkbkluTWFya2V0aW5nCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzCQABLAAAAAIJAAGkAAAAAQUAAAALbGF1bmNocGFkSWQFAAAAIWtleUFtb3VudFVTRE5Jbk1hcmtldGluZ0ZpbmFsaXplZAQAAAASbWFya2V0aW5nQ29taXNzaW9uCQAAawAAAAMFAAAAGnRvdGFsQW1vdW50VXNkbkluTWFya2V0aW5nBQAAAApjb21taXNzaW9uAAAAAAAAAABkBAAAAA11bnN0YWtlQW1vdW50CQAAZAAAAAIJAABkAAAAAgkAAGQAAAACBQAAABdzd29wZmlNZW1iZXJzVXNkbkFtb3VudAUAAAAadG90YWxBbW91bnRVc2RuSW5NYXJrZXRpbmcFAAAAFnN3b3BmaU1lbWJlcnNDb21pc3Npb24FAAAAEm1hcmtldGluZ0NvbWlzc2lvbgMJAABmAAAAAgUAAAAOdHJhbnNmZXJlZFVzZG4JAABkAAAAAgUAAAAXc3dvcGZpTWVtYmVyc1VzZG5BbW91bnQFAAAAGnRvdGFsQW1vdW50VXNkbkluTWFya2V0aW5nCQAAAgAAAAECAAAAKENhbid0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AaQAAAABBQAAAAtsYXVuY2hwYWRJZAUAAAAaa2V5VXNlcldpbm5lZFRpY2tldHNBbW91bnQAAAAAAAAAAAAEAAAAFGF3YWlsYWJsZUFsbG9jYXRpb25zCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyAgAAAAFfCQABpAAAAAEFAAAAC2xhdW5jaHBhZElkBQAAABtrZXlVc2VyQXZhaWxhYmxlQWxsb2NhdGlvbnMAAAAAAAAAAAAEAAAACmNvbW1pc3Npb24JAQAAABFAZXh0ck5hdGl2ZSgxMDUwKQAAAAIFAAAABHRoaXMJAAEsAAAAAgkAAaQAAAABBQAAAAtsYXVuY2hwYWRJZAUAAAAMa2V5Q29taXNzaW9uBAAAABJhbGxvd2VkQWxsb2NhdGlvbnMJAAGXAAAAAQkABEwAAAACBQAAABFib3VnaHRBbGxvY2F0aW9ucwkABEwAAAACBQAAABRhd2FpbGFibGVBbGxvY2F0aW9ucwUAAAADbmlsBAAAAAp0b2tlblByaWNlCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzCQABLAAAAAIJAAGkAAAAAQUAAAALbGF1bmNocGFkSWQFAAAAEGtleVByaWNlUGVyVG9rZW4EAAAAD3Rva2Vuc1BlclRpY2tldAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkAASwAAAACCQABpAAAAAEFAAAAC2xhdW5jaHBhZElkBQAAABJrZXlUb2tlbnNQZXJUaWNrZXQEAAAADSR0MDE2OTQ1MTcwMjEJAQAAAAxnZXRBc3NldEluZm8AAAABBQAAAAd0b2tlbklkBAAAAA90b2tlblN0ckFzc2V0SWQIBQAAAA0kdDAxNjk0NTE3MDIxAAAAAl8xBAAAAA50b2tlbkFzc2V0TmFtZQgFAAAADSR0MDE2OTQ1MTcwMjEAAAACXzIEAAAADXRva2VuRGVjaW1hbHMIBQAAAA0kdDAxNjk0NTE3MDIxAAAAAl8zBAAAAAt0aWNrZXRQcmljZQkAAGsAAAADBQAAAA90b2tlbnNQZXJUaWNrZXQFAAAACnRva2VuUHJpY2UJAABsAAAABgAAAAAAAAAACgAAAAAAAAAAAAUAAAANdG9rZW5EZWNpbWFscwAAAAAAAAAAAAAAAAAAAAAAAAUAAAAERE9XTgQAAAATdG9rZW5zUGVyQWxsb2NhdGlvbgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkAASwAAAACCQABpAAAAAEFAAAAC2xhdW5jaHBhZElkBQAAABZrZXlUb2tlbnNQZXJBbGxvY2F0aW9uBAAAABR0cmFuc2ZlclRva2Vuc0Ftb3VudAkAAGQAAAACCQAAaAAAAAIFAAAADXdvbm5lZFRpY2tldHMFAAAAD3Rva2Vuc1BlclRpY2tldAkAAGgAAAACBQAAABJhbGxvd2VkQWxsb2NhdGlvbnMFAAAAE3Rva2Vuc1BlckFsbG9jYXRpb24EAAAAG25vdEFsbG93ZWRBbGxvY2F0aW9uc1Rva2VucwkAAGgAAAACCQAAZQAAAAIFAAAAEWJvdWdodEFsbG9jYXRpb25zBQAAABJhbGxvd2VkQWxsb2NhdGlvbnMFAAAAE3Rva2Vuc1BlckFsbG9jYXRpb24EAAAAEnVzZG5Gb3JBbGxvY2F0aW9ucwkAAGsAAAADCQAAawAAAAMFAAAAG25vdEFsbG93ZWRBbGxvY2F0aW9uc1Rva2VucwUAAAAKdG9rZW5QcmljZQkAAGwAAAAGAAAAAAAAAAAKAAAAAAAAAAAABQAAAA10b2tlbkRlY2ltYWxzAAAAAAAAAAAAAAAAAAAAAAAABQAAAARET1dOCQAAZAAAAAIAAAAAAAAAAGQFAAAACmNvbW1pc3Npb24AAAAAAAAAAGQEAAAAFnVzZG5Gb3JVbndvbm5lZFRpY2tldHMJAABrAAAAAwkAAGgAAAACCQAAZQAAAAIFAAAADWJvdWdodFRpY2tldHMFAAAADXdvbm5lZFRpY2tldHMFAAAAC3RpY2tldFByaWNlCQAAZAAAAAIAAAAAAAAAAGQFAAAACmNvbW1pc3Npb24AAAAAAAAAAGQDAwkAAGYAAAACAAAAAAAAAAAABQAAABJ1c2RuRm9yQWxsb2NhdGlvbnMGCQAAZgAAAAIAAAAAAAAAAAAFAAAAFnVzZG5Gb3JVbndvbm5lZFRpY2tldHMJAAACAAAAAQIAAABSRXJyb3Igd2l0aCBh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", "height": 1813860, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BAaUTUxAp6nNLCyN5sLJ8gxi4hE9EwJ68Kmy9edw8q9b Next: 3DWedvTbm36mW5YHnShZYJrsqLZbNHYMZ2uDJp5fBE6L Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let keyActive = "active"
5-
6-let keyEndHeight = "end_height"
7-
8-let keyPrizesPrices = "prizes_prices"
9-
10-let keyPrizesAIds = "prizes_achievements_ids"
11-
12-let keyPrizesAmounts = "prizes_amount"
13-
14-let keyLevelPrices = "level_prices"
15-
16-let keyLevelAchievemntsIds = "level_achievements_ids"
17-
18-let keySWOPid = "SWOP_id"
19-
20-let keyTotalBurned = "total_burned"
21-
22-let keyVerifyHash = "verify_hash"
23-
24-let keyFinalizeHeight = "finalize_height"
25-
26-let keyUserTotalBurned = "_total_burned"
27-
28-let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
29-
30-let farming = Address(base58'3MsxHxruYWoddB4HRiPBYAWtMXMtCF1V9XT')
31-
32-let achievements = Address(base58'3N3HtdnBkqSSc16DaydiwtrMBUv3DfqKjSW')
335
346 let keyAdminPubKey1 = "admin_pub_1"
357
368 let keyAdminPubKey2 = "admin_pub_2"
379
3810 let keyAdminPubKey3 = "admin_pub_3"
11+
12+let keyLaunchpadDataTransactionStatus = "launchpad_data_transaction_status"
13+
14+let keyLaunchpadNextId = "launchpad_next_id"
15+
16+let keyLaunchpadActiveId = "launchpad_active_id"
17+
18+let keyInitCaller = "init_caller"
19+
20+let keyAddress = "_address"
21+
22+let keyInitHeight = "_init_height"
23+
24+let keyStartHeight = "_start_height"
25+
26+let keyFinaliseHeight = "_finalise_height"
27+
28+let keyComission = "_comission"
29+
30+let keyAssetId = "_asset_id"
31+
32+let keyTotalTokenAmount = "_total_token_amount"
33+
34+let keyTotalAmountUsdnSold = "_total_usdn_sold"
35+
36+let keyTokensPerTicket = "_tokens_per_ticket"
37+
38+let keyPricePerToken = "_price_per_token"
39+
40+let keySwopPerTicket = "_swop_per_ticket"
41+
42+let keySwopfiTicketsAmount = "_tickets_swopfi_members"
43+
44+let keyCampaignTokensAmount = "_tokens_access_list"
45+
46+let keyTokensPerAllocation = "_tokens_per_allocation"
47+
48+let keyTicketLastNumber = "_ticket_last_number"
49+
50+let keyGovernanceStaked = "_SWOP_amount"
51+
52+let keyUserRefId = "_ref_id"
53+
54+let keyVerifyHash = "_verify_hash"
55+
56+let keyDuration = "_duration"
57+
58+let keyAmountUSDNInMarketing = "_total_purchased_usdn_in_marketing"
59+
60+let keyAmountUSDNInMarketingFinalized = "_total_purchased_usdn_in_marketing_finalized"
61+
62+let keyTransferUsd = "_transfer_usd"
63+
64+let keyUserBoughtTicketsAmount = "_bought_tickets"
65+
66+let keyUserTickets = "_tickets_number"
67+
68+let keyUserAvailableAllocations = "_available_purchase_marketing"
69+
70+let keyUserAmountUSDNInMarketing = "_purchased_usdn_in_marketing"
71+
72+let keyUserBoughtAllocations = "_bought_allocations"
73+
74+let keyUserClaimStatus = "_claim_status"
75+
76+let keyUserWinnedTicketsAmount = "_tickets_result"
77+
78+let lauchpadDuration = 100
79+
80+let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
81+
82+let governance = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
83+
84+let commissionWallet = Address(base58'3N2hBdeDEs7wCNA9EY8qv3B6drjgKD64xQG')
85+
86+let stakingUSDNAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
87+
88+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
89+
90+let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
91+
92+let maxAllocationsAmount = 2
93+
94+let isActive = valueOrElse(getBoolean(this, keyActive), true)
95+
96+let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
3997
4098 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
4199 case string: String =>
51109
52110 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
53111
54-let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
55-
56-let swopId = fromBase58String(getStringValue(farming, keySWOPid))
57-
58-let isActive = valueOrElse(getBoolean(this, keyActive), true)
59-
60-func inListToStr (acc,next) = if ((acc == ""))
61- then (acc + toString(next))
62- else ((acc + ",") + toString(next))
112+func getAssetInfo (assetId) = match assetId {
113+ case id: ByteVector =>
114+ let stringId = toBase58String(id)
115+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
116+ $Tuple3(stringId, info.name, info.decimals)
117+ case waves: Unit =>
118+ $Tuple3("WAVES", "WAVES", 8)
119+ case _ =>
120+ throw("Match error")
121+}
63122
64123
65-func inListToInt (acc,next) = (acc :+ parseIntValue(next))
124+func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
66125
67126
68-func calcPrizesAmounts (acc,next) = {
69- let $t016511676 = acc
70- let total = $t016511676._1
71- let result = $t016511676._2
72- $Tuple2(total, (result :+ (total / next)))
73- }
74-
75-
76-func calcLevel (burned) = {
77- let levelPrices = {
78- let $l = split(getStringValue(this, keyLevelPrices), ",")
79- let $s = size($l)
80- let $acc0 = nil
81- func 1 ($a,$i) = if (($i >= $s))
82- then $a
83- else inListToInt($a, $l[$i])
84-
85- func 2 ($a,$i) = if (($i >= $s))
86- then $a
87- else throw("List size exceeds 5")
88-
89- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
90- }
91- if ((levelPrices[3] >= burned))
92- then 4
93- else if ((levelPrices[2] >= burned))
94- then 3
95- else if ((levelPrices[1] >= burned))
96- then 2
97- else if ((levelPrices[0] >= burned))
98- then 1
99- else 0
100- }
127+func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
101128
102129
103130 @Callable(i)
104-func init (endHeight,prizePrices,prizeAchievmentsIds,levelPrices,levelAchievmentsIds) = if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
105- then throw("Only admin can call this function")
106- else if (isDefined(getInteger(this, keyEndHeight)))
107- then throw("DApp is already inited")
108- else if ((height > endHeight))
109- then throw("Burning ending must be greater than current height")
110- else if (if ((size(prizePrices) != 5))
111- then true
112- else (size(prizeAchievmentsIds) != 5))
113- then throw("Amount of prizes achievemts lists must equal to 5")
114- else if (if ((size(levelPrices) != 4))
115- then true
116- else (size(levelAchievmentsIds) != 4))
117- then throw("Amount of levels lists must equal to 4")
118- else {
119- let prizePricesStr = {
120- let $l = prizePrices
121- let $s = size($l)
122- let $acc0 = ""
123- func 1 ($a,$i) = if (($i >= $s))
124- then $a
125- else inListToStr($a, $l[$i])
126-
127- func 2 ($a,$i) = if (($i >= $s))
128- then $a
129- else throw("List size exceeds 5")
130-
131- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
132- }
133- let prizeAchievmentsIdsStr = makeString(prizeAchievmentsIds, ",")
134- let levelPricesStr = {
135- let $l = levelPrices
136- let $s = size($l)
137- let $acc0 = ""
138- func 1 ($a,$i) = if (($i >= $s))
139- then $a
140- else inListToStr($a, $l[$i])
141-
142- func 2 ($a,$i) = if (($i >= $s))
143- then $a
144- else throw("List size exceeds 5")
145-
146- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
147- }
148- let levelAchievmentsIdsStr = makeString(levelAchievmentsIds, ",")
149- let prizesAmountStr = "0,0,0,0,0"
150-[IntegerEntry(keyEndHeight, endHeight), StringEntry(keyPrizesPrices, prizePricesStr), StringEntry(keyPrizesAIds, prizeAchievmentsIdsStr), StringEntry(keyLevelPrices, levelPricesStr), StringEntry(keyLevelAchievemntsIds, levelAchievmentsIdsStr), StringEntry(keyPrizesAmounts, prizesAmountStr)]
151- }
131+func hashingRandom (launchpadId,hash) = if (!(isActive))
132+ then throw("DApp is inactive at this moment")
133+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
134+ then throw("Only admin can call this function")
135+ else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
152136
153137
154138
155139 @Callable(i)
156-func add () = {
157- let $t035253600 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
158- let pmtAmount = $t035253600._1
159- let pmtAssetId = $t035253600._2
160- let endHeight = valueOrElse(getInteger(this, keyEndHeight), 0)
140+func initCaller (address) = if (!(isActive))
141+ then throw("DApp is inactive at this moment")
142+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
143+ then throw("Only admin can call this function")
144+ else [StringEntry(keyInitCaller, address)]
145+
146+
147+
148+@Callable(i)
149+func init (projectAddress,startHeight,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket) = {
150+ let $t042004275 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
151+ let pmtAmount = $t042004275._1
152+ let pmtAssetId = $t042004275._2
161153 if (!(isActive))
162154 then throw("DApp is inactive at this moment")
163- else if (if ((height > endHeight))
164- then true
165- else (endHeight == 0))
166- then throw("Swop burning are ended or not started yet")
167- else if ((pmtAssetId != swopId))
168- then throw("You can add only SWOP token")
169- else {
170- let newTotalBurned = (valueOrElse(getInteger(this, keyTotalBurned), 0) + pmtAmount)
171- let userTotalBurned = valueOrElse(getInteger(this, (toString(i.caller) + keyUserTotalBurned)), 0)
172- let prizesAmounts = {
173- let $l = split(getStringValue(this, keyPrizesAmounts), ",")
174- let $s = size($l)
175- let $acc0 = nil
176- func 1 ($a,$i) = if (($i >= $s))
177- then $a
178- else inListToInt($a, $l[$i])
179-
180- func 2 ($a,$i) = if (($i >= $s))
181- then $a
182- else throw("List size exceeds 5")
183-
184- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
155+ else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
156+ then throw("Only project admin can call init function")
157+ else if ((size(i.payments) != 1))
158+ then throw("One attached payment expected")
159+ else if ((height > startHeight))
160+ then throw("Start height must be greater than blockchain height")
161+ else {
162+ let $t047034776 = getAssetInfo(pmtAssetId)
163+ let pmtStrAssetId = $t047034776._1
164+ let pmtAssetName = $t047034776._2
165+ let pmtDecimals = $t047034776._3
166+ let launchpadId = getLaunchpadNextId()
167+ let launchpadIdStr = toString(launchpadId)
168+[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 + 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, "")]
185169 }
186- let prizesPrices = {
187- let $l = split(getStringValue(this, keyPrizesPrices), ",")
188- let $s = size($l)
189- let $acc0 = nil
190- func 1 ($a,$i) = if (($i >= $s))
191- then $a
192- else inListToInt($a, $l[$i])
193-
194- func 2 ($a,$i) = if (($i >= $s))
195- then $a
196- else throw("List size exceeds 5")
197-
198- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
199- }
200- let prizesAchievementsIds = split(getStringValue(this, keyPrizesAIds), ",")
201- let levelAchievementsIds = split(getStringValue(this, keyLevelAchievemntsIds), ",")
202- let res = {
203- let $l = prizesPrices
204- let $s = size($l)
205- let $acc0 = $Tuple2(newTotalBurned, nil)
206- func 1 ($a,$i) = if (($i >= $s))
207- then $a
208- else calcPrizesAmounts($a, $l[$i])
209-
210- func 2 ($a,$i) = if (($i >= $s))
211- then $a
212- else throw("List size exceeds 5")
213-
214- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
215- }
216- let newPrizesAmounts = res._2
217- let newPrizesAmountsStr = {
218- let $l = newPrizesAmounts
219- let $s = size($l)
220- let $acc0 = ""
221- func 1 ($a,$i) = if (($i >= $s))
222- then $a
223- else inListToStr($a, $l[$i])
224-
225- func 2 ($a,$i) = if (($i >= $s))
226- then $a
227- else throw("List size exceeds 5")
228-
229- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
230- }
231- let inv0 = if ((newPrizesAmounts[0] != prizesAmounts[0]))
232- then {
233- let achievementAmount = (newPrizesAmounts[0] - prizesAmounts[0])
234- invoke(achievements, "add", [prizesAchievementsIds[0], achievementAmount], nil)
235- }
236- else 0
237- if ((inv0 == inv0))
238- then {
239- let inv1 = if ((newPrizesAmounts[1] != prizesAmounts[1]))
240- then {
241- let achievementAmount = (newPrizesAmounts[1] - prizesAmounts[1])
242- invoke(achievements, "add", [prizesAchievementsIds[1], achievementAmount], nil)
243- }
244- else 0
245- if ((inv1 == inv1))
246- then {
247- let inv2 = if ((newPrizesAmounts[2] != prizesAmounts[2]))
248- then {
249- let achievementAmount = (newPrizesAmounts[2] - prizesAmounts[2])
250- invoke(achievements, "add", [prizesAchievementsIds[2], achievementAmount], nil)
251- }
252- else 0
253- if ((inv2 == inv2))
254- then {
255- let inv3 = if ((newPrizesAmounts[3] != prizesAmounts[3]))
256- then {
257- let achievementAmount = (newPrizesAmounts[3] - prizesAmounts[3])
258- invoke(achievements, "add", [prizesAchievementsIds[3], achievementAmount], nil)
259- }
260- else 0
261- if ((inv3 == inv3))
262- then {
263- let inv4 = if ((newPrizesAmounts[4] != prizesAmounts[4]))
264- then {
265- let achievementAmount = (newPrizesAmounts[4] - prizesAmounts[4])
266- invoke(achievements, "add", [prizesAchievementsIds[4], achievementAmount], nil)
267- }
268- else 0
269- if ((inv4 == inv4))
270- then {
271- let baseEntry = [IntegerEntry(keyTotalBurned, newTotalBurned), IntegerEntry((toString(i.caller) + keyUserTotalBurned), (userTotalBurned + pmtAmount)), StringEntry(keyPrizesAmounts, newPrizesAmountsStr)]
272- let oldLevel = calcLevel(userTotalBurned)
273- let newLevel = calcLevel(newTotalBurned)
274- let levelDiff = (newLevel - oldLevel)
275- if ((levelDiff > 0))
276- then {
277- let inv5 = if ((levelDiff == 1))
278- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
279- else 0
280- if ((inv5 == inv5))
281- then {
282- let inv6 = if ((levelDiff >= 2))
283- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
284- else 0
285- if ((inv6 == inv6))
286- then {
287- let inv7 = if ((levelDiff >= 3))
288- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
289- else 0
290- if ((inv7 == inv7))
291- then {
292- let inv8 = if ((levelDiff == 4))
293- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
294- else 0
295- if ((inv8 == inv8))
296- then baseEntry
297- else throw("Strict value is not equal to itself.")
298- }
299- else throw("Strict value is not equal to itself.")
300- }
301- else throw("Strict value is not equal to itself.")
302- }
303- else throw("Strict value is not equal to itself.")
304- }
305- else baseEntry
306- }
307- else throw("Strict value is not equal to itself.")
308- }
309- else throw("Strict value is not equal to itself.")
310- }
311- else throw("Strict value is not equal to itself.")
312- }
313- else throw("Strict value is not equal to itself.")
314- }
315- else throw("Strict value is not equal to itself.")
316- }
317170 }
318171
319172
320173
321174 @Callable(i)
322-func hashingRandom (hash) = if (!(isActive))
323- then throw("DApp is inactive at this moment")
324- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
325- then throw("Only admin can call this function")
326- else [StringEntry(keyVerifyHash, hash)]
175+func commitSwopfiSale (launchpadId,refId) = {
176+ let $t062706345 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
177+ let pmtAmount = $t062706345._1
178+ let pmtAssetId = $t062706345._2
179+ let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
180+ let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
181+ let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
182+ let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
183+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
184+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
185+ if (!(isActive))
186+ then throw("DApp is inactive at this moment")
187+ else if ((activeLaunchpadId != launchpadId))
188+ then throw("There is no active launchpad or this launchpad is ended")
189+ else if ((startHeight > height))
190+ then throw("Launchpad sale not started yet")
191+ else if ((height > (startHeight + duration)))
192+ then throw("Launchpad sale ended")
193+ else if (if ((size(i.payments) != 1))
194+ then true
195+ else (pmtAssetId != USDN))
196+ then throw("One attached payment in USDN expected")
197+ else if (if ((0 >= allowedTicketsAmountAll))
198+ then true
199+ else (0 >= allowedTicketsAmount))
200+ then throw("Not enought SWOP in staking to buy tickets")
201+ else {
202+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
203+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
204+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
205+ let $t078697945 = getAssetInfo(tokenId)
206+ let tokenStrAssetId = $t078697945._1
207+ let tokenAssetName = $t078697945._2
208+ let tokenDecimals = $t078697945._3
209+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
210+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
211+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
212+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
213+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
214+ let change = (pmtAmount - allowedBuyPriceWithComission)
215+ if ((buyTicketAmount == 0))
216+ then throw("Not enought USDN to buy tickets")
217+ else if ((change != 0))
218+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + "USDN"))
219+ else {
220+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
221+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
222+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
223+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
224+ then ("," + boughtRange)
225+ else ("" + boughtRange)))
226+ let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
227+ if ((inv == inv))
228+ then {
229+ 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)]
230+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
231+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
232+ else baseEntry
233+ }
234+ else throw("Strict value is not equal to itself.")
235+ }
236+ }
237+ }
327238
328239
329240
330241 @Callable(i)
331-func finalize (vrfHeight,secretWord) = {
332- let savedHash = getStringValue(this, keyVerifyHash)
242+func commitAccessListSale (launchpadId,refId) = {
243+ let $t01026510340 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
244+ let pmtAmount = $t01026510340._1
245+ let pmtAssetId = $t01026510340._2
246+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing)), 0)
247+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountUSDNInMarketing)), 0)
248+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
249+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
250+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
251+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
252+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
253+ let $t01109511171 = getAssetInfo(tokenId)
254+ let tokenStrAssetId = $t01109511171._1
255+ let tokenAssetName = $t01109511171._2
256+ let tokenDecimals = $t01109511171._3
257+ let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
258+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
259+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
260+ if (!(isActive))
261+ then throw("DApp is inactive at this moment")
262+ else if ((activeLaunchpadId != launchpadId))
263+ then throw("There is no active launchpad or this launchpad is ended")
264+ else if ((startHeight > height))
265+ then throw("Launchpad sale not started yet")
266+ else if ((height > (startHeight + duration)))
267+ then throw("Launchpad sale ended")
268+ else if (if ((size(i.payments) != 1))
269+ then true
270+ else (pmtAssetId != USDN))
271+ then throw("One attached payment in USDN expected")
272+ else if ((boughtAllocations >= maxAllocationsAmount))
273+ then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
274+ else if (if ((allocationPriceWithComission != pmtAmount))
275+ then ((allocationPriceWithComission * 2) != pmtAmount)
276+ else false)
277+ then throw((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + " USDN per allocation"))
278+ else {
279+ let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
280+ let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
281+ if ((inv == inv))
282+ then {
283+ 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))]
284+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
285+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
286+ else baseEntry
287+ }
288+ else throw("Strict value is not equal to itself.")
289+ }
290+ }
291+
292+
293+
294+@Callable(i)
295+func finalise (launchpadId,vrfHeight,secretWord) = {
296+ let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
333297 let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
334298 if (!(isActive))
335299 then throw("DApp is inactive at this moment")
338302 else if ((calcHash != savedHash))
339303 then throw("vrf Height hash not matching")
340304 else {
341- let burnAmount = getIntegerValue(this, keyTotalBurned)
342-[Burn(swopId, burnAmount), IntegerEntry(keyFinalizeHeight, height)]
305+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
306+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
307+ let transferedUsdn = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferUsd)), 0)
308+ let swopfiMembersUsdnAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountUsdnSold))
309+ let swopfiMembersComission = fraction(swopfiMembersUsdnAmount, commission, 100)
310+ let totalAmountUsdnInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountUSDNInMarketingFinalized))
311+ let marketingComission = fraction(totalAmountUsdnInMarketing, commission, 100)
312+ let unstakeAmount = (((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) + swopfiMembersComission) + marketingComission)
313+ if ((transferedUsdn > (swopfiMembersUsdnAmount + totalAmountUsdnInMarketing)))
314+ then throw("Can't transfer negative value to project")
315+ else {
316+ let inv = invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
317+ if ((inv == inv))
318+ then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) - transferedUsdn), USDN), ScriptTransfer(commissionWallet, (swopfiMembersComission + marketingComission), USDN)]
319+ else throw("Strict value is not equal to itself.")
320+ }
343321 }
344322 }
323+
324+
325+
326+@Callable(i)
327+func claim (launchpadId) = {
328+ let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
329+ let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
330+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
331+ if (!(isActive))
332+ then throw("DApp is inactive at this moment")
333+ else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
334+ then throw("You can't claim because results are not finalized")
335+ else if (userClaimStatus)
336+ then throw("You are already claimed")
337+ else if (if ((boughtTickets == 0))
338+ then (boughtAllocations == 0)
339+ else false)
340+ then throw("You can't claim because you don't buy anything")
341+ else {
342+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
343+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
344+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
345+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
346+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
347+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
348+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
349+ let $t01694517021 = getAssetInfo(tokenId)
350+ let tokenStrAssetId = $t01694517021._1
351+ let tokenAssetName = $t01694517021._2
352+ let tokenDecimals = $t01694517021._3
353+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
354+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
355+ let transferTokensAmount = ((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation))
356+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
357+ let usdnForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
358+ let usdnForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
359+ if (if ((0 > usdnForAllocations))
360+ then true
361+ else (0 > usdnForUnwonnedTickets))
362+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
363+ else {
364+ let returnedUsdnAmount = (usdnForAllocations + usdnForUnwonnedTickets)
365+ let transferUsdn = if ((returnedUsdnAmount > 0))
366+ then [ScriptTransfer(i.caller, returnedUsdnAmount, USDN)]
367+ else nil
368+ let transferTokens = if ((transferTokensAmount > 0))
369+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
370+ else nil
371+ let inv = if ((returnedUsdnAmount > 0))
372+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedUsdnAmount, toBase58String(USDN)], nil)
373+ else 0
374+ if ((inv == inv))
375+ then (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)] ++ transferTokens) ++ transferUsdn)
376+ else throw("Strict value is not equal to itself.")
377+ }
378+ }
379+ }
380+
381+
382+
383+@Callable(i)
384+func transferUsd (launchpadId,amountUsdn) = if (!(isActive))
385+ then throw("DApp is inactive")
386+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
387+ then throw("Only admin can call this function")
388+ else {
389+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
390+[IntegerEntry((toString(launchpadId) + keyTransferUsd), amountUsdn), ScriptTransfer(projectAddress, amountUsdn, USDN)]
391+ }
345392
346393
347394
384431 then true
385432 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
386433 match tx {
434+ case dtx: DataTransaction =>
435+ if (valueOrElse(getBoolean(oracle, keyLaunchpadDataTransactionStatus), false))
436+ then signedByAdmin
437+ else false
387438 case _ =>
388439 multiSignedByAdmins
389440 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let keyActive = "active"
5-
6-let keyEndHeight = "end_height"
7-
8-let keyPrizesPrices = "prizes_prices"
9-
10-let keyPrizesAIds = "prizes_achievements_ids"
11-
12-let keyPrizesAmounts = "prizes_amount"
13-
14-let keyLevelPrices = "level_prices"
15-
16-let keyLevelAchievemntsIds = "level_achievements_ids"
17-
18-let keySWOPid = "SWOP_id"
19-
20-let keyTotalBurned = "total_burned"
21-
22-let keyVerifyHash = "verify_hash"
23-
24-let keyFinalizeHeight = "finalize_height"
25-
26-let keyUserTotalBurned = "_total_burned"
27-
28-let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
29-
30-let farming = Address(base58'3MsxHxruYWoddB4HRiPBYAWtMXMtCF1V9XT')
31-
32-let achievements = Address(base58'3N3HtdnBkqSSc16DaydiwtrMBUv3DfqKjSW')
335
346 let keyAdminPubKey1 = "admin_pub_1"
357
368 let keyAdminPubKey2 = "admin_pub_2"
379
3810 let keyAdminPubKey3 = "admin_pub_3"
11+
12+let keyLaunchpadDataTransactionStatus = "launchpad_data_transaction_status"
13+
14+let keyLaunchpadNextId = "launchpad_next_id"
15+
16+let keyLaunchpadActiveId = "launchpad_active_id"
17+
18+let keyInitCaller = "init_caller"
19+
20+let keyAddress = "_address"
21+
22+let keyInitHeight = "_init_height"
23+
24+let keyStartHeight = "_start_height"
25+
26+let keyFinaliseHeight = "_finalise_height"
27+
28+let keyComission = "_comission"
29+
30+let keyAssetId = "_asset_id"
31+
32+let keyTotalTokenAmount = "_total_token_amount"
33+
34+let keyTotalAmountUsdnSold = "_total_usdn_sold"
35+
36+let keyTokensPerTicket = "_tokens_per_ticket"
37+
38+let keyPricePerToken = "_price_per_token"
39+
40+let keySwopPerTicket = "_swop_per_ticket"
41+
42+let keySwopfiTicketsAmount = "_tickets_swopfi_members"
43+
44+let keyCampaignTokensAmount = "_tokens_access_list"
45+
46+let keyTokensPerAllocation = "_tokens_per_allocation"
47+
48+let keyTicketLastNumber = "_ticket_last_number"
49+
50+let keyGovernanceStaked = "_SWOP_amount"
51+
52+let keyUserRefId = "_ref_id"
53+
54+let keyVerifyHash = "_verify_hash"
55+
56+let keyDuration = "_duration"
57+
58+let keyAmountUSDNInMarketing = "_total_purchased_usdn_in_marketing"
59+
60+let keyAmountUSDNInMarketingFinalized = "_total_purchased_usdn_in_marketing_finalized"
61+
62+let keyTransferUsd = "_transfer_usd"
63+
64+let keyUserBoughtTicketsAmount = "_bought_tickets"
65+
66+let keyUserTickets = "_tickets_number"
67+
68+let keyUserAvailableAllocations = "_available_purchase_marketing"
69+
70+let keyUserAmountUSDNInMarketing = "_purchased_usdn_in_marketing"
71+
72+let keyUserBoughtAllocations = "_bought_allocations"
73+
74+let keyUserClaimStatus = "_claim_status"
75+
76+let keyUserWinnedTicketsAmount = "_tickets_result"
77+
78+let lauchpadDuration = 100
79+
80+let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
81+
82+let governance = Address(base58'3N5W8da2iiijVieA6qLGo7KzCJj8B19smWU')
83+
84+let commissionWallet = Address(base58'3N2hBdeDEs7wCNA9EY8qv3B6drjgKD64xQG')
85+
86+let stakingUSDNAddress = Address(base58'3N6q7sCGSSLBUXDdjBdYGTJbZGZfhhh8cNg')
87+
88+let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
89+
90+let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
91+
92+let maxAllocationsAmount = 2
93+
94+let isActive = valueOrElse(getBoolean(this, keyActive), true)
95+
96+let activeLaunchpadId = valueOrElse(getIntegerValue(this, keyLaunchpadActiveId), -1)
3997
4098 func getAdminPub (keyAdminPub) = match getString(oracle, keyAdminPub) {
4199 case string: String =>
42100 fromBase58String(string)
43101 case nothing =>
44102 throw("Admin public key is empty")
45103 }
46104
47105
48106 let adminPubKey1 = getAdminPub(keyAdminPubKey1)
49107
50108 let adminPubKey2 = getAdminPub(keyAdminPubKey2)
51109
52110 let adminPubKey3 = getAdminPub(keyAdminPubKey3)
53111
54-let adminPubKeyStaking = base58'Kn7NpzaG12dLZgcHf2ipUftU6hbJygmrhFqQYE4B7ZK'
55-
56-let swopId = fromBase58String(getStringValue(farming, keySWOPid))
57-
58-let isActive = valueOrElse(getBoolean(this, keyActive), true)
59-
60-func inListToStr (acc,next) = if ((acc == ""))
61- then (acc + toString(next))
62- else ((acc + ",") + toString(next))
112+func getAssetInfo (assetId) = match assetId {
113+ case id: ByteVector =>
114+ let stringId = toBase58String(id)
115+ let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
116+ $Tuple3(stringId, info.name, info.decimals)
117+ case waves: Unit =>
118+ $Tuple3("WAVES", "WAVES", 8)
119+ case _ =>
120+ throw("Match error")
121+}
63122
64123
65-func inListToInt (acc,next) = (acc :+ parseIntValue(next))
124+func getLaunchpadNextId () = valueOrElse(getInteger(this, keyLaunchpadNextId), 1)
66125
67126
68-func calcPrizesAmounts (acc,next) = {
69- let $t016511676 = acc
70- let total = $t016511676._1
71- let result = $t016511676._2
72- $Tuple2(total, (result :+ (total / next)))
73- }
74-
75-
76-func calcLevel (burned) = {
77- let levelPrices = {
78- let $l = split(getStringValue(this, keyLevelPrices), ",")
79- let $s = size($l)
80- let $acc0 = nil
81- func 1 ($a,$i) = if (($i >= $s))
82- then $a
83- else inListToInt($a, $l[$i])
84-
85- func 2 ($a,$i) = if (($i >= $s))
86- then $a
87- else throw("List size exceeds 5")
88-
89- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
90- }
91- if ((levelPrices[3] >= burned))
92- then 4
93- else if ((levelPrices[2] >= burned))
94- then 3
95- else if ((levelPrices[1] >= burned))
96- then 2
97- else if ((levelPrices[0] >= burned))
98- then 1
99- else 0
100- }
127+func stakedUsdnAmount () = valueOrElse(getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(USDN)) + "_") + toString(this))), 0)
101128
102129
103130 @Callable(i)
104-func init (endHeight,prizePrices,prizeAchievmentsIds,levelPrices,levelAchievmentsIds) = if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
105- then throw("Only admin can call this function")
106- else if (isDefined(getInteger(this, keyEndHeight)))
107- then throw("DApp is already inited")
108- else if ((height > endHeight))
109- then throw("Burning ending must be greater than current height")
110- else if (if ((size(prizePrices) != 5))
111- then true
112- else (size(prizeAchievmentsIds) != 5))
113- then throw("Amount of prizes achievemts lists must equal to 5")
114- else if (if ((size(levelPrices) != 4))
115- then true
116- else (size(levelAchievmentsIds) != 4))
117- then throw("Amount of levels lists must equal to 4")
118- else {
119- let prizePricesStr = {
120- let $l = prizePrices
121- let $s = size($l)
122- let $acc0 = ""
123- func 1 ($a,$i) = if (($i >= $s))
124- then $a
125- else inListToStr($a, $l[$i])
126-
127- func 2 ($a,$i) = if (($i >= $s))
128- then $a
129- else throw("List size exceeds 5")
130-
131- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
132- }
133- let prizeAchievmentsIdsStr = makeString(prizeAchievmentsIds, ",")
134- let levelPricesStr = {
135- let $l = levelPrices
136- let $s = size($l)
137- let $acc0 = ""
138- func 1 ($a,$i) = if (($i >= $s))
139- then $a
140- else inListToStr($a, $l[$i])
141-
142- func 2 ($a,$i) = if (($i >= $s))
143- then $a
144- else throw("List size exceeds 5")
145-
146- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
147- }
148- let levelAchievmentsIdsStr = makeString(levelAchievmentsIds, ",")
149- let prizesAmountStr = "0,0,0,0,0"
150-[IntegerEntry(keyEndHeight, endHeight), StringEntry(keyPrizesPrices, prizePricesStr), StringEntry(keyPrizesAIds, prizeAchievmentsIdsStr), StringEntry(keyLevelPrices, levelPricesStr), StringEntry(keyLevelAchievemntsIds, levelAchievmentsIdsStr), StringEntry(keyPrizesAmounts, prizesAmountStr)]
151- }
131+func hashingRandom (launchpadId,hash) = if (!(isActive))
132+ then throw("DApp is inactive at this moment")
133+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
134+ then throw("Only admin can call this function")
135+ else [StringEntry((toString(launchpadId) + keyVerifyHash), hash)]
152136
153137
154138
155139 @Callable(i)
156-func add () = {
157- let $t035253600 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
158- let pmtAmount = $t035253600._1
159- let pmtAssetId = $t035253600._2
160- let endHeight = valueOrElse(getInteger(this, keyEndHeight), 0)
140+func initCaller (address) = if (!(isActive))
141+ then throw("DApp is inactive at this moment")
142+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
143+ then throw("Only admin can call this function")
144+ else [StringEntry(keyInitCaller, address)]
145+
146+
147+
148+@Callable(i)
149+func init (projectAddress,startHeight,commission,tokensPerTicket,pricePerToken,swopfiTicketsAmount,campaignTokensAmount,tokensPerAllocation,swopPerTicket) = {
150+ let $t042004275 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
151+ let pmtAmount = $t042004275._1
152+ let pmtAssetId = $t042004275._2
161153 if (!(isActive))
162154 then throw("DApp is inactive at this moment")
163- else if (if ((height > endHeight))
164- then true
165- else (endHeight == 0))
166- then throw("Swop burning are ended or not started yet")
167- else if ((pmtAssetId != swopId))
168- then throw("You can add only SWOP token")
169- else {
170- let newTotalBurned = (valueOrElse(getInteger(this, keyTotalBurned), 0) + pmtAmount)
171- let userTotalBurned = valueOrElse(getInteger(this, (toString(i.caller) + keyUserTotalBurned)), 0)
172- let prizesAmounts = {
173- let $l = split(getStringValue(this, keyPrizesAmounts), ",")
174- let $s = size($l)
175- let $acc0 = nil
176- func 1 ($a,$i) = if (($i >= $s))
177- then $a
178- else inListToInt($a, $l[$i])
179-
180- func 2 ($a,$i) = if (($i >= $s))
181- then $a
182- else throw("List size exceeds 5")
183-
184- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
155+ else if ((toString(i.caller) != valueOrElse(getString(this, keyInitCaller), "")))
156+ then throw("Only project admin can call init function")
157+ else if ((size(i.payments) != 1))
158+ then throw("One attached payment expected")
159+ else if ((height > startHeight))
160+ then throw("Start height must be greater than blockchain height")
161+ else {
162+ let $t047034776 = getAssetInfo(pmtAssetId)
163+ let pmtStrAssetId = $t047034776._1
164+ let pmtAssetName = $t047034776._2
165+ let pmtDecimals = $t047034776._3
166+ let launchpadId = getLaunchpadNextId()
167+ let launchpadIdStr = toString(launchpadId)
168+[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 + 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, "")]
185169 }
186- let prizesPrices = {
187- let $l = split(getStringValue(this, keyPrizesPrices), ",")
188- let $s = size($l)
189- let $acc0 = nil
190- func 1 ($a,$i) = if (($i >= $s))
191- then $a
192- else inListToInt($a, $l[$i])
193-
194- func 2 ($a,$i) = if (($i >= $s))
195- then $a
196- else throw("List size exceeds 5")
197-
198- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
199- }
200- let prizesAchievementsIds = split(getStringValue(this, keyPrizesAIds), ",")
201- let levelAchievementsIds = split(getStringValue(this, keyLevelAchievemntsIds), ",")
202- let res = {
203- let $l = prizesPrices
204- let $s = size($l)
205- let $acc0 = $Tuple2(newTotalBurned, nil)
206- func 1 ($a,$i) = if (($i >= $s))
207- then $a
208- else calcPrizesAmounts($a, $l[$i])
209-
210- func 2 ($a,$i) = if (($i >= $s))
211- then $a
212- else throw("List size exceeds 5")
213-
214- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
215- }
216- let newPrizesAmounts = res._2
217- let newPrizesAmountsStr = {
218- let $l = newPrizesAmounts
219- let $s = size($l)
220- let $acc0 = ""
221- func 1 ($a,$i) = if (($i >= $s))
222- then $a
223- else inListToStr($a, $l[$i])
224-
225- func 2 ($a,$i) = if (($i >= $s))
226- then $a
227- else throw("List size exceeds 5")
228-
229- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
230- }
231- let inv0 = if ((newPrizesAmounts[0] != prizesAmounts[0]))
232- then {
233- let achievementAmount = (newPrizesAmounts[0] - prizesAmounts[0])
234- invoke(achievements, "add", [prizesAchievementsIds[0], achievementAmount], nil)
235- }
236- else 0
237- if ((inv0 == inv0))
238- then {
239- let inv1 = if ((newPrizesAmounts[1] != prizesAmounts[1]))
240- then {
241- let achievementAmount = (newPrizesAmounts[1] - prizesAmounts[1])
242- invoke(achievements, "add", [prizesAchievementsIds[1], achievementAmount], nil)
243- }
244- else 0
245- if ((inv1 == inv1))
246- then {
247- let inv2 = if ((newPrizesAmounts[2] != prizesAmounts[2]))
248- then {
249- let achievementAmount = (newPrizesAmounts[2] - prizesAmounts[2])
250- invoke(achievements, "add", [prizesAchievementsIds[2], achievementAmount], nil)
251- }
252- else 0
253- if ((inv2 == inv2))
254- then {
255- let inv3 = if ((newPrizesAmounts[3] != prizesAmounts[3]))
256- then {
257- let achievementAmount = (newPrizesAmounts[3] - prizesAmounts[3])
258- invoke(achievements, "add", [prizesAchievementsIds[3], achievementAmount], nil)
259- }
260- else 0
261- if ((inv3 == inv3))
262- then {
263- let inv4 = if ((newPrizesAmounts[4] != prizesAmounts[4]))
264- then {
265- let achievementAmount = (newPrizesAmounts[4] - prizesAmounts[4])
266- invoke(achievements, "add", [prizesAchievementsIds[4], achievementAmount], nil)
267- }
268- else 0
269- if ((inv4 == inv4))
270- then {
271- let baseEntry = [IntegerEntry(keyTotalBurned, newTotalBurned), IntegerEntry((toString(i.caller) + keyUserTotalBurned), (userTotalBurned + pmtAmount)), StringEntry(keyPrizesAmounts, newPrizesAmountsStr)]
272- let oldLevel = calcLevel(userTotalBurned)
273- let newLevel = calcLevel(newTotalBurned)
274- let levelDiff = (newLevel - oldLevel)
275- if ((levelDiff > 0))
276- then {
277- let inv5 = if ((levelDiff == 1))
278- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
279- else 0
280- if ((inv5 == inv5))
281- then {
282- let inv6 = if ((levelDiff >= 2))
283- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
284- else 0
285- if ((inv6 == inv6))
286- then {
287- let inv7 = if ((levelDiff >= 3))
288- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
289- else 0
290- if ((inv7 == inv7))
291- then {
292- let inv8 = if ((levelDiff == 4))
293- then invoke(achievements, "add", [levelAchievementsIds[(newLevel - 1)], 1], nil)
294- else 0
295- if ((inv8 == inv8))
296- then baseEntry
297- else throw("Strict value is not equal to itself.")
298- }
299- else throw("Strict value is not equal to itself.")
300- }
301- else throw("Strict value is not equal to itself.")
302- }
303- else throw("Strict value is not equal to itself.")
304- }
305- else baseEntry
306- }
307- else throw("Strict value is not equal to itself.")
308- }
309- else throw("Strict value is not equal to itself.")
310- }
311- else throw("Strict value is not equal to itself.")
312- }
313- else throw("Strict value is not equal to itself.")
314- }
315- else throw("Strict value is not equal to itself.")
316- }
317170 }
318171
319172
320173
321174 @Callable(i)
322-func hashingRandom (hash) = if (!(isActive))
323- then throw("DApp is inactive at this moment")
324- else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
325- then throw("Only admin can call this function")
326- else [StringEntry(keyVerifyHash, hash)]
175+func commitSwopfiSale (launchpadId,refId) = {
176+ let $t062706345 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
177+ let pmtAmount = $t062706345._1
178+ let pmtAssetId = $t062706345._2
179+ let stakedSwops = valueOrElse(getInteger(governance, (toString(i.caller) + keyGovernanceStaked)), 0)
180+ let allowedTicketsAmountAll = (stakedSwops / getIntegerValue(this, (toString(launchpadId) + keySwopPerTicket)))
181+ let boughtTicketsAmount = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
182+ let allowedTicketsAmount = (allowedTicketsAmountAll - boughtTicketsAmount)
183+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
184+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
185+ if (!(isActive))
186+ then throw("DApp is inactive at this moment")
187+ else if ((activeLaunchpadId != launchpadId))
188+ then throw("There is no active launchpad or this launchpad is ended")
189+ else if ((startHeight > height))
190+ then throw("Launchpad sale not started yet")
191+ else if ((height > (startHeight + duration)))
192+ then throw("Launchpad sale ended")
193+ else if (if ((size(i.payments) != 1))
194+ then true
195+ else (pmtAssetId != USDN))
196+ then throw("One attached payment in USDN expected")
197+ else if (if ((0 >= allowedTicketsAmountAll))
198+ then true
199+ else (0 >= allowedTicketsAmount))
200+ then throw("Not enought SWOP in staking to buy tickets")
201+ else {
202+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
203+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
204+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
205+ let $t078697945 = getAssetInfo(tokenId)
206+ let tokenStrAssetId = $t078697945._1
207+ let tokenAssetName = $t078697945._2
208+ let tokenDecimals = $t078697945._3
209+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
210+ let commissionPerTicket = fraction(ticketPrice, getIntegerValue(this, (toString(launchpadId) + keyComission)), 100)
211+ let buyTicketAmount = (pmtAmount / (ticketPrice + commissionPerTicket))
212+ let allowedBuyTicketAmount = min([buyTicketAmount, allowedTicketsAmount])
213+ let allowedBuyPriceWithComission = (allowedBuyTicketAmount * (ticketPrice + commissionPerTicket))
214+ let change = (pmtAmount - allowedBuyPriceWithComission)
215+ if ((buyTicketAmount == 0))
216+ then throw("Not enought USDN to buy tickets")
217+ else if ((change != 0))
218+ then throw((((("Wrong payment. To buy " + toString(allowedBuyTicketAmount)) + "tickets you need to pay ") + toString(allowedBuyPriceWithComission)) + "USDN"))
219+ else {
220+ let userBoughtTicketsNumbers = valueOrElse(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserTickets)), "")
221+ let lastBoughtTicketNumber = getIntegerValue(this, (toString(launchpadId) + keyTicketLastNumber))
222+ let boughtRange = ((toString((lastBoughtTicketNumber + 1)) + "-") + toString((lastBoughtTicketNumber + allowedBuyTicketAmount)))
223+ let newUserBoughtTicketsNumbers = (userBoughtTicketsNumbers + (if ((userBoughtTicketsNumbers != ""))
224+ then ("," + boughtRange)
225+ else ("" + boughtRange)))
226+ let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
227+ if ((inv == inv))
228+ then {
229+ 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)]
230+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
231+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
232+ else baseEntry
233+ }
234+ else throw("Strict value is not equal to itself.")
235+ }
236+ }
237+ }
327238
328239
329240
330241 @Callable(i)
331-func finalize (vrfHeight,secretWord) = {
332- let savedHash = getStringValue(this, keyVerifyHash)
242+func commitAccessListSale (launchpadId,refId) = {
243+ let $t01026510340 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
244+ let pmtAmount = $t01026510340._1
245+ let pmtAssetId = $t01026510340._2
246+ let userUsdnInMarketing = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAmountUSDNInMarketing)), 0)
247+ let usdnInMarketing = valueOrElse(getInteger(this, (toString(launchpadId) + keyAmountUSDNInMarketing)), 0)
248+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
249+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
250+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
251+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
252+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
253+ let $t01109511171 = getAssetInfo(tokenId)
254+ let tokenStrAssetId = $t01109511171._1
255+ let tokenAssetName = $t01109511171._2
256+ let tokenDecimals = $t01109511171._3
257+ let allocationPriceWithComission = fraction(fraction(tokenPrice, tokensPerAllocation, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
258+ let startHeight = value(getInteger(this, (toString(launchpadId) + keyStartHeight)))
259+ let duration = value(getInteger(this, (toString(launchpadId) + keyDuration)))
260+ if (!(isActive))
261+ then throw("DApp is inactive at this moment")
262+ else if ((activeLaunchpadId != launchpadId))
263+ then throw("There is no active launchpad or this launchpad is ended")
264+ else if ((startHeight > height))
265+ then throw("Launchpad sale not started yet")
266+ else if ((height > (startHeight + duration)))
267+ then throw("Launchpad sale ended")
268+ else if (if ((size(i.payments) != 1))
269+ then true
270+ else (pmtAssetId != USDN))
271+ then throw("One attached payment in USDN expected")
272+ else if ((boughtAllocations >= maxAllocationsAmount))
273+ then throw((("You can buy only " + toString(maxAllocationsAmount)) + "allocations"))
274+ else if (if ((allocationPriceWithComission != pmtAmount))
275+ then ((allocationPriceWithComission * 2) != pmtAmount)
276+ else false)
277+ then throw((("Wrong payment. You can buy 1 or 2 allocations for " + toString(allocationPriceWithComission)) + " USDN per allocation"))
278+ else {
279+ let buyAllocationsAmount = (pmtAmount / allocationPriceWithComission)
280+ let inv = invoke(stakingUSDNAddress, "lockNeutrino", nil, [AttachedPayment(pmtAssetId, pmtAmount)])
281+ if ((inv == inv))
282+ then {
283+ 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))]
284+ if (!(isDefined(getString(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId)))))
285+ then (baseEntry ++ [StringEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserRefId), refId)])
286+ else baseEntry
287+ }
288+ else throw("Strict value is not equal to itself.")
289+ }
290+ }
291+
292+
293+
294+@Callable(i)
295+func finalise (launchpadId,vrfHeight,secretWord) = {
296+ let savedHash = getStringValue(this, (toString(launchpadId) + keyVerifyHash))
333297 let calcHash = toBase58String(sha256((toBytes(vrfHeight) + toBytes(secretWord))))
334298 if (!(isActive))
335299 then throw("DApp is inactive at this moment")
336300 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
337301 then throw("Only admin can call this function")
338302 else if ((calcHash != savedHash))
339303 then throw("vrf Height hash not matching")
340304 else {
341- let burnAmount = getIntegerValue(this, keyTotalBurned)
342-[Burn(swopId, burnAmount), IntegerEntry(keyFinalizeHeight, height)]
305+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
306+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
307+ let transferedUsdn = valueOrElse(getInteger(this, (toString(launchpadId) + keyTransferUsd)), 0)
308+ let swopfiMembersUsdnAmount = getIntegerValue(this, (toString(launchpadId) + keyTotalAmountUsdnSold))
309+ let swopfiMembersComission = fraction(swopfiMembersUsdnAmount, commission, 100)
310+ let totalAmountUsdnInMarketing = getIntegerValue(this, (toString(launchpadId) + keyAmountUSDNInMarketingFinalized))
311+ let marketingComission = fraction(totalAmountUsdnInMarketing, commission, 100)
312+ let unstakeAmount = (((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) + swopfiMembersComission) + marketingComission)
313+ if ((transferedUsdn > (swopfiMembersUsdnAmount + totalAmountUsdnInMarketing)))
314+ then throw("Can't transfer negative value to project")
315+ else {
316+ let inv = invoke(stakingUSDNAddress, "unlockNeutrino", [unstakeAmount, toBase58String(USDN)], nil)
317+ if ((inv == inv))
318+ then [IntegerEntry((toString(launchpadId) + keyFinaliseHeight), height), ScriptTransfer(projectAddress, ((swopfiMembersUsdnAmount + totalAmountUsdnInMarketing) - transferedUsdn), USDN), ScriptTransfer(commissionWallet, (swopfiMembersComission + marketingComission), USDN)]
319+ else throw("Strict value is not equal to itself.")
320+ }
343321 }
344322 }
323+
324+
325+
326+@Callable(i)
327+func claim (launchpadId) = {
328+ let userClaimStatus = valueOrElse(getBoolean(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus)), false)
329+ let boughtTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtTicketsAmount)), 0)
330+ let boughtAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserBoughtAllocations)), 0)
331+ if (!(isActive))
332+ then throw("DApp is inactive at this moment")
333+ else if (!(isDefined(getInteger(this, (toString(launchpadId) + keyFinaliseHeight)))))
334+ then throw("You can't claim because results are not finalized")
335+ else if (userClaimStatus)
336+ then throw("You are already claimed")
337+ else if (if ((boughtTickets == 0))
338+ then (boughtAllocations == 0)
339+ else false)
340+ then throw("You can't claim because you don't buy anything")
341+ else {
342+ let tokenId = fromBase58String(getStringValue(this, (toString(launchpadId) + keyAssetId)))
343+ let wonnedTickets = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserWinnedTicketsAmount)), 0)
344+ let awailableAllocations = valueOrElse(getInteger(this, (((toString(i.caller) + "_") + toString(launchpadId)) + keyUserAvailableAllocations)), 0)
345+ let commission = getIntegerValue(this, (toString(launchpadId) + keyComission))
346+ let allowedAllocations = min([boughtAllocations, awailableAllocations])
347+ let tokenPrice = getIntegerValue(this, (toString(launchpadId) + keyPricePerToken))
348+ let tokensPerTicket = getIntegerValue(this, (toString(launchpadId) + keyTokensPerTicket))
349+ let $t01694517021 = getAssetInfo(tokenId)
350+ let tokenStrAssetId = $t01694517021._1
351+ let tokenAssetName = $t01694517021._2
352+ let tokenDecimals = $t01694517021._3
353+ let ticketPrice = fraction(tokensPerTicket, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN))
354+ let tokensPerAllocation = getIntegerValue(this, (toString(launchpadId) + keyTokensPerAllocation))
355+ let transferTokensAmount = ((wonnedTickets * tokensPerTicket) + (allowedAllocations * tokensPerAllocation))
356+ let notAllowedAllocationsTokens = ((boughtAllocations - allowedAllocations) * tokensPerAllocation)
357+ let usdnForAllocations = fraction(fraction(notAllowedAllocationsTokens, tokenPrice, pow(10, 0, tokenDecimals, 0, 0, DOWN)), (100 + commission), 100)
358+ let usdnForUnwonnedTickets = fraction(((boughtTickets - wonnedTickets) * ticketPrice), (100 + commission), 100)
359+ if (if ((0 > usdnForAllocations))
360+ then true
361+ else (0 > usdnForUnwonnedTickets))
362+ then throw("Error with allowed allocation param or wonned tickets param please contact support")
363+ else {
364+ let returnedUsdnAmount = (usdnForAllocations + usdnForUnwonnedTickets)
365+ let transferUsdn = if ((returnedUsdnAmount > 0))
366+ then [ScriptTransfer(i.caller, returnedUsdnAmount, USDN)]
367+ else nil
368+ let transferTokens = if ((transferTokensAmount > 0))
369+ then [ScriptTransfer(i.caller, transferTokensAmount, tokenId)]
370+ else nil
371+ let inv = if ((returnedUsdnAmount > 0))
372+ then invoke(stakingUSDNAddress, "unlockNeutrino", [returnedUsdnAmount, toBase58String(USDN)], nil)
373+ else 0
374+ if ((inv == inv))
375+ then (([BooleanEntry((((toString(i.caller) + "_") + toString(launchpadId)) + keyUserClaimStatus), true)] ++ transferTokens) ++ transferUsdn)
376+ else throw("Strict value is not equal to itself.")
377+ }
378+ }
379+ }
380+
381+
382+
383+@Callable(i)
384+func transferUsd (launchpadId,amountUsdn) = if (!(isActive))
385+ then throw("DApp is inactive")
386+ else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
387+ then throw("Only admin can call this function")
388+ else {
389+ let projectAddress = addressFromStringValue(getStringValue(this, (toString(launchpadId) + keyAddress)))
390+[IntegerEntry((toString(launchpadId) + keyTransferUsd), amountUsdn), ScriptTransfer(projectAddress, amountUsdn, USDN)]
391+ }
345392
346393
347394
348395 @Callable(i)
349396 func shutdown () = if (!(isActive))
350397 then throw("DApp already inactive")
351398 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
352399 then throw("Only admin can call this function")
353400 else [BooleanEntry(keyActive, false)]
354401
355402
356403
357404 @Callable(i)
358405 func activate () = if (isActive)
359406 then throw("DApp already active")
360407 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
361408 then throw("Only admin can call this function")
362409 else [BooleanEntry(keyActive, true)]
363410
364411
365412 @Verifier(tx)
366413 func verify () = {
367414 let multiSignedByAdmins = {
368415 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
369416 then 1
370417 else 0
371418 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
372419 then 1
373420 else 0
374421 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
375422 then 1
376423 else 0
377424 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
378425 }
379426 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
380427 then true
381428 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
382429 then true
383430 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
384431 then true
385432 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyStaking)
386433 match tx {
434+ case dtx: DataTransaction =>
435+ if (valueOrElse(getBoolean(oracle, keyLaunchpadDataTransactionStatus), false))
436+ then signedByAdmin
437+ else false
387438 case _ =>
388439 multiSignedByAdmins
389440 }
390441 }
391442

github/deemru/w8io/026f985 
63.18 ms