tx · D5dPMa5Sz2QcHQrn5piwiHR2YZkjh1MZbUJt5MG5gath

3N3irEKCdj77h97aEbfj3fa3uMXCNCXVhKt:  -0.01200000 Waves

2023.12.11 09:53 [2881703] smart account 3N3irEKCdj77h97aEbfj3fa3uMXCNCXVhKt > SELF 0.00000000 Waves

{ "type": 13, "id": "D5dPMa5Sz2QcHQrn5piwiHR2YZkjh1MZbUJt5MG5gath", "fee": 1200000, "feeAssetId": null, "timestamp": 1702277624189, "version": 1, "sender": "3N3irEKCdj77h97aEbfj3fa3uMXCNCXVhKt", "senderPublicKey": "FACNGaFYnR8yFbQFg9sRBpzGVCyzMyLeVw3JMhGQT1wn", "proofs": [ "2QAC5bFUq7e2s5JbnBCNhFPWieNVfmkFkqwXP2UDd5aNNypNvp5iVhh3JSekaX8C5Y73EsJtukMYLC5hhEaAQrEk" ], "script": "base64:BgIWCAISBAoCCAESBQoDGBEBEgMKAQgSAC8ADGNvbnRyYWN0RmlsZQIRbDJtcF9zdGFraW5nLnJpZGUAA1NFUAICX18ABnNjYWxlOACAwtcvAAdzY2FsZTE4AICAkLu61q3wDQANc2NhbGUxOEJpZ0ludAkAtgIBBQdzY2FsZTE4ABJBRERSRVNTX0JZVEVTX1NJWkUAGgANQkxPQ0tTX0lOX0RBWQCgCwEIdGhyb3dFcnIBA21zZwkAAgEJAKwCAgkArAICBQxjb250cmFjdEZpbGUCAjogBQNtc2cACmtleUFzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCAgdhc3NldElkBQNuaWwFA1NFUAATa2V5RW1pc3Npb25QZXJCbG9jawkAuQkCCQDMCAICAiVzCQDMCAICEGVtaXNzaW9uUGVyQmxvY2sFA25pbAUDU0VQABlrZXlFbWlzc2lvblBlcmlvZEluQmxvY2tzCQC5CQIJAMwIAgICJXMJAMwIAgIWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwUDbmlsBQNTRVAADWtleVN0YXJ0QmxvY2sJALkJAgkAzAgCAgIlcwkAzAgCAgpzdGFydEJsb2NrBQNuaWwFA1NFUAAQa2V5VG90YWxMcEFtb3VudAkAuQkCCQDMCAICAiVzCQDMCAICDXRvdGFsTHBBbW91bnQFA25pbAUDU0VQABNrZXlUb3RhbEFzc2V0QW1vdW50CQC5CQIJAMwIAgICJXMJAMwIAgIQdG90YWxBc3NldEFtb3VudAUDbmlsBQNTRVAAFmtleVRvdGFsTG9ja2VkTHBBbW91bnQJALkJAgkAzAgCAgIlcwkAzAgCAhN0b3RhbExvY2tlZExwQW1vdW50BQNuaWwFA1NFUAEPa2V5VXNlckxwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIMdXNlckxwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEVa2V5VXNlckxvY2tlZExwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgISdXNlckxvY2tlZExwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAETa2V5VXNlclN0YWtpbmdOb2RlcwELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICEHVzZXJTdGFraW5nTm9kZXMJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARlrZXlVc2VyU3Rha2luZ05vZGVzU2hhcmVzAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIWdXNlclN0YWtpbmdOb2Rlc1NoYXJlcwkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGmtleVVzZXJUb3RhbEFzc2V0V2l0aGRyYXduAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgITdG90YWxBc3NldFdpdGhkcmF3bgkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIQdG90YWxBc3NldFN0YWtlZAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABCmtleUhpc3RvcnkDBHR5cGULdXNlckFkZHJlc3MEdHhJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJANgEAQUEdHhJZAUDbmlsBQNTRVABDWZvcm1hdEhpc3RvcnkEC3RvdGFsUHJvZml0BXByaWNlEHRvdGFsQXNzZXRBbW91bnQNdG90YWxMcEFtb3VudAkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQULdG90YWxQcm9maXQJAMwIAgkApgMBBQVwcmljZQkAzAgCCQCkAwEFEHRvdGFsQXNzZXRBbW91bnQJAMwIAgkApAMBBQ10b3RhbExwQW1vdW50BQNuaWwFA1NFUAANdG90YWxMcEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRBrZXlUb3RhbExwQW1vdW50AAAAEHRvdGFsQXNzZXRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUTa2V5VG90YWxBc3NldEFtb3VudAAAABN0b3RhbExvY2tlZExwQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFFmtleVRvdGFsTG9ja2VkTHBBbW91bnQAAAANYXNzZXRJZFN0cmluZwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQprZXlBc3NldElkAgVXQVZFUwAMYXNzZXRJZEJ5dGVzAwkAAAIFDWFzc2V0SWRTdHJpbmcCBVdBVkVTBQR1bml0CQDZBAEFDWFzc2V0SWRTdHJpbmcAFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUZa2V5RW1pc3Npb25QZXJpb2RJbkJsb2NrcwUNQkxPQ0tTX0lOX0RBWQAQZW1pc3Npb25QZXJCbG9jawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRNrZXlFbWlzc2lvblBlckJsb2NrAAAAEWVtaXNzaW9uUGVyUGVyaW9kCQBoAgUQZW1pc3Npb25QZXJCbG9jawUWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwEZc3RyaW5nTGlzdFRvSW50TGlzdEhlbHBlcgIDYWNjBXZhbHVlCQDNCAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQV2YWx1ZQEYY2FsY1RvdGFsUHJvZml0Rm9ySGVpZ2h0AQFoBApzdGFydEJsb2NrCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAQLc3RhcnRQZXJpb2QJAGsDBQpzdGFydEJsb2NrAAEFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MEDmVsYXBzZWRQZXJpb2RzCQBlAgkAaQIFAWgFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MFC3N0YXJ0UGVyaW9kCQCWAwEJAMwIAgAACQDMCAIJAGgCBRFlbWlzc2lvblBlclBlcmlvZAUOZWxhcHNlZFBlcmlvZHMFA25pbAEPY2FsY1RvdGFsUHJvZml0AAkBGGNhbGNUb3RhbFByb2ZpdEZvckhlaWdodAEFBmhlaWdodAEUZ2V0TWF4QXNzZXRBdmFpbGFibGUABAckbWF0Y2gwBQxhc3NldElkQnl0ZXMDCQABAgUHJG1hdGNoMAIEVW5pdAQBdQUHJG1hdGNoMAgJAO8HAQUEdGhpcwlhdmFpbGFibGUDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkA8AcCBQR0aGlzBQFiCQACAQILTWF0Y2ggZXJyb3IBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUBCGF0SGVpZ2h0BBp0b3RhbEFzc2V0QW1vdW50V2l0aFByb2ZpdAkAZAIFEHRvdGFsQXNzZXRBbW91bnQJARhjYWxjVG90YWxQcm9maXRGb3JIZWlnaHQBBQhhdEhlaWdodAQLdG90YWxBbW91bnQJAJcDAQkAzAgCBRp0b3RhbEFzc2V0QW1vdW50V2l0aFByb2ZpdAkAzAgCCQEUZ2V0TWF4QXNzZXRBdmFpbGFibGUABQNuaWwDCQAAAgUNdG90YWxMcEFtb3VudAAAAAAFC3RvdGFsQW1vdW50ARBnZXRQcmljZUF0SGVpZ2h0AQFoAwkBAiE9AgUNdG90YWxMcEFtb3VudAAACQC8AgMJALYCAQkBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUBBQFoBQ1zY2FsZTE4QmlnSW50CQC2AgEFDXRvdGFsTHBBbW91bnQFDXNjYWxlMThCaWdJbnQBD2dldEN1cnJlbnRQcmljZQAJARBnZXRQcmljZUF0SGVpZ2h0AQUGaGVpZ2h0ARJnZXRSZW1haW5pbmdCbG9ja3MAAwkAAAIFEGVtaXNzaW9uUGVyQmxvY2sAAAAACQBrAwkAZQIJARRnZXRNYXhBc3NldEF2YWlsYWJsZQAJAStnZXRUb3RhbEFzc2V0QW1vdW50V2l0aFByb2ZpdE9yTWF4QXZhaWxhYmxlAQUGaGVpZ2h0AAEFEGVtaXNzaW9uUGVyQmxvY2sBF2dldFVzZXJTdGFraW5nTm9kZXNEYXRhAQt1c2VyQWRkcmVzcwQIbm9kZXNSYXcJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBE2tleVVzZXJTdGFraW5nTm9kZXMBBQt1c2VyQWRkcmVzcwIABAlzaGFyZXNSYXcJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBGWtleVVzZXJTdGFraW5nTm9kZXNTaGFyZXMBBQt1c2VyQWRkcmVzcwIABAlub2Rlc0xpc3QDCQAAAgUIbm9kZXNSYXcCAAUDbmlsCQC1CQIFCG5vZGVzUmF3BQNTRVAEEHNoYXJlc1N0cmluZ0xpc3QDCQAAAgUJc2hhcmVzUmF3AgAFA25pbAkAtQkCBQlzaGFyZXNSYXcFA1NFUAQKc2hhcmVzTGlzdAoAAiRsBRBzaGFyZXNTdHJpbmdMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARlzdHJpbmdMaXN0VG9JbnRMaXN0SGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAyMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQJAJQKAgUJbm9kZXNMaXN0BQpzaGFyZXNMaXN0AQ9jYWxjQXNzZXRGcm9tTHACCGxwQW1vdW50CGF0SGVpZ2h0CQCWAwEJAMwIAgAACQDMCAIJAKADAQkAvAIDCQC2AgEFCGxwQW1vdW50CQEQZ2V0UHJpY2VBdEhlaWdodAEFCGF0SGVpZ2h0BQ1zY2FsZTE4QmlnSW50BQNuaWwBD2NhbGNMcEZyb21Bc3NldAILYXNzZXRBbW91bnQIYXRIZWlnaHQJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC8AgMJALYCAQULYXNzZXRBbW91bnQFDXNjYWxlMThCaWdJbnQJARBnZXRQcmljZUF0SGVpZ2h0AQUIYXRIZWlnaHQFA25pbAEPZ2V0VXNlckxwQW1vdW50AQt1c2VyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEPa2V5VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MAAAEVZ2V0VXNlckxvY2tlZExwQW1vdW50AQt1c2VyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEVa2V5VXNlckxvY2tlZExwQW1vdW50AQULdXNlckFkZHJlc3MAAAEgZ2V0VXNlckF2YWlsYWJsZUFzc2V0c1RvV2l0aGRyYXcBC3VzZXJBZGRyZXNzBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwkBD2NhbGNBc3NldEZyb21McAIFDHVzZXJMcEFtb3VudAUGaGVpZ2h0ARtnZXRDbGVhclN0YWtpbmdOb2Rlc0FjdGlvbnMBC3VzZXJBZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJARNrZXlVc2VyU3Rha2luZ05vZGVzAQULdXNlckFkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGWtleVVzZXJTdGFraW5nTm9kZXNTaGFyZXMBBQt1c2VyQWRkcmVzcwUDbmlsAQ9nZXRTdGFrZUFjdGlvbnMDAWkLdXNlckFkZHJlc3MLc3Rha2VIZWlnaHQEBmNoZWNrcwkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECGHNob3VsZCBpbmNsdWRlIDEgcGF5bWVudAkAzAgCAwkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUMYXNzZXRJZEJ5dGVzBgkBCHRocm93RXJyAQkArAICAhVwYXltZW50IHNob3VsZCBiZSBpbiAFDWFzc2V0SWRTdHJpbmcJAMwIAgMJAGYCCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAABgIncGF5bWVudCBhbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIDCQAAAgkAyAEBCQDZBAEFC3VzZXJBZGRyZXNzBRJBRERSRVNTX0JZVEVTX1NJWkUGCQEIdGhyb3dFcnIBAhl1c2VyIGFkZHJlc3MgaXMgbm90IHZhbGlkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDXBheW1lbnRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BA9wYXltZW50THBBbW91bnQJAQ9jYWxjTHBGcm9tQXNzZXQCBQ1wYXltZW50QW1vdW50BQtzdGFrZUhlaWdodAQMdXNlckxwQW1vdW50CQEPZ2V0VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MEFXVzZXJUb3RhbFN0YWtlZEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEXa2V5VXNlclRvdGFsQXNzZXRTdGFrZWQBBQt1c2VyQWRkcmVzcwAABBBuZXdUb3RhbExwQW1vdW50CQBkAgUNdG90YWxMcEFtb3VudAUPcGF5bWVudExwQW1vdW50BBNuZXdUb3RhbEFzc2V0QW1vdW50CQEPY2FsY0Fzc2V0RnJvbUxwAgUQbmV3VG90YWxMcEFtb3VudAULc3Rha2VIZWlnaHQED25ld1VzZXJMcEFtb3VudAkAZAIFDHVzZXJMcEFtb3VudAUPcGF5bWVudExwQW1vdW50BBhuZXdVc2VyVG90YWxTdGFrZWRBbW91bnQJAGQCBRV1c2VyVG90YWxTdGFrZWRBbW91bnQFDXBheW1lbnRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCmtleUhpc3RvcnkDAgVzdGFrZQULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQJAQ1mb3JtYXRIaXN0b3J5BAkBD2NhbGNUb3RhbFByb2ZpdAAJAQ9nZXRDdXJyZW50UHJpY2UABQ10b3RhbExwQW1vdW50BRB0b3RhbEFzc2V0QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrZXlUb3RhbExwQW1vdW50BRBuZXdUb3RhbExwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrZXlUb3RhbEFzc2V0QW1vdW50BRNuZXdUb3RhbEFzc2V0QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPa2V5VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MFD25ld1VzZXJMcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQULdXNlckFkZHJlc3MFGG5ld1VzZXJUb3RhbFN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa2V5U3RhcnRCbG9jawUGaGVpZ2h0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EAWkBDXN0YWtlRm9yQWRtaW4CC3VzZXJBZGRyZXNzC3N0YWtlSGVpZ2h0BAVjaGVjawkAzAgCAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYJAQh0aHJvd0VycgECEXBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrCQEPZ2V0U3Rha2VBY3Rpb25zAwUBaQULdXNlckFkZHJlc3MFC3N0YWtlSGVpZ2h0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2FpcmRyb3ADC2FkZHJlc3NMaXN0CmFtb3VudExpc3QNYWlyZHJvcEhlaWdodAoBA3N1bQIFYWNjdW0EbmV4dAMJAGYCAAAFBG5leHQJAQh0aHJvd0VycgECI25lZ2F0aXZlIGFtb3VudCB2YWx1ZSBpbiBhbW91bnRMaXN0CQBkAgUFYWNjdW0FBG5leHQEDWFtb3VudExpc3RTdW0KAAIkbAUKYW1vdW50TGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEDc3VtAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA5MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgQFY2hlY2sJAMwIAgMJAAACCAUBaQZjYWxsZXIFBHRoaXMGCQEIdGhyb3dFcnIBAhFwZXJtaXNzaW9uIGRlbmllZAkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECGHNob3VsZCBpbmNsdWRlIDEgcGF5bWVudAkAzAgCAwkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUMYXNzZXRJZEJ5dGVzBgkBCHRocm93RXJyAQkArAICAhVwYXltZW50IHNob3VsZCBiZSBpbiAFDWFzc2V0SWRTdHJpbmcJAMwIAgMJAGYCCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAABgIncGF5bWVudCBhbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIDCQAAAgkAkAMBBQthZGRyZXNzTGlzdAkAkAMBBQphbW91bnRMaXN0BgkBCHRocm93RXJyAQItYWRkcmVzc0xpc3Qgc2hvdWxkIGJlIHNhbWUgc2l6ZSBhcyBhbW91bnRMaXN0CQDMCAIDCQBnAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFDWFtb3VudExpc3RTdW0GCQEIdGhyb3dFcnIBAi1wYXltZW50IGFtb3VudCBpcyBsZXNzIHRoYW4gc3VtIG9mIGFtb3VudExpc3QFA25pbAMJAAACBQVjaGVjawUFY2hlY2sKARZnZXRBaXJkcm9wU3RhdGVDaGFuZ2VzAgVhY2N1bQthc3NldEFtb3VudAQLJHQwODE3MDgyMjEFBWFjY3VtBAZyZXN1bHQIBQskdDA4MTcwODIyMQJfMQQFaW5kZXgIBQskdDA4MTcwODIyMQJfMgQHdG90YWxMcAgFCyR0MDgxNzA4MjIxAl8zBA1wcm9jZXNzZWRMaXN0CAULJHQwODE3MDgyMjECXzQEDWFkZHJlc3NTdHJpbmcJAJEDAgULYWRkcmVzc0xpc3QFBWluZGV4BAdhZGRyZXNzBAckbWF0Y2gwCQCmCAEFDWFkZHJlc3NTdHJpbmcDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQDYWRyBQckbWF0Y2gwBQNhZHIJAQh0aHJvd0VycgECHmludmFsaWQgYWRkcmVzcyBpbiBhZGRyZXNzTGlzdAQCY2gJAMwIAgMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFDXByb2Nlc3NlZExpc3QFB2FkZHJlc3MGCQEIdGhyb3dFcnIBAiBkdXBsaWNhdGUgYWRkcmVzcyBpcyBhZGRyZXNzTGlzdAUDbmlsAwkAAAIFAmNoBQJjaAQNYWRkZWRMcEFtb3VudAkBD2NhbGNMcEZyb21Bc3NldAIFC2Fzc2V0QW1vdW50BQ1haXJkcm9wSGVpZ2h0BA91c2VyTG9ja2VkTHBLZXkJARVrZXlVc2VyTG9ja2VkTHBBbW91bnQBBQ1hZGRyZXNzU3RyaW5nBAtvbGRMcEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQ91c2VyTG9ja2VkTHBLZXkAAAkAlgoECQDNCAIFBnJlc3VsdAkBDEludGVnZXJFbnRyeQIFD3VzZXJMb2NrZWRMcEtleQkAZAIFC29sZExwQW1vdW50BQ1hZGRlZExwQW1vdW50CQBkAgUFaW5kZXgAAQkAZAIFB3RvdGFsTHAFDWFkZGVkTHBBbW91bnQJAM0IAgUNcHJvY2Vzc2VkTGlzdAUHYWRkcmVzcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQLJHQwOTAwMDkxMTcKAAIkbAUKYW1vdW50TGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAUDbmlsAAAAAAUDbmlsCgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARZnZXRBaXJkcm9wU3RhdGVDaGFuZ2VzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA5MAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgQOYWlyZHJvcEVudHJpZXMIBQskdDA5MDAwOTExNwJfMQQCX2EIBQskdDA5MDAwOTExNwJfMgQYYWRkZWRUb3RhbExvY2tlZExwQW1vdW50CAULJHQwOTAwMDkxMTcCXzMEAl9iCAULJHQwOTAwMDkxMTcCXzQEDW5ld1RvdGFsQXNzZXQJAQ9jYWxjQXNzZXRGcm9tTHACCQBkAgUNdG90YWxMcEFtb3VudAUYYWRkZWRUb3RhbExvY2tlZExwQW1vdW50BQ1haXJkcm9wSGVpZ2h0CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFFmtleVRvdGFsTG9ja2VkTHBBbW91bnQJAGQCBRN0b3RhbExvY2tlZExwQW1vdW50BRhhZGRlZFRvdGFsTG9ja2VkTHBBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEGtleVRvdGFsTHBBbW91bnQJAGQCBQ10b3RhbExwQW1vdW50BRhhZGRlZFRvdGFsTG9ja2VkTHBBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tleVRvdGFsQXNzZXRBbW91bnQFDW5ld1RvdGFsQXNzZXQJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAUDbmlsBQ5haXJkcm9wRW50cmllcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARVnZXRVc2VyQXNzZXRzUkVBRE9OTFkBC3VzZXJBZGRyZXNzBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwQSdXNlckxvY2tlZExwQW1vdW50CQEVZ2V0VXNlckxvY2tlZExwQW1vdW50AQULdXNlckFkZHJlc3MEFXVzZXJMb2NrZWRBc3NldEFtb3VudAkBD2NhbGNBc3NldEZyb21McAIFEnVzZXJMb2NrZWRMcEFtb3VudAUGaGVpZ2h0BBx1c2VyQXZhaWxhYmxlQXNzZXRUb1dpdGhkcmF3CQEgZ2V0VXNlckF2YWlsYWJsZUFzc2V0c1RvV2l0aGRyYXcBBQt1c2VyQWRkcmVzcwQVdXNlclRvdGFsU3Rha2VkQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARdrZXlVc2VyVG90YWxBc3NldFN0YWtlZAEFC3VzZXJBZGRyZXNzAAAEF3VzZXJUb3RhbEFzc2V0V2l0aGRyYXduCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARprZXlVc2VyVG90YWxBc3NldFdpdGhkcmF3bgEFC3VzZXJBZGRyZXNzAAAEDSR0MDEwNDkwMTA1ODIJARdnZXRVc2VyU3Rha2luZ05vZGVzRGF0YQEFC3VzZXJBZGRyZXNzBBR1c2VyU3Rha2luZ05vZGVzTGlzdAgFDSR0MDEwNDkwMTA1ODICXzEEGXVzZXJTdGFraW5nTm9kZVNoYXJlc0xpc3QIBQ0kdDAxMDQ5MDEwNTgyAl8yCQCUCgIFA25pbAkAnAoKBQx1c2VyTHBBbW91bnQFHHVzZXJBdmFpbGFibGVBc3NldFRvV2l0aGRyYXcJAQ9nZXRDdXJyZW50UHJpY2UABRV1c2VyVG90YWxTdGFrZWRBbW91bnQFF3VzZXJUb3RhbEFzc2V0V2l0aGRyYXduBRJ1c2VyTG9ja2VkTHBBbW91bnQFFXVzZXJMb2NrZWRBc3NldEFtb3VudAUUdXNlclN0YWtpbmdOb2Rlc0xpc3QFGXVzZXJTdGFraW5nTm9kZVNoYXJlc0xpc3QJARJnZXRSZW1haW5pbmdCbG9ja3MAAWkBFmdldFRvdGFsQXNzZXRzUkVBRE9OTFkACQCUCgIFA25pbAkAmAoGBQ10b3RhbExwQW1vdW50CQErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQEFBmhlaWdodAkBD2dldEN1cnJlbnRQcmljZQAFE3RvdGFsTG9ja2VkTHBBbW91bnQJAQ9jYWxjQXNzZXRGcm9tTHACBRN0b3RhbExvY2tlZExwQW1vdW50BQZoZWlnaHQJARJnZXRSZW1haW5pbmdCbG9ja3MAAOVYDts=", "chainId": 84, "height": 2881703, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: FNXT4xp1TdUQa5rtbNEocEEGXN1NDnkj5fSXyhD2zUk5 Next: Hq2jw7mQaM9AKWTJ8tdbXiGETFKmrbGH7GJNMr3cuhiX Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let contractFile = "proxy_pepe.ride"
4+let contractFile = "l2mp_staking.ride"
55
6-let keysWavesContract = "%s__sWavesContract"
6+let SEP = "__"
77
8-let keysWavesAssetId = "%s__sWavesAssetId"
8+let scale8 = 100000000
99
10-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), ("No data for this.key=" + key))
10+let scale18 = 1000000000000000000
11+
12+let scale18BigInt = toBigInt(scale18)
13+
14+let ADDRESS_BYTES_SIZE = 26
15+
16+let BLOCKS_IN_DAY = 1440
17+
18+func throwErr (msg) = throw(((contractFile + ": ") + msg))
1119
1220
13-func pepeContractAddress () = getStringOrFail(keysWavesContract)
21+let keyAssetId = makeString(["%s", "assetId"], SEP)
22+
23+let keyEmissionPerBlock = makeString(["%s", "emissionPerBlock"], SEP)
24+
25+let keyEmissionPeriodInBlocks = makeString(["%s", "emissionPeriodInBlocks"], SEP)
26+
27+let keyStartBlock = makeString(["%s", "startBlock"], SEP)
28+
29+let keyTotalLpAmount = makeString(["%s", "totalLpAmount"], SEP)
30+
31+let keyTotalAssetAmount = makeString(["%s", "totalAssetAmount"], SEP)
32+
33+let keyTotalLockedLpAmount = makeString(["%s", "totalLockedLpAmount"], SEP)
34+
35+func keyUserLpAmount (userAddress) = makeString(["%s%s", "userLpAmount", userAddress], SEP)
1436
1537
16-func sWavesIdString () = getStringOrFail(keysWavesAssetId)
38+func keyUserLockedLpAmount (userAddress) = makeString(["%s%s", "userLockedLpAmount", userAddress], SEP)
1739
1840
19-let pepeContract = addressFromStringValue(pepeContractAddress())
20-
21-let sWaves = fromBase58String(sWavesIdString())
22-
23-func keyManagerPublicKey () = "%s__managerPublicKey"
41+func keyUserStakingNodes (userAddress) = makeString(["%s%s", "userStakingNodes", userAddress], SEP)
2442
2543
26-func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
44+func keyUserStakingNodesShares (userAddress) = makeString(["%s%s", "userStakingNodesShares", userAddress], SEP)
2745
2846
29-func error (msg) = throw(((contractFile + ": ") + msg))
47+func keyUserTotalAssetWithdrawn (userAddress) = makeString(["%s%s", "totalAssetWithdrawn", userAddress], SEP)
3048
3149
32-func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
33- case s: String =>
34- fromBase58String(s)
35- case _: Unit =>
36- unit
50+func keyUserTotalAssetStaked (userAddress) = makeString(["%s%s", "totalAssetStaked", userAddress], SEP)
51+
52+
53+func keyHistory (type,userAddress,txId) = makeString(["%s%s%s", type, userAddress, toBase58String(txId)], SEP)
54+
55+
56+func formatHistory (totalProfit,price,totalAssetAmount,totalLpAmount) = makeString(["%d%d%d%d", toString(totalProfit), toString(price), toString(totalAssetAmount), toString(totalLpAmount)], SEP)
57+
58+
59+let totalLpAmount = valueOrElse(getInteger(this, keyTotalLpAmount), 0)
60+
61+let totalAssetAmount = valueOrElse(getInteger(this, keyTotalAssetAmount), 0)
62+
63+let totalLockedLpAmount = valueOrElse(getInteger(this, keyTotalLockedLpAmount), 0)
64+
65+let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
66+
67+let assetIdBytes = if ((assetIdString == "WAVES"))
68+ then unit
69+ else fromBase58String(assetIdString)
70+
71+let emissionPeriodInBlocks = valueOrElse(getInteger(this, keyEmissionPeriodInBlocks), BLOCKS_IN_DAY)
72+
73+let emissionPerBlock = valueOrElse(getInteger(this, keyEmissionPerBlock), 0)
74+
75+let emissionPerPeriod = (emissionPerBlock * emissionPeriodInBlocks)
76+
77+func stringListToIntListHelper (acc,value) = (acc :+ parseIntValue(value))
78+
79+
80+func calcTotalProfitForHeight (h) = {
81+ let startBlock = valueOrElse(getInteger(this, keyStartBlock), height)
82+ let startPeriod = fraction(startBlock, 1, emissionPeriodInBlocks)
83+ let elapsedPeriods = ((h / emissionPeriodInBlocks) - startPeriod)
84+ max([0, (emissionPerPeriod * elapsedPeriods)])
85+ }
86+
87+
88+func calcTotalProfit () = calcTotalProfitForHeight(height)
89+
90+
91+func getMaxAssetAvailable () = match assetIdBytes {
92+ case u: Unit =>
93+ wavesBalance(this).available
94+ case b: ByteVector =>
95+ assetBalance(this, b)
3796 case _ =>
3897 throw("Match error")
3998 }
4099
41100
42-func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
43- case s: String =>
44- fromBase58String(s)
45- case _: Unit =>
46- unit
47- case _ =>
48- throw("Match error")
49-}
101+func getTotalAssetAmountWithProfitOrMaxAvailable (atHeight) = {
102+ let totalAssetAmountWithProfit = (totalAssetAmount + calcTotalProfitForHeight(atHeight))
103+ let totalAmount = min([totalAssetAmountWithProfit, getMaxAssetAvailable()])
104+ if ((totalLpAmount == 0))
105+ then 0
106+ else totalAmount
107+ }
50108
51109
52-func isManager (i) = match managerPublicKeyOrUnit() {
53- case pk: ByteVector =>
54- (i.callerPublicKey == pk)
55- case _: Unit =>
56- (i.caller == this)
57- case _ =>
58- throw("Match error")
59-}
110+func getPriceAtHeight (h) = if ((totalLpAmount != 0))
111+ then fraction(toBigInt(getTotalAssetAmountWithProfitOrMaxAvailable(h)), scale18BigInt, toBigInt(totalLpAmount))
112+ else scale18BigInt
60113
61114
62-func mustManager (i) = if (isManager(i))
63- then true
64- else throw("permission denied")
115+func getCurrentPrice () = getPriceAtHeight(height)
116+
117+
118+func getRemainingBlocks () = if ((emissionPerBlock == 0))
119+ then 0
120+ else fraction((getMaxAssetAvailable() - getTotalAssetAmountWithProfitOrMaxAvailable(height)), 1, emissionPerBlock)
121+
122+
123+func getUserStakingNodesData (userAddress) = {
124+ let nodesRaw = valueOrElse(getString(this, keyUserStakingNodes(userAddress)), "")
125+ let sharesRaw = valueOrElse(getString(this, keyUserStakingNodesShares(userAddress)), "")
126+ let nodesList = if ((nodesRaw == ""))
127+ then nil
128+ else split(nodesRaw, SEP)
129+ let sharesStringList = if ((sharesRaw == ""))
130+ then nil
131+ else split(sharesRaw, SEP)
132+ let sharesList = {
133+ let $l = sharesStringList
134+ let $s = size($l)
135+ let $acc0 = nil
136+ func $f0_1 ($a,$i) = if (($i >= $s))
137+ then $a
138+ else stringListToIntListHelper($a, $l[$i])
139+
140+ func $f0_2 ($a,$i) = if (($i >= $s))
141+ then $a
142+ else throw("List size exceeds 20")
143+
144+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
145+ }
146+ $Tuple2(nodesList, sharesList)
147+ }
148+
149+
150+func calcAssetFromLp (lpAmount,atHeight) = max([0, toInt(fraction(toBigInt(lpAmount), getPriceAtHeight(atHeight), scale18BigInt))])
151+
152+
153+func calcLpFromAsset (assetAmount,atHeight) = max([0, toInt(fraction(toBigInt(assetAmount), scale18BigInt, getPriceAtHeight(atHeight)))])
154+
155+
156+func getUserLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLpAmount(userAddress)), 0)
157+
158+
159+func getUserLockedLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLockedLpAmount(userAddress)), 0)
160+
161+
162+func getUserAvailableAssetsToWithdraw (userAddress) = {
163+ let userLpAmount = getUserLpAmount(userAddress)
164+ calcAssetFromLp(userLpAmount, height)
165+ }
166+
167+
168+func getClearStakingNodesActions (userAddress) = [DeleteEntry(keyUserStakingNodes(userAddress)), DeleteEntry(keyUserStakingNodesShares(userAddress))]
169+
170+
171+func getStakeActions (i,userAddress,stakeHeight) = {
172+ let checks = [if ((size(i.payments) == 1))
173+ then true
174+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
175+ then true
176+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
177+ then true
178+ else "payment amount should be greater than 0", if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
179+ then true
180+ else throwErr("user address is not valid")]
181+ if ((checks == checks))
182+ then {
183+ let paymentAmount = i.payments[0].amount
184+ let paymentLpAmount = calcLpFromAsset(paymentAmount, stakeHeight)
185+ let userLpAmount = getUserLpAmount(userAddress)
186+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
187+ let newTotalLpAmount = (totalLpAmount + paymentLpAmount)
188+ let newTotalAssetAmount = calcAssetFromLp(newTotalLpAmount, stakeHeight)
189+ let newUserLpAmount = (userLpAmount + paymentLpAmount)
190+ let newUserTotalStakedAmount = (userTotalStakedAmount + paymentAmount)
191+[StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount), IntegerEntry(keyStartBlock, height)]
192+ }
193+ else throw("Strict value is not equal to itself.")
194+ }
65195
66196
67197 @Callable(i)
68-func getRate () = {
69- let results = invoke(pepeContract, "getRate", nil, nil)
70- match results {
71- case t: String =>
72- $Tuple2(nil, parseIntValue(t))
73- case _ =>
74- error("getRate(): unexpected return")
75- }
198+func stakeForAdmin (userAddress,stakeHeight) = {
199+ let check = [if ((i.caller == this))
200+ then true
201+ else throwErr("permission denied")]
202+ if ((check == check))
203+ then getStakeActions(i, userAddress, stakeHeight)
204+ else throw("Strict value is not equal to itself.")
76205 }
77206
78207
79208
80209 @Callable(i)
81-func deposit () = {
82- let startBalance = assetBalance(this, sWaves)
83- if ((startBalance == startBalance))
210+func airdrop (addressList,amountList,airdropHeight) = {
211+ func sum (accum,next) = if ((0 > next))
212+ then throwErr("negative amount value in amountList")
213+ else (accum + next)
214+
215+ let amountListSum = {
216+ let $l = amountList
217+ let $s = size($l)
218+ let $acc0 = 0
219+ func $f0_1 ($a,$i) = if (($i >= $s))
220+ then $a
221+ else sum($a, $l[$i])
222+
223+ func $f0_2 ($a,$i) = if (($i >= $s))
224+ then $a
225+ else throw("List size exceeds 90")
226+
227+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
228+ }
229+ let check = [if ((i.caller == this))
230+ then true
231+ else throwErr("permission denied"), if ((size(i.payments) == 1))
232+ then true
233+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
234+ then true
235+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
236+ then true
237+ else "payment amount should be greater than 0", if ((size(addressList) == size(amountList)))
238+ then true
239+ else throwErr("addressList should be same size as amountList"), if ((i.payments[0].amount >= amountListSum))
240+ then true
241+ else throwErr("payment amount is less than sum of amountList")]
242+ if ((check == check))
84243 then {
85- let results = invoke(pepeContract, "deposit", nil, i.payments)
86- if ((results == results))
87- then {
88- let newBalance = assetBalance(this, sWaves)
89- let sendAmount = (newBalance - startBalance)
90- $Tuple2([ScriptTransfer(i.caller, sendAmount, sWaves)], sendAmount)
91- }
92- else throw("Strict value is not equal to itself.")
244+ func getAirdropStateChanges (accum,assetAmount) = {
245+ let $t081708221 = accum
246+ let result = $t081708221._1
247+ let index = $t081708221._2
248+ let totalLp = $t081708221._3
249+ let processedList = $t081708221._4
250+ let addressString = addressList[index]
251+ let address = match addressFromString(addressString) {
252+ case adr: Address =>
253+ adr
254+ case _ =>
255+ throwErr("invalid address in addressList")
256+ }
257+ let ch = [if (!(containsElement(processedList, address)))
258+ then true
259+ else throwErr("duplicate address is addressList")]
260+ if ((ch == ch))
261+ then {
262+ let addedLpAmount = calcLpFromAsset(assetAmount, airdropHeight)
263+ let userLockedLpKey = keyUserLockedLpAmount(addressString)
264+ let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
265+ $Tuple4((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount), (processedList :+ address))
266+ }
267+ else throw("Strict value is not equal to itself.")
268+ }
269+
270+ let $t090009117 = {
271+ let $l = amountList
272+ let $s = size($l)
273+ let $acc0 = $Tuple4(nil, 0, 0, nil)
274+ func $f1_1 ($a,$i) = if (($i >= $s))
275+ then $a
276+ else getAirdropStateChanges($a, $l[$i])
277+
278+ func $f1_2 ($a,$i) = if (($i >= $s))
279+ then $a
280+ else throw("List size exceeds 90")
281+
282+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
283+ }
284+ let airdropEntries = $t090009117._1
285+ let _a = $t090009117._2
286+ let addedTotalLockedLpAmount = $t090009117._3
287+ let _b = $t090009117._4
288+ let newTotalAsset = calcAssetFromLp((totalLpAmount + addedTotalLockedLpAmount), airdropHeight)
289+ ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, newTotalAsset), IntegerEntry(keyStartBlock, height)] ++ airdropEntries)
93290 }
94291 else throw("Strict value is not equal to itself.")
95292 }
97294
98295
99296 @Callable(i)
100-func withdraw () = {
101- let startBalance = wavesBalance(this).available
102- if ((startBalance == startBalance))
103- then {
104- let results = invoke(pepeContract, "withdraw", nil, i.payments)
105- if ((results == results))
106- then {
107- let newBalance = wavesBalance(this).available
108- let sendAmount = (newBalance - startBalance)
109- $Tuple2([ScriptTransfer(i.caller, sendAmount, unit)], sendAmount)
110- }
111- else throw("Strict value is not equal to itself.")
112- }
113- else throw("Strict value is not equal to itself.")
297+func getUserAssetsREADONLY (userAddress) = {
298+ let userLpAmount = getUserLpAmount(userAddress)
299+ let userLockedLpAmount = getUserLockedLpAmount(userAddress)
300+ let userLockedAssetAmount = calcAssetFromLp(userLockedLpAmount, height)
301+ let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
302+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
303+ let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
304+ let $t01049010582 = getUserStakingNodesData(userAddress)
305+ let userStakingNodesList = $t01049010582._1
306+ let userStakingNodeSharesList = $t01049010582._2
307+ $Tuple2(nil, $Tuple10(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList, getRemainingBlocks()))
114308 }
115309
116310
117311
118312 @Callable(i)
119-func setManager (pendingManagerPublicKey) = {
120- let checkCaller = mustManager(i)
121- if ((checkCaller == checkCaller))
122- then {
123- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
124- if ((checkManagerPublicKey == checkManagerPublicKey))
125- then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
126- else throw("Strict value is not equal to itself.")
127- }
128- else throw("Strict value is not equal to itself.")
129- }
313+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple6(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(height), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount, height), getRemainingBlocks()))
130314
131-
132-
133-@Callable(i)
134-func confirmManager () = {
135- let pm = pendingManagerPublicKeyOrUnit()
136- let hasPM = if (isDefined(pm))
137- then true
138- else throw("no pending manager")
139- if ((hasPM == hasPM))
140- then {
141- let checkPM = if ((i.callerPublicKey == value(pm)))
142- then true
143- else throw("you are not pending manager")
144- if ((checkPM == checkPM))
145- then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
146- else throw("Strict value is not equal to itself.")
147- }
148- else throw("Strict value is not equal to itself.")
149- }
150-
151-
152-@Verifier(tx)
153-func verify () = {
154- let targetPublicKey = match managerPublicKeyOrUnit() {
155- case pk: ByteVector =>
156- pk
157- case _: Unit =>
158- tx.senderPublicKey
159- case _ =>
160- throw("Match error")
161- }
162- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
163- }
164315
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let contractFile = "proxy_pepe.ride"
4+let contractFile = "l2mp_staking.ride"
55
6-let keysWavesContract = "%s__sWavesContract"
6+let SEP = "__"
77
8-let keysWavesAssetId = "%s__sWavesAssetId"
8+let scale8 = 100000000
99
10-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), ("No data for this.key=" + key))
10+let scale18 = 1000000000000000000
11+
12+let scale18BigInt = toBigInt(scale18)
13+
14+let ADDRESS_BYTES_SIZE = 26
15+
16+let BLOCKS_IN_DAY = 1440
17+
18+func throwErr (msg) = throw(((contractFile + ": ") + msg))
1119
1220
13-func pepeContractAddress () = getStringOrFail(keysWavesContract)
21+let keyAssetId = makeString(["%s", "assetId"], SEP)
22+
23+let keyEmissionPerBlock = makeString(["%s", "emissionPerBlock"], SEP)
24+
25+let keyEmissionPeriodInBlocks = makeString(["%s", "emissionPeriodInBlocks"], SEP)
26+
27+let keyStartBlock = makeString(["%s", "startBlock"], SEP)
28+
29+let keyTotalLpAmount = makeString(["%s", "totalLpAmount"], SEP)
30+
31+let keyTotalAssetAmount = makeString(["%s", "totalAssetAmount"], SEP)
32+
33+let keyTotalLockedLpAmount = makeString(["%s", "totalLockedLpAmount"], SEP)
34+
35+func keyUserLpAmount (userAddress) = makeString(["%s%s", "userLpAmount", userAddress], SEP)
1436
1537
16-func sWavesIdString () = getStringOrFail(keysWavesAssetId)
38+func keyUserLockedLpAmount (userAddress) = makeString(["%s%s", "userLockedLpAmount", userAddress], SEP)
1739
1840
19-let pepeContract = addressFromStringValue(pepeContractAddress())
20-
21-let sWaves = fromBase58String(sWavesIdString())
22-
23-func keyManagerPublicKey () = "%s__managerPublicKey"
41+func keyUserStakingNodes (userAddress) = makeString(["%s%s", "userStakingNodes", userAddress], SEP)
2442
2543
26-func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
44+func keyUserStakingNodesShares (userAddress) = makeString(["%s%s", "userStakingNodesShares", userAddress], SEP)
2745
2846
29-func error (msg) = throw(((contractFile + ": ") + msg))
47+func keyUserTotalAssetWithdrawn (userAddress) = makeString(["%s%s", "totalAssetWithdrawn", userAddress], SEP)
3048
3149
32-func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
33- case s: String =>
34- fromBase58String(s)
35- case _: Unit =>
36- unit
50+func keyUserTotalAssetStaked (userAddress) = makeString(["%s%s", "totalAssetStaked", userAddress], SEP)
51+
52+
53+func keyHistory (type,userAddress,txId) = makeString(["%s%s%s", type, userAddress, toBase58String(txId)], SEP)
54+
55+
56+func formatHistory (totalProfit,price,totalAssetAmount,totalLpAmount) = makeString(["%d%d%d%d", toString(totalProfit), toString(price), toString(totalAssetAmount), toString(totalLpAmount)], SEP)
57+
58+
59+let totalLpAmount = valueOrElse(getInteger(this, keyTotalLpAmount), 0)
60+
61+let totalAssetAmount = valueOrElse(getInteger(this, keyTotalAssetAmount), 0)
62+
63+let totalLockedLpAmount = valueOrElse(getInteger(this, keyTotalLockedLpAmount), 0)
64+
65+let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
66+
67+let assetIdBytes = if ((assetIdString == "WAVES"))
68+ then unit
69+ else fromBase58String(assetIdString)
70+
71+let emissionPeriodInBlocks = valueOrElse(getInteger(this, keyEmissionPeriodInBlocks), BLOCKS_IN_DAY)
72+
73+let emissionPerBlock = valueOrElse(getInteger(this, keyEmissionPerBlock), 0)
74+
75+let emissionPerPeriod = (emissionPerBlock * emissionPeriodInBlocks)
76+
77+func stringListToIntListHelper (acc,value) = (acc :+ parseIntValue(value))
78+
79+
80+func calcTotalProfitForHeight (h) = {
81+ let startBlock = valueOrElse(getInteger(this, keyStartBlock), height)
82+ let startPeriod = fraction(startBlock, 1, emissionPeriodInBlocks)
83+ let elapsedPeriods = ((h / emissionPeriodInBlocks) - startPeriod)
84+ max([0, (emissionPerPeriod * elapsedPeriods)])
85+ }
86+
87+
88+func calcTotalProfit () = calcTotalProfitForHeight(height)
89+
90+
91+func getMaxAssetAvailable () = match assetIdBytes {
92+ case u: Unit =>
93+ wavesBalance(this).available
94+ case b: ByteVector =>
95+ assetBalance(this, b)
3796 case _ =>
3897 throw("Match error")
3998 }
4099
41100
42-func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
43- case s: String =>
44- fromBase58String(s)
45- case _: Unit =>
46- unit
47- case _ =>
48- throw("Match error")
49-}
101+func getTotalAssetAmountWithProfitOrMaxAvailable (atHeight) = {
102+ let totalAssetAmountWithProfit = (totalAssetAmount + calcTotalProfitForHeight(atHeight))
103+ let totalAmount = min([totalAssetAmountWithProfit, getMaxAssetAvailable()])
104+ if ((totalLpAmount == 0))
105+ then 0
106+ else totalAmount
107+ }
50108
51109
52-func isManager (i) = match managerPublicKeyOrUnit() {
53- case pk: ByteVector =>
54- (i.callerPublicKey == pk)
55- case _: Unit =>
56- (i.caller == this)
57- case _ =>
58- throw("Match error")
59-}
110+func getPriceAtHeight (h) = if ((totalLpAmount != 0))
111+ then fraction(toBigInt(getTotalAssetAmountWithProfitOrMaxAvailable(h)), scale18BigInt, toBigInt(totalLpAmount))
112+ else scale18BigInt
60113
61114
62-func mustManager (i) = if (isManager(i))
63- then true
64- else throw("permission denied")
115+func getCurrentPrice () = getPriceAtHeight(height)
116+
117+
118+func getRemainingBlocks () = if ((emissionPerBlock == 0))
119+ then 0
120+ else fraction((getMaxAssetAvailable() - getTotalAssetAmountWithProfitOrMaxAvailable(height)), 1, emissionPerBlock)
121+
122+
123+func getUserStakingNodesData (userAddress) = {
124+ let nodesRaw = valueOrElse(getString(this, keyUserStakingNodes(userAddress)), "")
125+ let sharesRaw = valueOrElse(getString(this, keyUserStakingNodesShares(userAddress)), "")
126+ let nodesList = if ((nodesRaw == ""))
127+ then nil
128+ else split(nodesRaw, SEP)
129+ let sharesStringList = if ((sharesRaw == ""))
130+ then nil
131+ else split(sharesRaw, SEP)
132+ let sharesList = {
133+ let $l = sharesStringList
134+ let $s = size($l)
135+ let $acc0 = nil
136+ func $f0_1 ($a,$i) = if (($i >= $s))
137+ then $a
138+ else stringListToIntListHelper($a, $l[$i])
139+
140+ func $f0_2 ($a,$i) = if (($i >= $s))
141+ then $a
142+ else throw("List size exceeds 20")
143+
144+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
145+ }
146+ $Tuple2(nodesList, sharesList)
147+ }
148+
149+
150+func calcAssetFromLp (lpAmount,atHeight) = max([0, toInt(fraction(toBigInt(lpAmount), getPriceAtHeight(atHeight), scale18BigInt))])
151+
152+
153+func calcLpFromAsset (assetAmount,atHeight) = max([0, toInt(fraction(toBigInt(assetAmount), scale18BigInt, getPriceAtHeight(atHeight)))])
154+
155+
156+func getUserLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLpAmount(userAddress)), 0)
157+
158+
159+func getUserLockedLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLockedLpAmount(userAddress)), 0)
160+
161+
162+func getUserAvailableAssetsToWithdraw (userAddress) = {
163+ let userLpAmount = getUserLpAmount(userAddress)
164+ calcAssetFromLp(userLpAmount, height)
165+ }
166+
167+
168+func getClearStakingNodesActions (userAddress) = [DeleteEntry(keyUserStakingNodes(userAddress)), DeleteEntry(keyUserStakingNodesShares(userAddress))]
169+
170+
171+func getStakeActions (i,userAddress,stakeHeight) = {
172+ let checks = [if ((size(i.payments) == 1))
173+ then true
174+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
175+ then true
176+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
177+ then true
178+ else "payment amount should be greater than 0", if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
179+ then true
180+ else throwErr("user address is not valid")]
181+ if ((checks == checks))
182+ then {
183+ let paymentAmount = i.payments[0].amount
184+ let paymentLpAmount = calcLpFromAsset(paymentAmount, stakeHeight)
185+ let userLpAmount = getUserLpAmount(userAddress)
186+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
187+ let newTotalLpAmount = (totalLpAmount + paymentLpAmount)
188+ let newTotalAssetAmount = calcAssetFromLp(newTotalLpAmount, stakeHeight)
189+ let newUserLpAmount = (userLpAmount + paymentLpAmount)
190+ let newUserTotalStakedAmount = (userTotalStakedAmount + paymentAmount)
191+[StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount), IntegerEntry(keyStartBlock, height)]
192+ }
193+ else throw("Strict value is not equal to itself.")
194+ }
65195
66196
67197 @Callable(i)
68-func getRate () = {
69- let results = invoke(pepeContract, "getRate", nil, nil)
70- match results {
71- case t: String =>
72- $Tuple2(nil, parseIntValue(t))
73- case _ =>
74- error("getRate(): unexpected return")
75- }
198+func stakeForAdmin (userAddress,stakeHeight) = {
199+ let check = [if ((i.caller == this))
200+ then true
201+ else throwErr("permission denied")]
202+ if ((check == check))
203+ then getStakeActions(i, userAddress, stakeHeight)
204+ else throw("Strict value is not equal to itself.")
76205 }
77206
78207
79208
80209 @Callable(i)
81-func deposit () = {
82- let startBalance = assetBalance(this, sWaves)
83- if ((startBalance == startBalance))
210+func airdrop (addressList,amountList,airdropHeight) = {
211+ func sum (accum,next) = if ((0 > next))
212+ then throwErr("negative amount value in amountList")
213+ else (accum + next)
214+
215+ let amountListSum = {
216+ let $l = amountList
217+ let $s = size($l)
218+ let $acc0 = 0
219+ func $f0_1 ($a,$i) = if (($i >= $s))
220+ then $a
221+ else sum($a, $l[$i])
222+
223+ func $f0_2 ($a,$i) = if (($i >= $s))
224+ then $a
225+ else throw("List size exceeds 90")
226+
227+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
228+ }
229+ let check = [if ((i.caller == this))
230+ then true
231+ else throwErr("permission denied"), if ((size(i.payments) == 1))
232+ then true
233+ else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
234+ then true
235+ else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
236+ then true
237+ else "payment amount should be greater than 0", if ((size(addressList) == size(amountList)))
238+ then true
239+ else throwErr("addressList should be same size as amountList"), if ((i.payments[0].amount >= amountListSum))
240+ then true
241+ else throwErr("payment amount is less than sum of amountList")]
242+ if ((check == check))
84243 then {
85- let results = invoke(pepeContract, "deposit", nil, i.payments)
86- if ((results == results))
87- then {
88- let newBalance = assetBalance(this, sWaves)
89- let sendAmount = (newBalance - startBalance)
90- $Tuple2([ScriptTransfer(i.caller, sendAmount, sWaves)], sendAmount)
91- }
92- else throw("Strict value is not equal to itself.")
244+ func getAirdropStateChanges (accum,assetAmount) = {
245+ let $t081708221 = accum
246+ let result = $t081708221._1
247+ let index = $t081708221._2
248+ let totalLp = $t081708221._3
249+ let processedList = $t081708221._4
250+ let addressString = addressList[index]
251+ let address = match addressFromString(addressString) {
252+ case adr: Address =>
253+ adr
254+ case _ =>
255+ throwErr("invalid address in addressList")
256+ }
257+ let ch = [if (!(containsElement(processedList, address)))
258+ then true
259+ else throwErr("duplicate address is addressList")]
260+ if ((ch == ch))
261+ then {
262+ let addedLpAmount = calcLpFromAsset(assetAmount, airdropHeight)
263+ let userLockedLpKey = keyUserLockedLpAmount(addressString)
264+ let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
265+ $Tuple4((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount), (processedList :+ address))
266+ }
267+ else throw("Strict value is not equal to itself.")
268+ }
269+
270+ let $t090009117 = {
271+ let $l = amountList
272+ let $s = size($l)
273+ let $acc0 = $Tuple4(nil, 0, 0, nil)
274+ func $f1_1 ($a,$i) = if (($i >= $s))
275+ then $a
276+ else getAirdropStateChanges($a, $l[$i])
277+
278+ func $f1_2 ($a,$i) = if (($i >= $s))
279+ then $a
280+ else throw("List size exceeds 90")
281+
282+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
283+ }
284+ let airdropEntries = $t090009117._1
285+ let _a = $t090009117._2
286+ let addedTotalLockedLpAmount = $t090009117._3
287+ let _b = $t090009117._4
288+ let newTotalAsset = calcAssetFromLp((totalLpAmount + addedTotalLockedLpAmount), airdropHeight)
289+ ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, newTotalAsset), IntegerEntry(keyStartBlock, height)] ++ airdropEntries)
93290 }
94291 else throw("Strict value is not equal to itself.")
95292 }
96293
97294
98295
99296 @Callable(i)
100-func withdraw () = {
101- let startBalance = wavesBalance(this).available
102- if ((startBalance == startBalance))
103- then {
104- let results = invoke(pepeContract, "withdraw", nil, i.payments)
105- if ((results == results))
106- then {
107- let newBalance = wavesBalance(this).available
108- let sendAmount = (newBalance - startBalance)
109- $Tuple2([ScriptTransfer(i.caller, sendAmount, unit)], sendAmount)
110- }
111- else throw("Strict value is not equal to itself.")
112- }
113- else throw("Strict value is not equal to itself.")
297+func getUserAssetsREADONLY (userAddress) = {
298+ let userLpAmount = getUserLpAmount(userAddress)
299+ let userLockedLpAmount = getUserLockedLpAmount(userAddress)
300+ let userLockedAssetAmount = calcAssetFromLp(userLockedLpAmount, height)
301+ let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
302+ let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
303+ let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
304+ let $t01049010582 = getUserStakingNodesData(userAddress)
305+ let userStakingNodesList = $t01049010582._1
306+ let userStakingNodeSharesList = $t01049010582._2
307+ $Tuple2(nil, $Tuple10(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList, getRemainingBlocks()))
114308 }
115309
116310
117311
118312 @Callable(i)
119-func setManager (pendingManagerPublicKey) = {
120- let checkCaller = mustManager(i)
121- if ((checkCaller == checkCaller))
122- then {
123- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
124- if ((checkManagerPublicKey == checkManagerPublicKey))
125- then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
126- else throw("Strict value is not equal to itself.")
127- }
128- else throw("Strict value is not equal to itself.")
129- }
313+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple6(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(height), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount, height), getRemainingBlocks()))
130314
131-
132-
133-@Callable(i)
134-func confirmManager () = {
135- let pm = pendingManagerPublicKeyOrUnit()
136- let hasPM = if (isDefined(pm))
137- then true
138- else throw("no pending manager")
139- if ((hasPM == hasPM))
140- then {
141- let checkPM = if ((i.callerPublicKey == value(pm)))
142- then true
143- else throw("you are not pending manager")
144- if ((checkPM == checkPM))
145- then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
146- else throw("Strict value is not equal to itself.")
147- }
148- else throw("Strict value is not equal to itself.")
149- }
150-
151-
152-@Verifier(tx)
153-func verify () = {
154- let targetPublicKey = match managerPublicKeyOrUnit() {
155- case pk: ByteVector =>
156- pk
157- case _: Unit =>
158- tx.senderPublicKey
159- case _ =>
160- throw("Match error")
161- }
162- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
163- }
164315

github/deemru/w8io/3ef1775 
69.37 ms