tx · 6ST3R7oAds1sqwyPD7hgcnwuz3VwoQXYE2fdK8tegr8p

3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz:  -0.02400000 Waves

2023.03.24 14:59 [2504060] smart account 3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz > SELF 0.00000000 Waves

{ "type": 13, "id": "6ST3R7oAds1sqwyPD7hgcnwuz3VwoQXYE2fdK8tegr8p", "fee": 2400000, "feeAssetId": null, "timestamp": 1679659199365, "version": 2, "chainId": 84, "sender": "3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz", "senderPublicKey": "D28XoueZWsMfm8Y5pa6C5ZFuYoWgre2Wm8tzJANJgMnq", "proofs": [ "4vC2chHZ1rMgovp4xNh7JrcxP3LjVLDDqiZxvkTW4feWWEc9DAAsJGwezPgkuDxWHr5kzgYgrNMqTZZpewWAo211" ], "script": "base64:BgK+IAgCEgMKAQgSAwoBCBIDCgEIEgASABIDCgEIEgQKAggBEgYKBAIBAgISAwoBCBIDCgEIEgUKAwgIBBIGCgQBGAgYEgQKAhgIEgQKAggIEgQKAggIEgMKAQgSBAoCCAgiBlNDQUxFOCIFTVVMVDMiBU1VTFQ4IgdTQ0FMRTE4IgZNVUxUMTgiA1NFUCIOUE9PTFdFSUdIVE1VTFQiCnplcm9CaWdJbnQiCW9uZUJpZ0ludCIHd3JhcEVyciIDbXNnIgh0aHJvd0VyciIJYXNBbnlMaXN0IgN2YWwiByRtYXRjaDAiCnZhbEFueUx5c3QiBWFzSW50IgZ2YWxJbnQiCGFzU3RyaW5nIgZ2YWxTdHIiDGFzQnl0ZVZlY3RvciIGdmFsQmluIg9nZXRTdHJpbmdPckZhaWwiB2FkZHJlc3MiA2tleSIYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsIgxnZXRJbnRPclplcm8iD2dldEludE9yRGVmYXVsdCIKZGVmYXVsdFZhbCIMZ2V0SW50T3JGYWlsIhlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvIhxnZXRCaWdJbnRGcm9tU3RyaW5nT3JEZWZhdWx0IgFzIgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCIHZnJvbVgxOCIPcmVzdWx0U2NhbGVNdWx0IhFrZXlGYWN0b3J5QWRkcmVzcyIZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdCIYSWR4RmFjdG9yeUNmZ1N0YWtpbmdEYXBwIhlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwIhRJZHhGYWN0b3J5Q2ZnSWRvRGFwcCIVSWR4RmFjdG9yeUNmZ1RlYW1EYXBwIhlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwIhVJZHhGYWN0b3J5Q2ZnUmVzdERhcHAiGUlkeEZhY3RvcnlDZmdTbGlwcGFnZURhcHAiDWtleUZhY3RvcnlDZmciE2tleU1hbmFnZXJQdWJsaWNLZXkiGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5IhZrZXlTdGFibGVQb29sQWRkb25BZGRyIgxrZXlBZGRvbkFkZHIiGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nIgpscEFzc2V0U3RyIhBrZXlGYWN0b3J5THBMaXN0IiZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcyIUa2V5RmFjdG9yeVBvb2xXZWlnaHQiD2NvbnRyYWN0QWRkcmVzcyIKcmVhZExwTGlzdCIHZmFjdG9yeSIUcmVhZEZhY3RvcnlDZmdPckZhaWwiGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbCIKZmFjdG9yeUNmZyIYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsIhdnZXRTdGFraW5nQWRkcmVzc09yRmFpbCIea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50IiFrZXlFbWlzc2lvblJhdGVQZXJCbG9ja01heEN1cnJlbnQiFWtleUVtaXNzaW9uU3RhcnRCbG9jayIba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzIhNrZXlFbWlzc2lvbkVuZEJsb2NrIg9rZXlTdGFrZWRCeVVzZXIiDnVzZXJBZGRyZXNzU3RyIgxscEFzc2V0SWRTdHIiDmtleVN0YWtlZFRvdGFsIhBrZXlDbGFpbWVkQnlVc2VyIhlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkIhtrZXlDbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQiD2tleUNsYWltZWRUb3RhbCIKcmVhZFN0YWtlZCIVa2V5TGFzdFRvdGFsTHBCYWxhbmNlIglscEFzc2V0SWQiFGtleUxhc3RVc2VyTHBCYWxhbmNlIgt1c2VyQWRkcmVzcyIZa2V5VG90YWxMcEJhbGFuY2VJbnRlZ3JhbCIYa2V5VXNlckxwQmFsYW5jZUludGVncmFsIiZrZXlUb3RhbExwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodCIla2V5VXNlckxwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodCISa2V5V3hQZXJMcEludGVncmFsIh9rZXlXeFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0IhBrZXlXeFRvQ2xhaW1Vc2VyIiNrZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodCIKa2V5V3hQZXJMcCINa2V5V3hQZXJMcFgxOCIaa2V5V3hQZXJMcEludGVncmFsVXNlckxhc3QiGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQiBHR5cGUiBnR4SWQ1OCITZm9ybWF0SGlzdG9yeVJlY29yZCIGYW1vdW50IhVPcGVyYXRpb25IaXN0b3J5RW50cnkiBHR4SWQiDmZhY3RvcnlBZGRyZXNzIg9mYWN0b3J5Q29udHJhY3QiEGVtaXNzaW9uQ29udHJhY3QiEGJvb3N0aW5nQ29udHJhY3QiCmJvb3N0Q29lZmYiAUAiFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QiC2tleU5leHRVc2VyIhBnZXRVc2Vyc0xpc3ROYW1lIgtrZXlMaXN0SGVhZCIIbGlzdE5hbWUiC2tleUxpc3RTaXplIgtrZXlMaXN0UHJldiICaWQiC2tleUxpc3ROZXh0Igxjb250YWluc05vZGUiCmhlYWRPclVuaXQiCnByZXZPclVuaXQiCm5leHRPclVuaXQiEWluc2VydE5vZGVBY3Rpb25zIghsaXN0U2l6ZSIJY2hlY2tOb2RlIhFkZWxldGVOb2RlQWN0aW9ucyIbY2FsY1d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0IgxzdGFrZWRCeVVzZXIiJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvIhJ3eFBlckxwSW50ZWdyYWxOZXciGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZIhRyZWZyZXNoUG9vbElOVEVHUkFMUyIOcG9vbEFkZHJlc3NTdHIiDWxwRGVsdGFBbW91bnQiDnN0YWtlZFRvdGFsS0VZIgtzdGFrZWRUb3RhbCISbm9uWmVyb1N0YWtlZFRvdGFsIgpwb29sV2VpZ2h0IhJlbWlzc2lvblN0YXJ0QmxvY2siFHd4RW1pc3Npb25QZXJCbG9ja1gzIhhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMiEnd4UGVyTHBJbnRlZ3JhbEtFWSIfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWSIKd3hQZXJMcEtFWSIcd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodCIPd3hQZXJMcEludGVncmFsIg93eFBlckxwT3JaZXJvWDMiAmRoIgl3eFBlckxwWDMiDnN0YWtlZFRvdGFsTmV3IhVub25aZXJvU3Rha2VkVG90YWxOZXciDHd4UGVyTHBYM05ldyIfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodE5ldyIFZGVidWciEHJlZnJlc2hJTlRFR1JBTFMiDSR0MDE0NzYyMTQ4ODQiEXBvb2xJbnRlZ3JhbFNUQVRFIglwb29sREVCVUciD3N0YWtlZEJ5VXNlcktFWSIQd3hUb0NsYWltVXNlcktFWSIjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkiDXd4VG9DbGFpbVVzZXIiF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0IgZNVUxUMTEiEHd4VG9DbGFpbVVzZXJOZXciGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0TmV3IiN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE5ldyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCIdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQiFXBlcm1pc3Npb25EZW5pZWRFcnJvciIIbXVzdFRoaXMiAWkiC211c3RNYW5hZ2VyIgJwayIMc3Rha2VBY3Rpb25zIgtwb29sQWRkcmVzcyIRcmVmcmVzaFN0YWtlZFZvdGUiDSR0MDE4MTAwMTgyMTciDWludGVncmFsU1RBVEUiC2xpc3RBY3Rpb25zIg51bnN0YWtlQWN0aW9ucyIXbHBBc3NldFJlY2lwaWVudEFkZHJlc3MiFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQiEGF2YWlsYWJsZVRvQ2xhaW0iFXRocm93SWZOb3RoaW5nVG9DbGFpbSIBciIRZmFjdG9yeUFkZHJlc3NTdHIiC2NoZWNrQ2FsbGVyIhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0IgVjaGVrcyIXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIgNwbXQiCXBvb2xBZGRvbiIJY2FsbGVyU3RyIgZyZXN1bHQiEGNsYWltZWRCeVVzZXJLRVkiD2NsYWltZWRUb3RhbEtFWSIZY2xhaW1lZEJ5VXNlck1pblJld2FyZEtFWSIbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZIg1jbGFpbWVkQnlVc2VyIhhjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQiDGNsYWltZWRUb3RhbCINJHQwMjYxNzkyNjI5MSISd3hBbW91bnRCb29zdFRvdGFsIg1taW5SZXdhcmRQYXJ0Ig9ib29zdFJld2FyZFBhcnQiC3RvdGFsUmV3YXJkIgl3eEFzc2V0SWQiCWVtaXRCb29zdCISY2xhaW1lZEJ5VXNlclZhbHVlIh5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQiK2NsYWltZWRCeVVzZXJCb29zdFJld2FyZFBsdXNCb29zdFJld2FyZFBhcnQiIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltIgtjdXJyZW50SXRlciIKbHBBc3NldElkcyIGcmVzQWNjIgRpbmZvIgl1bmNsYWltZWQiB2NsYWltZWQiEXVzZXJWb3RlRmluYWxpemVkIgNyZXMiA2ludiISd3hFbWlzc2lvblBlckJsb2NrIgxwYXNzZWRCbG9ja3MiDnBvb2xXeEVtaXNzaW9uIgx1c2VyV3hSZXdhcmQiDSR0MDMwMzM5MzA0NTEiDmJvb3N0SW52UmVzdWx0Igpib29zdERlYnVnIgp1c2VyT3JVbml0IgckbWF0Y2gxIgRoZWFkIg5uZXh0VXNlck9yVW5pdCIIbmV4dFVzZXIiDSR0MDMzMDcyMzMxODIiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleWUAAWEACAABYgDoBwABYwCAwtcvAAFkABIAAWUJALYCAQCAgJC7utat8A0AAWYCAl9fAAFnBQFjAAFoCQC2AgEAAAABaQkAtgIBAAEBAWoBAWsJALkJAgkAzAgCAg1zdGFraW5nLnJpZGU6CQDMCAIJAKUIAQUEdGhpcwkAzAgCBQFrBQNuaWwCASABAWwBAWsJAAIBCQEBagEFAWsBAW0BAW4EAW8FAW4DCQABAgUBbwIJTGlzdFtBbnldBAFwBQFvBQFwCQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQFxAQFuBAFvBQFuAwkAAQIFAW8CA0ludAQBcgUBbwUBcgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBcwEBbgQBbwUBbgMJAAECBQFvAgZTdHJpbmcEAXQFAW8FAXQJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBAXUBAW4EAW8FAW4DCQABAgUBbwIKQnl0ZVZlY3RvcgQBdgUBbwUBdgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBdwIBeAF5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUBeAUBeQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBeQIPIGlzIG5vdCBkZWZpbmVkAQF6AgF4AXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQF4BQF5CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUBeAIBLgUBeQIPIGlzIG5vdCBkZWZpbmVkAQFBAgF4AXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBeAUBeQAAAQFCAwF4AXkBQwkBC3ZhbHVlT3JFbHNlAgkAmggCBQF4BQF5BQFDAQFEAgF4AXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQF4BQF5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQF5Ag8gaXMgbm90IGRlZmluZWQBAUUCAXgBeQkBBXZhbHVlAQkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFAXgFAXkCATABAUYDAXgBeQFDBAFvCQCdCAIFAXgFAXkDCQABAgUBbwIGU3RyaW5nBAFHBQFvCQEFdmFsdWUBCQCoAwEFAUcDCQABAgUBbwIEVW5pdAUBQwkAAgECC01hdGNoIGVycm9yAQFIAgFJAUoJALwCAwkAtgIBBQFJBQFlCQC2AgEFAUoBAUsCAW4BTAkAoAMBCQC8AgMFAW4JALYCAQUBTAUBZQEBTQACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MBAU4AAholc19fdm90aW5nRW1pc3Npb25Db250cmFjdAABTwABAAFQAAIAAVEAAwABUgAEAAFTAAUAAVQABgABVQAHAQFWAAIRJXNfX2ZhY3RvcnlDb25maWcBAVcAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBWAACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBWQACFyVzX19zdGFibGVQb29sQWRkb25BZGRyAQFaAAINJXNfX2FkZG9uQWRkcgECYWEBAmFiCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmFiCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFmAQJhYwACECVzX19scFRva2Vuc0xpc3QBAmFkAQJhYgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhYgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUBZgECYWUBAmFmCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFAmFmBQNuaWwFAWYBAmFnAQJhaAkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFAmFoCQECYWMAAgAFAWYBAmFpAQJhaAkAtQkCCQEBegIFAmFoCQEBVgAFAWYBAmFqAQJhawkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhawUBUAECYWwBAmFrCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFrBQFTAQJhbQECYWsJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYWsFAU8BAmFuAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhbwACHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAECYXAAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawECYXEAAhglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BAmFyAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQJhcwICYXQCYXUJALkJAgkAzAgCAg4lcyVzJXNfX3N0YWtlZAkAzAgCBQJhdAkAzAgCBQJhdQUDbmlsBQFmAQJhdgECYXUJAKwCAgIXJXMlcyVzX19zdGFrZWRfX3RvdGFsX18FAmF1AQJhdwICYXUCYXQJALkJAgkAzAgCAg8lcyVzJXNfX2NsYWltZWQJAMwIAgUCYXQJAMwIAgUCYXUFA25pbAUBZgECYXgCAmF1AmF0CQC5CQIJAMwIAgIYJXMlcyVzX19jbGFpbWVkTWluUmV3YXJkCQDMCAIFAmF0CQDMCAIFAmF1BQNuaWwFAWYBAmF5AgJhdQJhdAkAuQkCCQDMCAICGiVzJXMlc19fY2xhaW1lZEJvb3N0UmV3YXJkCQDMCAIFAmF0CQDMCAIFAmF1BQNuaWwFAWYBAmF6AQJhdQkAuQkCCQDMCAICFiVzJXMlc19fY2xhaW1lZF9fdG90YWwJAMwIAgUCYXUFA25pbAUBZgECYUEBAXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBeQAAAQJhQgECYUMJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYUMJAMwIAgIFdG90YWwJAMwIAgIDYmFsBQNuaWwFAWYBAmFEAgJhQwJhRQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCBQJhRQkAzAgCAgNiYWwFA25pbAUBZgECYUYBAmFDCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmFDCQDMCAICBXRvdGFsCQDMCAICBmJhbElOVAUDbmlsBQFmAQJhRwICYUMCYUUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYUMJAMwIAgUCYUUJAMwIAgIGYmFsSU5UBQNuaWwFAWYBAmFIAQJhQwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCAgV0b3RhbAkAzAgCAgdsYXN0VXBkBQNuaWwFAWYBAmFJAgJhQwJhRQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCBQJhRQkAzAgCAgdsYXN0VXBkBQNuaWwFAWYBAmFKAQJhQwkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAICBmNvbW1vbgkAzAgCAgVscEludAUDbmlsBQFmAQJhSwECYUMJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJhQwkAzAgCAgZjb21tb24JAMwIAgIGbHBJbnRIBQNuaWwFAWYBAmFMAgJhQwJhRQkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAIFAmFFCQDMCAICBWxwSW50BQNuaWwFAWYBAmFNAgJhQwJhRQkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAIFAmFFCQDMCAICBmxwSW50SAUDbmlsBQFmAQJhTgECYUMJALkJAgkAzAgCAgIlcwkAzAgCBQJhQwkAzAgCAgd3eFBlckxwBQNuaWwFAWYBAmFPAQJhQwkAuQkCCQDMCAICAiVzCQDMCAIFAmFDCQDMCAICCnd4UGVyTHBYMTgFA25pbAUBZgECYVACAmFDAmFFCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUCYUMJAMwIAgUCYUUJAMwIAgIFdUludEwFA25pbAUBZgECYVEDAmFSAmFFAmFTCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCYVIJAMwIAgUCYUUJAMwIAgUCYVMFA25pbAUBZgECYVQEAmFFAmFDAmFSAmFVCQC5CQIJAMwIAgIMJXMlcyVzJWQlZCVkCQDMCAIFAmFFCQDMCAIFAmFDCQDMCAIFAmFSCQDMCAIJAKQDAQUGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQJhVQUDbmlsBQFmAQJhVgUCYVICYUUCYUMCYVUCYVcJAQtTdHJpbmdFbnRyeQIJAQJhUQMFAmFSBQJhRQkA2AQBBQJhVwkBAmFUBAUCYUUFAmFDBQJhUgUCYVUAAmFYCQEBdwIFBHRoaXMJAQFNAAACYVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFYAAJhawkBAmFpAQUCYVkAAmFaCQECYWwBBQJhawACYmEJAQJhagEFAmFrAAJiYgoAAmJjCQD8BwQFAmFaAhVnZXRCb29zdENvZWZmUkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmJjAgNJbnQFAmJjCQACAQkArAICCQADAQUCYmMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAACYmQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkAuQkCCQDMCAICAiVzCQDMCAICFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QFA25pbAUBZgkBAWoBAi5scF9zdGFraW5nX3Bvb2xzIGNvbnRyYWN0IGFkZHJlc3MgaXMgdW5kZWZpbmVkCQEBagECKWludmFsaWQgbHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzAQJiZQECYUMJALkJAgkAzAgCAgQlcyVzCQDMCAIFAmFDCQDMCAICCG5leHRVc2VyBQNuaWwFAWYBAmJmAQJhQwkAuQkCCQDMCAICBXVzZXJzCQDMCAIFAmFDBQNuaWwFAWYBAmJnAQJiaAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJiaAkAzAgCAgRoZWFkBQNuaWwFAWYBAmJpAQJiaAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJiaAkAzAgCAgRzaXplBQNuaWwFAWYBAmJqAgJiaAJiawkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmJoCQDMCAIFAmJrCQDMCAICBHByZXYFA25pbAUBZgECYmwCAmJoAmJrCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUCYmgJAMwIAgUCYmsJAMwIAgIEbmV4dAUDbmlsBQFmAQJibQICYmgCYmsEAmJuCQCdCAIFBHRoaXMJAQJiZwEFAmJoBAJibwkAnQgCBQR0aGlzCQECYmoCBQJiaAUCYmsEAmJwCQCdCAIFBHRoaXMJAQJibAIFAmJoBQJiawMDCQAAAgUCYmsJAQt2YWx1ZU9yRWxzZQIFAmJuAgAGCQECIT0CBQJibwUEdW5pdAYJAQIhPQIFAmJwBQR1bml0AQJicQICYmgCYmsEAmJuCQCdCAIFBHRoaXMJAQJiZwEFAmJoBAJicgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYmkBBQJiaAAABAJicwMJAQEhAQkBAmJtAgUCYmgFAmJrBgkAAgECC05vZGUgZXhpc3RzAwkAAAIFAmJzBQJicwkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiaQEFAmJoCQBkAgUCYnIAAQUDbmlsAwkBAiE9AgUCYm4FBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJsAgUCYmgFAmJrCQEFdmFsdWUBBQJibgkAzAgCCQELU3RyaW5nRW50cnkCCQECYmoCBQJiaAkBBXZhbHVlAQUCYm4FAmJrBQNuaWwFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQECYmcBBQJiaAUCYmsFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECYnQCAmJoAmJrBAJibgkAnQgCBQR0aGlzCQECYmcBBQJiaAQCYnIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJpAQUCYmgAAAQCYm8JAJ0IAgUEdGhpcwkBAmJqAgUCYmgFAmJrBAJicAkAnQgCBQR0aGlzCQECYmwCBQJiaAUCYmsJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJpAQUCYmgJAGUCBQJicgABBQNuaWwDAwkBAiE9AgUCYm8FBHVuaXQJAQIhPQIFAmJwBQR1bml0BwkAzAgCCQELU3RyaW5nRW50cnkCCQECYmwCBQJiaAkBBXZhbHVlAQUCYm8JAQV2YWx1ZQEFAmJwCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiagIFAmJoCQEFdmFsdWUBBQJicAkBBXZhbHVlAQUCYm8JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJqAgUCYmgFAmJrCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJibAIFAmJoBQJiawUDbmlsAwkBAiE9AgUCYnAFBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJnAQUCYmgJAQV2YWx1ZQEFAmJwCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJibAIFAmJoBQJiawkAzAgCCQELRGVsZXRlRW50cnkBCQECYmoCBQJiaAkBBXZhbHVlAQUCYnAFA25pbAMJAQIhPQIFAmJvBQR1bml0CQDMCAIJAQtEZWxldGVFbnRyeQEJAQJiagIFAmJoBQJiawkAzAgCCQELRGVsZXRlRW50cnkBCQECYmwCBQJiaAkBBXZhbHVlAQUCYm8FA25pbAMJAAACBQJiawkBC3ZhbHVlT3JFbHNlAgUCYm4CAAkAzAgCCQELRGVsZXRlRW50cnkBCQECYmcBBQJiaAUDbmlsCQACAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmJoAgEuBQJiawECYnUEAmJ2AmJ3AmJ4AmJ5AwMJAAACBQJidwUBaAkAvwICBQJidgUBaAcFAWgDCQAAAgUCYnYFAWgFAmJ4AwMJAL8CAgUCYncFAWgJAL8CAgUCYnYFAWgHCQEFdmFsdWUBCQCoAwEJAQF3AgUEdGhpcwUCYnkJAAIBAi1jYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3Q6IHVuZXhwZWN0ZWQgc3RhdGUBAmJ6AwJhdQJiQQJiQgQCYkMJAQJhdgEFAmF1BAJiRAkAtgIBCQECYUEBBQJiQwQCYkUDCQAAAgUCYkQFAWgFAWkFAmJEBAJiRgkBEUBleHRyTmF0aXZlKDEwNTApAgUCYVkJAQJhZQEFAmJBBAJiRwkBAUQCBQJhWgkBAmFwAAQCYkgJAGgCCQEBRAIFAmFaCQECYW4ABQFiBAJiSQkAawMFAmJIBQJiRgkAaAIFAWcFAmJiBAJiSgkBAmFKAQUCYXUEAmJLCQECYUsBBQJhdQQCYkwJAQJhTgEFAmF1BAJiTQkBAUIDBQR0aGlzBQJiSwUCYkcEAmJOCQEBRQIFBHRoaXMFAmJKBAJiTwAABAJiUAkAlgMBCQDMCAIJAGUCBQZoZWlnaHQFAmJNCQDMCAIAAAUDbmlsBAJiUQMJAQIhPQIFAmJPAAAJALYCAQUCYk8JALwCAwkAtgIBBQJiSQkAtgIBBQFjBQJiRQQCYlIJALcCAgUCYkQJALYCAQUCYkIEAmJTAwkAAAIFAmJSBQFoBQFpBQJiUgQCYngJALcCAgUCYk4JALkCAgUCYlEJALYCAQUCYlAEAmJUCQC6AgIJALYCAQUCYkkFAmJTBAJiVQUGaGVpZ2h0BAJiVgkAuQkCCQDMCAIJAKYDAQUCYngJAMwIAgkApAMBBQJiUAkAzAgCCQCmAwEFAmJRCQDMCAIJAKYDAQUCYkQJAMwIAgkApAMBBQJiSQkAzAgCCQCkAwEFAmJICQDMCAIJAKQDAQUCYkYFA25pbAICOjoJAJUKAwUCYngJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYkoJAKYDAQUCYngJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJLBQJiVQkAzAgCCQELU3RyaW5nRW50cnkCBQJiTAkApgMBBQJiVAUDbmlsBQJiVgECYlcEAmF1AmF0AmJBAmJCBAJiWAkBAmJ6AwUCYXUFAmJBBQJiQgQCYngIBQJiWAJfMQQCYlkIBQJiWAJfMgQCYloIBQJiWAJfMwQCY2EJAQJhcwIFAmF0BQJhdQQCYnYJAQJhQQEFAmNhBAJjYgkBAmFMAgUCYXUFAmF0BAJjYwkBAmFNAgUCYXUFAmF0BAJieQkBAmFQAgUCYXUFAmF0BAJjZAkBAUUCBQR0aGlzBQJjYgQCYncJAQFBAgUEdGhpcwUCY2MEAmNlCQECYnUECQC2AgEFAmJ2CQC2AgEFAmJ3BQJieAUCYnkEAmNmCQBoAgUBYwUBYgQCY2cJAJgDAQkAzAgCCQC3AgIFAmNkCQC8AgMJALgCAgUCYngFAmNlCQC2AgEFAmJ2CQC2AgEFAmNmCQDMCAIFAWgFA25pbAQCY2gFAmJ4BAJjaQUGaGVpZ2h0BAJiVgkAuQkCCQDMCAIJAKYDAQUCY2QJAMwIAgkApgMBBQJjZQkAzAgCCQCkAwEFAmJ2CQDMCAIFAmJaCQDMCAIJAKQDAQUGaGVpZ2h0BQNuaWwCAjo6CQCVCgMFAmNnCQDOCAIFAmJZCQDMCAIJAQtTdHJpbmdFbnRyeQIFAmNiCQCmAwEFAmNnCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjYwUCY2kJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYnkJAKYDAQUCY2gFA25pbAUCYlYBAmNqAAQBbwkAoggBCQEBVwADCQABAgUBbwIGU3RyaW5nBAFHBQFvCQDZBAEFAUcDCQABAgUBbwIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJjawAEAW8JAKIIAQkBAVgAAwkAAQIFAW8CBlN0cmluZwQBRwUBbwkA2QQBBQFHAwkAAQIFAW8CBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACY2wJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAECY20BAmNuAwkAAAIIBQJjbgZjYWxsZXIFBHRoaXMGBQJjbAECY28BAmNuBAFvCQECY2oAAwkAAQIFAW8CCkJ5dGVWZWN0b3IEAmNwBQFvAwkAAAIIBQJjbg9jYWxsZXJQdWJsaWNLZXkFAmNwBgUCY2wDCQABAgUBbwIEVW5pdAMJAAACCAUCY24GY2FsbGVyBQR0aGlzBgUCY2wJAAIBAgtNYXRjaCBlcnJvcgECY3EFAmNuAmFDAmNyAmFFAmFVBAJhdAkApQgBBQJhRQQCYXUJANgEAQUCYUMEAmJBCQClCAEFAmNyBAJjYQkBAmFzAgUCYXQFAmF1BAJiQwkBAmF2AQUCYXUEAmJ2CQECYUEBBQJjYQQCY3MDCQAAAgUCYnYAAAkA/AcEBQJiYQISb25TdGFrZWRWb3RlVXBkYXRlCQDMCAIFAmF1CQDMCAIFAmF0CQDMCAIGBQNuaWwFA25pbAUEdW5pdAMJAAACBQJjcwUCY3MEAmJECQECYUEBBQJiQwQCY3QJAQJiVwQFAmF1BQJhdAUCYkEFAmFVBAJjZwgFAmN0Al8xBAJjdQgFAmN0Al8yBAJiVggFAmN0Al8zBAJiaAkBAmJmAQUCYXUEAmN2AwkBAmJtAgUCYmgFAmF0BQNuaWwJAQJicQIFAmJoBQJhdAkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNhCQBkAgUCYnYFAmFVCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJiQwkAZAIFAmJEBQJhVQkAzAgCCQECYVYFAgVzdGFrZQUCYXQFAmF1BQJhVQgFAmNuDXRyYW5zYWN0aW9uSWQFA25pbAUCY3UFAmN2CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjdwYCY24CYUMCY3ICYUUCY3gCYVUEAmF0CQClCAEFAmFFBAJhdQkA2AQBBQJhQwQCYkEJAKUIAQUCY3IEAmNhCQECYXMCBQJhdAUCYXUEAmJDCQECYXYBBQJhdQQCYnYJAQJhQQEFAmNhBAJiRAkBAmFBAQUCYkMEAmN1CAkBAmJXBAUCYXUFAmF0BQJiQQkBAS0BBQJhVQJfMgQCYmgJAQJiZgEFAmF1BAJjdgMDCQECYm0CBQJiaAUCYXQJAAACBQJhVQUCYnYHCQECYnQCBQJiaAUCYXQFA25pbAQCY3MDCQAAAgUCYVUFAmJ2CQD8BwQFAmJhAhJvblN0YWtlZFZvdGVVcGRhdGUJAMwIAgUCYXUJAMwIAgUCYXQJAMwIAgcFA25pbAUDbmlsBQR1bml0AwkAAAIFAmNzBQJjcwQCY3kJAQFFAgUEdGhpcwkBAmF4AgUCYXUFAmF0BAJjZwgJAQJiVwQFAmF1BQJhdAUCYkEAAAJfMQQCY3oJALgCAgUCY2cFAmN5BAJjQQYEAmNCAwkAvwICBQJjegUBaAkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUCYXUJAMwIAgUCYXQJAMwIAgUCY0EFA25pbAUDbmlsBQR1bml0AwkAAAIFAmNCBQJjQgMJAGYCBQJhVQUCYnYJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICDnBhc3NlZCBhbW91bnQ9CQCkAwEFAmFVAhsgaXMgZ3JlYXRlciB0aGFuIGF2YWlsYWJsZT0JAKQDAQUCYnYCDC4gbHBBc3NldElkPQUCYXUCEi4gc3Rha2VkQnlVc2VyS0VZPQUCY2EJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjYQkAZQIFAmJ2BQJhVQkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYkMJAGUCBQJiRAUCYVUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCY3gFAmFVBQJhQwkAzAgCCQECYVYFAgd1bnN0YWtlBQJhdAUCYXUFAmFVCAUCY24NdHJhbnNhY3Rpb25JZAUDbmlsBQJjdQUCY3YJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4RAmNuAQtjb25zdHJ1Y3RvcgECY0MEAmNECQECY28BBQJjbgMJAAACBQJjRAUCY0QJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU0ABQJjQwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuAQ1jb25zdHJ1Y3RvclYyAQJjRQQCY0YJAMwIAgkBAmNvAQUCY24JAMwIAgMJAQIhPQIJAKYIAQUCY0UFBHVuaXQGAihpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjb250cmFjdCBhZGRyZXNzBQNuaWwDCQAAAgUCY0YFAmNGCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFOAAUCY0UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjbgEKc2V0TWFuYWdlcgECY0cEAmNECQECY28BBQJjbgMJAAACBQJjRAUCY0QEAmNICQDZBAEFAmNHAwkAAAIFAmNIBQJjSAkAzAgCCQELU3RyaW5nRW50cnkCCQEBWAAFAmNHBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY24BDmNvbmZpcm1NYW5hZ2VyAAQCY0kJAQJjawAEAmNKAwkBCWlzRGVmaW5lZAEFAmNJBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJjSgUCY0oEAmNLAwkAAAIIBQJjbg9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmNJBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJjSwUCY0sJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVcACQDYBAEJAQV2YWx1ZQEFAmNJCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFYAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuAQVzdGFrZQADCQECIT0CCQCQAwEIBQJjbghwYXltZW50cwABCQACAQI0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQCY0wJAJEDAggFAmNuCHBheW1lbnRzAAAEAmFDCQEFdmFsdWUBCAUCY0wHYXNzZXRJZAQCYXUJANgEAQUCYUMEAmFVCAUCY0wGYW1vdW50BAJiQQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFZCQECYWEBBQJhdQkArAICAhV1bnN1cHBvcnRlZCBscCBhc3NldCAFAmF1BAJjcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYkEEAmFFAwkAAAIIBQJjbgZjYWxsZXIFAmNyCAUCY24Mb3JpZ2luQ2FsbGVyCAUCY24GY2FsbGVyCQECY3EFBQJjbgUCYUMFAmNyBQJhRQUCYVUCY24BCHN0YWtlRm9yAQJhdAMJAQIhPQIJAJADAQgFAmNuCHBheW1lbnRzAAEJAAIBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAJjTAkAkQMCCAUCY24IcGF5bWVudHMAAAQCYUMJAQV2YWx1ZQEIBQJjTAdhc3NldElkBAJhdQkA2AQBBQJhQwQCYVUIBQJjTAZhbW91bnQEAmJBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVkJAQJhYQEFAmF1CQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYXUEAmNyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiQQQCYUUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQJhdAkBAWoBAhRpbnZhbGlkIHVzZXIgYWRkcmVzcwkBAmNxBQUCY24FAmFDBQJjcgUCYUUFAmFVAmNuAQd1bnN0YWtlAgJhdQJhVQQCYUMJANkEAQUCYXUEAmJBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVkJAQJhYQEFAmF1CQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYXUEAmNyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiQQQCY00JAQt2YWx1ZU9yRWxzZQIJAJ0IAgUCY3IJAQFaAAUCYkEEAmNOCQClCAEIBQJjbgZjYWxsZXIEAmFFAwMJAAACBQJjTgUCYkEGCQAAAgUCY04FAmNNCAUCY24Mb3JpZ2luQ2FsbGVyCAUCY24GY2FsbGVyBAJjeAgFAmNuBmNhbGxlcgkBAmN3BgUCY24FAmFDBQJjcgUCYUUFAmN4BQJhVQJjbgEPdW5zdGFrZUlOVEVSTkFMBAJhQwJhVQJhRQJjeAQCYXUJANgEAQUCYUMEAmNyCQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVkJAQJhYQEFAmF1CQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYXUEAmNEAwkAAAIIBQJjbgZjYWxsZXIFAmNyBgUCY2wDCQAAAgUCY0QFAmNECQECY3cGBQJjbgUCYUMFAmNyCQEHQWRkcmVzcwEFAmFFCQEHQWRkcmVzcwEFAmN4BQJhVQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjbgEHY2xhaW1XeAECYXUEAmF0CQClCAEIBQJjbgZjYWxsZXIEAmNBBgQCY08JAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFAmF1CQDMCAIFAmF0CQDMCAIFAmNBBQNuaWwFA25pbAkAlAoCBQNuaWwFAmNPAmNuARFjbGFpbVd4RG9Ob3RUaHJvdwECYXUEAmF0CQClCAEIBQJjbgZjYWxsZXIEAmNBBwQCY08JAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFAmF1CQDMCAIFAmF0CQDMCAIFAmNBBQNuaWwFA25pbAkAlAoCBQNuaWwFAmNPAmNuAQ9jbGFpbVd4SU5URVJOQUwDAmF1AmF0AmNBBAJjRAkBAmNtAQUCY24DCQAAAgUCY0QFAmNEBAJhRQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmF0AiVjbGFpbVd4SU5URVJOQUw6IGludmFsaWQgdXNlciBhZGRyZXNzBAJiQQkBAXoCBQJhWQkBAmFkAQUCYXUEAmNQCQECYXcCBQJhdQUCYXQEAmNRCQECYXoBBQJhdQQCY1IJAQJheAIFAmF1BQJhdAQCY1MJAQJheQIFAmF1BQJhdAQCY1QJAQFFAgUEdGhpcwUCY1AEAmN5CQEBRQIFBHRoaXMFAmNSBAJjVQkBAUUCBQR0aGlzBQJjUwQCY1YJAQFFAgUEdGhpcwUCY1EEAmNXCQECYlcEBQJhdQUCYXQFAmJBAAAEAmNnCAUCY1cCXzEEAmN1CAUCY1cCXzIEAmJWCAUCY1cCXzMEAmN6CQCYAwEJAMwIAgkAuAICBQJjZwUCY3kJAMwIAgUBaAUDbmlsAwkAwAICBQFoBQJjegMFAmNBCQACAQIQbm90aGluZyB0byBjbGFpbQkAlAoCBQNuaWwAAAQCY1gJAJYDAQkAzAgCCQEBcQEJAJEDAgkBAW0BCQD8BwQFAmJhAgxjbGFpbVd4Qm9vc3QJAMwIAgUCYXUJAMwIAgUCYXQFA25pbAUDbmlsAAAJAMwIAgAABQNuaWwEAmNZBQJjegQCY1oJAJkDAQkAzAgCCQC5AgIFAmNZCQC2AgEJAGUCBQJiYgABCQDMCAIJALYCAQUCY1gFA25pbAQCZGEJALcCAgUCY1kFAmNaBAJkYgkBAXUBCQCRAwIJAQFtAQkA/AcEBQJhWgIEZW1pdAkAzAgCCQCgAwEFAmNZBQNuaWwFA25pbAAABAJkYwkBAW0BCQD8BwQFAmFaAgRlbWl0CQDMCAIJAKADAQUCY1oFA25pbAUDbmlsAwkAAAIFAmRjBQJkYwQCZGQJALcCAgkAtwICBQJjVAUCY1kFAmNaBAJkZQkAtwICBQJjeQUCY1kEAmRmCQC3AgIFAmNVBQJjWgQCZGcJALcCAgUCY1YFAmN6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY1AJAKYDAQUCZGQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY1IJAKYDAQUCZGUJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY1MJAKYDAQUCZGYJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY1EJAKYDAQUCZGcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUUJAKADAQUCY1kFAmRiCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFFCQCgAwEFAmNaBQJkYgkAzAgCCQECYVYFAgVjbGFpbQUCYXQFAmF1CQCgAwEFAmN6CAUCY24NdHJhbnNhY3Rpb25JZAUDbmlsCQCgAwEFAmRhCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuARtjbGFpbVd4QnVsa0ludGVybmFsUkVBRE9OTFkEAmRoAmRpAmF0AmRqAwkAAAIFAmRoCQCQAwEFAmRpCQCUCgIFA25pbAUCZGoEAmFDCQCRAwIFAmRpBQJkaAQCZGsJALUJAgoAAmJjCQD8BwQFBHRoaXMCD2NsYWltV3hSRUFET05MWQkAzAgCBQJhQwkAzAgCBQJhdAUDbmlsBQNuaWwDCQABAgUCYmMCBlN0cmluZwUCYmMJAAIBCQCsAgIJAAMBBQJiYwIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBQFmBAJkbAkAkQMCBQJkawADBAJkbQkAkQMCBQJkawAEBAJkbgoAAmJjCQD8BwQFAmJhAhxnZXRVc2VyVm90ZUZpbmFsaXplZFJFQURPTkxZCQDMCAIFAmFDCQDMCAIFAmF0BQNuaWwFA25pbAMJAAECBQJiYwIDSW50BQJiYwkAAgEJAKwCAgkAAwEFAmJjAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmRvCQDNCAIFAmRqCQC5CQIJAMwIAgIGJWQlZCVkCQDMCAIFAmRsCQDMCAIFAmRtCQDMCAIJAKQDAQUCZG4FA25pbAUBZgQCZHAKAAJiYwkA/AcEBQR0aGlzAhtjbGFpbVd4QnVsa0ludGVybmFsUkVBRE9OTFkJAMwIAgkAZAIFAmRoAAEJAMwIAgUCZGkJAMwIAgUCYXQJAMwIAgUCZG8FA25pbAUDbmlsAwkAAQIFAmJjAglMaXN0W0FueV0FAmJjCQACAQkArAICCQADAQUCYmMCHiBjb3VsZG4ndCBiZSBjYXN0IHRvIExpc3RbQW55XQMJAAACBQJkcAUCZHAJAJQKAgUDbmlsBQJkcAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjbgETY2xhaW1XeEJ1bGtSRUFET05MWQICZGkCYXQEAmRvCQD8BwQFBHRoaXMCG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQkAzAgCAAAJAMwIAgUCZGkJAMwIAgUCYXQJAMwIAgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFAmRvAmNuAQ9jbGFpbVd4UkVBRE9OTFkCAmF1AmF0BAJjYQkBAmFzAgUCYXQFAmF1BAJiQwkBAmF2AQUCYXUEAmNQCQECYXcCBQJhdQUCYXQEAmNSCQECYXgCBQJhdQUCYXQEAmJ2CQECYUEBBQJjYQQCYkQJAQJhQQEFAmJDBAJjVAkBAUUCBQR0aGlzBQJjUAQCY3kJAQFFAgUEdGhpcwUCY1IEAmJBCQEBegIFAmFZCQECYWQBBQJhdQQCYkYJARFAZXh0ck5hdGl2ZSgxMDUwKQIFAmFZCQECYWUBBQJiQQQCZHEJAQFEAgUCYVoJAQJhbgAEAmJHCQEBRAIFAmFaCQECYXAABAJkcgMJAGYCBQJiRwUGaGVpZ2h0AAAJAGUCBQZoZWlnaHQFAmJHBAJkcwkAawMJAGgCBQJkcQUCZHIFAmJGBQFnBAJkdAkAawMFAmRzBQJidgUCYkQEAmR1CQECYlcEBQJhdQUCYXQFAmJBAAAEAmNnCAUCZHUCXzEEAmN1CAUCZHUCXzIEAmJWCAUCZHUCXzMEAmN6CQCYAwEJAMwIAgkAuAICBQJjZwUCY3kJAMwIAgUBaAUDbmlsBAJkdgkBAW0BCQD8BwQFAmJhAhRjbGFpbVd4Qm9vc3RSRUFET05MWQkAzAgCBQJhdQkAzAgCBQJhdAUDbmlsBQNuaWwEAmNYCQCWAwEJAMwIAgkBAXEBCQCRAwIFAmR2AAAJAMwIAgAABQNuaWwEAmR3CQEBcwEJAJEDAgUCZHYAAQQCY1kFAmN6BAJjWgkAmQMBCQDMCAIJALkCAgUCY1kJALYCAQkAZQIFAmJiAAEJAMwIAgkAtgIBBQJjWAUDbmlsBAJkYQkAtwICBQJjWQUCY1oJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJXMlcyVkJWQlZCVkJXMJAMwIAgUCYXUJAMwIAgUCYXQJAMwIAgkApgMBBQJkYQkAzAgCCQCmAwEFAmNUCQDMCAIJAKYDAQUCY1kJAMwIAgkApgMBBQJjWgkAzAgCAgRzb29uBQNuaWwFAWYCY24BFHN0YWtlZEJ5VXNlclJFQURPTkxZAgJhdQJhdAQCYnYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmFzAgUCYXQFAmF1AAAJAJQKAgUDbmlsBQJidgJjbgESdXNlcnNMaXN0VHJhdmVyc2FsAQJhQwQCY0QDCQAAAgkA2AQBCAgFAmNuBmNhbGxlcgVieXRlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEBTgACAAYJAQJjbwEFAmNuAwkAAAIFAmNEBQJjRAQCYmgJAQJiZgEFAmFDBAJkeAkAoggBCQECYmUBBQJhQwQCYm4JAKIIAQkBAmJnAQUCYmgEAW8FAmR4AwkAAQIFAW8CBFVuaXQEAmR5BQJibgMJAAECBQJkeQIEVW5pdAkAlAoCBQNuaWwHAwkAAQIFAmR5AgZTdHJpbmcEAmR6BQJkeQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiZQEFAmFDBQJkegUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAW8CBlN0cmluZwQCYUUFAW8EAmN5CQEBRQIFBHRoaXMJAQJheAIFAmFDBQJhRQQCY3IJAQF6AgUCYVkJAQJhZAEFAmFDBAJjZwgJAQJiVwQFAmFDBQJhRQUCY3IAAAJfMQQCY3oJALgCAgUCY2cFAmN5BAJjQQYEAmNCAwkAvwICBQJjegUBaAkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUCYUMJAMwIAgUCYUUJAMwIAgUCY0EFA25pbAUDbmlsBQR1bml0AwkAAAIFAmNCBQJjQgQCZEEJAKIIAQkBAmJsAgUCYmgFAmFFBAJkeQUCZEEDCQABAgUCZHkCBFVuaXQJAJQKAgkAzAgCCQELRGVsZXRlRW50cnkBCQECYmUBBQJhQwUDbmlsBwMJAAECBQJkeQIGU3RyaW5nBAJkQgUCZHkJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYmUBBQJhQwUCZEIFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuAQ5vbk1vZGlmeVdlaWdodAICYXUCYkEDCQECIT0CCAUCY24GY2FsbGVyBQJhWQkAAgECEnBlcm1pc3Npb25zIGRlbmllZAQCZEMJAQJiegMFAmF1BQJiQQAABAJieAgFAmRDAl8xBAJiWQgFAmRDAl8yBAJiWggFAmRDAl8zBQJiWQECZEQBAmRFAAQCZEYEAW8JAQJjagADCQABAgUBbwIKQnl0ZVZlY3RvcgQCY3AFAW8FAmNwAwkAAQIFAW8CBFVuaXQIBQJkRA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCZEQJYm9keUJ5dGVzCQCRAwIIBQJkRAZwcm9vZnMAAAUCZEaUUm90", "height": 2504060, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Ha2VyedYJfJzftgbk1YUW5XuRHJBwvYvitGFNbYHdHH4 Next: EbsRBQWZa8sJRpSdEuAtvhhzAdcEMshah6YSyeDUYVwo Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SCALE8 = 8
5+
6+let MULT3 = 1000
57
68 let MULT8 = 100000000
79
245247
246248 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247249
250+let boostCoeff = {
251+ let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
252+ if ($isInstanceOf(@, "Int"))
253+ then @
254+ else throw(($getType(@) + " couldn't be cast to Int"))
255+ }
256+
248257 let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
249258
250259 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
331340 else stakedTotal
332341 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
333342 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
334- let MULT3 = 1000
335343 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
336- let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
344+ let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * boostCoeff))
337345 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
338346 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
339347 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
357365
358366
359367 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01475014872._1
362- let poolIntegralSTATE = $t01475014872._2
363- let poolDEBUG = $t01475014872._3
364- let MULT3 = 1000
368+ let $t01476214884 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
369+ let wxPerLpIntegralNew = $t01476214884._1
370+ let poolIntegralSTATE = $t01476214884._2
371+ let poolDEBUG = $t01476214884._3
365372 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366373 let stakedByUser = readStaked(stakedByUserKEY)
367374 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
433440 if ((refreshStakedVote == refreshStakedVote))
434441 then {
435442 let stakedTotal = readStaked(stakedTotalKEY)
436- let $t01810718224 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
437- let wxToClaimUserNew = $t01810718224._1
438- let integralSTATE = $t01810718224._2
439- let debug = $t01810718224._3
443+ let $t01810018217 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
444+ let wxToClaimUserNew = $t01810018217._1
445+ let integralSTATE = $t01810018217._2
446+ let debug = $t01810018217._3
440447 let listName = getUsersListName(lpAssetIdStr)
441448 let listActions = if (containsNode(listName, userAddressStr))
442449 then nil
642649 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
643650 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
644651 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
645- let $t02618626298 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
646- let wxToClaimUserNew = $t02618626298._1
647- let integralSTATE = $t02618626298._2
648- let debug = $t02618626298._3
652+ let $t02617926291 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
653+ let wxToClaimUserNew = $t02617926291._1
654+ let integralSTATE = $t02617926291._2
655+ let debug = $t02617926291._3
649656 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
650657 if ((zeroBigInt >= availableToClaim))
651658 then if (throwIfNothingToClaim)
654661 else {
655662 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
656663 let minRewardPart = availableToClaim
657- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
664+ let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
658665 let totalReward = (minRewardPart + boostRewardPart)
659666 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
660667 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
687694 }, SEP)
688695 let unclaimed = info[3]
689696 let claimed = info[4]
690- let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
697+ let userVoteFinalized = {
698+ let @ = invoke(boostingContract, "getUserVoteFinalizedREADONLY", [lpAssetId, userAddressStr], nil)
699+ if ($isInstanceOf(@, "Int"))
700+ then @
701+ else throw(($getType(@) + " couldn't be cast to Int"))
702+ }
703+ let res = (resAcc :+ makeString(["%d%d%d", unclaimed, claimed, toString(userVoteFinalized)], SEP))
691704 let inv = {
692705 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
693706 if ($isInstanceOf(@, "List[Any]"))
728741 else (height - emissionStartBlock)
729742 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
730743 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
731- let $t03010730219 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
732- let wxToClaimUserNew = $t03010730219._1
733- let integralSTATE = $t03010730219._2
734- let debug = $t03010730219._3
744+ let $t03033930451 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
745+ let wxToClaimUserNew = $t03033930451._1
746+ let integralSTATE = $t03033930451._2
747+ let debug = $t03033930451._3
735748 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
736749 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
737750 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
738751 let boostDebug = asString(boostInvResult[1])
739752 let minRewardPart = availableToClaim
740- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
753+ let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
741754 let totalReward = (minRewardPart + boostRewardPart)
742755 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
743756 }
807820 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
808821 then throw("permissions denied")
809822 else {
810- let $t03282532935 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
811- let wxPerLpIntegralNew = $t03282532935._1
812- let poolIntegralSTATE = $t03282532935._2
813- let poolDEBUG = $t03282532935._3
823+ let $t03307233182 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
824+ let wxPerLpIntegralNew = $t03307233182._1
825+ let poolIntegralSTATE = $t03307233182._2
826+ let poolDEBUG = $t03307233182._3
814827 poolIntegralSTATE
815828 }
816829
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SCALE8 = 8
5+
6+let MULT3 = 1000
57
68 let MULT8 = 100000000
79
810 let SCALE18 = 18
911
1012 let MULT18 = toBigInt(1000000000000000000)
1113
1214 let SEP = "__"
1315
1416 let POOLWEIGHTMULT = MULT8
1517
1618 let zeroBigInt = toBigInt(0)
1719
1820 let oneBigInt = toBigInt(1)
1921
2022 func wrapErr (msg) = makeString(["staking.ride:", toString(this), msg], " ")
2123
2224
2325 func throwErr (msg) = throw(wrapErr(msg))
2426
2527
2628 func asAnyList (val) = match val {
2729 case valAnyLyst: List[Any] =>
2830 valAnyLyst
2931 case _ =>
3032 throw("fail to cast into List[Any]")
3133 }
3234
3335
3436 func asInt (val) = match val {
3537 case valInt: Int =>
3638 valInt
3739 case _ =>
3840 throw("fail to cast into Int")
3941 }
4042
4143
4244 func asString (val) = match val {
4345 case valStr: String =>
4446 valStr
4547 case _ =>
4648 throw("fail to cast into Int")
4749 }
4850
4951
5052 func asByteVector (val) = match val {
5153 case valBin: ByteVector =>
5254 valBin
5355 case _ =>
5456 throw("fail to cast into Int")
5557 }
5658
5759
5860 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5961
6062
6163 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
6264
6365
6466 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
6567
6668
6769 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6870
6971
7072 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
7173
7274
7375 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
7476
7577
7678 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7779 case s: String =>
7880 value(parseBigInt(s))
7981 case _: Unit =>
8082 defaultVal
8183 case _ =>
8284 throw("Match error")
8385 }
8486
8587
8688 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8789
8890
8991 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
9092
9193
9294 func keyFactoryAddress () = "%s%s__config__factoryAddress"
9395
9496
9597 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9698
9799
98100 let IdxFactoryCfgStakingDapp = 1
99101
100102 let IdxFactoryCfgBoostingDapp = 2
101103
102104 let IdxFactoryCfgIdoDapp = 3
103105
104106 let IdxFactoryCfgTeamDapp = 4
105107
106108 let IdxFactoryCfgEmissionDapp = 5
107109
108110 let IdxFactoryCfgRestDapp = 6
109111
110112 let IdxFactoryCfgSlippageDapp = 7
111113
112114 func keyFactoryCfg () = "%s__factoryConfig"
113115
114116
115117 func keyManagerPublicKey () = "%s__managerPublicKey"
116118
117119
118120 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
119121
120122
121123 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
122124
123125
124126 func keyAddonAddr () = "%s__addonAddr"
125127
126128
127129 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
128130
129131
130132 func keyFactoryLpList () = "%s__lpTokensList"
131133
132134
133135 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
134136
135137
136138 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
137139
138140
139141 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
140142
141143
142144 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
143145
144146
145147 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
146148
147149
148150 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
149151
150152
151153 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
152154
153155
154156 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
155157
156158
157159 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
158160
159161
160162 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
161163
162164
163165 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
164166
165167
166168 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
167169
168170
169171 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
170172
171173
172174 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
173175
174176
175177 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
176178
177179
178180 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
179181
180182
181183 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
182184
183185
184186 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
185187
186188
187189 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
188190
189191
190192 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
191193
192194
193195 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
194196
195197
196198 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
197199
198200
199201 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
200202
201203
202204 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
203205
204206
205207 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
206208
207209
208210 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
209211
210212
211213 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
212214
213215
214216 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
215217
216218
217219 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
218220
219221
220222 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
221223
222224
223225 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
224226
225227
226228 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
227229
228230
229231 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
230232
231233
232234 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
233235
234236
235237 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
236238
237239
238240 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
239241
240242 let factoryContract = addressFromStringValue(factoryAddress)
241243
242244 let factoryCfg = readFactoryCfgOrFail(factoryContract)
243245
244246 let emissionContract = getEmissionAddressOrFail(factoryCfg)
245247
246248 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247249
250+let boostCoeff = {
251+ let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
252+ if ($isInstanceOf(@, "Int"))
253+ then @
254+ else throw(($getType(@) + " couldn't be cast to Int"))
255+ }
256+
248257 let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
249258
250259 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251260
252261
253262 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
254263
255264
256265 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
257266
258267
259268 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
260269
261270
262271 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
263272
264273
265274 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
266275
267276
268277 func containsNode (listName,id) = {
269278 let headOrUnit = getString(this, keyListHead(listName))
270279 let prevOrUnit = getString(this, keyListPrev(listName, id))
271280 let nextOrUnit = getString(this, keyListNext(listName, id))
272281 if (if ((id == valueOrElse(headOrUnit, "")))
273282 then true
274283 else (prevOrUnit != unit))
275284 then true
276285 else (nextOrUnit != unit)
277286 }
278287
279288
280289 func insertNodeActions (listName,id) = {
281290 let headOrUnit = getString(this, keyListHead(listName))
282291 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
283292 let checkNode = if (!(containsNode(listName, id)))
284293 then true
285294 else throw("Node exists")
286295 if ((checkNode == checkNode))
287296 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
288297 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
289298 else nil)) ++ [StringEntry(keyListHead(listName), id)])
290299 else throw("Strict value is not equal to itself.")
291300 }
292301
293302
294303 func deleteNodeActions (listName,id) = {
295304 let headOrUnit = getString(this, keyListHead(listName))
296305 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
297306 let prevOrUnit = getString(this, keyListPrev(listName, id))
298307 let nextOrUnit = getString(this, keyListNext(listName, id))
299308 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
300309 then (nextOrUnit != unit)
301310 else false)
302311 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
303312 else if ((nextOrUnit != unit))
304313 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
305314 else if ((prevOrUnit != unit))
306315 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
307316 else if ((id == valueOrElse(headOrUnit, "")))
308317 then [DeleteEntry(keyListHead(listName))]
309318 else throw(((("invalid node: " + listName) + ".") + id))))
310319 }
311320
312321
313322 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
314323 then (stakedByUser > zeroBigInt)
315324 else false)
316325 then zeroBigInt
317326 else if ((stakedByUser == zeroBigInt))
318327 then wxPerLpIntegralNew
319328 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
320329 then (stakedByUser > zeroBigInt)
321330 else false)
322331 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
323332 else throw("calcWxPerLpIntegralUserLast: unexpected state")
324333
325334
326335 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
327336 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
328337 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
329338 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
330339 then oneBigInt
331340 else stakedTotal
332341 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
333342 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
334- let MULT3 = 1000
335343 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
336- let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
344+ let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * boostCoeff))
337345 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
338346 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
339347 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
340348 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
341349 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
342350 let wxPerLpOrZeroX3 = 0
343351 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
344352 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
345353 then toBigInt(wxPerLpOrZeroX3)
346354 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
347355 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
348356 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
349357 then oneBigInt
350358 else stakedTotalNew
351359 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
352360 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
353361 let wxPerLpIntegralLastUpdHeightNew = height
354362 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
355363 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
356364 }
357365
358366
359367 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01475014872._1
362- let poolIntegralSTATE = $t01475014872._2
363- let poolDEBUG = $t01475014872._3
364- let MULT3 = 1000
368+ let $t01476214884 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
369+ let wxPerLpIntegralNew = $t01476214884._1
370+ let poolIntegralSTATE = $t01476214884._2
371+ let poolDEBUG = $t01476214884._3
365372 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366373 let stakedByUser = readStaked(stakedByUserKEY)
367374 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
368375 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
369376 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
370377 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
371378 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
372379 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
373380 let MULT11 = (MULT8 * MULT3)
374381 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
375382 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
376383 let wxPerLpIntegralUserLastUpdHeightNew = height
377384 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
378385 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
379386 }
380387
381388
382389 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
383390 case s: String =>
384391 fromBase58String(s)
385392 case _: Unit =>
386393 unit
387394 case _ =>
388395 throw("Match error")
389396 }
390397
391398
392399 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
393400 case s: String =>
394401 fromBase58String(s)
395402 case _: Unit =>
396403 unit
397404 case _ =>
398405 throw("Match error")
399406 }
400407
401408
402409 let permissionDeniedError = throw("Permission denied")
403410
404411 func mustThis (i) = if ((i.caller == this))
405412 then true
406413 else permissionDeniedError
407414
408415
409416 func mustManager (i) = match managerPublicKeyOrUnit() {
410417 case pk: ByteVector =>
411418 if ((i.callerPublicKey == pk))
412419 then true
413420 else permissionDeniedError
414421 case _: Unit =>
415422 if ((i.caller == this))
416423 then true
417424 else permissionDeniedError
418425 case _ =>
419426 throw("Match error")
420427 }
421428
422429
423430 func stakeActions (i,lpAssetId,poolAddress,userAddress,amount) = {
424431 let userAddressStr = toString(userAddress)
425432 let lpAssetIdStr = toBase58String(lpAssetId)
426433 let poolAddressStr = toString(poolAddress)
427434 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
428435 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
429436 let stakedByUser = readStaked(stakedByUserKEY)
430437 let refreshStakedVote = if ((stakedByUser == 0))
431438 then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, true], nil)
432439 else unit
433440 if ((refreshStakedVote == refreshStakedVote))
434441 then {
435442 let stakedTotal = readStaked(stakedTotalKEY)
436- let $t01810718224 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
437- let wxToClaimUserNew = $t01810718224._1
438- let integralSTATE = $t01810718224._2
439- let debug = $t01810718224._3
443+ let $t01810018217 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
444+ let wxToClaimUserNew = $t01810018217._1
445+ let integralSTATE = $t01810018217._2
446+ let debug = $t01810018217._3
440447 let listName = getUsersListName(lpAssetIdStr)
441448 let listActions = if (containsNode(listName, userAddressStr))
442449 then nil
443450 else insertNodeActions(listName, userAddressStr)
444451 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
445452 }
446453 else throw("Strict value is not equal to itself.")
447454 }
448455
449456
450457 func unstakeActions (i,lpAssetId,poolAddress,userAddress,lpAssetRecipientAddress,amount) = {
451458 let userAddressStr = toString(userAddress)
452459 let lpAssetIdStr = toBase58String(lpAssetId)
453460 let poolAddressStr = toString(poolAddress)
454461 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
455462 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
456463 let stakedByUser = readStaked(stakedByUserKEY)
457464 let stakedTotal = readStaked(stakedTotalKEY)
458465 let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
459466 let listName = getUsersListName(lpAssetIdStr)
460467 let listActions = if (if (containsNode(listName, userAddressStr))
461468 then (amount == stakedByUser)
462469 else false)
463470 then deleteNodeActions(listName, userAddressStr)
464471 else nil
465472 let refreshStakedVote = if ((amount == stakedByUser))
466473 then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, false], nil)
467474 else unit
468475 if ((refreshStakedVote == refreshStakedVote))
469476 then {
470477 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
471478 let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
472479 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
473480 let throwIfNothingToClaim = true
474481 let r = if ((availableToClaim > zeroBigInt))
475482 then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
476483 else unit
477484 if ((r == r))
478485 then if ((amount > stakedByUser))
479486 then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
480487 else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
481488 else throw("Strict value is not equal to itself.")
482489 }
483490 else throw("Strict value is not equal to itself.")
484491 }
485492
486493
487494 @Callable(i)
488495 func constructor (factoryAddressStr) = {
489496 let checkCaller = mustManager(i)
490497 if ((checkCaller == checkCaller))
491498 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
492499 else throw("Strict value is not equal to itself.")
493500 }
494501
495502
496503
497504 @Callable(i)
498505 func constructorV2 (votingEmissionContract) = {
499506 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
500507 then true
501508 else "invalid voting emission contract address"]
502509 if ((cheks == cheks))
503510 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
504511 else throw("Strict value is not equal to itself.")
505512 }
506513
507514
508515
509516 @Callable(i)
510517 func setManager (pendingManagerPublicKey) = {
511518 let checkCaller = mustManager(i)
512519 if ((checkCaller == checkCaller))
513520 then {
514521 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
515522 if ((checkManagerPublicKey == checkManagerPublicKey))
516523 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
517524 else throw("Strict value is not equal to itself.")
518525 }
519526 else throw("Strict value is not equal to itself.")
520527 }
521528
522529
523530
524531 @Callable(i)
525532 func confirmManager () = {
526533 let pm = pendingManagerPublicKeyOrUnit()
527534 let hasPM = if (isDefined(pm))
528535 then true
529536 else throw("No pending manager")
530537 if ((hasPM == hasPM))
531538 then {
532539 let checkPM = if ((i.callerPublicKey == value(pm)))
533540 then true
534541 else throw("You are not pending manager")
535542 if ((checkPM == checkPM))
536543 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
537544 else throw("Strict value is not equal to itself.")
538545 }
539546 else throw("Strict value is not equal to itself.")
540547 }
541548
542549
543550
544551 @Callable(i)
545552 func stake () = if ((size(i.payments) != 1))
546553 then throw("invalid payment - exact one payment must be attached")
547554 else {
548555 let pmt = i.payments[0]
549556 let lpAssetId = value(pmt.assetId)
550557 let lpAssetIdStr = toBase58String(lpAssetId)
551558 let amount = pmt.amount
552559 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
553560 let poolAddress = addressFromStringValue(poolAddressStr)
554561 let userAddress = if ((i.caller == poolAddress))
555562 then i.originCaller
556563 else i.caller
557564 stakeActions(i, lpAssetId, poolAddress, userAddress, amount)
558565 }
559566
560567
561568
562569 @Callable(i)
563570 func stakeFor (userAddressStr) = if ((size(i.payments) != 1))
564571 then throw("invalid payment - exact one payment must be attached")
565572 else {
566573 let pmt = i.payments[0]
567574 let lpAssetId = value(pmt.assetId)
568575 let lpAssetIdStr = toBase58String(lpAssetId)
569576 let amount = pmt.amount
570577 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
571578 let poolAddress = addressFromStringValue(poolAddressStr)
572579 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
573580 stakeActions(i, lpAssetId, poolAddress, userAddress, amount)
574581 }
575582
576583
577584
578585 @Callable(i)
579586 func unstake (lpAssetIdStr,amount) = {
580587 let lpAssetId = fromBase58String(lpAssetIdStr)
581588 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
582589 let poolAddress = addressFromStringValue(poolAddressStr)
583590 let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
584591 let callerStr = toString(i.caller)
585592 let userAddress = if (if ((callerStr == poolAddressStr))
586593 then true
587594 else (callerStr == poolAddon))
588595 then i.originCaller
589596 else i.caller
590597 let lpAssetRecipientAddress = i.caller
591598 unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
592599 }
593600
594601
595602
596603 @Callable(i)
597604 func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
598605 let lpAssetIdStr = toBase58String(lpAssetId)
599606 let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)))
600607 let checkCaller = if ((i.caller == poolAddress))
601608 then true
602609 else permissionDeniedError
603610 if ((checkCaller == checkCaller))
604611 then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
605612 else throw("Strict value is not equal to itself.")
606613 }
607614
608615
609616
610617 @Callable(i)
611618 func claimWx (lpAssetIdStr) = {
612619 let userAddressStr = toString(i.caller)
613620 let throwIfNothingToClaim = true
614621 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
615622 $Tuple2(nil, result)
616623 }
617624
618625
619626
620627 @Callable(i)
621628 func claimWxDoNotThrow (lpAssetIdStr) = {
622629 let userAddressStr = toString(i.caller)
623630 let throwIfNothingToClaim = false
624631 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
625632 $Tuple2(nil, result)
626633 }
627634
628635
629636
630637 @Callable(i)
631638 func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
632639 let checkCaller = mustThis(i)
633640 if ((checkCaller == checkCaller))
634641 then {
635642 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
636643 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
637644 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
638645 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
639646 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
640647 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
641648 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
642649 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
643650 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
644651 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
645- let $t02618626298 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
646- let wxToClaimUserNew = $t02618626298._1
647- let integralSTATE = $t02618626298._2
648- let debug = $t02618626298._3
652+ let $t02617926291 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
653+ let wxToClaimUserNew = $t02617926291._1
654+ let integralSTATE = $t02617926291._2
655+ let debug = $t02617926291._3
649656 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
650657 if ((zeroBigInt >= availableToClaim))
651658 then if (throwIfNothingToClaim)
652659 then throw("nothing to claim")
653660 else $Tuple2(nil, 0)
654661 else {
655662 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
656663 let minRewardPart = availableToClaim
657- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
664+ let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
658665 let totalReward = (minRewardPart + boostRewardPart)
659666 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
660667 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
661668 if ((emitBoost == emitBoost))
662669 then {
663670 let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
664671 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
665672 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
666673 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
667674 $Tuple2([StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)], toInt(totalReward))
668675 }
669676 else throw("Strict value is not equal to itself.")
670677 }
671678 }
672679 else throw("Strict value is not equal to itself.")
673680 }
674681
675682
676683
677684 @Callable(i)
678685 func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
679686 then $Tuple2(nil, resAcc)
680687 else {
681688 let lpAssetId = lpAssetIds[currentIter]
682689 let info = split({
683690 let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
684691 if ($isInstanceOf(@, "String"))
685692 then @
686693 else throw(($getType(@) + " couldn't be cast to String"))
687694 }, SEP)
688695 let unclaimed = info[3]
689696 let claimed = info[4]
690- let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
697+ let userVoteFinalized = {
698+ let @ = invoke(boostingContract, "getUserVoteFinalizedREADONLY", [lpAssetId, userAddressStr], nil)
699+ if ($isInstanceOf(@, "Int"))
700+ then @
701+ else throw(($getType(@) + " couldn't be cast to Int"))
702+ }
703+ let res = (resAcc :+ makeString(["%d%d%d", unclaimed, claimed, toString(userVoteFinalized)], SEP))
691704 let inv = {
692705 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
693706 if ($isInstanceOf(@, "List[Any]"))
694707 then @
695708 else throw(($getType(@) + " couldn't be cast to List[Any]"))
696709 }
697710 if ((inv == inv))
698711 then $Tuple2(nil, inv)
699712 else throw("Strict value is not equal to itself.")
700713 }
701714
702715
703716
704717 @Callable(i)
705718 func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
706719 let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
707720 $Tuple2(nil, res)
708721 }
709722
710723
711724
712725 @Callable(i)
713726 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
714727 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
715728 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
716729 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
717730 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
718731 let stakedByUser = readStaked(stakedByUserKEY)
719732 let stakedTotal = readStaked(stakedTotalKEY)
720733 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
721734 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
722735 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
723736 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
724737 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
725738 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
726739 let passedBlocks = if ((emissionStartBlock > height))
727740 then 0
728741 else (height - emissionStartBlock)
729742 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
730743 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
731- let $t03010730219 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
732- let wxToClaimUserNew = $t03010730219._1
733- let integralSTATE = $t03010730219._2
734- let debug = $t03010730219._3
744+ let $t03033930451 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
745+ let wxToClaimUserNew = $t03033930451._1
746+ let integralSTATE = $t03033930451._2
747+ let debug = $t03033930451._3
735748 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
736749 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
737750 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
738751 let boostDebug = asString(boostInvResult[1])
739752 let minRewardPart = availableToClaim
740- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
753+ let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
741754 let totalReward = (minRewardPart + boostRewardPart)
742755 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
743756 }
744757
745758
746759
747760 @Callable(i)
748761 func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
749762 let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
750763 $Tuple2(nil, stakedByUser)
751764 }
752765
753766
754767
755768 @Callable(i)
756769 func usersListTraversal (lpAssetId) = {
757770 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
758771 then true
759772 else mustManager(i)
760773 if ((checkCaller == checkCaller))
761774 then {
762775 let listName = getUsersListName(lpAssetId)
763776 let userOrUnit = getString(keyNextUser(lpAssetId))
764777 let headOrUnit = getString(keyListHead(listName))
765778 match userOrUnit {
766779 case _: Unit =>
767780 match headOrUnit {
768781 case _: Unit =>
769782 $Tuple2(nil, false)
770783 case head: String =>
771784 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
772785 case _ =>
773786 throw("Match error")
774787 }
775788 case userAddress: String =>
776789 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
777790 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
778791 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
779792 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
780793 let throwIfNothingToClaim = true
781794 let r = if ((availableToClaim > zeroBigInt))
782795 then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
783796 else unit
784797 if ((r == r))
785798 then {
786799 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
787800 match nextUserOrUnit {
788801 case _: Unit =>
789802 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
790803 case nextUser: String =>
791804 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
792805 case _ =>
793806 throw("Match error")
794807 }
795808 }
796809 else throw("Strict value is not equal to itself.")
797810 case _ =>
798811 throw("Match error")
799812 }
800813 }
801814 else throw("Strict value is not equal to itself.")
802815 }
803816
804817
805818
806819 @Callable(i)
807820 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
808821 then throw("permissions denied")
809822 else {
810- let $t03282532935 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
811- let wxPerLpIntegralNew = $t03282532935._1
812- let poolIntegralSTATE = $t03282532935._2
813- let poolDEBUG = $t03282532935._3
823+ let $t03307233182 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
824+ let wxPerLpIntegralNew = $t03307233182._1
825+ let poolIntegralSTATE = $t03307233182._2
826+ let poolDEBUG = $t03307233182._3
814827 poolIntegralSTATE
815828 }
816829
817830
818831 @Verifier(tx)
819832 func verify () = {
820833 let targetPublicKey = match managerPublicKeyOrUnit() {
821834 case pk: ByteVector =>
822835 pk
823836 case _: Unit =>
824837 tx.senderPublicKey
825838 case _ =>
826839 throw("Match error")
827840 }
828841 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
829842 }
830843

github/deemru/w8io/026f985 
109.23 ms