tx · J5Lh9MkQ91t9KECkv7tAdt17itVkLFbzdZMGejJ2G3RB

3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA:  -0.02900000 Waves

2022.09.12 17:24 [2226003] smart account 3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA > SELF 0.00000000 Waves

{ "type": 13, "id": "J5Lh9MkQ91t9KECkv7tAdt17itVkLFbzdZMGejJ2G3RB", "fee": 2900000, "feeAssetId": null, "timestamp": 1662992756587, "version": 1, "sender": "3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA", "senderPublicKey": "35yd3qw1gxKDxKwGAykHN9fANbXNWwseaUwbWDj24o3x", "proofs": [ "2mCyJRU8eUmxJzfXbFvsqyVHASyNERrZpJvc3SrfARmjE6qA5RbADyXkM5d5PTkpCq3YozsA7nngTDPzwoApb9oM" ], "script": "base64:BgJ/CAISAwoBCBIDCgEIEgASBAoCAQQSBwoFAQEBAQQSAwoBARIAEgcKBQEBAQgBEgQKAgEBEgMKAQESBAoCCAgSBAoCCAgSBAoCCAESABIDCgEIEgUKAwEBARIECgIIARIECgIBARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCFIABnNjYWxlOACAwtcvAAxzY2FsZThCaWdJbnQJALYCAQCAwtcvAAdzY2FsZTE4CQC2AgEAgICQu7rWrfANAAh0aG91c2FuZADoBwAKemVyb0JpZ0ludAkAtgIBAAAACW9uZUJpZ0ludAkAtgIBAAEACnNsaXBwYWdlNEQJALYCAQkAZQIFBnNjYWxlOAkAaQIJAGgCBQZzY2FsZTgAAQUGc2NhbGU4AAVBbXVsdAIDMTAwAAVEY29udgIBMQADU0VQAgJfXwAFRU1QVFkCAAAKUG9vbEFjdGl2ZQABAApQb29sUHV0RGlzAAIADlBvb2xNYXRjaGVyRGlzAAMADFBvb2xTaHV0ZG93bgAEAA5pZHhQb29sQWRkcmVzcwABAAlpZHhQb29sU3QAAgAJaWR4TFBBc0lkAAMACWlkeEFtQXNJZAAEAAlpZHhQckFzSWQABQALaWR4QW10QXNEY20ABgANaWR4UHJpY2VBc0RjbQAHAAtpZHhJQW10QXNJZAAIAA1pZHhJUHJpY2VBc0lkAAkAD2lkeEZhY3RTdGFrQ250cgABABBpZHhGYWN0U2xpcHBDbnRyAAcAEWlkeEZhY3RHd3hSZXdDbnRyAAoAEmZlZVBlcm1pbGxlRGVmYXVsdAAAAQJ0MQIHb3JpZ1ZhbA1vcmlnU2NhbGVNdWx0CQC8AgMJALYCAQUHb3JpZ1ZhbAUHc2NhbGUxOAkAtgIBBQ1vcmlnU2NhbGVNdWx0AQJmMQIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFB3NjYWxlMTgBAnRzAwNhbXQIcmVzU2NhbGUIY3VyU2NhbGUJAGsDBQNhbXQFCHJlc1NjYWxlBQhjdXJTY2FsZQEDYWJzAQN2YWwDCQC/AgIFCnplcm9CaWdJbnQFA3ZhbAkAvgIBBQN2YWwFA3ZhbAECZmMAAhMlc19fZmFjdG9yeUNvbnRyYWN0AQNtcGsAAhQlc19fbWFuYWdlclB1YmxpY0tleQEEcG1wawACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQECcGwAAhElcyVzX19wcmljZV9fbGFzdAECcGgCAWgBdAkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAWgJAMwIAgkApAMBBQF0BQNuaWwFA1NFUAEDcGF1AgJ1YQR0eElkCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwUCdWECAl9fBQR0eElkAQNnYXUCAnVhBHR4SWQJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQJ1YQICX18FBHR4SWQBAmFhAAIPJXNfX2Ftb3VudEFzc2V0AQJwYQACDiVzX19wcmljZUFzc2V0AQNhbXAAAgclc19fYW1wAQNhZGEAAg0lc19fYWRkb25BZGRyAA5rZXlGZWVQZXJtaWxsZQIPJXNfX2ZlZVBlcm1pbGxlAAtmZWVQZXJtaWxsZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQ5rZXlGZWVQZXJtaWxsZQUSZmVlUGVybWlsbGVEZWZhdWx0AQRmY2ZnAAIRJXNfX2ZhY3RvcnlDb25maWcBBG10cGsAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAnBjAgZpQW10QXMFaVByQXMJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FBmlBbXRBcwICX18FBWlQckFzAghfX2NvbmZpZwEDbWJhAQViQVN0cgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQViQVN0cgEDYXBzAAIMJXNfX3NodXRkb3duARxrZXlBbGxvd2VkTHBTdGFibGVTY3JpcHRIYXNoAAIdJXNfX2FsbG93ZWRMcFN0YWJsZVNjcmlwdEhhc2gBFmtleUZlZUNvbGxlY3RvckFkZHJlc3MAAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwEDdG9lAwNvclYGc2VuZHJWBm1hdGNoVgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhFGYWlsZWQ6IG9yZFZhbGlkPQkApQMBBQNvclYCCyBzbmRyVmFsaWQ9CQClAwEFBnNlbmRyVgIMIG10Y2hyVmFsaWQ9CQClAwEFBm1hdGNoVgEDc3RyAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEBnZhbFN0cgUHJG1hdGNoMAUGdmFsU3RyCQACAQITZmFpbCBjYXN0IHRvIFN0cmluZwEEc3RyZgIEYWRkcgNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQRhZGRyBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUEYWRkcgkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAgwgbm90IGRlZmluZWQFA25pbAIAAQRpbnRmAgRhZGRyA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBGFkZHIFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQRhZGRyCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDCBub3QgZGVmaW5lZAUDbmlsAgAAA2ZjYQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQR0aGlzCQECZmMAAAFBCQEEc3RyZgIFBHRoaXMJAQNhbXAAAQNpZ3MACQELdmFsdWVPckVsc2UCCQCbCAIFA2ZjYQkBA2FwcwAHAQJtcAAJANkEAQkBBHN0cmYCBQNmY2EJAQRtdHBrAAATZmVlQ29sbGVjdG9yQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBHN0cmYCBQNmY2EJARZrZXlGZWVDb2xsZWN0b3JBZGRyZXNzAAEDZ3BjAAQFYW10QXMJAQRzdHJmAgUEdGhpcwkBAmFhAAQHcHJpY2VBcwkBBHN0cmYCBQR0aGlzCQECcGEABAhpUHJpY2VBcwkBBGludGYCBQNmY2EJAQNtYmEBBQdwcmljZUFzBAZpQW10QXMJAQRpbnRmAgUDZmNhCQEDbWJhAQUFYW10QXMJALUJAgkBBHN0cmYCBQNmY2EJAQJwYwIJAKQDAQUGaUFtdEFzCQCkAwEFCGlQcmljZUFzBQNTRVABA2dmYwAJALUJAgkBBHN0cmYCBQNmY2EJAQRmY2ZnAAUDU0VQARFkYXRhUHV0QWN0aW9uSW5mbwoNaW5BbXRBc3NldEFtdA9pblByaWNlQXNzZXRBbXQIb3V0THBBbXQFcHJpY2UKc2xpcEJ5VXNlcgxzbGlwcGFnZVJlYWwIdHhIZWlnaHQLdHhUaW1lc3RhbXAMc2xpcGFnZUFtQW10DHNsaXBhZ2VQckFtdAkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUNaW5BbXRBc3NldEFtdAkAzAgCCQCkAwEFD2luUHJpY2VBc3NldEFtdAkAzAgCCQCkAwEFCG91dExwQW10CQDMCAIJAKQDAQUFcHJpY2UJAMwIAgkApAMBBQpzbGlwQnlVc2VyCQDMCAIJAKQDAQUMc2xpcHBhZ2VSZWFsCQDMCAIJAKQDAQUIdHhIZWlnaHQJAMwIAgkApAMBBQt0eFRpbWVzdGFtcAkAzAgCCQCkAwEFDHNsaXBhZ2VBbUFtdAkAzAgCCQCkAwEFDHNsaXBhZ2VQckFtdAUDbmlsBQNTRVABEWRhdGFHZXRBY3Rpb25JbmZvBg5vdXRBbXRBc3NldEFtdBBvdXRQcmljZUFzc2V0QW10B2luTHBBbXQFcHJpY2UIdHhIZWlnaHQLdHhUaW1lc3RhbXAJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQ5vdXRBbXRBc3NldEFtdAkAzAgCCQCkAwEFEG91dFByaWNlQXNzZXRBbXQJAMwIAgkApAMBBQdpbkxwQW10CQDMCAIJAKQDAQUFcHJpY2UJAMwIAgkApAMBBQh0eEhlaWdodAkAzAgCCQCkAwEFC3R4VGltZXN0YW1wBQNuaWwFA1NFUAENZ2V0QWNjQmFsYW5jZQEHYXNzZXRJZAMJAAACBQdhc3NldElkAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQdhc3NldElkAQRjcGJpAghwckFtdFgxOAhhbUFtdFgxOAkAvAIDBQhwckFtdFgxOAUHc2NhbGUxOAUIYW1BbXRYMTgBA3ZhZAMCQTECQTIIc2xpcHBhZ2UEBGRpZmYJALwCAwkAuAICBQJBMQUCQTIFDHNjYWxlOEJpZ0ludAUCQTIEBHBhc3MJAL8CAgkAuAICBQhzbGlwcGFnZQkBA2FicwEFBGRpZmYFCnplcm9CaWdJbnQDCQEBIQEFBHBhc3MJAAIBCQCsAgICCkJpZyBzbHBnOiAJAKYDAQUEZGlmZgkAlAoCBQRwYXNzCQCZAwEJAMwIAgUCQTEJAMwIAgUCQTIFA25pbAECdmQDAkQxAkQwBHNscGcEBGRpZmYJALwCAwUCRDAFDHNjYWxlOEJpZ0ludAUCRDEEBGZhaWwJAL8CAgUEc2xwZwUEZGlmZgMDBQRmYWlsBgkAvwICBQJEMAUCRDEJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCmAwEFAkQwAgEgCQCmAwEFAkQxAgEgCQCmAwEFBGRpZmYCASAJAKYDAQUEc2xwZwUEZmFpbAEDcGNwBAphbUFzc2V0RGNtCnByQXNzZXREY20FYW1BbXQFcHJBbXQEC2FtdEFzQW10WDE4CQECdDECBQVhbUFtdAUKYW1Bc3NldERjbQQKcHJBc0FtdFgxOAkBAnQxAgUFcHJBbXQFCnByQXNzZXREY20JAQRjcGJpAgUKcHJBc0FtdFgxOAULYW10QXNBbXRYMTgBCmNhbGNQcmljZXMDBWFtQW10BXByQW10BWxwQW10BANjZmcJAQNncGMABAhhbXRBc0RjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwULaWR4QW10QXNEY20EB3ByQXNEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDWlkeFByaWNlQXNEY20ECHByaWNlWDE4CQEDcGNwBAUIYW10QXNEY20FB3ByQXNEY20FBWFtQW10BQVwckFtdAQIYW1BbXRYMTgJAQJ0MQIFBWFtQW10BQhhbXRBc0RjbQQIcHJBbXRYMTgJAQJ0MQIFBXByQW10BQdwckFzRGNtBAhscEFtdFgxOAkBAnQxAgUFbHBBbXQFBnNjYWxlOAQNbHBQckluQW1Bc1gxOAkBBGNwYmkCBQhhbUFtdFgxOAUIbHBBbXRYMTgEDWxwUHJJblByQXNYMTgJAQRjcGJpAgUIcHJBbXRYMTgFCGxwQW10WDE4CQDMCAIFCHByaWNlWDE4CQDMCAIFDWxwUHJJbkFtQXNYMTgJAMwIAgUNbHBQckluUHJBc1gxOAUDbmlsAQ9jYWxjdWxhdGVQcmljZXMDBWFtQW10BXByQW10BWxwQW10BAFwCQEKY2FsY1ByaWNlcwMFBWFtQW10BQVwckFtdAUFbHBBbXQJAMwIAgkBAmYxAgkAkQMCBQFwAAAFBnNjYWxlOAkAzAgCCQECZjECCQCRAwIFAXAAAQUGc2NhbGU4CQDMCAIJAQJmMQIJAJEDAgUBcAACBQZzY2FsZTgFA25pbAEDZWdvBAZ0eElkNTgKcG10QXNzZXRJZAhwbXRMcEFtdAt1c2VyQWRkcmVzcwQDY2ZnCQEDZ3BjAAQEbHBJZAkAkQMCBQNjZmcFCWlkeExQQXNJZAQEYW1JZAkAkQMCBQNjZmcFCWlkeEFtQXNJZAQEcHJJZAkAkQMCBQNjZmcFCWlkeFByQXNJZAQFYW1EY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFC2lkeEFtdEFzRGNtBAVwckRjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUNaWR4UHJpY2VBc0RjbQQDc3RzCQCRAwIFA2NmZwUJaWR4UG9vbFN0BAdscEVtaXNzCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEJANkEAQUEbHBJZAILV3JvbmcgTFAgaWQIcXVhbnRpdHkDCQECIT0CBQRscElkBQpwbXRBc3NldElkCQACAQIPV3JvbmcgcG10IGFzc2V0BAlhbUJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEYW1JZAQMYW1CYWxhbmNlWDE4CQECdDECBQlhbUJhbGFuY2UFBWFtRGNtBAlwckJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEcHJJZAQMcHJCYWxhbmNlWDE4CQECdDECBQlwckJhbGFuY2UFBXByRGNtBAtjdXJQcmljZVgxOAkBBGNwYmkCBQxwckJhbGFuY2VYMTgFDGFtQmFsYW5jZVgxOAQIY3VyUHJpY2UJAQJmMQIFC2N1clByaWNlWDE4BQZzY2FsZTgEC3BtdExwQW10WDE4CQECdDECBQhwbXRMcEFtdAUGc2NhbGU4BApscEVtaXNzWDE4CQECdDECBQdscEVtaXNzBQZzY2FsZTgEC291dEFtQW10WDE4CQC8AgMFDGFtQmFsYW5jZVgxOAULcG10THBBbXRYMTgFCmxwRW1pc3NYMTgEC291dFByQW10WDE4CQC8AgMFDHByQmFsYW5jZVgxOAULcG10THBBbXRYMTgFCmxwRW1pc3NYMTgECG91dEFtQW10CQECZjECBQtvdXRBbUFtdFgxOAUFYW1EY20ECG91dFByQW10CQECZjECBQtvdXRQckFtdFgxOAUFcHJEY20EBXN0YXRlAwkAAAIFBnR4SWQ1OAIABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFCG91dEFtQW10AwkAAAIFBGFtSWQCBVdBVkVTBQR1bml0CQDZBAEFBGFtSWQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFCG91dFByQW10AwkAAAIFBHBySWQCBVdBVkVTBQR1bml0CQDZBAEFBHBySWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBA2dhdQIJAKUIAQULdXNlckFkZHJlc3MFBnR4SWQ1OAkBEWRhdGFHZXRBY3Rpb25JbmZvBgUIb3V0QW1BbXQFCG91dFByQW10BQhwbXRMcEFtdAUIY3VyUHJpY2UFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwbAAFCGN1clByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQhjdXJQcmljZQUDbmlsCQCcCgoFCG91dEFtQW10BQhvdXRQckFtdAUEYW1JZAUEcHJJZAUJYW1CYWxhbmNlBQlwckJhbGFuY2UFB2xwRW1pc3MFC2N1clByaWNlWDE4BQNzdHMFBXN0YXRlAQNlcG8MBnR4SWQ1OAhzbGlwcGFnZQdpbkFtQW10BmluQW1JZAdpblByQW10BmluUHJJZAt1c2VyQWRkcmVzcwZpc0V2YWwGZW1pdExwCmlzT25lQXNzZXQGcG10QW10BXBtdElkBANjZmcJAQNncGMABARscElkCQDZBAEJAJEDAgUDY2ZnBQlpZHhMUEFzSWQEB2FtSWRTdHIJAJEDAgUDY2ZnBQlpZHhBbUFzSWQEB3BySWRTdHIJAJEDAgUDY2ZnBQlpZHhQckFzSWQECWluQW1JZFN0cgkAkQMCBQNjZmcFC2lkeElBbXRBc0lkBAlpblBySWRTdHIJAJEDAgUDY2ZnBQ1pZHhJUHJpY2VBc0lkBAZhbXREY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFC2lkeEFtdEFzRGNtBAhwcmljZURjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUNaWR4UHJpY2VBc0RjbQQDc3RzCQCRAwIFA2NmZwUJaWR4UG9vbFN0BARscEVtCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFBGxwSWQCCFdyIGxwIGFzCHF1YW50aXR5BAlhbUJhbGFuY2UDBQZpc0V2YWwJAQ1nZXRBY2NCYWxhbmNlAQUHYW1JZFN0cgMDBQppc09uZUFzc2V0CQAAAgUFcG10SWQFB2FtSWRTdHIHCQBlAgkBDWdldEFjY0JhbGFuY2UBBQdhbUlkU3RyBQZwbXRBbXQDBQppc09uZUFzc2V0CQENZ2V0QWNjQmFsYW5jZQEFB2FtSWRTdHIJAGUCCQENZ2V0QWNjQmFsYW5jZQEFB2FtSWRTdHIFB2luQW1BbXQECXByQmFsYW5jZQMFBmlzRXZhbAkBDWdldEFjY0JhbGFuY2UBBQdwcklkU3RyAwMFCmlzT25lQXNzZXQJAAACBQVwbXRJZAUHcHJJZFN0cgcJAGUCCQENZ2V0QWNjQmFsYW5jZQEFB3BySWRTdHIFBnBtdEFtdAMFCmlzT25lQXNzZXQJAQ1nZXRBY2NCYWxhbmNlAQUHcHJJZFN0cgkAZQIJAQ1nZXRBY2NCYWxhbmNlAQUHcHJJZFN0cgUHaW5QckFtdAQPaW5BbUFzc2V0QW10WDE4CQECdDECBQdpbkFtQW10BQZhbXREY20ED2luUHJBc3NldEFtdFgxOAkBAnQxAgUHaW5QckFtdAUIcHJpY2VEY20EDHVzZXJQcmljZVgxOAkBBGNwYmkCBQ9pblByQXNzZXRBbXRYMTgFD2luQW1Bc3NldEFtdFgxOAQMYW1CYWxhbmNlWDE4CQECdDECBQlhbUJhbGFuY2UFBmFtdERjbQQMcHJCYWxhbmNlWDE4CQECdDECBQlwckJhbGFuY2UFCHByaWNlRGNtBAFyAwkAAAIFBGxwRW0AAAQLY3VyUHJpY2VYMTgFCnplcm9CaWdJbnQEC3NsaXBwYWdlWDE4BQp6ZXJvQmlnSW50BAhscEFtdFgxOAkAdgYJALkCAgUPaW5BbUFzc2V0QW10WDE4BQ9pblByQXNzZXRBbXRYMTgAAAkAtgIBAAUAAQAABQRET1dOCQCXCgUJAQJmMQIFCGxwQW10WDE4BQZzY2FsZTgJAQJmMQIFD2luQW1Bc3NldEFtdFgxOAUGYW10RGNtCQECZjECBQ9pblByQXNzZXRBbXRYMTgFCHByaWNlRGNtCQEEY3BiaQIJALcCAgUMcHJCYWxhbmNlWDE4BQ9pblByQXNzZXRBbXRYMTgJALcCAgUMYW1CYWxhbmNlWDE4BQ9pbkFtQXNzZXRBbXRYMTgFC3NsaXBwYWdlWDE4BAtjdXJQcmljZVgxOAkBBGNwYmkCBQxwckJhbGFuY2VYMTgFDGFtQmFsYW5jZVgxOAQPc2xpcHBhZ2VSZWFsWDE4CQC8AgMJAQNhYnMBCQC4AgIFC2N1clByaWNlWDE4BQx1c2VyUHJpY2VYMTgFB3NjYWxlMTgFC2N1clByaWNlWDE4BAtzbGlwcGFnZVgxOAkBAnQxAgUIc2xpcHBhZ2UFBnNjYWxlOAMDCQECIT0CBQtjdXJQcmljZVgxOAUKemVyb0JpZ0ludAkAvwICBQ9zbGlwcGFnZVJlYWxYMTgFC3NsaXBwYWdlWDE4BwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQ9zbGlwcGFnZVJlYWxYMTgCAyA+IAkApgMBBQtzbGlwcGFnZVgxOAQNbHBFbWlzc2lvblgxOAkBAnQxAgUEbHBFbQUGc2NhbGU4BApwclZpYUFtWDE4CQC8AgMFD2luQW1Bc3NldEFtdFgxOAULY3VyUHJpY2VYMTgFB3NjYWxlMTgECmFtVmlhUHJYMTgJALwCAwUPaW5QckFzc2V0QW10WDE4BQdzY2FsZTE4BQtjdXJQcmljZVgxOAQMZXhwZWN0ZWRBbXRzAwkAvwICBQpwclZpYUFtWDE4BQ9pblByQXNzZXRBbXRYMTgJAJQKAgUKYW1WaWFQclgxOAUPaW5QckFzc2V0QW10WDE4CQCUCgIFD2luQW1Bc3NldEFtdFgxOAUKcHJWaWFBbVgxOAQRZXhwQW10QXNzZXRBbXRYMTgIBQxleHBlY3RlZEFtdHMCXzEEE2V4cFByaWNlQXNzZXRBbXRYMTgIBQxleHBlY3RlZEFtdHMCXzIECGxwQW10WDE4CQC8AgMFDWxwRW1pc3Npb25YMTgFE2V4cFByaWNlQXNzZXRBbXRYMTgFDHByQmFsYW5jZVgxOAkAlwoFCQECZjECBQhscEFtdFgxOAUGc2NhbGU4CQECZjECBRFleHBBbXRBc3NldEFtdFgxOAUGYW10RGNtCQECZjECBRNleHBQcmljZUFzc2V0QW10WDE4BQhwcmljZURjbQULY3VyUHJpY2VYMTgFC3NsaXBwYWdlWDE4BAljYWxjTHBBbXQIBQFyAl8xBA5jYWxjQW1Bc3NldFBtdAgFAXICXzIEDmNhbGNQckFzc2V0UG10CAUBcgJfMwQIY3VyUHJpY2UJAQJmMQIIBQFyAl80BQZzY2FsZTgEDHNsaXBwYWdlQ2FsYwkBAmYxAggFAXICXzUFBnNjYWxlOAMJAGcCAAAFCWNhbGNMcEFtdAkAAgECB0xQIDw9IDAECWVtaXRMcEFtdAMJAQEhAQUGZW1pdExwAAAFCWNhbGNMcEFtdAQGYW1EaWZmCQBlAgUHaW5BbUFtdAUOY2FsY0FtQXNzZXRQbXQEBnByRGlmZgkAZQIFB2luUHJBbXQFDmNhbGNQckFzc2V0UG10BA0kdDAxNTY4MjE2MDI3AwMFCmlzT25lQXNzZXQJAAACBQVwbXRJZAUHYW1JZFN0cgcJAJQKAgUGcG10QW10AAADAwUKaXNPbmVBc3NldAkAAAIFBXBtdElkBQdwcklkU3RyBwkAlAoCAAAFBnBtdEFtdAkAlAoCBQ5jYWxjQW1Bc3NldFBtdAUOY2FsY1ByQXNzZXRQbXQECndyaXRlQW1BbXQIBQ0kdDAxNTY4MjE2MDI3Al8xBAp3cml0ZVByQW10CAUNJHQwMTU2ODIxNjAyNwJfMgQLY29tbW9uU3RhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwbAAFCGN1clByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQhjdXJQcmljZQkAzAgCCQELU3RyaW5nRW50cnkCCQEDcGF1AgULdXNlckFkZHJlc3MFBnR4SWQ1OAkBEWRhdGFQdXRBY3Rpb25JbmZvCgUKd3JpdGVBbUFtdAUKd3JpdGVQckFtdAUJZW1pdExwQW10BQhjdXJQcmljZQUIc2xpcHBhZ2UFDHNsaXBwYWdlQ2FsYwUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUGYW1EaWZmBQZwckRpZmYFA25pbAkAnwoNBQljYWxjTHBBbXQFCWVtaXRMcEFtdAUIY3VyUHJpY2UFCWFtQmFsYW5jZQUJcHJCYWxhbmNlBQRscEVtBQRscElkBQNzdHMFC2NvbW1vblN0YXRlBQZhbURpZmYFBnByRGlmZgUGaW5BbUlkBQZpblBySWQBA21vYQEFb3JkZXIEA2NmZwkBA2dwYwAEB2FtdEFzSWQJAJEDAgUDY2ZnBQlpZHhBbUFzSWQEBnByQXNJZAkAkQMCBQNjZmcFCWlkeFByQXNJZAQDc3RzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQlpZHhQb29sU3QECGFtdEFzRGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQtpZHhBbXRBc0RjbQQHcHJBc0RjbQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2NmZwUNaWR4UHJpY2VBc0RjbQQPYWNjQW10QXNCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFB2FtdEFzSWQEDmFjY1ByQXNCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBnByQXNJZAQLY3VyUHJpY2VYMTgDCQAAAggFBW9yZGVyCW9yZGVyVHlwZQUDQnV5CQEDcGNwBAUIYW10QXNEY20FB3ByQXNEY20JAGQCBQ9hY2NBbXRBc0JhbGFuY2UIBQVvcmRlcgZhbW91bnQFDmFjY1ByQXNCYWxhbmNlCQEDcGNwBAUIYW10QXNEY20FB3ByQXNEY20JAGUCBQ9hY2NBbXRBc0JhbGFuY2UIBQVvcmRlcgZhbW91bnQFDmFjY1ByQXNCYWxhbmNlBAhjdXJQcmljZQkBAmYxAgULY3VyUHJpY2VYMTgFBnNjYWxlOAMDAwkBA2lncwAGCQAAAgUDc3RzBQ5Qb29sTWF0Y2hlckRpcwYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgECDUFkbWluIGJsb2NrZWQECm9yQW10QXNzZXQICAUFb3JkZXIJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BApvckFtdEFzU3RyAwkAAAIFCm9yQW10QXNzZXQFBHVuaXQCBVdBVkVTCQDYBAEJAQV2YWx1ZQEFCm9yQW10QXNzZXQECW9yUHJBc3NldAgIBQVvcmRlcglhc3NldFBhaXIKcHJpY2VBc3NldAQJb3JQckFzU3RyAwkAAAIFCW9yUHJBc3NldAUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUJb3JQckFzc2V0AwMJAQIhPQIFCm9yQW10QXNTdHIFB2FtdEFzSWQGCQECIT0CBQlvclByQXNTdHIFBnByQXNJZAkAAgECCVdyIGFzc2V0cwQKb3JkZXJQcmljZQgFBW9yZGVyBXByaWNlBAhwcmljZURjbQkAawMFBnNjYWxlOAUHcHJBc0RjbQUIYW10QXNEY20EDmNhc3RPcmRlclByaWNlCQECdHMDBQpvcmRlclByaWNlBQZzY2FsZTgFCHByaWNlRGNtBBFpc09yZGVyUHJpY2VWYWxpZAMJAAACCAUFb3JkZXIJb3JkZXJUeXBlBQNCdXkJAGcCBQhjdXJQcmljZQUOY2FzdE9yZGVyUHJpY2UJAGcCBQ5jYXN0T3JkZXJQcmljZQUIY3VyUHJpY2UGAQJjZwEBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECCjEgcG1udCBleHAEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABApwbXRBc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEBnBtdEFtdAgFA3BtdAZhbW91bnQEAXIJAQNlZ28ECQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJANgEAQUKcG10QXNzZXRJZAUGcG10QW10CAUBaQZjYWxsZXIECG91dEFtQW10CAUBcgJfMQQIb3V0UHJBbXQIBQFyAl8yBANzdHMJAQ1wYXJzZUludFZhbHVlAQgFAXICXzkEBXN0YXRlCAUBcgNfMTADAwkBA2lncwAGCQAAAgUDc3RzBQxQb29sU2h1dGRvd24JAAIBCQCsAgICD0FkbWluIGJsb2NrZWQ6IAkApAMBBQNzdHMJAJcKBQUIb3V0QW1BbXQFCG91dFByQW10BQZwbXRBbXQFCnBtdEFzc2V0SWQFBXN0YXRlAQJjcAkGY2FsbGVyBHR4SWQHYW1Bc1BtdAdwckFzUG10CHNsaXBwYWdlBmVtaXRMcAppc09uZUFzc2V0BnBtdEFtdAVwbXRJZAQBcgkBA2VwbwwFBHR4SWQFCHNsaXBwYWdlCAkBBXZhbHVlAQUHYW1Bc1BtdAZhbW91bnQICQEFdmFsdWUBBQdhbUFzUG10B2Fzc2V0SWQICQEFdmFsdWUBBQdwckFzUG10BmFtb3VudAgJAQV2YWx1ZQEFB3ByQXNQbXQHYXNzZXRJZAUGY2FsbGVyBwUGZW1pdExwBQppc09uZUFzc2V0BQZwbXRBbXQFBXBtdElkBANzdHMJAQ1wYXJzZUludFZhbHVlAQgFAXICXzgDAwMJAQNpZ3MABgkAAAIFA3N0cwUKUG9vbFB1dERpcwYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIIQmxvY2tlZDoJAKQDAQUDc3RzBQFyAQd0YWtlRmVlAQZhbW91bnQEA2ZlZQkAawMFBmFtb3VudAULZmVlUGVybWlsbGUFCHRob3VzYW5kCQCUCgIJAGUCBQZhbW91bnQFA2ZlZQUDZmVlAQFtAAQHJG1hdGNoMAkAoggBCQEDbXBrAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAnBtAAQHJG1hdGNoMAkAoggBCQEEcG1wawADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAAJwZAkAAgECEVBlcm1pc3Npb24gZGVuaWVkAQJtbQEBaQQHJG1hdGNoMAkBAW0AAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBQJwZAMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFAnBkCQACAQILTWF0Y2ggZXJyb3IVAWkBC2NvbnN0cnVjdG9yAQJmYwQBYwkBAm1tAQUBaQMJAAACBQFjBQFjCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJmYwAFAmZjBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEAWMJAQJtbQEFAWkDCQAAAgUBYwUBYwQCY20JANkEAQUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkDCQAAAgUCY20FAmNtCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQRwbXBrAAUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5jb25maXJtTWFuYWdlcgAEAXAJAQJwbQAEA2hwbQMJAQlpc0RlZmluZWQBBQFwBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQNocG0FA2hwbQQDY3BtAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUBcAYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUDY3BtBQNjcG0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBA21wawAJANgEAQkBBXZhbHVlAQUBcAkAzAgCCQELRGVsZXRlRW50cnkBCQEEcG1wawAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQNwdXQCBHNsaXAJYXV0b1N0YWtlBAdmYWN0Q2ZnCQEDZ2ZjAAQLc3Rha2luZ0NudHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB2ZhY3RDZmcFD2lkeEZhY3RTdGFrQ250cgIKV3Igc3QgYWRkcgQIc2xpcENudHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB2ZhY3RDZmcFEGlkeEZhY3RTbGlwcENudHICCldyIHNsIGFkZHIDCQBmAgAABQRzbGlwCQACAQIOV3Jvbmcgc2xpcHBhZ2UDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAIJAAIBAgwyIHBtbnRzIGV4cGQEAWUJAQJjcAkJAKUIAQgFAWkGY2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQICQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50CQCRAwIIBQFpCHBheW1lbnRzAAEFBHNsaXAGBwAAAgAECWVtaXRMcEFtdAgFAWUCXzIECWxwQXNzZXRJZAgFAWUCXzcEBXN0YXRlCAUBZQJfOQQGYW1EaWZmCAUBZQNfMTAEBnByRGlmZggFAWUDXzExBARhbUlkCAUBZQNfMTIEBHBySWQIBQFlA18xMwQBcgkA/AcEBQNmY2ECBGVtaXQJAMwIAgUJZW1pdExwQW10BQNuaWwFA25pbAMJAAACBQFyBQFyBAJlbAQHJG1hdGNoMAUBcgMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAZsZWdhY3kFByRtYXRjaDAJAPwHBAUGbGVnYWN5AgRlbWl0CQDMCAIFCWVtaXRMcEFtdAUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZWwFAmVsBAJzYQMJAGYCBQZhbURpZmYAAAkA/AcEBQhzbGlwQ250cgIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBGFtSWQFBmFtRGlmZgUDbmlsBQNuaWwDCQAAAgUCc2EFAnNhBAJzcAMJAGYCBQZwckRpZmYAAAkA/AcEBQhzbGlwQ250cgIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHBySWQFBnByRGlmZgUDbmlsBQNuaWwDCQAAAgUCc3AFAnNwBAhscFRybnNmcgMFCWF1dG9TdGFrZQQCc3MJAPwHBAULc3Rha2luZ0NudHICBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCWxwQXNzZXRJZAUJZW1pdExwQW10BQNuaWwDCQAAAgUCc3MFAnNzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQllbWl0THBBbXQFCWxwQXNzZXRJZAUDbmlsCQDOCAIFBXN0YXRlBQhscFRybnNmcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQlwdXRPbmVUa24FC2FtQXNzZXRQYXJ0C3ByQXNzZXRQYXJ0BW91dExwCHNsaXBwYWdlCWF1dG9TdGFrZQQDY2ZnCQEDZ2ZjAAQLc3Rha2luZ0NudHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFA2NmZwUPaWR4RmFjdFN0YWtDbnRyAgpXciBzdCBhZGRyBAhzbGlwQ250cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUDY2ZnBRBpZHhGYWN0U2xpcHBDbnRyAgpXciBzbCBhZGRyBAdnd3hDbnRyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQNjZmcFEWlkeEZhY3RHd3hSZXdDbnRyAgtXciBnd3ggYWRkcgQHcG9vbENmZwkBA2dwYwAEBGFtSWQJAJEDAgUHcG9vbENmZwUJaWR4QW1Bc0lkBARwcklkCQCRAwIFB3Bvb2xDZmcFCWlkeFByQXNJZAQFYW1EY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdwb29sQ2ZnBQtpZHhBbXRBc0RjbQQFcHJEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdwb29sQ2ZnBQ1pZHhQcmljZUFzRGNtBAVhZGRvbgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEDYWRhAAIABAt1c2VyQWRkcmVzcwMJAAACBQVhZGRvbgkApQgBCAUBaQZjYWxsZXIIBQFpDG9yaWdpbkNhbGxlcggFAWkGY2FsbGVyAwMDAwkAZwIAAAUIc2xpcHBhZ2UGCQBnAgAABQthbUFzc2V0UGFydAYJAGcCAAAFC3ByQXNzZXRQYXJ0BgkAZwIAAAUFb3V0THAJAAIBAgxXcm9uZyBwYXJhbXMDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAgsxIHBtbnQgZXhwZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAECnBtdEFzc2V0SWQJANgEAQkBBXZhbHVlAQgFA3BtdAdhc3NldElkBBBwYXltZW50QW1vdW50UmF3CAUDcG10BmFtb3VudAQNJHQwMjQ2NDQyNDY5NgkBB3Rha2VGZWUBBRBwYXltZW50QW1vdW50UmF3BAZwbXRBbXQIBQ0kdDAyNDY0NDI0Njk2Al8xBAlmZWVBbW91bnQIBQ0kdDAyNDY0NDI0Njk2Al8yAwkAZgIAgK3iBAUQcGF5bWVudEFtb3VudFJhdwkAAgECDVdyb25nIHBtdCBhbXQECWFtQmFsYW5jZQkBDWdldEFjY0JhbGFuY2UBBQRhbUlkBAlwckJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEcHJJZAQNJHQwMjQ4NTYyNTQ3MgMJAAACBQpwbXRBc3NldElkBQRhbUlkAwMJAGYCBRBwYXltZW50QW1vdW50UmF3BQlhbUJhbGFuY2UGCQBmAgULYW1Bc3NldFBhcnQFBnBtdEFtdAkAAgECFmludmFsaWQgcGF5bWVudCBhbW91bnQJAJgKBgkAZQIFCWFtQmFsYW5jZQUQcGF5bWVudEFtb3VudFJhdwUJcHJCYWxhbmNlCQBlAgUGcG10QW10BQthbUFzc2V0UGFydAULcHJBc3NldFBhcnQAAAAAAwkAAAIFCnBtdEFzc2V0SWQFBHBySWQDAwkAZgIFEHBheW1lbnRBbW91bnRSYXcFCXByQmFsYW5jZQYJAGYCBQtwckFzc2V0UGFydAUGcG10QW10CQACAQIWaW52YWxpZCBwYXltZW50IGFtb3VudAkAmAoGBQlhbUJhbGFuY2UJAGUCBQlwckJhbGFuY2UFEHBheW1lbnRBbW91bnRSYXcAAAAACQBlAgUGcG10QW10BQtwckFzc2V0UGFydAULYW1Bc3NldFBhcnQJAAIBAhB3cm9uZyBwbXRBc3NldElkBAxhbUJhbGFuY2VOb3cIBQ0kdDAyNDg1NjI1NDcyAl8xBAxwckJhbGFuY2VOb3cIBQ0kdDAyNDg1NjI1NDcyAl8yBAx2aXJ0U3dhcEluQW0IBQ0kdDAyNDg1NjI1NDcyAl8zBA12aXJ0U3dhcE91dFByCAUNJHQwMjQ4NTYyNTQ3MgJfNAQMdmlydFN3YXBJblByCAUNJHQwMjQ4NTYyNTQ3MgJfNQQNdmlydFN3YXBPdXRBbQgFDSR0MDI0ODU2MjU0NzICXzYEAkQwCQD8BwQFB2d3eENudHICBWNhbGNECQDMCAIJAKQDAQUMYW1CYWxhbmNlTm93CQDMCAIJAKQDAQUMcHJCYWxhbmNlTm93CQDMCAIFAUEJAMwIAgUFQW11bHQJAMwIAgUFRGNvbnYFA25pbAUDbmlsBAJEMQkA/AcEBQdnd3hDbnRyAgVjYWxjRAkAzAgCCQCmAwEJALYCAQkAZQIJAGQCBQxhbUJhbGFuY2VOb3cFDHZpcnRTd2FwSW5BbQUNdmlydFN3YXBPdXRBbQkAzAgCCQCmAwEJALYCAQkAZQIJAGQCBQxwckJhbGFuY2VOb3cFDHZpcnRTd2FwSW5QcgUNdmlydFN3YXBPdXRQcgkAzAgCBQFBCQDMCAIFBUFtdWx0CQDMCAIFBURjb252BQNuaWwFA25pbAQGRDB2c0QxCQECdmQDCQCnAwEJAQNzdHIBBQJEMQkApwMBCQEDc3RyAQUCRDAFCnNsaXBwYWdlNEQDCQAAAgUGRDB2c0QxBQZEMHZzRDEEBmVzdFB1dAkBAmNwCQkApQgBCAUBaQZjYWxsZXIJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAkBD0F0dGFjaGVkUGF5bWVudAIJANkEAQUEYW1JZAULYW1Bc3NldFBhcnQJAQ9BdHRhY2hlZFBheW1lbnQCCQDZBAEFBHBySWQFC3ByQXNzZXRQYXJ0BQhzbGlwcGFnZQYGBQZwbXRBbXQFCnBtdEFzc2V0SWQEB2VzdGltTFAIBQZlc3RQdXQCXzIECWxwQXNzZXRJZAgFBmVzdFB1dAJfNwQFc3RhdGUIBQZlc3RQdXQCXzkEBmFtRGlmZggFBmVzdFB1dANfMTAEBnByRGlmZggFBmVzdFB1dANfMTEECWxwQ2FsY1JlcwkBA3ZhZAMJALYCAQUHZXN0aW1MUAkAtgIBBQVvdXRMcAkAtgIBBQhzbGlwcGFnZQQJZW1pdExwQW10CQCgAwEIBQlscENhbGNSZXMCXzIEAWUJAPwHBAUDZmNhAgRlbWl0CQDMCAIFCWVtaXRMcEFtdAUDbmlsBQNuaWwDCQAAAgUBZQUBZQQCZWwEByRtYXRjaDAFAWUDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQGbGVnYWN5BQckbWF0Y2gwCQD8BwQFBmxlZ2FjeQIEZW1pdAkAzAgCBQllbWl0THBBbXQFA25pbAUDbmlsBQR1bml0AwkAAAIFAmVsBQJlbAQCc2EDCQBmAgUGYW1EaWZmAAAJAPwHBAUIc2xpcENudHICA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQDZBAEFBGFtSWQFBmFtRGlmZgUDbmlsBQNuaWwDCQAAAgUCc2EFAnNhBAJzcAMJAGYCBQZwckRpZmYAAAkA/AcEBQhzbGlwQ250cgIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJANkEAQUEcHJJZAUGcHJEaWZmBQNuaWwFA25pbAMJAAACBQJzcAUCc3AECGxwVHJuc2ZyAwUJYXV0b1N0YWtlBAJzcwkA/AcEBQtzdGFraW5nQ250cgIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJbHBBc3NldElkBQllbWl0THBBbXQFA25pbAMJAAACBQJzcwUCc3MFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFCWVtaXRMcEFtdAUJbHBBc3NldElkBQNuaWwEEHNlbmRGZWVUb01hdGNoZXIDCQBmAgUJZmVlQW1vdW50AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUTZmVlQ29sbGVjdG9yQWRkcmVzcwUJZmVlQW1vdW50CQDZBAEFCnBtdEFzc2V0SWQFA25pbAUDbmlsCQDOCAIJAM4IAgUFc3RhdGUFCGxwVHJuc2ZyBRBzZW5kRmVlVG9NYXRjaGVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnB1dEZvckZyZWUBB21heFNscGcDCQBmAgAABQdtYXhTbHBnCQACAQIKV3Jvbmcgc2xwZwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAgkAAgECDDIgcG1udHMgZXhwZAQGZXN0UHV0CQECY3AJCQClCAEIBQFpBmNhbGxlcgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQEPQXR0YWNoZWRQYXltZW50AggJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkAkQMCCAUBaQhwYXltZW50cwABBQdtYXhTbHBnBwcAAAIACAUGZXN0UHV0Al85AWkBA2dldAAEAXIJAQJjZwEFAWkECW91dEFtdEFtdAgFAXICXzEECG91dFByQW10CAUBcgJfMgQGcG10QW10CAUBcgJfMwQKcG10QXNzZXRJZAgFAXICXzQEBXN0YXRlCAUBcgJfNQQBYgkA/AcEBQNmY2ECBGJ1cm4JAMwIAgUGcG10QW10BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCnBtdEFzc2V0SWQFBnBtdEFtdAUDbmlsAwkAAAIFAWIFAWIFBXN0YXRlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWdldE9uZVRrbgUKZXhjaFJlc3VsdAdub3RVc2VkCW91dEFtb3VudApvdXRBc3NldElkCHNsaXBwYWdlAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQILMSBwbW50IGV4cGQEA2NmZwkBA2dwYwAEBGxwSWQJAJEDAgUDY2ZnBQlpZHhMUEFzSWQEBGFtSWQJAJEDAgUDY2ZnBQlpZHhBbUFzSWQEBHBySWQJAJEDAgUDY2ZnBQlpZHhQckFzSWQEBWFtRGNtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDY2ZnBQtpZHhBbXRBc0RjbQQFcHJEY20JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNjZmcFDWlkeFByaWNlQXNEY20EA3N0cwkAkQMCBQNjZmcFCWlkeFBvb2xTdAQHZmFjdENmZwkBA2dmYwAEB2d3eENudHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB2ZhY3RDZmcFEWlkeEZhY3RHd3hSZXdDbnRyAgpXciBzbCBhZGRyBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQFYWRkb24JAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBA2FkYQACAAQLdXNlckFkZHJlc3MDCQAAAgUFYWRkb24JAKUIAQgFAWkGY2FsbGVyCAUBaQxvcmlnaW5DYWxsZXIIBQFpBmNhbGxlcgQGdHhJZDU4CQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQECnBtdEFzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQGcG10QW10CAUDcG10BmFtb3VudAMJAGYCAICU69wDBQZwbXRBbXQJAAIBAg1NaW4gcG10IDEwIExQAwMDCQBmAgAABQhzbGlwcGFnZQYJAGYCAAAFCmV4Y2hSZXN1bHQGCQBmAgAABQlvdXRBbW91bnQJAAIBAgxXcm9uZyBwYXJhbXMDCQECIT0CBQRscElkCQDYBAEFCnBtdEFzc2V0SWQJAAIBAghXcm9uZyBMUAQBcgkBA2VnbwQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAkA2AQBBQpwbXRBc3NldElkBQZwbXRBbXQIBQFpBmNhbGxlcgQKZXN0aW1BbUFtdAgFAXICXzEECmVzdGltUHJBbXQIBQFyAl8yBAlhbUJhbGFuY2UJAQ1nZXRBY2NCYWxhbmNlAQUEYW1JZAQJcHJCYWxhbmNlCQENZ2V0QWNjQmFsYW5jZQEFBHBySWQEDSR0MDMwNDE1MzA4NzUDCQAAAgUKb3V0QXNzZXRJZAUEYW1JZAkAmQoHCQBlAgUJYW1CYWxhbmNlBQplc3RpbUFtQW10CQBlAgUJcHJCYWxhbmNlBQplc3RpbVByQW10BQpleGNoUmVzdWx0BQplc3RpbVByQW10AAAAAAkAZAIFCmVzdGltQW1BbXQFCmV4Y2hSZXN1bHQDCQAAAgUKb3V0QXNzZXRJZAUEcHJJZAkAmQoHCQBlAgUJYW1CYWxhbmNlBQplc3RpbUFtQW10CQBlAgUJcHJCYWxhbmNlBQplc3RpbVByQW10AAAAAAUKZXhjaFJlc3VsdAUKZXN0aW1BbUFtdAkAZAIFCmVzdGltUHJBbXQFCmV4Y2hSZXN1bHQJAAIBAhB3cm9uZyBvdXRBc3NldElkBAxhbUJhbGFuY2VOb3cIBQ0kdDAzMDQxNTMwODc1Al8xBAxwckJhbGFuY2VOb3cIBQ0kdDAzMDQxNTMwODc1Al8yBAx2aXJ0U3dhcEluQW0IBQ0kdDAzMDQxNTMwODc1Al8zBA12aXJ0U3dhcE91dFByCAUNJHQwMzA0MTUzMDg3NQJfNAQMdmlydFN3YXBJblByCAUNJHQwMzA0MTUzMDg3NQJfNQQNdmlydFN3YXBPdXRBbQgFDSR0MDMwNDE1MzA4NzUCXzYEC3RvdGFsR2V0UmF3CAUNJHQwMzA0MTUzMDg3NQJfNwMDCQBmAgAABQx2aXJ0U3dhcEluQW0GCQBmAgAABQx2aXJ0U3dhcEluUHIJAAIBAgpXcm9uZyBjYWxjBAJEMAkA/AcEBQdnd3hDbnRyAgVjYWxjRAkAzAgCCQCkAwEFDGFtQmFsYW5jZU5vdwkAzAgCCQCkAwEFDHByQmFsYW5jZU5vdwkAzAgCBQFBCQDMCAIFBUFtdWx0CQDMCAIFBURjb252BQNuaWwFA25pbAQCRDEJAPwHBAUHZ3d4Q250cgIFY2FsY0QJAMwIAgkApAMBCQBkAgkAZQIFDGFtQmFsYW5jZU5vdwUMdmlydFN3YXBJbkFtBQ12aXJ0U3dhcE91dEFtCQDMCAIJAKQDAQkAZQIJAGQCBQxwckJhbGFuY2VOb3cFDXZpcnRTd2FwT3V0UHIFDHZpcnRTd2FwSW5QcgkAzAgCBQFBCQDMCAIFBUFtdWx0CQDMCAIFBURjb252BQNuaWwFA25pbAQGRDB2c0QxCQECdmQDCQCnAwEJAQNzdHIBBQJEMQkApwMBCQEDc3RyAQUCRDAFCnNsaXBwYWdlNEQDCQAAAgUGRDB2c0QxBQZEMHZzRDEECHRvdGFsR2V0CAkBB3Rha2VGZWUBBQt0b3RhbEdldFJhdwJfMQQIZmluYWxSZXMJAQN2YWQDCQC2AgEFCHRvdGFsR2V0CQC2AgEFCW91dEFtb3VudAkAtgIBBQhzbGlwcGFnZQMJAAACBQhmaW5hbFJlcwUIZmluYWxSZXMEDSR0MDMxNjIyMzE3MjYDCQAAAgUKb3V0QXNzZXRJZAUEYW1JZAkAlAoCCQCgAwEIBQhmaW5hbFJlcwJfMgAACQCUCgIAAAkAoAMBCAUIZmluYWxSZXMCXzIEBW91dEFtCAUNJHQwMzE2MjIzMTcyNgJfMQQFb3V0UHIIBQ0kdDAzMTYyMjMxNzI2Al8yBAt0b3RhbEFtb3VudAkAZAIFBW91dEFtBQVvdXRQcgQJZmVlQW1vdW50CQBlAgULdG90YWxHZXRSYXcFCHRvdGFsR2V0BBFvdXRBc3NldElkT3JXYXZlcwMJAAACBQpvdXRBc3NldElkAgVXQVZFUwUEdW5pdAkA2QQBBQpvdXRBc3NldElkBBBzZW5kRmVlVG9NYXRjaGVyAwkAZgIFCWZlZUFtb3VudAAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFE2ZlZUNvbGxlY3RvckFkZHJlc3MFCWZlZUFtb3VudAURb3V0QXNzZXRJZE9yV2F2ZXMFA25pbAUDbmlsBAhjdXJQclgxOAkBBGNwYmkCCQECdDECBQlwckJhbGFuY2UFBXByRGNtCQECdDECBQlhbUJhbGFuY2UFBWFtRGNtBAVjdXJQcgkBAmYxAgUIY3VyUHJYMTgFBnNjYWxlOAQFc3RhdGUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MFC3RvdGFsQW1vdW50BRFvdXRBc3NldElkT3JXYXZlcwkAzAgCCQELU3RyaW5nRW50cnkCCQEDZ2F1AgkApQgBBQt1c2VyQWRkcmVzcwUGdHhJZDU4CQERZGF0YUdldEFjdGlvbkluZm8GBQVvdXRBbQUFb3V0UHIFBnBtdEFtdAUFY3VyUHIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJwbAAFBWN1clByCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECcGgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQVjdXJQcgUDbmlsAwkAAAIFBXN0YXRlBQVzdGF0ZQQEYnVybgkA/AcEBQNmY2ECBGJ1cm4JAMwIAgUGcG10QW10BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCnBtdEFzc2V0SWQFBnBtdEFtdAUDbmlsAwkAAAIFBGJ1cm4FBGJ1cm4JAM4IAgUFc3RhdGUFEHNlbmRGZWVUb01hdGNoZXIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEJZ2V0Tm9MZXNzAhJub0xlc3NUaGVuQW10QXNzZXQUbm9MZXNzVGhlblByaWNlQXNzZXQEAXIJAQJjZwEFAWkECG91dEFtQW10CAUBcgJfMQQIb3V0UHJBbXQIBQFyAl8yBAZwbXRBbXQIBQFyAl8zBApwbXRBc3NldElkCAUBcgJfNAQFc3RhdGUIBQFyAl81AwkAZgIFEm5vTGVzc1RoZW5BbXRBc3NldAUIb3V0QW1BbXQJAAIBCQCsAgIJAKwCAgkArAICAglGYWlsZWQ6ICAJAKQDAQUIb3V0QW1BbXQCAyA8IAkApAMBBRJub0xlc3NUaGVuQW10QXNzZXQDCQBmAgUUbm9MZXNzVGhlblByaWNlQXNzZXQFCG91dFByQW10CQACAQkArAICCQCsAgIJAKwCAgIIRmFpbGVkOiAJAKQDAQUIb3V0UHJBbXQCAyA8IAkApAMBBRRub0xlc3NUaGVuUHJpY2VBc3NldAQUYnVybkxQQXNzZXRPbkZhY3RvcnkJAPwHBAUDZmNhAgRidXJuCQDMCAIFBnBtdEFtdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQpwbXRBc3NldElkBQZwbXRBbXQFA25pbAMJAAACBRRidXJuTFBBc3NldE9uRmFjdG9yeQUUYnVybkxQQXNzZXRPbkZhY3RvcnkFBXN0YXRlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXVuc3Rha2VBbmRHZXQBBmFtb3VudAQNY2hlY2tQYXltZW50cwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECDU5vIHBtbnRzIGV4cGQGAwkAAAIFDWNoZWNrUGF5bWVudHMFDWNoZWNrUGF5bWVudHMEA2NmZwkBA2dwYwAECmZhY3RvcnlDZmcJAQNnZmMABAlscEFzc2V0SWQJANkEAQkAkQMCBQNjZmcFCWlkeExQQXNJZAQHc3Rha2luZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKZmFjdG9yeUNmZwUPaWR4RmFjdFN0YWtDbnRyAgpXciBzdCBhZGRyBAp1bnN0YWtlSW52CQD8BwQFB3N0YWtpbmcCB3Vuc3Rha2UJAMwIAgkA2AQBBQlscEFzc2V0SWQJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQp1bnN0YWtlSW52BQp1bnN0YWtlSW52BAFyCQEDZWdvBAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQDYBAEFCWxwQXNzZXRJZAUGYW1vdW50CAUBaQZjYWxsZXIEA3N0cwkBDXBhcnNlSW50VmFsdWUBCAUBcgJfOQQFc3RhdGUIBQFyA18xMAQBdgMDCQEDaWdzAAYJAAACBQNzdHMFDFBvb2xTaHV0ZG93bgkAAgEJAKwCAgIJQmxvY2tlZDogCQCkAwEFA3N0cwYDCQAAAgUBdgUBdgQFYnVybkEJAPwHBAUDZmNhAgRidXJuCQDMCAIFBmFtb3VudAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQlscEFzc2V0SWQFBmFtb3VudAUDbmlsAwkAAAIFBWJ1cm5BBQVidXJuQQUFc3RhdGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYWN0aXZhdGUCCGFtdEFzU3RyB3ByQXNTdHIDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkApQgBBQNmY2EJAAIBAgZkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWEABQhhbXRBc1N0cgkAzAgCCQELU3RyaW5nRW50cnkCCQECcGEABQdwckFzU3RyBQNuaWwCB3N1Y2Nlc3MBaQEEc2V0UwIBawF2AwkBAiE9AgkApQgBCAUBaQZjYWxsZXIJAQRzdHJmAgUEdGhpcwkBA2FkYQAFAnBkCQDMCAIJAQtTdHJpbmdFbnRyeQIFAWsFAXYFA25pbAFpAQRzZXRJAgFrAXYDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkBBHN0cmYCBQR0aGlzCQEDYWRhAAUCcGQJAMwIAgkBDEludGVnZXJFbnRyeQIFAWsFAXYFA25pbAFpARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQNncGMAAWkBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBB2Fzc2V0SWQJAJQKAgUDbmlsCQENZ2V0QWNjQmFsYW5jZQEFB2Fzc2V0SWQBaQEZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQMFYW1BbXQFcHJBbXQFbHBBbXQEAnByCQEKY2FsY1ByaWNlcwMFBWFtQW10BQVwckFtdAUFbHBBbXQJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJwcgAACQDMCAIJAKYDAQkAkQMCBQJwcgABCQDMCAIJAKYDAQkAkQMCBQJwcgACBQNuaWwBaQEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIDdmFsDHJlc1NjYWxlTXVsdAkAlAoCBQNuaWwJAQJmMQIJAKcDAQUDdmFsBQxyZXNTY2FsZU11bHQBaQEUdG9YMThXcmFwcGVyUkVBRE9OTFkCB29yaWdWYWwNb3JpZ1NjYWxlTXVsdAkAlAoCBQNuaWwJAKYDAQkBAnQxAgUHb3JpZ1ZhbAUNb3JpZ1NjYWxlTXVsdAFpAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCCHByQW10WDE4CGFtQW10WDE4CQCUCgIFA25pbAkApgMBCQEEY3BiaQIJAKcDAQUIcHJBbXRYMTgJAKcDAQUIYW1BbXRYMTgBaQEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJBnR4SWQ1OAhzbGlwcGFnZQdpbkFtQW10BmluQW1JZAdpblByQW10BmluUHJJZAd1c3JBZGRyBmlzRXZhbAZlbWl0THAJAJQKAgUDbmlsCQEDZXBvDAUGdHhJZDU4BQhzbGlwcGFnZQUHaW5BbUFtdAUGaW5BbUlkBQdpblByQW10BQZpblBySWQFB3VzckFkZHIFBmlzRXZhbAUGZW1pdExwBwAAAgABaQEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEBnR4SWQ1OAdwbXRBc0lkCHBtdExwQW10B3VzckFkZHIEAXIJAQNlZ28EBQZ0eElkNTgFB3BtdEFzSWQFCHBtdExwQW10CQERQGV4dHJOYXRpdmUoMTA2MikBBQd1c3JBZGRyCQCUCgIFA25pbAkAnAoKCAUBcgJfMQgFAXICXzIIBQFyAl8zCAUBcgJfNAgFAXICXzUIBQFyAl82CAUBcgJfNwkApgMBCAUBcgJfOAgFAXICXzkIBQFyA18xMAECdHgBBnZlcmlmeQAED3RhcmdldFB1YmxpY0tleQQHJG1hdGNoMAkBAW0AAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwBQJwawMJAAECBQckbWF0Y2gwAgRVbml0CAUCdHgPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACBU9yZGVyBAVvcmRlcgUHJG1hdGNoMAQKbWF0Y2hlclB1YgkBAm1wAAQKb3JkZXJWYWxpZAkBA21vYQEFBW9yZGVyBAtzZW5kZXJWYWxpZAkA9AMDCAUFb3JkZXIJYm9keUJ5dGVzCQCRAwIIBQVvcmRlcgZwcm9vZnMAAAgFBW9yZGVyD3NlbmRlclB1YmxpY0tleQQMbWF0Y2hlclZhbGlkCQD0AwMIBQVvcmRlcglib2R5Qnl0ZXMJAJEDAggFBW9yZGVyBnByb29mcwABBQptYXRjaGVyUHViAwMDBQpvcmRlclZhbGlkBQtzZW5kZXJWYWxpZAcFDG1hdGNoZXJWYWxpZAcGCQEDdG9lAwUKb3JkZXJWYWxpZAULc2VuZGVyVmFsaWQFDG1hdGNoZXJWYWxpZAMJAAECBQckbWF0Y2gwAhRTZXRTY3JpcHRUcmFuc2FjdGlvbgQBcwUHJG1hdGNoMAQHbmV3SGFzaAkA9gMBCQEFdmFsdWUBCAUBcwZzY3JpcHQEC2FsbG93ZWRIYXNoCQDbBAEJAQV2YWx1ZQEJAJ0IAgUDZmNhCQEca2V5QWxsb3dlZExwU3RhYmxlU2NyaXB0SGFzaAAEC2N1cnJlbnRIYXNoCQDxBwEFBHRoaXMDAwkAAAIFC2FsbG93ZWRIYXNoBQduZXdIYXNoCQECIT0CBQtjdXJyZW50SGFzaAUHbmV3SGFzaAcGCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAABQ90YXJnZXRQdWJsaWNLZXkJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFD3RhcmdldFB1YmxpY0tleei8Leo=", "chainId": 84, "height": 2226003, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Hmt2U1HBWakXvid12118nvFqEyxFqneteFfGBCYMEsos Next: 5kH5x73nCt9s9dRMZ7VFN2GWQ6AyeAiCMReMkWsNFbdw Diff:
OldNewDifferences
66 let scale8BigInt = toBigInt(100000000)
77
88 let scale18 = toBigInt(1000000000000000000)
9+
10+let thousand = 1000
911
1012 let zeroBigInt = toBigInt(0)
1113
5355
5456 let idxFactGwxRewCntr = 10
5557
56-let delay = "%s__delay"
58+let feePermilleDefault = 0
5759
5860 func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5961
102104 func ada () = "%s__addonAddr"
103105
104106
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
107+let keyFeePermille = "%s__feePermille"
106108
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
109+let feePermille = valueOrElse(getInteger(this, keyFeePermille), feePermilleDefault)
110110
111111 func fcfg () = "%s__factoryConfig"
112112
124124
125125
126126 func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
127+
128+
129+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
127130
128131
129132 func toe (orV,sendrV,matchV) = throw(((((("Failed: ordValid=" + toString(orV)) + " sndrValid=") + toString(sendrV)) + " mtchrValid=") + toString(matchV)))
152155
153156 func mp () = fromBase58String(strf(fca, mtpk()))
154157
158+
159+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
155160
156161 func gpc () = {
157162 let amtAs = strf(this, aa())
337342 else calcLpAmt
338343 let amDiff = (inAmAmt - calcAmAssetPmt)
339344 let prDiff = (inPrAmt - calcPrAssetPmt)
340- let $t01560115946 = if (if (isOneAsset)
345+ let $t01568216027 = if (if (isOneAsset)
341346 then (pmtId == amIdStr)
342347 else false)
343348 then $Tuple2(pmtAmt, 0)
346351 else false)
347352 then $Tuple2(0, pmtAmt)
348353 else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
349- let writeAmAmt = $t01560115946._1
350- let writePrAmt = $t01560115946._2
354+ let writeAmAmt = $t01568216027._1
355+ let writePrAmt = $t01568216027._2
351356 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
352357 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
353358 }
428433 else (sts == PoolShutdown))
429434 then throw(("Blocked:" + toString(sts)))
430435 else r
436+ }
437+
438+
439+func takeFee (amount) = {
440+ let fee = fraction(amount, feePermille, thousand)
441+ $Tuple2((amount - fee), fee)
431442 }
432443
433444
588599 let userAddress = if ((addon == toString(i.caller)))
589600 then i.originCaller
590601 else i.caller
591- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
592- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
593- if ((check == check))
594- then if (if (if (if ((0 >= slippage))
595- then true
596- else (0 >= amAssetPart))
597- then true
598- else (0 >= prAssetPart))
599- then true
600- else (0 >= outLp))
601- then throw("Wrong params")
602- else if ((size(i.payments) != 1))
603- then throw("1 pmnt expd")
604- else {
605- let pmt = value(i.payments[0])
606- let pmtAssetId = toBase58String(value(pmt.assetId))
607- let pmtAmt = pmt.amount
608- if ((10000000 > pmtAmt))
609- then throw("Wrong pmt amt")
610- else {
611- let amBalance = getAccBalance(amId)
612- let prBalance = getAccBalance(prId)
613- let $t02485925435 = if ((pmtAssetId == amId))
614- then if (if ((pmtAmt > amBalance))
602+ if (if (if (if ((0 >= slippage))
603+ then true
604+ else (0 >= amAssetPart))
605+ then true
606+ else (0 >= prAssetPart))
607+ then true
608+ else (0 >= outLp))
609+ then throw("Wrong params")
610+ else if ((size(i.payments) != 1))
611+ then throw("1 pmnt expd")
612+ else {
613+ let pmt = value(i.payments[0])
614+ let pmtAssetId = toBase58String(value(pmt.assetId))
615+ let paymentAmountRaw = pmt.amount
616+ let $t02464424696 = takeFee(paymentAmountRaw)
617+ let pmtAmt = $t02464424696._1
618+ let feeAmount = $t02464424696._2
619+ if ((10000000 > paymentAmountRaw))
620+ then throw("Wrong pmt amt")
621+ else {
622+ let amBalance = getAccBalance(amId)
623+ let prBalance = getAccBalance(prId)
624+ let $t02485625472 = if ((pmtAssetId == amId))
625+ then if (if ((paymentAmountRaw > amBalance))
626+ then true
627+ else (amAssetPart > pmtAmt))
628+ then throw("invalid payment amount")
629+ else $Tuple6((amBalance - paymentAmountRaw), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
630+ else if ((pmtAssetId == prId))
631+ then if (if ((paymentAmountRaw > prBalance))
615632 then true
616- else (amAssetPart > pmtAmt))
633+ else (prAssetPart > pmtAmt))
617634 then throw("invalid payment amount")
618- else $Tuple6((amBalance - pmtAmt), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
619- else if ((pmtAssetId == prId))
620- then if (if ((pmtAmt > prBalance))
621- then true
622- else (prAssetPart > pmtAmt))
623- then throw("invalid payment amount")
624- else $Tuple6(amBalance, (prBalance - pmtAmt), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
625- else throw("wrong pmtAssetId")
626- let amBalanceNow = $t02485925435._1
627- let prBalanceNow = $t02485925435._2
628- let virtSwapInAm = $t02485925435._3
629- let virtSwapOutPr = $t02485925435._4
630- let virtSwapInPr = $t02485925435._5
631- let virtSwapOutAm = $t02485925435._6
632- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
633- let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
634- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
635- if ((D0vsD1 == D0vsD1))
636- then {
637- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
638- let estimLP = estPut._2
639- let lpAssetId = estPut._7
640- let state = estPut._9
641- let amDiff = estPut._10
642- let prDiff = estPut._11
643- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
644- let emitLpAmt = toInt(lpCalcRes._2)
645- let e = invoke(fca, "emit", [emitLpAmt], nil)
646- if ((e == e))
647- then {
648- let el = match e {
649- case legacy: Address =>
650- invoke(legacy, "emit", [emitLpAmt], nil)
651- case _ =>
652- unit
653- }
654- if ((el == el))
655- then {
656- let sa = if ((amDiff > 0))
657- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
658- else nil
659- if ((sa == sa))
660- then {
661- let sp = if ((prDiff > 0))
662- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
663- else nil
664- if ((sp == sp))
665- then {
666- let lpTrnsfr = if (autoStake)
667- then {
668- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
669- if ((ss == ss))
670- then nil
671- else throw("Strict value is not equal to itself.")
672- }
673- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
674- (state ++ lpTrnsfr)
675- }
676- else throw("Strict value is not equal to itself.")
677- }
678- else throw("Strict value is not equal to itself.")
679- }
680- else throw("Strict value is not equal to itself.")
681- }
682- else throw("Strict value is not equal to itself.")
683- }
684- else throw("Strict value is not equal to itself.")
685- }
686- }
687- else throw("Strict value is not equal to itself.")
688- }
689-
690-
691-
692-@Callable(i)
693-func putOneTknV2 (outLp,slippage,autoStake) = {
694- let cfg = gfc()
695- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wr st addr")
696- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wr sl addr")
697- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wr gwx addr")
698- let poolCfg = gpc()
699- let amId = poolCfg[idxAmAsId]
700- let prId = poolCfg[idxPrAsId]
701- let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
702- let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
703- let addon = valueOrElse(getString(this, ada()), "")
704- let userAddress = if ((addon == toString(i.caller)))
705- then i.originCaller
706- else i.caller
707- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
708- if ((size(i.payments) != 1))
709- then throw("1 pmnt expd")
710- else {
711- let pmt = value(i.payments[0])
712- let pmtAssetId = toBase58String(value(pmt.assetId))
713- let pmtAmt = pmt.amount
714- if ((10000000 > pmtAmt))
715- then throw("Wrong pmt amt")
716- else {
717- let amBalance = getAccBalance(amId)
718- let prBalance = getAccBalance(prId)
719- let $t02878529173 = if ((pmtAssetId == amId))
720- then if ((pmtAmt > amBalance))
721- then throw("invalid payment amount")
722- else $Tuple2((amBalance - pmtAmt), prBalance)
723- else if ((pmtAssetId == prId))
724- then if ((pmtAmt > prBalance))
725- then throw("invalid payment amount")
726- else $Tuple2(amBalance, (prBalance - pmtAmt))
727- else throw("wrong pmtAssetId")
728- let amBalanceNow = $t02878529173._1
729- let prBalanceNow = $t02878529173._2
730- let $t02917929313 = if ((pmtAssetId == amId))
731- then $Tuple2(amBalanceNow, prBalanceNow)
732- else $Tuple2(prBalanceNow, amBalanceNow)
733- let amBalanceForCalc = $t02917929313._1
734- let prBalanceForCalc = $t02917929313._2
735- let xPrecision = 1
736- let result = {
737- let @ = invoke(gwxCntr, "calcPutXOnly", [toString(pmtAmt), toString(amBalanceForCalc), toString(prBalanceForCalc), "", A, Amult, toString(xPrecision), Dconv], nil)
738- if ($isInstanceOf(@, "(Int, Int)"))
739- then @
740- else throw(($getType(invoke(gwxCntr, "calcPutXOnly", [toString(pmtAmt), toString(amBalanceForCalc), toString(prBalanceForCalc), "", A, Amult, toString(xPrecision), Dconv], nil)) + " couldn't be cast to (Int, Int)"))
635+ else $Tuple6(amBalance, (prBalance - paymentAmountRaw), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
636+ else throw("wrong pmtAssetId")
637+ let amBalanceNow = $t02485625472._1
638+ let prBalanceNow = $t02485625472._2
639+ let virtSwapInAm = $t02485625472._3
640+ let virtSwapOutPr = $t02485625472._4
641+ let virtSwapInPr = $t02485625472._5
642+ let virtSwapOutAm = $t02485625472._6
643+ let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
644+ let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
645+ let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
646+ if ((D0vsD1 == D0vsD1))
647+ then {
648+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
649+ let estimLP = estPut._2
650+ let lpAssetId = estPut._7
651+ let state = estPut._9
652+ let amDiff = estPut._10
653+ let prDiff = estPut._11
654+ let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
655+ let emitLpAmt = toInt(lpCalcRes._2)
656+ let e = invoke(fca, "emit", [emitLpAmt], nil)
657+ if ((e == e))
658+ then {
659+ let el = match e {
660+ case legacy: Address =>
661+ invoke(legacy, "emit", [emitLpAmt], nil)
662+ case _ =>
663+ unit
664+ }
665+ if ((el == el))
666+ then {
667+ let sa = if ((amDiff > 0))
668+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
669+ else nil
670+ if ((sa == sa))
671+ then {
672+ let sp = if ((prDiff > 0))
673+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
674+ else nil
675+ if ((sp == sp))
676+ then {
677+ let lpTrnsfr = if (autoStake)
678+ then {
679+ let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
680+ if ((ss == ss))
681+ then nil
682+ else throw("Strict value is not equal to itself.")
683+ }
684+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
685+ let sendFeeToMatcher = if ((feeAmount > 0))
686+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
687+ else nil
688+ ((state ++ lpTrnsfr) ++ sendFeeToMatcher)
689+ }
690+ else throw("Strict value is not equal to itself.")
691+ }
692+ else throw("Strict value is not equal to itself.")
693+ }
694+ else throw("Strict value is not equal to itself.")
695+ }
696+ else throw("Strict value is not equal to itself.")
697+ }
698+ else throw("Strict value is not equal to itself.")
741699 }
742- let $t02982529921 = if ((pmtAssetId == amId))
743- then result
744- else $Tuple2(result._2, result._1)
745- let amAssetPart = $t02982529921._1
746- let prAssetPart = $t02982529921._2
747- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
748- let estimLP = estPut._2
749- let lpAssetId = estPut._7
750- let state = estPut._9
751- let amDiff = estPut._10
752- let prDiff = estPut._11
753- let emitLpAmt = if ((outLp > 0))
754- then {
755- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
756- toInt(lpCalcRes._2)
757- }
758- else estimLP
759- let e = invoke(fca, "emit", [emitLpAmt], nil)
760- if ((e == e))
761- then {
762- let el = match e {
763- case legacy: Address =>
764- invoke(legacy, "emit", [emitLpAmt], nil)
765- case _ =>
766- unit
767- }
768- if ((el == el))
769- then {
770- let sa = if ((amDiff > 0))
771- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
772- else nil
773- if ((sa == sa))
774- then {
775- let sp = if ((prDiff > 0))
776- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
777- else nil
778- if ((sp == sp))
779- then {
780- let lpTrnsfr = if (autoStake)
781- then {
782- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
783- if ((ss == ss))
784- then nil
785- else throw("Strict value is not equal to itself.")
786- }
787- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
788- (state ++ lpTrnsfr)
789- }
790- else throw("Strict value is not equal to itself.")
791- }
792- else throw("Strict value is not equal to itself.")
793- }
794- else throw("Strict value is not equal to itself.")
795- }
796- else throw("Strict value is not equal to itself.")
797- }
798- }
700+ }
799701 }
800702
801703
849751 let txId58 = toBase58String(i.transactionId)
850752 let pmtAssetId = value(pmt.assetId)
851753 let pmtAmt = pmt.amount
852- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
853- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
854- if ((check == check))
855- then if ((1000000000 > pmtAmt))
856- then throw("Min pmt 10 LP")
857- else if (if (if ((0 > slippage))
858- then true
859- else (0 > exchResult))
860- then true
861- else (0 > outAmount))
862- then throw("Wrong params")
863- else if ((lpId != toBase58String(pmtAssetId)))
864- then throw("Wrong LP")
865- else {
866- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
867- let estimAmAmt = r._1
868- let estimPrAmt = r._2
869- let amBalance = getAccBalance(amId)
870- let prBalance = getAccBalance(prId)
871- let $t03449034947 = if ((outAssetId == amId))
872- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
873- else if ((outAssetId == prId))
874- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
875- else throw("wrong outAssetId")
876- let amBalanceNow = $t03449034947._1
877- let prBalanceNow = $t03449034947._2
878- let virtSwapInAm = $t03449034947._3
879- let virtSwapOutPr = $t03449034947._4
880- let virtSwapInPr = $t03449034947._5
881- let virtSwapOutAm = $t03449034947._6
882- let totalGet = $t03449034947._7
883- if (if ((0 > virtSwapInAm))
884- then true
885- else (0 > virtSwapInPr))
886- then throw("Wrong calc")
887- else {
888- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
889- let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
890- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
891- if ((D0vsD1 == D0vsD1))
892- then {
893- let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
894- if ((finalRes == finalRes))
895- then {
896- let $t03565235756 = if ((outAssetId == amId))
897- then $Tuple2(toInt(finalRes._2), 0)
898- else $Tuple2(0, toInt(finalRes._2))
899- let outAm = $t03565235756._1
900- let outPr = $t03565235756._2
901- let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
902- let curPr = f1(curPrX18, scale8)
903- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
904- then unit
905- else fromBase58String(outAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
906- if ((state == state))
907- then {
908- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
909- if ((burn == burn))
910- then state
911- else throw("Strict value is not equal to itself.")
912- }
913- else throw("Strict value is not equal to itself.")
914- }
915- else throw("Strict value is not equal to itself.")
916- }
917- else throw("Strict value is not equal to itself.")
918- }
919- }
920- else throw("Strict value is not equal to itself.")
754+ if ((1000000000 > pmtAmt))
755+ then throw("Min pmt 10 LP")
756+ else if (if (if ((0 > slippage))
757+ then true
758+ else (0 > exchResult))
759+ then true
760+ else (0 > outAmount))
761+ then throw("Wrong params")
762+ else if ((lpId != toBase58String(pmtAssetId)))
763+ then throw("Wrong LP")
764+ else {
765+ let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
766+ let estimAmAmt = r._1
767+ let estimPrAmt = r._2
768+ let amBalance = getAccBalance(amId)
769+ let prBalance = getAccBalance(prId)
770+ let $t03041530875 = if ((outAssetId == amId))
771+ then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
772+ else if ((outAssetId == prId))
773+ then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
774+ else throw("wrong outAssetId")
775+ let amBalanceNow = $t03041530875._1
776+ let prBalanceNow = $t03041530875._2
777+ let virtSwapInAm = $t03041530875._3
778+ let virtSwapOutPr = $t03041530875._4
779+ let virtSwapInPr = $t03041530875._5
780+ let virtSwapOutAm = $t03041530875._6
781+ let totalGetRaw = $t03041530875._7
782+ if (if ((0 > virtSwapInAm))
783+ then true
784+ else (0 > virtSwapInPr))
785+ then throw("Wrong calc")
786+ else {
787+ let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
788+ let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
789+ let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
790+ if ((D0vsD1 == D0vsD1))
791+ then {
792+ let totalGet = takeFee(totalGetRaw)._1
793+ let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
794+ if ((finalRes == finalRes))
795+ then {
796+ let $t03162231726 = if ((outAssetId == amId))
797+ then $Tuple2(toInt(finalRes._2), 0)
798+ else $Tuple2(0, toInt(finalRes._2))
799+ let outAm = $t03162231726._1
800+ let outPr = $t03162231726._2
801+ let totalAmount = (outAm + outPr)
802+ let feeAmount = (totalGetRaw - totalGet)
803+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
804+ then unit
805+ else fromBase58String(outAssetId)
806+ let sendFeeToMatcher = if ((feeAmount > 0))
807+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
808+ else nil
809+ let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
810+ let curPr = f1(curPrX18, scale8)
811+ let state = [ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
812+ if ((state == state))
813+ then {
814+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
815+ if ((burn == burn))
816+ then (state ++ sendFeeToMatcher)
817+ else throw("Strict value is not equal to itself.")
818+ }
819+ else throw("Strict value is not equal to itself.")
820+ }
821+ else throw("Strict value is not equal to itself.")
822+ }
823+ else throw("Strict value is not equal to itself.")
824+ }
825+ }
921826 }
922827
923828
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let scale8 = 100000000
55
66 let scale8BigInt = toBigInt(100000000)
77
88 let scale18 = toBigInt(1000000000000000000)
9+
10+let thousand = 1000
911
1012 let zeroBigInt = toBigInt(0)
1113
1214 let oneBigInt = toBigInt(1)
1315
1416 let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
1517
1618 let Amult = "100"
1719
1820 let Dconv = "1"
1921
2022 let SEP = "__"
2123
2224 let EMPTY = ""
2325
2426 let PoolActive = 1
2527
2628 let PoolPutDis = 2
2729
2830 let PoolMatcherDis = 3
2931
3032 let PoolShutdown = 4
3133
3234 let idxPoolAddress = 1
3335
3436 let idxPoolSt = 2
3537
3638 let idxLPAsId = 3
3739
3840 let idxAmAsId = 4
3941
4042 let idxPrAsId = 5
4143
4244 let idxAmtAsDcm = 6
4345
4446 let idxPriceAsDcm = 7
4547
4648 let idxIAmtAsId = 8
4749
4850 let idxIPriceAsId = 9
4951
5052 let idxFactStakCntr = 1
5153
5254 let idxFactSlippCntr = 7
5355
5456 let idxFactGwxRewCntr = 10
5557
56-let delay = "%s__delay"
58+let feePermilleDefault = 0
5759
5860 func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5961
6062
6163 func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6264
6365
6466 func ts (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6567
6668
6769 func abs (val) = if ((zeroBigInt > val))
6870 then -(val)
6971 else val
7072
7173
7274 func fc () = "%s__factoryContract"
7375
7476
7577 func mpk () = "%s__managerPublicKey"
7678
7779
7880 func pmpk () = "%s__pendingManagerPublicKey"
7981
8082
8183 func pl () = "%s%s__price__last"
8284
8385
8486 func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
8587
8688
8789 func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
8890
8991
9092 func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
9193
9294
9395 func aa () = "%s__amountAsset"
9496
9597
9698 func pa () = "%s__priceAsset"
9799
98100
99101 func amp () = "%s__amp"
100102
101103
102104 func ada () = "%s__addonAddr"
103105
104106
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
107+let keyFeePermille = "%s__feePermille"
106108
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
109+let feePermille = valueOrElse(getInteger(this, keyFeePermille), feePermilleDefault)
110110
111111 func fcfg () = "%s__factoryConfig"
112112
113113
114114 func mtpk () = "%s%s__matcher__publicKey"
115115
116116
117117 func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
118118
119119
120120 func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
121121
122122
123123 func aps () = "%s__shutdown"
124124
125125
126126 func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
127+
128+
129+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
127130
128131
129132 func toe (orV,sendrV,matchV) = throw(((((("Failed: ordValid=" + toString(orV)) + " sndrValid=") + toString(sendrV)) + " mtchrValid=") + toString(matchV)))
130133
131134
132135 func str (val) = match val {
133136 case valStr: String =>
134137 valStr
135138 case _ =>
136139 throw("fail cast to String")
137140 }
138141
139142
140143 func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
141144
142145
143146 func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
144147
145148
146149 let fca = addressFromStringValue(strf(this, fc()))
147150
148151 let A = strf(this, amp())
149152
150153 func igs () = valueOrElse(getBoolean(fca, aps()), false)
151154
152155
153156 func mp () = fromBase58String(strf(fca, mtpk()))
154157
158+
159+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
155160
156161 func gpc () = {
157162 let amtAs = strf(this, aa())
158163 let priceAs = strf(this, pa())
159164 let iPriceAs = intf(fca, mba(priceAs))
160165 let iAmtAs = intf(fca, mba(amtAs))
161166 split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
162167 }
163168
164169
165170 func gfc () = split(strf(fca, fcfg()), SEP)
166171
167172
168173 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
169174
170175
171176 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
172177
173178
174179 func getAccBalance (assetId) = if ((assetId == "WAVES"))
175180 then wavesBalance(this).available
176181 else assetBalance(this, fromBase58String(assetId))
177182
178183
179184 func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
180185
181186
182187 func vad (A1,A2,slippage) = {
183188 let diff = fraction((A1 - A2), scale8BigInt, A2)
184189 let pass = ((slippage - abs(diff)) > zeroBigInt)
185190 if (!(pass))
186191 then throw(("Big slpg: " + toString(diff)))
187192 else $Tuple2(pass, min([A1, A2]))
188193 }
189194
190195
191196 func vd (D1,D0,slpg) = {
192197 let diff = fraction(D0, scale8BigInt, D1)
193198 let fail = (slpg > diff)
194199 if (if (fail)
195200 then true
196201 else (D0 > D1))
197202 then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
198203 else fail
199204 }
200205
201206
202207 func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
203208 let amtAsAmtX18 = t1(amAmt, amAssetDcm)
204209 let prAsAmtX18 = t1(prAmt, prAssetDcm)
205210 cpbi(prAsAmtX18, amtAsAmtX18)
206211 }
207212
208213
209214 func calcPrices (amAmt,prAmt,lpAmt) = {
210215 let cfg = gpc()
211216 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
212217 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
213218 let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
214219 let amAmtX18 = t1(amAmt, amtAsDcm)
215220 let prAmtX18 = t1(prAmt, prAsDcm)
216221 let lpAmtX18 = t1(lpAmt, scale8)
217222 let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
218223 let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
219224 [priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
220225 }
221226
222227
223228 func calculatePrices (amAmt,prAmt,lpAmt) = {
224229 let p = calcPrices(amAmt, prAmt, lpAmt)
225230 [f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
226231 }
227232
228233
229234 func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
230235 let cfg = gpc()
231236 let lpId = cfg[idxLPAsId]
232237 let amId = cfg[idxAmAsId]
233238 let prId = cfg[idxPrAsId]
234239 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
235240 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
236241 let sts = cfg[idxPoolSt]
237242 let lpEmiss = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "Wrong LP id").quantity
238243 if ((lpId != pmtAssetId))
239244 then throw("Wrong pmt asset")
240245 else {
241246 let amBalance = getAccBalance(amId)
242247 let amBalanceX18 = t1(amBalance, amDcm)
243248 let prBalance = getAccBalance(prId)
244249 let prBalanceX18 = t1(prBalance, prDcm)
245250 let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
246251 let curPrice = f1(curPriceX18, scale8)
247252 let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
248253 let lpEmissX18 = t1(lpEmiss, scale8)
249254 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
250255 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
251256 let outAmAmt = f1(outAmAmtX18, amDcm)
252257 let outPrAmt = f1(outPrAmtX18, prDcm)
253258 let state = if ((txId58 == ""))
254259 then nil
255260 else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
256261 then unit
257262 else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
258263 then unit
259264 else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
260265 $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
261266 }
262267 }
263268
264269
265270 func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,pmtAmt,pmtId) = {
266271 let cfg = gpc()
267272 let lpId = fromBase58String(cfg[idxLPAsId])
268273 let amIdStr = cfg[idxAmAsId]
269274 let prIdStr = cfg[idxPrAsId]
270275 let inAmIdStr = cfg[idxIAmtAsId]
271276 let inPrIdStr = cfg[idxIPriceAsId]
272277 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
273278 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
274279 let sts = cfg[idxPoolSt]
275280 let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
276281 let amBalance = if (isEval)
277282 then getAccBalance(amIdStr)
278283 else if (if (isOneAsset)
279284 then (pmtId == amIdStr)
280285 else false)
281286 then (getAccBalance(amIdStr) - pmtAmt)
282287 else if (isOneAsset)
283288 then getAccBalance(amIdStr)
284289 else (getAccBalance(amIdStr) - inAmAmt)
285290 let prBalance = if (isEval)
286291 then getAccBalance(prIdStr)
287292 else if (if (isOneAsset)
288293 then (pmtId == prIdStr)
289294 else false)
290295 then (getAccBalance(prIdStr) - pmtAmt)
291296 else if (isOneAsset)
292297 then getAccBalance(prIdStr)
293298 else (getAccBalance(prIdStr) - inPrAmt)
294299 let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
295300 let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
296301 let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
297302 let amBalanceX18 = t1(amBalance, amtDcm)
298303 let prBalanceX18 = t1(prBalance, priceDcm)
299304 let r = if ((lpEm == 0))
300305 then {
301306 let curPriceX18 = zeroBigInt
302307 let slippageX18 = zeroBigInt
303308 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
304309 $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
305310 }
306311 else {
307312 let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
308313 let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
309314 let slippageX18 = t1(slippage, scale8)
310315 if (if ((curPriceX18 != zeroBigInt))
311316 then (slippageRealX18 > slippageX18)
312317 else false)
313318 then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
314319 else {
315320 let lpEmissionX18 = t1(lpEm, scale8)
316321 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
317322 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
318323 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
319324 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
320325 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
321326 let expAmtAssetAmtX18 = expectedAmts._1
322327 let expPriceAssetAmtX18 = expectedAmts._2
323328 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
324329 $Tuple5(f1(lpAmtX18, scale8), f1(expAmtAssetAmtX18, amtDcm), f1(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
325330 }
326331 }
327332 let calcLpAmt = r._1
328333 let calcAmAssetPmt = r._2
329334 let calcPrAssetPmt = r._3
330335 let curPrice = f1(r._4, scale8)
331336 let slippageCalc = f1(r._5, scale8)
332337 if ((0 >= calcLpAmt))
333338 then throw("LP <= 0")
334339 else {
335340 let emitLpAmt = if (!(emitLp))
336341 then 0
337342 else calcLpAmt
338343 let amDiff = (inAmAmt - calcAmAssetPmt)
339344 let prDiff = (inPrAmt - calcPrAssetPmt)
340- let $t01560115946 = if (if (isOneAsset)
345+ let $t01568216027 = if (if (isOneAsset)
341346 then (pmtId == amIdStr)
342347 else false)
343348 then $Tuple2(pmtAmt, 0)
344349 else if (if (isOneAsset)
345350 then (pmtId == prIdStr)
346351 else false)
347352 then $Tuple2(0, pmtAmt)
348353 else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
349- let writeAmAmt = $t01560115946._1
350- let writePrAmt = $t01560115946._2
354+ let writeAmAmt = $t01568216027._1
355+ let writePrAmt = $t01568216027._2
351356 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
352357 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
353358 }
354359 }
355360
356361
357362 func moa (order) = {
358363 let cfg = gpc()
359364 let amtAsId = cfg[idxAmAsId]
360365 let prAsId = cfg[idxPrAsId]
361366 let sts = parseIntValue(cfg[idxPoolSt])
362367 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
363368 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
364369 let accAmtAsBalance = getAccBalance(amtAsId)
365370 let accPrAsBalance = getAccBalance(prAsId)
366371 let curPriceX18 = if ((order.orderType == Buy))
367372 then pcp(amtAsDcm, prAsDcm, (accAmtAsBalance + order.amount), accPrAsBalance)
368373 else pcp(amtAsDcm, prAsDcm, (accAmtAsBalance - order.amount), accPrAsBalance)
369374 let curPrice = f1(curPriceX18, scale8)
370375 if (if (if (igs())
371376 then true
372377 else (sts == PoolMatcherDis))
373378 then true
374379 else (sts == PoolShutdown))
375380 then throw("Admin blocked")
376381 else {
377382 let orAmtAsset = order.assetPair.amountAsset
378383 let orAmtAsStr = if ((orAmtAsset == unit))
379384 then "WAVES"
380385 else toBase58String(value(orAmtAsset))
381386 let orPrAsset = order.assetPair.priceAsset
382387 let orPrAsStr = if ((orPrAsset == unit))
383388 then "WAVES"
384389 else toBase58String(value(orPrAsset))
385390 if (if ((orAmtAsStr != amtAsId))
386391 then true
387392 else (orPrAsStr != prAsId))
388393 then throw("Wr assets")
389394 else {
390395 let orderPrice = order.price
391396 let priceDcm = fraction(scale8, prAsDcm, amtAsDcm)
392397 let castOrderPrice = ts(orderPrice, scale8, priceDcm)
393398 let isOrderPriceValid = if ((order.orderType == Buy))
394399 then (curPrice >= castOrderPrice)
395400 else (castOrderPrice >= curPrice)
396401 true
397402 }
398403 }
399404 }
400405
401406
402407 func cg (i) = if ((size(i.payments) != 1))
403408 then throw("1 pmnt exp")
404409 else {
405410 let pmt = value(i.payments[0])
406411 let pmtAssetId = value(pmt.assetId)
407412 let pmtAmt = pmt.amount
408413 let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
409414 let outAmAmt = r._1
410415 let outPrAmt = r._2
411416 let sts = parseIntValue(r._9)
412417 let state = r._10
413418 if (if (igs())
414419 then true
415420 else (sts == PoolShutdown))
416421 then throw(("Admin blocked: " + toString(sts)))
417422 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
418423 }
419424
420425
421426 func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,pmtAmt,pmtId) = {
422427 let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp, isOneAsset, pmtAmt, pmtId)
423428 let sts = parseIntValue(r._8)
424429 if (if (if (igs())
425430 then true
426431 else (sts == PoolPutDis))
427432 then true
428433 else (sts == PoolShutdown))
429434 then throw(("Blocked:" + toString(sts)))
430435 else r
436+ }
437+
438+
439+func takeFee (amount) = {
440+ let fee = fraction(amount, feePermille, thousand)
441+ $Tuple2((amount - fee), fee)
431442 }
432443
433444
434445 func m () = match getString(mpk()) {
435446 case s: String =>
436447 fromBase58String(s)
437448 case _: Unit =>
438449 unit
439450 case _ =>
440451 throw("Match error")
441452 }
442453
443454
444455 func pm () = match getString(pmpk()) {
445456 case s: String =>
446457 fromBase58String(s)
447458 case _: Unit =>
448459 unit
449460 case _ =>
450461 throw("Match error")
451462 }
452463
453464
454465 let pd = throw("Permission denied")
455466
456467 func mm (i) = match m() {
457468 case pk: ByteVector =>
458469 if ((i.callerPublicKey == pk))
459470 then true
460471 else pd
461472 case _: Unit =>
462473 if ((i.caller == this))
463474 then true
464475 else pd
465476 case _ =>
466477 throw("Match error")
467478 }
468479
469480
470481 @Callable(i)
471482 func constructor (fc) = {
472483 let c = mm(i)
473484 if ((c == c))
474485 then [StringEntry(fc(), fc)]
475486 else throw("Strict value is not equal to itself.")
476487 }
477488
478489
479490
480491 @Callable(i)
481492 func setManager (pendingManagerPublicKey) = {
482493 let c = mm(i)
483494 if ((c == c))
484495 then {
485496 let cm = fromBase58String(pendingManagerPublicKey)
486497 if ((cm == cm))
487498 then [StringEntry(pmpk(), pendingManagerPublicKey)]
488499 else throw("Strict value is not equal to itself.")
489500 }
490501 else throw("Strict value is not equal to itself.")
491502 }
492503
493504
494505
495506 @Callable(i)
496507 func confirmManager () = {
497508 let p = pm()
498509 let hpm = if (isDefined(p))
499510 then true
500511 else throw("No pending manager")
501512 if ((hpm == hpm))
502513 then {
503514 let cpm = if ((i.callerPublicKey == value(p)))
504515 then true
505516 else throw("You are not pending manager")
506517 if ((cpm == cpm))
507518 then [StringEntry(mpk(), toBase58String(value(p))), DeleteEntry(pmpk())]
508519 else throw("Strict value is not equal to itself.")
509520 }
510521 else throw("Strict value is not equal to itself.")
511522 }
512523
513524
514525
515526 @Callable(i)
516527 func put (slip,autoStake) = {
517528 let factCfg = gfc()
518529 let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
519530 let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
520531 if ((0 > slip))
521532 then throw("Wrong slippage")
522533 else if ((size(i.payments) != 2))
523534 then throw("2 pmnts expd")
524535 else {
525536 let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, 0, "")
526537 let emitLpAmt = e._2
527538 let lpAssetId = e._7
528539 let state = e._9
529540 let amDiff = e._10
530541 let prDiff = e._11
531542 let amId = e._12
532543 let prId = e._13
533544 let r = invoke(fca, "emit", [emitLpAmt], nil)
534545 if ((r == r))
535546 then {
536547 let el = match r {
537548 case legacy: Address =>
538549 invoke(legacy, "emit", [emitLpAmt], nil)
539550 case _ =>
540551 unit
541552 }
542553 if ((el == el))
543554 then {
544555 let sa = if ((amDiff > 0))
545556 then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
546557 else nil
547558 if ((sa == sa))
548559 then {
549560 let sp = if ((prDiff > 0))
550561 then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
551562 else nil
552563 if ((sp == sp))
553564 then {
554565 let lpTrnsfr = if (autoStake)
555566 then {
556567 let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
557568 if ((ss == ss))
558569 then nil
559570 else throw("Strict value is not equal to itself.")
560571 }
561572 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
562573 (state ++ lpTrnsfr)
563574 }
564575 else throw("Strict value is not equal to itself.")
565576 }
566577 else throw("Strict value is not equal to itself.")
567578 }
568579 else throw("Strict value is not equal to itself.")
569580 }
570581 else throw("Strict value is not equal to itself.")
571582 }
572583 }
573584
574585
575586
576587 @Callable(i)
577588 func putOneTkn (amAssetPart,prAssetPart,outLp,slippage,autoStake) = {
578589 let cfg = gfc()
579590 let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wr st addr")
580591 let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wr sl addr")
581592 let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wr gwx addr")
582593 let poolCfg = gpc()
583594 let amId = poolCfg[idxAmAsId]
584595 let prId = poolCfg[idxPrAsId]
585596 let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
586597 let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
587598 let addon = valueOrElse(getString(this, ada()), "")
588599 let userAddress = if ((addon == toString(i.caller)))
589600 then i.originCaller
590601 else i.caller
591- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
592- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
593- if ((check == check))
594- then if (if (if (if ((0 >= slippage))
595- then true
596- else (0 >= amAssetPart))
597- then true
598- else (0 >= prAssetPart))
599- then true
600- else (0 >= outLp))
601- then throw("Wrong params")
602- else if ((size(i.payments) != 1))
603- then throw("1 pmnt expd")
604- else {
605- let pmt = value(i.payments[0])
606- let pmtAssetId = toBase58String(value(pmt.assetId))
607- let pmtAmt = pmt.amount
608- if ((10000000 > pmtAmt))
609- then throw("Wrong pmt amt")
610- else {
611- let amBalance = getAccBalance(amId)
612- let prBalance = getAccBalance(prId)
613- let $t02485925435 = if ((pmtAssetId == amId))
614- then if (if ((pmtAmt > amBalance))
602+ if (if (if (if ((0 >= slippage))
603+ then true
604+ else (0 >= amAssetPart))
605+ then true
606+ else (0 >= prAssetPart))
607+ then true
608+ else (0 >= outLp))
609+ then throw("Wrong params")
610+ else if ((size(i.payments) != 1))
611+ then throw("1 pmnt expd")
612+ else {
613+ let pmt = value(i.payments[0])
614+ let pmtAssetId = toBase58String(value(pmt.assetId))
615+ let paymentAmountRaw = pmt.amount
616+ let $t02464424696 = takeFee(paymentAmountRaw)
617+ let pmtAmt = $t02464424696._1
618+ let feeAmount = $t02464424696._2
619+ if ((10000000 > paymentAmountRaw))
620+ then throw("Wrong pmt amt")
621+ else {
622+ let amBalance = getAccBalance(amId)
623+ let prBalance = getAccBalance(prId)
624+ let $t02485625472 = if ((pmtAssetId == amId))
625+ then if (if ((paymentAmountRaw > amBalance))
626+ then true
627+ else (amAssetPart > pmtAmt))
628+ then throw("invalid payment amount")
629+ else $Tuple6((amBalance - paymentAmountRaw), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
630+ else if ((pmtAssetId == prId))
631+ then if (if ((paymentAmountRaw > prBalance))
615632 then true
616- else (amAssetPart > pmtAmt))
633+ else (prAssetPart > pmtAmt))
617634 then throw("invalid payment amount")
618- else $Tuple6((amBalance - pmtAmt), prBalance, (pmtAmt - amAssetPart), prAssetPart, 0, 0)
619- else if ((pmtAssetId == prId))
620- then if (if ((pmtAmt > prBalance))
621- then true
622- else (prAssetPart > pmtAmt))
623- then throw("invalid payment amount")
624- else $Tuple6(amBalance, (prBalance - pmtAmt), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
625- else throw("wrong pmtAssetId")
626- let amBalanceNow = $t02485925435._1
627- let prBalanceNow = $t02485925435._2
628- let virtSwapInAm = $t02485925435._3
629- let virtSwapOutPr = $t02485925435._4
630- let virtSwapInPr = $t02485925435._5
631- let virtSwapOutAm = $t02485925435._6
632- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
633- let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
634- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
635- if ((D0vsD1 == D0vsD1))
636- then {
637- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
638- let estimLP = estPut._2
639- let lpAssetId = estPut._7
640- let state = estPut._9
641- let amDiff = estPut._10
642- let prDiff = estPut._11
643- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
644- let emitLpAmt = toInt(lpCalcRes._2)
645- let e = invoke(fca, "emit", [emitLpAmt], nil)
646- if ((e == e))
647- then {
648- let el = match e {
649- case legacy: Address =>
650- invoke(legacy, "emit", [emitLpAmt], nil)
651- case _ =>
652- unit
653- }
654- if ((el == el))
655- then {
656- let sa = if ((amDiff > 0))
657- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
658- else nil
659- if ((sa == sa))
660- then {
661- let sp = if ((prDiff > 0))
662- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
663- else nil
664- if ((sp == sp))
665- then {
666- let lpTrnsfr = if (autoStake)
667- then {
668- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
669- if ((ss == ss))
670- then nil
671- else throw("Strict value is not equal to itself.")
672- }
673- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
674- (state ++ lpTrnsfr)
675- }
676- else throw("Strict value is not equal to itself.")
677- }
678- else throw("Strict value is not equal to itself.")
679- }
680- else throw("Strict value is not equal to itself.")
681- }
682- else throw("Strict value is not equal to itself.")
683- }
684- else throw("Strict value is not equal to itself.")
685- }
686- }
687- else throw("Strict value is not equal to itself.")
688- }
689-
690-
691-
692-@Callable(i)
693-func putOneTknV2 (outLp,slippage,autoStake) = {
694- let cfg = gfc()
695- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wr st addr")
696- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wr sl addr")
697- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wr gwx addr")
698- let poolCfg = gpc()
699- let amId = poolCfg[idxAmAsId]
700- let prId = poolCfg[idxPrAsId]
701- let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
702- let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
703- let addon = valueOrElse(getString(this, ada()), "")
704- let userAddress = if ((addon == toString(i.caller)))
705- then i.originCaller
706- else i.caller
707- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
708- if ((size(i.payments) != 1))
709- then throw("1 pmnt expd")
710- else {
711- let pmt = value(i.payments[0])
712- let pmtAssetId = toBase58String(value(pmt.assetId))
713- let pmtAmt = pmt.amount
714- if ((10000000 > pmtAmt))
715- then throw("Wrong pmt amt")
716- else {
717- let amBalance = getAccBalance(amId)
718- let prBalance = getAccBalance(prId)
719- let $t02878529173 = if ((pmtAssetId == amId))
720- then if ((pmtAmt > amBalance))
721- then throw("invalid payment amount")
722- else $Tuple2((amBalance - pmtAmt), prBalance)
723- else if ((pmtAssetId == prId))
724- then if ((pmtAmt > prBalance))
725- then throw("invalid payment amount")
726- else $Tuple2(amBalance, (prBalance - pmtAmt))
727- else throw("wrong pmtAssetId")
728- let amBalanceNow = $t02878529173._1
729- let prBalanceNow = $t02878529173._2
730- let $t02917929313 = if ((pmtAssetId == amId))
731- then $Tuple2(amBalanceNow, prBalanceNow)
732- else $Tuple2(prBalanceNow, amBalanceNow)
733- let amBalanceForCalc = $t02917929313._1
734- let prBalanceForCalc = $t02917929313._2
735- let xPrecision = 1
736- let result = {
737- let @ = invoke(gwxCntr, "calcPutXOnly", [toString(pmtAmt), toString(amBalanceForCalc), toString(prBalanceForCalc), "", A, Amult, toString(xPrecision), Dconv], nil)
738- if ($isInstanceOf(@, "(Int, Int)"))
739- then @
740- else throw(($getType(invoke(gwxCntr, "calcPutXOnly", [toString(pmtAmt), toString(amBalanceForCalc), toString(prBalanceForCalc), "", A, Amult, toString(xPrecision), Dconv], nil)) + " couldn't be cast to (Int, Int)"))
635+ else $Tuple6(amBalance, (prBalance - paymentAmountRaw), 0, 0, (pmtAmt - prAssetPart), amAssetPart)
636+ else throw("wrong pmtAssetId")
637+ let amBalanceNow = $t02485625472._1
638+ let prBalanceNow = $t02485625472._2
639+ let virtSwapInAm = $t02485625472._3
640+ let virtSwapOutPr = $t02485625472._4
641+ let virtSwapInPr = $t02485625472._5
642+ let virtSwapOutAm = $t02485625472._6
643+ let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
644+ let D1 = invoke(gwxCntr, "calcD", [toString(toBigInt(((amBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((prBalanceNow + virtSwapInPr) - virtSwapOutPr))), A, Amult, Dconv], nil)
645+ let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
646+ if ((D0vsD1 == D0vsD1))
647+ then {
648+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
649+ let estimLP = estPut._2
650+ let lpAssetId = estPut._7
651+ let state = estPut._9
652+ let amDiff = estPut._10
653+ let prDiff = estPut._11
654+ let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
655+ let emitLpAmt = toInt(lpCalcRes._2)
656+ let e = invoke(fca, "emit", [emitLpAmt], nil)
657+ if ((e == e))
658+ then {
659+ let el = match e {
660+ case legacy: Address =>
661+ invoke(legacy, "emit", [emitLpAmt], nil)
662+ case _ =>
663+ unit
664+ }
665+ if ((el == el))
666+ then {
667+ let sa = if ((amDiff > 0))
668+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
669+ else nil
670+ if ((sa == sa))
671+ then {
672+ let sp = if ((prDiff > 0))
673+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
674+ else nil
675+ if ((sp == sp))
676+ then {
677+ let lpTrnsfr = if (autoStake)
678+ then {
679+ let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
680+ if ((ss == ss))
681+ then nil
682+ else throw("Strict value is not equal to itself.")
683+ }
684+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
685+ let sendFeeToMatcher = if ((feeAmount > 0))
686+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
687+ else nil
688+ ((state ++ lpTrnsfr) ++ sendFeeToMatcher)
689+ }
690+ else throw("Strict value is not equal to itself.")
691+ }
692+ else throw("Strict value is not equal to itself.")
693+ }
694+ else throw("Strict value is not equal to itself.")
695+ }
696+ else throw("Strict value is not equal to itself.")
697+ }
698+ else throw("Strict value is not equal to itself.")
741699 }
742- let $t02982529921 = if ((pmtAssetId == amId))
743- then result
744- else $Tuple2(result._2, result._1)
745- let amAssetPart = $t02982529921._1
746- let prAssetPart = $t02982529921._2
747- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), amAssetPart), AttachedPayment(fromBase58String(prId), prAssetPart), slippage, true, true, pmtAmt, pmtAssetId)
748- let estimLP = estPut._2
749- let lpAssetId = estPut._7
750- let state = estPut._9
751- let amDiff = estPut._10
752- let prDiff = estPut._11
753- let emitLpAmt = if ((outLp > 0))
754- then {
755- let lpCalcRes = vad(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
756- toInt(lpCalcRes._2)
757- }
758- else estimLP
759- let e = invoke(fca, "emit", [emitLpAmt], nil)
760- if ((e == e))
761- then {
762- let el = match e {
763- case legacy: Address =>
764- invoke(legacy, "emit", [emitLpAmt], nil)
765- case _ =>
766- unit
767- }
768- if ((el == el))
769- then {
770- let sa = if ((amDiff > 0))
771- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
772- else nil
773- if ((sa == sa))
774- then {
775- let sp = if ((prDiff > 0))
776- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
777- else nil
778- if ((sp == sp))
779- then {
780- let lpTrnsfr = if (autoStake)
781- then {
782- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
783- if ((ss == ss))
784- then nil
785- else throw("Strict value is not equal to itself.")
786- }
787- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
788- (state ++ lpTrnsfr)
789- }
790- else throw("Strict value is not equal to itself.")
791- }
792- else throw("Strict value is not equal to itself.")
793- }
794- else throw("Strict value is not equal to itself.")
795- }
796- else throw("Strict value is not equal to itself.")
797- }
798- }
700+ }
799701 }
800702
801703
802704
803705 @Callable(i)
804706 func putForFree (maxSlpg) = if ((0 > maxSlpg))
805707 then throw("Wrong slpg")
806708 else if ((size(i.payments) != 2))
807709 then throw("2 pmnts expd")
808710 else {
809711 let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, 0, "")
810712 estPut._9
811713 }
812714
813715
814716
815717 @Callable(i)
816718 func get () = {
817719 let r = cg(i)
818720 let outAmtAmt = r._1
819721 let outPrAmt = r._2
820722 let pmtAmt = r._3
821723 let pmtAssetId = r._4
822724 let state = r._5
823725 let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
824726 if ((b == b))
825727 then state
826728 else throw("Strict value is not equal to itself.")
827729 }
828730
829731
830732
831733 @Callable(i)
832734 func getOneTkn (exchResult,notUsed,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
833735 then throw("1 pmnt expd")
834736 else {
835737 let cfg = gpc()
836738 let lpId = cfg[idxLPAsId]
837739 let amId = cfg[idxAmAsId]
838740 let prId = cfg[idxPrAsId]
839741 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
840742 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
841743 let sts = cfg[idxPoolSt]
842744 let factCfg = gfc()
843745 let gwxCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactGwxRewCntr]), "Wr sl addr")
844746 let pmt = value(i.payments[0])
845747 let addon = valueOrElse(getString(this, ada()), "")
846748 let userAddress = if ((addon == toString(i.caller)))
847749 then i.originCaller
848750 else i.caller
849751 let txId58 = toBase58String(i.transactionId)
850752 let pmtAssetId = value(pmt.assetId)
851753 let pmtAmt = pmt.amount
852- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(ada()), "no addons")), "addon address in not valid")
853- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
854- if ((check == check))
855- then if ((1000000000 > pmtAmt))
856- then throw("Min pmt 10 LP")
857- else if (if (if ((0 > slippage))
858- then true
859- else (0 > exchResult))
860- then true
861- else (0 > outAmount))
862- then throw("Wrong params")
863- else if ((lpId != toBase58String(pmtAssetId)))
864- then throw("Wrong LP")
865- else {
866- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
867- let estimAmAmt = r._1
868- let estimPrAmt = r._2
869- let amBalance = getAccBalance(amId)
870- let prBalance = getAccBalance(prId)
871- let $t03449034947 = if ((outAssetId == amId))
872- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
873- else if ((outAssetId == prId))
874- then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
875- else throw("wrong outAssetId")
876- let amBalanceNow = $t03449034947._1
877- let prBalanceNow = $t03449034947._2
878- let virtSwapInAm = $t03449034947._3
879- let virtSwapOutPr = $t03449034947._4
880- let virtSwapInPr = $t03449034947._5
881- let virtSwapOutAm = $t03449034947._6
882- let totalGet = $t03449034947._7
883- if (if ((0 > virtSwapInAm))
884- then true
885- else (0 > virtSwapInPr))
886- then throw("Wrong calc")
887- else {
888- let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
889- let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
890- let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
891- if ((D0vsD1 == D0vsD1))
892- then {
893- let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
894- if ((finalRes == finalRes))
895- then {
896- let $t03565235756 = if ((outAssetId == amId))
897- then $Tuple2(toInt(finalRes._2), 0)
898- else $Tuple2(0, toInt(finalRes._2))
899- let outAm = $t03565235756._1
900- let outPr = $t03565235756._2
901- let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
902- let curPr = f1(curPrX18, scale8)
903- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
904- then unit
905- else fromBase58String(outAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
906- if ((state == state))
907- then {
908- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
909- if ((burn == burn))
910- then state
911- else throw("Strict value is not equal to itself.")
912- }
913- else throw("Strict value is not equal to itself.")
914- }
915- else throw("Strict value is not equal to itself.")
916- }
917- else throw("Strict value is not equal to itself.")
918- }
919- }
920- else throw("Strict value is not equal to itself.")
754+ if ((1000000000 > pmtAmt))
755+ then throw("Min pmt 10 LP")
756+ else if (if (if ((0 > slippage))
757+ then true
758+ else (0 > exchResult))
759+ then true
760+ else (0 > outAmount))
761+ then throw("Wrong params")
762+ else if ((lpId != toBase58String(pmtAssetId)))
763+ then throw("Wrong LP")
764+ else {
765+ let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
766+ let estimAmAmt = r._1
767+ let estimPrAmt = r._2
768+ let amBalance = getAccBalance(amId)
769+ let prBalance = getAccBalance(prId)
770+ let $t03041530875 = if ((outAssetId == amId))
771+ then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
772+ else if ((outAssetId == prId))
773+ then $Tuple7((amBalance - estimAmAmt), (prBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
774+ else throw("wrong outAssetId")
775+ let amBalanceNow = $t03041530875._1
776+ let prBalanceNow = $t03041530875._2
777+ let virtSwapInAm = $t03041530875._3
778+ let virtSwapOutPr = $t03041530875._4
779+ let virtSwapInPr = $t03041530875._5
780+ let virtSwapOutAm = $t03041530875._6
781+ let totalGetRaw = $t03041530875._7
782+ if (if ((0 > virtSwapInAm))
783+ then true
784+ else (0 > virtSwapInPr))
785+ then throw("Wrong calc")
786+ else {
787+ let D0 = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), A, Amult, Dconv], nil)
788+ let D1 = invoke(gwxCntr, "calcD", [toString(((amBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((prBalanceNow + virtSwapOutPr) - virtSwapInPr)), A, Amult, Dconv], nil)
789+ let D0vsD1 = vd(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
790+ if ((D0vsD1 == D0vsD1))
791+ then {
792+ let totalGet = takeFee(totalGetRaw)._1
793+ let finalRes = vad(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
794+ if ((finalRes == finalRes))
795+ then {
796+ let $t03162231726 = if ((outAssetId == amId))
797+ then $Tuple2(toInt(finalRes._2), 0)
798+ else $Tuple2(0, toInt(finalRes._2))
799+ let outAm = $t03162231726._1
800+ let outPr = $t03162231726._2
801+ let totalAmount = (outAm + outPr)
802+ let feeAmount = (totalGetRaw - totalGet)
803+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
804+ then unit
805+ else fromBase58String(outAssetId)
806+ let sendFeeToMatcher = if ((feeAmount > 0))
807+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
808+ else nil
809+ let curPrX18 = cpbi(t1(prBalance, prDcm), t1(amBalance, amDcm))
810+ let curPr = f1(curPrX18, scale8)
811+ let state = [ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)]
812+ if ((state == state))
813+ then {
814+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
815+ if ((burn == burn))
816+ then (state ++ sendFeeToMatcher)
817+ else throw("Strict value is not equal to itself.")
818+ }
819+ else throw("Strict value is not equal to itself.")
820+ }
821+ else throw("Strict value is not equal to itself.")
822+ }
823+ else throw("Strict value is not equal to itself.")
824+ }
825+ }
921826 }
922827
923828
924829
925830 @Callable(i)
926831 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
927832 let r = cg(i)
928833 let outAmAmt = r._1
929834 let outPrAmt = r._2
930835 let pmtAmt = r._3
931836 let pmtAssetId = r._4
932837 let state = r._5
933838 if ((noLessThenAmtAsset > outAmAmt))
934839 then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
935840 else if ((noLessThenPriceAsset > outPrAmt))
936841 then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
937842 else {
938843 let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
939844 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
940845 then state
941846 else throw("Strict value is not equal to itself.")
942847 }
943848 }
944849
945850
946851
947852 @Callable(i)
948853 func unstakeAndGet (amount) = {
949854 let checkPayments = if ((size(i.payments) != 0))
950855 then throw("No pmnts expd")
951856 else true
952857 if ((checkPayments == checkPayments))
953858 then {
954859 let cfg = gpc()
955860 let factoryCfg = gfc()
956861 let lpAssetId = fromBase58String(cfg[idxLPAsId])
957862 let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
958863 let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
959864 if ((unstakeInv == unstakeInv))
960865 then {
961866 let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
962867 let sts = parseIntValue(r._9)
963868 let state = r._10
964869 let v = if (if (igs())
965870 then true
966871 else (sts == PoolShutdown))
967872 then throw(("Blocked: " + toString(sts)))
968873 else true
969874 if ((v == v))
970875 then {
971876 let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
972877 if ((burnA == burnA))
973878 then state
974879 else throw("Strict value is not equal to itself.")
975880 }
976881 else throw("Strict value is not equal to itself.")
977882 }
978883 else throw("Strict value is not equal to itself.")
979884 }
980885 else throw("Strict value is not equal to itself.")
981886 }
982887
983888
984889
985890 @Callable(i)
986891 func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
987892 then throw("denied")
988893 else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr)], "success")
989894
990895
991896
992897 @Callable(i)
993898 func setS (k,v) = if ((toString(i.caller) != strf(this, ada())))
994899 then pd
995900 else [StringEntry(k, v)]
996901
997902
998903
999904 @Callable(i)
1000905 func setI (k,v) = if ((toString(i.caller) != strf(this, ada())))
1001906 then pd
1002907 else [IntegerEntry(k, v)]
1003908
1004909
1005910
1006911 @Callable(i)
1007912 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1008913
1009914
1010915
1011916 @Callable(i)
1012917 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
1013918
1014919
1015920
1016921 @Callable(i)
1017922 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1018923 let pr = calcPrices(amAmt, prAmt, lpAmt)
1019924 $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1020925 }
1021926
1022927
1023928
1024929 @Callable(i)
1025930 func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1026931
1027932
1028933
1029934 @Callable(i)
1030935 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1031936
1032937
1033938
1034939 @Callable(i)
1035940 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1036941
1037942
1038943
1039944 @Callable(i)
1040945 func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, false, 0, ""))
1041946
1042947
1043948
1044949 @Callable(i)
1045950 func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1046951 let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1047952 $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1048953 }
1049954
1050955
1051956 @Verifier(tx)
1052957 func verify () = {
1053958 let targetPublicKey = match m() {
1054959 case pk: ByteVector =>
1055960 pk
1056961 case _: Unit =>
1057962 tx.senderPublicKey
1058963 case _ =>
1059964 throw("Match error")
1060965 }
1061966 match tx {
1062967 case order: Order =>
1063968 let matcherPub = mp()
1064969 let orderValid = moa(order)
1065970 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1066971 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1067972 if (if (if (orderValid)
1068973 then senderValid
1069974 else false)
1070975 then matcherValid
1071976 else false)
1072977 then true
1073978 else toe(orderValid, senderValid, matcherValid)
1074979 case s: SetScriptTransaction =>
1075980 let newHash = blake2b256(value(s.script))
1076981 let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1077982 let currentHash = scriptHash(this)
1078983 if (if ((allowedHash == newHash))
1079984 then (currentHash != newHash)
1080985 else false)
1081986 then true
1082987 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1083988 case _ =>
1084989 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1085990 }
1086991 }
1087992

github/deemru/w8io/026f985 
110.07 ms