tx · 5NjufpnggLyQB99Abxsr37ytDCCWaVprj3WXLYnDbhWg

3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS:  -0.38000000 Waves

2023.05.23 13:53 [2590525] smart account 3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS > SELF 0.00000000 Waves

{ "type": 13, "id": "5NjufpnggLyQB99Abxsr37ytDCCWaVprj3WXLYnDbhWg", "fee": 38000000, "feeAssetId": null, "timestamp": 1684839216799, "version": 2, "chainId": 84, "sender": "3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS", "senderPublicKey": "HP8sssVq1866F7CaPQJwgFrt6fsqhQjKwM84cL1wjD2a", "proofs": [ "27o9tRi2q8xTG61cvNHoN8QjgtMaY6MPHxZk12YcMiiC2Hzb97WuRykWbfizvQgjajdXC8h5G7kQNPsbQ5HpBJ8D" ], "script": "base64:BgKKAQgCEgUKAwgBCBIDCgEIEgUKAwgBCBIDCgEIEgQKAggBEgYKBAEICAESBQoDAQgIEgMKAQgSBgoECAEICBIGCgQIAQgBEg4KDAgICAEEERgYEQEBGBIKCggICAgBBAgBGBIOCgwICAgBBBgYGBgYARgSCgoICAgBAQEBAQESBgoECAgIARIECgIICFgAB1NGX1BPT0wCAlNGAAdXWF9QT09MAgJXWAAPQ0FQX0ZFRV9OT19MT0FOAgljYXBOb0xvYW4ADENBUF9GRUVfTE9BTgIHY2FwTG9hbgAUU1RPUExPU1NfRkVFX05PX0xPQU4CCWNhcE5vTG9hbgANU1RPUExPU1NfTE9BTgIHY2FwTG9hbgAITE9BTl9GRUUCBGxvYW4AC05PX0xPQU5fRkVFAgZub0xvYW4ABk5PX0ZFRQIFbm9GZWUABlNDQUxFOACAwtcvAAdTQ0FMRTEwAIDIr6AlAApGRUVfU0NBTEU2AMCEPQAUa1NGUG9vbEFBc3NldEJhbGFuY2UCD0FfYXNzZXRfYmFsYW5jZQAUa1NGUG9vbEJBc3NldEJhbGFuY2UCD0JfYXNzZXRfYmFsYW5jZQAPa1NGUG9vbEFBc3NldElkAgpBX2Fzc2V0X2lkAA9rU0ZQb29sQkFzc2V0SWQCCkJfYXNzZXRfaWQADmtTRlBvb2xTaGFyZUlkAg5zaGFyZV9hc3NldF9pZAASa1NGUG9vbFNoYXJlU3VwcGx5AhJzaGFyZV9hc3NldF9zdXBwbHkACmtTRlBvb2xGZWUCCmNvbW1pc3Npb24ADWtVc2VyUG9zaXRpb24CDl91c2VyX3Bvc2l0aW9uABFrVXNlckJvcnJvd0Ftb3VudAIcX3VzZXJfcG9zaXRpb25fYm9ycm93X2Ftb3VudAASa1VzZXJCb3Jyb3dBc3NldElkAh5fdXNlcl9wb3NpdGlvbl9ib3Jyb3dfYXNzZXRfaWQAEGtVc2VyUG9zaXRpb25OdW0CFV91c2VyX3Bvc2l0aW9uX251bWJlcgAVa1VzZXJQb3NpdGlvbkludGVyZXN0AhdfdXNlcl9wb3NpdGlvbl9pbnRlcmVzdAAKa1Bvb2xUb3RhbAILX3Bvb2xfdG90YWwADmtQb29sVG90YWxMb2FuAhBfcG9vbF90b3RhbF9sb2FuABFrUG9vbEludGVyZXN0TG9hbgITX3Bvb2xfaW50ZXJlc3RfbG9hbgATa1Bvb2xJbnRlcmVzdE5vTG9hbgIWX3Bvb2xfaW50ZXJlc3Rfbm9fbG9hbgAVa0F4bHlJbkZlZVdpdGhvdXRMb2FuAhZfYXhseV9mZWVfd2l0aG91dF9sb2FuABJrQXhseUluRmVlV2l0aExvYW4CE19heGx5X2ZlZV93aXRoX2xvYW4AEWtBeGx5Tm9Mb2FuQ2FwRmVlAhdfYXhseV9mZWVfY2FwX3dpdGhfbG9hbgATa0F4bHlXaXRoTG9hbkNhcEZlZQIVX2F4bHlfZmVlX2NhcF9ub19sb2FuABZrQXhseVN0b3BMb3NzTm9Mb2FuRmVlAhxfYXhseV9mZWVfc3RvcGxvc3Nfd2l0aF9sb2FuABRrQXhseVN0b3BMb3NzTG9hbkZlZQIaX2F4bHlfZmVlX3N0b3Bsb3NzX25vX2xvYW4ACmtSZXF1ZXN0SWQCC19yZXF1ZXN0X2lkAAxrUmVxdWVzdEl0ZXICDXJlcXVlc3RzX2l0ZXIABWtQb29sAgVwb29sXwAKa1NoYXJlUG9vbAIOX3Bvb2xfc2hhcmVfaWQADmtQb29sQ2FwQ2hhbmdlAhBfcG9vbF9jYXBfY2hhbmdlAA9rVG9rZW5MYXN0UHJpY2UCC19sYXN0X3ByaWNlAA1rVXNlclN0b3BMb3NzAgpfc3RvcF9sb3NzAAlrTW9uZXlCb3gCDmF4bHlfbW9uZXlfYm94AA5rU0ZGYXJtaW5nQWRkcgITc3dvcGZpX2Zhcm1pbmdfYWRkcgAMa0xlbmRTZXJ2aWNlAhFsZW5kX3NlcnZpY2VfYWRkcgAMa1ByaWNlT3JhY2xlAgxwcmljZV9vcmFjbGUAC2tFeENvbnRyYWN0AhFleGNoYW5nZV9jb250cmFjdAAPa1d4U3dhcENvbnRyYWN0AhB3eF9zd2FwX2NvbnRyYWN0AAhtb25leUJveAkBB0FkZHJlc3MBCQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQlrTW9uZXlCb3gCGE5vIGF4bHkgbW9uZXlCb3ggYWRkcmVzcwAKZXhDb250cmFjdAkBB0FkZHJlc3MBCQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQtrRXhDb250cmFjdAIcTm8gZXhjaGFuZ2UgY29udHJhY3QgYWRkcmVzcwAPcHJpY2VPcmFjbGVBZGRyCQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDGtQcmljZU9yYWNsZQIXTm8gcHJpY2Ugb3JhY2xlIGFkZHJlc3MADnd4U3dhcENvbnRyYWN0CQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFD2tXeFN3YXBDb250cmFjdAISTm8gd3ggc3dhcCBhZGRyZXNzAAZTV09QSUQBIDQBE1aOYEbiflupuAFHguexACYSm3bkTkuioHycbe6BAARXWElEASDGUh6BTupu4zzAl7AOXyzyauntnbKG0ZpCeKhgfT4bsQEKaXNTZWxmQ2FsbAEBaQMJAAACCAUBaQZjYWxsZXIFBHRoaXMFBHVuaXQJAAIBAitPbmx5IGNvbnRyYWN0IGl0c2VsZiBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAQ5hY2NvdW50QmFsYW5jZQEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJpZAUHJG1hdGNoMAkA8AcCBQR0aGlzBQJpZAMJAAECBQckbWF0Y2gwAgRVbml0BAV3YXZlcwUHJG1hdGNoMAgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAAIBAgtNYXRjaCBlcnJvcgENZ2V0U0ZQb29sRGF0YQEIcG9vbEFkZHIJAJcKBQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCHBvb2xBZGRyBQ9rU0ZQb29sQUFzc2V0SWQCGUNhbid0IGdldCBwb29sIEEgYXNzZXQgaWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQhwb29sQWRkcgUPa1NGUG9vbEJBc3NldElkAhlDYW4ndCBnZXQgcG9vbCBCIGFzc2V0IGlkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUIcG9vbEFkZHIFFGtTRlBvb2xBQXNzZXRCYWxhbmNlAh5DYW4ndCBnZXQgcG9vbCBBIGFzc2V0IGJhbGFuY2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQhwb29sQWRkcgUUa1NGUG9vbEJBc3NldEJhbGFuY2UCHkNhbid0IGdldCBwb29sIEIgYXNzZXQgYmFsYW5jZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCHBvb2xBZGRyBQ5rU0ZQb29sU2hhcmVJZAIYQ2FuJ3QgZ2V0IHNoYXJlIGFzc2V0IGlkAQ1nZXRXWFBvb2xEYXRhAQhwb29sQWRkcgQDY2ZnCgABQAkA/AcEBQhwb29sQWRkcgIcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQUDbmlsBQNuaWwDCQABAgUBQAIJTGlzdFtBbnldBQFACQACAQkArAICCQADAQUBQAIeIGNvdWxkbid0IGJlIGNhc3QgdG8gTGlzdFtBbnldAwkAAAIFA2NmZwUDY2ZnBANhSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgoAAUAJAJEDAgUDY2ZnAAQDCQABAgUBQAIGU3RyaW5nBQFABQR1bml0AhlDYW4ndCBnZXQgcG9vbCBBIGFzc2V0IGlkBANiSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgoAAUAJAJEDAgUDY2ZnAAUDCQABAgUBQAIGU3RyaW5nBQFABQR1bml0AhlDYW4ndCBnZXQgcG9vbCBCIGFzc2V0IGlkBAdzaGFyZUlkCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQCRAwIFA2NmZwADAwkAAQIFAUACBlN0cmluZwUBQAUEdW5pdAIaQ2FuJ3QgZ2V0IHBvb2wgTFAgYXNzZXQgaWQEBGJhbEEKAAFACQD8BwQFCHBvb2xBZGRyAhxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZCQDMCAIFA2FJZAUDbmlsBQNuaWwDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AwkAAAIFBGJhbEEFBGJhbEEEBGJhbEIKAAFACQD8BwQFCHBvb2xBZGRyAhxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZCQDMCAIFA2JJZAUDbmlsBQNuaWwDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AwkAAAIFBGJhbEIFBGJhbEIJAJcKBQUDYUlkBQNiSWQFBGJhbEEFBGJhbEIFB3NoYXJlSWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC2dldFBvb2xEYXRhAghwb29sQWRkcgR0eXBlAwkAAAIFBHR5cGUFB1NGX1BPT0wJAQ1nZXRTRlBvb2xEYXRhAQUIcG9vbEFkZHIDCQAAAgUEdHlwZQUHV1hfUE9PTAkBDWdldFdYUG9vbERhdGEBBQhwb29sQWRkcgkAAgECD1dyb25nIHBvb2wgdHlwZQEOZ2V0U2hhcmVTdXBwbHkDCHBvb2xBZGRyBHR5cGUHc2hhcmVJZAMJAAACBQR0eXBlBQdTRl9QT09MCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUIcG9vbEFkZHIFEmtTRlBvb2xTaGFyZVN1cHBseQIcQ2FuJ3QgZ2V0IHNoYXJlIGFzc2V0IHN1cHBseQMJAAACBQR0eXBlBQdXWF9QT09MCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEJANkEAQUHc2hhcmVJZAINV3JvbmcgU2hhcmVJZAhxdWFudGl0eQkAAgECD1dyb25nIHBvb2wgdHlwZQERZ2V0UG9vbFRvdGFsU2hhcmUBBHBvb2wJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBQprUG9vbFRvdGFsAAABGWdldFBvb2xUb3RhbFNoYXJlV2l0aExvYW4BBHBvb2wJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBQ5rUG9vbFRvdGFsTG9hbgAAARhnZXROZXdVc2VyUG9zaXRpb25OdW1iZXICBHBvb2wEdXNlcgkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUQa1VzZXJQb3NpdGlvbk51bQAAAAEBCmdldEF4bHlGZWUCBHBvb2wHZmVlVHlwZQMJAAACBQdmZWVUeXBlBQxDQVBfRkVFX0xPQU4JARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUTa0F4bHlXaXRoTG9hbkNhcEZlZQMJAAACBQdmZWVUeXBlBQ9DQVBfRkVFX05PX0xPQU4JARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAURa0F4bHlOb0xvYW5DYXBGZWUDCQAAAgUHZmVlVHlwZQUITE9BTl9GRUUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUSa0F4bHlJbkZlZVdpdGhMb2FuAwkAAAIFB2ZlZVR5cGUFC05PX0xPQU5fRkVFCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIFBHBvb2wFFWtBeGx5SW5GZWVXaXRob3V0TG9hbgkAAgECDldyb25nIGZlZSB0eXBlARBnZXRTRkZhcm1pbmdBZGRyAAkBB0FkZHJlc3MBCQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQ5rU0ZGYXJtaW5nQWRkcgIdQ2FuJ3QgZ2V0IHN3b3BmaSBmYXJtaW5nIGFkZHIBEGdldFdYRmFybWluZ0FkZHIBCHBvb2xBZGRyBAlmQ29udHJhY3QJAQdBZGRyZXNzAQkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUIcG9vbEFkZHICEyVzX19mYWN0b3J5Q29udHJhY3QCIkNhbid0IGdldCBXWCBmYWN0b3J5IGNvbnRyYWN0IGFkZHIECmZhY3Ryb3lDZmcJALUJAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCWZDb250cmFjdAIRJXNfX2ZhY3RvcnlDb25maWcCGENhbid0IGdldCBXWCBmYWN0b3J5IGNmZwICX18JAQdBZGRyZXNzAQkA2QQBCQCRAwIFCmZhY3Ryb3lDZmcAAQEOZ2V0TGVuZFNydkFkZHIACQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDGtMZW5kU2VydmljZQIbQ2FuJ3QgZ2V0IGxlbmQgc2VydmljZSBhZGRyAQxhc3NldElkVG9TdHIBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAJANgEAQUCaWQDCQABAgUHJG1hdGNoMAIEVW5pdAQFd2F2ZXMFByRtYXRjaDACBVdBVkVTCQACAQILTWF0Y2ggZXJyb3IBDmFzc2V0SWRGcm9tU3RyAQdhc3NldElkAwkAAAIFB2Fzc2V0SWQCBVdBVkVTBQR1bml0CQDZBAEFB2Fzc2V0SWQBEGdldEFzc2V0RGVjaW1hbHMBB2Fzc2V0SWQDCQAAAgUHYXNzZXRJZAIFV0FWRVMACAQHJG1hdGNoMAkA7AcBCQDZBAEFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIFQXNzZXQEBWFzc2V0BQckbWF0Y2gwCAUFYXNzZXQIZGVjaW1hbHMJAAIBAhBDYW4ndCBmaW5kIGFzc2V0ARFnZXRBc3NldFByZWNpdGlvbgEHYXNzZXRJZAkAbAYACgAACQEQZ2V0QXNzZXREZWNpbWFscwEFB2Fzc2V0SWQAAAAABQRET1dOAQ5nZXRBc3NldHNQcmljZQEIYXNzZXRJZHMKAQlnZXRQcmljZXMCAWEHYXNzZXRJZAQKYXNzZXRQcmljZQgKAAFACQD8BwQFD3ByaWNlT3JhY2xlQWRkcgIJZ2V0VFdBUDYwCQDMCAIFB2Fzc2V0SWQJAMwIAgcFA25pbAUDbmlsAwkAAQIFAUACCihJbnQsIEludCkFAUAJAAIBCQCsAgIJAAMBBQFAAh8gY291bGRuJ3QgYmUgY2FzdCB0byAoSW50LCBJbnQpAl8yCQDNCAIFAWEFCmFzc2V0UHJpY2UKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCWdldFByaWNlcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIVTGlzdCBzaXplIGV4Y2VlZHMgMTAwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAt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AQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAQ5nZXRDdXJzRW50cmllcwMDYUlkA2JJZAdzaGFyZUlkBAxhc3NldHNQcmljZXMJAQ5nZXRBc3NldHNQcmljZQEJAMwIAgUDYUlkCQDMCAIFA2JJZAUDbmlsBApzaGFyZVByaWNlCQENZ2V0U2hhcmVQcmljZQEJAMwIAgUHc2hhcmVJZAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFA2FJZAUPa1Rva2VuTGFzdFByaWNlCQCRAwIFDGFzc2V0c1ByaWNlcwAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFA2JJZAUPa1Rva2VuTGFzdFByaWNlCQCRAwIFDGFzc2V0c1ByaWNlcwABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB3NoYXJlSWQFD2tUb2tlbkxhc3RQcmljZQkAkQMCBQpzaGFyZVByaWNlAAAFA25pbAEPcmVwbGVuaXNoU3dvcEZpCQRwb29sB2ZlZVR5cGUEcG10QQlwbXRBc3NldEEEcG10QglwbXRBc3NldEIEYmFsQQRiYWxCB3NoYXJlSWQEEnNoYXJlQmFsYW5jZUJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQkA2QQBBQdzaGFyZUlkAwkAAAIFEnNoYXJlQmFsYW5jZUJlZm9yZQUSc2hhcmVCYWxhbmNlQmVmb3JlBAhwb29sQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wEBnJhdGlvQQkAawMFBlNDQUxFOAUEcG10QQUEYmFsQQQGcmF0aW9CCQBrAwUGU0NBTEU4BQRwbXRCBQRiYWxCBAwkdDA5ODU0MTAxNDYDCQBmAgUGcmF0aW9CBQZyYXRpb0EEA3BtdAkAbgQFBGJhbEIFBnJhdGlvQQUGU0NBTEU4BQdDRUlMSU5HCQCWCgQFBHBtdEEFA3BtdAkAZQIFBHBtdEIFA3BtdAUJcG10QXNzZXRCBANwbXQJAG4EBQRiYWxBBQZyYXRpb0IFBlNDQUxFOAUHQ0VJTElORwkAlgoEBQNwbXQFBHBtdEIJAGUCBQRwbXRBBQNwbXQFCXBtdEFzc2V0QQQKcG10QW1vdW50QQgFDCR0MDk4NTQxMDE0NgJfMQQKcG10QW1vdW50QggFDCR0MDk4NTQxMDE0NgJfMgQGY2hhbmdlCAUMJHQwOTg1NDEwMTQ2Al8zBA1jaGFuZ2VBc3NldElkCAUMJHQwOTg1NDEwMTQ2Al80BARpbnYxAwMJAGYCBQpwbXRBbW91bnRBAAAJAGYCBQpwbXRBbW91bnRCAAAHBAhwYXltZW50cwkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUJcG10QXNzZXRBBQpwbXRBbW91bnRBCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEOYXNzZXRJZEZyb21TdHIBBQlwbXRBc3NldEIFCnBtdEFtb3VudEIFA25pbAkA/AcEBQhwb29sQWRkcgIMY2FsbEZ1bmN0aW9uCQDMCAICFnJlcGxlbmlzaFdpdGhUd29Ub2tlbnMJAMwIAgkAzAgCAgVmYWxzZQkAzAgCAgEwBQNuaWwFA25pbAUIcGF5bWVudHMAAAMJAAACBQRpbnYxBQRpbnYxBARpbnYyAwkAZgIFBmNoYW5nZQAABAhwYXltZW50cwkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUNY2hhbmdlQXNzZXRJZAUGY2hhbmdlBQNuaWwEBHZhcnMJAMwIAgIBMAkAzAgCAgVmYWxzZQkAzAgCAgEwBQNuaWwJAPwHBAUIcG9vbEFkZHICDGNhbGxGdW5jdGlvbgkAzAgCAhVyZXBsZW5pc2hXaXRoT25lVG9rZW4JAMwIAgUEdmFycwUDbmlsBQhwYXltZW50cwAAAwkAAAIFBGludjIFBGludjIEEXNoYXJlQmFsYW5jZUFmdGVyCQEOYWNjb3VudEJhbGFuY2UBCQDZBAEFB3NoYXJlSWQEC3RvdGFsU3Rha2VkCQBlAgURc2hhcmVCYWxhbmNlQWZ0ZXIFEnNoYXJlQmFsYW5jZUJlZm9yZQQNYXhseUZlZUFtb3VudAkAawMFC3RvdGFsU3Rha2VkCQEKZ2V0QXhseUZlZQIFBHBvb2wFB2ZlZVR5cGUFCkZFRV9TQ0FMRTYEEXVzZXJTaGFyZUZvclN0YWtlCQBlAgULdG90YWxTdGFrZWQFDWF4bHlGZWVBbW91bnQDCQBnAgAABRF1c2VyU2hhcmVGb3JTdGFrZQkAAgECKGFtb3VudCBvZiBzdGFrZWQgc2hhcmV0b2tlbnMgbXVzdCBiZSA+IDAEBGludjMJAPwHBAkBEGdldFNGRmFybWluZ0FkZHIAAg9sb2NrU2hhcmVUb2tlbnMJAMwIAgUEcG9vbAkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkA2QQBBQdzaGFyZUlkBRF1c2VyU2hhcmVGb3JTdGFrZQUDbmlsAwkAAAIFBGludjMFBGludjMJAJQKAgURdXNlclNoYXJlRm9yU3Rha2UFDWF4bHlGZWVBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC3JlcGxlbmlzaFdYBwRwb29sB2ZlZVR5cGUEcG10QQlwbXRBc3NldEEEcG10QglwbXRBc3NldEIHc2hhcmVJZAQIcG9vbEFkZHIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBA0kdDAxMTU5NzEyNDQ2AwMJAGYCBQRwbXRBAAAJAGYCBQRwbXRCAAAHBApldmFsUHV0SW5BCQC1CQIKAAFACQD8BwQFCHBvb2xBZGRyAiBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQkAzAgCBQRwbXRBBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcCAl9fAwkAAAIFCmV2YWxQdXRJbkEFCmV2YWxQdXRJbkEECmV2YWxQdXRJbkIJALUJAgoAAUAJAPwHBAUIcG9vbEFkZHICH2V2YWx1YXRlUHV0QnlQcmljZUFzc2V0UkVBRE9OTFkJAMwIAgUEcG10QgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAgJfXwMJAAACBQpldmFsUHV0SW5CBQpldmFsUHV0SW5CBAVscEluQQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmV2YWxQdXRJbkEAAQQFbHBJbkIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpldmFsUHV0SW5CAAEDCQBmAgUFbHBJbkIFBWxwSW5BBAZwbXRJbkIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpldmFsUHV0SW5BAAgJAJYKBAUEcG10QQUGcG10SW5CCQBlAgUEcG10QgUGcG10SW5CBQlwbXRBc3NldEIEBnBtdEluQQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmV2YWxQdXRJbkIABwkAlgoEBQZwbXRJbkEFBHBtdEIJAGUCBQRwbXRBBQZwbXRJbkEFCXBtdEFzc2V0QQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAGYCBQRwbXRBAAAJAJYKBAUEcG10QQUEcG10QgUEcG10QQUJcG10QXNzZXRBAwkAZgIFBHBtdEIAAAkAlgoEBQRwbXRBBQRwbXRCBQRwbXRCBQlwbXRBc3NldEIJAAIBAhBwbXRzIG11c3QgYmUgPiAwBApwbXRBbW91bnRBCAUNJHQwMTE1OTcxMjQ0NgJfMQQKcG10QW1vdW50QggFDSR0MDExNTk3MTI0NDYCXzIEBmNoYW5nZQgFDSR0MDExNTk3MTI0NDYCXzMEDWNoYW5nZUFzc2V0SWQIBQ0kdDAxMTU5NzEyNDQ2Al80BBJzaGFyZUJhbGFuY2VCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJANkEAQUHc2hhcmVJZAMJAAACBRJzaGFyZUJhbGFuY2VCZWZvcmUFEnNoYXJlQmFsYW5jZUJlZm9yZQQEaW52MQMDCQBmAgUKcG10QW1vdW50QQAACQBmAgUKcG10QW1vdW50QgAABwQIcGF5bWVudHMJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ5hc3NldElkRnJvbVN0cgEFCXBtdEFzc2V0QQUKcG10QW1vdW50QQkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUJcG10QXNzZXRCBQpwbXRBbW91bnRCBQNuaWwJAPwHBAUIcG9vbEFkZHICA3B1dAkAzAgCAMCEPQkAzAgCBwUDbmlsBQhwYXltZW50cwAAAwkAAAIFBGludjEFBGludjEEBGludjIDCQBmAgUGY2hhbmdlAAAECHBheW1lbnRzCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEOYXNzZXRJZEZyb21TdHIBBQ1jaGFuZ2VBc3NldElkBQZjaGFuZ2UFA25pbAkA/AcEBQhwb29sQWRkcgIJcHV0T25lVGtuCQDMCAIAAAkAzAgCBwUDbmlsBQhwYXltZW50cwAAAwkAAAIFBGludjIFBGludjIEEXNoYXJlQmFsYW5jZUFmdGVyCQEOYWNjb3VudEJhbGFuY2UBCQDZBAEFB3NoYXJlSWQEC3RvdGFsU3Rha2VkCQBlAgURc2hhcmVCYWxhbmNlQWZ0ZXIFEnNoYXJlQmFsYW5jZUJlZm9yZQQNYXhseUZlZUFtb3VudAkAawMFC3RvdGFsU3Rha2VkCQEKZ2V0QXhseUZlZQIFBHBvb2wFB2ZlZVR5cGUFCkZFRV9TQ0FMRTYEEXVzZXJTaGFyZUZvclN0YWtlCQBlAgULdG90YWxTdGFrZWQFDWF4bHlGZWVBbW91bnQDCQBnAgAABRF1c2VyU2hhcmVGb3JTdGFrZQkAAgECKGFtb3VudCBvZiBzdGFrZWQgc2hhcmV0b2tlbnMgbXVzdCBiZSA+IDAEBGludjMJAPwHBAkBEGdldFdYRmFybWluZ0FkZHIBBQhwb29sQWRkcgIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkA2QQBBQdzaGFyZUlkBRF1c2VyU2hhcmVGb3JTdGFrZQUDbmlsAwkAAAIFBGludjMFBGludjMJAJQKAgURdXNlclNoYXJlRm9yU3Rha2UFDWF4bHlGZWVBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD3JlcGxlbmlzaEJ5VHlwZQoEdHlwZQRwb29sB2ZlZVR5cGUEcG10QQNBSWQEcG10QgNCSWQEYmFsQQRiYWxCB3NoYXJlSWQDCQAAAgUEdHlwZQUHU0ZfUE9PTAkBD3JlcGxlbmlzaFN3b3BGaQkFBHBvb2wFB2ZlZVR5cGUFBHBtdEEFA0FJZAUEcG10QgUDQklkBQRiYWxBBQRiYWxCBQdzaGFyZUlkAwkAAAIFBHR5cGUFB1dYX1BPT0wJAQtyZXBsZW5pc2hXWAcFBHBvb2wFB2ZlZVR5cGUFBHBtdEEFA0FJZAUEcG10QgUDQklkBQdzaGFyZUlkCQACAQIPV3JvbmcgcG9vbCB0eXBlARByZXBsZW5pc2hFbnRyaWVzCARwb29sBHVzZXIMc3Rha2VkQW1vdW50DWF4bHlGZWVBbW91bnQGcG9zTnVtB3NoYXJlSWQEdHlwZQh3aXRoTG9hbgQLdG90YWxBbW91bnQJARFnZXRQb29sVG90YWxTaGFyZQEFBHBvb2wED3RvdGFsQW1vdW50TG9hbgkBGWdldFBvb2xUb3RhbFNoYXJlV2l0aExvYW4BBQRwb29sBA0kdDAxNDQ2NDE0NzAyAwUId2l0aExvYW4JAJQKAgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgkAZAIFD3RvdGFsQW1vdW50TG9hbgUMc3Rha2VkQW1vdW50CQCUCgIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUTa1Bvb2xJbnRlcmVzdE5vTG9hbgUPdG90YWxBbW91bnRMb2FuBA9jdXJQb29sSW50ZXJlc3QIBQ0kdDAxNDQ2NDE0NzAyAl8xBBN0b3RhbFN0YWtlZFdpdGhMb2FuCAUNJHQwMTQ0NjQxNDcwMgJfMgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQprUG9vbFRvdGFsCQBkAgULdG90YWxBbW91bnQFDHN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQ5rUG9vbFRvdGFsTG9hbgkAZAIFD3RvdGFsQW1vdW50TG9hbgUMc3Rha2VkQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwkApAMBBQZwb3NOdW0FDWtVc2VyUG9zaXRpb24FDHN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUGcG9zTnVtBRVrVXNlclBvc2l0aW9uSW50ZXJlc3QFD2N1clBvb2xJbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgUQa1VzZXJQb3NpdGlvbk51bQUGcG9zTnVtCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFCG1vbmV5Qm94BQ1heGx5RmVlQW1vdW50CQDZBAEFB3NoYXJlSWQFA25pbAELY2xhaW1GYXJtZWQCBHR5cGUEcG9vbAMJAAACBQR0eXBlBQdTRl9QT09MBAliYWxCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEFBlNXT1BJRAMJAAACBQliYWxCZWZvcmUFCWJhbEJlZm9yZQQDaW52CQD8BwQJARBnZXRTRkZhcm1pbmdBZGRyAAIFY2xhaW0JAMwIAgUEcG9vbAUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYECGJhbEFmdGVyCQEOYWNjb3VudEJhbGFuY2UBBQZTV09QSUQJAJQKAgkAZQIFCGJhbEFmdGVyBQliYWxCZWZvcmUFBlNXT1BJRAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAACBQR0eXBlBQdXWF9QT09MBAliYWxCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEFBFdYSUQDCQAAAgUJYmFsQmVmb3JlBQliYWxCZWZvcmUEA2ludgkA/AcECQEQZ2V0V1hGYXJtaW5nQWRkcgEJAQdBZGRyZXNzAQkA2QQBBQRwb29sAgdjbGFpbVdYCQDMCAIFBHBvb2wFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BAhiYWxBZnRlcgkBDmFjY291bnRCYWxhbmNlAQUEV1hJRAkAlAoCCQBlAgUIYmFsQWZ0ZXIFCWJhbEJlZm9yZQUEV1hJRAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECD1dyb25nIHBvb2wgdHlwZQEOZXhjaGFuZ2VLZWVwZXIKB3RvVG9rZW4JcG10QW1vdW50CHBtdEFzc2V0CWFtb3VudHNJbglhZGRyZXNzZXMPYXNzZXRzVG9SZWNlaXZlC2VzdFJlY2VpdmVkEXNsaXBwYWdlVG9sZXJhbmNlC21pblJlY2VpdmVkB29wdGlvbnMEEnRva2VuQmFsYW5jZUJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUHdG9Ub2tlbgMJAAACBRJ0b2tlbkJhbGFuY2VCZWZvcmUFEnRva2VuQmFsYW5jZUJlZm9yZQQDaW52CQD8BwQFCmV4Q29udHJhY3QCBHN3YXAJAMwIAgUJYW1vdW50c0luCQDMCAIFCWFkZHJlc3NlcwkAzAgCBQ9hc3NldHNUb1JlY2VpdmUJAMwIAgULZXN0UmVjZWl2ZWQJAMwIAgURc2xpcHBhZ2VUb2xlcmFuY2UJAMwIAgULbWluUmVjZWl2ZWQJAMwIAgUHb3B0aW9ucwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhwbXRBc3NldAUJcG10QW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAGUCCQEOYWNjb3VudEJhbGFuY2UBCQEOYXNzZXRJZEZyb21TdHIBBQd0b1Rva2VuBRJ0b2tlbkJhbGFuY2VCZWZvcmUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDmV4Y2hhbmdlUHV6emxlBgd0b1Rva2VuCXBtdEFtb3VudAhwbXRBc3NldAlyb3V0ZXNTdHIMbWluVG9SZWNlaXZlB29wdGlvbnMEEnRva2VuQmFsYW5jZUJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUHdG9Ub2tlbgMJAAACBRJ0b2tlbkJhbGFuY2VCZWZvcmUFEnRva2VuQmFsYW5jZUJlZm9yZQQDaW52CQD8BwQFCmV4Q29udHJhY3QCCnB1enpsZVN3YXAJAMwIAgUJcm91dGVzU3RyCQDMCAIFDG1pblRvUmVjZWl2ZQkAzAgCBQdvcHRpb25zBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCHBtdEFzc2V0BQlwbXRBbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgkAZQIJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFB3RvVG9rZW4FEnRva2VuQmFsYW5jZUJlZm9yZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEOZXhjaGFuZ2VTd29wRmkKB3RvVG9rZW4JcG10QW1vdW50CHBtdEFzc2V0CmV4Y2hhbmdlcnMOZXhjaGFuZ2Vyc1R5cGUFYXJnczEFYXJnczIRcm91dGluZ0Fzc2V0c0tleXMSbWluQW1vdW50VG9SZWNlaXZlB29wdGlvbnMEEnRva2VuQmFsYW5jZUJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUHdG9Ub2tlbgMJAAACBRJ0b2tlbkJhbGFuY2VCZWZvcmUFEnRva2VuQmFsYW5jZUJlZm9yZQQDaW52CQD8BwQFCmV4Q29udHJhY3QCCnN3b3BmaVN3YXAJAMwIAgUKZXhjaGFuZ2VycwkAzAgCBQ5leGNoYW5nZXJzVHlwZQkAzAgCBQVhcmdzMQkAzAgCBQVhcmdzMgkAzAgCBRFyb3V0aW5nQXNzZXRzS2V5cwkAzAgCBRJtaW5BbW91bnRUb1JlY2VpdmUJAMwIAgUHb3B0aW9ucwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhwbXRBc3NldAUJcG10QW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAGUCCQEOYWNjb3VudEJhbGFuY2UBCQEOYXNzZXRJZEZyb21TdHIBBQd0b1Rva2VuBRJ0b2tlbkJhbGFuY2VCZWZvcmUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BCmNhcGl0YWxpemUEBHBvb2wFcFR5cGUHdG9rZW5JZAt0b2tlbkFtb3VudAQIcG9vbEFkZHIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBA0kdDAxNzYwMTE3NjgwCQELZ2V0UG9vbERhdGECBQhwb29sQWRkcgUFcFR5cGUEA0FJZAgFDSR0MDE3NjAxMTc2ODACXzEEA0JJZAgFDSR0MDE3NjAxMTc2ODACXzIEBGJhbEEIBQ0kdDAxNzYwMTE3NjgwAl8zBARiYWxCCAUNJHQwMTc2MDExNzY4MAJfNAQHc2hhcmVJZAgFDSR0MDE3NjAxMTc2ODACXzUEDSR0MDE3NjgzMTc3NjMDCQAAAgUHdG9rZW5JZAUDQUlkCQCUCgIFC3Rva2VuQW1vdW50AAAJAJQKAgAABQt0b2tlbkFtb3VudAQEcG10QQgFDSR0MDE3NjgzMTc3NjMCXzEEBHBtdEIIBQ0kdDAxNzY4MzE3NzYzAl8yBA0kdDAxNzc2NjE3ODcwCQEPcmVwbGVuaXNoQnlUeXBlCgUFcFR5cGUFBHBvb2wFBk5PX0ZFRQUEcG10QQUDQUlkBQRwbXRCBQNCSWQFBGJhbEEFBGJhbEIFB3NoYXJlSWQEDHN0YWtlZEFtb3VudAgFDSR0MDE3NzY2MTc4NzACXzEEAm5mCAUNJHQwMTc3NjYxNzg3MAJfMgQTY3VyUG9vbEludGVyZXN0TG9hbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFEWtQb29sSW50ZXJlc3RMb2FuAAAEFWN1clBvb2xJbnRlcmVzdE5vTG9hbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFE2tQb29sSW50ZXJlc3ROb0xvYW4AAAQQdG90YWxTaGFyZUFtb3VudAkBEWdldFBvb2xUb3RhbFNoYXJlAQUEcG9vbAQYdG90YWxTaGFyZUFtb3VudFdpdGhMb2FuCQEZZ2V0UG9vbFRvdGFsU2hhcmVXaXRoTG9hbgEFBHBvb2wEC2xvYW5QZXJjZW50CQBrAwUYdG90YWxTaGFyZUFtb3VudFdpdGhMb2FuBQZTQ0FMRTgFEHRvdGFsU2hhcmVBbW91bnQECnN0YWtlZExvYW4JAGsDBQxzdGFrZWRBbW91bnQFC2xvYW5QZXJjZW50BQZTQ0FMRTgEDHN0YWtlZE5vTG9hbgkAZQIFDHN0YWtlZEFtb3VudAUKc3Rha2VkTG9hbgQPbmV3SW50ZXJlc3RMb2FuCQBkAgUTY3VyUG9vbEludGVyZXN0TG9hbgkAawMFCnN0YWtlZExvYW4FB1NDQUxFMTAFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgQRbmV3SW50ZXJlc3ROb0xvYW4JAGQCBRVjdXJQb29sSW50ZXJlc3ROb0xvYW4JAGsDBQxzdGFrZWROb0xvYW4FB1NDQUxFMTAJAGUCBRB0b3RhbFNoYXJlQW1vdW50BRh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4EC2F4bHlGZWVMb2FuCQBrAwUKc3Rha2VkTG9hbgkBCmdldEF4bHlGZWUCBQRwb29sBQxDQVBfRkVFX0xPQU4FCkZFRV9TQ0FMRTYEDWF4bHlGZWVOb0xvYW4JAGsDBQxzdGFrZWROb0xvYW4JAQpnZXRBeGx5RmVlAgUEcG9vbAUPQ0FQX0ZFRV9OT19MT0FOBQpGRUVfU0NBTEU2CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAURa1Bvb2xJbnRlcmVzdExvYW4FD25ld0ludGVyZXN0TG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRNrUG9vbEludGVyZXN0Tm9Mb2FuBRFuZXdJbnRlcmVzdE5vTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQprUG9vbFRvdGFsCQBlAgkAZQIJAGQCBRB0b3RhbFNoYXJlQW1vdW50BQxzdGFrZWRBbW91bnQFC2F4bHlGZWVMb2FuBQ1heGx5RmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFDmtQb29sVG90YWxMb2FuCQBlAgkAZAIFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgUKc3Rha2VkTG9hbgULYXhseUZlZUxvYW4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUIbW9uZXlCb3gJAGQCBQtheGx5RmVlTG9hbgUNYXhseUZlZU5vTG9hbgkA2QQBBQdzaGFyZUlkBQNuaWwJAQ5nZXRDdXJzRW50cmllcwMFA0FJZAUDQklkBQdzaGFyZUlkARJleGNoYW5nZURpcmVjdGx5U0YHBHBvb2wIYXNzZXRJZEEIYXNzZXRJZEIEYmFsQQRiYWxCEGFtb3VudFRva2VuVG9HZXQPYXNzZXRUb2tlblRvR2V0BAhwb29sQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wECWZlZVNjYWxlNgDAhD0EA2ZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUIcG9vbEFkZHIFCmtTRlBvb2xGZWUEDGFtbnRHZXROb0ZlZQkAawMFEGFtb3VudFRva2VuVG9HZXQFCWZlZVNjYWxlNgkAZQIFCWZlZVNjYWxlNgUDZmVlBA0kdDAxOTU1ODE5ODQ2AwkAAAIFD2Fzc2V0VG9rZW5Ub0dldAUIYXNzZXRJZEEEC2Ftb3VudFRvUGF5CQBrAwUEYmFsQQUMYW1udEdldE5vRmVlCQBlAgUEYmFsQgUMYW1udEdldE5vRmVlCQCUCgIFC2Ftb3VudFRvUGF5BQhhc3NldElkQgQLYW1vdW50VG9QYXkJAGsDBQRiYWxCBQxhbW50R2V0Tm9GZWUJAGUCBQRiYWxBBQxhbW50R2V0Tm9GZWUJAJQKAgULYW1vdW50VG9QYXkFCGFzc2V0SWRBBAthbW91bnRUb1BheQgFDSR0MDE5NTU4MTk4NDYCXzEECmFzc2V0VG9QYXkIBQ0kdDAxOTU1ODE5ODQ2Al8yCQD8BwQFCHBvb2xBZGRyAgxjYWxsRnVuY3Rpb24JAMwIAgIIZXhjaGFuZ2UJAMwIAgkAzAgCAgExBQNuaWwFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUKYXNzZXRUb1BheQULYW1vdW50VG9QYXkFA25pbAESZXhjaGFuZ2VEaXJlY3RseVdYBwRwb29sCGFzc2V0SWRBCGFzc2V0SWRCBGJhbEEEYmFsQhBhbW91bnRUb2tlblRvR2V0D2Fzc2V0VG9rZW5Ub0dldAQIcG9vbEFkZHIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBAVwckZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUOd3hTd2FwQ29udHJhY3QCDyVzX19wcm90b2NvbEZlZQQEcEZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUOd3hTd2FwQ29udHJhY3QCCyVzX19wb29sRmVlBAhmZWVTY2FsZQkAtgIBAIDC1y8EDSR0MDIwMzI1MjA2MzMDCQAAAgUPYXNzZXRUb2tlblRvR2V0BQhhc3NldElkQQQLYW1vdW50VG9QYXkJAGsDBQRiYWxBBRBhbW91bnRUb2tlblRvR2V0CQBlAgUEYmFsQgUQYW1vdW50VG9rZW5Ub0dldAkAlAoCBQthbW91bnRUb1BheQUIYXNzZXRJZEIEC2Ftb3VudFRvUGF5CQBrAwUEYmFsQgUQYW1vdW50VG9rZW5Ub0dldAkAZQIFBGJhbEEFEGFtb3VudFRva2VuVG9HZXQJAJQKAgULYW1vdW50VG9QYXkFCGFzc2V0SWRBBAthbW91bnRUb1BheQgFDSR0MDIwMzI1MjA2MzMCXzEECmFzc2V0VG9QYXkIBQ0kdDAyMDMyNTIwNjMzAl8yBBJhbW91bnRUb1BheVdpdGhGZWUJAKADAQkAvAIDCQC2AgEFC2Ftb3VudFRvUGF5BQhmZWVTY2FsZQkAuAICBQhmZWVTY2FsZQkAtgIBCQBkAgUFcHJGZWUFBHBGZWUJAPwHBAUOd3hTd2FwQ29udHJhY3QCBHN3YXAJAMwIAgABCQDMCAIFD2Fzc2V0VG9rZW5Ub0dldAkAzAgCCQClCAEFBHRoaXMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUKYXNzZXRUb1BheQUSYW1vdW50VG9QYXlXaXRoRmVlBQNuaWwBEGV4Y2hhbmdlRGlyZWN0bHkIBHR5cGUEcG9vbAhhc3NldElkQQhhc3NldElkQgRiYWxBBGJhbEIQYW1vdW50VG9rZW5Ub0dldA9hc3NldFRva2VuVG9HZXQDCQAAAgUEdHlwZQUHU0ZfUE9PTAkBEmV4Y2hhbmdlRGlyZWN0bHlTRgcFBHBvb2wFCGFzc2V0SWRBBQhhc3NldElkQgUEYmFsQQUEYmFsQgUQYW1vdW50VG9rZW5Ub0dldAUPYXNzZXRUb2tlblRvR2V0CQESZXhjaGFuZ2VEaXJlY3RseVdYBwUEcG9vbAUIYXNzZXRJZEEFCGFzc2V0SWRCBQRiYWxBBQRiYWxCBRBhbW91bnRUb2tlblRvR2V0BQ9hc3NldFRva2VuVG9HZXQBEndpdGhkcmF3QW1vdW50Q2FsYwQEcG9vbA91c2VyQ2FuV2l0aGRyYXcEZGVidAtib3Jyb3dBc3NldAQIcG9vbEFkZHIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBAVwVHlwZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wCDFVua25vd24gcG9vbAQNJHQwMjE0OTgyMTU3NAkBC2dldFBvb2xEYXRhAgUIcG9vbEFkZHIFBXBUeXBlBAhhc3NldElkQQgFDSR0MDIxNDk4MjE1NzQCXzEECGFzc2V0SWRCCAUNJHQwMjE0OTgyMTU3NAJfMgQEYmFsQQgFDSR0MDIxNDk4MjE1NzQCXzMEBGJhbEIIBQ0kdDAyMTQ5ODIxNTc0Al80BAdzaGFyZUlkCAUNJHQwMjE0OTgyMTU3NAJfNQQLY0JhbEFCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFCGFzc2V0SWRBAwkAAAIFC2NCYWxBQmVmb3JlBQtjQmFsQUJlZm9yZQQLY0JhbEJCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFCGFzc2V0SWRCAwkAAAIFC2NCYWxCQmVmb3JlBQtjQmFsQkJlZm9yZQQDaW52AwkAAAIFBXBUeXBlBQdTRl9QT09MCQD8BwQFCHBvb2xBZGRyAgxjYWxsRnVuY3Rpb24JAMwIAgIId2l0aGRyYXcJAMwIAgkAzAgCCQCkAwEFD3VzZXJDYW5XaXRoZHJhdwUDbmlsBQNuaWwFA25pbAMJAAACBQVwVHlwZQUHV1hfUE9PTAkA/AcEBQhwb29sQWRkcgINdW5zdGFrZUFuZEdldAkAzAgCBQ91c2VyQ2FuV2l0aGRyYXcFA25pbAUDbmlsCQACAQITV3JvbmcgcG9zaXRpb24gdHlwZQMJAAACBQNpbnYFA2ludgQKY0JhbEFBZnRlcgkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUIYXNzZXRJZEEECmNCYWxCQWZ0ZXIJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFCGFzc2V0SWRCBA0kdDAyMjA4NjIyMTc1CQCUCgIJAGUCBQpjQmFsQUFmdGVyBQtjQmFsQUJlZm9yZQkAZQIFCmNCYWxCQWZ0ZXIFC2NCYWxCQmVmb3JlBA10b2tlbnNBbW91bnRBCAUNJHQwMjIwODYyMjE3NQJfMQQNdG9rZW5zQW1vdW50QggFDSR0MDIyMDg2MjIxNzUCXzIEDSR0MDIyMTc4MjI4NzQDCQBmAgUEZGVidAAABA1hbW91bnRUb0dldEV4AwMJAAACBQtib3Jyb3dBc3NldAUIYXNzZXRJZEEJAGYCBQRkZWJ0BQ10b2tlbnNBbW91bnRBBwkAZQIFBGRlYnQFDXRva2Vuc0Ftb3VudEEDAwkAAAIFC2JvcnJvd0Fzc2V0BQhhc3NldElkQgkAZgIFBGRlYnQFDXRva2Vuc0Ftb3VudEIHCQBlAgUEZGVidAUNdG9rZW5zQW1vdW50QgAABAVleEludgMJAGYCBQ1hbW91bnRUb0dldEV4AAAJARBleGNoYW5nZURpcmVjdGx5CAUFcFR5cGUFBHBvb2wFCGFzc2V0SWRBBQhhc3NldElkQgUEYmFsQQUEYmFsQgUNYW1vdW50VG9HZXRFeAULYm9ycm93QXNzZXQAAAMJAAACBQVleEludgUFZXhJbnYED2NCYWxBQWZ0ZXJSZXBheQkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUIYXNzZXRJZEEED2NCYWxCQWZ0ZXJSZXBheQkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUIYXNzZXRJZEIJAJQKAgkAZQIFD2NCYWxBQWZ0ZXJSZXBheQULY0JhbEFCZWZvcmUJAGUCBQ9jQmFsQkFmdGVyUmVwYXkFC2NCYWxCQmVmb3JlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFDXRva2Vuc0Ftb3VudEEFDXRva2Vuc0Ftb3VudEIEDXRvVXNlckFtb3VudEEIBQ0kdDAyMjE3ODIyODc0Al8xBA10b1VzZXJBbW91bnRCCAUNJHQwMjIxNzgyMjg3NAJfMgkAmQoHBQ10b1VzZXJBbW91bnRBBQhhc3NldElkQQUNdG9Vc2VyQW1vdW50QgUIYXNzZXRJZEIFCmNCYWxBQWZ0ZXIFCmNCYWxCQWZ0ZXIFB3NoYXJlSWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDndpdGhkcmF3VG9Vc2VyBAR1c2VyBHBvb2wFcG9zSWQIc3RvcExvc3MEB3BBbW91bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwUFcG9zSWQFDWtVc2VyUG9zaXRpb24CEFVua25vd24gcG9zaXRpb24EDHVzZXJJbnRlcmVzdAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRVrVXNlclBvc2l0aW9uSW50ZXJlc3QEDnBvb2xUb3RhbFNoYXJlCQERZ2V0UG9vbFRvdGFsU2hhcmUBBQRwb29sBAh1c2VyQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHVzZXIEDGJvcnJvd0Ftb3VudAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRFrVXNlckJvcnJvd0Ftb3VudAQLYm9ycm93QXNzZXQJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAUSa1VzZXJCb3Jyb3dBc3NldElkBA0kdDAyMzU1ODIzOTAwAwkAZgIFDGJvcnJvd0Ftb3VudAAACQCUCgIKAAFACQD8BwQJAQ5nZXRMZW5kU3J2QWRkcgACDGdldEFzc2V0RGVidAkAzAgCBwkAzAgCCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkCQDMCAIFC2JvcnJvd0Fzc2V0BQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAURa1Bvb2xJbnRlcmVzdExvYW4JAJQKAgAACQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIFBHBvb2wFE2tQb29sSW50ZXJlc3ROb0xvYW4EBGRlYnQIBQ0kdDAyMzU1ODIzOTAwAl8xBAxwb29sSW50ZXJlc3QIBQ0kdDAyMzU1ODIzOTAwAl8yBA91c2VyQ2FuV2l0aGRyYXcJAGQCBQdwQW1vdW50CQBrAwUHcEFtb3VudAkAZQIFDHBvb2xJbnRlcmVzdAUMdXNlckludGVyZXN0BQdTQ0FMRTEwBA0kdDAyMzk5OTI0MTUyCQESd2l0aGRyYXdBbW91bnRDYWxjBAUEcG9vbAUPdXNlckNhbldpdGhkcmF3BQRkZWJ0BQtib3Jyb3dBc3NldAMJAAACBQ0kdDAyMzk5OTI0MTUyBQ0kdDAyMzk5OTI0MTUyBAdzaGFyZUlkCAUNJHQwMjM5OTkyNDE1MgJfNwQKY0JhbEJBZnRlcggFDSR0MDIzOTk5MjQxNTICXzYECmNCYWxBQWZ0ZXIIBQ0kdDAyMzk5OTI0MTUyAl81BAhhc3NldElkQggFDSR0MDIzOTk5MjQxNTICXzQEDXRvVXNlckFtb3VudEIIBQ0kdDAyMzk5OTI0MTUyAl8zBAhhc3NldElkQQgFDSR0MDIzOTk5MjQxNTICXzIEDXRvVXNlckFtb3VudEEIBQ0kdDAyMzk5OTI0MTUyAl8xBAtjbG9zZURidEludgMJAGYCBQRkZWJ0AAAJAPwHBAkBDmdldExlbmRTcnZBZGRyAAIIcmVwYXlGb3IJAMwIAgkArAICCQCsAgIFBHVzZXICAV8FBXBvc0lkBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ5hc3NldElkRnJvbVN0cgEFC2JvcnJvd0Fzc2V0BQRkZWJ0BQNuaWwAAAMJAAACBQtjbG9zZURidEludgULY2xvc2VEYnRJbnYJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwUFcG9zSWQFDWtVc2VyUG9zaXRpb24JAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRVrVXNlclBvc2l0aW9uSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUKa1Bvb2xUb3RhbAkAZQIFDnBvb2xUb3RhbFNoYXJlBQ91c2VyQ2FuV2l0aGRyYXcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUIdXNlckFkZHIFDXRvVXNlckFtb3VudEEJAQ5hc3NldElkRnJvbVN0cgEFCGFzc2V0SWRBCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFCHVzZXJBZGRyBQ10b1VzZXJBbW91bnRCCQEOYXNzZXRJZEZyb21TdHIBBQhhc3NldElkQgUDbmlsCQEOZ2V0Q3Vyc0VudHJpZXMDBQhhc3NldElkQQUIYXNzZXRJZEIFB3NoYXJlSWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDHBhcnNlUmVxdWVzdAEJcmVxdWVzdElkBAdyZXF1ZXN0CQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFCXJlcXVlc3RJZAUKa1JlcXVlc3RJZAkArAICAhNObyByZXF1ZXN0IHdpdGggaWQgBQlyZXF1ZXN0SWQCASwEBHVzZXIJAJEDAgUHcmVxdWVzdAAABARwb29sCQCRAwIFB3JlcXVlc3QAAQQEcG10QQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3JlcXVlc3QAAgQDQUlkCQCRAwIFB3JlcXVlc3QAAwQEcG10QgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3JlcXVlc3QABAQDQklkCQCRAwIFB3JlcXVlc3QABQQEYmFsQQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3JlcXVlc3QABgQEYmFsQgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3JlcXVlc3QABwQHc2hhcmVJZAkAkQMCBQdyZXF1ZXN0AAgEB2J3QXNzZXQJAJEDAgUHcmVxdWVzdAAJBAhid0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB3JlcXVlc3QACgkAnQoLBQR1c2VyBQRwb29sBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAUHYndBc3NldAUIYndBbW91bnQQAWkBEXJlcGxlbmlzaEVWQUxPTkxZAwRwb29sCGxldmVyYWdlDWJvcnJvd0Fzc2V0SWQDAwkAZgIAZAUIbGV2ZXJhZ2UGCQBmAgUIbGV2ZXJhZ2UArAIJAAIBAh9MZXZlcmFnZSBjYW4ndCBiZSA8MTAwIGFuZCA+MzAwBAVwVHlwZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wCElBvb2wgaXMgbm90IGluaXRlZAQNJHQwMjU2NDIyNTczMgkBC2dldFBvb2xEYXRhAgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wFBXBUeXBlBANBSWQIBQ0kdDAyNTY0MjI1NzMyAl8xBANCSWQIBQ0kdDAyNTY0MjI1NzMyAl8yBARiYWxBCAUNJHQwMjU2NDIyNTczMgJfMwQEYmFsQggFDSR0MDI1NjQyMjU3MzICXzQEB3NoYXJlSWQIBQ0kdDAyNTY0MjI1NzMyAl81BA0kdDAyNTczNTI2MzcyAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAgMJAQIhPQIJAQxhc3NldElkVG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFA0FJZAkAAgECFVdyb25nIHBheW1lbnQgYXNzZXQgQQMJAQIhPQIJAQxhc3NldElkVG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwABB2Fzc2V0SWQFA0JJZAkAAgECFVdyb25nIHBheW1lbnQgYXNzZXQgQgkAlgoECAkAkQMCCAUBaQhwYXlt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YWwgdG8gaXRzZWxmLgkAlAoCCAkBD3JlcGxlbmlzaEJ5VHlwZQoFBXBUeXBlBQRwb29sBQtOT19MT0FOX0ZFRQUEcG10QQUDQUlkBQRwbXRCBQNCSWQFBGJhbEEFBGJhbEIFB3NoYXJlSWQCXzEAAAQKdXNlclN0YWtlZAgFDSR0MDI2Mzc1Mjc4MjYCXzEEDGJvcnJvd0Ftb3VudAgFDSR0MDI2Mzc1Mjc4MjYCXzIEDSR0MDI3ODMwMjc5OTcJARJ3aXRoZHJhd0Ftb3VudENhbGMEBQRwb29sBQp1c2VyU3Rha2VkBQxib3Jyb3dBbW91bnQFDWJvcnJvd0Fzc2V0SWQDCQAAAgUNJHQwMjc4MzAyNzk5NwUNJHQwMjc4MzAyNzk5NwQTdXNlckdldEJCZWZvcmVSZXBheQgFDSR0MDI3ODMwMjc5OTcCXzYEE3VzZXJHZXRBQmVmb3JlUmVwYXkIBQ0kdDAyNzgzMDI3OTk3Al81BAhhc3NldElkQggFDSR0MDI3ODMwMjc5OTcCXzQEDXRvVXNlckFtb3VudEIIBQ0kdDAyNzgzMDI3OTk3Al8zBAhhc3NldElkQQgFDSR0MDI3ODMwMjc5OTcCXzIEDXRvVXNlckFtb3VudEEIBQ0kdDAyNzgzMDI3OTk3Al8xBA0kdDAyODAwMDI4MTE1CQELZ2V0UG9vbERhdGECCQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUECEFJZEFmdGVyCAUNJHQwMjgwMDAyODExNQJfMQQIQklkQWZ0ZXIIBQ0kdDAyODAwMDI4MTE1Al8yBAliYWxBQWZ0ZXIIBQ0kdDAyODAwMDI4MTE1Al8zBAliYWxCQWZ0ZXIIBQ0kdDAyODAwMDI4MTE1Al80BAxzaGFyZUlkQWZ0ZXIIBQ0kdDAyODAwMDI4MTE1Al81BAtyYXRpb0JlZm9yZQkAawMFBGJhbEIFBlNDQUxFOAUEYmFsQQQKcmF0aW9BZnRlcgkAawMFCWJhbEJBZnRlcgUGU0NBTEU4BQliYWxBQWZ0ZXIEBmltcGFjdAkAZQIFBlNDQUxFOAkAawMFC3JhdGlvQmVmb3JlBQZTQ0FMRTgFCnJhdGlvQWZ0ZXIECGltY2F0TW9kAwkAZgIAAAUGaW1wYWN0CQBoAgUGaW1wYWN0AP///////////wEFBmltcGFjdAkAlAoCBQNuaWwJAMwIAgUTdXNlckdldEFCZWZvcmVSZXBheQkAzAgCBRN1c2VyR2V0QkJlZm9yZVJlcGF5CQDMCAIFCGltY2F0TW9kBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEZcmVwbGVuaXNoRnJvbUxhbmRFVkFMT05MWQEJcmVxdWVzdElkBA0kdDAyODQ4NTI4NTg5CQEMcGFyc2VSZXF1ZXN0AQUJcmVxdWVzdElkBAR1c2VyCAUNJHQwMjg0ODUyODU4OQJfMQQEcG9vbAgFDSR0MDI4NDg1Mjg1ODkCXzIEBHBtdEEIBQ0kdDAyODQ4NTI4NTg5Al8zBANBSWQIBQ0kdDAyODQ4NTI4NTg5Al80BARwbXRCCAUNJHQwMjg0ODUyODU4OQJfNQQDQklkCAUNJHQwMjg0ODUyODU4OQJfNgQEYmFsQQgFDSR0MDI4NDg1Mjg1ODkCXzcEBGJhbEIIBQ0kdDAyODQ4NTI4NTg5Al84BAdzaGFyZUlkCAUNJHQwMjg0ODUyODU4OQJfOQQHYndBc3NldAgFDSR0MDI4NDg1Mjg1ODkDXzEwBAhid0Ftb3VudAgFDSR0MDI4NDg1Mjg1ODkDXzExAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQISV3JvbmcgcGF5bWVudCBzaXplAwMJAQIhPQIJAQxhc3NldElkVG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFB2J3QXNzZXQGCQECIT0CCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUIYndBbW91bnQJAAIBAg1Xcm9uZyBwYXltZW50BA0kdDAyODc3OTI4OTAzAwkAAAIFA0FJZAUHYndBc3NldAkAlAoCCQBkAgUEcG10QQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFBHBtdEIJAJQKAgUEcG10QQkAZAIFBHBtdEIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAdwbXRBbGxBCAUNJHQwMjg3NzkyODkwMwJfMQQHcG10QWxsQggFDSR0MDI4Nzc5Mjg5MDMCXzIEBXBUeXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAIMVW5rbm93biBwb29sBA0kdDAyODk4NTI5MDk0CQEPcmVwbGVuaXNoQnlUeXBlCgUFcFR5cGUFBHBvb2wFCExPQU5fRkVFBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAQKdXNlclN0YWtlZAgFDSR0MDI4OTg1MjkwOTQCXzEEB2F4bHlGZWUIBQ0kdDAyODk4NTI5MDk0Al8yCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQICFUVWQUxPTkxZX1NUQUtFREFNT1VOVAUKdXNlclN0YWtlZAUDbmlsBQp1c2VyU3Rha2VkAWkBCXJlcGxlbmlzaAMEcG9vbAhsZXZlcmFnZQ1ib3Jyb3dBc3NldElkAwMJAGYCAGQFCGxldmVyYWdlBgkAZgIFCGxldmVyYWdlAKwCCQACAQIfTGV2ZXJhZ2UgY2FuJ3QgYmUgPDEwMCBhbmQgPjMwMAQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sAhJQb29sIGlzIG5vdCBpbml0ZWQEDSR0MDI5NDcxMjk1NjEJAQtnZXRQb29sRGF0YQIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBQVwVHlwZQQDQUlkCAUNJHQwMjk0NzEyOTU2MQJfMQQDQklkCAUNJHQwMjk0NzEyOTU2MQJfMgQEYmFsQQgFDSR0MDI5NDcxMjk1NjECXzMEBGJhbEIIBQ0kdDAyOTQ3MTI5NTYxAl80BAdzaGFyZUlkCAUNJHQwMjk0NzEyOTU2MQJfNQQNJHQwMjk1NjQzMDIwMQMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAIDCQECIT0CCQEMYXNzZXRJZFRvU3RyAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQNBSWQJAAIBAhVXcm9uZyBwYXltZW50IGFzc2V0IEEDCQECIT0CCQEMYXNzZXRJZFRvU3RyAQgJAJEDAggFAWkIcGF5bWVudHMAAQdhc3NldElkBQNCSWQJAAIBAhVXcm9uZyBwYXltZW50IGFzc2V0IEIJAJYKBAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFA0FJZAgJ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cFR5cGUFBHBvb2wFC05PX0xPQU5fRkVFBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAQKdXNlclN0YWtlZAgFDSR0MDMxNDk4MzE2MTACXzEEB2F4bHlGZWUIBQ0kdDAzMTQ5ODMxNjEwAl8yCQDOCAIJARByZXBsZW5pc2hFbnRyaWVzCAUEcG9vbAkApQgBCAUBaQZjYWxsZXIFCnVzZXJTdGFrZWQFB2F4bHlGZWUFCW5ld1Bvc051bQUHc2hhcmVJZAUFcFR5cGUHCQEOZ2V0Q3Vyc0VudHJpZXMDBQNBSWQFA0JJZAUHc2hhcmVJZAFpARFyZXBsZW5pc2hGcm9tTGFuZAEJcmVxdWVzdElkBA0kdDAzMTgyMTMxOTI1CQEMcGFyc2VSZXF1ZXN0AQUJcmVxdWVzdElkBAR1c2VyCAUNJHQwMzE4MjEzMTkyNQJfMQQEcG9vbAgFDSR0MDMxODIxMzE5MjUCXzIEBHBtdEEIBQ0kdDAzMTgyMTMxOTI1Al8zBANBSWQIBQ0kdDAzMTgyMTMxOTI1Al80BARwbXRCCAUNJHQwMzE4MjEzMTkyNQJfNQQDQklkCAUNJHQwMzE4MjEzMTkyNQJfNgQEYmFsQQgFDSR0MDMxODIxMzE5MjUCXzcEBGJhbEIIBQ0kdDAzMTgyMTMxOTI1Al84BAdzaGFyZUlkCAUNJHQwMzE4MjEzMTkyNQJfOQQHYndBc3NldAgFDSR0MDMxODIxMzE5MjUDXzEwBAhid0Ftb3VudAgFDSR0MDMxODIxMzE5MjUDXzExAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQISV3JvbmcgcGF5bWVudCBzaXplAwMJAQIhPQIJAQxhc3NldElkVG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFB2J3QXNzZXQGCQECIT0CCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUIYndBbW91bnQJAAIBAg1Xcm9uZyBwYXltZW50BA0kdDAzMjExNTMyMjM5AwkAAAIFA0FJZAUHYndBc3NldAkAlAoCCQBkAgUEcG10QQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFBHBtdEIJAJQKAgUEcG10QQkAZAIFBHBtdEIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAdwbXRBbGxBCAUNJHQwMzIxMTUzMjIzOQJfMQQHcG10QWxsQggFDSR0MDMyMTE1MzIyMzkCXzIEBXBUeXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAIMVW5rbm93biBwb29sBA0kdDAzMjMyMTMyNDMwCQEPcmVwbGVuaXNoQnlUeXBlCgUFcFR5cGUFBHBvb2wFCExPQU5fRkVFBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAQKdXNlclN0YWtlZAgFDSR0MDMyMzIxMzI0MzACXzEEB2F4bHlGZWUIBQ0kdDAzMjMyMTMyNDMwAl8yBAZwb3NOdW0JARhnZXROZXdVc2VyUG9zaXRpb25OdW1iZXICBQRwb29sCQClCAEIBQFpBmNhbGxlcgQNYm9ycm93RW50cmllcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUGcG9zTnVtBRFrVXNlckJvcnJvd0Ftb3VudAUIYndBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUGcG9zTnVtBRJrVXNlckJvcnJvd0Fzc2V0SWQFB2J3QXNzZXQFA25pbAQHZW50cmllcwkBEHJlcGxlbmlzaEVudHJpZXMIBQRwb29sBQR1c2VyBQp1c2VyU3Rha2VkBQdheGx5RmVlBQZwb3NOdW0FB3NoYXJlSWQFBXBUeXBlBgkAlAoCCQDNCAIJAM4IAgkAzggCBQdlbnRyaWVzCQEOZ2V0Q3Vyc0VudHJpZXMDBQNBSWQFA0JJZAUHc2hhcmVJZAUNYm9ycm93RW50cmllcwkBC0RlbGV0ZUVudHJ5AQkArAICBQlyZXF1ZXN0SWQFCmtSZXF1ZXN0SWQFCnVzZXJTdGFrZWQBaQEId2l0aGRyYXcCBHBvb2wFcG9zSWQJAQ53aXRoZHJhd1RvVXNlcgQJAKUIAQgFAWkGY2FsbGVyBQRwb29sCQCkAwEFBXBvc0lkBwFpARRjcmVhdGVVcGRhdGVTdG9wTG9zcwQFcG9zSWQGcG9vbElkB2Fzc2V0SWQFcHJpY2UEEHRva2VuT3JhY2xlUHJpY2UICgABQAkA/AcEBQ9wcmljZU9yYWNsZUFkZHICCWdldFRXQVA2MAkAzAgCBQdhc3NldElkCQDMCAIHBQNuaWwFA25pbAMJAAECBQFAAgooSW50LCBJbnQpBQFACQACAQkArAICCQADAQUBQAIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQJfMQMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBnBvb2xJZAIBXwkApQgBCAUBaQZjYWxsZXICAV8JAKQDAQUFcG9zSWQFDWtVc2VyUG9zaXRpb24JAAIBAhpUaGVyZSBhcmUgbm8gdXNlciBwb3NpdGlvbgMJAGcCAAAFBXByaWNlCQACAQIcUHJpY2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gMAMJAGYCBQVwcmljZQUQdG9rZW5PcmFjbGVQcmljZQkAAgECK1ByaWNlIG11c3QgYmUgbGVzcyB0aGFuIGN1cnJlbnQgdG9rZW4gcHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQZjYWxsZXICAV8JAKQDAQUFcG9zSWQCAV8FBnBvb2xJZAIBXwUHYXNzZXRJZAUNa1VzZXJTdG9wTG9zcwUFcHJpY2UFA25pbAFpAQ5kZWxldGVTdG9wTG9zcwMFcG9zSWQGcG9vbElkB2Fzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQZjYWxsZXICAV8JAKQDAQUFcG9zSWQCAV8FBnBvb2xJZAIBXwUHYXNzZXRJZAUNa1VzZXJTdG9wTG9zcwkAAgECCE5vIGVudHJ5CQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQZjYWxsZXICAV8JAKQDAQUFcG9zSWQCAV8FBnBvb2xJZAIBXwUHYXNzZXRJZAUNa1VzZXJTdG9wTG9zcwUDbmlsAWkBEGNyZWF0ZU5ld1JlcXVlc3QBBnBhcmFtcwkBC3ZhbHVlT3JFbHNlAgkBCmlzU2VsZkNhbGwBBQFpBAxuZXdSZXF1ZXN0SWQJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDGtSZXF1ZXN0SXRlcgAAAAEJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKQDAQUMbmV3UmVxdWVzdElkBQprUmVxdWVzdElkBQZwYXJhbXMJAMwIAgkBDEludGVnZXJFbnRyeQIFDGtSZXF1ZXN0SXRlcgUMbmV3UmVxdWVzdElkBQNuaWwFDG5ld1JlcXVlc3RJZAFpAQhzdG9wTG9zcwQEdXNlcgVwb3NJZARwb29sB2Fzc2V0SWQEEHRva2VuT3JhY2xlUHJpY2UICgABQAkA/AcEBQ9wcmljZU9yYWNsZUFkZHICCWdldFRXQVA2MAkAzAgCBQdhc3NldElkCQDMCAIHBQNuaWwFA25pbAMJAAECBQFAAgooSW50LCBJbnQpBQFACQACAQkArAICCQADAQUBQAIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQJfMQMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQR1c2VyAgFfCQCkAwEFBXBvc0lkAgFfBQRwb29sAgFfBQdhc3NldElkBQ1rVXNlclN0b3BMb3NzCQACAQIITm8gZW50cnkJAM0IAgkBDndpdGhkcmF3VG9Vc2VyBAkApQgBCAUBaQZjYWxsZXIFBHBvb2wJAKQDAQUFcG9zSWQGCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHVzZXICAV8JAKQDAQUFcG9zSWQCAV8FBHBvb2wCAV8FB2Fzc2V0SWQFDWtVc2VyU3RvcExvc3MBaQEJbGlxdWlkYXRlBAR1c2VyBXBvc0lkBHBvb2wPbGlxdWlkYXRlQW1vdW50BAVwVHlwZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wCElBvb2wgaXMgbm90IGluaXRlZAQNJHQwMzUxMjEzNTIxMQkBC2dldFBvb2xEYXRhAgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wFBXBUeXBlBANBSWQIBQ0kdDAzNTEyMTM1MjExAl8xBANCSWQIBQ0kdDAzNTEyMTM1MjExAl8yBARiYWxBCAUNJHQwMzUxMjEzNTIxMQJfMwQEYmFsQggFDSR0MDM1MTIxMzUyMTECXzQEB3NoYXJlSWQIBQ0kdDAzNTEyMTM1MjExAl81BAdwQW1vdW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUFcG9zSWQFDWtVc2VyUG9zaXRpb24CEFVua25vd24gcG9zaXRpb24EDHVzZXJJbnRlcmVzdAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUFcG9zSWQFFWtVc2VyUG9zaXRpb25JbnRlcmVzdAQOcG9vbFRvdGFsU2hhcmUJARFnZXRQb29sVG90YWxTaGFyZQEFBHBvb2wECHVzZXJBZGRyCQEHQWRkcmVzcwEJANkEAQUEdXNlcgQMYm9ycm93QW1vdW50CQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwkApAMBBQVwb3NJZAURa1VzZXJCb3Jyb3dBbW91bnQEC2JvcnJvd0Fzc2V0CQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwkApAMBBQVwb3NJZAUSa1VzZXJCb3Jyb3dBc3NldElkBA0kdDAzNTc2NTM2MTE4AwkAZgIFDGJvcnJvd0Ftb3VudAAACQCUCgIKAAFACQD8BwQJAQ5nZXRMZW5kU3J2QWRkcgACDGdldEFzc2V0RGVidAkAzAgCBwkAzAgCCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUFcG9zSWQJAMwIAgULYm9ycm93QXNzZXQFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEFAUACGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgkAlAoCAAAJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUTa1Bvb2xJbnRlcmVzdE5vTG9hbgQEZGVidAgFDSR0MDM1NzY1MzYxMTgCXzEEDHBvb2xJbnRlcmVzdAgFDSR0MDM1NzY1MzYxMTgCXzIED3VzZXJDYW5XaXRoZHJhdwkAZAIFB3BBbW91bnQJAGsDBQdwQW1vdW50CQBlAgUMcG9vbEludGVyZXN0BQx1c2VySW50ZXJlc3QFB1NDQUxFMTAECnNoYXJlUHJpY2UJAJEDAgkBDWdldFNoYXJlUHJpY2UBCQDMCAIFB3NoYXJlSWQFA25pbAAABBBib3Jyb3dBc3NldFByaWNlCQCRAwIJAQ5nZXRBc3NldHNQcmljZQEJAMwIAgULYm9ycm93QXNzZXQFA25pbAAABBJ1c2VyQ2FuV2l0aGRyYXdJbkQJAGsDBQ91c2VyQ2FuV2l0aGRyYXcFCnNoYXJlUHJpY2UJARBnZXRBc3NldERlY2ltYWxzAQUHc2hhcmVJZAQPYm9ycm93QW1vdW50SW5ECQBrAwUMYm9ycm93QW1vdW50BRBib3Jyb3dBc3NldFByaWNlCQERZ2V0QXNzZXRQcmVjaXRpb24BBQtib3Jyb3dBc3NldAQNdXNlckFtb3VudEluRAkAZQIFEnVzZXJDYW5XaXRoZHJhd0luRAUPYm9ycm93QW1vdW50SW5EBQNuaWwBaQESY2FwaXRhbGl6ZUV4S2VlcGVyDARwb29sBHR5cGUJdG9rZW5Ub0lkEGFtb3VudFRvRXhjaGFuZ2UFY2xhaW0JYW1vdW50c0luCWFkZHJlc3Nlcw9hc3NldHNUb1JlY2VpdmULZXN0UmVjZWl2ZWQRc2xpcHBhZ2VUb2xlcmFuY2ULbWluUmVjZWl2ZWQHb3B0aW9ucwQNJHQwMzY5MDMzNzA5NwMFBWNsYWltCQELY2xhaW1GYXJtZWQCBQR0eXBlBQRwb29sBAxjbGFpbWVkQXNzZXQDCQAAAgUEdHlwZQUHU0ZfUE9PTAUGU1dPUElEBQRXWElECQCUCgIFEGFtb3VudFRvRXhjaGFuZ2UFDGNsYWltZWRBc3NldAQNY2xhaW1lZEFtb3VudAgFDSR0MDM2OTAzMzcwOTcCXzEEDGNsYWltZWRBc3NldAgFDSR0MDM2OTAzMzcwOTcCXzIED2V4Y2hhbmdlZEFtb3VudAkBDmV4Y2hhbmdlS2VlcGVyCgUJdG9rZW5Ub0lkBRBhbW91bnRUb0V4Y2hhbmdlBQxjbGFpbWVkQXNzZXQFCWFtb3VudHNJbgUJYWRkcmVzc2VzBQ9hc3NldHNUb1JlY2VpdmUFC2VzdFJlY2VpdmVkBRFzbGlwcGFnZVRvbGVyYW5jZQULbWluUmVjZWl2ZWQFB29wdGlvbnMEBmNoYW5nZQkAZQIFDWNsYWltZWRBbW91bnQFEGFtb3VudFRvRXhjaGFuZ2UEC2NoYW5nZUVudHJ5AwkAZgIFBmNoYW5nZQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFDmtQb29sQ2FwQ2hhbmdlCQBkAgUGY2hhbmdlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UAAAUDbmlsBQNuaWwJAM4IAgkBCmNhcGl0YWxpemUEBQRwb29sBQR0eXBlBQl0b2tlblRvSWQFD2V4Y2hhbmdlZEFtb3VudAULY2hhbmdlRW50cnkBaQESY2FwaXRhbGl6ZUV4UHV6emxlCARwb29sBHR5cGUJdG9rZW5Ub0lkEGFtb3VudFRvRXhjaGFuZ2UFY2xhaW0Jcm91dGVzU3RyDG1pblRvUmVjZWl2ZQdvcHRpb25zBA0kdDAzNzc1NDM3OTQ4AwUFY2xhaW0JAQtjbGFpbUZhcm1lZAIFBHR5cGUFBHBvb2wEDGNsYWltZWRBc3NldAMJAAACBQR0eXBlBQdTRl9QT09MBQZTV09QSUQFBFdYSUQJAJQKAgUQYW1vdW50VG9FeGNoYW5nZQUMY2xhaW1lZEFzc2V0BA1jbGFpbWVkQW1vdW50CAUNJHQwMzc3NTQzNzk0OAJfMQQMY2xhaW1lZEFzc2V0CAUNJHQwMzc3NTQzNzk0OAJfMgQPZXhjaGFuZ2VkQW1vdW50CQEOZXhjaGFuZ2VQdXp6bGUGBQl0b2tlblRvSWQFEGFtb3VudFRvRXhjaGFuZ2UFDGNsYWltZWRBc3NldAUJcm91dGVzU3RyBQxtaW5Ub1JlY2VpdmUFB29wdGlvbnMEBmNoYW5nZQkAZQIFDWNsYWltZWRBbW91bnQFEGFtb3VudFRvRXhjaGFuZ2UEC2NoYW5nZUVudHJ5AwkAZgIFBmNoYW5nZQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFDmtQb29sQ2FwQ2hhbmdlCQBkAgUGY2hhbmdlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UAAAUDbmlsBQNuaWwJAM4IAgkBCmNhcGl0YWxpemUEBQRwb29sBQR0eXBlBQl0b2tlblRvSWQFD2V4Y2hhbmdlZEFtb3VudAULY2hhbmdlRW50cnkBaQESY2FwaXRhbGl6ZUV4U3dvcEZpDARwb29sBHR5cGUJdG9rZW5Ub0lkEGFtb3VudFRvRXhjaGFuZ2UFY2xhaW0KZXhjaGFuZ2Vycw5leGNoYW5nZXJzVHlwZQVhcmdzMQVhcmdzMhFyb3V0aW5nQXNzZXRzS2V5cxJtaW5BbW91bnRUb1JlY2VpdmUHb3B0aW9ucwQNJHQwMzg2NzEzODg2NQMFBWNsYWltCQELY2xhaW1GYXJtZWQCBQR0eXBlBQRwb29sBAxjbGFpbWVkQXNzZXQDCQAAAgUEdHlwZQUHU0ZfUE9PTAUGU1dPUElEBQRXWElECQCUCgIFEGFtb3VudFRvRXhjaGFuZ2UFDGNsYWltZWRBc3NldAQNY2xhaW1lZEFtb3VudAgFDSR0MDM4NjcxMzg4NjUCXzEEDGNsYWltZWRBc3NldAgFDSR0MDM4NjcxMzg4NjUCXzIED2V4Y2hhbmdlZEFtb3VudAkBDmV4Y2hhbmdlU3dvcEZpCgUJdG9rZW5Ub0lkBRBhbW91bnRUb0V4Y2hhbmdlBQxjbGFpbWVkQXNzZXQFCmV4Y2hhbmdlcnMFDmV4Y2hhbmdlcnNUeXBlBQVhcmdzMQUFYXJnczIFEXJvdXRpbmdBc3NldHNLZXlzBRJtaW5BbW91bnRUb1JlY2VpdmUFB29wdGlvbnMEBmNoYW5nZQkAZQIFDWNsYWltZWRBbW91bnQFEGFtb3VudFRvRXhjaGFuZ2UEC2NoYW5nZUVudHJ5AwkAZgIFBmNoYW5nZQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFDmtQb29sQ2FwQ2hhbmdlCQBkAgUGY2hhbmdlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UAAAUDbmlsBQNuaWwJAM4IAgkBCmNhcGl0YWxpemUEBQRwb29sBQR0eXBlBQl0b2tlblRvSWQFD2V4Y2hhbmdlZEFtb3VudAULY2hhbmdlRW50cnkBaQELaW5pdE5ld1Bvb2wIBHR5cGUIcG9vbEFkZHILaW5GZWVOb0xvYW4JaW5GZWVMb2FuDGNhcEZlZU5vTG9hbg5jYXBGZWVXaXRoTG9hbhFzdG9wbG9zc0ZlZU5vTG9hbhNzdG9wbG9zc0ZlZVdpdGhMb2FuAwMJAQIhPQIFBHR5cGUFB1NGX1BPT0wJAQIhPQIFBHR5cGUFB1dYX1BPT0wHCQACAQIKV3JvbmcgdHlwZQQNJHQwMzk1NTgzOTY1MgkBC2dldFBvb2xEYXRhAgkBB0FkZHJlc3MBCQDZBAEFCHBvb2xBZGRyBQR0eXBlBANhSWQIBQ0kdDAzOTU1ODM5NjUyAl8xBANiSWQIBQ0kdDAzOTU1ODM5NjUyAl8yBARhQmFsCAUNJHQwMzk1NTgzOTY1MgJfMwQEYkJhbAgFDSR0MDM5NTU4Mzk2NTICXzQEB3NoYXJlSWQIBQ0kdDAzOTU1ODM5NjUyAl81CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRVrQXhseUluRmVlV2l0aG91dExvYW4FC2luRmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRJrQXhseUluRmVlV2l0aExvYW4FCWluRmVlTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgURa0F4bHlOb0xvYW5DYXBGZWUFDGNhcEZlZU5vTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgUTa0F4bHlXaXRoTG9hbkNhcEZlZQUOY2FwRmVlV2l0aExvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIcG9vbEFkZHIFFmtBeGx5U3RvcExvc3NOb0xvYW5GZWUFEXN0b3Bsb3NzRmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRRrQXhseVN0b3BMb3NzTG9hbkZlZQUTc3RvcGxvc3NGZWVXaXRoTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgURa1Bvb2xJbnRlcmVzdExvYW4AAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgUTa1Bvb2xJbnRlcmVzdE5vTG9hbgAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUFa1Bvb2wFCHBvb2xBZGRyBQR0eXBlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUHc2hhcmVJZAUKa1NoYXJlUG9vbAUIcG9vbEFkZHIFA25pbAFpAQ5jYXBpdGFsaXplVGVzdAQEcG9vbAVwVHlwZQd0b2tlbklkC3Rva2VuQW1vdW50BAhwb29sQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wEDSR0MDQwNDQ4NDA1MjcJAQtnZXRQb29sRGF0YQIFCHBvb2xBZGRyBQVwVHlwZQQDQUlkCAUNJHQwNDA0NDg0MDUyNwJfMQQDQklkCAUNJHQwNDA0NDg0MDUyNwJfMgQEYmFsQQgFDSR0MDQwNDQ4NDA1MjcCXzMEBGJhbEIIBQ0kdDA0MDQ0ODQwNTI3Al80BAdzaGFyZUlkCAUNJHQwNDA0NDg0MDUyNwJfNQQNJHQwNDA1MzA0MDYxMAMJAAACBQd0b2tlbklkBQNBSWQJAJQKAgULdG9rZW5BbW91bnQAAAkAlAoCAAAFC3Rva2VuQW1vdW50BARwbXRBCAUNJHQwNDA1MzA0MDYxMAJfMQQEcG10QggFDSR0MDQwNTMwNDA2MTACXzIEDSR0MDQwNjEzNDA3MTcJAQ9yZXBsZW5pc2hCeVR5cGUKBQVwVHlwZQUEcG9vbAUGTk9fRkVFBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAQMc3Rha2VkQW1vdW50CAUNJHQwNDA2MTM0MDcxNwJfMQQCbmYIBQ0kdDA0MDYxMzQwNzE3Al8yBBNjdXJQb29sSW50ZXJlc3RMb2FuCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAURa1Bvb2xJbnRlcmVzdExvYW4AAAQVY3VyUG9vbEludGVyZXN0Tm9Mb2FuCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUTa1Bvb2xJbnRlcmVzdE5vTG9hbgAABBB0b3RhbFNoYXJlQW1vdW50CQERZ2V0UG9vbFRvdGFsU2hhcmUBBQRwb29sBBh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4JARlnZXRQb29sVG90YWxTaGFyZVdpdGhMb2FuAQUEcG9vbAQLbG9hblBlcmNlbnQJAGsDBRh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4FBlNDQUxFOAUQdG90YWxTaGFyZUFtb3VudAQKc3Rha2VkTG9hbgkAawMFDHN0YWtlZEFtb3VudAULbG9hblBlcmNlbnQFBlNDQUxFOAQMc3Rha2VkTm9Mb2FuCQBlAgUMc3Rha2VkQW1vdW50BQpzdGFrZWRMb2FuBA9uZXdJbnRlcmVzdExvYW4JAGQCBRNjdXJQb29sSW50ZXJlc3RMb2FuCQBrAwUKc3Rha2VkTG9hbgUHU0NBTEUxMAUYdG90YWxTaGFyZUFtb3VudFdpdGhMb2FuBBFuZXdJbnRlcmVzdE5vTG9hbgkAZAIFFWN1clBvb2xJbnRlcmVzdE5vTG9hbgkAawMFDHN0YWtlZE5vTG9hbgUHU0NBTEUxMAkAZQIFEHRvdGFsU2hhcmVBbW91bnQFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgQLYXhseUZlZUxvYW4JAGsDBQpzdGFrZWRMb2FuCQEKZ2V0QXhseUZlZQIFBHBvb2wFDENBUF9GRUVfTE9BTgUKRkVFX1NDQUxFNgQNYXhseUZlZU5vTG9hbgkAawMFDHN0YWtlZE5vTG9hbgkBCmdldEF4bHlGZWUCBQRwb29sBQ9DQVBfRkVFX05PX0xPQU4FCkZFRV9TQ0FMRTYJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgUPbmV3SW50ZXJlc3RMb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFE2tQb29sSW50ZXJlc3ROb0xvYW4FEW5ld0ludGVyZXN0Tm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFCmtQb29sVG90YWwJAGUCCQBlAgkAZAIFEHRvdGFsU2hhcmVBbW91bnQFDHN0YWtlZEFtb3VudAULYXhseUZlZUxvYW4FDWF4bHlGZWVOb0xvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUOa1Bvb2xUb3RhbExvYW4JAGUCCQBkAgUYdG90YWxTaGFyZUFtb3VudFdpdGhMb2FuBQpzdGFrZWRMb2FuBQtheGx5RmVlTG9hbgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQhtb25leUJveAkAZAIFC2F4bHlGZWVMb2FuBQ1heGx5RmVlTm9Mb2FuCQDZBAEFB3NoYXJlSWQFA25pbAkBDmdldEN1cnNFbnRyaWVzAwUDQUlkBQNCSWQFB3NoYXJlSWQBaQEPY2xhaW1GYXJtZWRUZXN0AgR0eXBlBHBvb2wDCQAAAgUEdHlwZQUHU0ZfUE9PTAQJYmFsQmVmb3JlCQEOYWNjb3VudEJhbGFuY2UBBQZTV09QSUQDCQAAAgUJYmFsQmVmb3JlBQliYWxCZWZvcmUEA2ludgkA/AcECQEQZ2V0U0ZGYXJtaW5nQWRkcgACBWNsYWltCQDMCAIFBHBvb2wFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BAhiYWxBZnRlcgkBDmFjY291bnRCYWxhbmNlAQUGU1dPUElECQCUCgIFA25pbAkAlAoCCQBlAgUIYmFsQWZ0ZXIFCWJhbEJlZm9yZQUGU1dPUElECQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFBHR5cGUFB1dYX1BPT0wECWJhbEJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQUEV1hJRAMJAAACBQliYWxCZWZvcmUFCWJhbEJlZm9yZQQDaW52CQD8BwQJARBnZXRXWEZhcm1pbmdBZGRyAQkBB0FkZHJlc3MBCQDZBAEFBHBvb2wCB2NsYWltV1gJAMwIAgUEcG9vbAUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYECGJhbEFmdGVyCQEOYWNjb3VudEJhbGFuY2UBBQRXWElECQCUCgIFA25pbAkAlAoCCQBlAgUIYmFsQWZ0ZXIFCWJhbEJlZm9yZQUEV1hJRAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECD1dyb25nIHBvb2wgdHlwZQECdHgBBnZlcmlmeQAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXlJ8XUP", "height": 2590525, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DLjrR2vLeenXbj8E4QgH17CRKUmoXPhgb72462z7ya4a Next: 34uXxfmT4NjEJ4uEruy3HeM3tVjhhyH6qyMEkvEmpTK1 Diff:
OldNewDifferences
99
1010 let CAP_FEE_LOAN = "capLoan"
1111
12-let CAP_FEE = "cap"
12+let STOPLOSS_FEE_NO_LOAN = "capNoLoan"
13+
14+let STOPLOSS_LOAN = "capLoan"
1315
1416 let LOAN_FEE = "loan"
1517
1618 let NO_LOAN_FEE = "noLoan"
19+
20+let NO_FEE = "noFee"
1721
1822 let SCALE8 = 100000000
1923
4953
5054 let kPoolTotalLoan = "_pool_total_loan"
5155
52-let kPoolInterest = "_pool_interest"
56+let kPoolInterestLoan = "_pool_interest_loan"
57+
58+let kPoolInterestNoLoan = "_pool_interest_no_loan"
5359
5460 let kAxlyInFeeWithoutLoan = "_axly_fee_without_loan"
5561
5864 let kAxlyNoLoanCapFee = "_axly_fee_cap_with_loan"
5965
6066 let kAxlyWithLoanCapFee = "_axly_fee_cap_no_loan"
67+
68+let kAxlyStopLossNoLoanFee = "_axly_fee_stoploss_with_loan"
69+
70+let kAxlyStopLossLoanFee = "_axly_fee_stoploss_no_loan"
6171
6272 let kRequestId = "_request_id"
6373
7080 let kPoolCapChange = "_pool_cap_change"
7181
7282 let kTokenLastPrice = "_last_price"
83+
84+let kUserStopLoss = "_stop_loss"
7385
7486 let kMoneyBox = "axly_money_box"
7587
236248 }
237249
238250
251+func getAssetPrecition (assetId) = pow(10, 0, getAssetDecimals(assetId), 0, 0, DOWN)
252+
253+
239254 func getAssetsPrice (assetIds) = {
240255 func getPrices (a,assetId) = {
241256 let assetPrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
265280 let pool = valueOrErrorMessage(getString(this, (shareId + kSharePool)), "Can't find pool addr by share id")
266281 let poolAddr = Address(fromBase58String(pool))
267282 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
268- let $t077377802 = getPoolData(poolAddr, pType)
269- let aId = $t077377802._1
270- let bId = $t077377802._2
271- let aBalance = $t077377802._3
272- let bBalance = $t077377802._4
283+ let $t082848349 = getPoolData(poolAddr, pType)
284+ let aId = $t082848349._1
285+ let bId = $t082848349._2
286+ let aBalance = $t082848349._3
287+ let bBalance = $t082848349._4
273288 let dPriceA = ( let @ = invoke(priceOracleAddr, "getTWAP60", [aId, false], nil)
274289 if ($isInstanceOf(@, "(Int, Int)"))
275290 then @
316331 let poolAddr = Address(fromBase58String(pool))
317332 let ratioA = fraction(SCALE8, pmtA, balA)
318333 let ratioB = fraction(SCALE8, pmtB, balB)
319- let $t093079599 = if ((ratioB > ratioA))
334+ let $t0985410146 = if ((ratioB > ratioA))
320335 then {
321336 let pmt = fraction(balB, ratioA, SCALE8, CEILING)
322337 $Tuple4(pmtA, pmt, (pmtB - pmt), pmtAssetB)
325340 let pmt = fraction(balA, ratioB, SCALE8, CEILING)
326341 $Tuple4(pmt, pmtB, (pmtA - pmt), pmtAssetA)
327342 }
328- let pmtAmountA = $t093079599._1
329- let pmtAmountB = $t093079599._2
330- let change = $t093079599._3
331- let changeAssetId = $t093079599._4
343+ let pmtAmountA = $t0985410146._1
344+ let pmtAmountB = $t0985410146._2
345+ let change = $t0985410146._3
346+ let changeAssetId = $t0985410146._4
332347 let inv1 = if (if ((pmtAmountA > 0))
333348 then (pmtAmountB > 0)
334349 else false)
350365 then {
351366 let shareBalanceAfter = accountBalance(fromBase58String(shareId))
352367 let totalStaked = (shareBalanceAfter - shareBalanceBefore)
353- let axlyFeeAmount = if ((feeType == CAP_FEE))
354- then fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
355- else fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
368+ let axlyFeeAmount = fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
356369 let userShareForStake = (totalStaked - axlyFeeAmount)
357370 if ((0 >= userShareForStake))
358371 then throw("amount of staked sharetokens must be > 0")
373386
374387 func replenishWX (pool,feeType,pmtA,pmtAssetA,pmtB,pmtAssetB,shareId) = {
375388 let poolAddr = Address(fromBase58String(pool))
376- let $t01116412013 = if (if ((pmtA > 0))
389+ let $t01159712446 = if (if ((pmtA > 0))
377390 then (pmtB > 0)
378391 else false)
379392 then {
414427 else if ((pmtB > 0))
415428 then $Tuple4(pmtA, pmtB, pmtB, pmtAssetB)
416429 else throw("pmts must be > 0")
417- let pmtAmountA = $t01116412013._1
418- let pmtAmountB = $t01116412013._2
419- let change = $t01116412013._3
420- let changeAssetId = $t01116412013._4
430+ let pmtAmountA = $t01159712446._1
431+ let pmtAmountB = $t01159712446._2
432+ let change = $t01159712446._3
433+ let changeAssetId = $t01159712446._4
421434 let shareBalanceBefore = accountBalance(fromBase58String(shareId))
422435 if ((shareBalanceBefore == shareBalanceBefore))
423436 then {
467480 else throw("Wrong pool type")
468481
469482
470-func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type) = {
483+func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type,withLoan) = {
471484 let totalAmount = getPoolTotalShare(pool)
472485 let totalAmountLoan = getPoolTotalShareWithLoan(pool)
473- let curPoolInterest = getIntegerValue(this, (pool + kPoolInterest))
486+ let $t01446414702 = if (withLoan)
487+ then $Tuple2(getIntegerValue(this, (pool + kPoolInterestLoan)), (totalAmountLoan + stakedAmount))
488+ else $Tuple2(getIntegerValue(this, (pool + kPoolInterestNoLoan)), totalAmountLoan)
489+ let curPoolInterest = $t01446414702._1
490+ let totalStakedWithLoan = $t01446414702._2
474491 [IntegerEntry((pool + kPoolTotal), (totalAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), (totalAmountLoan + stakedAmount)), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPosition), stakedAmount), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPositionInterest), curPoolInterest), IntegerEntry((((pool + "_") + user) + kUserPositionNum), posNum), ScriptTransfer(moneyBox, axlyFeeAmount, fromBase58String(shareId))]
475492 }
476493
521538 }
522539
523540
524-func exchangePazzle (toToken,pmtAmount,pmtAsset,routesStr,minToReceive,options) = {
541+func exchangePuzzle (toToken,pmtAmount,pmtAsset,routesStr,minToReceive,options) = {
525542 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
526543 if ((tokenBalanceBefore == tokenBalanceBefore))
527544 then {
549566
550567 func capitalize (pool,pType,tokenId,tokenAmount) = {
551568 let poolAddr = Address(fromBase58String(pool))
552- let $t01697517054 = getPoolData(poolAddr, pType)
553- let AId = $t01697517054._1
554- let BId = $t01697517054._2
555- let balA = $t01697517054._3
556- let balB = $t01697517054._4
557- let shareId = $t01697517054._5
558- let $t01705717137 = if ((tokenId == AId))
569+ let $t01760117680 = getPoolData(poolAddr, pType)
570+ let AId = $t01760117680._1
571+ let BId = $t01760117680._2
572+ let balA = $t01760117680._3
573+ let balB = $t01760117680._4
574+ let shareId = $t01760117680._5
575+ let $t01768317763 = if ((tokenId == AId))
559576 then $Tuple2(tokenAmount, 0)
560577 else $Tuple2(0, tokenAmount)
561- let pmtA = $t01705717137._1
562- let pmtB = $t01705717137._2
563- let $t01714017250 = replenishByType(pType, pool, CAP_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
564- let stakedAmount = $t01714017250._1
565- let axlyFee = $t01714017250._2
566- let curPoolInterest = valueOrElse(getInteger(this, (pool + kPoolInterest)), 0)
578+ let pmtA = $t01768317763._1
579+ let pmtB = $t01768317763._2
580+ let $t01776617870 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
581+ let stakedAmount = $t01776617870._1
582+ let nf = $t01776617870._2
583+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
584+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
567585 let totalShareAmount = getPoolTotalShare(pool)
568- let newInterest = (curPoolInterest + fraction(stakedAmount, SCALE10, totalShareAmount))
569- ([IntegerEntry((pool + kPoolInterest), newInterest), ScriptTransfer(moneyBox, axlyFee, fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
586+ let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
587+ let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
588+ let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
589+ let stakedNoLoan = (stakedAmount - stakedLoan)
590+ let newInterestLoan = (curPoolInterestLoan + fraction(stakedLoan, SCALE10, totalShareAmountWithLoan))
591+ let newInterestNoLoan = (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
592+ let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
593+ let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
594+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (((totalShareAmount + stakedAmount) - axlyFeeLoan) - axlyFeeNoLoan)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
570595 }
571596
572597
575600 let feeScale6 = 1000000
576601 let fee = getIntegerValue(poolAddr, kSFPoolFee)
577602 let amntGetNoFee = fraction(amountTokenToGet, feeScale6, (feeScale6 - fee))
578- let $t01798018268 = if ((assetTokenToGet == assetIdA))
603+ let $t01955819846 = if ((assetTokenToGet == assetIdA))
579604 then {
580605 let amountToPay = fraction(balA, amntGetNoFee, (balB - amntGetNoFee))
581606 $Tuple2(amountToPay, assetIdB)
584609 let amountToPay = fraction(balB, amntGetNoFee, (balA - amntGetNoFee))
585610 $Tuple2(amountToPay, assetIdA)
586611 }
587- let amountToPay = $t01798018268._1
588- let assetToPay = $t01798018268._2
612+ let amountToPay = $t01955819846._1
613+ let assetToPay = $t01955819846._2
589614 invoke(poolAddr, "callFunction", ["exchange", ["1"]], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
590615 }
591616
595620 let prFee = getIntegerValue(wxSwapContract, "%s__protocolFee")
596621 let pFee = getIntegerValue(wxSwapContract, "%s__poolFee")
597622 let feeScale = toBigInt(100000000)
598- let $t01874719055 = if ((assetTokenToGet == assetIdA))
623+ let $t02032520633 = if ((assetTokenToGet == assetIdA))
599624 then {
600625 let amountToPay = fraction(balA, amountTokenToGet, (balB - amountTokenToGet))
601626 $Tuple2(amountToPay, assetIdB)
604629 let amountToPay = fraction(balB, amountTokenToGet, (balA - amountTokenToGet))
605630 $Tuple2(amountToPay, assetIdA)
606631 }
607- let amountToPay = $t01874719055._1
608- let assetToPay = $t01874719055._2
632+ let amountToPay = $t02032520633._1
633+ let assetToPay = $t02032520633._2
609634 let amountToPayWithFee = toInt(fraction(toBigInt(amountToPay), feeScale, (feeScale - toBigInt((prFee + pFee)))))
610635 invoke(wxSwapContract, "swap", [1, assetTokenToGet, toString(this)], [AttachedPayment(assetIdFromStr(assetToPay), amountToPayWithFee)])
611636 }
619644 func withdrawAmountCalc (pool,userCanWithdraw,debt,borrowAsset) = {
620645 let poolAddr = Address(fromBase58String(pool))
621646 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
622- let $t01992019996 = getPoolData(poolAddr, pType)
623- let assetIdA = $t01992019996._1
624- let assetIdB = $t01992019996._2
625- let balA = $t01992019996._3
626- let balB = $t01992019996._4
627- let shareId = $t01992019996._5
647+ let $t02149821574 = getPoolData(poolAddr, pType)
648+ let assetIdA = $t02149821574._1
649+ let assetIdB = $t02149821574._2
650+ let balA = $t02149821574._3
651+ let balB = $t02149821574._4
652+ let shareId = $t02149821574._5
628653 let cBalABefore = accountBalance(assetIdFromStr(assetIdA))
629654 if ((cBalABefore == cBalABefore))
630655 then {
640665 then {
641666 let cBalAAfter = accountBalance(assetIdFromStr(assetIdA))
642667 let cBalBAfter = accountBalance(assetIdFromStr(assetIdB))
643- let $t02050820597 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
644- let tokensAmountA = $t02050820597._1
645- let tokensAmountB = $t02050820597._2
646- let $t02060021296 = if ((debt > 0))
668+ let $t02208622175 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
669+ let tokensAmountA = $t02208622175._1
670+ let tokensAmountB = $t02208622175._2
671+ let $t02217822874 = if ((debt > 0))
647672 then {
648673 let amountToGetEx = if (if ((borrowAsset == assetIdA))
649674 then (debt > tokensAmountA)
666691 else throw("Strict value is not equal to itself.")
667692 }
668693 else $Tuple2(tokensAmountA, tokensAmountB)
669- let toUserAmountA = $t02060021296._1
670- let toUserAmountB = $t02060021296._2
694+ let toUserAmountA = $t02217822874._1
695+ let toUserAmountB = $t02217822874._2
671696 $Tuple7(toUserAmountA, assetIdA, toUserAmountB, assetIdB, cBalAAfter, cBalBAfter, shareId)
672697 }
673698 else throw("Strict value is not equal to itself.")
674699 }
700+ else throw("Strict value is not equal to itself.")
701+ }
702+ else throw("Strict value is not equal to itself.")
703+ }
704+
705+
706+func withdrawToUser (user,pool,posId,stopLoss) = {
707+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
708+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
709+ let poolTotalShare = getPoolTotalShare(pool)
710+ let userAddr = Address(fromBase58String(user))
711+ let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount))
712+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
713+ let $t02355823900 = if ((borrowAmount > 0))
714+ then $Tuple2({
715+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + posId), borrowAsset], nil)
716+ if ($isInstanceOf(@, "Int"))
717+ then @
718+ else throw(($getType(@) + " couldn't be cast to Int"))
719+ }, getIntegerValue(this, (pool + kPoolInterestLoan)))
720+ else $Tuple2(0, getIntegerValue(this, (pool + kPoolInterestNoLoan)))
721+ let debt = $t02355823900._1
722+ let poolInterest = $t02355823900._2
723+ let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
724+ let $t02399924152 = withdrawAmountCalc(pool, userCanWithdraw, debt, borrowAsset)
725+ if (($t02399924152 == $t02399924152))
726+ then {
727+ let shareId = $t02399924152._7
728+ let cBalBAfter = $t02399924152._6
729+ let cBalAAfter = $t02399924152._5
730+ let assetIdB = $t02399924152._4
731+ let toUserAmountB = $t02399924152._3
732+ let assetIdA = $t02399924152._2
733+ let toUserAmountA = $t02399924152._1
734+ let closeDbtInv = if ((debt > 0))
735+ then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
736+ else 0
737+ if ((closeDbtInv == closeDbtInv))
738+ then ([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), (poolTotalShare - userCanWithdraw)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB))] ++ getCursEntries(assetIdA, assetIdB, shareId))
675739 else throw("Strict value is not equal to itself.")
676740 }
677741 else throw("Strict value is not equal to itself.")
702766 then throw("Leverage can't be <100 and >300")
703767 else {
704768 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
705- let $t02228422374 = getPoolData(Address(fromBase58String(pool)), pType)
706- let AId = $t02228422374._1
707- let BId = $t02228422374._2
708- let balA = $t02228422374._3
709- let balB = $t02228422374._4
710- let shareId = $t02228422374._5
711- let $t02237723014 = if ((size(i.payments) == 2))
769+ let $t02564225732 = getPoolData(Address(fromBase58String(pool)), pType)
770+ let AId = $t02564225732._1
771+ let BId = $t02564225732._2
772+ let balA = $t02564225732._3
773+ let balB = $t02564225732._4
774+ let shareId = $t02564225732._5
775+ let $t02573526372 = if ((size(i.payments) == 2))
712776 then if ((assetIdToStr(i.payments[0].assetId) != AId))
713777 then throw("Wrong payment asset A")
714778 else if ((assetIdToStr(i.payments[1].assetId) != BId))
721785 then $Tuple4(0, AId, i.payments[0].amount, BId)
722786 else throw("Wrong payment")
723787 else throw("One or two payments expected")
724- let pmtA = $t02237723014._1
725- let pmtAssetA = $t02237723014._2
726- let pmtB = $t02237723014._3
727- let pmtAssetB = $t02237723014._4
728- let $t02301724468 = if ((leverage > 100))
788+ let pmtA = $t02573526372._1
789+ let pmtAssetA = $t02573526372._2
790+ let pmtB = $t02573526372._3
791+ let pmtAssetB = $t02573526372._4
792+ let $t02637527826 = if ((leverage > 100))
729793 then {
730794 let dPriceA = ( let @ = invoke(priceOracleAddr, "getTWAP60", [pmtAssetA, false], nil)
731795 if ($isInstanceOf(@, "(Int, Int)"))
755819 else throw("Strict value is not equal to itself.")
756820 }
757821 else $Tuple2(replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)._1, 0)
758- let userStaked = $t02301724468._1
759- let borrowAmount = $t02301724468._2
760- let $t02447224639 = withdrawAmountCalc(pool, userStaked, borrowAmount, borrowAssetId)
761- if (($t02447224639 == $t02447224639))
822+ let userStaked = $t02637527826._1
823+ let borrowAmount = $t02637527826._2
824+ let $t02783027997 = withdrawAmountCalc(pool, userStaked, borrowAmount, borrowAssetId)
825+ if (($t02783027997 == $t02783027997))
762826 then {
763- let userGetBBeforeRepay = $t02447224639._6
764- let userGetABeforeRepay = $t02447224639._5
765- let assetIdB = $t02447224639._4
766- let toUserAmountB = $t02447224639._3
767- let assetIdA = $t02447224639._2
768- let toUserAmountA = $t02447224639._1
769- let $t02464224757 = getPoolData(Address(fromBase58String(pool)), pType)
770- let AIdAfter = $t02464224757._1
771- let BIdAfter = $t02464224757._2
772- let balAAfter = $t02464224757._3
773- let balBAfter = $t02464224757._4
774- let shareIdAfter = $t02464224757._5
827+ let userGetBBeforeRepay = $t02783027997._6
828+ let userGetABeforeRepay = $t02783027997._5
829+ let assetIdB = $t02783027997._4
830+ let toUserAmountB = $t02783027997._3
831+ let assetIdA = $t02783027997._2
832+ let toUserAmountA = $t02783027997._1
833+ let $t02800028115 = getPoolData(Address(fromBase58String(pool)), pType)
834+ let AIdAfter = $t02800028115._1
835+ let BIdAfter = $t02800028115._2
836+ let balAAfter = $t02800028115._3
837+ let balBAfter = $t02800028115._4
838+ let shareIdAfter = $t02800028115._5
775839 let ratioBefore = fraction(balB, SCALE8, balA)
776840 let ratioAfter = fraction(balBAfter, SCALE8, balAAfter)
777841 let impact = (SCALE8 - fraction(ratioBefore, SCALE8, ratioAfter))
787851
788852 @Callable(i)
789853 func replenishFromLandEVALONLY (requestId) = {
790- let $t02512725231 = parseRequest(requestId)
791- let user = $t02512725231._1
792- let pool = $t02512725231._2
793- let pmtA = $t02512725231._3
794- let AId = $t02512725231._4
795- let pmtB = $t02512725231._5
796- let BId = $t02512725231._6
797- let balA = $t02512725231._7
798- let balB = $t02512725231._8
799- let shareId = $t02512725231._9
800- let bwAsset = $t02512725231._10
801- let bwAmount = $t02512725231._11
854+ let $t02848528589 = parseRequest(requestId)
855+ let user = $t02848528589._1
856+ let pool = $t02848528589._2
857+ let pmtA = $t02848528589._3
858+ let AId = $t02848528589._4
859+ let pmtB = $t02848528589._5
860+ let BId = $t02848528589._6
861+ let balA = $t02848528589._7
862+ let balB = $t02848528589._8
863+ let shareId = $t02848528589._9
864+ let bwAsset = $t02848528589._10
865+ let bwAmount = $t02848528589._11
802866 if ((size(i.payments) != 1))
803867 then throw("Wrong payment size")
804868 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
806870 else (i.payments[0].amount != bwAmount))
807871 then throw("Wrong payment")
808872 else {
809- let $t02542125545 = if ((AId == bwAsset))
873+ let $t02877928903 = if ((AId == bwAsset))
810874 then $Tuple2((pmtA + i.payments[0].amount), pmtB)
811875 else $Tuple2(pmtA, (pmtB + i.payments[0].amount))
812- let pmtAllA = $t02542125545._1
813- let pmtAllB = $t02542125545._2
876+ let pmtAllA = $t02877928903._1
877+ let pmtAllB = $t02877928903._2
814878 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
815- let $t02562725736 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
816- let userStaked = $t02562725736._1
817- let axlyFee = $t02562725736._2
879+ let $t02898529094 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
880+ let userStaked = $t02898529094._1
881+ let axlyFee = $t02898529094._2
818882 $Tuple2([IntegerEntry("EVALONLY_STAKEDAMOUNT", userStaked)], userStaked)
819883 }
820884 }
828892 then throw("Leverage can't be <100 and >300")
829893 else {
830894 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
831- let $t02611326203 = getPoolData(Address(fromBase58String(pool)), pType)
832- let AId = $t02611326203._1
833- let BId = $t02611326203._2
834- let balA = $t02611326203._3
835- let balB = $t02611326203._4
836- let shareId = $t02611326203._5
837- let $t02620626843 = if ((size(i.payments) == 2))
895+ let $t02947129561 = getPoolData(Address(fromBase58String(pool)), pType)
896+ let AId = $t02947129561._1
897+ let BId = $t02947129561._2
898+ let balA = $t02947129561._3
899+ let balB = $t02947129561._4
900+ let shareId = $t02947129561._5
901+ let $t02956430201 = if ((size(i.payments) == 2))
838902 then if ((assetIdToStr(i.payments[0].assetId) != AId))
839903 then throw("Wrong payment asset A")
840904 else if ((assetIdToStr(i.payments[1].assetId) != BId))
847911 then $Tuple4(0, AId, i.payments[0].amount, BId)
848912 else throw("Wrong payment")
849913 else throw("One or two payments expected")
850- let pmtA = $t02620626843._1
851- let pmtAssetA = $t02620626843._2
852- let pmtB = $t02620626843._3
853- let pmtAssetB = $t02620626843._4
914+ let pmtA = $t02956430201._1
915+ let pmtAssetA = $t02956430201._2
916+ let pmtB = $t02956430201._3
917+ let pmtAssetB = $t02956430201._4
854918 let newPosNum = getNewUserPositionNumber(pool, toString(i.caller))
855919 if ((leverage > 100))
856920 then {
882946 else throw("Strict value is not equal to itself.")
883947 }
884948 else {
885- let $t02814028252 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
886- let userStaked = $t02814028252._1
887- let axlyFee = $t02814028252._2
888- (replenishEntries(pool, toString(i.caller), userStaked, axlyFee, newPosNum, shareId, pType) ++ getCursEntries(AId, BId, shareId))
949+ let $t03149831610 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
950+ let userStaked = $t03149831610._1
951+ let axlyFee = $t03149831610._2
952+ (replenishEntries(pool, toString(i.caller), userStaked, axlyFee, newPosNum, shareId, pType, false) ++ getCursEntries(AId, BId, shareId))
889953 }
890954 }
891955
893957
894958 @Callable(i)
895959 func replenishFromLand (requestId) = {
896- let $t02845628560 = parseRequest(requestId)
897- let user = $t02845628560._1
898- let pool = $t02845628560._2
899- let pmtA = $t02845628560._3
900- let AId = $t02845628560._4
901- let pmtB = $t02845628560._5
902- let BId = $t02845628560._6
903- let balA = $t02845628560._7
904- let balB = $t02845628560._8
905- let shareId = $t02845628560._9
906- let bwAsset = $t02845628560._10
907- let bwAmount = $t02845628560._11
960+ let $t03182131925 = parseRequest(requestId)
961+ let user = $t03182131925._1
962+ let pool = $t03182131925._2
963+ let pmtA = $t03182131925._3
964+ let AId = $t03182131925._4
965+ let pmtB = $t03182131925._5
966+ let BId = $t03182131925._6
967+ let balA = $t03182131925._7
968+ let balB = $t03182131925._8
969+ let shareId = $t03182131925._9
970+ let bwAsset = $t03182131925._10
971+ let bwAmount = $t03182131925._11
908972 if ((size(i.payments) != 1))
909973 then throw("Wrong payment size")
910974 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
912976 else (i.payments[0].amount != bwAmount))
913977 then throw("Wrong payment")
914978 else {
915- let $t02875028874 = if ((AId == bwAsset))
979+ let $t03211532239 = if ((AId == bwAsset))
916980 then $Tuple2((pmtA + i.payments[0].amount), pmtB)
917981 else $Tuple2(pmtA, (pmtB + i.payments[0].amount))
918- let pmtAllA = $t02875028874._1
919- let pmtAllB = $t02875028874._2
982+ let pmtAllA = $t03211532239._1
983+ let pmtAllB = $t03211532239._2
920984 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
921- let $t02895629065 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
922- let userStaked = $t02895629065._1
923- let axlyFee = $t02895629065._2
985+ let $t03232132430 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
986+ let userStaked = $t03232132430._1
987+ let axlyFee = $t03232132430._2
924988 let posNum = getNewUserPositionNumber(pool, toString(i.caller))
925989 let borrowEntries = [IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAmount), bwAmount), StringEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAssetId), bwAsset)]
926- let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType)
990+ let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType, true)
927991 $Tuple2((((entries ++ getCursEntries(AId, BId, shareId)) ++ borrowEntries) :+ DeleteEntry((requestId + kRequestId))), userStaked)
928992 }
929993 }
931995
932996
933997 @Callable(i)
934-func withdraw (pool,posId) = {
935- let user = toString(i.caller)
936- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), "Unknown position")
937- let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest))
938- let poolInterst = getIntegerValue(this, (pool + kPoolInterest))
939- let poolTotalShare = getPoolTotalShare(pool)
940- let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterst - userInterest), SCALE10))
941- let userAddr = Address(fromBase58String(user))
942- let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAmount))
943- let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAssetId))
944- let debt = if ((borrowAmount > 0))
945- then {
946- let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + toString(posId)), borrowAsset], nil)
947- if ($isInstanceOf(@, "Int"))
948- then @
949- else throw(($getType(@) + " couldn't be cast to Int"))
950- }
951- else 0
952- let $t03054430697 = withdrawAmountCalc(pool, userCanWithdraw, debt, borrowAsset)
953- if (($t03054430697 == $t03054430697))
954- then {
955- let shareId = $t03054430697._7
956- let cBalBAfter = $t03054430697._6
957- let cBalAAfter = $t03054430697._5
958- let assetIdB = $t03054430697._4
959- let toUserAmountB = $t03054430697._3
960- let assetIdA = $t03054430697._2
961- let toUserAmountA = $t03054430697._1
962- let closeDbtInv = if ((debt > 0))
963- then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + toString(posId))], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
964- else 0
965- if ((closeDbtInv == closeDbtInv))
966- then ([DeleteEntry((((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), DeleteEntry((((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), (poolTotalShare - userCanWithdraw)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB))] ++ getCursEntries(assetIdA, assetIdB, shareId))
967- else throw("Strict value is not equal to itself.")
968- }
969- else throw("Strict value is not equal to itself.")
998+func withdraw (pool,posId) = withdrawToUser(toString(i.caller), pool, toString(posId), false)
999+
1000+
1001+
1002+@Callable(i)
1003+func createUpdateStopLoss (posId,poolId,assetId,price) = {
1004+ let tokenOraclePrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
1005+ if ($isInstanceOf(@, "(Int, Int)"))
1006+ then @
1007+ else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._1
1008+ if (!(isDefined(getInteger(this, (((((poolId + "_") + toString(i.caller)) + "_") + toString(posId)) + kUserPosition)))))
1009+ then throw("There are no user position")
1010+ else if ((0 >= price))
1011+ then throw("Price must be greater than 0")
1012+ else if ((price > tokenOraclePrice))
1013+ then throw("Price must be less than current token price")
1014+ else [IntegerEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss), price)]
9701015 }
1016+
1017+
1018+
1019+@Callable(i)
1020+func deleteStopLoss (posId,poolId,assetId) = if (!(isDefined(getInteger(this, (((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss)))))
1021+ then throw("No entry")
1022+ else [DeleteEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss))]
9711023
9721024
9731025
9801032
9811033
9821034 @Callable(i)
1035+func stopLoss (user,posId,pool,assetId) = {
1036+ let tokenOraclePrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
1037+ if ($isInstanceOf(@, "(Int, Int)"))
1038+ then @
1039+ else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._1
1040+ if (!(isDefined(getInteger(this, (((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)))))
1041+ then throw("No entry")
1042+ else (withdrawToUser(toString(i.caller), pool, toString(posId), true) :+ DeleteEntry((((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)))
1043+ }
1044+
1045+
1046+
1047+@Callable(i)
1048+func liquidate (user,posId,pool,liquidateAmount) = {
1049+ let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1050+ let $t03512135211 = getPoolData(Address(fromBase58String(pool)), pType)
1051+ let AId = $t03512135211._1
1052+ let BId = $t03512135211._2
1053+ let balA = $t03512135211._3
1054+ let balB = $t03512135211._4
1055+ let shareId = $t03512135211._5
1056+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), "Unknown position")
1057+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest))
1058+ let poolTotalShare = getPoolTotalShare(pool)
1059+ let userAddr = Address(fromBase58String(user))
1060+ let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAmount))
1061+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAssetId))
1062+ let $t03576536118 = if ((borrowAmount > 0))
1063+ then $Tuple2({
1064+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + toString(posId)), borrowAsset], nil)
1065+ if ($isInstanceOf(@, "Int"))
1066+ then @
1067+ else throw(($getType(@) + " couldn't be cast to Int"))
1068+ }, getIntegerValue(this, (pool + kPoolInterestLoan)))
1069+ else $Tuple2(0, getIntegerValue(this, (pool + kPoolInterestNoLoan)))
1070+ let debt = $t03576536118._1
1071+ let poolInterest = $t03576536118._2
1072+ let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
1073+ let sharePrice = getSharePrice([shareId])[0]
1074+ let borrowAssetPrice = getAssetsPrice([borrowAsset])[0]
1075+ let userCanWithdrawInD = fraction(userCanWithdraw, sharePrice, getAssetDecimals(shareId))
1076+ let borrowAmountInD = fraction(borrowAmount, borrowAssetPrice, getAssetPrecition(borrowAsset))
1077+ let userAmountInD = (userCanWithdrawInD - borrowAmountInD)
1078+ nil
1079+ }
1080+
1081+
1082+
1083+@Callable(i)
9831084 func capitalizeExKeeper (pool,type,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
984- let $t03204132235 = if (claim)
1085+ let $t03690337097 = if (claim)
9851086 then claimFarmed(type, pool)
9861087 else {
9871088 let claimedAsset = if ((type == SF_POOL))
9891090 else WXID
9901091 $Tuple2(amountToExchange, claimedAsset)
9911092 }
992- let claimedAmount = $t03204132235._1
993- let claimedAsset = $t03204132235._2
1093+ let claimedAmount = $t03690337097._1
1094+ let claimedAsset = $t03690337097._2
9941095 let exchangedAmount = exchangeKeeper(tokenToId, amountToExchange, claimedAsset, amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options)
9951096 let change = (claimedAmount - amountToExchange)
9961097 let changeEntry = if ((change > 0))
10021103
10031104
10041105 @Callable(i)
1005-func capitalizeExPazzle (pool,type,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = {
1006- let $t03289233086 = if (claim)
1106+func capitalizeExPuzzle (pool,type,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = {
1107+ let $t03775437948 = if (claim)
10071108 then claimFarmed(type, pool)
10081109 else {
10091110 let claimedAsset = if ((type == SF_POOL))
10111112 else WXID
10121113 $Tuple2(amountToExchange, claimedAsset)
10131114 }
1014- let claimedAmount = $t03289233086._1
1015- let claimedAsset = $t03289233086._2
1016- let exchangedAmount = exchangePazzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
1115+ let claimedAmount = $t03775437948._1
1116+ let claimedAsset = $t03775437948._2
1117+ let exchangedAmount = exchangePuzzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
10171118 let change = (claimedAmount - amountToExchange)
10181119 let changeEntry = if ((change > 0))
10191120 then [IntegerEntry((pool + kPoolCapChange), (change + valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)))]
10251126
10261127 @Callable(i)
10271128 func capitalizeExSwopFi (pool,type,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
1028- let $t03380934003 = if (claim)
1129+ let $t03867138865 = if (claim)
10291130 then claimFarmed(type, pool)
10301131 else {
10311132 let claimedAsset = if ((type == SF_POOL))
10331134 else WXID
10341135 $Tuple2(amountToExchange, claimedAsset)
10351136 }
1036- let claimedAmount = $t03380934003._1
1037- let claimedAsset = $t03380934003._2
1137+ let claimedAmount = $t03867138865._1
1138+ let claimedAsset = $t03867138865._2
10381139 let exchangedAmount = exchangeSwopFi(tokenToId, amountToExchange, claimedAsset, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options)
10391140 let change = (claimedAmount - amountToExchange)
10401141 let changeEntry = if ((change > 0))
10461147
10471148
10481149 @Callable(i)
1049-func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan) = if (if ((type != SF_POOL))
1150+func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan) = if (if ((type != SF_POOL))
10501151 then (type != WX_POOL)
10511152 else false)
10521153 then throw("Wrong type")
10531154 else {
1054- let $t03464834742 = getPoolData(Address(fromBase58String(poolAddr)), type)
1055- let aId = $t03464834742._1
1056- let bId = $t03464834742._2
1057- let aBal = $t03464834742._3
1058- let bBal = $t03464834742._4
1059- let shareId = $t03464834742._5
1060-[IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kPoolInterest), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr)]
1155+ let $t03955839652 = getPoolData(Address(fromBase58String(poolAddr)), type)
1156+ let aId = $t03955839652._1
1157+ let bId = $t03955839652._2
1158+ let aBal = $t03955839652._3
1159+ let bBal = $t03955839652._4
1160+ let shareId = $t03955839652._5
1161+[IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan), IntegerEntry((poolAddr + kPoolInterestLoan), 0), IntegerEntry((poolAddr + kPoolInterestNoLoan), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr)]
10611162 }
1163+
1164+
1165+
1166+@Callable(i)
1167+func capitalizeTest (pool,pType,tokenId,tokenAmount) = {
1168+ let poolAddr = Address(fromBase58String(pool))
1169+ let $t04044840527 = getPoolData(poolAddr, pType)
1170+ let AId = $t04044840527._1
1171+ let BId = $t04044840527._2
1172+ let balA = $t04044840527._3
1173+ let balB = $t04044840527._4
1174+ let shareId = $t04044840527._5
1175+ let $t04053040610 = if ((tokenId == AId))
1176+ then $Tuple2(tokenAmount, 0)
1177+ else $Tuple2(0, tokenAmount)
1178+ let pmtA = $t04053040610._1
1179+ let pmtB = $t04053040610._2
1180+ let $t04061340717 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1181+ let stakedAmount = $t04061340717._1
1182+ let nf = $t04061340717._2
1183+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
1184+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
1185+ let totalShareAmount = getPoolTotalShare(pool)
1186+ let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
1187+ let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
1188+ let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
1189+ let stakedNoLoan = (stakedAmount - stakedLoan)
1190+ let newInterestLoan = (curPoolInterestLoan + fraction(stakedLoan, SCALE10, totalShareAmountWithLoan))
1191+ let newInterestNoLoan = (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
1192+ let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
1193+ let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
1194+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (((totalShareAmount + stakedAmount) - axlyFeeLoan) - axlyFeeNoLoan)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
1195+ }
1196+
1197+
1198+
1199+@Callable(i)
1200+func claimFarmedTest (type,pool) = if ((type == SF_POOL))
1201+ then {
1202+ let balBefore = accountBalance(SWOPID)
1203+ if ((balBefore == balBefore))
1204+ then {
1205+ let inv = invoke(getSFFarmingAddr(), "claim", [pool], nil)
1206+ if ((inv == inv))
1207+ then {
1208+ let balAfter = accountBalance(SWOPID)
1209+ $Tuple2(nil, $Tuple2((balAfter - balBefore), SWOPID))
1210+ }
1211+ else throw("Strict value is not equal to itself.")
1212+ }
1213+ else throw("Strict value is not equal to itself.")
1214+ }
1215+ else if ((type == WX_POOL))
1216+ then {
1217+ let balBefore = accountBalance(WXID)
1218+ if ((balBefore == balBefore))
1219+ then {
1220+ let inv = invoke(getWXFarmingAddr(Address(fromBase58String(pool))), "claimWX", [pool], nil)
1221+ if ((inv == inv))
1222+ then {
1223+ let balAfter = accountBalance(WXID)
1224+ $Tuple2(nil, $Tuple2((balAfter - balBefore), WXID))
1225+ }
1226+ else throw("Strict value is not equal to itself.")
1227+ }
1228+ else throw("Strict value is not equal to itself.")
1229+ }
1230+ else throw("Wrong pool type")
10621231
10631232
10641233 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SF_POOL = "SF"
55
66 let WX_POOL = "WX"
77
88 let CAP_FEE_NO_LOAN = "capNoLoan"
99
1010 let CAP_FEE_LOAN = "capLoan"
1111
12-let CAP_FEE = "cap"
12+let STOPLOSS_FEE_NO_LOAN = "capNoLoan"
13+
14+let STOPLOSS_LOAN = "capLoan"
1315
1416 let LOAN_FEE = "loan"
1517
1618 let NO_LOAN_FEE = "noLoan"
19+
20+let NO_FEE = "noFee"
1721
1822 let SCALE8 = 100000000
1923
2024 let SCALE10 = 10000000000
2125
2226 let FEE_SCALE6 = 1000000
2327
2428 let kSFPoolAAssetBalance = "A_asset_balance"
2529
2630 let kSFPoolBAssetBalance = "B_asset_balance"
2731
2832 let kSFPoolAAssetId = "A_asset_id"
2933
3034 let kSFPoolBAssetId = "B_asset_id"
3135
3236 let kSFPoolShareId = "share_asset_id"
3337
3438 let kSFPoolShareSupply = "share_asset_supply"
3539
3640 let kSFPoolFee = "commission"
3741
3842 let kUserPosition = "_user_position"
3943
4044 let kUserBorrowAmount = "_user_position_borrow_amount"
4145
4246 let kUserBorrowAssetId = "_user_position_borrow_asset_id"
4347
4448 let kUserPositionNum = "_user_position_number"
4549
4650 let kUserPositionInterest = "_user_position_interest"
4751
4852 let kPoolTotal = "_pool_total"
4953
5054 let kPoolTotalLoan = "_pool_total_loan"
5155
52-let kPoolInterest = "_pool_interest"
56+let kPoolInterestLoan = "_pool_interest_loan"
57+
58+let kPoolInterestNoLoan = "_pool_interest_no_loan"
5359
5460 let kAxlyInFeeWithoutLoan = "_axly_fee_without_loan"
5561
5662 let kAxlyInFeeWithLoan = "_axly_fee_with_loan"
5763
5864 let kAxlyNoLoanCapFee = "_axly_fee_cap_with_loan"
5965
6066 let kAxlyWithLoanCapFee = "_axly_fee_cap_no_loan"
67+
68+let kAxlyStopLossNoLoanFee = "_axly_fee_stoploss_with_loan"
69+
70+let kAxlyStopLossLoanFee = "_axly_fee_stoploss_no_loan"
6171
6272 let kRequestId = "_request_id"
6373
6474 let kRequestIter = "requests_iter"
6575
6676 let kPool = "pool_"
6777
6878 let kSharePool = "_pool_share_id"
6979
7080 let kPoolCapChange = "_pool_cap_change"
7181
7282 let kTokenLastPrice = "_last_price"
83+
84+let kUserStopLoss = "_stop_loss"
7385
7486 let kMoneyBox = "axly_money_box"
7587
7688 let kSFFarmingAddr = "swopfi_farming_addr"
7789
7890 let kLendService = "lend_service_addr"
7991
8092 let kPriceOracle = "price_oracle"
8193
8294 let kExContract = "exchange_contract"
8395
8496 let kWxSwapContract = "wx_swap_contract"
8597
8698 let moneyBox = Address(fromBase58String(valueOrErrorMessage(getString(this, kMoneyBox), "No axly moneyBox address")))
8799
88100 let exContract = Address(fromBase58String(valueOrErrorMessage(getString(this, kExContract), "No exchange contract address")))
89101
90102 let priceOracleAddr = Address(fromBase58String(valueOrErrorMessage(getString(this, kPriceOracle), "No price oracle address")))
91103
92104 let wxSwapContract = Address(fromBase58String(valueOrErrorMessage(getString(this, kWxSwapContract), "No wx swap address")))
93105
94106 let SWOPID = base58'4W19ndijcc2CsQa9HGW2dfXKTVXhnneWWttxXrtjPmEp'
95107
96108 let WXID = base58'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc'
97109
98110 func isSelfCall (i) = if ((i.caller == this))
99111 then unit
100112 else throw("Only contract itself can call this function")
101113
102114
103115 func accountBalance (assetId) = match assetId {
104116 case id: ByteVector =>
105117 assetBalance(this, id)
106118 case waves: Unit =>
107119 wavesBalance(this).available
108120 case _ =>
109121 throw("Match error")
110122 }
111123
112124
113125 func getSFPoolData (poolAddr) = $Tuple5(valueOrErrorMessage(getString(poolAddr, kSFPoolAAssetId), "Can't get pool A asset id"), valueOrErrorMessage(getString(poolAddr, kSFPoolBAssetId), "Can't get pool B asset id"), valueOrErrorMessage(getInteger(poolAddr, kSFPoolAAssetBalance), "Can't get pool A asset balance"), valueOrErrorMessage(getInteger(poolAddr, kSFPoolBAssetBalance), "Can't get pool B asset balance"), valueOrErrorMessage(getString(poolAddr, kSFPoolShareId), "Can't get share asset id"))
114126
115127
116128 func getWXPoolData (poolAddr) = {
117129 let cfg = {
118130 let @ = invoke(poolAddr, "getPoolConfigWrapperREADONLY", nil, nil)
119131 if ($isInstanceOf(@, "List[Any]"))
120132 then @
121133 else throw(($getType(@) + " couldn't be cast to List[Any]"))
122134 }
123135 if ((cfg == cfg))
124136 then {
125137 let aId = valueOrErrorMessage({
126138 let @ = cfg[4]
127139 if ($isInstanceOf(@, "String"))
128140 then @
129141 else unit
130142 }, "Can't get pool A asset id")
131143 let bId = valueOrErrorMessage({
132144 let @ = cfg[5]
133145 if ($isInstanceOf(@, "String"))
134146 then @
135147 else unit
136148 }, "Can't get pool B asset id")
137149 let shareId = valueOrErrorMessage({
138150 let @ = cfg[3]
139151 if ($isInstanceOf(@, "String"))
140152 then @
141153 else unit
142154 }, "Can't get pool LP asset id")
143155 let balA = {
144156 let @ = invoke(poolAddr, "getAccBalanceWrapperREADONLY", [aId], nil)
145157 if ($isInstanceOf(@, "Int"))
146158 then @
147159 else throw(($getType(@) + " couldn't be cast to Int"))
148160 }
149161 if ((balA == balA))
150162 then {
151163 let balB = {
152164 let @ = invoke(poolAddr, "getAccBalanceWrapperREADONLY", [bId], nil)
153165 if ($isInstanceOf(@, "Int"))
154166 then @
155167 else throw(($getType(@) + " couldn't be cast to Int"))
156168 }
157169 if ((balB == balB))
158170 then $Tuple5(aId, bId, balA, balB, shareId)
159171 else throw("Strict value is not equal to itself.")
160172 }
161173 else throw("Strict value is not equal to itself.")
162174 }
163175 else throw("Strict value is not equal to itself.")
164176 }
165177
166178
167179 func getPoolData (poolAddr,type) = if ((type == SF_POOL))
168180 then getSFPoolData(poolAddr)
169181 else if ((type == WX_POOL))
170182 then getWXPoolData(poolAddr)
171183 else throw("Wrong pool type")
172184
173185
174186 func getShareSupply (poolAddr,type,shareId) = if ((type == SF_POOL))
175187 then valueOrErrorMessage(getInteger(poolAddr, kSFPoolShareSupply), "Can't get share asset supply")
176188 else if ((type == WX_POOL))
177189 then valueOrErrorMessage(assetInfo(fromBase58String(shareId)), "Wrong ShareId").quantity
178190 else throw("Wrong pool type")
179191
180192
181193 func getPoolTotalShare (pool) = valueOrElse(getInteger(this, (pool + kPoolTotal)), 0)
182194
183195
184196 func getPoolTotalShareWithLoan (pool) = valueOrElse(getInteger(this, (pool + kPoolTotalLoan)), 0)
185197
186198
187199 func getNewUserPositionNumber (pool,user) = (valueOrElse(getInteger(this, (((pool + "_") + user) + kUserPositionNum)), 0) + 1)
188200
189201
190202 func getAxlyFee (pool,feeType) = if ((feeType == CAP_FEE_LOAN))
191203 then getIntegerValue(this, (pool + kAxlyWithLoanCapFee))
192204 else if ((feeType == CAP_FEE_NO_LOAN))
193205 then getIntegerValue(this, (pool + kAxlyNoLoanCapFee))
194206 else if ((feeType == LOAN_FEE))
195207 then getIntegerValue(this, (pool + kAxlyInFeeWithLoan))
196208 else if ((feeType == NO_LOAN_FEE))
197209 then getIntegerValue(this, (pool + kAxlyInFeeWithoutLoan))
198210 else throw("Wrong fee type")
199211
200212
201213 func getSFFarmingAddr () = Address(fromBase58String(valueOrErrorMessage(getString(this, kSFFarmingAddr), "Can't get swopfi farming addr")))
202214
203215
204216 func getWXFarmingAddr (poolAddr) = {
205217 let fContract = Address(fromBase58String(valueOrErrorMessage(getString(poolAddr, "%s__factoryContract"), "Can't get WX factory contract addr")))
206218 let factroyCfg = split(valueOrErrorMessage(getString(fContract, "%s__factoryConfig"), "Can't get WX factory cfg"), "__")
207219 Address(fromBase58String(factroyCfg[1]))
208220 }
209221
210222
211223 func getLendSrvAddr () = Address(fromBase58String(valueOrErrorMessage(getString(this, kLendService), "Can't get lend service addr")))
212224
213225
214226 func assetIdToStr (assetId) = match assetId {
215227 case id: ByteVector =>
216228 toBase58String(id)
217229 case waves: Unit =>
218230 "WAVES"
219231 case _ =>
220232 throw("Match error")
221233 }
222234
223235
224236 func assetIdFromStr (assetId) = if ((assetId == "WAVES"))
225237 then unit
226238 else fromBase58String(assetId)
227239
228240
229241 func getAssetDecimals (assetId) = if ((assetId == "WAVES"))
230242 then 8
231243 else match assetInfo(fromBase58String(assetId)) {
232244 case asset: Asset =>
233245 asset.decimals
234246 case _ =>
235247 throw("Can't find asset")
236248 }
237249
238250
251+func getAssetPrecition (assetId) = pow(10, 0, getAssetDecimals(assetId), 0, 0, DOWN)
252+
253+
239254 func getAssetsPrice (assetIds) = {
240255 func getPrices (a,assetId) = {
241256 let assetPrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
242257 if ($isInstanceOf(@, "(Int, Int)"))
243258 then @
244259 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
245260 (a :+ assetPrice)
246261 }
247262
248263 let $l = assetIds
249264 let $s = size($l)
250265 let $acc0 = nil
251266 func $f0_1 ($a,$i) = if (($i >= $s))
252267 then $a
253268 else getPrices($a, $l[$i])
254269
255270 func $f0_2 ($a,$i) = if (($i >= $s))
256271 then $a
257272 else throw("List size exceeds 100")
258273
259274 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
260275 }
261276
262277
263278 func getSharePrice (shareIds) = {
264279 func getPrices (a,shareId) = {
265280 let pool = valueOrErrorMessage(getString(this, (shareId + kSharePool)), "Can't find pool addr by share id")
266281 let poolAddr = Address(fromBase58String(pool))
267282 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
268- let $t077377802 = getPoolData(poolAddr, pType)
269- let aId = $t077377802._1
270- let bId = $t077377802._2
271- let aBalance = $t077377802._3
272- let bBalance = $t077377802._4
283+ let $t082848349 = getPoolData(poolAddr, pType)
284+ let aId = $t082848349._1
285+ let bId = $t082848349._2
286+ let aBalance = $t082848349._3
287+ let bBalance = $t082848349._4
273288 let dPriceA = ( let @ = invoke(priceOracleAddr, "getTWAP60", [aId, false], nil)
274289 if ($isInstanceOf(@, "(Int, Int)"))
275290 then @
276291 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
277292 let dPriceB = ( let @ = invoke(priceOracleAddr, "getTWAP60", [bId, false], nil)
278293 if ($isInstanceOf(@, "(Int, Int)"))
279294 then @
280295 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
281296 let shareSupply = getShareSupply(poolAddr, pType, shareId)
282297 let APrecision = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
283298 let BPrecision = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
284299 let sharePrecision = pow(10, 0, getAssetDecimals(shareId), 0, 0, DOWN)
285300 let sum = (fraction(aBalance, dPriceA, APrecision) + fraction(bBalance, dPriceB, BPrecision))
286301 let sharePrice = fraction(sum, sharePrecision, shareSupply)
287302 (a :+ sharePrice)
288303 }
289304
290305 let $l = shareIds
291306 let $s = size($l)
292307 let $acc0 = nil
293308 func $f0_1 ($a,$i) = if (($i >= $s))
294309 then $a
295310 else getPrices($a, $l[$i])
296311
297312 func $f0_2 ($a,$i) = if (($i >= $s))
298313 then $a
299314 else throw("List size exceeds 50")
300315
301316 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
302317 }
303318
304319
305320 func getCursEntries (aId,bId,shareId) = {
306321 let assetsPrices = getAssetsPrice([aId, bId])
307322 let sharePrice = getSharePrice([shareId])
308323 [IntegerEntry((aId + kTokenLastPrice), assetsPrices[0]), IntegerEntry((bId + kTokenLastPrice), assetsPrices[1]), IntegerEntry((shareId + kTokenLastPrice), sharePrice[0])]
309324 }
310325
311326
312327 func replenishSwopFi (pool,feeType,pmtA,pmtAssetA,pmtB,pmtAssetB,balA,balB,shareId) = {
313328 let shareBalanceBefore = accountBalance(fromBase58String(shareId))
314329 if ((shareBalanceBefore == shareBalanceBefore))
315330 then {
316331 let poolAddr = Address(fromBase58String(pool))
317332 let ratioA = fraction(SCALE8, pmtA, balA)
318333 let ratioB = fraction(SCALE8, pmtB, balB)
319- let $t093079599 = if ((ratioB > ratioA))
334+ let $t0985410146 = if ((ratioB > ratioA))
320335 then {
321336 let pmt = fraction(balB, ratioA, SCALE8, CEILING)
322337 $Tuple4(pmtA, pmt, (pmtB - pmt), pmtAssetB)
323338 }
324339 else {
325340 let pmt = fraction(balA, ratioB, SCALE8, CEILING)
326341 $Tuple4(pmt, pmtB, (pmtA - pmt), pmtAssetA)
327342 }
328- let pmtAmountA = $t093079599._1
329- let pmtAmountB = $t093079599._2
330- let change = $t093079599._3
331- let changeAssetId = $t093079599._4
343+ let pmtAmountA = $t0985410146._1
344+ let pmtAmountB = $t0985410146._2
345+ let change = $t0985410146._3
346+ let changeAssetId = $t0985410146._4
332347 let inv1 = if (if ((pmtAmountA > 0))
333348 then (pmtAmountB > 0)
334349 else false)
335350 then {
336351 let payments = [AttachedPayment(assetIdFromStr(pmtAssetA), pmtAmountA), AttachedPayment(assetIdFromStr(pmtAssetB), pmtAmountB)]
337352 invoke(poolAddr, "callFunction", ["replenishWithTwoTokens", ["false", "0"]], payments)
338353 }
339354 else 0
340355 if ((inv1 == inv1))
341356 then {
342357 let inv2 = if ((change > 0))
343358 then {
344359 let payments = [AttachedPayment(assetIdFromStr(changeAssetId), change)]
345360 let vars = ["0", "false", "0"]
346361 invoke(poolAddr, "callFunction", ["replenishWithOneToken", vars], payments)
347362 }
348363 else 0
349364 if ((inv2 == inv2))
350365 then {
351366 let shareBalanceAfter = accountBalance(fromBase58String(shareId))
352367 let totalStaked = (shareBalanceAfter - shareBalanceBefore)
353- let axlyFeeAmount = if ((feeType == CAP_FEE))
354- then fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
355- else fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
368+ let axlyFeeAmount = fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
356369 let userShareForStake = (totalStaked - axlyFeeAmount)
357370 if ((0 >= userShareForStake))
358371 then throw("amount of staked sharetokens must be > 0")
359372 else {
360373 let inv3 = invoke(getSFFarmingAddr(), "lockShareTokens", [pool, 0], [AttachedPayment(fromBase58String(shareId), userShareForStake)])
361374 if ((inv3 == inv3))
362375 then $Tuple2(userShareForStake, axlyFeeAmount)
363376 else throw("Strict value is not equal to itself.")
364377 }
365378 }
366379 else throw("Strict value is not equal to itself.")
367380 }
368381 else throw("Strict value is not equal to itself.")
369382 }
370383 else throw("Strict value is not equal to itself.")
371384 }
372385
373386
374387 func replenishWX (pool,feeType,pmtA,pmtAssetA,pmtB,pmtAssetB,shareId) = {
375388 let poolAddr = Address(fromBase58String(pool))
376- let $t01116412013 = if (if ((pmtA > 0))
389+ let $t01159712446 = if (if ((pmtA > 0))
377390 then (pmtB > 0)
378391 else false)
379392 then {
380393 let evalPutInA = split({
381394 let @ = invoke(poolAddr, "evaluatePutByAmountAssetREADONLY", [pmtA], nil)
382395 if ($isInstanceOf(@, "String"))
383396 then @
384397 else throw(($getType(@) + " couldn't be cast to String"))
385398 }, "__")
386399 if ((evalPutInA == evalPutInA))
387400 then {
388401 let evalPutInB = split({
389402 let @ = invoke(poolAddr, "evaluatePutByPriceAssetREADONLY", [pmtB], nil)
390403 if ($isInstanceOf(@, "String"))
391404 then @
392405 else throw(($getType(@) + " couldn't be cast to String"))
393406 }, "__")
394407 if ((evalPutInB == evalPutInB))
395408 then {
396409 let lpInA = parseIntValue(evalPutInA[1])
397410 let lpInB = parseIntValue(evalPutInB[1])
398411 if ((lpInB > lpInA))
399412 then {
400413 let pmtInB = parseIntValue(evalPutInA[8])
401414 $Tuple4(pmtA, pmtInB, (pmtB - pmtInB), pmtAssetB)
402415 }
403416 else {
404417 let pmtInA = parseIntValue(evalPutInB[7])
405418 $Tuple4(pmtInA, pmtB, (pmtA - pmtInA), pmtAssetA)
406419 }
407420 }
408421 else throw("Strict value is not equal to itself.")
409422 }
410423 else throw("Strict value is not equal to itself.")
411424 }
412425 else if ((pmtA > 0))
413426 then $Tuple4(pmtA, pmtB, pmtA, pmtAssetA)
414427 else if ((pmtB > 0))
415428 then $Tuple4(pmtA, pmtB, pmtB, pmtAssetB)
416429 else throw("pmts must be > 0")
417- let pmtAmountA = $t01116412013._1
418- let pmtAmountB = $t01116412013._2
419- let change = $t01116412013._3
420- let changeAssetId = $t01116412013._4
430+ let pmtAmountA = $t01159712446._1
431+ let pmtAmountB = $t01159712446._2
432+ let change = $t01159712446._3
433+ let changeAssetId = $t01159712446._4
421434 let shareBalanceBefore = accountBalance(fromBase58String(shareId))
422435 if ((shareBalanceBefore == shareBalanceBefore))
423436 then {
424437 let inv1 = if (if ((pmtAmountA > 0))
425438 then (pmtAmountB > 0)
426439 else false)
427440 then {
428441 let payments = [AttachedPayment(assetIdFromStr(pmtAssetA), pmtAmountA), AttachedPayment(assetIdFromStr(pmtAssetB), pmtAmountB)]
429442 invoke(poolAddr, "put", [1000000, false], payments)
430443 }
431444 else 0
432445 if ((inv1 == inv1))
433446 then {
434447 let inv2 = if ((change > 0))
435448 then {
436449 let payments = [AttachedPayment(assetIdFromStr(changeAssetId), change)]
437450 invoke(poolAddr, "putOneTkn", [0, false], payments)
438451 }
439452 else 0
440453 if ((inv2 == inv2))
441454 then {
442455 let shareBalanceAfter = accountBalance(fromBase58String(shareId))
443456 let totalStaked = (shareBalanceAfter - shareBalanceBefore)
444457 let axlyFeeAmount = fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
445458 let userShareForStake = (totalStaked - axlyFeeAmount)
446459 if ((0 >= userShareForStake))
447460 then throw("amount of staked sharetokens must be > 0")
448461 else {
449462 let inv3 = invoke(getWXFarmingAddr(poolAddr), "stake", nil, [AttachedPayment(fromBase58String(shareId), userShareForStake)])
450463 if ((inv3 == inv3))
451464 then $Tuple2(userShareForStake, axlyFeeAmount)
452465 else throw("Strict value is not equal to itself.")
453466 }
454467 }
455468 else throw("Strict value is not equal to itself.")
456469 }
457470 else throw("Strict value is not equal to itself.")
458471 }
459472 else throw("Strict value is not equal to itself.")
460473 }
461474
462475
463476 func replenishByType (type,pool,feeType,pmtA,AId,pmtB,BId,balA,balB,shareId) = if ((type == SF_POOL))
464477 then replenishSwopFi(pool, feeType, pmtA, AId, pmtB, BId, balA, balB, shareId)
465478 else if ((type == WX_POOL))
466479 then replenishWX(pool, feeType, pmtA, AId, pmtB, BId, shareId)
467480 else throw("Wrong pool type")
468481
469482
470-func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type) = {
483+func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type,withLoan) = {
471484 let totalAmount = getPoolTotalShare(pool)
472485 let totalAmountLoan = getPoolTotalShareWithLoan(pool)
473- let curPoolInterest = getIntegerValue(this, (pool + kPoolInterest))
486+ let $t01446414702 = if (withLoan)
487+ then $Tuple2(getIntegerValue(this, (pool + kPoolInterestLoan)), (totalAmountLoan + stakedAmount))
488+ else $Tuple2(getIntegerValue(this, (pool + kPoolInterestNoLoan)), totalAmountLoan)
489+ let curPoolInterest = $t01446414702._1
490+ let totalStakedWithLoan = $t01446414702._2
474491 [IntegerEntry((pool + kPoolTotal), (totalAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), (totalAmountLoan + stakedAmount)), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPosition), stakedAmount), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPositionInterest), curPoolInterest), IntegerEntry((((pool + "_") + user) + kUserPositionNum), posNum), ScriptTransfer(moneyBox, axlyFeeAmount, fromBase58String(shareId))]
475492 }
476493
477494
478495 func claimFarmed (type,pool) = if ((type == SF_POOL))
479496 then {
480497 let balBefore = accountBalance(SWOPID)
481498 if ((balBefore == balBefore))
482499 then {
483500 let inv = invoke(getSFFarmingAddr(), "claim", [pool], nil)
484501 if ((inv == inv))
485502 then {
486503 let balAfter = accountBalance(SWOPID)
487504 $Tuple2((balAfter - balBefore), SWOPID)
488505 }
489506 else throw("Strict value is not equal to itself.")
490507 }
491508 else throw("Strict value is not equal to itself.")
492509 }
493510 else if ((type == WX_POOL))
494511 then {
495512 let balBefore = accountBalance(WXID)
496513 if ((balBefore == balBefore))
497514 then {
498515 let inv = invoke(getWXFarmingAddr(Address(fromBase58String(pool))), "claimWX", [pool], nil)
499516 if ((inv == inv))
500517 then {
501518 let balAfter = accountBalance(WXID)
502519 $Tuple2((balAfter - balBefore), WXID)
503520 }
504521 else throw("Strict value is not equal to itself.")
505522 }
506523 else throw("Strict value is not equal to itself.")
507524 }
508525 else throw("Wrong pool type")
509526
510527
511528 func exchangeKeeper (toToken,pmtAmount,pmtAsset,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
512529 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
513530 if ((tokenBalanceBefore == tokenBalanceBefore))
514531 then {
515532 let inv = invoke(exContract, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [AttachedPayment(pmtAsset, pmtAmount)])
516533 if ((inv == inv))
517534 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
518535 else throw("Strict value is not equal to itself.")
519536 }
520537 else throw("Strict value is not equal to itself.")
521538 }
522539
523540
524-func exchangePazzle (toToken,pmtAmount,pmtAsset,routesStr,minToReceive,options) = {
541+func exchangePuzzle (toToken,pmtAmount,pmtAsset,routesStr,minToReceive,options) = {
525542 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
526543 if ((tokenBalanceBefore == tokenBalanceBefore))
527544 then {
528545 let inv = invoke(exContract, "puzzleSwap", [routesStr, minToReceive, options], [AttachedPayment(pmtAsset, pmtAmount)])
529546 if ((inv == inv))
530547 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
531548 else throw("Strict value is not equal to itself.")
532549 }
533550 else throw("Strict value is not equal to itself.")
534551 }
535552
536553
537554 func exchangeSwopFi (toToken,pmtAmount,pmtAsset,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
538555 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
539556 if ((tokenBalanceBefore == tokenBalanceBefore))
540557 then {
541558 let inv = invoke(exContract, "swopfiSwap", [exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options], [AttachedPayment(pmtAsset, pmtAmount)])
542559 if ((inv == inv))
543560 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
544561 else throw("Strict value is not equal to itself.")
545562 }
546563 else throw("Strict value is not equal to itself.")
547564 }
548565
549566
550567 func capitalize (pool,pType,tokenId,tokenAmount) = {
551568 let poolAddr = Address(fromBase58String(pool))
552- let $t01697517054 = getPoolData(poolAddr, pType)
553- let AId = $t01697517054._1
554- let BId = $t01697517054._2
555- let balA = $t01697517054._3
556- let balB = $t01697517054._4
557- let shareId = $t01697517054._5
558- let $t01705717137 = if ((tokenId == AId))
569+ let $t01760117680 = getPoolData(poolAddr, pType)
570+ let AId = $t01760117680._1
571+ let BId = $t01760117680._2
572+ let balA = $t01760117680._3
573+ let balB = $t01760117680._4
574+ let shareId = $t01760117680._5
575+ let $t01768317763 = if ((tokenId == AId))
559576 then $Tuple2(tokenAmount, 0)
560577 else $Tuple2(0, tokenAmount)
561- let pmtA = $t01705717137._1
562- let pmtB = $t01705717137._2
563- let $t01714017250 = replenishByType(pType, pool, CAP_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
564- let stakedAmount = $t01714017250._1
565- let axlyFee = $t01714017250._2
566- let curPoolInterest = valueOrElse(getInteger(this, (pool + kPoolInterest)), 0)
578+ let pmtA = $t01768317763._1
579+ let pmtB = $t01768317763._2
580+ let $t01776617870 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
581+ let stakedAmount = $t01776617870._1
582+ let nf = $t01776617870._2
583+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
584+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
567585 let totalShareAmount = getPoolTotalShare(pool)
568- let newInterest = (curPoolInterest + fraction(stakedAmount, SCALE10, totalShareAmount))
569- ([IntegerEntry((pool + kPoolInterest), newInterest), ScriptTransfer(moneyBox, axlyFee, fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
586+ let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
587+ let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
588+ let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
589+ let stakedNoLoan = (stakedAmount - stakedLoan)
590+ let newInterestLoan = (curPoolInterestLoan + fraction(stakedLoan, SCALE10, totalShareAmountWithLoan))
591+ let newInterestNoLoan = (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
592+ let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
593+ let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
594+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (((totalShareAmount + stakedAmount) - axlyFeeLoan) - axlyFeeNoLoan)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
570595 }
571596
572597
573598 func exchangeDirectlySF (pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = {
574599 let poolAddr = Address(fromBase58String(pool))
575600 let feeScale6 = 1000000
576601 let fee = getIntegerValue(poolAddr, kSFPoolFee)
577602 let amntGetNoFee = fraction(amountTokenToGet, feeScale6, (feeScale6 - fee))
578- let $t01798018268 = if ((assetTokenToGet == assetIdA))
603+ let $t01955819846 = if ((assetTokenToGet == assetIdA))
579604 then {
580605 let amountToPay = fraction(balA, amntGetNoFee, (balB - amntGetNoFee))
581606 $Tuple2(amountToPay, assetIdB)
582607 }
583608 else {
584609 let amountToPay = fraction(balB, amntGetNoFee, (balA - amntGetNoFee))
585610 $Tuple2(amountToPay, assetIdA)
586611 }
587- let amountToPay = $t01798018268._1
588- let assetToPay = $t01798018268._2
612+ let amountToPay = $t01955819846._1
613+ let assetToPay = $t01955819846._2
589614 invoke(poolAddr, "callFunction", ["exchange", ["1"]], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
590615 }
591616
592617
593618 func exchangeDirectlyWX (pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = {
594619 let poolAddr = Address(fromBase58String(pool))
595620 let prFee = getIntegerValue(wxSwapContract, "%s__protocolFee")
596621 let pFee = getIntegerValue(wxSwapContract, "%s__poolFee")
597622 let feeScale = toBigInt(100000000)
598- let $t01874719055 = if ((assetTokenToGet == assetIdA))
623+ let $t02032520633 = if ((assetTokenToGet == assetIdA))
599624 then {
600625 let amountToPay = fraction(balA, amountTokenToGet, (balB - amountTokenToGet))
601626 $Tuple2(amountToPay, assetIdB)
602627 }
603628 else {
604629 let amountToPay = fraction(balB, amountTokenToGet, (balA - amountTokenToGet))
605630 $Tuple2(amountToPay, assetIdA)
606631 }
607- let amountToPay = $t01874719055._1
608- let assetToPay = $t01874719055._2
632+ let amountToPay = $t02032520633._1
633+ let assetToPay = $t02032520633._2
609634 let amountToPayWithFee = toInt(fraction(toBigInt(amountToPay), feeScale, (feeScale - toBigInt((prFee + pFee)))))
610635 invoke(wxSwapContract, "swap", [1, assetTokenToGet, toString(this)], [AttachedPayment(assetIdFromStr(assetToPay), amountToPayWithFee)])
611636 }
612637
613638
614639 func exchangeDirectly (type,pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = if ((type == SF_POOL))
615640 then exchangeDirectlySF(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
616641 else exchangeDirectlyWX(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
617642
618643
619644 func withdrawAmountCalc (pool,userCanWithdraw,debt,borrowAsset) = {
620645 let poolAddr = Address(fromBase58String(pool))
621646 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
622- let $t01992019996 = getPoolData(poolAddr, pType)
623- let assetIdA = $t01992019996._1
624- let assetIdB = $t01992019996._2
625- let balA = $t01992019996._3
626- let balB = $t01992019996._4
627- let shareId = $t01992019996._5
647+ let $t02149821574 = getPoolData(poolAddr, pType)
648+ let assetIdA = $t02149821574._1
649+ let assetIdB = $t02149821574._2
650+ let balA = $t02149821574._3
651+ let balB = $t02149821574._4
652+ let shareId = $t02149821574._5
628653 let cBalABefore = accountBalance(assetIdFromStr(assetIdA))
629654 if ((cBalABefore == cBalABefore))
630655 then {
631656 let cBalBBefore = accountBalance(assetIdFromStr(assetIdB))
632657 if ((cBalBBefore == cBalBBefore))
633658 then {
634659 let inv = if ((pType == SF_POOL))
635660 then invoke(poolAddr, "callFunction", ["withdraw", [toString(userCanWithdraw)]], nil)
636661 else if ((pType == WX_POOL))
637662 then invoke(poolAddr, "unstakeAndGet", [userCanWithdraw], nil)
638663 else throw("Wrong position type")
639664 if ((inv == inv))
640665 then {
641666 let cBalAAfter = accountBalance(assetIdFromStr(assetIdA))
642667 let cBalBAfter = accountBalance(assetIdFromStr(assetIdB))
643- let $t02050820597 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
644- let tokensAmountA = $t02050820597._1
645- let tokensAmountB = $t02050820597._2
646- let $t02060021296 = if ((debt > 0))
668+ let $t02208622175 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
669+ let tokensAmountA = $t02208622175._1
670+ let tokensAmountB = $t02208622175._2
671+ let $t02217822874 = if ((debt > 0))
647672 then {
648673 let amountToGetEx = if (if ((borrowAsset == assetIdA))
649674 then (debt > tokensAmountA)
650675 else false)
651676 then (debt - tokensAmountA)
652677 else if (if ((borrowAsset == assetIdB))
653678 then (debt > tokensAmountB)
654679 else false)
655680 then (debt - tokensAmountB)
656681 else 0
657682 let exInv = if ((amountToGetEx > 0))
658683 then exchangeDirectly(pType, pool, assetIdA, assetIdB, balA, balB, amountToGetEx, borrowAsset)
659684 else 0
660685 if ((exInv == exInv))
661686 then {
662687 let cBalAAfterRepay = accountBalance(assetIdFromStr(assetIdA))
663688 let cBalBAfterRepay = accountBalance(assetIdFromStr(assetIdB))
664689 $Tuple2((cBalAAfterRepay - cBalABefore), (cBalBAfterRepay - cBalBBefore))
665690 }
666691 else throw("Strict value is not equal to itself.")
667692 }
668693 else $Tuple2(tokensAmountA, tokensAmountB)
669- let toUserAmountA = $t02060021296._1
670- let toUserAmountB = $t02060021296._2
694+ let toUserAmountA = $t02217822874._1
695+ let toUserAmountB = $t02217822874._2
671696 $Tuple7(toUserAmountA, assetIdA, toUserAmountB, assetIdB, cBalAAfter, cBalBAfter, shareId)
672697 }
673698 else throw("Strict value is not equal to itself.")
674699 }
700+ else throw("Strict value is not equal to itself.")
701+ }
702+ else throw("Strict value is not equal to itself.")
703+ }
704+
705+
706+func withdrawToUser (user,pool,posId,stopLoss) = {
707+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
708+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
709+ let poolTotalShare = getPoolTotalShare(pool)
710+ let userAddr = Address(fromBase58String(user))
711+ let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount))
712+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
713+ let $t02355823900 = if ((borrowAmount > 0))
714+ then $Tuple2({
715+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + posId), borrowAsset], nil)
716+ if ($isInstanceOf(@, "Int"))
717+ then @
718+ else throw(($getType(@) + " couldn't be cast to Int"))
719+ }, getIntegerValue(this, (pool + kPoolInterestLoan)))
720+ else $Tuple2(0, getIntegerValue(this, (pool + kPoolInterestNoLoan)))
721+ let debt = $t02355823900._1
722+ let poolInterest = $t02355823900._2
723+ let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
724+ let $t02399924152 = withdrawAmountCalc(pool, userCanWithdraw, debt, borrowAsset)
725+ if (($t02399924152 == $t02399924152))
726+ then {
727+ let shareId = $t02399924152._7
728+ let cBalBAfter = $t02399924152._6
729+ let cBalAAfter = $t02399924152._5
730+ let assetIdB = $t02399924152._4
731+ let toUserAmountB = $t02399924152._3
732+ let assetIdA = $t02399924152._2
733+ let toUserAmountA = $t02399924152._1
734+ let closeDbtInv = if ((debt > 0))
735+ then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
736+ else 0
737+ if ((closeDbtInv == closeDbtInv))
738+ then ([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), (poolTotalShare - userCanWithdraw)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB))] ++ getCursEntries(assetIdA, assetIdB, shareId))
675739 else throw("Strict value is not equal to itself.")
676740 }
677741 else throw("Strict value is not equal to itself.")
678742 }
679743
680744
681745 func parseRequest (requestId) = {
682746 let request = split(valueOrErrorMessage(getString(this, (requestId + kRequestId)), ("No request with id " + requestId)), ",")
683747 let user = request[0]
684748 let pool = request[1]
685749 let pmtA = parseIntValue(request[2])
686750 let AId = request[3]
687751 let pmtB = parseIntValue(request[4])
688752 let BId = request[5]
689753 let balA = parseIntValue(request[6])
690754 let balB = parseIntValue(request[7])
691755 let shareId = request[8]
692756 let bwAsset = request[9]
693757 let bwAmount = parseIntValue(request[10])
694758 $Tuple11(user, pool, pmtA, AId, pmtB, BId, balA, balB, shareId, bwAsset, bwAmount)
695759 }
696760
697761
698762 @Callable(i)
699763 func replenishEVALONLY (pool,leverage,borrowAssetId) = if (if ((100 > leverage))
700764 then true
701765 else (leverage > 300))
702766 then throw("Leverage can't be <100 and >300")
703767 else {
704768 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
705- let $t02228422374 = getPoolData(Address(fromBase58String(pool)), pType)
706- let AId = $t02228422374._1
707- let BId = $t02228422374._2
708- let balA = $t02228422374._3
709- let balB = $t02228422374._4
710- let shareId = $t02228422374._5
711- let $t02237723014 = if ((size(i.payments) == 2))
769+ let $t02564225732 = getPoolData(Address(fromBase58String(pool)), pType)
770+ let AId = $t02564225732._1
771+ let BId = $t02564225732._2
772+ let balA = $t02564225732._3
773+ let balB = $t02564225732._4
774+ let shareId = $t02564225732._5
775+ let $t02573526372 = if ((size(i.payments) == 2))
712776 then if ((assetIdToStr(i.payments[0].assetId) != AId))
713777 then throw("Wrong payment asset A")
714778 else if ((assetIdToStr(i.payments[1].assetId) != BId))
715779 then throw("Wrong payment asset B")
716780 else $Tuple4(i.payments[0].amount, AId, i.payments[1].amount, BId)
717781 else if ((size(i.payments) == 1))
718782 then if ((assetIdToStr(i.payments[0].assetId) == AId))
719783 then $Tuple4(i.payments[0].amount, AId, 0, BId)
720784 else if ((assetIdToStr(i.payments[0].assetId) == BId))
721785 then $Tuple4(0, AId, i.payments[0].amount, BId)
722786 else throw("Wrong payment")
723787 else throw("One or two payments expected")
724- let pmtA = $t02237723014._1
725- let pmtAssetA = $t02237723014._2
726- let pmtB = $t02237723014._3
727- let pmtAssetB = $t02237723014._4
728- let $t02301724468 = if ((leverage > 100))
788+ let pmtA = $t02573526372._1
789+ let pmtAssetA = $t02573526372._2
790+ let pmtB = $t02573526372._3
791+ let pmtAssetB = $t02573526372._4
792+ let $t02637527826 = if ((leverage > 100))
729793 then {
730794 let dPriceA = ( let @ = invoke(priceOracleAddr, "getTWAP60", [pmtAssetA, false], nil)
731795 if ($isInstanceOf(@, "(Int, Int)"))
732796 then @
733797 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
734798 let dPriceB = ( let @ = invoke(priceOracleAddr, "getTWAP60", [pmtAssetB, false], nil)
735799 if ($isInstanceOf(@, "(Int, Int)"))
736800 then @
737801 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
738802 let paydInDollar = (fraction(dPriceA, pmtA, pow(10, 0, getAssetDecimals(pmtAssetA), 0, 0, DOWN)) + fraction(dPriceB, pmtB, pow(10, 0, getAssetDecimals(pmtAssetB), 0, 0, DOWN)))
739803 let borrowAmount = fraction(paydInDollar, (leverage - 100), 100)
740804 let request = makeString([toString(i.caller), pool, toString(pmtA), pmtAssetA, toString(pmtB), pmtAssetB, toString(balA), toString(balB), shareId, borrowAssetId, toString(borrowAmount), toString(1)], ",")
741805 let newRequestId = {
742806 let @ = invoke(this, "createNewRequest", [request], nil)
743807 if ($isInstanceOf(@, "Int"))
744808 then @
745809 else throw(($getType(@) + " couldn't be cast to Int"))
746810 }
747811 if ((newRequestId == newRequestId))
748812 then {
749813 let args = [((toString(i.caller) + "_") + toString(1)), shareId, borrowAssetId, borrowAmount, toString(this), "replenishFromLandEVALONLY", toString(valueOrErrorMessage(newRequestId, "Can't create new request"))]
750814 let inv = reentrantInvoke(getLendSrvAddr(), "flashPosition", args, nil)
751815 if ((inv == inv))
752816 then $Tuple2(getIntegerValue(this, "EVALONLY_STAKEDAMOUNT"), borrowAmount)
753817 else throw("Strict value is not equal to itself.")
754818 }
755819 else throw("Strict value is not equal to itself.")
756820 }
757821 else $Tuple2(replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)._1, 0)
758- let userStaked = $t02301724468._1
759- let borrowAmount = $t02301724468._2
760- let $t02447224639 = withdrawAmountCalc(pool, userStaked, borrowAmount, borrowAssetId)
761- if (($t02447224639 == $t02447224639))
822+ let userStaked = $t02637527826._1
823+ let borrowAmount = $t02637527826._2
824+ let $t02783027997 = withdrawAmountCalc(pool, userStaked, borrowAmount, borrowAssetId)
825+ if (($t02783027997 == $t02783027997))
762826 then {
763- let userGetBBeforeRepay = $t02447224639._6
764- let userGetABeforeRepay = $t02447224639._5
765- let assetIdB = $t02447224639._4
766- let toUserAmountB = $t02447224639._3
767- let assetIdA = $t02447224639._2
768- let toUserAmountA = $t02447224639._1
769- let $t02464224757 = getPoolData(Address(fromBase58String(pool)), pType)
770- let AIdAfter = $t02464224757._1
771- let BIdAfter = $t02464224757._2
772- let balAAfter = $t02464224757._3
773- let balBAfter = $t02464224757._4
774- let shareIdAfter = $t02464224757._5
827+ let userGetBBeforeRepay = $t02783027997._6
828+ let userGetABeforeRepay = $t02783027997._5
829+ let assetIdB = $t02783027997._4
830+ let toUserAmountB = $t02783027997._3
831+ let assetIdA = $t02783027997._2
832+ let toUserAmountA = $t02783027997._1
833+ let $t02800028115 = getPoolData(Address(fromBase58String(pool)), pType)
834+ let AIdAfter = $t02800028115._1
835+ let BIdAfter = $t02800028115._2
836+ let balAAfter = $t02800028115._3
837+ let balBAfter = $t02800028115._4
838+ let shareIdAfter = $t02800028115._5
775839 let ratioBefore = fraction(balB, SCALE8, balA)
776840 let ratioAfter = fraction(balBAfter, SCALE8, balAAfter)
777841 let impact = (SCALE8 - fraction(ratioBefore, SCALE8, ratioAfter))
778842 let imcatMod = if ((0 > impact))
779843 then (impact * -1)
780844 else impact
781845 $Tuple2(nil, [userGetABeforeRepay, userGetBBeforeRepay, imcatMod])
782846 }
783847 else throw("Strict value is not equal to itself.")
784848 }
785849
786850
787851
788852 @Callable(i)
789853 func replenishFromLandEVALONLY (requestId) = {
790- let $t02512725231 = parseRequest(requestId)
791- let user = $t02512725231._1
792- let pool = $t02512725231._2
793- let pmtA = $t02512725231._3
794- let AId = $t02512725231._4
795- let pmtB = $t02512725231._5
796- let BId = $t02512725231._6
797- let balA = $t02512725231._7
798- let balB = $t02512725231._8
799- let shareId = $t02512725231._9
800- let bwAsset = $t02512725231._10
801- let bwAmount = $t02512725231._11
854+ let $t02848528589 = parseRequest(requestId)
855+ let user = $t02848528589._1
856+ let pool = $t02848528589._2
857+ let pmtA = $t02848528589._3
858+ let AId = $t02848528589._4
859+ let pmtB = $t02848528589._5
860+ let BId = $t02848528589._6
861+ let balA = $t02848528589._7
862+ let balB = $t02848528589._8
863+ let shareId = $t02848528589._9
864+ let bwAsset = $t02848528589._10
865+ let bwAmount = $t02848528589._11
802866 if ((size(i.payments) != 1))
803867 then throw("Wrong payment size")
804868 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
805869 then true
806870 else (i.payments[0].amount != bwAmount))
807871 then throw("Wrong payment")
808872 else {
809- let $t02542125545 = if ((AId == bwAsset))
873+ let $t02877928903 = if ((AId == bwAsset))
810874 then $Tuple2((pmtA + i.payments[0].amount), pmtB)
811875 else $Tuple2(pmtA, (pmtB + i.payments[0].amount))
812- let pmtAllA = $t02542125545._1
813- let pmtAllB = $t02542125545._2
876+ let pmtAllA = $t02877928903._1
877+ let pmtAllB = $t02877928903._2
814878 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
815- let $t02562725736 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
816- let userStaked = $t02562725736._1
817- let axlyFee = $t02562725736._2
879+ let $t02898529094 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
880+ let userStaked = $t02898529094._1
881+ let axlyFee = $t02898529094._2
818882 $Tuple2([IntegerEntry("EVALONLY_STAKEDAMOUNT", userStaked)], userStaked)
819883 }
820884 }
821885
822886
823887
824888 @Callable(i)
825889 func replenish (pool,leverage,borrowAssetId) = if (if ((100 > leverage))
826890 then true
827891 else (leverage > 300))
828892 then throw("Leverage can't be <100 and >300")
829893 else {
830894 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
831- let $t02611326203 = getPoolData(Address(fromBase58String(pool)), pType)
832- let AId = $t02611326203._1
833- let BId = $t02611326203._2
834- let balA = $t02611326203._3
835- let balB = $t02611326203._4
836- let shareId = $t02611326203._5
837- let $t02620626843 = if ((size(i.payments) == 2))
895+ let $t02947129561 = getPoolData(Address(fromBase58String(pool)), pType)
896+ let AId = $t02947129561._1
897+ let BId = $t02947129561._2
898+ let balA = $t02947129561._3
899+ let balB = $t02947129561._4
900+ let shareId = $t02947129561._5
901+ let $t02956430201 = if ((size(i.payments) == 2))
838902 then if ((assetIdToStr(i.payments[0].assetId) != AId))
839903 then throw("Wrong payment asset A")
840904 else if ((assetIdToStr(i.payments[1].assetId) != BId))
841905 then throw("Wrong payment asset B")
842906 else $Tuple4(i.payments[0].amount, AId, i.payments[1].amount, BId)
843907 else if ((size(i.payments) == 1))
844908 then if ((assetIdToStr(i.payments[0].assetId) == AId))
845909 then $Tuple4(i.payments[0].amount, AId, 0, BId)
846910 else if ((assetIdToStr(i.payments[0].assetId) == BId))
847911 then $Tuple4(0, AId, i.payments[0].amount, BId)
848912 else throw("Wrong payment")
849913 else throw("One or two payments expected")
850- let pmtA = $t02620626843._1
851- let pmtAssetA = $t02620626843._2
852- let pmtB = $t02620626843._3
853- let pmtAssetB = $t02620626843._4
914+ let pmtA = $t02956430201._1
915+ let pmtAssetA = $t02956430201._2
916+ let pmtB = $t02956430201._3
917+ let pmtAssetB = $t02956430201._4
854918 let newPosNum = getNewUserPositionNumber(pool, toString(i.caller))
855919 if ((leverage > 100))
856920 then {
857921 let dPriceA = ( let @ = invoke(priceOracleAddr, "getTWAP60", [pmtAssetA, false], nil)
858922 if ($isInstanceOf(@, "(Int, Int)"))
859923 then @
860924 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
861925 let dPriceB = ( let @ = invoke(priceOracleAddr, "getTWAP60", [pmtAssetB, false], nil)
862926 if ($isInstanceOf(@, "(Int, Int)"))
863927 then @
864928 else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._2
865929 let paydInDollar = (fraction(dPriceA, pmtA, pow(10, 0, getAssetDecimals(pmtAssetA), 0, 0, DOWN)) + fraction(dPriceB, pmtB, pow(10, 0, getAssetDecimals(pmtAssetB), 0, 0, DOWN)))
866930 let borrowAmount = fraction(paydInDollar, (leverage - 100), 100)
867931 let request = makeString([toString(i.caller), pool, toString(pmtA), pmtAssetA, toString(pmtB), pmtAssetB, toString(balA), toString(balB), shareId, borrowAssetId, toString(borrowAmount)], ",")
868932 let newRequestId = {
869933 let @ = invoke(this, "createNewRequest", [request], nil)
870934 if ($isInstanceOf(@, "Int"))
871935 then @
872936 else throw(($getType(@) + " couldn't be cast to Int"))
873937 }
874938 if ((newRequestId == newRequestId))
875939 then {
876940 let args = [((toString(i.caller) + "_") + toString(newPosNum)), shareId, borrowAssetId, borrowAmount, toString(this), "replenishFromLand", toString(valueOrErrorMessage(newRequestId, "Can't create new request"))]
877941 let inv = reentrantInvoke(getLendSrvAddr(), "flashPosition", args, nil)
878942 if ((inv == inv))
879943 then nil
880944 else throw("Strict value is not equal to itself.")
881945 }
882946 else throw("Strict value is not equal to itself.")
883947 }
884948 else {
885- let $t02814028252 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
886- let userStaked = $t02814028252._1
887- let axlyFee = $t02814028252._2
888- (replenishEntries(pool, toString(i.caller), userStaked, axlyFee, newPosNum, shareId, pType) ++ getCursEntries(AId, BId, shareId))
949+ let $t03149831610 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
950+ let userStaked = $t03149831610._1
951+ let axlyFee = $t03149831610._2
952+ (replenishEntries(pool, toString(i.caller), userStaked, axlyFee, newPosNum, shareId, pType, false) ++ getCursEntries(AId, BId, shareId))
889953 }
890954 }
891955
892956
893957
894958 @Callable(i)
895959 func replenishFromLand (requestId) = {
896- let $t02845628560 = parseRequest(requestId)
897- let user = $t02845628560._1
898- let pool = $t02845628560._2
899- let pmtA = $t02845628560._3
900- let AId = $t02845628560._4
901- let pmtB = $t02845628560._5
902- let BId = $t02845628560._6
903- let balA = $t02845628560._7
904- let balB = $t02845628560._8
905- let shareId = $t02845628560._9
906- let bwAsset = $t02845628560._10
907- let bwAmount = $t02845628560._11
960+ let $t03182131925 = parseRequest(requestId)
961+ let user = $t03182131925._1
962+ let pool = $t03182131925._2
963+ let pmtA = $t03182131925._3
964+ let AId = $t03182131925._4
965+ let pmtB = $t03182131925._5
966+ let BId = $t03182131925._6
967+ let balA = $t03182131925._7
968+ let balB = $t03182131925._8
969+ let shareId = $t03182131925._9
970+ let bwAsset = $t03182131925._10
971+ let bwAmount = $t03182131925._11
908972 if ((size(i.payments) != 1))
909973 then throw("Wrong payment size")
910974 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
911975 then true
912976 else (i.payments[0].amount != bwAmount))
913977 then throw("Wrong payment")
914978 else {
915- let $t02875028874 = if ((AId == bwAsset))
979+ let $t03211532239 = if ((AId == bwAsset))
916980 then $Tuple2((pmtA + i.payments[0].amount), pmtB)
917981 else $Tuple2(pmtA, (pmtB + i.payments[0].amount))
918- let pmtAllA = $t02875028874._1
919- let pmtAllB = $t02875028874._2
982+ let pmtAllA = $t03211532239._1
983+ let pmtAllB = $t03211532239._2
920984 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
921- let $t02895629065 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
922- let userStaked = $t02895629065._1
923- let axlyFee = $t02895629065._2
985+ let $t03232132430 = replenishByType(pType, pool, LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
986+ let userStaked = $t03232132430._1
987+ let axlyFee = $t03232132430._2
924988 let posNum = getNewUserPositionNumber(pool, toString(i.caller))
925989 let borrowEntries = [IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAmount), bwAmount), StringEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAssetId), bwAsset)]
926- let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType)
990+ let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType, true)
927991 $Tuple2((((entries ++ getCursEntries(AId, BId, shareId)) ++ borrowEntries) :+ DeleteEntry((requestId + kRequestId))), userStaked)
928992 }
929993 }
930994
931995
932996
933997 @Callable(i)
934-func withdraw (pool,posId) = {
935- let user = toString(i.caller)
936- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), "Unknown position")
937- let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest))
938- let poolInterst = getIntegerValue(this, (pool + kPoolInterest))
939- let poolTotalShare = getPoolTotalShare(pool)
940- let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterst - userInterest), SCALE10))
941- let userAddr = Address(fromBase58String(user))
942- let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAmount))
943- let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAssetId))
944- let debt = if ((borrowAmount > 0))
945- then {
946- let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + toString(posId)), borrowAsset], nil)
947- if ($isInstanceOf(@, "Int"))
948- then @
949- else throw(($getType(@) + " couldn't be cast to Int"))
950- }
951- else 0
952- let $t03054430697 = withdrawAmountCalc(pool, userCanWithdraw, debt, borrowAsset)
953- if (($t03054430697 == $t03054430697))
954- then {
955- let shareId = $t03054430697._7
956- let cBalBAfter = $t03054430697._6
957- let cBalAAfter = $t03054430697._5
958- let assetIdB = $t03054430697._4
959- let toUserAmountB = $t03054430697._3
960- let assetIdA = $t03054430697._2
961- let toUserAmountA = $t03054430697._1
962- let closeDbtInv = if ((debt > 0))
963- then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + toString(posId))], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
964- else 0
965- if ((closeDbtInv == closeDbtInv))
966- then ([DeleteEntry((((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), DeleteEntry((((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), (poolTotalShare - userCanWithdraw)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB))] ++ getCursEntries(assetIdA, assetIdB, shareId))
967- else throw("Strict value is not equal to itself.")
968- }
969- else throw("Strict value is not equal to itself.")
998+func withdraw (pool,posId) = withdrawToUser(toString(i.caller), pool, toString(posId), false)
999+
1000+
1001+
1002+@Callable(i)
1003+func createUpdateStopLoss (posId,poolId,assetId,price) = {
1004+ let tokenOraclePrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
1005+ if ($isInstanceOf(@, "(Int, Int)"))
1006+ then @
1007+ else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._1
1008+ if (!(isDefined(getInteger(this, (((((poolId + "_") + toString(i.caller)) + "_") + toString(posId)) + kUserPosition)))))
1009+ then throw("There are no user position")
1010+ else if ((0 >= price))
1011+ then throw("Price must be greater than 0")
1012+ else if ((price > tokenOraclePrice))
1013+ then throw("Price must be less than current token price")
1014+ else [IntegerEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss), price)]
9701015 }
1016+
1017+
1018+
1019+@Callable(i)
1020+func deleteStopLoss (posId,poolId,assetId) = if (!(isDefined(getInteger(this, (((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss)))))
1021+ then throw("No entry")
1022+ else [DeleteEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss))]
9711023
9721024
9731025
9741026 @Callable(i)
9751027 func createNewRequest (params) = valueOrElse(isSelfCall(i), {
9761028 let newRequestId = (valueOrElse(getInteger(this, kRequestIter), 0) + 1)
9771029 $Tuple2([StringEntry((toString(newRequestId) + kRequestId), params), IntegerEntry(kRequestIter, newRequestId)], newRequestId)
9781030 })
9791031
9801032
9811033
9821034 @Callable(i)
1035+func stopLoss (user,posId,pool,assetId) = {
1036+ let tokenOraclePrice = ( let @ = invoke(priceOracleAddr, "getTWAP60", [assetId, false], nil)
1037+ if ($isInstanceOf(@, "(Int, Int)"))
1038+ then @
1039+ else throw(($getType(@) + " couldn't be cast to (Int, Int)")))._1
1040+ if (!(isDefined(getInteger(this, (((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)))))
1041+ then throw("No entry")
1042+ else (withdrawToUser(toString(i.caller), pool, toString(posId), true) :+ DeleteEntry((((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)))
1043+ }
1044+
1045+
1046+
1047+@Callable(i)
1048+func liquidate (user,posId,pool,liquidateAmount) = {
1049+ let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1050+ let $t03512135211 = getPoolData(Address(fromBase58String(pool)), pType)
1051+ let AId = $t03512135211._1
1052+ let BId = $t03512135211._2
1053+ let balA = $t03512135211._3
1054+ let balB = $t03512135211._4
1055+ let shareId = $t03512135211._5
1056+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPosition)), "Unknown position")
1057+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserPositionInterest))
1058+ let poolTotalShare = getPoolTotalShare(pool)
1059+ let userAddr = Address(fromBase58String(user))
1060+ let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAmount))
1061+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + toString(posId)) + kUserBorrowAssetId))
1062+ let $t03576536118 = if ((borrowAmount > 0))
1063+ then $Tuple2({
1064+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((((pool + "_") + user) + "_") + toString(posId)), borrowAsset], nil)
1065+ if ($isInstanceOf(@, "Int"))
1066+ then @
1067+ else throw(($getType(@) + " couldn't be cast to Int"))
1068+ }, getIntegerValue(this, (pool + kPoolInterestLoan)))
1069+ else $Tuple2(0, getIntegerValue(this, (pool + kPoolInterestNoLoan)))
1070+ let debt = $t03576536118._1
1071+ let poolInterest = $t03576536118._2
1072+ let userCanWithdraw = (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
1073+ let sharePrice = getSharePrice([shareId])[0]
1074+ let borrowAssetPrice = getAssetsPrice([borrowAsset])[0]
1075+ let userCanWithdrawInD = fraction(userCanWithdraw, sharePrice, getAssetDecimals(shareId))
1076+ let borrowAmountInD = fraction(borrowAmount, borrowAssetPrice, getAssetPrecition(borrowAsset))
1077+ let userAmountInD = (userCanWithdrawInD - borrowAmountInD)
1078+ nil
1079+ }
1080+
1081+
1082+
1083+@Callable(i)
9831084 func capitalizeExKeeper (pool,type,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
984- let $t03204132235 = if (claim)
1085+ let $t03690337097 = if (claim)
9851086 then claimFarmed(type, pool)
9861087 else {
9871088 let claimedAsset = if ((type == SF_POOL))
9881089 then SWOPID
9891090 else WXID
9901091 $Tuple2(amountToExchange, claimedAsset)
9911092 }
992- let claimedAmount = $t03204132235._1
993- let claimedAsset = $t03204132235._2
1093+ let claimedAmount = $t03690337097._1
1094+ let claimedAsset = $t03690337097._2
9941095 let exchangedAmount = exchangeKeeper(tokenToId, amountToExchange, claimedAsset, amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options)
9951096 let change = (claimedAmount - amountToExchange)
9961097 let changeEntry = if ((change > 0))
9971098 then [IntegerEntry((pool + kPoolCapChange), (change + valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)))]
9981099 else nil
9991100 (capitalize(pool, type, tokenToId, exchangedAmount) ++ changeEntry)
10001101 }
10011102
10021103
10031104
10041105 @Callable(i)
1005-func capitalizeExPazzle (pool,type,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = {
1006- let $t03289233086 = if (claim)
1106+func capitalizeExPuzzle (pool,type,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = {
1107+ let $t03775437948 = if (claim)
10071108 then claimFarmed(type, pool)
10081109 else {
10091110 let claimedAsset = if ((type == SF_POOL))
10101111 then SWOPID
10111112 else WXID
10121113 $Tuple2(amountToExchange, claimedAsset)
10131114 }
1014- let claimedAmount = $t03289233086._1
1015- let claimedAsset = $t03289233086._2
1016- let exchangedAmount = exchangePazzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
1115+ let claimedAmount = $t03775437948._1
1116+ let claimedAsset = $t03775437948._2
1117+ let exchangedAmount = exchangePuzzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
10171118 let change = (claimedAmount - amountToExchange)
10181119 let changeEntry = if ((change > 0))
10191120 then [IntegerEntry((pool + kPoolCapChange), (change + valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)))]
10201121 else nil
10211122 (capitalize(pool, type, tokenToId, exchangedAmount) ++ changeEntry)
10221123 }
10231124
10241125
10251126
10261127 @Callable(i)
10271128 func capitalizeExSwopFi (pool,type,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
1028- let $t03380934003 = if (claim)
1129+ let $t03867138865 = if (claim)
10291130 then claimFarmed(type, pool)
10301131 else {
10311132 let claimedAsset = if ((type == SF_POOL))
10321133 then SWOPID
10331134 else WXID
10341135 $Tuple2(amountToExchange, claimedAsset)
10351136 }
1036- let claimedAmount = $t03380934003._1
1037- let claimedAsset = $t03380934003._2
1137+ let claimedAmount = $t03867138865._1
1138+ let claimedAsset = $t03867138865._2
10381139 let exchangedAmount = exchangeSwopFi(tokenToId, amountToExchange, claimedAsset, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options)
10391140 let change = (claimedAmount - amountToExchange)
10401141 let changeEntry = if ((change > 0))
10411142 then [IntegerEntry((pool + kPoolCapChange), (change + valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)))]
10421143 else nil
10431144 (capitalize(pool, type, tokenToId, exchangedAmount) ++ changeEntry)
10441145 }
10451146
10461147
10471148
10481149 @Callable(i)
1049-func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan) = if (if ((type != SF_POOL))
1150+func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan) = if (if ((type != SF_POOL))
10501151 then (type != WX_POOL)
10511152 else false)
10521153 then throw("Wrong type")
10531154 else {
1054- let $t03464834742 = getPoolData(Address(fromBase58String(poolAddr)), type)
1055- let aId = $t03464834742._1
1056- let bId = $t03464834742._2
1057- let aBal = $t03464834742._3
1058- let bBal = $t03464834742._4
1059- let shareId = $t03464834742._5
1060-[IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kPoolInterest), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr)]
1155+ let $t03955839652 = getPoolData(Address(fromBase58String(poolAddr)), type)
1156+ let aId = $t03955839652._1
1157+ let bId = $t03955839652._2
1158+ let aBal = $t03955839652._3
1159+ let bBal = $t03955839652._4
1160+ let shareId = $t03955839652._5
1161+[IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan), IntegerEntry((poolAddr + kPoolInterestLoan), 0), IntegerEntry((poolAddr + kPoolInterestNoLoan), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr)]
10611162 }
1163+
1164+
1165+
1166+@Callable(i)
1167+func capitalizeTest (pool,pType,tokenId,tokenAmount) = {
1168+ let poolAddr = Address(fromBase58String(pool))
1169+ let $t04044840527 = getPoolData(poolAddr, pType)
1170+ let AId = $t04044840527._1
1171+ let BId = $t04044840527._2
1172+ let balA = $t04044840527._3
1173+ let balB = $t04044840527._4
1174+ let shareId = $t04044840527._5
1175+ let $t04053040610 = if ((tokenId == AId))
1176+ then $Tuple2(tokenAmount, 0)
1177+ else $Tuple2(0, tokenAmount)
1178+ let pmtA = $t04053040610._1
1179+ let pmtB = $t04053040610._2
1180+ let $t04061340717 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1181+ let stakedAmount = $t04061340717._1
1182+ let nf = $t04061340717._2
1183+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
1184+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
1185+ let totalShareAmount = getPoolTotalShare(pool)
1186+ let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
1187+ let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
1188+ let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
1189+ let stakedNoLoan = (stakedAmount - stakedLoan)
1190+ let newInterestLoan = (curPoolInterestLoan + fraction(stakedLoan, SCALE10, totalShareAmountWithLoan))
1191+ let newInterestNoLoan = (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
1192+ let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
1193+ let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
1194+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (((totalShareAmount + stakedAmount) - axlyFeeLoan) - axlyFeeNoLoan)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId))
1195+ }
1196+
1197+
1198+
1199+@Callable(i)
1200+func claimFarmedTest (type,pool) = if ((type == SF_POOL))
1201+ then {
1202+ let balBefore = accountBalance(SWOPID)
1203+ if ((balBefore == balBefore))
1204+ then {
1205+ let inv = invoke(getSFFarmingAddr(), "claim", [pool], nil)
1206+ if ((inv == inv))
1207+ then {
1208+ let balAfter = accountBalance(SWOPID)
1209+ $Tuple2(nil, $Tuple2((balAfter - balBefore), SWOPID))
1210+ }
1211+ else throw("Strict value is not equal to itself.")
1212+ }
1213+ else throw("Strict value is not equal to itself.")
1214+ }
1215+ else if ((type == WX_POOL))
1216+ then {
1217+ let balBefore = accountBalance(WXID)
1218+ if ((balBefore == balBefore))
1219+ then {
1220+ let inv = invoke(getWXFarmingAddr(Address(fromBase58String(pool))), "claimWX", [pool], nil)
1221+ if ((inv == inv))
1222+ then {
1223+ let balAfter = accountBalance(WXID)
1224+ $Tuple2(nil, $Tuple2((balAfter - balBefore), WXID))
1225+ }
1226+ else throw("Strict value is not equal to itself.")
1227+ }
1228+ else throw("Strict value is not equal to itself.")
1229+ }
1230+ else throw("Wrong pool type")
10621231
10631232
10641233 @Verifier(tx)
10651234 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
10661235

github/deemru/w8io/3ef1775 
301.82 ms