tx · 7Sn8aJWrWUwG7L5o8ps4qXkCqXcDXAsBujNT1dxt1J8j 3NADcxHXbecCheinqFbvhDjfzZhsMFZJUuH: -0.03700000 Waves 2022.12.12 16:42 [2357198] smart account 3NADcxHXbecCheinqFbvhDjfzZhsMFZJUuH > SELF 0.00000000 Waves
{ "type": 13, "id": "7Sn8aJWrWUwG7L5o8ps4qXkCqXcDXAsBujNT1dxt1J8j", "fee": 3700000, "feeAssetId": null, "timestamp": 1670852621373, "version": 2, "chainId": 84, "sender": "3NADcxHXbecCheinqFbvhDjfzZhsMFZJUuH", "senderPublicKey": "DKfzQgvVdTqPHgGbdZptWYA8G5xVfmSMAwL3UnhwQmdy", "proofs": [ "3mJpkjgcqGtFyqYpcQN9RuNGB19hpP8k22dkDeTUjgjbmmziZb4N7fKgRdPPQixptSBbTpsZeEfzNvvHd7wi8j8d" ], "script": "base64:BgIzCAISAwoBCBIAEgMKAQESABIDCgEEEgMKAQESAwoBARIDCgEBEgMKAQESAwoBCBIDCgEIQgANa190b3RhbFN1cHBseQINa190b3RhbFN1cHBseQAPa19sb2NrZWRCYWxhbmNlAg9rX2xvY2tlZEJhbGFuY2UAEGtfdkxvY2tlZEJhbGFuY2UCEGtfdkxvY2tlZEJhbGFuY2UADWtfZnJlZUJhbGFuY2UCDWtfZnJlZUJhbGFuY2UAFWtfZnJlZUJhbGFuY2VCb3Jyb3dlZAIVa19mcmVlQmFsYW5jZUJvcnJvd2VkAAZrX3JhdGUCBmtfcmF0ZQAJa19iYWxhbmNlAglrX2JhbGFuY2UADmtfYXZlcmFnZV9yYXRlAg5rX2F2ZXJhZ2VfcmF0ZQAQa193aXRoZHJhd19saW1pdAIQa193aXRoZHJhd19saW1pdAAUa19sYXN0X3dpdGhkcmF3X2RhdGUCFGtfbGFzdF93aXRoZHJhd19kYXRlABRrX3dpdGhkcmF3X2luX3BlcmlvZAIUa193aXRoZHJhd19pbl9wZXJpb2QADWtfaW5pdGlhbGl6ZWQCDWtfaW5pdGlhbGl6ZWQAFGtfY29vcmRpbmF0b3JBZGRyZXNzAhRrX2Nvb3JkaW5hdG9yQWRkcmVzcwAFa19hbW0CBWtfYW1tAA1rX3F1b3RlX2Fzc2V0Ag1rX3F1b3RlX2Fzc2V0ABJrX2FkbWluX3B1YmxpY19rZXkCEmtfYWRtaW5fcHVibGljX2tleQAPa19hZG1pbl9hZGRyZXNzAg9rX2FkbWluX2FkZHJlc3MAEWtfbWFuYWdlcl9hZGRyZXNzAhFrX21hbmFnZXJfYWRkcmVzcwAUa19jb2xsYXRlcmFsX2FkZHJlc3MCFGtfY29sbGF0ZXJhbF9hZGRyZXNzAQ50b0NvbXBvc2l0ZUtleQIEX2tleQhfYWRkcmVzcwkArAICCQCsAgIFBF9rZXkCAV8FCF9hZGRyZXNzAQtjb29yZGluYXRvcgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwITQ29vcmRpbmF0b3Igbm90IHNldAELaXNXaGl0ZWxpc3QBCF9hZGRyZXNzCQELdmFsdWVPckVsc2UCCQCbCAIJAQtjb29yZGluYXRvcgAJAQ50b0NvbXBvc2l0ZUtleQIFBWtfYW1tBQhfYWRkcmVzcwcBDmFkbWluUHVibGljS2V5AAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRJrX2FkbWluX3B1YmxpY19rZXkBDGFkbWluQWRkcmVzcwAJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQtjb29yZGluYXRvcgAFD2tfYWRtaW5fYWRkcmVzcwIVQWRtaW4gYWRkcmVzcyBub3Qgc2V0AQpxdW90ZUFzc2V0AAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABQ1rX3F1b3RlX2Fzc2V0AQ5tYW5hZ2VyQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRFrX21hbmFnZXJfYWRkcmVzcwIPTWFuYWdlciBub3Qgc2V0ARFjb2xsYXRlcmFsQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRRrX2NvbGxhdGVyYWxfYWRkcmVzcwIaQ29sbGF0ZXJhbCBNYW5hZ2VyIG5vdCBzZXQADERFQ0lNQUxfVU5JVAkAaAIAAQkAaAIJAGgCCQBoAgkAaAIJAGgCCQBoAgkAaAIACgAKAAoACgAKAAoACgAKAAhEVVJBVElPTgkAaAIJAGgCADwAPAAYAApOT19BRERSRVNTAgAACU5PX1NUQUtFUgAAARB1c2RuRnJvbURlY2ltYWxzAQdfYW1vdW50CQBpAgUHX2Ftb3VudABkAQ51c2RuVG9EZWNpbWFscwEHX2Ftb3VudAkAaAIFB19hbW91bnQAZAEEZGl2ZAICX3gCX3kJAG4EBQJfeAUMREVDSU1BTF9VTklUBQJfeQUISEFMRkVWRU4BBG11bGQCAl94Al95CQBuBAUCX3gFAl95BQxERUNJTUFMX1VOSVQFCEhBTEZFVkVOAQNhYnMBAl94AwkAZgIFAl94AAAFAl94CQEBLQEFAl94AQRtaW52AgJfeAJfeQMJAGYCBQJfeAUCX3kFAl95BQJfeAAPV0lUSERSQVdfUEVSSU9ECQBoAgCAowUA6AcAE1dJVEhEUkFXX1BFUl9QRVJJT0QJAQRkaXZkAgkAaAIAAQUMREVDSU1BTF9VTklUCQBoAgAEBQxERUNJTUFMX1VOSVQBA2ludAEBawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAWsJAKwCAgINbm8gdmFsdWUgZm9yIAUBawEEaW50MAEBawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrAAABBGludDEBAWsJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBawUMREVDSU1BTF9VTklUAQt0b3RhbFN1cHBseQAJAQRpbnQwAQUNa190b3RhbFN1cHBseQEEcmF0ZQAJAQRpbnQxAQUGa19yYXRlAQliYWxhbmNlT2YBB19zdGFrZXIJAQRpbnQwAQkBDnRvQ29tcG9zaXRlS2V5AgUJa19iYWxhbmNlBQdfc3Rha2VyAQthdmVyYWdlUmF0ZQEHX3N0YWtlcgkBBGludDABCQEOdG9Db21wb3NpdGVLZXkCBQ5rX2F2ZXJhZ2VfcmF0ZQUHX3N0YWtlcgENd2l0aGRyYXdMaW1pdAEHX3N0YWtlcgkBBGludDABCQEOdG9Db21wb3NpdGVLZXkCBRBrX3dpdGhkcmF3X2xpbWl0BQdfc3Rha2VyARF3aXRoZHJhd25JblBlcmlvZAEHX3N0YWtlcgkBBGludDABCQEOdG9Db21wb3NpdGVLZXkCBRRrX3dpdGhkcmF3X2luX3BlcmlvZAUHX3N0YWtlcgERbGFzdFdpdGhkcmF3bkRhdGUBB19zdGFrZXIJAQRpbnQwAQkBDnRvQ29tcG9zaXRlS2V5AgUUa19sYXN0X3dpdGhkcmF3X2RhdGUFB19zdGFrZXIBC2ZyZWVCYWxhbmNlAAkBBGludDABBQ1rX2ZyZWVCYWxhbmNlARNmcmVlQmFsYW5jZUJvcnJvd2VkAAkBBGludDABBRVrX2ZyZWVCYWxhbmNlQm9ycm93ZWQBDWxvY2tlZEJhbGFuY2UACQEEaW50MAEFD2tfbG9ja2VkQmFsYW5jZQEOdkxvY2tlZEJhbGFuY2UACQEEaW50MAEFEGtfdkxvY2tlZEJhbGFuY2UBC2luaXRpYWxpemVkAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQ1rX2luaXRpYWxpemVkBwEUZ2V0V2l0aGRyYXdMaW1pdExlZnQBB19zdGFrZXIEC2N1cnJlbnREYXRlCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQQbGFzdFdpdGhkcmF3RGF0ZQkBEWxhc3RXaXRoZHJhd25EYXRlAQUHX3N0YWtlcgQLJHQwNDQ1NjQ3MjADCQBmAgkAZQIFC2N1cnJlbnREYXRlBRBsYXN0V2l0aGRyYXdEYXRlBQ9XSVRIRFJBV19QRVJJT0QJAJQKAgULY3VycmVudERhdGUJAQ13aXRoZHJhd0xpbWl0AQUHX3N0YWtlcgkAlAoCBRBsYXN0V2l0aGRyYXdEYXRlCQBlAgkBDXdpdGhkcmF3TGltaXQBBQdfc3Rha2VyCQERd2l0aGRyYXduSW5QZXJpb2QBBQdfc3Rha2VyBBRuZXdMYXN0V2l0aGRyYXduRGF0ZQgFCyR0MDQ0NTY0NzIwAl8xBBF3aXRoZHJhd0xpbWl0TGVmdAgFCyR0MDQ0NTY0NzIwAl8yCQCUCgIFFG5ld0xhc3RXaXRoZHJhd25EYXRlBRF3aXRoZHJhd0xpbWl0TGVmdAEOY29tcHV0ZU5ld1JhdGUBE19hbW91bnRPZlF1b3RlQXNzZXQEB25ld1JhdGUDCQBmAgkBC3RvdGFsU3VwcGx5AAAACQEEZGl2ZAIJAGQCCQELZnJlZUJhbGFuY2UABRNfYW1vdW50T2ZRdW90ZUFzc2V0CQELdG90YWxTdXBwbHkABQxERUNJTUFMX1VOSVQFB25ld1JhdGUBEXVwZGF0ZVVzZXJCYWxhbmNlAgVfdXNlcgdfY2hhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBQlrX2JhbGFuY2UFBV91c2VyCQBkAgkBCWJhbGFuY2VPZgEFBV91c2VyBQdfY2hhbmdlBQNuaWwBFHNldFVzZXJXaXRoZHJhd0xpbWl0AgVfdXNlcgVfcmF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUQa193aXRoZHJhd19saW1pdAUFX3VzZXIFBV9yYXRlBQNuaWwBEnNldFVzZXJBdmVyYWdlUmF0ZQIFX3VzZXIFX3JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFDmtfYXZlcmFnZV9yYXRlBQVfdXNlcgUFX3JhdGUFA25pbAERdXBkYXRlRnJlZUJhbGFuY2UBB19jaGFuZ2UJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtfZnJlZUJhbGFuY2UJAGQCCQELZnJlZUJhbGFuY2UABQdfY2hhbmdlBQNuaWwBGXVwZGF0ZUZyZWVCb3Jyb3dlZEJhbGFuY2UBB19jaGFuZ2UED2JvcnJvd2VkQmFsYW5jZQkBE2ZyZWVCYWxhbmNlQm9ycm93ZWQAAwkAZwIJAGQCBQ9ib3Jyb3dlZEJhbGFuY2UFB19jaGFuZ2UAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUVa19mcmVlQmFsYW5jZUJvcnJvd2VkCQBkAgUPYm9ycm93ZWRCYWxhbmNlBQdfY2hhbmdlBQNuaWwJAAIBCQCsAgIJAKwCAgkArAICAjZWYXVsdDogY2FuIG5vdCB1cGRhdGUgYm9ycm93ZWQgZnJlZSBiYWxhbmNlLiBCYWxhbmNlOiAJAKQDAQUPYm9ycm93ZWRCYWxhbmNlAgkgY2hhbmdlOiAJAKQDAQUHX2NoYW5nZQETdXBkYXRlTG9ja2VkQmFsYW5jZQEHX2NoYW5nZQQHYmFsYW5jZQkBDWxvY2tlZEJhbGFuY2UAAwkAZwIJAGQCBQdiYWxhbmNlBQdfY2hhbmdlAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFD2tfbG9ja2VkQmFsYW5jZQkAZAIFB2JhbGFuY2UFB19jaGFuZ2UFA25pbAkAAgEJAKwCAgkArAICCQCsAgICL1ZhdWx0OiBjYW4gbm90IHVwZGF0ZSBsb2NrZWQgYmFsYW5jZS4gQmFsYW5jZTogCQCkAwEFB2JhbGFuY2UCCSBjaGFuZ2U6IAkApAMBBQdfY2hhbmdlARR1cGRhdGVWTG9ja2VkQmFsYW5jZQEHX2NoYW5nZQQHYmFsYW5jZQkBDnZMb2NrZWRCYWxhbmNlAAMJAGcCCQBkAgUHYmFsYW5jZQUHX2NoYW5nZQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX3ZMb2NrZWRCYWxhbmNlCQBkAgUHYmFsYW5jZQUHX2NoYW5nZQUDbmlsCQACAQkArAICCQCsAgIJAKwCAgIxVmF1bHQ6IGNhbiBub3QgdXBkYXRlIHYtbG9ja2VkIGJhbGFuY2UuIEJhbGFuY2U6IAkApAMBBQdiYWxhbmNlAgkgY2hhbmdlOiAJAKQDAQUHX2NoYW5nZQERdXBkYXRlVG90YWxTdXBwbHkBB19jaGFuZ2UJAMwIAgkBDEludGVnZXJFbnRyeQIFDWtfdG90YWxTdXBwbHkJAGQCCQELdG90YWxTdXBwbHkABQdfY2hhbmdlBQNuaWwBCnVwZGF0ZVJhdGUBBV9yYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQZrX3JhdGUFBV9yYXRlBQNuaWwBFXNldFVzZXJXaXRoZHJhd1BhcmFtcwMFX3VzZXIRX2xhc3RXaXRoZHJhd0RhdGUKX3dpdGhkcmF3bgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUUa19sYXN0X3dpdGhkcmF3X2RhdGUFBV91c2VyBRFfbGFzdFdpdGhkcmF3RGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUUa193aXRoZHJhd19pbl9wZXJpb2QFBV91c2VyBQpfd2l0aGRyYXduBQNuaWwLAWkBCmluaXRpYWxpemUBDF9jb29yZGluYXRvcgMJAQtpbml0aWFsaXplZAAJAAIBAhNBbHJlYWR5IGluaXRpYWxpemVkCQDMCAIJAQtTdHJpbmdFbnRyeQIFFGtfY29vcmRpbmF0b3JBZGRyZXNzBQxfY29vcmRpbmF0b3IJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDWtfaW5pdGlhbGl6ZWQGBQNuaWwBaQEFc3Rha2UABAdfc3Rha2VyCQClCAEIBQFpBmNhbGxlcgQHX2Ftb3VudAkBDnVzZG5Ub0RlY2ltYWxzAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQDAwkBAiE9AggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCQEKcXVvdGVBc3NldAAGCQEBIQEJAQtpbml0aWFsaXplZAAJAAIBAhVJbnZhbGlkIGNhbGwgdG8gc3Rha2UEC2N1cnJlbnRSYXRlCQEEcmF0ZQAED3ByZXZBdmVyYWdlUmF0ZQkBC2F2ZXJhZ2VSYXRlAQUHX3N0YWtlcgQHdkFtb3VudAkBBGRpdmQCBQdfYW1vdW50BQtjdXJyZW50UmF0ZQQObmV3QXZlcmFnZVJhdGUJAQRkaXZkAgkAZAIJAQRtdWxkAgUHdkFtb3VudAULY3VycmVudFJhdGUJAQRtdWxkAgkBCWJhbGFuY2VPZgEFB19zdGFrZXIFD3ByZXZBdmVyYWdlUmF0ZQkAZAIFC2N1cnJlbnRSYXRlBQ9wcmV2QXZlcmFnZVJhdGUED25ld1RvdGFsQmFsYW5jZQkAZAIFB3ZBbW91bnQJAQliYWxhbmNlT2YBBQdfc3Rha2VyBBBuZXdXaXRoZHJhd0xpbWl0CQEEbXVsZAIFD25ld1RvdGFsQmFsYW5jZQUTV0lUSERSQVdfUEVSX1BFUklPRAQFc3Rha2UJAPwHBAkBDm1hbmFnZXJBZGRyZXNzAAIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAJARB1c2RuRnJvbURlY2ltYWxzAQUHX2Ftb3VudAUDbmlsAwkAAAIFBXN0YWtlBQVzdGFrZQkAzggCCQDOCAIJAM4IAgkAzggCCQERdXBkYXRlRnJlZUJhbGFuY2UBBQdfYW1vdW50CQERdXBkYXRlVXNlckJhbGFuY2UCBQdfc3Rha2VyBQd2QW1vdW50CQESc2V0VXNlckF2ZXJhZ2VSYXRlAgUHX3N0YWtlcgUObmV3QXZlcmFnZVJhdGUJARRzZXRVc2VyV2l0aGRyYXdMaW1pdAIFB19zdGFrZXIFEG5ld1dpdGhkcmF3TGltaXQJARF1cGRhdGVUb3RhbFN1cHBseQEFB3ZBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHdW5TdGFrZQEHX2Ftb3VudAQHX3N0YWtlcgkApQgBCAUBaQZjYWxsZXIEEmFtb3VudE9mUXVvdGVBc3NldAkBDnVzZG5Ub0RlY2ltYWxzAQUHX2Ftb3VudAMDCQECIT0CCAUBaQhwYXltZW50cwUDbmlsBgkBASEBCQELaW5pdGlhbGl6ZWQACQACAQIXSW52YWxpZCBjYWxsIHRvIHVuU3Rha2UECyR0MDg4OTM5MDM0CQEUZ2V0V2l0aGRyYXdMaW1pdExlZnQBBQdfc3Rha2VyBBRuZXdMYXN0V2l0aGRyYXduRGF0ZQgFCyR0MDg4OTM5MDM0Al8xBBF3aXRoZHJhd0xpbWl0TGVmdAgFCyR0MDg4OTM5MDM0Al8yBAd2QW1vdW50CQEEZGl2ZAIFEmFtb3VudE9mUXVvdGVBc3NldAkBBHJhdGUAAwkAZgIFB3ZBbW91bnQFEXdpdGhkcmF3TGltaXRMZWZ0CQACAQIsSW52YWxpZCBjYWxsIHRvIHVuU3Rha2U6IHdpdGhkcmF3IG92ZXIgbGltaXQEFG5ld1dpdGhkcmF3bkluUGVyaW9kCQBkAgkBEXdpdGhkcmF3bkluUGVyaW9kAQUHX3N0YWtlcgUHdkFtb3VudAMJAGYCBRJhbW91bnRPZlF1b3RlQXNzZXQJAQtmcmVlQmFsYW5jZQAJAAIBAihJbnZhbGlkIGNhbGwgdG8gdW5TdGFrZTogYmFsYW5jZSB0b28gbG93BAd1bnN0YWtlCQD8BwQJAQ5tYW5hZ2VyQWRkcmVzcwACCHdpdGhkcmF3CQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIJARB1c2RuRnJvbURlY2ltYWxzAQUSYW1vdW50T2ZRdW90ZUFzc2V0BQNuaWwFA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlCQDOCAIJAM4IAgkAzggCCQDOCAIJARF1cGRhdGVGcmVlQmFsYW5jZQEJAQEtAQUSYW1vdW50T2ZRdW90ZUFzc2V0CQERdXBkYXRlVXNlckJhbGFuY2UCBQdfc3Rha2VyCQEBLQEFB3ZBbW91bnQJARF1cGRhdGVUb3RhbFN1cHBseQEJAQEtAQUHdkFtb3VudAkBFXNldFVzZXJXaXRoZHJhd1BhcmFtcwMFB19zdGFrZXIFFG5ld0xhc3RXaXRoZHJhd25EYXRlBRRuZXdXaXRoZHJhd25JblBlcmlvZAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJARB1c2RuRnJvbURlY2ltYWxzAQUSYW1vdW50T2ZRdW90ZUFzc2V0CQEKcXVvdGVBc3NldAAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQdhZGRGcmVlAAQHX2Ftb3VudAkBDnVzZG5Ub0RlY2ltYWxzAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQDAwMJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAkBCnF1b3RlQXNzZXQABgkBASEBCQELaW5pdGlhbGl6ZWQABgkBASEBAwkBC2lzV2hpdGVsaXN0AQkApQgBCAUBaQZjYWxsZXIGCQAAAggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECFkludmFsaWQgYWRkRnJlZSBwYXJhbXMEB25ld1JhdGUDCQBmAgkBC3RvdGFsU3VwcGx5AAAACQEEZGl2ZAIJAGQCCQELZnJlZUJhbGFuY2UABQdfYW1vdW50CQELdG90YWxTdXBwbHkABQxERUNJTUFMX1VOSVQEB3Vuc3Rha2UJAPwHBAkBDm1hbmFnZXJBZGRyZXNzAAIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAJARB1c2RuRnJvbURlY2ltYWxzAQUHX2Ftb3VudAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UJAM4IAgkBEXVwZGF0ZUZyZWVCYWxhbmNlAQUHX2Ftb3VudAkBCnVwZGF0ZVJhdGUBBQduZXdSYXRlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWFkZExvY2tlZAEGX3JlcGF5BAdfYW1vdW50CQEOdXNkblRvRGVjaW1hbHMBCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAMDAwkBAiE9AggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCQEKcXVvdGVBc3NldAAGCQEBIQEJAQtpbml0aWFsaXplZAAGCQEBIQEDAwkBC2lzV2hpdGVsaXN0AQkApQgBCAUBaQZjYWxsZXIGCQAAAggFAWkGY2FsbGVyCQERY29sbGF0ZXJhbEFkZHJlc3MABgkAAAIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAJAAIBAhhJbnZhbGlkIGFkZExvY2tlZCBwYXJhbXMEB3Vuc3Rha2UJAPwHBAkBDm1hbmFnZXJBZGRyZXNzAAIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAJARB1c2RuRnJvbURlY2ltYWxzAQUHX2Ftb3VudAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEDGZyZWVCb3Jyb3dlZAkBE2ZyZWVCYWxhbmNlQm9ycm93ZWQACQDOCAIDAwUGX3JlcGF5CQBmAgUMZnJlZUJvcnJvd2VkAAAHCQEZdXBkYXRlRnJlZUJvcnJvd2VkQmFsYW5jZQEJAQEtAQkBBG1pbnYCBQxmcmVlQm9ycm93ZWQFB19hbW91bnQFA25pbAkBE3VwZGF0ZUxvY2tlZEJhbGFuY2UBBQdfYW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmFkZExvY2tlZFYBC19hbW91bnRVc2RuBAdfYW1vdW50CQEOdXNkblRvRGVjaW1hbHMBBQtfYW1vdW50VXNkbgMDCQEBIQEJAQtpbml0aWFsaXplZAAGCQEBIQEDCQAAAggFAWkGY2FsbGVyCQERY29sbGF0ZXJhbEFkZHJlc3MABgkAAAIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAJAAIBAhlJbnZhbGlkIGFkZExvY2tlZFYgcGFyYW1zCQDOCAIJARN1cGRhdGVMb2NrZWRCYWxhbmNlAQUHX2Ftb3VudAkBFHVwZGF0ZVZMb2NrZWRCYWxhbmNlAQUHX2Ftb3VudAFpARVleGNoYW5nZUZyZWVBbmRMb2NrZWQBB19hbW91bnQDAwkBASEBCQELaW5pdGlhbGl6ZWQABgkBASEBAwkBC2lzV2hpdGVsaXN0AQkApQgBCAUBaQZjYWxsZXIGCQAAAggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECJEludmFsaWQgZXhjaGFuZ2VGcmVlQW5kTG9ja2VkIHBhcmFtcwQSYW1vdW50T2ZRdW90ZUFzc2V0CQEOdXNkblRvRGVjaW1hbHMBBQdfYW1vdW50BA9ib3Jyb3dlZEJhbGFuY2UJARNmcmVlQmFsYW5jZUJvcnJvd2VkAAQNJHQwMTI0NDUxMjkzMgMDCQBmAgUSYW1vdW50T2ZRdW90ZUFzc2V0AAAJAGYCBQ9ib3Jyb3dlZEJhbGFuY2UAAAcJAJQKAgkBAS0BBRJhbW91bnRPZlF1b3RlQXNzZXQJAQEtAQkBBG1pbnYCBRJhbW91bnRPZlF1b3RlQXNzZXQFD2JvcnJvd2VkQmFsYW5jZQkAlAoCCQEBLQEFEmFtb3VudE9mUXVvdGVBc3NldAAABApmcmVlVXBkYXRlCAUNJHQwMTI0NDUxMjkzMgJfMQQSZnJlZUJvcnJvd2VkVXBkYXRlCAUNJHQwMTI0NDUxMjkzMgJfMgQHbmV3UmF0ZQkBDmNvbXB1dGVOZXdSYXRlAQUKZnJlZVVwZGF0ZQkAzggCCQDOCAIJAM4IAgkBE3VwZGF0ZUxvY2tlZEJhbGFuY2UBBRJhbW91bnRPZlF1b3RlQXNzZXQJARF1cGRhdGVGcmVlQmFsYW5jZQEFCmZyZWVVcGRhdGUJARl1cGRhdGVGcmVlQm9ycm93ZWRCYWxhbmNlAQUSZnJlZUJvcnJvd2VkVXBkYXRlCQEKdXBkYXRlUmF0ZQEFB25ld1JhdGUBaQEOd2l0aGRyYXdMb2NrZWQBB19hbW91bnQDAwMJAQEhAQkBC2luaXRpYWxpemVkAAYJAGcCAAAFB19hbW91bnQGCQEBIQEJAQtpc1doaXRlbGlzdAEJAKUIAQgFAWkGY2FsbGVyCQACAQIdSW52YWxpZCB3aXRoZHJhd0xvY2tlZCBwYXJhbXMEEmFtb3VudE9mUXVvdGVBc3NldAkBDnVzZG5Ub0RlY2ltYWxzAQUHX2Ftb3VudAQHdW5zdGFrZQkA/AcECQEObWFuYWdlckFkZHJlc3MAAgh3aXRoZHJhdwkAzAgCCQDYBAEJAQpxdW90ZUFzc2V0AAkAzAgCCQEQdXNkbkZyb21EZWNpbWFscwEFEmFtb3VudE9mUXVvdGVBc3NldAUDbmlsBQNuaWwDCQAAAgUHdW5zdGFrZQUHdW5zdGFrZQQObG9ja0JhbGFuY2VOb3cJAQ1sb2NrZWRCYWxhbmNlAAQNJHQwMTM3MTYxMzkwOQMJAGYCBRJhbW91bnRPZlF1b3RlQXNzZXQFDmxvY2tCYWxhbmNlTm93CQCUCgIFDmxvY2tCYWxhbmNlTm93CQBlAgUSYW1vdW50T2ZRdW90ZUFzc2V0BQ5sb2NrQmFsYW5jZU5vdwkAlAoCBRJhbW91bnRPZlF1b3RlQXNzZXQAAAQKZnJvbUxvY2tlZAgFDSR0MDEzNzE2MTM5MDkCXzEECGZyb21GcmVlCAUNJHQwMTM3MTYxMzkwOQJfMgQPdkxvY2tCYWxhbmNlTm93CQEOdkxvY2tlZEJhbGFuY2UABBJyZWFsTG9ja0JhbGFuY2VOb3cJAGUCBQ5sb2NrQmFsYW5jZU5vdwUPdkxvY2tCYWxhbmNlTm93BA0kdDAxNDAyNzE0MjE1AwkAZgIFCmZyb21Mb2NrZWQFEnJlYWxMb2NrQmFsYW5jZU5vdwkAlAoCBRJyZWFsTG9ja0JhbGFuY2VOb3cJAGUCBQpmcm9tTG9ja2VkBRJyZWFsTG9ja0JhbGFuY2VOb3cJAJQKAgUKZnJvbUxvY2tlZAAABA5mcm9tUmVhbExvY2tlZAgFDSR0MDE0MDI3MTQyMTUCXzEEC2Zyb21WTG9ja2VkCAUNJHQwMTQwMjcxNDIxNQJfMgkAzggCCQDOCAIJAM4IAgMJAGYCBQtmcm9tVkxvY2tlZAAACQEZdXBkYXRlRnJlZUJvcnJvd2VkQmFsYW5jZQEFC2Zyb21WTG9ja2VkBQNuaWwDCQBmAgUIZnJvbUZyZWUAAAQHbmV3UmF0ZQkBDmNvbXB1dGVOZXdSYXRlAQkBAS0BBQhmcm9tRnJlZQkAzggCCQERdXBkYXRlRnJlZUJhbGFuY2UBCQEBLQEFCGZyb21GcmVlCQEKdXBkYXRlUmF0ZQEFB25ld1JhdGUFA25pbAkBE3VwZGF0ZUxvY2tlZEJhbGFuY2UBCQEBLQEFCmZyb21Mb2NrZWQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQEQdXNkbkZyb21EZWNpbWFscwEFEmFtb3VudE9mUXVvdGVBc3NldAkBCnF1b3RlQXNzZXQABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEPd2l0aGRyYXdMb2NrZWRWAQtfYW1vdW50VXNkbgMDAwkBASEBCQELaW5pdGlhbGl6ZWQABgkAZwIAAAULX2Ftb3VudFVzZG4GCQEBIQEJAAACCAUBaQZjYWxsZXIJARFjb2xsYXRlcmFsQWRkcmVzcwAJAAIBAh5JbnZhbGlkIHdpdGhkcmF3TG9ja2VkViBwYXJhbXMEEmFtb3VudE9mUXVvdGVBc3NldAkBDnVzZG5Ub0RlY2ltYWxzAQULX2Ftb3VudFVzZG4EDmxvY2tCYWxhbmNlTm93CQENbG9ja2VkQmFsYW5jZQAEDSR0MDE1MDcyMTUyNjUDCQBmAgUSYW1vdW50T2ZRdW90ZUFzc2V0BQ5sb2NrQmFsYW5jZU5vdwkAlAoCBQ5sb2NrQmFsYW5jZU5vdwkAZQIFEmFtb3VudE9mUXVvdGVBc3NldAUObG9ja0JhbGFuY2VOb3cJAJQKAgUSYW1vdW50T2ZRdW90ZUFzc2V0AAAECmZyb21Mb2NrZWQIBQ0kdDAxNTA3MjE1MjY1Al8xBAhmcm9tRnJlZQgFDSR0MDE1MDcyMTUyNjUCXzIJAM4IAgkAzggCAwkAZgIFCGZyb21GcmVlAAAEB25ld1JhdGUJAQ5jb21wdXRlTmV3UmF0ZQEJAQEtAQUIZnJvbUZyZWUJAM4IAgkBEXVwZGF0ZUZyZWVCYWxhbmNlAQkBAS0BBQhmcm9tRnJlZQkBCnVwZGF0ZVJhdGUBBQduZXdSYXRlBQNuaWwJARN1cGRhdGVMb2NrZWRCYWxhbmNlAQkBAS0BBQpmcm9tTG9ja2VkCQEUdXBkYXRlVkxvY2tlZEJhbGFuY2UBCQEBLQEFEmFtb3VudE9mUXVvdGVBc3NldAFpAQt2aWV3X3Jld2FyZAEHX3N0YWtlcgQHYmFsYW5jZQkBCWJhbGFuY2VPZgEFB19zdGFrZXIED2RlcG9zaXRlZEFtb3VudAkBBG11bGQCCQELYXZlcmFnZVJhdGUBBQdfc3Rha2VyBQdiYWxhbmNlBA1jdXJyZW50QW1vdW50CQEEbXVsZAIJAQRyYXRlAAUHYmFsYW5jZQQGZWFybmVkCQBlAgUNY3VycmVudEFtb3VudAUPZGVwb3NpdGVkQW1vdW50CQACAQkApAMBBQZlYXJuZWQBaQESdmlld193aXRoZHJhd0xpbWl0AQdfc3Rha2VyBBF3aXRoZHJhd0xpbWl0TGVmdAgJARRnZXRXaXRoZHJhd0xpbWl0TGVmdAEFB19zdGFrZXICXzIEC2xpbWl0SW5Vc2RuCQEQdXNkbkZyb21EZWNpbWFscwEJAQRtdWxkAgURd2l0aGRyYXdMaW1pdExlZnQJAQRyYXRlAAkAAgEJAKQDAQULbGltaXRJblVzZG4BAnR4AQZ2ZXJpZnkACQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACQEOYWRtaW5QdWJsaWNLZXkAw/0oEA==", "height": 2357198, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: CePWAsvbqcM4ypm1268t74p7MsF7Bo5GFNqxSfGUZCej Next: AedhUzzEoxMx1HxeTKckrhCuTAEmKim9aXjm3pQM6qip Diff:
Old | New | Differences | |
---|---|---|---|
5 | 5 | ||
6 | 6 | let k_lockedBalance = "k_lockedBalance" | |
7 | 7 | ||
8 | + | let k_vLockedBalance = "k_vLockedBalance" | |
9 | + | ||
8 | 10 | let k_freeBalance = "k_freeBalance" | |
11 | + | ||
12 | + | let k_freeBalanceBorrowed = "k_freeBalanceBorrowed" | |
9 | 13 | ||
10 | 14 | let k_rate = "k_rate" | |
11 | 15 | ||
33 | 37 | ||
34 | 38 | let k_manager_address = "k_manager_address" | |
35 | 39 | ||
40 | + | let k_collateral_address = "k_collateral_address" | |
41 | + | ||
36 | 42 | func toCompositeKey (_key,_address) = ((_key + "_") + _address) | |
37 | 43 | ||
38 | 44 | ||
52 | 58 | ||
53 | 59 | ||
54 | 60 | func managerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_manager_address)), "Manager not set") | |
61 | + | ||
62 | + | ||
63 | + | func collateralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_collateral_address)), "Collateral Manager not set") | |
55 | 64 | ||
56 | 65 | ||
57 | 66 | let DECIMAL_UNIT = (1 * (((((((10 * 10) * 10) * 10) * 10) * 10) * 10) * 10)) | |
121 | 130 | func freeBalance () = int0(k_freeBalance) | |
122 | 131 | ||
123 | 132 | ||
133 | + | func freeBalanceBorrowed () = int0(k_freeBalanceBorrowed) | |
134 | + | ||
135 | + | ||
124 | 136 | func lockedBalance () = int0(k_lockedBalance) | |
137 | + | ||
138 | + | ||
139 | + | func vLockedBalance () = int0(k_vLockedBalance) | |
125 | 140 | ||
126 | 141 | ||
127 | 142 | func initialized () = valueOrElse(getBoolean(this, k_initialized), false) | |
130 | 145 | func getWithdrawLimitLeft (_staker) = { | |
131 | 146 | let currentDate = lastBlock.timestamp | |
132 | 147 | let lastWithdrawDate = lastWithdrawnDate(_staker) | |
133 | - | let $ | |
148 | + | let $t044564720 = if (((currentDate - lastWithdrawDate) > WITHDRAW_PERIOD)) | |
134 | 149 | then $Tuple2(currentDate, withdrawLimit(_staker)) | |
135 | 150 | else $Tuple2(lastWithdrawDate, (withdrawLimit(_staker) - withdrawnInPeriod(_staker))) | |
136 | - | let newLastWithdrawnDate = $ | |
137 | - | let withdrawLimitLeft = $ | |
151 | + | let newLastWithdrawnDate = $t044564720._1 | |
152 | + | let withdrawLimitLeft = $t044564720._2 | |
138 | 153 | $Tuple2(newLastWithdrawnDate, withdrawLimitLeft) | |
154 | + | } | |
155 | + | ||
156 | + | ||
157 | + | func computeNewRate (_amountOfQuoteAsset) = { | |
158 | + | let newRate = if ((totalSupply() > 0)) | |
159 | + | then divd((freeBalance() + _amountOfQuoteAsset), totalSupply()) | |
160 | + | else DECIMAL_UNIT | |
161 | + | newRate | |
139 | 162 | } | |
140 | 163 | ||
141 | 164 | ||
151 | 174 | func updateFreeBalance (_change) = [IntegerEntry(k_freeBalance, (freeBalance() + _change))] | |
152 | 175 | ||
153 | 176 | ||
154 | - | func updateLockedBalance (_change) = [IntegerEntry(k_lockedBalance, (lockedBalance() + _change))] | |
177 | + | func updateFreeBorrowedBalance (_change) = { | |
178 | + | let borrowedBalance = freeBalanceBorrowed() | |
179 | + | if (((borrowedBalance + _change) >= 0)) | |
180 | + | then [IntegerEntry(k_freeBalanceBorrowed, (borrowedBalance + _change))] | |
181 | + | else throw(((("Vault: can not update borrowed free balance. Balance: " + toString(borrowedBalance)) + " change: ") + toString(_change))) | |
182 | + | } | |
183 | + | ||
184 | + | ||
185 | + | func updateLockedBalance (_change) = { | |
186 | + | let balance = lockedBalance() | |
187 | + | if (((balance + _change) >= 0)) | |
188 | + | then [IntegerEntry(k_lockedBalance, (balance + _change))] | |
189 | + | else throw(((("Vault: can not update locked balance. Balance: " + toString(balance)) + " change: ") + toString(_change))) | |
190 | + | } | |
191 | + | ||
192 | + | ||
193 | + | func updateVLockedBalance (_change) = { | |
194 | + | let balance = vLockedBalance() | |
195 | + | if (((balance + _change) >= 0)) | |
196 | + | then [IntegerEntry(k_vLockedBalance, (balance + _change))] | |
197 | + | else throw(((("Vault: can not update v-locked balance. Balance: " + toString(balance)) + " change: ") + toString(_change))) | |
198 | + | } | |
155 | 199 | ||
156 | 200 | ||
157 | 201 | func updateTotalSupply (_change) = [IntegerEntry(k_totalSupply, (totalSupply() + _change))] | |
203 | 247 | else !(initialized())) | |
204 | 248 | then throw("Invalid call to unStake") | |
205 | 249 | else { | |
206 | - | let $ | |
207 | - | let newLastWithdrawnDate = $ | |
208 | - | let withdrawLimitLeft = $ | |
250 | + | let $t088939034 = getWithdrawLimitLeft(_staker) | |
251 | + | let newLastWithdrawnDate = $t088939034._1 | |
252 | + | let withdrawLimitLeft = $t088939034._2 | |
209 | 253 | let vAmount = divd(amountOfQuoteAsset, rate()) | |
210 | 254 | if ((vAmount > withdrawLimitLeft)) | |
211 | 255 | then throw("Invalid call to unStake: withdraw over limit") | |
250 | 294 | ||
251 | 295 | ||
252 | 296 | @Callable(i) | |
253 | - | func addLocked () = { | |
297 | + | func addLocked (_repay) = { | |
254 | 298 | let _amount = usdnToDecimals(i.payments[0].amount) | |
255 | 299 | if (if (if ((i.payments[0].assetId != quoteAsset())) | |
256 | 300 | then true | |
257 | 301 | else !(initialized())) | |
258 | 302 | then true | |
259 | - | else !(if (isWhitelist(toString(i.caller))) | |
303 | + | else !(if (if (isWhitelist(toString(i.caller))) | |
304 | + | then true | |
305 | + | else (i.caller == collateralAddress())) | |
260 | 306 | then true | |
261 | 307 | else (i.caller == adminAddress()))) | |
262 | 308 | then throw("Invalid addLocked params") | |
263 | 309 | else { | |
264 | 310 | let unstake = invoke(managerAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), usdnFromDecimals(_amount))]) | |
265 | 311 | if ((unstake == unstake)) | |
266 | - | then updateLockedBalance(_amount) | |
312 | + | then { | |
313 | + | let freeBorrowed = freeBalanceBorrowed() | |
314 | + | ((if (if (_repay) | |
315 | + | then (freeBorrowed > 0) | |
316 | + | else false) | |
317 | + | then updateFreeBorrowedBalance(-(minv(freeBorrowed, _amount))) | |
318 | + | else nil) ++ updateLockedBalance(_amount)) | |
319 | + | } | |
267 | 320 | else throw("Strict value is not equal to itself.") | |
268 | 321 | } | |
322 | + | } | |
323 | + | ||
324 | + | ||
325 | + | ||
326 | + | @Callable(i) | |
327 | + | func addLockedV (_amountUsdn) = { | |
328 | + | let _amount = usdnToDecimals(_amountUsdn) | |
329 | + | if (if (!(initialized())) | |
330 | + | then true | |
331 | + | else !(if ((i.caller == collateralAddress())) | |
332 | + | then true | |
333 | + | else (i.caller == adminAddress()))) | |
334 | + | then throw("Invalid addLockedV params") | |
335 | + | else (updateLockedBalance(_amount) ++ updateVLockedBalance(_amount)) | |
269 | 336 | } | |
270 | 337 | ||
271 | 338 | ||
279 | 346 | then throw("Invalid exchangeFreeAndLocked params") | |
280 | 347 | else { | |
281 | 348 | let amountOfQuoteAsset = usdnToDecimals(_amount) | |
282 | - | let newRate = if ((totalSupply() > 0)) | |
283 | - | then divd((freeBalance() - amountOfQuoteAsset), totalSupply()) | |
284 | - | else DECIMAL_UNIT | |
285 | - | ((updateLockedBalance(amountOfQuoteAsset) ++ updateFreeBalance(-(amountOfQuoteAsset))) ++ updateRate(newRate)) | |
349 | + | let borrowedBalance = freeBalanceBorrowed() | |
350 | + | let $t01244512932 = if (if ((amountOfQuoteAsset > 0)) | |
351 | + | then (borrowedBalance > 0) | |
352 | + | else false) | |
353 | + | then $Tuple2(-(amountOfQuoteAsset), -(minv(amountOfQuoteAsset, borrowedBalance))) | |
354 | + | else $Tuple2(-(amountOfQuoteAsset), 0) | |
355 | + | let freeUpdate = $t01244512932._1 | |
356 | + | let freeBorrowedUpdate = $t01244512932._2 | |
357 | + | let newRate = computeNewRate(freeUpdate) | |
358 | + | (((updateLockedBalance(amountOfQuoteAsset) ++ updateFreeBalance(freeUpdate)) ++ updateFreeBorrowedBalance(freeBorrowedUpdate)) ++ updateRate(newRate)) | |
286 | 359 | } | |
287 | 360 | ||
288 | 361 | ||
298 | 371 | let amountOfQuoteAsset = usdnToDecimals(_amount) | |
299 | 372 | let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), usdnFromDecimals(amountOfQuoteAsset)], nil) | |
300 | 373 | if ((unstake == unstake)) | |
301 | - | then (updateLockedBalance(-(amountOfQuoteAsset)) ++ [ScriptTransfer(i.caller, usdnFromDecimals(amountOfQuoteAsset), quoteAsset())]) | |
374 | + | then { | |
375 | + | let lockBalanceNow = lockedBalance() | |
376 | + | let $t01371613909 = if ((amountOfQuoteAsset > lockBalanceNow)) | |
377 | + | then $Tuple2(lockBalanceNow, (amountOfQuoteAsset - lockBalanceNow)) | |
378 | + | else $Tuple2(amountOfQuoteAsset, 0) | |
379 | + | let fromLocked = $t01371613909._1 | |
380 | + | let fromFree = $t01371613909._2 | |
381 | + | let vLockBalanceNow = vLockedBalance() | |
382 | + | let realLockBalanceNow = (lockBalanceNow - vLockBalanceNow) | |
383 | + | let $t01402714215 = if ((fromLocked > realLockBalanceNow)) | |
384 | + | then $Tuple2(realLockBalanceNow, (fromLocked - realLockBalanceNow)) | |
385 | + | else $Tuple2(fromLocked, 0) | |
386 | + | let fromRealLocked = $t01402714215._1 | |
387 | + | let fromVLocked = $t01402714215._2 | |
388 | + | ((((if ((fromVLocked > 0)) | |
389 | + | then updateFreeBorrowedBalance(fromVLocked) | |
390 | + | else nil) ++ (if ((fromFree > 0)) | |
391 | + | then { | |
392 | + | let newRate = computeNewRate(-(fromFree)) | |
393 | + | (updateFreeBalance(-(fromFree)) ++ updateRate(newRate)) | |
394 | + | } | |
395 | + | else nil)) ++ updateLockedBalance(-(fromLocked))) ++ [ScriptTransfer(i.caller, usdnFromDecimals(amountOfQuoteAsset), quoteAsset())]) | |
396 | + | } | |
302 | 397 | else throw("Strict value is not equal to itself.") | |
398 | + | } | |
399 | + | ||
400 | + | ||
401 | + | ||
402 | + | @Callable(i) | |
403 | + | func withdrawLockedV (_amountUsdn) = if (if (if (!(initialized())) | |
404 | + | then true | |
405 | + | else (0 >= _amountUsdn)) | |
406 | + | then true | |
407 | + | else !((i.caller == collateralAddress()))) | |
408 | + | then throw("Invalid withdrawLockedV params") | |
409 | + | else { | |
410 | + | let amountOfQuoteAsset = usdnToDecimals(_amountUsdn) | |
411 | + | let lockBalanceNow = lockedBalance() | |
412 | + | let $t01507215265 = if ((amountOfQuoteAsset > lockBalanceNow)) | |
413 | + | then $Tuple2(lockBalanceNow, (amountOfQuoteAsset - lockBalanceNow)) | |
414 | + | else $Tuple2(amountOfQuoteAsset, 0) | |
415 | + | let fromLocked = $t01507215265._1 | |
416 | + | let fromFree = $t01507215265._2 | |
417 | + | (((if ((fromFree > 0)) | |
418 | + | then { | |
419 | + | let newRate = computeNewRate(-(fromFree)) | |
420 | + | (updateFreeBalance(-(fromFree)) ++ updateRate(newRate)) | |
421 | + | } | |
422 | + | else nil) ++ updateLockedBalance(-(fromLocked))) ++ updateVLockedBalance(-(amountOfQuoteAsset))) | |
303 | 423 | } | |
304 | 424 | ||
305 | 425 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let k_totalSupply = "k_totalSupply" | |
5 | 5 | ||
6 | 6 | let k_lockedBalance = "k_lockedBalance" | |
7 | 7 | ||
8 | + | let k_vLockedBalance = "k_vLockedBalance" | |
9 | + | ||
8 | 10 | let k_freeBalance = "k_freeBalance" | |
11 | + | ||
12 | + | let k_freeBalanceBorrowed = "k_freeBalanceBorrowed" | |
9 | 13 | ||
10 | 14 | let k_rate = "k_rate" | |
11 | 15 | ||
12 | 16 | let k_balance = "k_balance" | |
13 | 17 | ||
14 | 18 | let k_average_rate = "k_average_rate" | |
15 | 19 | ||
16 | 20 | let k_withdraw_limit = "k_withdraw_limit" | |
17 | 21 | ||
18 | 22 | let k_last_withdraw_date = "k_last_withdraw_date" | |
19 | 23 | ||
20 | 24 | let k_withdraw_in_period = "k_withdraw_in_period" | |
21 | 25 | ||
22 | 26 | let k_initialized = "k_initialized" | |
23 | 27 | ||
24 | 28 | let k_coordinatorAddress = "k_coordinatorAddress" | |
25 | 29 | ||
26 | 30 | let k_amm = "k_amm" | |
27 | 31 | ||
28 | 32 | let k_quote_asset = "k_quote_asset" | |
29 | 33 | ||
30 | 34 | let k_admin_public_key = "k_admin_public_key" | |
31 | 35 | ||
32 | 36 | let k_admin_address = "k_admin_address" | |
33 | 37 | ||
34 | 38 | let k_manager_address = "k_manager_address" | |
35 | 39 | ||
40 | + | let k_collateral_address = "k_collateral_address" | |
41 | + | ||
36 | 42 | func toCompositeKey (_key,_address) = ((_key + "_") + _address) | |
37 | 43 | ||
38 | 44 | ||
39 | 45 | func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set") | |
40 | 46 | ||
41 | 47 | ||
42 | 48 | func isWhitelist (_address) = valueOrElse(getBoolean(coordinator(), toCompositeKey(k_amm, _address)), false) | |
43 | 49 | ||
44 | 50 | ||
45 | 51 | func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key)) | |
46 | 52 | ||
47 | 53 | ||
48 | 54 | func adminAddress () = addressFromString(valueOrErrorMessage(getString(coordinator(), k_admin_address), "Admin address not set")) | |
49 | 55 | ||
50 | 56 | ||
51 | 57 | func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset)) | |
52 | 58 | ||
53 | 59 | ||
54 | 60 | func managerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_manager_address)), "Manager not set") | |
61 | + | ||
62 | + | ||
63 | + | func collateralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_collateral_address)), "Collateral Manager not set") | |
55 | 64 | ||
56 | 65 | ||
57 | 66 | let DECIMAL_UNIT = (1 * (((((((10 * 10) * 10) * 10) * 10) * 10) * 10) * 10)) | |
58 | 67 | ||
59 | 68 | let DURATION = ((60 * 60) * 24) | |
60 | 69 | ||
61 | 70 | let NO_ADDRESS = "" | |
62 | 71 | ||
63 | 72 | let NO_STAKER = 0 | |
64 | 73 | ||
65 | 74 | func usdnFromDecimals (_amount) = (_amount / 100) | |
66 | 75 | ||
67 | 76 | ||
68 | 77 | func usdnToDecimals (_amount) = (_amount * 100) | |
69 | 78 | ||
70 | 79 | ||
71 | 80 | func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN) | |
72 | 81 | ||
73 | 82 | ||
74 | 83 | func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN) | |
75 | 84 | ||
76 | 85 | ||
77 | 86 | func abs (_x) = if ((_x > 0)) | |
78 | 87 | then _x | |
79 | 88 | else -(_x) | |
80 | 89 | ||
81 | 90 | ||
82 | 91 | func minv (_x,_y) = if ((_x > _y)) | |
83 | 92 | then _y | |
84 | 93 | else _x | |
85 | 94 | ||
86 | 95 | ||
87 | 96 | let WITHDRAW_PERIOD = (86400 * 1000) | |
88 | 97 | ||
89 | 98 | let WITHDRAW_PER_PERIOD = divd((1 * DECIMAL_UNIT), (4 * DECIMAL_UNIT)) | |
90 | 99 | ||
91 | 100 | func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k)) | |
92 | 101 | ||
93 | 102 | ||
94 | 103 | func int0 (k) = valueOrElse(getInteger(this, k), 0) | |
95 | 104 | ||
96 | 105 | ||
97 | 106 | func int1 (k) = valueOrElse(getInteger(this, k), DECIMAL_UNIT) | |
98 | 107 | ||
99 | 108 | ||
100 | 109 | func totalSupply () = int0(k_totalSupply) | |
101 | 110 | ||
102 | 111 | ||
103 | 112 | func rate () = int1(k_rate) | |
104 | 113 | ||
105 | 114 | ||
106 | 115 | func balanceOf (_staker) = int0(toCompositeKey(k_balance, _staker)) | |
107 | 116 | ||
108 | 117 | ||
109 | 118 | func averageRate (_staker) = int0(toCompositeKey(k_average_rate, _staker)) | |
110 | 119 | ||
111 | 120 | ||
112 | 121 | func withdrawLimit (_staker) = int0(toCompositeKey(k_withdraw_limit, _staker)) | |
113 | 122 | ||
114 | 123 | ||
115 | 124 | func withdrawnInPeriod (_staker) = int0(toCompositeKey(k_withdraw_in_period, _staker)) | |
116 | 125 | ||
117 | 126 | ||
118 | 127 | func lastWithdrawnDate (_staker) = int0(toCompositeKey(k_last_withdraw_date, _staker)) | |
119 | 128 | ||
120 | 129 | ||
121 | 130 | func freeBalance () = int0(k_freeBalance) | |
122 | 131 | ||
123 | 132 | ||
133 | + | func freeBalanceBorrowed () = int0(k_freeBalanceBorrowed) | |
134 | + | ||
135 | + | ||
124 | 136 | func lockedBalance () = int0(k_lockedBalance) | |
137 | + | ||
138 | + | ||
139 | + | func vLockedBalance () = int0(k_vLockedBalance) | |
125 | 140 | ||
126 | 141 | ||
127 | 142 | func initialized () = valueOrElse(getBoolean(this, k_initialized), false) | |
128 | 143 | ||
129 | 144 | ||
130 | 145 | func getWithdrawLimitLeft (_staker) = { | |
131 | 146 | let currentDate = lastBlock.timestamp | |
132 | 147 | let lastWithdrawDate = lastWithdrawnDate(_staker) | |
133 | - | let $ | |
148 | + | let $t044564720 = if (((currentDate - lastWithdrawDate) > WITHDRAW_PERIOD)) | |
134 | 149 | then $Tuple2(currentDate, withdrawLimit(_staker)) | |
135 | 150 | else $Tuple2(lastWithdrawDate, (withdrawLimit(_staker) - withdrawnInPeriod(_staker))) | |
136 | - | let newLastWithdrawnDate = $ | |
137 | - | let withdrawLimitLeft = $ | |
151 | + | let newLastWithdrawnDate = $t044564720._1 | |
152 | + | let withdrawLimitLeft = $t044564720._2 | |
138 | 153 | $Tuple2(newLastWithdrawnDate, withdrawLimitLeft) | |
154 | + | } | |
155 | + | ||
156 | + | ||
157 | + | func computeNewRate (_amountOfQuoteAsset) = { | |
158 | + | let newRate = if ((totalSupply() > 0)) | |
159 | + | then divd((freeBalance() + _amountOfQuoteAsset), totalSupply()) | |
160 | + | else DECIMAL_UNIT | |
161 | + | newRate | |
139 | 162 | } | |
140 | 163 | ||
141 | 164 | ||
142 | 165 | func updateUserBalance (_user,_change) = [IntegerEntry(toCompositeKey(k_balance, _user), (balanceOf(_user) + _change))] | |
143 | 166 | ||
144 | 167 | ||
145 | 168 | func setUserWithdrawLimit (_user,_rate) = [IntegerEntry(toCompositeKey(k_withdraw_limit, _user), _rate)] | |
146 | 169 | ||
147 | 170 | ||
148 | 171 | func setUserAverageRate (_user,_rate) = [IntegerEntry(toCompositeKey(k_average_rate, _user), _rate)] | |
149 | 172 | ||
150 | 173 | ||
151 | 174 | func updateFreeBalance (_change) = [IntegerEntry(k_freeBalance, (freeBalance() + _change))] | |
152 | 175 | ||
153 | 176 | ||
154 | - | func updateLockedBalance (_change) = [IntegerEntry(k_lockedBalance, (lockedBalance() + _change))] | |
177 | + | func updateFreeBorrowedBalance (_change) = { | |
178 | + | let borrowedBalance = freeBalanceBorrowed() | |
179 | + | if (((borrowedBalance + _change) >= 0)) | |
180 | + | then [IntegerEntry(k_freeBalanceBorrowed, (borrowedBalance + _change))] | |
181 | + | else throw(((("Vault: can not update borrowed free balance. Balance: " + toString(borrowedBalance)) + " change: ") + toString(_change))) | |
182 | + | } | |
183 | + | ||
184 | + | ||
185 | + | func updateLockedBalance (_change) = { | |
186 | + | let balance = lockedBalance() | |
187 | + | if (((balance + _change) >= 0)) | |
188 | + | then [IntegerEntry(k_lockedBalance, (balance + _change))] | |
189 | + | else throw(((("Vault: can not update locked balance. Balance: " + toString(balance)) + " change: ") + toString(_change))) | |
190 | + | } | |
191 | + | ||
192 | + | ||
193 | + | func updateVLockedBalance (_change) = { | |
194 | + | let balance = vLockedBalance() | |
195 | + | if (((balance + _change) >= 0)) | |
196 | + | then [IntegerEntry(k_vLockedBalance, (balance + _change))] | |
197 | + | else throw(((("Vault: can not update v-locked balance. Balance: " + toString(balance)) + " change: ") + toString(_change))) | |
198 | + | } | |
155 | 199 | ||
156 | 200 | ||
157 | 201 | func updateTotalSupply (_change) = [IntegerEntry(k_totalSupply, (totalSupply() + _change))] | |
158 | 202 | ||
159 | 203 | ||
160 | 204 | func updateRate (_rate) = [IntegerEntry(k_rate, _rate)] | |
161 | 205 | ||
162 | 206 | ||
163 | 207 | func setUserWithdrawParams (_user,_lastWithdrawDate,_withdrawn) = [IntegerEntry(toCompositeKey(k_last_withdraw_date, _user), _lastWithdrawDate), IntegerEntry(toCompositeKey(k_withdraw_in_period, _user), _withdrawn)] | |
164 | 208 | ||
165 | 209 | ||
166 | 210 | @Callable(i) | |
167 | 211 | func initialize (_coordinator) = if (initialized()) | |
168 | 212 | then throw("Already initialized") | |
169 | 213 | else [StringEntry(k_coordinatorAddress, _coordinator), BooleanEntry(k_initialized, true)] | |
170 | 214 | ||
171 | 215 | ||
172 | 216 | ||
173 | 217 | @Callable(i) | |
174 | 218 | func stake () = { | |
175 | 219 | let _staker = toString(i.caller) | |
176 | 220 | let _amount = usdnToDecimals(i.payments[0].amount) | |
177 | 221 | if (if ((i.payments[0].assetId != quoteAsset())) | |
178 | 222 | then true | |
179 | 223 | else !(initialized())) | |
180 | 224 | then throw("Invalid call to stake") | |
181 | 225 | else { | |
182 | 226 | let currentRate = rate() | |
183 | 227 | let prevAverageRate = averageRate(_staker) | |
184 | 228 | let vAmount = divd(_amount, currentRate) | |
185 | 229 | let newAverageRate = divd((muld(vAmount, currentRate) + muld(balanceOf(_staker), prevAverageRate)), (currentRate + prevAverageRate)) | |
186 | 230 | let newTotalBalance = (vAmount + balanceOf(_staker)) | |
187 | 231 | let newWithdrawLimit = muld(newTotalBalance, WITHDRAW_PER_PERIOD) | |
188 | 232 | let stake = invoke(managerAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), usdnFromDecimals(_amount))]) | |
189 | 233 | if ((stake == stake)) | |
190 | 234 | then ((((updateFreeBalance(_amount) ++ updateUserBalance(_staker, vAmount)) ++ setUserAverageRate(_staker, newAverageRate)) ++ setUserWithdrawLimit(_staker, newWithdrawLimit)) ++ updateTotalSupply(vAmount)) | |
191 | 235 | else throw("Strict value is not equal to itself.") | |
192 | 236 | } | |
193 | 237 | } | |
194 | 238 | ||
195 | 239 | ||
196 | 240 | ||
197 | 241 | @Callable(i) | |
198 | 242 | func unStake (_amount) = { | |
199 | 243 | let _staker = toString(i.caller) | |
200 | 244 | let amountOfQuoteAsset = usdnToDecimals(_amount) | |
201 | 245 | if (if ((i.payments != nil)) | |
202 | 246 | then true | |
203 | 247 | else !(initialized())) | |
204 | 248 | then throw("Invalid call to unStake") | |
205 | 249 | else { | |
206 | - | let $ | |
207 | - | let newLastWithdrawnDate = $ | |
208 | - | let withdrawLimitLeft = $ | |
250 | + | let $t088939034 = getWithdrawLimitLeft(_staker) | |
251 | + | let newLastWithdrawnDate = $t088939034._1 | |
252 | + | let withdrawLimitLeft = $t088939034._2 | |
209 | 253 | let vAmount = divd(amountOfQuoteAsset, rate()) | |
210 | 254 | if ((vAmount > withdrawLimitLeft)) | |
211 | 255 | then throw("Invalid call to unStake: withdraw over limit") | |
212 | 256 | else { | |
213 | 257 | let newWithdrawnInPeriod = (withdrawnInPeriod(_staker) + vAmount) | |
214 | 258 | if ((amountOfQuoteAsset > freeBalance())) | |
215 | 259 | then throw("Invalid call to unStake: balance too low") | |
216 | 260 | else { | |
217 | 261 | let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), usdnFromDecimals(amountOfQuoteAsset)], nil) | |
218 | 262 | if ((unstake == unstake)) | |
219 | 263 | then ((((updateFreeBalance(-(amountOfQuoteAsset)) ++ updateUserBalance(_staker, -(vAmount))) ++ updateTotalSupply(-(vAmount))) ++ setUserWithdrawParams(_staker, newLastWithdrawnDate, newWithdrawnInPeriod)) ++ [ScriptTransfer(i.caller, usdnFromDecimals(amountOfQuoteAsset), quoteAsset())]) | |
220 | 264 | else throw("Strict value is not equal to itself.") | |
221 | 265 | } | |
222 | 266 | } | |
223 | 267 | } | |
224 | 268 | } | |
225 | 269 | ||
226 | 270 | ||
227 | 271 | ||
228 | 272 | @Callable(i) | |
229 | 273 | func addFree () = { | |
230 | 274 | let _amount = usdnToDecimals(i.payments[0].amount) | |
231 | 275 | if (if (if ((i.payments[0].assetId != quoteAsset())) | |
232 | 276 | then true | |
233 | 277 | else !(initialized())) | |
234 | 278 | then true | |
235 | 279 | else !(if (isWhitelist(toString(i.caller))) | |
236 | 280 | then true | |
237 | 281 | else (i.caller == adminAddress()))) | |
238 | 282 | then throw("Invalid addFree params") | |
239 | 283 | else { | |
240 | 284 | let newRate = if ((totalSupply() > 0)) | |
241 | 285 | then divd((freeBalance() + _amount), totalSupply()) | |
242 | 286 | else DECIMAL_UNIT | |
243 | 287 | let unstake = invoke(managerAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), usdnFromDecimals(_amount))]) | |
244 | 288 | if ((unstake == unstake)) | |
245 | 289 | then (updateFreeBalance(_amount) ++ updateRate(newRate)) | |
246 | 290 | else throw("Strict value is not equal to itself.") | |
247 | 291 | } | |
248 | 292 | } | |
249 | 293 | ||
250 | 294 | ||
251 | 295 | ||
252 | 296 | @Callable(i) | |
253 | - | func addLocked () = { | |
297 | + | func addLocked (_repay) = { | |
254 | 298 | let _amount = usdnToDecimals(i.payments[0].amount) | |
255 | 299 | if (if (if ((i.payments[0].assetId != quoteAsset())) | |
256 | 300 | then true | |
257 | 301 | else !(initialized())) | |
258 | 302 | then true | |
259 | - | else !(if (isWhitelist(toString(i.caller))) | |
303 | + | else !(if (if (isWhitelist(toString(i.caller))) | |
304 | + | then true | |
305 | + | else (i.caller == collateralAddress())) | |
260 | 306 | then true | |
261 | 307 | else (i.caller == adminAddress()))) | |
262 | 308 | then throw("Invalid addLocked params") | |
263 | 309 | else { | |
264 | 310 | let unstake = invoke(managerAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), usdnFromDecimals(_amount))]) | |
265 | 311 | if ((unstake == unstake)) | |
266 | - | then updateLockedBalance(_amount) | |
312 | + | then { | |
313 | + | let freeBorrowed = freeBalanceBorrowed() | |
314 | + | ((if (if (_repay) | |
315 | + | then (freeBorrowed > 0) | |
316 | + | else false) | |
317 | + | then updateFreeBorrowedBalance(-(minv(freeBorrowed, _amount))) | |
318 | + | else nil) ++ updateLockedBalance(_amount)) | |
319 | + | } | |
267 | 320 | else throw("Strict value is not equal to itself.") | |
268 | 321 | } | |
322 | + | } | |
323 | + | ||
324 | + | ||
325 | + | ||
326 | + | @Callable(i) | |
327 | + | func addLockedV (_amountUsdn) = { | |
328 | + | let _amount = usdnToDecimals(_amountUsdn) | |
329 | + | if (if (!(initialized())) | |
330 | + | then true | |
331 | + | else !(if ((i.caller == collateralAddress())) | |
332 | + | then true | |
333 | + | else (i.caller == adminAddress()))) | |
334 | + | then throw("Invalid addLockedV params") | |
335 | + | else (updateLockedBalance(_amount) ++ updateVLockedBalance(_amount)) | |
269 | 336 | } | |
270 | 337 | ||
271 | 338 | ||
272 | 339 | ||
273 | 340 | @Callable(i) | |
274 | 341 | func exchangeFreeAndLocked (_amount) = if (if (!(initialized())) | |
275 | 342 | then true | |
276 | 343 | else !(if (isWhitelist(toString(i.caller))) | |
277 | 344 | then true | |
278 | 345 | else (i.caller == adminAddress()))) | |
279 | 346 | then throw("Invalid exchangeFreeAndLocked params") | |
280 | 347 | else { | |
281 | 348 | let amountOfQuoteAsset = usdnToDecimals(_amount) | |
282 | - | let newRate = if ((totalSupply() > 0)) | |
283 | - | then divd((freeBalance() - amountOfQuoteAsset), totalSupply()) | |
284 | - | else DECIMAL_UNIT | |
285 | - | ((updateLockedBalance(amountOfQuoteAsset) ++ updateFreeBalance(-(amountOfQuoteAsset))) ++ updateRate(newRate)) | |
349 | + | let borrowedBalance = freeBalanceBorrowed() | |
350 | + | let $t01244512932 = if (if ((amountOfQuoteAsset > 0)) | |
351 | + | then (borrowedBalance > 0) | |
352 | + | else false) | |
353 | + | then $Tuple2(-(amountOfQuoteAsset), -(minv(amountOfQuoteAsset, borrowedBalance))) | |
354 | + | else $Tuple2(-(amountOfQuoteAsset), 0) | |
355 | + | let freeUpdate = $t01244512932._1 | |
356 | + | let freeBorrowedUpdate = $t01244512932._2 | |
357 | + | let newRate = computeNewRate(freeUpdate) | |
358 | + | (((updateLockedBalance(amountOfQuoteAsset) ++ updateFreeBalance(freeUpdate)) ++ updateFreeBorrowedBalance(freeBorrowedUpdate)) ++ updateRate(newRate)) | |
286 | 359 | } | |
287 | 360 | ||
288 | 361 | ||
289 | 362 | ||
290 | 363 | @Callable(i) | |
291 | 364 | func withdrawLocked (_amount) = if (if (if (!(initialized())) | |
292 | 365 | then true | |
293 | 366 | else (0 >= _amount)) | |
294 | 367 | then true | |
295 | 368 | else !(isWhitelist(toString(i.caller)))) | |
296 | 369 | then throw("Invalid withdrawLocked params") | |
297 | 370 | else { | |
298 | 371 | let amountOfQuoteAsset = usdnToDecimals(_amount) | |
299 | 372 | let unstake = invoke(managerAddress(), "withdraw", [toBase58String(quoteAsset()), usdnFromDecimals(amountOfQuoteAsset)], nil) | |
300 | 373 | if ((unstake == unstake)) | |
301 | - | then (updateLockedBalance(-(amountOfQuoteAsset)) ++ [ScriptTransfer(i.caller, usdnFromDecimals(amountOfQuoteAsset), quoteAsset())]) | |
374 | + | then { | |
375 | + | let lockBalanceNow = lockedBalance() | |
376 | + | let $t01371613909 = if ((amountOfQuoteAsset > lockBalanceNow)) | |
377 | + | then $Tuple2(lockBalanceNow, (amountOfQuoteAsset - lockBalanceNow)) | |
378 | + | else $Tuple2(amountOfQuoteAsset, 0) | |
379 | + | let fromLocked = $t01371613909._1 | |
380 | + | let fromFree = $t01371613909._2 | |
381 | + | let vLockBalanceNow = vLockedBalance() | |
382 | + | let realLockBalanceNow = (lockBalanceNow - vLockBalanceNow) | |
383 | + | let $t01402714215 = if ((fromLocked > realLockBalanceNow)) | |
384 | + | then $Tuple2(realLockBalanceNow, (fromLocked - realLockBalanceNow)) | |
385 | + | else $Tuple2(fromLocked, 0) | |
386 | + | let fromRealLocked = $t01402714215._1 | |
387 | + | let fromVLocked = $t01402714215._2 | |
388 | + | ((((if ((fromVLocked > 0)) | |
389 | + | then updateFreeBorrowedBalance(fromVLocked) | |
390 | + | else nil) ++ (if ((fromFree > 0)) | |
391 | + | then { | |
392 | + | let newRate = computeNewRate(-(fromFree)) | |
393 | + | (updateFreeBalance(-(fromFree)) ++ updateRate(newRate)) | |
394 | + | } | |
395 | + | else nil)) ++ updateLockedBalance(-(fromLocked))) ++ [ScriptTransfer(i.caller, usdnFromDecimals(amountOfQuoteAsset), quoteAsset())]) | |
396 | + | } | |
302 | 397 | else throw("Strict value is not equal to itself.") | |
398 | + | } | |
399 | + | ||
400 | + | ||
401 | + | ||
402 | + | @Callable(i) | |
403 | + | func withdrawLockedV (_amountUsdn) = if (if (if (!(initialized())) | |
404 | + | then true | |
405 | + | else (0 >= _amountUsdn)) | |
406 | + | then true | |
407 | + | else !((i.caller == collateralAddress()))) | |
408 | + | then throw("Invalid withdrawLockedV params") | |
409 | + | else { | |
410 | + | let amountOfQuoteAsset = usdnToDecimals(_amountUsdn) | |
411 | + | let lockBalanceNow = lockedBalance() | |
412 | + | let $t01507215265 = if ((amountOfQuoteAsset > lockBalanceNow)) | |
413 | + | then $Tuple2(lockBalanceNow, (amountOfQuoteAsset - lockBalanceNow)) | |
414 | + | else $Tuple2(amountOfQuoteAsset, 0) | |
415 | + | let fromLocked = $t01507215265._1 | |
416 | + | let fromFree = $t01507215265._2 | |
417 | + | (((if ((fromFree > 0)) | |
418 | + | then { | |
419 | + | let newRate = computeNewRate(-(fromFree)) | |
420 | + | (updateFreeBalance(-(fromFree)) ++ updateRate(newRate)) | |
421 | + | } | |
422 | + | else nil) ++ updateLockedBalance(-(fromLocked))) ++ updateVLockedBalance(-(amountOfQuoteAsset))) | |
303 | 423 | } | |
304 | 424 | ||
305 | 425 | ||
306 | 426 | ||
307 | 427 | @Callable(i) | |
308 | 428 | func view_reward (_staker) = { | |
309 | 429 | let balance = balanceOf(_staker) | |
310 | 430 | let depositedAmount = muld(averageRate(_staker), balance) | |
311 | 431 | let currentAmount = muld(rate(), balance) | |
312 | 432 | let earned = (currentAmount - depositedAmount) | |
313 | 433 | throw(toString(earned)) | |
314 | 434 | } | |
315 | 435 | ||
316 | 436 | ||
317 | 437 | ||
318 | 438 | @Callable(i) | |
319 | 439 | func view_withdrawLimit (_staker) = { | |
320 | 440 | let withdrawLimitLeft = getWithdrawLimitLeft(_staker)._2 | |
321 | 441 | let limitInUsdn = usdnFromDecimals(muld(withdrawLimitLeft, rate())) | |
322 | 442 | throw(toString(limitInUsdn)) | |
323 | 443 | } | |
324 | 444 | ||
325 | 445 | ||
326 | 446 | @Verifier(tx) | |
327 | 447 | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey()) | |
328 | 448 |
github/deemru/w8io/169f3d6 66.22 ms ◑