tx · DHrPoHw8EmsUpxjcgYLZMFJmYfqEKsWNhUnQwyMJWfJg

3N98Ngyaszw66EakvWRCiZ771ja2RDgNaxV:  -0.02600000 Waves

2022.12.27 13:01 [2378533] smart account 3N98Ngyaszw66EakvWRCiZ771ja2RDgNaxV > SELF 0.00000000 Waves

{ "type": 13, "id": "DHrPoHw8EmsUpxjcgYLZMFJmYfqEKsWNhUnQwyMJWfJg", "fee": 2600000, "feeAssetId": null, "timestamp": 1672135302774, "version": 1, "sender": "3N98Ngyaszw66EakvWRCiZ771ja2RDgNaxV", "senderPublicKey": "F4oaTkX67vt2MEsXLJJ8a7gaURGjW7x8fkvGfdEiH5oy", "proofs": [ "5D7DyLFbjyRmiZh2LMo3ctVBoqZoHwT89R95HW3eJ4QxQE5gYiRZJd58LLhxKRdAdy8SbnwyxwDL7Fyre7vqjbeo" ], "script": "base64:BgInCAISAwoBCBIAEgcKBQgICAgIEgASBAoCCAgSABIECgIICBIDCgEIOQAJc2VwYXJhdG9yAgJfXwASc2hhcmVBc3NldERlY2ltYWxzAAgAC3dhdmVzU3RyaW5nAgVXQVZFUwAHc2NhbGUxOACAgJC7utat8A0ADXNjYWxlMThCaWdJbnQJALYCAQUHc2NhbGUxOAEHd3JhcEVycgEDbXNnCQC5CQIJAMwIAgIWbHBfc3Rha2luZ19wb29scy5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIdGhyb3dFcnIBA21zZwkAAgEJAQd3cmFwRXJyAQUDbXNnARJlcnJLZXlJc05vdERlZmluZWQCB2FkZHJlc3MDa2V5CQEHd3JhcEVycgEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQxnZXRTdHJPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQESZXJyS2V5SXNOb3REZWZpbmVkAgUHYWRkcmVzcwUDa2V5AQxnZXRJbnRPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUHYWRkcmVzcwUDa2V5CQESZXJyS2V5SXNOb3REZWZpbmVkAgUHYWRkcmVzcwUDa2V5AQxwYXJzZUFzc2V0SWQBBWlucHV0AwkAAAIFBWlucHV0BQt3YXZlc1N0cmluZwUEdW5pdAkA2QQBBQVpbnB1dAEPYXNzZXRJZFRvU3RyaW5nAQVpbnB1dAMJAAACBQVpbnB1dAUEdW5pdAULd2F2ZXNTdHJpbmcJANgEAQkBBXZhbHVlAQUFaW5wdXQBDmVuc3VyZVBvc2l0aXZlAQF2AwkAZwIFAXYAAAUBdgkBCHRocm93RXJyAQIYdmFsdWUgc2hvdWxkIGJlIHBvc2l0aXZlARJrZXlGYWN0b3J5Q29udHJhY3QACQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgEUa2V5THBTdGFraW5nQ29udHJhY3QACQC5CQIJAMwIAgICJXMJAMwIAgIRbHBTdGFraW5nQ29udHJhY3QFA25pbAUJc2VwYXJhdG9yARJrZXlTdGFraW5nQ29udHJhY3QACQC5CQIJAMwIAgICJXMJAMwIAgIPc3Rha2luZ0NvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgETa2V5Qm9vc3RpbmdDb250cmFjdAAJALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgEPa2V5U3dhcENvbnRyYWN0AAkAuQkCCQDMCAICAiVzCQDMCAICDHN3YXBDb250cmFjdAUDbmlsBQlzZXBhcmF0b3IBFmtleUFzc2V0c1N0b3JlQ29udHJhY3QACQC5CQIJAMwIAgICJXMJAMwIAgITYXNzZXRzU3RvcmVDb250cmFjdAUDbmlsBQlzZXBhcmF0b3IBDmtleVVzZG5Bc3NldElkAAkAuQkCCQDMCAICAiVzCQDMCAICC3VzZG5Bc3NldElkBQNuaWwFCXNlcGFyYXRvcgEMa2V5V3hBc3NldElkAAkAuQkCCQDMCAICAiVzCQDMCAICCXd4QXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBC2tleU1pbkRlbGF5AAkAuQkCCQDMCAICAiVzCQDMCAICCG1pbkRlbGF5BQNuaWwFCXNlcGFyYXRvcgEPa2V5U2hhcmVBc3NldElkAQtiYXNlQXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAICDHNoYXJlQXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBDmtleUJhc2VBc3NldElkAQxzaGFyZUFzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQxzaGFyZUFzc2V0SWQJAMwIAgILYmFzZUFzc2V0SWQFA25pbAUJc2VwYXJhdG9yAQlrZXlQZXJpb2QBC2Jhc2VBc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQJAMwIAgIGcGVyaW9kBQNuaWwFCXNlcGFyYXRvcgEUa2V5UGVyaW9kU3RhcnRIZWlnaHQCC2Jhc2VBc3NldElkBnBlcmlvZAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQJAMwIAgIRcGVyaW9kU3RhcnRIZWlnaHQJAMwIAgkApAMBBQZwZXJpb2QFA25pbAUJc2VwYXJhdG9yARtrZXlCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQBC2Jhc2VBc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQJAMwIAgIYYmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0BQNuaWwFCXNlcGFyYXRvcgEca2V5U2hhcmVBc3NldEFtb3VudFRvQ29udmVydAELYmFzZUFzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAkAzAgCAhlzaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0BQNuaWwFCXNlcGFyYXRvcgEfa2V5VXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydAILYmFzZUFzc2V0SWQLdXNlckFkZHJlc3MJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAIJAKUIAQULdXNlckFkZHJlc3MJAMwIAgIYYmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0BQNuaWwFCXNlcGFyYXRvcgEla2V5VXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZAILYmFzZUFzc2V0SWQLdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCAhhiYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQJAMwIAgIGcGVyaW9kBQNuaWwFCXNlcGFyYXRvcgEga2V5VXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQCC2Jhc2VBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAkAzAgCCQClCAEFC3VzZXJBZGRyZXNzCQDMCAICGXNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQFA25pbAUJc2VwYXJhdG9yASZrZXlVc2VyU2hhcmVBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZAILYmFzZUFzc2V0SWQLdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQULYmFzZUFzc2V0SWQJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCAhlzaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0CQDMCAICBnBlcmlvZAUDbmlsBQlzZXBhcmF0b3IBDmtleVByaWNlUGVyaW9kAgtiYXNlQXNzZXRJZAZwZXJpb2QJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAICBXByaWNlCQDMCAIJAKQDAQUGcGVyaW9kBQNuaWwFCXNlcGFyYXRvcgEPa2V5UHJpY2VIaXN0b3J5AQtiYXNlQXNzZXRJZAkAuQkCCQDMCAICCiVzJXMlcyVkJWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAICBXByaWNlCQDMCAICB2hpc3RvcnkJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQNuaWwFCXNlcGFyYXRvcgERa2V5UHJpY2VQZXJpb2RQdXQCC2Jhc2VBc3NldElkBnBlcmlvZAkAuQkCCQDMCAICCCVzJXMlZCVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAkAzAgCAgVwcmljZQkAzAgCCQCkAwEFBnBlcmlvZAkAzAgCAgNwdXQFA25pbAUJc2VwYXJhdG9yARJrZXlQcmljZVB1dEhpc3RvcnkBC2Jhc2VBc3NldElkCQC5CQIJAMwIAgIMJXMlcyVzJXMlZCVkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAkAzAgCAgVwcmljZQkAzAgCAgdoaXN0b3J5CQDMCAICA3B1dAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAFA25pbAUJc2VwYXJhdG9yARFrZXlQcmljZVBlcmlvZEdldAILYmFzZUFzc2V0SWQGcGVyaW9kCQC5CQIJAMwIAgIIJXMlcyVkJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAICBXByaWNlCQDMCAIJAKQDAQUGcGVyaW9kCQDMCAICA2dldAUDbmlsBQlzZXBhcmF0b3IBEmtleVByaWNlR2V0SGlzdG9yeQELYmFzZUFzc2V0SWQJALkJAgkAzAgCAgwlcyVzJXMlcyVkJWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAICBXByaWNlCQDMCAICB2hpc3RvcnkJAMwIAgIDZ2V0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUDbmlsBQlzZXBhcmF0b3IBD2tleUhpc3RvcnlFbnRyeQULYmFzZUFzc2V0SWQJb3BlcmF0aW9uBnBlcmlvZAt1c2VyQWRkcmVzcwR0eElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgIHaGlzdG9yeQkAzAgCBQlvcGVyYXRpb24JAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCCQDYBAEFBHR4SWQJAMwIAgkApAMBBQZoZWlnaHQFA25pbAUJc2VwYXJhdG9yARNrZXlNYW5hZ2VyUHVibGljS2V5AAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5ARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQETa2V5TWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IAFXBlcm1pc3Npb25EZW5pZWRFcnJvcgkAAgECEVBlcm1pc3Npb24gZGVuaWVkAQhtdXN0VGhpcwEBaQMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IBC211c3RNYW5hZ2VyAQFpBAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDADCQAAAggFAWkPY2FsbGVyUHVibGljS2V5BQJwawYFFXBlcm1pc3Npb25EZW5pZWRFcnJvcgMJAAECBQckbWF0Y2gwAgRVbml0CQEIbXVzdFRoaXMBBQFpCQACAQILTWF0Y2ggZXJyb3IAD2ZhY3RvcnlDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMJARJrZXlGYWN0b3J5Q29udHJhY3QAABFscFN0YWtpbmdDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMJARRrZXlMcFN0YWtpbmdDb250cmFjdAAAD3N0YWtpbmdDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMJARJrZXlTdGFraW5nQ29udHJhY3QAABBib29zdGluZ0NvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQEMZ2V0U3RyT3JGYWlsAgUEdGhpcwkBE2tleUJvb3N0aW5nQ29udHJhY3QAAAxzd2FwQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQxnZXRTdHJPckZhaWwCBQR0aGlzCQEPa2V5U3dhcENvbnRyYWN0AAATYXNzZXRzU3RvcmVDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMJARZrZXlBc3NldHNTdG9yZUNvbnRyYWN0AAALdXNkbkFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQEMZ2V0U3RyT3JGYWlsAgUEdGhpcwkBDmtleVVzZG5Bc3NldElkAAAJd3hBc3NldElkCQEMcGFyc2VBc3NldElkAQkBDGdldFN0ck9yRmFpbAIFBHRoaXMJAQxrZXlXeEFzc2V0SWQAAA9taW5EZWxheURlZmF1bHQAoAsACG1pbkRlbGF5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQtrZXlNaW5EZWxheQAFD21pbkRlbGF5RGVmYXVsdAELZ2V0UG9vbEluZm8BDWFtb3VudEFzc2V0SWQEEGFtb3VudEFzc2V0SWRTdHIJAQ9hc3NldElkVG9TdHJpbmcBBQ1hbW91bnRBc3NldElkBA9wcmljZUFzc2V0SWRTdHIJAQ9hc3NldElkVG9TdHJpbmcBBQt1c2RuQXNzZXRJZAQOcG9vbEluZm9PcHRpb24KAAFACQD8BwQFD2ZhY3RvcnlDb250cmFjdAIQcG9vbEluZm9SRUFET05MWQkAzAgCBRBhbW91bnRBc3NldElkU3RyCQDMCAIFD3ByaWNlQXNzZXRJZFN0cgUDbmlsBQNuaWwDCQABAgUBQAIVKEFkZHJlc3MsIEJ5dGVWZWN0b3IpBQFABQR1bml0BQ5wb29sSW5mb09wdGlvbggBaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFFWNoZWNrTWFuYWdlclB1YmxpY0tleQUVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY29uZmlybU1hbmFnZXIABAJwbQkBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQFaGFzUE0DCQEJaXNEZWZpbmVkAQUCcG0GCQEIdGhyb3dFcnIBAhJubyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUFaGFzUE0FBWhhc1BNBAdjaGVja1BNAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCcG0GCQEIdGhyb3dFcnIBAht5b3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUHY2hlY2tQTQUHY2hlY2tQTQkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TWFuYWdlclB1YmxpY0tleQAJANgEAQkBBXZhbHVlAQUCcG0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBmNyZWF0ZQUOYmFzZUFzc2V0SWRTdHIPc2hhcmVBc3NldElkU3RyDnNoYXJlQXNzZXROYW1lFXNoYXJlQXNzZXREZXNjcmlwdGlvbg5zaGFyZUFzc2V0TG9nbwQPc2hhcmVBc3NldExhYmVsAhBMUF9TVEFLSU5HX1BPT0xTBAtiYXNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFDmJhc2VBc3NldElkU3RyBAZjaGVja3MJAMwIAgkBC211c3RNYW5hZ2VyAQUBaQkAzAgCAwkBCWlzRGVmaW5lZAEJAQtnZXRQb29sSW5mbwEFC2Jhc2VBc3NldElkBgkBCHRocm93RXJyAQISaW52YWxpZCBiYXNlIGFzc2V0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEC2NvbW1vblN0YXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJa2V5UGVyaW9kAQULYmFzZUFzc2V0SWQAAAUDbmlsAwkAAAIFD3NoYXJlQXNzZXRJZFN0cgIABBVzaGFyZUFzc2V0SXNzdWVBbW91bnQAAQQVc2hhcmVBc3NldElzc3VlQWN0aW9uCQDCCAUFDnNoYXJlQXNzZXROYW1lBRVzaGFyZUFzc2V0RGVzY3JpcHRpb24FFXNoYXJlQXNzZXRJc3N1ZUFtb3VudAUSc2hhcmVBc3NldERlY2ltYWxzBgQWY2FsY3VsYXRlZFNoYXJlQXNzZXRJZAkAuAgBBRVzaGFyZUFzc2V0SXNzdWVBY3Rpb24EFHNoYXJlQXNzZXRCdXJuQWN0aW9uCQEEQnVybgIFFmNhbGN1bGF0ZWRTaGFyZUFzc2V0SWQFFXNoYXJlQXNzZXRJc3N1ZUFtb3VudAQZY2FsY3VsYXRlZFNoYXJlQXNzZXRJZFN0cgkA2AQBBRZjYWxjdWxhdGVkU2hhcmVBc3NldElkBA5jcmVhdGVPclVwZGF0ZQkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0Ag5jcmVhdGVPclVwZGF0ZQkAzAgCBRljYWxjdWxhdGVkU2hhcmVBc3NldElkU3RyCQDMCAIFDnNoYXJlQXNzZXRMb2dvCQDMCAIHBQNuaWwFA25pbAMJAAACBQ5jcmVhdGVPclVwZGF0ZQUOY3JlYXRlT3JVcGRhdGUECGFkZExhYmVsCQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCCGFkZExhYmVsCQDMCAIFGWNhbGN1bGF0ZWRTaGFyZUFzc2V0SWRTdHIJAMwIAgUPc2hhcmVBc3NldExhYmVsBQNuaWwFA25pbAMJAAACBQhhZGRMYWJlbAUIYWRkTGFiZWwJAJQKAgkAzggCBQtjb21tb25TdGF0ZQkAzAgCBRVzaGFyZUFzc2V0SXNzdWVBY3Rpb24JAMwIAgUUc2hhcmVBc3NldEJ1cm5BY3Rpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleVNoYXJlQXNzZXRJZAEFC2Jhc2VBc3NldElkBRljYWxjdWxhdGVkU2hhcmVBc3NldElkU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlCYXNlQXNzZXRJZAEFFmNhbGN1bGF0ZWRTaGFyZUFzc2V0SWQFDmJhc2VBc3NldElkU3RyBQNuaWwFGWNhbGN1bGF0ZWRTaGFyZUFzc2V0SWRTdHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDHNoYXJlQXNzZXRJZAkA2QQBBQ9zaGFyZUFzc2V0SWRTdHIEDnNoYXJlQXNzZXRJbmZvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUMc2hhcmVBc3NldElkCQEHd3JhcEVycgECFmludmFsaWQgc2hhcmUgYXNzZXQgaWQEC2NoZWNrSXNzdWVyAwkAAAIIBQ5zaGFyZUFzc2V0SW5mbwZpc3N1ZXIFEWxwU3Rha2luZ0NvbnRyYWN0BgkBCHRocm93RXJyAQIdaW52YWxpZCBzaGFyZSBhc3NldCBpZCBpc3N1ZXIDCQAAAgULY2hlY2tJc3N1ZXIFC2NoZWNrSXNzdWVyCQCUCgIJAM4IAgULY29tbW9uU3RhdGUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleVNoYXJlQXNzZXRJZAEFC2Jhc2VBc3NldElkBQ9zaGFyZUFzc2V0SWRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleVNoYXJlQXNzZXRJZAEFDHNoYXJlQXNzZXRJZAUOYmFzZUFzc2V0SWRTdHIFA25pbAUPc2hhcmVBc3NldElkU3RyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBA3B1dAAEA3BtdAMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEJAJEDAggFAWkIcGF5bWVudHMAAAkBCHRocm93RXJyAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEC2Jhc2VBc3NldElkCAUDcG10B2Fzc2V0SWQEC3VzZXJBZGRyZXNzCAUBaQZjYWxsZXIEBmNoZWNrcwkAzAgCAwkBCWlzRGVmaW5lZAEJAKIIAQkBD2tleVNoYXJlQXNzZXRJZAEFC2Jhc2VBc3NldElkBgkBCHRocm93RXJyAQINaW52YWxpZCBhc3NldAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA0kdDAxMDA3ODEwMTgxCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAQtnZXRQb29sSW5mbwEFC2Jhc2VBc3NldElkCQEHd3JhcEVycgECDWludmFsaWQgYXNzZXQEC3Bvb2xBZGRyZXNzCAUNJHQwMTAwNzgxMDE4MQJfMQQJbHBBc3NldElkCAUNJHQwMTAwNzgxMDE4MQJfMgQGcGVyaW9kCQEFdmFsdWUBCQCfCAEJAQlrZXlQZXJpb2QBBQtiYXNlQXNzZXRJZAQodXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZE9wdGlvbgkAnwgBCQEla2V5VXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZAIFC2Jhc2VBc3NldElkBQt1c2VyQWRkcmVzcwQZY2xhaW1TaGFyZUFzc2V0SW52b2NhdGlvbgMJAAACBSh1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kT3B0aW9uBQR1bml0BQR1bml0BCJ1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kCQEFdmFsdWUBBSh1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kT3B0aW9uAwkAAAIFInVzZXJCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QFBnBlcmlvZAUEdW5pdAkA/AcEBQR0aGlzAg9jbGFpbVNoYXJlQXNzZXQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkCQDMCAIJAKUIAQULdXNlckFkZHJlc3MFA25pbAUDbmlsAwkAAAIFGWNsYWltU2hhcmVBc3NldEludm9jYXRpb24FGWNsYWltU2hhcmVBc3NldEludm9jYXRpb24EGGJhc2VBc3NldEFtb3VudFRvQ29udmVydAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEba2V5QmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AQULYmFzZUFzc2V0SWQAAAQcdXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEfa2V5VXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydAIFC2Jhc2VBc3NldElkBQt1c2VyQWRkcmVzcwAACQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARtrZXlCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQBBQtiYXNlQXNzZXRJZAkAZAIFGGJhc2VBc3NldEFtb3VudFRvQ29udmVydAgFA3BtdAZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAR9rZXlVc2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzCQBkAgUcdXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydAgFA3BtdAZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJASVrZXlVc2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kAgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzBQZwZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlIaXN0b3J5RW50cnkFBQtiYXNlQXNzZXRJZAIDcHV0BQZwZXJpb2QFC3VzZXJBZGRyZXNzCAUBaQ10cmFuc2FjdGlvbklkCAUDcG10BmFtb3VudAUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBD2NsYWltU2hhcmVBc3NldAIOYmFzZUFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEC3VzZXJBZGRyZXNzAwkAAAIFDnVzZXJBZGRyZXNzU3RyAgAIBQFpBmNhbGxlcgQLY2hlY2tDYWxsZXIJAQhtdXN0VGhpcwEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUOdXNlckFkZHJlc3NTdHIJAQd3cmFwRXJyAQIUaW52YWxpZCB1c2VyIGFkZHJlc3MJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgULdXNlckFkZHJlc3MFC3VzZXJBZGRyZXNzBAtiYXNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFDmJhc2VBc3NldElkU3RyBAxzaGFyZUFzc2V0SWQJAQV2YWx1ZQEJAQxwYXJzZUFzc2V0SWQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBD2tleVNoYXJlQXNzZXRJZAEFC2Jhc2VBc3NldElkCQEHd3JhcEVycgECFWludmFsaWQgYmFzZSBhc3NldCBpZAMJAAACBQxzaGFyZUFzc2V0SWQFDHNoYXJlQXNzZXRJZAQGcGVyaW9kCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBCWtleVBlcmlvZAEFC2Jhc2VBc3NldElkCQEHd3JhcEVycgECDmludmFsaWQgcGVyaW9kAwkAAAIFBnBlcmlvZAUGcGVyaW9kBBx1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0CQELdmFsdWVPckVsc2UCCQCfCAEJAR9rZXlVc2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzAAAEFGNoZWNrQW1vdW50VG9Db252ZXJ0AwkAZgIFHHVzZXJCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQAAAYJAQh0aHJvd0VycgECEG5vdGhpbmcgdG8gY2xhaW0DCQAAAgUUY2hlY2tBbW91bnRUb0NvbnZlcnQFFGNoZWNrQW1vdW50VG9Db252ZXJ0BCJ1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBJWtleVVzZXJCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QCBQtiYXNlQXNzZXRJZAULdXNlckFkZHJlc3MJAQd3cmFwRXJyAQIUZmFpbGVkIHRvIGdldCBwZXJpb2QEC2NoZWNrUGVyaW9kAwkAZgIFBnBlcmlvZAUidXNlckJhc2VBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZAYJAQh0aHJvd0VycgECDmludmFsaWQgcGVyaW9kAwkAAAIFC2NoZWNrUGVyaW9kBQtjaGVja1BlcmlvZAQFcHJpY2UJAJ4DAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQChCAEJARFrZXlQcmljZVBlcmlvZFB1dAIFC2Jhc2VBc3NldElkBSJ1c2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kCQEHd3JhcEVycgECE2ZhaWxlZCB0byBnZXQgcHJpY2UEEHNoYXJlQXNzZXRBbW91bnQJAKADAQkAvAIDCQC2AgEFHHVzZXJCYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQFDXNjYWxlMThCaWdJbnQFBXByaWNlCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAR9rZXlVc2VyQmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFEHNoYXJlQXNzZXRBbW91bnQFDHNoYXJlQXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD2tleUhpc3RvcnlFbnRyeQUFC2Jhc2VBc3NldElkAg9jbGFpbVNoYXJlQXNzZXQFBnBlcmlvZAULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQFEHNoYXJlQXNzZXRBbW91bnQFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQNnZXQABANwbXQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABCQCRAwIIBQFpCHBheW1lbnRzAAAJAQh0aHJvd0VycgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAxzaGFyZUFzc2V0SWQIBQNwbXQHYXNzZXRJZAQLYmFzZUFzc2V0SWQJAQV2YWx1ZQEJAQxwYXJzZUFzc2V0SWQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBDmtleUJhc2VBc3NldElkAQUMc2hhcmVBc3NldElkCQEHd3JhcEVycgECFmludmFsaWQgc2hhcmUgYXNzZXQgaWQDCQAAAgULYmFzZUFzc2V0SWQFC2Jhc2VBc3NldElkBAt1c2VyQWRkcmVzcwgFAWkGY2FsbGVyBA0kdDAxMzc5MDEzODkzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAQtnZXRQb29sSW5mbwEFC2Jhc2VBc3NldElkCQEHd3JhcEVycgECDWludmFsaWQgYXNzZXQEC3Bvb2xBZGRyZXNzCAUNJHQwMTM3OTAxMzg5MwJfMQQJbHBBc3NldElkCAUNJHQwMTM3OTAxMzg5MwJfMgQGcGVyaW9kCQEFdmFsdWUBCQCfCAEJAQlrZXlQZXJpb2QBBQtiYXNlQXNzZXRJZAQpdXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2RPcHRpb24JAJ8IAQkBJmtleVVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kAgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzBBhjbGFpbUJhc2VBc3NldEludm9jYXRpb24DCQAAAgUpdXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2RPcHRpb24FBHVuaXQFBHVuaXQEI3VzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0UGVyaW9kCQEFdmFsdWUBBSl1c2VyU2hhcmVBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZE9wdGlvbgMJAAACBSN1c2VyU2hhcmVBc3NldEFtb3VudFRvQ29udmVydFBlcmlvZAUGcGVyaW9kBQR1bml0CQD8BwQFBHRoaXMCDmNsYWltQmFzZUFzc2V0CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA25pbAMJAAACBRhjbGFpbUJhc2VBc3NldEludm9jYXRpb24FGGNsYWltQmFzZUFzc2V0SW52b2NhdGlvbgQZc2hhcmVBc3NldEFtb3VudFRvQ29udmVydAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEca2V5U2hhcmVBc3NldEFtb3VudFRvQ29udmVydAEFC2Jhc2VBc3NldElkAAAEHXVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0CQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlVc2VyU2hhcmVBc3NldEFtb3VudFRvQ29udmVydAIFC2Jhc2VBc3NldElkBQt1c2VyQWRkcmVzcwAACQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARxrZXlTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0AQULYmFzZUFzc2V0SWQJAGQCBRlzaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0CAUDcG10BmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBIGtleVVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzCQBkAgUddXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQIBQNwbXQGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEma2V5VXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QCBQtiYXNlQXNzZXRJZAULdXNlckFkZHJlc3MFBnBlcmlvZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD2tleUhpc3RvcnlFbnRyeQUFC2Jhc2VBc3NldElkAgNnZXQFBnBlcmlvZAULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQIBQNwbXQGYW1vdW50BQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY2xhaW1CYXNlQXNzZXQCDmJhc2VBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBAt1c2VyQWRkcmVzcwMJAAACBQ51c2VyQWRkcmVzc1N0cgIACAUBaQZjYWxsZXIEC2NoZWNrQ2FsbGVyCQEIbXVzdFRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFDnVzZXJBZGRyZXNzU3RyCQEHd3JhcEVycgECFGludmFsaWQgdXNlciBhZGRyZXNzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFC3VzZXJBZGRyZXNzBQt1c2VyQWRkcmVzcwQLYmFzZUFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBBQ5iYXNlQXNzZXRJZFN0cgQMc2hhcmVBc3NldElkCQEFdmFsdWUBCQEMcGFyc2VBc3NldElkAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ9rZXlTaGFyZUFzc2V0SWQBBQtiYXNlQXNzZXRJZAkBB3dyYXBFcnIBAhVpbnZhbGlkIGJhc2UgYXNzZXQgaWQDCQAAAgUMc2hhcmVBc3NldElkBQxzaGFyZUFzc2V0SWQEBnBlcmlvZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAQlrZXlQZXJpb2QBBQtiYXNlQXNzZXRJZAkBB3dyYXBFcnIBAg5pbnZhbGlkIHBlcmlvZAMJAAACBQZwZXJpb2QFBnBlcmlvZAQddXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleVVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzAAAEFGNoZWNrQW1vdW50VG9Db252ZXJ0AwkAZgIFHXVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0AAAGCQEIdGhyb3dFcnIBAhBub3RoaW5nIHRvIGNsYWltAwkAAAIFFGNoZWNrQW1vdW50VG9Db252ZXJ0BRRjaGVja0Ftb3VudFRvQ29udmVydAQjdXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBCQEma2V5VXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QCBQtiYXNlQXNzZXRJZAULdXNlckFkZHJlc3MJAQd3cmFwRXJyAQIUZmFpbGVkIHRvIGdldCBwZXJpb2QEC2NoZWNrUGVyaW9kAwkAZgIFBnBlcmlvZAUjdXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QGCQEIdGhyb3dFcnIBAg5pbnZhbGlkIHBlcmlvZAMJAAACBQtjaGVja1BlcmlvZAULY2hlY2tQZXJpb2QEBXByaWNlCQCeAwEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoQgBCQERa2V5UHJpY2VQZXJpb2RHZXQCBQtiYXNlQXNzZXRJZAUjdXNlclNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnRQZXJpb2QJAQd3cmFwRXJyAQITZmFpbGVkIHRvIGdldCBwcmljZQQPYmFzZUFzc2V0QW1vdW50CQCgAwEJALwCAwkAtgIBBR11c2VyU2hhcmVBc3NldEFtb3VudFRvQ29udmVydAUFcHJpY2UFDXNjYWxlMThCaWdJbnQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBIGtleVVzZXJTaGFyZUFzc2V0QW1vdW50VG9Db252ZXJ0AgULYmFzZUFzc2V0SWQFC3VzZXJBZGRyZXNzAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFD2Jhc2VBc3NldEFtb3VudAULYmFzZUFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlIaXN0b3J5RW50cnkFBQtiYXNlQXNzZXRJZAIOY2xhaW1CYXNlQXNzZXQFBnBlcmlvZAULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQFD2Jhc2VBc3NldEFtb3VudAUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCGZpbmFsaXplAQ5iYXNlQXNzZXRJZFN0cgQLYmFzZUFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBBQ5iYXNlQXNzZXRJZFN0cgQMc2hhcmVBc3NldElkCQEFdmFsdWUBCQEMcGFyc2VBc3NldElkAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ9rZXlTaGFyZUFzc2V0SWQBBQtiYXNlQXNzZXRJZAkBB3dyYXBFcnIBAhVpbnZhbGlkIGJhc2UgYXNzZXQgaWQDCQAAAgUMc2hhcmVBc3NldElkBQxzaGFyZUFzc2V0SWQEBnBlcmlvZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAQlrZXlQZXJpb2QBBQtiYXNlQXNzZXRJZAkBB3dyYXBFcnIBAg5pbnZhbGlkIHBlcmlvZAMJAAACBQZwZXJpb2QFBnBlcmlvZAQXcGVyaW9kU3RhcnRIZWlnaHRPcHRpb24JAJ8IAQkBFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AgULYmFzZUFzc2V0SWQFBnBlcmlvZAQKY2hlY2tEZWxheQMJAAACBRdwZXJpb2RTdGFydEhlaWdodE9wdGlvbgUEdW5pdAUEdW5pdAQFZGVsYXkJAGUCBQZoZWlnaHQJAQV2YWx1ZQEFF3BlcmlvZFN0YXJ0SGVpZ2h0T3B0aW9uBAxibG9ja3NUb1dhaXQJAJcDAQkAzAgCAAAJAMwIAgkAZQIFCG1pbkRlbGF5BQVkZWxheQUDbmlsAwkAAAIFDGJsb2Nrc1RvV2FpdAAABQR1bml0CQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIhZmluYWxpemF0aW9uIHdpbGwgYmUgcG9zc2libGUgaW4gCQDMCAIJAKQDAQUMYmxvY2tzVG9XYWl0CQDMCAICByBibG9ja3MFA25pbAIAAwkAAAIFCmNoZWNrRGVsYXkFCmNoZWNrRGVsYXkEDSR0MDE3NzQzMTc5MjMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkBC2dldFBvb2xJbmZvAQULYmFzZUFzc2V0SWQJAQd3cmFwRXJyAQINaW52YWxpZCBhc3NldAQLcG9vbEFkZHJlc3MIBQ0kdDAxNzc0MzE3OTIzAl8xBAlscEFzc2V0SWQIBQ0kdDAxNzc0MzE3OTIzAl8yBA1zdGFraW5nUmV3YXJkCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQD8BwQFD3N0YWtpbmdDb250cmFjdAIHY2xhaW1XeAkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQUJbHBBc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAFBHVuaXQJAQd3cmFwRXJyAQIWaW52YWxpZCBjbGFpbVd4IHJlc3VsdAMJAAACBQ1zdGFraW5nUmV3YXJkBQ1zdGFraW5nUmV3YXJkBBB1c2VTdGFraW5nUmV3YXJkAwkAZgIFDXN0YWtpbmdSZXdhcmQAAAQIbG9ja1BhcnQJAGkCBQ1zdGFraW5nUmV3YXJkAAIEC2NvbnZlcnRQYXJ0CQBlAgUNc3Rha2luZ1Jld2FyZAUIbG9ja1BhcnQEAXIJAPwHBAUQYm9vc3RpbmdDb250cmFjdAIXdXNlck1heER1cmF0aW9uUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAQEbG9jawQHJG1hdGNoMAUBcgMDAwkAAQIIBQckbWF0Y2gwAl8xAgZTdHJpbmcJAAECCAUHJG1hdGNoMAJfMgIDSW50BwkAAQIFByRtYXRjaDACDShTdHJpbmcsIEludCkHBAhmdW5jdGlvbggFByRtYXRjaDACXzEECGR1cmF0aW9uCAUHJG1hdGNoMAJfMgMJAGYCBQhsb2NrUGFydAAACQD8BwQFEGJvb3N0aW5nQ29udHJhY3QFCGZ1bmN0aW9uCQDMCAIFCGR1cmF0aW9uBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCXd4QXNzZXRJZAUIbG9ja1BhcnQFA25pbAUEdW5pdAkBCHRocm93RXJyAQITaW52YWxpZCBsb2NrIHBhcmFtcwMJAAACBQRsb2NrBQRsb2NrBA9jb252ZXJ0ZWRBbW91bnQECWluQXNzZXRJZAUJd3hBc3NldElkBBBtaW5pbXVtVG9SZWNlaXZlAAAEDW91dEFzc2V0SWRTdHIJAQ9hc3NldElkVG9TdHJpbmcBBQt1c2RuQXNzZXRJZAQNdGFyZ2V0QWRkcmVzcwIACQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQD8BwQFDHN3YXBDb250cmFjdAIEc3dhcAkAzAgCBRBtaW5pbXVtVG9SZWNlaXZlCQDMCAIFDW91dEFzc2V0SWRTdHIJAMwIAgUNdGFyZ2V0QWRkcmVzcwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQlpbkFzc2V0SWQFC2NvbnZlcnRQYXJ0BQNuaWwDCQABAgUBQAIDSW50BQFABQR1bml0CQEHd3JhcEVycgECE2ludmFsaWQgc3dhcCByZXN1bHQDCQAAAgUPY29udmVydGVkQW1vdW50BQ9jb252ZXJ0ZWRBbW91bnQEDWxwQXNzZXRBbW91bnQEDG1pbk91dEFtb3VudAAABAlhdXRvU3Rha2UGCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQD8BwQFC3Bvb2xBZGRyZXNzAgtwdXRPbmVUa25WMgkAzAgCBQxtaW5PdXRBbW91bnQJAMwIAgUJYXV0b1N0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFC3VzZG5Bc3NldElkBQ9jb252ZXJ0ZWRBbW91bnQFA25pbAMJAAECBQFAAgNJbnQFAUAFBHVuaXQJAQd3cmFwRXJyAQIaaW52YWxpZCBwdXRPbmVUa25WMiByZXN1bHQDCQAAAgUNbHBBc3NldEFtb3VudAUNbHBBc3NldEFtb3VudAUNbHBBc3NldEFtb3VudAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUEdW5pdAMJAAACBRB1c2VTdGFraW5nUmV3YXJkBRB1c2VTdGFraW5nUmV3YXJkBA5zaGFyZUFzc2V0SW5mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFDHNoYXJlQXNzZXRJZAIeZmFpbGVkIHRvIGdldCBzaGFyZSBhc3NldCBpbmZvBBJzaGFyZUFzc2V0RW1pc3Npb24IBQ5zaGFyZUFzc2V0SW5mbwhxdWFudGl0eQQMc3Rha2VkQW1vdW50CQEOZW5zdXJlUG9zaXRpdmUBCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQD8BwQFD3N0YWtpbmdDb250cmFjdAIUc3Rha2VkQnlVc2VyUkVBRE9OTFkJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFCWxwQXNzZXRJZAkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAUEdW5pdAkBB3dyYXBFcnIBAiNpbnZhbGlkIHN0YWtlZEJ5VXNlclJFQURPTkxZIHJlc3VsdAQFcHJpY2UDCQAAAgUSc2hhcmVBc3NldEVtaXNzaW9uAAAFDXNjYWxlMThCaWdJbnQJAL0CBAkAtgIBBQxzdGFrZWRBbW91bnQFDXNjYWxlMThCaWdJbnQJALYCAQUSc2hhcmVBc3NldEVtaXNzaW9uBQVGTE9PUgMJAAACBQVwcmljZQUFcHJpY2UEGXNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBHGtleVNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQBBQtiYXNlQXNzZXRJZAAABApnZXRBY3Rpb25zAwkAZgIFGXNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQAAAQNdW5zdGFrZUFtb3VudAkAoAMBCQC9AgQJALYCAQUZc2hhcmVBc3NldEFtb3VudFRvQ29udmVydAUFcHJpY2UFDXNjYWxlMThCaWdJbnQFBUZMT09SBA9iYXNlQXNzZXRBbW91bnQECm91dEFzc2V0SWQFC2Jhc2VBc3NldElkBAxtaW5PdXRBbW91bnQAAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCgABQAkA/AcEBQtwb29sQWRkcmVzcwIVdW5zdGFrZUFuZEdldE9uZVRrblYyCQDMCAIFDXVuc3Rha2VBbW91bnQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFCm91dEFzc2V0SWQJAMwIAgUMbWluT3V0QW1vdW50BQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAFBHVuaXQJAQd3cmFwRXJyAQIkaW52YWxpZCB1bnN0YWtlQW5kR2V0T25lVGtuVjIgcmVzdWx0AwkAAAIFD2Jhc2VBc3NldEFtb3VudAUPYmFzZUFzc2V0QW1vdW50BBVzaGFyZUFzc2V0QnVybkFjdGlvbnMJAMwIAgkBBEJ1cm4CBQxzaGFyZUFzc2V0SWQFGXNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQFA25pbAQIcHJpY2VHZXQJAL0CBAkAtgIBBQ9iYXNlQXNzZXRBbW91bnQFDXNjYWxlMThCaWdJbnQJALYCAQUZc2hhcmVBc3NldEFtb3VudFRvQ29udmVydAUFRkxPT1IEFXByaWNlR2V0VXBkYXRlQWN0aW9ucwkAzAgCCQELQmluYXJ5RW50cnkCCQERa2V5UHJpY2VQZXJpb2RHZXQCBQtiYXNlQXNzZXRJZAUGcGVyaW9kCQCdAwEFCHByaWNlR2V0CQDMCAIJAQtTdHJpbmdFbnRyeQIJARJrZXlQcmljZUdldEhpc3RvcnkBBQtiYXNlQXNzZXRJZAkApgMBBQhwcmljZUdldAUDbmlsCQDOCAIFFXNoYXJlQXNzZXRCdXJuQWN0aW9ucwUVcHJpY2VHZXRVcGRhdGVBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwEGGJhc2VBc3NldEFtb3VudFRvQ29udmVydAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEba2V5QmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AQULYmFzZUFzc2V0SWQAAAQKcHV0QWN0aW9ucwMJAGYCBRhiYXNlQXNzZXRBbW91bnRUb0NvbnZlcnQAAAQNbHBBc3NldEFtb3VudAQMbWluT3V0QW1vdW50AAAECWF1dG9TdGFrZQYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgoAAUAJAPwHBAULcG9vbEFkZHJlc3MCC3B1dE9uZVRrblYyCQDMCAIFDG1pbk91dEFtb3VudAkAzAgCBQlhdXRvU3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULYmFzZUFzc2V0SWQFGGJhc2VBc3NldEFtb3VudFRvQ29udmVydAUDbmlsAwkAAQIFAUACA0ludAUBQAUEdW5pdAkBB3dyYXBFcnIBAhppbnZhbGlkIHB1dE9uZVRrblYyIHJlc3VsdAMJAAACBQ1scEFzc2V0QW1vdW50BQ1scEFzc2V0QW1vdW50BBBzaGFyZUFzc2V0QW1vdW50CQCgAwEJAL0CBAkAtgIBBQ1scEFzc2V0QW1vdW50BQ1zY2FsZTE4QmlnSW50BQVwcmljZQUFRkxPT1IEDGlzUmVpc3N1YWJsZQYEGHNoYXJlQXNzZXRSZWlzc3VlQWN0aW9ucwkAzAgCCQEHUmVpc3N1ZQMFDHNoYXJlQXNzZXRJZAUQc2hhcmVBc3NldEFtb3VudAUMaXNSZWlzc3VhYmxlBQNuaWwECHByaWNlUHV0CQC8AgMJALYCAQUYYmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0BQ1zY2FsZTE4QmlnSW50CQC2AgEFEHNoYXJlQXNzZXRBbW91bnQEFXByaWNlUHV0VXBkYXRlQWN0aW9ucwkAzAgCCQELQmluYXJ5RW50cnkCCQERa2V5UHJpY2VQZXJpb2RQdXQCBQtiYXNlQXNzZXRJZAUGcGVyaW9kCQCdAwEFCHByaWNlUHV0CQDMCAIJAQtTdHJpbmdFbnRyeQIJARJrZXlQcmljZVB1dEhpc3RvcnkBBQtiYXNlQXNzZXRJZAkApgMBBQhwcmljZVB1dAUDbmlsCQDOCAIFGHNoYXJlQXNzZXRSZWlzc3VlQWN0aW9ucwUVcHJpY2VQdXRVcGRhdGVBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwECW5ld1BlcmlvZAkAZAIFBnBlcmlvZAABBAdhY3Rpb25zCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCWtleVBlcmlvZAEFC2Jhc2VBc3NldElkBQluZXdQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlQZXJpb2RTdGFydEhlaWdodAIFC2Jhc2VBc3NldElkBQluZXdQZXJpb2QFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHGtleVNoYXJlQXNzZXRBbW91bnRUb0NvbnZlcnQBBQtiYXNlQXNzZXRJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEba2V5QmFzZUFzc2V0QW1vdW50VG9Db252ZXJ0AQULYmFzZUFzc2V0SWQAAAkAzAgCCQELQmluYXJ5RW50cnkCCQEOa2V5UHJpY2VQZXJpb2QCBQtiYXNlQXNzZXRJZAUGcGVyaW9kCQCdAwEFBXByaWNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlQcmljZUhpc3RvcnkBBQtiYXNlQXNzZXRJZAkApgMBBQVwcmljZQUDbmlsBQpwdXRBY3Rpb25zBQpnZXRBY3Rpb25zCQCUCgIFB2FjdGlvbnMJAJ0DAQUFcHJpY2UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABA90YXJnZXRQdWJsaWNLZXkEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAUCcGsDCQABAgUHJG1hdGNoMAIEVW5pdAgFAnR4D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXnHhe0f", "chainId": 84, "height": 2378533, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5nwqH9xD1xWSmSh51kErzz8zj7CcR68LxgKcVYovHcNd Next: 2bUJSF69oVgVZx6im6Av9mB7ipNMYzy67MnPmhUwpSxg Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let separator = "__"
5+
6+let shareAssetDecimals = 8
7+
8+let wavesString = "WAVES"
9+
10+let scale18 = 1000000000000000000
11+
12+let scale18BigInt = toBigInt(scale18)
13+
14+func wrapErr (msg) = makeString(["lp_staking_pools.ride:", msg], " ")
15+
16+
17+func throwErr (msg) = throw(wrapErr(msg))
18+
19+
20+func errKeyIsNotDefined (address,key) = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
21+
22+
23+func getStrOrFail (address,key) = valueOrErrorMessage(getString(address, key), errKeyIsNotDefined(address, key))
24+
25+
26+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), errKeyIsNotDefined(address, key))
27+
28+
29+func parseAssetId (input) = if ((input == wavesString))
30+ then unit
31+ else fromBase58String(input)
32+
33+
34+func assetIdToString (input) = if ((input == unit))
35+ then wavesString
36+ else toBase58String(value(input))
37+
38+
39+func ensurePositive (v) = if ((v >= 0))
40+ then v
41+ else throwErr("value should be positive")
42+
43+
44+func keyFactoryContract () = makeString(["%s", "factoryContract"], separator)
45+
46+
47+func keyLpStakingContract () = makeString(["%s", "lpStakingContract"], separator)
48+
49+
50+func keyStakingContract () = makeString(["%s", "stakingContract"], separator)
51+
52+
53+func keyBoostingContract () = makeString(["%s", "boostingContract"], separator)
54+
55+
56+func keySwapContract () = makeString(["%s", "swapContract"], separator)
57+
58+
59+func keyAssetsStoreContract () = makeString(["%s", "assetsStoreContract"], separator)
60+
61+
62+func keyUsdnAssetId () = makeString(["%s", "usdnAssetId"], separator)
63+
64+
65+func keyWxAssetId () = makeString(["%s", "wxAssetId"], separator)
66+
67+
68+func keyMinDelay () = makeString(["%s", "minDelay"], separator)
69+
70+
71+func keyShareAssetId (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "shareAssetId"], separator)
72+
73+
74+func keyBaseAssetId (shareAssetId) = makeString(["%s%s", assetIdToString(shareAssetId), "baseAssetId"], separator)
75+
76+
77+func keyPeriod (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "period"], separator)
78+
79+
80+func keyPeriodStartHeight (baseAssetId,period) = makeString(["%s%s%d", assetIdToString(baseAssetId), "periodStartHeight", toString(period)], separator)
81+
82+
83+func keyBaseAssetAmountToConvert (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "baseAssetAmountToConvert"], separator)
84+
85+
86+func keyShareAssetAmountToConvert (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "shareAssetAmountToConvert"], separator)
87+
88+
89+func keyUserBaseAssetAmountToConvert (baseAssetId,userAddress) = makeString(["%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "baseAssetAmountToConvert"], separator)
90+
91+
92+func keyUserBaseAssetAmountToConvertPeriod (baseAssetId,userAddress) = makeString(["%s%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "baseAssetAmountToConvert", "period"], separator)
93+
94+
95+func keyUserShareAssetAmountToConvert (baseAssetId,userAddress) = makeString(["%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "shareAssetAmountToConvert"], separator)
96+
97+
98+func keyUserShareAssetAmountToConvertPeriod (baseAssetId,userAddress) = makeString(["%s%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "shareAssetAmountToConvert", "period"], separator)
99+
100+
101+func keyPricePeriod (baseAssetId,period) = makeString(["%s%s%d", assetIdToString(baseAssetId), "price", toString(period)], separator)
102+
103+
104+func keyPriceHistory (baseAssetId) = makeString(["%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
105+
106+
107+func keyPricePeriodPut (baseAssetId,period) = makeString(["%s%s%d%s", assetIdToString(baseAssetId), "price", toString(period), "put"], separator)
108+
109+
110+func keyPricePutHistory (baseAssetId) = makeString(["%s%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", "put", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
111+
112+
113+func keyPricePeriodGet (baseAssetId,period) = makeString(["%s%s%d%s", assetIdToString(baseAssetId), "price", toString(period), "get"], separator)
114+
115+
116+func keyPriceGetHistory (baseAssetId) = makeString(["%s%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", "get", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
117+
118+
119+func keyHistoryEntry (baseAssetId,operation,period,userAddress,txId) = makeString(["%s%s%s%s", "history", operation, toString(userAddress), toBase58String(txId), toString(height)], separator)
120+
121+
4122 func keyManagerPublicKey () = "%s__managerPublicKey"
5123
6124
27145 }
28146
29147
30-func mustManager (i) = {
31- let pd = throw("Permission denied")
32- match managerPublicKeyOrUnit() {
33- case pk: ByteVector =>
34- if ((i.callerPublicKey == pk))
35- then true
36- else pd
37- case _: Unit =>
38- if ((i.caller == this))
39- then true
40- else pd
41- case _ =>
42- throw("Match error")
43- }
148+let permissionDeniedError = throw("Permission denied")
149+
150+func mustThis (i) = if ((i.caller == this))
151+ then true
152+ else permissionDeniedError
153+
154+
155+func mustManager (i) = match managerPublicKeyOrUnit() {
156+ case pk: ByteVector =>
157+ if ((i.callerPublicKey == pk))
158+ then true
159+ else permissionDeniedError
160+ case _: Unit =>
161+ mustThis(i)
162+ case _ =>
163+ throw("Match error")
164+}
165+
166+
167+let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract()))
168+
169+let lpStakingContract = addressFromStringValue(getStrOrFail(this, keyLpStakingContract()))
170+
171+let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract()))
172+
173+let boostingContract = addressFromStringValue(getStrOrFail(this, keyBoostingContract()))
174+
175+let swapContract = addressFromStringValue(getStrOrFail(this, keySwapContract()))
176+
177+let assetsStoreContract = addressFromStringValue(getStrOrFail(this, keyAssetsStoreContract()))
178+
179+let usdnAssetId = parseAssetId(getStrOrFail(this, keyUsdnAssetId()))
180+
181+let wxAssetId = parseAssetId(getStrOrFail(this, keyWxAssetId()))
182+
183+let minDelayDefault = 1440
184+
185+let minDelay = valueOrElse(getInteger(this, keyMinDelay()), minDelayDefault)
186+
187+func getPoolInfo (amountAssetId) = {
188+ let amountAssetIdStr = assetIdToString(amountAssetId)
189+ let priceAssetIdStr = assetIdToString(usdnAssetId)
190+ let poolInfoOption = {
191+ let @ = invoke(factoryContract, "poolInfoREADONLY", [amountAssetIdStr, priceAssetIdStr], nil)
192+ if ($isInstanceOf(@, "(Address, ByteVector)"))
193+ then @
194+ else unit
195+ }
196+ poolInfoOption
44197 }
45198
46199
64217 let pm = pendingManagerPublicKeyOrUnit()
65218 let hasPM = if (isDefined(pm))
66219 then true
67- else throw("No pending manager")
220+ else throwErr("no pending manager")
68221 if ((hasPM == hasPM))
69222 then {
70223 let checkPM = if ((i.callerPublicKey == value(pm)))
71224 then true
72- else throw("You are not pending manager")
225+ else throwErr("you are not pending manager")
73226 if ((checkPM == checkPM))
74227 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
228+ else throw("Strict value is not equal to itself.")
229+ }
230+ else throw("Strict value is not equal to itself.")
231+ }
232+
233+
234+
235+@Callable(i)
236+func create (baseAssetIdStr,shareAssetIdStr,shareAssetName,shareAssetDescription,shareAssetLogo) = {
237+ let shareAssetLabel = "LP_STAKING_POOLS"
238+ let baseAssetId = parseAssetId(baseAssetIdStr)
239+ let checks = [mustManager(i), if (isDefined(getPoolInfo(baseAssetId)))
240+ then true
241+ else throwErr("invalid base asset")]
242+ if ((checks == checks))
243+ then {
244+ let commonState = [IntegerEntry(keyPeriod(baseAssetId), 0)]
245+ if ((shareAssetIdStr == ""))
246+ then {
247+ let shareAssetIssueAmount = 1
248+ let shareAssetIssueAction = Issue(shareAssetName, shareAssetDescription, shareAssetIssueAmount, shareAssetDecimals, true)
249+ let calculatedShareAssetId = calculateAssetId(shareAssetIssueAction)
250+ let shareAssetBurnAction = Burn(calculatedShareAssetId, shareAssetIssueAmount)
251+ let calculatedShareAssetIdStr = toBase58String(calculatedShareAssetId)
252+ let createOrUpdate = invoke(assetsStoreContract, "createOrUpdate", [calculatedShareAssetIdStr, shareAssetLogo, false], nil)
253+ if ((createOrUpdate == createOrUpdate))
254+ then {
255+ let addLabel = invoke(assetsStoreContract, "addLabel", [calculatedShareAssetIdStr, shareAssetLabel], nil)
256+ if ((addLabel == addLabel))
257+ then $Tuple2((commonState ++ [shareAssetIssueAction, shareAssetBurnAction, StringEntry(keyShareAssetId(baseAssetId), calculatedShareAssetIdStr), StringEntry(keyBaseAssetId(calculatedShareAssetId), baseAssetIdStr)]), calculatedShareAssetIdStr)
258+ else throw("Strict value is not equal to itself.")
259+ }
260+ else throw("Strict value is not equal to itself.")
261+ }
262+ else {
263+ let shareAssetId = fromBase58String(shareAssetIdStr)
264+ let shareAssetInfo = valueOrErrorMessage(assetInfo(shareAssetId), wrapErr("invalid share asset id"))
265+ let checkIssuer = if ((shareAssetInfo.issuer == lpStakingContract))
266+ then true
267+ else throwErr("invalid share asset id issuer")
268+ if ((checkIssuer == checkIssuer))
269+ then $Tuple2((commonState ++ [StringEntry(keyShareAssetId(baseAssetId), shareAssetIdStr), StringEntry(keyShareAssetId(shareAssetId), baseAssetIdStr)]), shareAssetIdStr)
270+ else throw("Strict value is not equal to itself.")
271+ }
272+ }
273+ else throw("Strict value is not equal to itself.")
274+ }
275+
276+
277+
278+@Callable(i)
279+func put () = {
280+ let pmt = if ((size(i.payments) == 1))
281+ then i.payments[0]
282+ else throwErr("exactly 1 payment is expected")
283+ let baseAssetId = pmt.assetId
284+ let userAddress = i.caller
285+ let checks = [if (isDefined(getString(keyShareAssetId(baseAssetId))))
286+ then true
287+ else throwErr("invalid asset")]
288+ if ((checks == checks))
289+ then {
290+ let $t01007810181 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
291+ let poolAddress = $t01007810181._1
292+ let lpAssetId = $t01007810181._2
293+ let period = value(getInteger(keyPeriod(baseAssetId)))
294+ let userBaseAssetAmountToConvertPeriodOption = getInteger(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress))
295+ let claimShareAssetInvocation = if ((userBaseAssetAmountToConvertPeriodOption == unit))
296+ then unit
297+ else {
298+ let userBaseAssetAmountToConvertPeriod = value(userBaseAssetAmountToConvertPeriodOption)
299+ if ((userBaseAssetAmountToConvertPeriod == period))
300+ then unit
301+ else invoke(this, "claimShareAsset", [assetIdToString(baseAssetId), toString(userAddress)], nil)
302+ }
303+ if ((claimShareAssetInvocation == claimShareAssetInvocation))
304+ then {
305+ let baseAssetAmountToConvert = valueOrElse(getInteger(keyBaseAssetAmountToConvert(baseAssetId)), 0)
306+ let userBaseAssetAmountToConvert = valueOrElse(getInteger(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress)), 0)
307+ $Tuple2([IntegerEntry(keyBaseAssetAmountToConvert(baseAssetId), (baseAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress), (userBaseAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress), period), IntegerEntry(keyHistoryEntry(baseAssetId, "put", period, userAddress, i.transactionId), pmt.amount)], unit)
308+ }
309+ else throw("Strict value is not equal to itself.")
310+ }
311+ else throw("Strict value is not equal to itself.")
312+ }
313+
314+
315+
316+@Callable(i)
317+func claimShareAsset (baseAssetIdStr,userAddressStr) = {
318+ let userAddress = if ((userAddressStr == ""))
319+ then i.caller
320+ else {
321+ let checkCaller = mustThis(i)
322+ if ((checkCaller == checkCaller))
323+ then valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
324+ else throw("Strict value is not equal to itself.")
325+ }
326+ if ((userAddress == userAddress))
327+ then {
328+ let baseAssetId = parseAssetId(baseAssetIdStr)
329+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
330+ if ((shareAssetId == shareAssetId))
331+ then {
332+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
333+ if ((period == period))
334+ then {
335+ let userBaseAssetAmountToConvert = valueOrElse(getInteger(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress)), 0)
336+ let checkAmountToConvert = if ((userBaseAssetAmountToConvert > 0))
337+ then true
338+ else throwErr("nothing to claim")
339+ if ((checkAmountToConvert == checkAmountToConvert))
340+ then {
341+ let userBaseAssetAmountToConvertPeriod = valueOrErrorMessage(getInteger(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress)), wrapErr("failed to get period"))
342+ let checkPeriod = if ((period > userBaseAssetAmountToConvertPeriod))
343+ then true
344+ else throwErr("invalid period")
345+ if ((checkPeriod == checkPeriod))
346+ then {
347+ let price = toBigInt(valueOrErrorMessage(getBinary(keyPricePeriodPut(baseAssetId, userBaseAssetAmountToConvertPeriod)), wrapErr("failed to get price")))
348+ let shareAssetAmount = toInt(fraction(toBigInt(userBaseAssetAmountToConvert), scale18BigInt, price))
349+ $Tuple2([IntegerEntry(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress), 0), ScriptTransfer(userAddress, shareAssetAmount, shareAssetId), IntegerEntry(keyHistoryEntry(baseAssetId, "claimShareAsset", period, userAddress, i.transactionId), shareAssetAmount)], unit)
350+ }
351+ else throw("Strict value is not equal to itself.")
352+ }
353+ else throw("Strict value is not equal to itself.")
354+ }
355+ else throw("Strict value is not equal to itself.")
356+ }
357+ else throw("Strict value is not equal to itself.")
358+ }
359+ else throw("Strict value is not equal to itself.")
360+ }
361+
362+
363+
364+@Callable(i)
365+func get () = {
366+ let pmt = if ((size(i.payments) == 1))
367+ then i.payments[0]
368+ else throwErr("exactly 1 payment is expected")
369+ let shareAssetId = pmt.assetId
370+ let baseAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyBaseAssetId(shareAssetId)), wrapErr("invalid share asset id"))))
371+ if ((baseAssetId == baseAssetId))
372+ then {
373+ let userAddress = i.caller
374+ let $t01379013893 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
375+ let poolAddress = $t01379013893._1
376+ let lpAssetId = $t01379013893._2
377+ let period = value(getInteger(keyPeriod(baseAssetId)))
378+ let userShareAssetAmountToConvertPeriodOption = getInteger(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress))
379+ let claimBaseAssetInvocation = if ((userShareAssetAmountToConvertPeriodOption == unit))
380+ then unit
381+ else {
382+ let userShareAssetAmountToConvertPeriod = value(userShareAssetAmountToConvertPeriodOption)
383+ if ((userShareAssetAmountToConvertPeriod == period))
384+ then unit
385+ else invoke(this, "claimBaseAsset", [userAddress], nil)
386+ }
387+ if ((claimBaseAssetInvocation == claimBaseAssetInvocation))
388+ then {
389+ let shareAssetAmountToConvert = valueOrElse(getInteger(keyShareAssetAmountToConvert(baseAssetId)), 0)
390+ let userShareAssetAmountToConvert = valueOrElse(getInteger(keyUserShareAssetAmountToConvert(baseAssetId, userAddress)), 0)
391+ $Tuple2([IntegerEntry(keyShareAssetAmountToConvert(baseAssetId), (shareAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserShareAssetAmountToConvert(baseAssetId, userAddress), (userShareAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress), period), IntegerEntry(keyHistoryEntry(baseAssetId, "get", period, userAddress, i.transactionId), pmt.amount)], unit)
392+ }
393+ else throw("Strict value is not equal to itself.")
394+ }
395+ else throw("Strict value is not equal to itself.")
396+ }
397+
398+
399+
400+@Callable(i)
401+func claimBaseAsset (baseAssetIdStr,userAddressStr) = {
402+ let userAddress = if ((userAddressStr == ""))
403+ then i.caller
404+ else {
405+ let checkCaller = mustThis(i)
406+ if ((checkCaller == checkCaller))
407+ then valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
408+ else throw("Strict value is not equal to itself.")
409+ }
410+ if ((userAddress == userAddress))
411+ then {
412+ let baseAssetId = parseAssetId(baseAssetIdStr)
413+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
414+ if ((shareAssetId == shareAssetId))
415+ then {
416+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
417+ if ((period == period))
418+ then {
419+ let userShareAssetAmountToConvert = valueOrElse(getInteger(keyUserShareAssetAmountToConvert(baseAssetId, userAddress)), 0)
420+ let checkAmountToConvert = if ((userShareAssetAmountToConvert > 0))
421+ then true
422+ else throwErr("nothing to claim")
423+ if ((checkAmountToConvert == checkAmountToConvert))
424+ then {
425+ let userShareAssetAmountToConvertPeriod = valueOrErrorMessage(getInteger(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress)), wrapErr("failed to get period"))
426+ let checkPeriod = if ((period > userShareAssetAmountToConvertPeriod))
427+ then true
428+ else throwErr("invalid period")
429+ if ((checkPeriod == checkPeriod))
430+ then {
431+ let price = toBigInt(valueOrErrorMessage(getBinary(keyPricePeriodGet(baseAssetId, userShareAssetAmountToConvertPeriod)), wrapErr("failed to get price")))
432+ let baseAssetAmount = toInt(fraction(toBigInt(userShareAssetAmountToConvert), price, scale18BigInt))
433+ $Tuple2([IntegerEntry(keyUserShareAssetAmountToConvert(baseAssetId, userAddress), 0), ScriptTransfer(userAddress, baseAssetAmount, baseAssetId), IntegerEntry(keyHistoryEntry(baseAssetId, "claimBaseAsset", period, userAddress, i.transactionId), baseAssetAmount)], unit)
434+ }
435+ else throw("Strict value is not equal to itself.")
436+ }
437+ else throw("Strict value is not equal to itself.")
438+ }
439+ else throw("Strict value is not equal to itself.")
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ else throw("Strict value is not equal to itself.")
444+ }
445+
446+
447+
448+@Callable(i)
449+func finalize (baseAssetIdStr) = {
450+ let baseAssetId = parseAssetId(baseAssetIdStr)
451+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
452+ if ((shareAssetId == shareAssetId))
453+ then {
454+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
455+ if ((period == period))
456+ then {
457+ let periodStartHeightOption = getInteger(keyPeriodStartHeight(baseAssetId, period))
458+ let checkDelay = if ((periodStartHeightOption == unit))
459+ then unit
460+ else {
461+ let delay = (height - value(periodStartHeightOption))
462+ let blocksToWait = min([0, (minDelay - delay)])
463+ if ((blocksToWait == 0))
464+ then unit
465+ else throwErr(makeString(["finalization will be possible in ", toString(blocksToWait), " blocks"], ""))
466+ }
467+ if ((checkDelay == checkDelay))
468+ then {
469+ let $t01774317923 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
470+ let poolAddress = $t01774317923._1
471+ let lpAssetId = $t01774317923._2
472+ let stakingReward = valueOrErrorMessage({
473+ let @ = invoke(stakingContract, "claimWx", [assetIdToString(lpAssetId)], nil)
474+ if ($isInstanceOf(@, "Int"))
475+ then @
476+ else unit
477+ }, wrapErr("invalid claimWx result"))
478+ if ((stakingReward == stakingReward))
479+ then {
480+ let useStakingReward = if ((stakingReward > 0))
481+ then {
482+ let lockPart = (stakingReward / 2)
483+ let convertPart = (stakingReward - lockPart)
484+ let r = invoke(boostingContract, "userMaxDurationREADONLY", [toString(this)], nil)
485+ let lock = match r {
486+ case _ =>
487+ if (if (if ($isInstanceOf($match0._1, "String"))
488+ then $isInstanceOf($match0._2, "Int")
489+ else false)
490+ then $isInstanceOf($match0, "(String, Int)")
491+ else false)
492+ then {
493+ let function = $match0._1
494+ let duration = $match0._2
495+ if ((lockPart > 0))
496+ then invoke(boostingContract, function, [duration], [AttachedPayment(wxAssetId, lockPart)])
497+ else unit
498+ }
499+ else throwErr("invalid lock params")
500+ }
501+ if ((lock == lock))
502+ then {
503+ let convertedAmount = {
504+ let inAssetId = wxAssetId
505+ let minimumToReceive = 0
506+ let outAssetIdStr = assetIdToString(usdnAssetId)
507+ let targetAddress = ""
508+ valueOrErrorMessage({
509+ let @ = invoke(swapContract, "swap", [minimumToReceive, outAssetIdStr, targetAddress], [AttachedPayment(inAssetId, convertPart)])
510+ if ($isInstanceOf(@, "Int"))
511+ then @
512+ else unit
513+ }, wrapErr("invalid swap result"))
514+ }
515+ if ((convertedAmount == convertedAmount))
516+ then {
517+ let lpAssetAmount = {
518+ let minOutAmount = 0
519+ let autoStake = true
520+ valueOrErrorMessage({
521+ let @ = invoke(poolAddress, "putOneTknV2", [minOutAmount, autoStake], [AttachedPayment(usdnAssetId, convertedAmount)])
522+ if ($isInstanceOf(@, "Int"))
523+ then @
524+ else unit
525+ }, wrapErr("invalid putOneTknV2 result"))
526+ }
527+ if ((lpAssetAmount == lpAssetAmount))
528+ then lpAssetAmount
529+ else throw("Strict value is not equal to itself.")
530+ }
531+ else throw("Strict value is not equal to itself.")
532+ }
533+ else throw("Strict value is not equal to itself.")
534+ }
535+ else unit
536+ if ((useStakingReward == useStakingReward))
537+ then {
538+ let shareAssetInfo = valueOrErrorMessage(assetInfo(shareAssetId), "failed to get share asset info")
539+ let shareAssetEmission = shareAssetInfo.quantity
540+ let stakedAmount = ensurePositive(valueOrErrorMessage({
541+ let @ = invoke(stakingContract, "stakedByUserREADONLY", [assetIdToString(lpAssetId), toString(this)], nil)
542+ if ($isInstanceOf(@, "Int"))
543+ then @
544+ else unit
545+ }, wrapErr("invalid stakedByUserREADONLY result")))
546+ let price = if ((shareAssetEmission == 0))
547+ then scale18BigInt
548+ else fraction(toBigInt(stakedAmount), scale18BigInt, toBigInt(shareAssetEmission), FLOOR)
549+ if ((price == price))
550+ then {
551+ let shareAssetAmountToConvert = valueOrElse(getInteger(keyShareAssetAmountToConvert(baseAssetId)), 0)
552+ let getActions = if ((shareAssetAmountToConvert > 0))
553+ then {
554+ let unstakeAmount = toInt(fraction(toBigInt(shareAssetAmountToConvert), price, scale18BigInt, FLOOR))
555+ let baseAssetAmount = {
556+ let outAssetId = baseAssetId
557+ let minOutAmount = 0
558+ valueOrErrorMessage({
559+ let @ = invoke(poolAddress, "unstakeAndGetOneTknV2", [unstakeAmount, assetIdToString(outAssetId), minOutAmount], nil)
560+ if ($isInstanceOf(@, "Int"))
561+ then @
562+ else unit
563+ }, wrapErr("invalid unstakeAndGetOneTknV2 result"))
564+ }
565+ if ((baseAssetAmount == baseAssetAmount))
566+ then {
567+ let shareAssetBurnActions = [Burn(shareAssetId, shareAssetAmountToConvert)]
568+ let priceGet = fraction(toBigInt(baseAssetAmount), scale18BigInt, toBigInt(shareAssetAmountToConvert), FLOOR)
569+ let priceGetUpdateActions = [BinaryEntry(keyPricePeriodGet(baseAssetId, period), toBytes(priceGet)), StringEntry(keyPriceGetHistory(baseAssetId), toString(priceGet))]
570+ (shareAssetBurnActions ++ priceGetUpdateActions)
571+ }
572+ else throw("Strict value is not equal to itself.")
573+ }
574+ else nil
575+ let baseAssetAmountToConvert = valueOrElse(getInteger(keyBaseAssetAmountToConvert(baseAssetId)), 0)
576+ let putActions = if ((baseAssetAmountToConvert > 0))
577+ then {
578+ let lpAssetAmount = {
579+ let minOutAmount = 0
580+ let autoStake = true
581+ valueOrErrorMessage({
582+ let @ = invoke(poolAddress, "putOneTknV2", [minOutAmount, autoStake], [AttachedPayment(baseAssetId, baseAssetAmountToConvert)])
583+ if ($isInstanceOf(@, "Int"))
584+ then @
585+ else unit
586+ }, wrapErr("invalid putOneTknV2 result"))
587+ }
588+ if ((lpAssetAmount == lpAssetAmount))
589+ then {
590+ let shareAssetAmount = toInt(fraction(toBigInt(lpAssetAmount), scale18BigInt, price, FLOOR))
591+ let isReissuable = true
592+ let shareAssetReissueActions = [Reissue(shareAssetId, shareAssetAmount, isReissuable)]
593+ let pricePut = fraction(toBigInt(baseAssetAmountToConvert), scale18BigInt, toBigInt(shareAssetAmount))
594+ let pricePutUpdateActions = [BinaryEntry(keyPricePeriodPut(baseAssetId, period), toBytes(pricePut)), StringEntry(keyPricePutHistory(baseAssetId), toString(pricePut))]
595+ (shareAssetReissueActions ++ pricePutUpdateActions)
596+ }
597+ else throw("Strict value is not equal to itself.")
598+ }
599+ else nil
600+ let newPeriod = (period + 1)
601+ let actions = (([IntegerEntry(keyPeriod(baseAssetId), newPeriod), IntegerEntry(keyPeriodStartHeight(baseAssetId, newPeriod), height), IntegerEntry(keyShareAssetAmountToConvert(baseAssetId), 0), IntegerEntry(keyBaseAssetAmountToConvert(baseAssetId), 0), BinaryEntry(keyPricePeriod(baseAssetId, period), toBytes(price)), StringEntry(keyPriceHistory(baseAssetId), toString(price))] ++ putActions) ++ getActions)
602+ $Tuple2(actions, toBytes(price))
603+ }
604+ else throw("Strict value is not equal to itself.")
605+ }
606+ else throw("Strict value is not equal to itself.")
607+ }
608+ else throw("Strict value is not equal to itself.")
609+ }
610+ else throw("Strict value is not equal to itself.")
611+ }
75612 else throw("Strict value is not equal to itself.")
76613 }
77614 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let separator = "__"
5+
6+let shareAssetDecimals = 8
7+
8+let wavesString = "WAVES"
9+
10+let scale18 = 1000000000000000000
11+
12+let scale18BigInt = toBigInt(scale18)
13+
14+func wrapErr (msg) = makeString(["lp_staking_pools.ride:", msg], " ")
15+
16+
17+func throwErr (msg) = throw(wrapErr(msg))
18+
19+
20+func errKeyIsNotDefined (address,key) = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
21+
22+
23+func getStrOrFail (address,key) = valueOrErrorMessage(getString(address, key), errKeyIsNotDefined(address, key))
24+
25+
26+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), errKeyIsNotDefined(address, key))
27+
28+
29+func parseAssetId (input) = if ((input == wavesString))
30+ then unit
31+ else fromBase58String(input)
32+
33+
34+func assetIdToString (input) = if ((input == unit))
35+ then wavesString
36+ else toBase58String(value(input))
37+
38+
39+func ensurePositive (v) = if ((v >= 0))
40+ then v
41+ else throwErr("value should be positive")
42+
43+
44+func keyFactoryContract () = makeString(["%s", "factoryContract"], separator)
45+
46+
47+func keyLpStakingContract () = makeString(["%s", "lpStakingContract"], separator)
48+
49+
50+func keyStakingContract () = makeString(["%s", "stakingContract"], separator)
51+
52+
53+func keyBoostingContract () = makeString(["%s", "boostingContract"], separator)
54+
55+
56+func keySwapContract () = makeString(["%s", "swapContract"], separator)
57+
58+
59+func keyAssetsStoreContract () = makeString(["%s", "assetsStoreContract"], separator)
60+
61+
62+func keyUsdnAssetId () = makeString(["%s", "usdnAssetId"], separator)
63+
64+
65+func keyWxAssetId () = makeString(["%s", "wxAssetId"], separator)
66+
67+
68+func keyMinDelay () = makeString(["%s", "minDelay"], separator)
69+
70+
71+func keyShareAssetId (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "shareAssetId"], separator)
72+
73+
74+func keyBaseAssetId (shareAssetId) = makeString(["%s%s", assetIdToString(shareAssetId), "baseAssetId"], separator)
75+
76+
77+func keyPeriod (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "period"], separator)
78+
79+
80+func keyPeriodStartHeight (baseAssetId,period) = makeString(["%s%s%d", assetIdToString(baseAssetId), "periodStartHeight", toString(period)], separator)
81+
82+
83+func keyBaseAssetAmountToConvert (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "baseAssetAmountToConvert"], separator)
84+
85+
86+func keyShareAssetAmountToConvert (baseAssetId) = makeString(["%s%s", assetIdToString(baseAssetId), "shareAssetAmountToConvert"], separator)
87+
88+
89+func keyUserBaseAssetAmountToConvert (baseAssetId,userAddress) = makeString(["%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "baseAssetAmountToConvert"], separator)
90+
91+
92+func keyUserBaseAssetAmountToConvertPeriod (baseAssetId,userAddress) = makeString(["%s%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "baseAssetAmountToConvert", "period"], separator)
93+
94+
95+func keyUserShareAssetAmountToConvert (baseAssetId,userAddress) = makeString(["%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "shareAssetAmountToConvert"], separator)
96+
97+
98+func keyUserShareAssetAmountToConvertPeriod (baseAssetId,userAddress) = makeString(["%s%s%s%s", assetIdToString(baseAssetId), toString(userAddress), "shareAssetAmountToConvert", "period"], separator)
99+
100+
101+func keyPricePeriod (baseAssetId,period) = makeString(["%s%s%d", assetIdToString(baseAssetId), "price", toString(period)], separator)
102+
103+
104+func keyPriceHistory (baseAssetId) = makeString(["%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
105+
106+
107+func keyPricePeriodPut (baseAssetId,period) = makeString(["%s%s%d%s", assetIdToString(baseAssetId), "price", toString(period), "put"], separator)
108+
109+
110+func keyPricePutHistory (baseAssetId) = makeString(["%s%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", "put", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
111+
112+
113+func keyPricePeriodGet (baseAssetId,period) = makeString(["%s%s%d%s", assetIdToString(baseAssetId), "price", toString(period), "get"], separator)
114+
115+
116+func keyPriceGetHistory (baseAssetId) = makeString(["%s%s%s%s%d%d", assetIdToString(baseAssetId), "price", "history", "get", toString(lastBlock.height), toString(lastBlock.timestamp)], separator)
117+
118+
119+func keyHistoryEntry (baseAssetId,operation,period,userAddress,txId) = makeString(["%s%s%s%s", "history", operation, toString(userAddress), toBase58String(txId), toString(height)], separator)
120+
121+
4122 func keyManagerPublicKey () = "%s__managerPublicKey"
5123
6124
7125 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
8126
9127
10128 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
11129 case s: String =>
12130 fromBase58String(s)
13131 case _: Unit =>
14132 unit
15133 case _ =>
16134 throw("Match error")
17135 }
18136
19137
20138 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
21139 case s: String =>
22140 fromBase58String(s)
23141 case _: Unit =>
24142 unit
25143 case _ =>
26144 throw("Match error")
27145 }
28146
29147
30-func mustManager (i) = {
31- let pd = throw("Permission denied")
32- match managerPublicKeyOrUnit() {
33- case pk: ByteVector =>
34- if ((i.callerPublicKey == pk))
35- then true
36- else pd
37- case _: Unit =>
38- if ((i.caller == this))
39- then true
40- else pd
41- case _ =>
42- throw("Match error")
43- }
148+let permissionDeniedError = throw("Permission denied")
149+
150+func mustThis (i) = if ((i.caller == this))
151+ then true
152+ else permissionDeniedError
153+
154+
155+func mustManager (i) = match managerPublicKeyOrUnit() {
156+ case pk: ByteVector =>
157+ if ((i.callerPublicKey == pk))
158+ then true
159+ else permissionDeniedError
160+ case _: Unit =>
161+ mustThis(i)
162+ case _ =>
163+ throw("Match error")
164+}
165+
166+
167+let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract()))
168+
169+let lpStakingContract = addressFromStringValue(getStrOrFail(this, keyLpStakingContract()))
170+
171+let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract()))
172+
173+let boostingContract = addressFromStringValue(getStrOrFail(this, keyBoostingContract()))
174+
175+let swapContract = addressFromStringValue(getStrOrFail(this, keySwapContract()))
176+
177+let assetsStoreContract = addressFromStringValue(getStrOrFail(this, keyAssetsStoreContract()))
178+
179+let usdnAssetId = parseAssetId(getStrOrFail(this, keyUsdnAssetId()))
180+
181+let wxAssetId = parseAssetId(getStrOrFail(this, keyWxAssetId()))
182+
183+let minDelayDefault = 1440
184+
185+let minDelay = valueOrElse(getInteger(this, keyMinDelay()), minDelayDefault)
186+
187+func getPoolInfo (amountAssetId) = {
188+ let amountAssetIdStr = assetIdToString(amountAssetId)
189+ let priceAssetIdStr = assetIdToString(usdnAssetId)
190+ let poolInfoOption = {
191+ let @ = invoke(factoryContract, "poolInfoREADONLY", [amountAssetIdStr, priceAssetIdStr], nil)
192+ if ($isInstanceOf(@, "(Address, ByteVector)"))
193+ then @
194+ else unit
195+ }
196+ poolInfoOption
44197 }
45198
46199
47200 @Callable(i)
48201 func setManager (pendingManagerPublicKey) = {
49202 let checkCaller = mustManager(i)
50203 if ((checkCaller == checkCaller))
51204 then {
52205 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
53206 if ((checkManagerPublicKey == checkManagerPublicKey))
54207 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
55208 else throw("Strict value is not equal to itself.")
56209 }
57210 else throw("Strict value is not equal to itself.")
58211 }
59212
60213
61214
62215 @Callable(i)
63216 func confirmManager () = {
64217 let pm = pendingManagerPublicKeyOrUnit()
65218 let hasPM = if (isDefined(pm))
66219 then true
67- else throw("No pending manager")
220+ else throwErr("no pending manager")
68221 if ((hasPM == hasPM))
69222 then {
70223 let checkPM = if ((i.callerPublicKey == value(pm)))
71224 then true
72- else throw("You are not pending manager")
225+ else throwErr("you are not pending manager")
73226 if ((checkPM == checkPM))
74227 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
228+ else throw("Strict value is not equal to itself.")
229+ }
230+ else throw("Strict value is not equal to itself.")
231+ }
232+
233+
234+
235+@Callable(i)
236+func create (baseAssetIdStr,shareAssetIdStr,shareAssetName,shareAssetDescription,shareAssetLogo) = {
237+ let shareAssetLabel = "LP_STAKING_POOLS"
238+ let baseAssetId = parseAssetId(baseAssetIdStr)
239+ let checks = [mustManager(i), if (isDefined(getPoolInfo(baseAssetId)))
240+ then true
241+ else throwErr("invalid base asset")]
242+ if ((checks == checks))
243+ then {
244+ let commonState = [IntegerEntry(keyPeriod(baseAssetId), 0)]
245+ if ((shareAssetIdStr == ""))
246+ then {
247+ let shareAssetIssueAmount = 1
248+ let shareAssetIssueAction = Issue(shareAssetName, shareAssetDescription, shareAssetIssueAmount, shareAssetDecimals, true)
249+ let calculatedShareAssetId = calculateAssetId(shareAssetIssueAction)
250+ let shareAssetBurnAction = Burn(calculatedShareAssetId, shareAssetIssueAmount)
251+ let calculatedShareAssetIdStr = toBase58String(calculatedShareAssetId)
252+ let createOrUpdate = invoke(assetsStoreContract, "createOrUpdate", [calculatedShareAssetIdStr, shareAssetLogo, false], nil)
253+ if ((createOrUpdate == createOrUpdate))
254+ then {
255+ let addLabel = invoke(assetsStoreContract, "addLabel", [calculatedShareAssetIdStr, shareAssetLabel], nil)
256+ if ((addLabel == addLabel))
257+ then $Tuple2((commonState ++ [shareAssetIssueAction, shareAssetBurnAction, StringEntry(keyShareAssetId(baseAssetId), calculatedShareAssetIdStr), StringEntry(keyBaseAssetId(calculatedShareAssetId), baseAssetIdStr)]), calculatedShareAssetIdStr)
258+ else throw("Strict value is not equal to itself.")
259+ }
260+ else throw("Strict value is not equal to itself.")
261+ }
262+ else {
263+ let shareAssetId = fromBase58String(shareAssetIdStr)
264+ let shareAssetInfo = valueOrErrorMessage(assetInfo(shareAssetId), wrapErr("invalid share asset id"))
265+ let checkIssuer = if ((shareAssetInfo.issuer == lpStakingContract))
266+ then true
267+ else throwErr("invalid share asset id issuer")
268+ if ((checkIssuer == checkIssuer))
269+ then $Tuple2((commonState ++ [StringEntry(keyShareAssetId(baseAssetId), shareAssetIdStr), StringEntry(keyShareAssetId(shareAssetId), baseAssetIdStr)]), shareAssetIdStr)
270+ else throw("Strict value is not equal to itself.")
271+ }
272+ }
273+ else throw("Strict value is not equal to itself.")
274+ }
275+
276+
277+
278+@Callable(i)
279+func put () = {
280+ let pmt = if ((size(i.payments) == 1))
281+ then i.payments[0]
282+ else throwErr("exactly 1 payment is expected")
283+ let baseAssetId = pmt.assetId
284+ let userAddress = i.caller
285+ let checks = [if (isDefined(getString(keyShareAssetId(baseAssetId))))
286+ then true
287+ else throwErr("invalid asset")]
288+ if ((checks == checks))
289+ then {
290+ let $t01007810181 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
291+ let poolAddress = $t01007810181._1
292+ let lpAssetId = $t01007810181._2
293+ let period = value(getInteger(keyPeriod(baseAssetId)))
294+ let userBaseAssetAmountToConvertPeriodOption = getInteger(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress))
295+ let claimShareAssetInvocation = if ((userBaseAssetAmountToConvertPeriodOption == unit))
296+ then unit
297+ else {
298+ let userBaseAssetAmountToConvertPeriod = value(userBaseAssetAmountToConvertPeriodOption)
299+ if ((userBaseAssetAmountToConvertPeriod == period))
300+ then unit
301+ else invoke(this, "claimShareAsset", [assetIdToString(baseAssetId), toString(userAddress)], nil)
302+ }
303+ if ((claimShareAssetInvocation == claimShareAssetInvocation))
304+ then {
305+ let baseAssetAmountToConvert = valueOrElse(getInteger(keyBaseAssetAmountToConvert(baseAssetId)), 0)
306+ let userBaseAssetAmountToConvert = valueOrElse(getInteger(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress)), 0)
307+ $Tuple2([IntegerEntry(keyBaseAssetAmountToConvert(baseAssetId), (baseAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress), (userBaseAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress), period), IntegerEntry(keyHistoryEntry(baseAssetId, "put", period, userAddress, i.transactionId), pmt.amount)], unit)
308+ }
309+ else throw("Strict value is not equal to itself.")
310+ }
311+ else throw("Strict value is not equal to itself.")
312+ }
313+
314+
315+
316+@Callable(i)
317+func claimShareAsset (baseAssetIdStr,userAddressStr) = {
318+ let userAddress = if ((userAddressStr == ""))
319+ then i.caller
320+ else {
321+ let checkCaller = mustThis(i)
322+ if ((checkCaller == checkCaller))
323+ then valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
324+ else throw("Strict value is not equal to itself.")
325+ }
326+ if ((userAddress == userAddress))
327+ then {
328+ let baseAssetId = parseAssetId(baseAssetIdStr)
329+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
330+ if ((shareAssetId == shareAssetId))
331+ then {
332+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
333+ if ((period == period))
334+ then {
335+ let userBaseAssetAmountToConvert = valueOrElse(getInteger(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress)), 0)
336+ let checkAmountToConvert = if ((userBaseAssetAmountToConvert > 0))
337+ then true
338+ else throwErr("nothing to claim")
339+ if ((checkAmountToConvert == checkAmountToConvert))
340+ then {
341+ let userBaseAssetAmountToConvertPeriod = valueOrErrorMessage(getInteger(keyUserBaseAssetAmountToConvertPeriod(baseAssetId, userAddress)), wrapErr("failed to get period"))
342+ let checkPeriod = if ((period > userBaseAssetAmountToConvertPeriod))
343+ then true
344+ else throwErr("invalid period")
345+ if ((checkPeriod == checkPeriod))
346+ then {
347+ let price = toBigInt(valueOrErrorMessage(getBinary(keyPricePeriodPut(baseAssetId, userBaseAssetAmountToConvertPeriod)), wrapErr("failed to get price")))
348+ let shareAssetAmount = toInt(fraction(toBigInt(userBaseAssetAmountToConvert), scale18BigInt, price))
349+ $Tuple2([IntegerEntry(keyUserBaseAssetAmountToConvert(baseAssetId, userAddress), 0), ScriptTransfer(userAddress, shareAssetAmount, shareAssetId), IntegerEntry(keyHistoryEntry(baseAssetId, "claimShareAsset", period, userAddress, i.transactionId), shareAssetAmount)], unit)
350+ }
351+ else throw("Strict value is not equal to itself.")
352+ }
353+ else throw("Strict value is not equal to itself.")
354+ }
355+ else throw("Strict value is not equal to itself.")
356+ }
357+ else throw("Strict value is not equal to itself.")
358+ }
359+ else throw("Strict value is not equal to itself.")
360+ }
361+
362+
363+
364+@Callable(i)
365+func get () = {
366+ let pmt = if ((size(i.payments) == 1))
367+ then i.payments[0]
368+ else throwErr("exactly 1 payment is expected")
369+ let shareAssetId = pmt.assetId
370+ let baseAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyBaseAssetId(shareAssetId)), wrapErr("invalid share asset id"))))
371+ if ((baseAssetId == baseAssetId))
372+ then {
373+ let userAddress = i.caller
374+ let $t01379013893 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
375+ let poolAddress = $t01379013893._1
376+ let lpAssetId = $t01379013893._2
377+ let period = value(getInteger(keyPeriod(baseAssetId)))
378+ let userShareAssetAmountToConvertPeriodOption = getInteger(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress))
379+ let claimBaseAssetInvocation = if ((userShareAssetAmountToConvertPeriodOption == unit))
380+ then unit
381+ else {
382+ let userShareAssetAmountToConvertPeriod = value(userShareAssetAmountToConvertPeriodOption)
383+ if ((userShareAssetAmountToConvertPeriod == period))
384+ then unit
385+ else invoke(this, "claimBaseAsset", [userAddress], nil)
386+ }
387+ if ((claimBaseAssetInvocation == claimBaseAssetInvocation))
388+ then {
389+ let shareAssetAmountToConvert = valueOrElse(getInteger(keyShareAssetAmountToConvert(baseAssetId)), 0)
390+ let userShareAssetAmountToConvert = valueOrElse(getInteger(keyUserShareAssetAmountToConvert(baseAssetId, userAddress)), 0)
391+ $Tuple2([IntegerEntry(keyShareAssetAmountToConvert(baseAssetId), (shareAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserShareAssetAmountToConvert(baseAssetId, userAddress), (userShareAssetAmountToConvert + pmt.amount)), IntegerEntry(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress), period), IntegerEntry(keyHistoryEntry(baseAssetId, "get", period, userAddress, i.transactionId), pmt.amount)], unit)
392+ }
393+ else throw("Strict value is not equal to itself.")
394+ }
395+ else throw("Strict value is not equal to itself.")
396+ }
397+
398+
399+
400+@Callable(i)
401+func claimBaseAsset (baseAssetIdStr,userAddressStr) = {
402+ let userAddress = if ((userAddressStr == ""))
403+ then i.caller
404+ else {
405+ let checkCaller = mustThis(i)
406+ if ((checkCaller == checkCaller))
407+ then valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
408+ else throw("Strict value is not equal to itself.")
409+ }
410+ if ((userAddress == userAddress))
411+ then {
412+ let baseAssetId = parseAssetId(baseAssetIdStr)
413+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
414+ if ((shareAssetId == shareAssetId))
415+ then {
416+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
417+ if ((period == period))
418+ then {
419+ let userShareAssetAmountToConvert = valueOrElse(getInteger(keyUserShareAssetAmountToConvert(baseAssetId, userAddress)), 0)
420+ let checkAmountToConvert = if ((userShareAssetAmountToConvert > 0))
421+ then true
422+ else throwErr("nothing to claim")
423+ if ((checkAmountToConvert == checkAmountToConvert))
424+ then {
425+ let userShareAssetAmountToConvertPeriod = valueOrErrorMessage(getInteger(keyUserShareAssetAmountToConvertPeriod(baseAssetId, userAddress)), wrapErr("failed to get period"))
426+ let checkPeriod = if ((period > userShareAssetAmountToConvertPeriod))
427+ then true
428+ else throwErr("invalid period")
429+ if ((checkPeriod == checkPeriod))
430+ then {
431+ let price = toBigInt(valueOrErrorMessage(getBinary(keyPricePeriodGet(baseAssetId, userShareAssetAmountToConvertPeriod)), wrapErr("failed to get price")))
432+ let baseAssetAmount = toInt(fraction(toBigInt(userShareAssetAmountToConvert), price, scale18BigInt))
433+ $Tuple2([IntegerEntry(keyUserShareAssetAmountToConvert(baseAssetId, userAddress), 0), ScriptTransfer(userAddress, baseAssetAmount, baseAssetId), IntegerEntry(keyHistoryEntry(baseAssetId, "claimBaseAsset", period, userAddress, i.transactionId), baseAssetAmount)], unit)
434+ }
435+ else throw("Strict value is not equal to itself.")
436+ }
437+ else throw("Strict value is not equal to itself.")
438+ }
439+ else throw("Strict value is not equal to itself.")
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ else throw("Strict value is not equal to itself.")
444+ }
445+
446+
447+
448+@Callable(i)
449+func finalize (baseAssetIdStr) = {
450+ let baseAssetId = parseAssetId(baseAssetIdStr)
451+ let shareAssetId = value(parseAssetId(valueOrErrorMessage(getString(keyShareAssetId(baseAssetId)), wrapErr("invalid base asset id"))))
452+ if ((shareAssetId == shareAssetId))
453+ then {
454+ let period = valueOrErrorMessage(getInteger(keyPeriod(baseAssetId)), wrapErr("invalid period"))
455+ if ((period == period))
456+ then {
457+ let periodStartHeightOption = getInteger(keyPeriodStartHeight(baseAssetId, period))
458+ let checkDelay = if ((periodStartHeightOption == unit))
459+ then unit
460+ else {
461+ let delay = (height - value(periodStartHeightOption))
462+ let blocksToWait = min([0, (minDelay - delay)])
463+ if ((blocksToWait == 0))
464+ then unit
465+ else throwErr(makeString(["finalization will be possible in ", toString(blocksToWait), " blocks"], ""))
466+ }
467+ if ((checkDelay == checkDelay))
468+ then {
469+ let $t01774317923 = valueOrErrorMessage(getPoolInfo(baseAssetId), wrapErr("invalid asset"))
470+ let poolAddress = $t01774317923._1
471+ let lpAssetId = $t01774317923._2
472+ let stakingReward = valueOrErrorMessage({
473+ let @ = invoke(stakingContract, "claimWx", [assetIdToString(lpAssetId)], nil)
474+ if ($isInstanceOf(@, "Int"))
475+ then @
476+ else unit
477+ }, wrapErr("invalid claimWx result"))
478+ if ((stakingReward == stakingReward))
479+ then {
480+ let useStakingReward = if ((stakingReward > 0))
481+ then {
482+ let lockPart = (stakingReward / 2)
483+ let convertPart = (stakingReward - lockPart)
484+ let r = invoke(boostingContract, "userMaxDurationREADONLY", [toString(this)], nil)
485+ let lock = match r {
486+ case _ =>
487+ if (if (if ($isInstanceOf($match0._1, "String"))
488+ then $isInstanceOf($match0._2, "Int")
489+ else false)
490+ then $isInstanceOf($match0, "(String, Int)")
491+ else false)
492+ then {
493+ let function = $match0._1
494+ let duration = $match0._2
495+ if ((lockPart > 0))
496+ then invoke(boostingContract, function, [duration], [AttachedPayment(wxAssetId, lockPart)])
497+ else unit
498+ }
499+ else throwErr("invalid lock params")
500+ }
501+ if ((lock == lock))
502+ then {
503+ let convertedAmount = {
504+ let inAssetId = wxAssetId
505+ let minimumToReceive = 0
506+ let outAssetIdStr = assetIdToString(usdnAssetId)
507+ let targetAddress = ""
508+ valueOrErrorMessage({
509+ let @ = invoke(swapContract, "swap", [minimumToReceive, outAssetIdStr, targetAddress], [AttachedPayment(inAssetId, convertPart)])
510+ if ($isInstanceOf(@, "Int"))
511+ then @
512+ else unit
513+ }, wrapErr("invalid swap result"))
514+ }
515+ if ((convertedAmount == convertedAmount))
516+ then {
517+ let lpAssetAmount = {
518+ let minOutAmount = 0
519+ let autoStake = true
520+ valueOrErrorMessage({
521+ let @ = invoke(poolAddress, "putOneTknV2", [minOutAmount, autoStake], [AttachedPayment(usdnAssetId, convertedAmount)])
522+ if ($isInstanceOf(@, "Int"))
523+ then @
524+ else unit
525+ }, wrapErr("invalid putOneTknV2 result"))
526+ }
527+ if ((lpAssetAmount == lpAssetAmount))
528+ then lpAssetAmount
529+ else throw("Strict value is not equal to itself.")
530+ }
531+ else throw("Strict value is not equal to itself.")
532+ }
533+ else throw("Strict value is not equal to itself.")
534+ }
535+ else unit
536+ if ((useStakingReward == useStakingReward))
537+ then {
538+ let shareAssetInfo = valueOrErrorMessage(assetInfo(shareAssetId), "failed to get share asset info")
539+ let shareAssetEmission = shareAssetInfo.quantity
540+ let stakedAmount = ensurePositive(valueOrErrorMessage({
541+ let @ = invoke(stakingContract, "stakedByUserREADONLY", [assetIdToString(lpAssetId), toString(this)], nil)
542+ if ($isInstanceOf(@, "Int"))
543+ then @
544+ else unit
545+ }, wrapErr("invalid stakedByUserREADONLY result")))
546+ let price = if ((shareAssetEmission == 0))
547+ then scale18BigInt
548+ else fraction(toBigInt(stakedAmount), scale18BigInt, toBigInt(shareAssetEmission), FLOOR)
549+ if ((price == price))
550+ then {
551+ let shareAssetAmountToConvert = valueOrElse(getInteger(keyShareAssetAmountToConvert(baseAssetId)), 0)
552+ let getActions = if ((shareAssetAmountToConvert > 0))
553+ then {
554+ let unstakeAmount = toInt(fraction(toBigInt(shareAssetAmountToConvert), price, scale18BigInt, FLOOR))
555+ let baseAssetAmount = {
556+ let outAssetId = baseAssetId
557+ let minOutAmount = 0
558+ valueOrErrorMessage({
559+ let @ = invoke(poolAddress, "unstakeAndGetOneTknV2", [unstakeAmount, assetIdToString(outAssetId), minOutAmount], nil)
560+ if ($isInstanceOf(@, "Int"))
561+ then @
562+ else unit
563+ }, wrapErr("invalid unstakeAndGetOneTknV2 result"))
564+ }
565+ if ((baseAssetAmount == baseAssetAmount))
566+ then {
567+ let shareAssetBurnActions = [Burn(shareAssetId, shareAssetAmountToConvert)]
568+ let priceGet = fraction(toBigInt(baseAssetAmount), scale18BigInt, toBigInt(shareAssetAmountToConvert), FLOOR)
569+ let priceGetUpdateActions = [BinaryEntry(keyPricePeriodGet(baseAssetId, period), toBytes(priceGet)), StringEntry(keyPriceGetHistory(baseAssetId), toString(priceGet))]
570+ (shareAssetBurnActions ++ priceGetUpdateActions)
571+ }
572+ else throw("Strict value is not equal to itself.")
573+ }
574+ else nil
575+ let baseAssetAmountToConvert = valueOrElse(getInteger(keyBaseAssetAmountToConvert(baseAssetId)), 0)
576+ let putActions = if ((baseAssetAmountToConvert > 0))
577+ then {
578+ let lpAssetAmount = {
579+ let minOutAmount = 0
580+ let autoStake = true
581+ valueOrErrorMessage({
582+ let @ = invoke(poolAddress, "putOneTknV2", [minOutAmount, autoStake], [AttachedPayment(baseAssetId, baseAssetAmountToConvert)])
583+ if ($isInstanceOf(@, "Int"))
584+ then @
585+ else unit
586+ }, wrapErr("invalid putOneTknV2 result"))
587+ }
588+ if ((lpAssetAmount == lpAssetAmount))
589+ then {
590+ let shareAssetAmount = toInt(fraction(toBigInt(lpAssetAmount), scale18BigInt, price, FLOOR))
591+ let isReissuable = true
592+ let shareAssetReissueActions = [Reissue(shareAssetId, shareAssetAmount, isReissuable)]
593+ let pricePut = fraction(toBigInt(baseAssetAmountToConvert), scale18BigInt, toBigInt(shareAssetAmount))
594+ let pricePutUpdateActions = [BinaryEntry(keyPricePeriodPut(baseAssetId, period), toBytes(pricePut)), StringEntry(keyPricePutHistory(baseAssetId), toString(pricePut))]
595+ (shareAssetReissueActions ++ pricePutUpdateActions)
596+ }
597+ else throw("Strict value is not equal to itself.")
598+ }
599+ else nil
600+ let newPeriod = (period + 1)
601+ let actions = (([IntegerEntry(keyPeriod(baseAssetId), newPeriod), IntegerEntry(keyPeriodStartHeight(baseAssetId, newPeriod), height), IntegerEntry(keyShareAssetAmountToConvert(baseAssetId), 0), IntegerEntry(keyBaseAssetAmountToConvert(baseAssetId), 0), BinaryEntry(keyPricePeriod(baseAssetId, period), toBytes(price)), StringEntry(keyPriceHistory(baseAssetId), toString(price))] ++ putActions) ++ getActions)
602+ $Tuple2(actions, toBytes(price))
603+ }
604+ else throw("Strict value is not equal to itself.")
605+ }
606+ else throw("Strict value is not equal to itself.")
607+ }
608+ else throw("Strict value is not equal to itself.")
609+ }
610+ else throw("Strict value is not equal to itself.")
611+ }
75612 else throw("Strict value is not equal to itself.")
76613 }
77614 else throw("Strict value is not equal to itself.")
78615 }
79616
80617
81618 @Verifier(tx)
82619 func verify () = {
83620 let targetPublicKey = match managerPublicKeyOrUnit() {
84621 case pk: ByteVector =>
85622 pk
86623 case _: Unit =>
87624 tx.senderPublicKey
88625 case _ =>
89626 throw("Match error")
90627 }
91628 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
92629 }
93630

github/deemru/w8io/fabc49c 
48.62 ms