2022.01.19 20:57 [2951207] smart account 3PAZv9tgK1PX7dKR7b4kchq5qdpUS3G5sYT > SELF 0.00000000 Waves

{ "type": 13, "id": "EmWEq8XmGgLoGazRJC7ND3dUHZZkWj8NrcFkjoL7uQi5", "fee": 1000000, "feeAssetId": null, "timestamp": 1642614917917, "version": 1, "sender": "3PAZv9tgK1PX7dKR7b4kchq5qdpUS3G5sYT", "senderPublicKey": "2cFG5wZimjVSeCT8ZCRybx7Mzo5tJF879aw2b31uLRmR", "proofs": [ "4wh2W9TzxMQQwHny7ioNncp6HJ2joSVRmfRanigMDMZU8f3tNBupqmv9mwp2Q42nrifwSF8NHjpqqUV8HTHcqPyN" ], "script": "base64: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AA1yZXNlcnZlc1N0b3JlAgAAAAhyZXNlcnZlcwAAAAANYVRva2VuSWRTdG9yZQIAAAAIYVRva2VuSWQAAAAADGFzc2V0SWRTdG9yZQIAAAAHYXNzZXRJZAAAAAAQZGlzdHJpYnV0b3JTdG9yZQIAAAARdmlyZXNfZGlzdHJpYnV0b3IAAAAABWFkbWluCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAAphZG1pblN0b3JlAAAAAAZjb25maWcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAC2NvbmZpZ1N0b3JlAAAAAAtyZXNlcnZlc1N0cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADXJlc2VydmVzU3RvcmUCAAAAFm5vIHJlc2VydmVzIHJlZ2lzdGVyZWQAAAAACHJlc2VydmVzCQAEtQAAAAIFAAAAC3Jlc2VydmVzU3RyAgAAAAF8AAAAAANlYlIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAZjb25maWcCAAAACmViX3Jld2FyZHMCAAAAIG5vIGViX3Jld2FyZHMgY29udHJhY3QgaW4gY29uZmlnAAAAAAt2aXJlc01pbnRlcgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAZjb25maWcCAAAADHZpcmVzX21pbnRlcgIAAAAUbWFpbjogbm8gdmlyZXNNaW50ZXICAAAAE2ludmFsaWQgdmlyZXNNaW50ZXIAAAAAB21heWJldlMJAAQdAAAAAgUAAAAGY29uZmlnAgAAAAx2aXJlc19zdGFrZXIAAAAAAnZTCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIFAAAAB21heWJldlMCAAAAD25vIHZpcmVzX3N0YWtlcgAAAAACZEMJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAGY29uZmlnAgAAABJkaXZpZGVuZHNfY29udHJhY3QCAAAAFW5vIGRpdmlkZW5kc19jb250cmFjdAIAAAAaaW52YWxpZCBkaXZpZGVuZHNfY29udHJhY3QAAAAAA21WRAQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAZjb25maWcFAAAAEGRpc3RyaWJ1dG9yU3RvcmUDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABZAUAAAAHJG1hdGNoMAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAABZAUAAAAEdW5pdAAAAAACVkQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgUAAAADbVZEAgAAAB9ubyBkaXN0cmlidXRvciB0byBjbGFpbSByZXdhcmRzAAAAABFtYXliZVZpcmVzQXNzZXRJZAkABB0AAAACBQAAAAt2aXJlc01pbnRlcgIAAAAHYXNzZXRJZAAAAAAMdmlyZXNBc3NldElkCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAJZAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACBQAAABFtYXliZVZpcmVzQXNzZXRJZAIAAAAXdmlyZXMgYXNzZXRJZCBub3QgZm91bmQCAAAAFWludmFsaWQgdmlyZXMgYXNzZXRJZAEAAAAQYXNzZXRJZE9mUmVzZXJ2ZQAAAAEAAAAHcmVzZXJ2ZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAB3Jlc2VydmUFAAAADGFzc2V0SWRTdG9yZQIAAAAVbm8gYXNzZXRJZCBpbiByZXNlcnZlAQAAABBjb2xsYXRlcmFsRmFjdG9yAAAAAQAAAAdyZXNlcnZlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAGY29uZmlnCQABLAAAAAIJAQAAABBhc3NldElkT2ZSZXNlcnZlAAAAAQUAAAAHcmVzZXJ2ZQIAAAARX0NvbGxhdGVyYWxGYWN0b3ICAAAAHW5vIENvbGxhdGVyYWxGYWN0b3IgaW4gY29uZmlnAQAAABRsaXF1aWRhdGlvblRocmVzaG9sZAAAAAEAAAAHcmVzZXJ2ZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABmNvbmZpZwkAASwAAAACCQEAAAAQYXNzZXRJZE9mUmVzZXJ2ZQAAAAEFAAAAB3Jlc2VydmUCAAAAFV9MaXF1aWRhdGlvblRocmVzaG9sZAIAAAAhbm8gTGlxdWlkYXRpb25UaHJlc2hvbGQgaW4gY29uZmlnAQAAABJsaXF1aWRhdGlvblBlbmFsdHkAAAABAAAAB2Fzc2V0SWQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZjb25maWcJAAEsAAAAAgUAAAAHYXNzZXRJZAIAAAATX0xpcXVpZGF0aW9uUGVuYWx0eQIAAAAfbm8gTGlxdWlkYXRpb25QZW5hbHR5IGluIGNvbmZpZwAAAAAWYWNjb3VudEhlYWx0aFRocmVzaG9sZAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABmNvbmZpZwIAAAAYYWNjb3VudF9oZWFsdGhfdGhyZXNob2xkAgAAABtubyBhY2NvdW50X2hlYWx0aF90aHJlc2hvbGQAAAAAFGFjY291bnRIZWFsdGhPdmVybGFwCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAGY29uZmlnAgAAABZhY2NvdW50X2hlYWx0aF9vdmVybGFwAgAAABlubyBhY2NvdW50X2hlYWx0aF9vdmVybGFwAAAAAA9jb2xsYXBzZVBlbmFsdHkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZjb25maWcCAAAAEGNvbGxhcHNlX3BlbmFsdHkCAAAAE25vIGNvbGxhcHNlX3BlbmFsdHkAAAAAC2xpcXVpZGF0b3JzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABmNvbmZpZwIAAAALbGlxdWlkYXRvcnMCAAAAAAEAAAANZmluZFJlc2VydmVCeQAAAAIAAAAFc3RvcmUAAAAFdmFsdWUK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AAAABnRvdGFsRAgFAAAACyR0MDUyMjg1MjU3AAAAAl8xBAAAAAZ0b3RhbEIIBQAAAAskdDA1MjI4NTI1NwAAAAJfMgQAAAAHcmVzZXJ2ZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEFAAAAAXICAAAAE3Jlc2VydmUgYmFkIGFkZHJlc3MEAAAAAmNmCQEAAAAQY29sbGF0ZXJhbEZhY3RvcgAAAAEFAAAAB3Jlc2VydmUEAAAAAmx0CQEAAAAUbGlxdWlkYXRpb25UaHJlc2hvbGQAAAABBQAAAAdyZXNlcnZlBAAAAAskdDA1NDI3NTUxNQkBAAAAC3VzZXJCYWxhbmNlAAAAAgUAAAAHcmVzZXJ2ZQUAAAAEdXNlcgQAAAAFdG9rZW4IBQAAAAskdDA1NDI3NTUxNQAAAAJfMQQAAAAFYXNzZXQIBQAAAAskdDA1NDI3NTUxNQAAAAJfMgQAAAAKZGVwb3NpdFVzZAgFAAAACyR0MDU0Mjc1NTE1AAAAAl8zBAAAAARkZWJ0CAUAAAALJHQwNTQyNzU1MTUAAAACXzQEAAAAB2RlYnRVc2QIBQAAAAskdDA1NDI3NTUxNQAAAAJfNQQAAAAMYXNDb2xsYXRlcmFsCAUAAAALJHQwNTQyNzU1MTUAAAACXzYEAAAAE2VmZmVjdGl2ZURlcG9zaXRVc2QDBQAAAAxhc0NvbGxhdGVyYWwFAAAACmRlcG9zaXRVc2QAAAAAAAAAAAAEAAAACm92ZXJsYXBVc2QJAAGXAAAAAQkABEwAAAACBQAAAAdkZWJ0VXNkCQAETAAAAAIFAAAAE2VmZmVjdGl2ZURlcG9zaXRVc2QFAAAAA25pbAQAAAANb3ZlcmxhcENoYXJnZQkBAAAADGZyYWN0aW9uQ2VpbAAAAAMFAAAACm92ZXJsYXBVc2QFAAAAFGFjY291bnRIZWFsdGhPdmVybGFwBQAAAAtmYWN0b3JzQmFzZQMJAABmAAAAAgUAAAAHZGVidFVzZAUAAAATZWZmZWN0aXZlRGVwb3NpdFVzZAkABRQAAAACBQAAAAZ0b3RhbEQJAABkAAAAAgkAAGQAAAACBQAAAAZ0b3RhbEIJAABrAAAAAwkAAGUAAAACBQAAAAdkZWJ0VXNkBQAAABNlZmZlY3RpdmVEZXBvc2l0VXNkBQAA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ZSBkZXBvc2l0IG5vdCB1c2VkIGFzIGNvbGxhdGVyYWwEAAAADSR0MDEwNTY0MTA2NTQJAQAAAAt1c2VyQmFsYW5jZQAAAAIFAAAAAmJyBQAAAAhib3Jyb3dlcgMJAAAAAAAAAgUAAAANJHQwMTA1NjQxMDY1NAUAAAANJHQwMTA1NjQxMDY1NAQAAAALdXNlckRlYnRVc2QIBQAAAA0kdDAxMDU2NDEwNjU0AAAAAl81BAAAAAh1c2VyRGVidAgFAAAADSR0MDEwNTY0MTA2NTQAAAACXzQEAAAADHVzZXJBc3NldFVzZAgFAAAADSR0MDEwNTY0MTA2NTQAAAACXzMEAAAACXVzZXJBc3NldAgFAAAADSR0MDEwNTY0MTA2NTQAAAACXzIEAAAABmlnbm9yZQgFAAAADSR0MDEwNTY0MTA2NTQAAAACXzEDCQAAZwAAAAIFAAAACXVzZXJBc3NldAUAAAAIdXNlckRlYnQJAAACAAAAAQIAAAAvY2FuJ3QgbGlxdWlkYXRlIGRlYnQgb2YgYXNzZXQgb2YgcG9zaXRpdmUgc2FsZG8DCQAAZwAAAAIAAAAAAAAAAAAFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQJAAACAAAAAQIAAAAnY2FuJ3QgbGlxdWlkYXRlIHplcm8gb3IgbmVnYXRpdmUgYW1vdW50AwkAAGYAAAACCQAAaAAAAAIFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQAAAAAAAAAAAIJAABlAAAAAgUAAAAIdXNlckRlYnQFAAAACXVzZXJBc3NldAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAuY2FuJ3QgbGlxdWlkYXRlIG1vcmUgdGhhbiBoYWxmIG9mIHNhbGRvOiBkZWJ0PQkAAaQAAAABBQAAAAh1c2VyRGVidAIAAAAKLCBkZXBvc2l0PQkAAaQAAAABBQAAAAl1c2VyQXNzZXQCAAAAGCwgbGlxdWlkYXRlRGVidEFtb3VudCA9IAkAAaQAAAABBQAAABNsaXF1aWRhdGVEZWJ0QW1vdW50BAAAAA1jb2xsYXRlcmFsVXNkCQAAawAAAAMFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQFAAAAC3VzZXJEZWJ0VXNkBQAAAAh1c2VyRGVidAQAAAANcGVuYWx0aXplZFVzZAkAAGsAAAADBQAAAA1jb2xsYXRlcmFsVXNkCQAAZAAAAAIFAAAAC2ZhY3RvcnNCYXNlCQEAAAASbGlxdWlkYXRpb25QZW5hbHR5AAAAAQUAAAALYm9ycm93QXNzZXQFAAAAC2ZhY3RvcnNCYXNlBAAAAAJtYwMFAAAADWZyb21Qcm90ZWN0ZWQJAQAAAA5tb3ZlQ29sbGF0ZXJhbAAAAAQFAAAACGJvcnJvd2VyBQAAAA9jb2xsYXRlcmFsQXNzZXQFAAAAAmNyBQAAABFjb2xsYXRlcmFsUmVzZXJ2ZQUAAAAEdW5pdAMJAAAAAAAAAgUAAAACbWMFAAAAAm1jBAAAABV0cmFuc2ZlcnJlZENvbGxhdGVyYWwJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAACY3ICAAAAEnRyYW5zZmVyQVRva2Vuc0ZvcgkABEwAAAACBQAAAAhib3Jyb3dlcgkABEwAAAACBQAAAApsaXF1aWRhdG9yCQAETAAAAAIFAAAADXBlbmFsdGl6ZWRVc2QFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAABV0cmFuc2ZlcnJlZENvbGxhdGVyYWwFAAAAFXRyYW5zZmVycmVkQ29sbGF0ZXJhbAQAAAAEcFJ3MQkBAAAACm1vdmVTdHJlYW0AAAAFBQAAABFjb2xsYXRlcmFsUmVzZXJ2ZQIAAAAHZGVwb3NpdAUAAAAIYm9ycm93ZXIFAAAACmxpcXVpZGF0b3IFAAAAFXRyYW5zZmVycmVkQ29sbGF0ZXJhbAMJAAAAAAAAAgUAAAAEcFJ3MQUAAAAEcFJ3MQQAAAAPdHJhbnNmZXJyZWREZWJ0CQEAAAAFYXNJbnQAAAABCQAD/AAAAAQFAAAAAmJyAgAAAA90cmFuc2ZlckRlYnRGb3IJAARMAAAAAgUAAAAIYm9ycm93ZXIJAARMAAAAAgUAAAAKbGlxdWlkYXRvcgkABEwAAAACBQAAABNsaXF1aWRhdGVEZWJ0QW1vdW50BQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAPdHJhbnNmZXJyZWREZWJ0BQAAAA90cmFuc2ZlcnJlZERlYnQEAAAABHBSdzIJAQAAAAptb3ZlU3RyZWFtAAAABQUAAAANYm9ycm93UmVzZXJ2ZQIAAAAGYm9ycm93BQAAAAhib3Jyb3dlcgUAAAAKbGlxdWlkYXRvcgUAAAAPdHJhbnNmZXJyZWREZWJ0AwkAAAAAAAACBQAAAARwUncyBQAAAARwUncyBAAAABVsaXF1aWRhdG9ySGVhbHRoQ2hlY2sDCQEAAAAIY29udGFpbnMAAAACBQAAAAtsaXF1aWRhdG9ycwUAAAAKbGlxdWlkYXRvcgUAAAADbmlsCQEAAAANdmFsaWRhdGVBZnRlcgAAAAIFAAAACmxpcXVpZGF0b3ICAAAAEXRyYW5zZmVycmluZyBkZWJ0AwkAAAAAAAACBQAAABVsaXF1aWRhdG9ySGVhbHRoQ2hlY2sFAAAAFWxpcXVpZGF0b3JIZWFsdGhDaGVjawkABRQAAAACBQAAABVsaXF1aWRhdG9ySGVhbHRoQ2hlY2sFAAAAFXRyYW5zZmVycmVkQ29sbGF0ZXJhbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAAAAFWZvcmNlQ29sbGFwc2VJbnRlcm5hbAAAAAQAAAAKbGlxdWlkYXRvcgAAAAdyZXNlcnZlAAAACGJvcnJvd2VyAAAADWZyb21Qcm90ZWN0ZWQEAAAADnJlc2VydmVBZGRyZXNzCQEAAAAPdmFsaWRhdGVSZXNlcnZlAAAAAQUAAAAHcmVzZXJ2ZQMJAAAAAAAAAgUAAAAOcmVzZXJ2ZUFkZHJlc3MFAAAADnJlc2VydmVBZGRyZXNzBAAAAAJzaAkBAAAAEXN5bmNSZXdhcmRzSGVpZ2h0AAAAAQUAAAAHcmVzZXJ2ZQMJAAAAAAAAAgUAAAACc2gFAAAAAnNoAwkAAAAAAAACBQAAAApsaXF1aWRhdG9yBQAAAAhib3Jyb3dlcgkAAAIAAAABAgAAACRjYW4ndCBjb2xsYXBzZSBzZWxmIGluIHRoaXMgZnVuY3Rpb24EAAAADSR0MDEyMzQxMTIzNzYJAQAAAAl1c2VyUG93ZXIAAAABBQAAAAhib3Jyb3dlcgQAAAACYnAIBQAAAA0kdDAxMjM0MTEyMzc2AAAAAl8xBAAAAANicHUIBQAAAA0kdDAxMjM0MTEyMzc2AAAAAl8yAwkAAGYAAAACBQAAAAJicAUAAAADYnB1CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACVjYW4ndCBmb3JjZSBjb2xsYXBzZSBoZWFsdGh5IHVzZXI6IHU9BQAAAAhib3Jyb3dlcgIAAAAFLCBicD0JAAGkAAAAAQUAAAACYnACAAAABiwgYnB1PQkAAaQAAAABBQAAAANicHUEAAAABWFzc2V0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAOcmVzZXJ2ZUFkZHJlc3MCAAAAB2Fzc2V0SWQJAAEsAAAAAgIAAAAcbm8gYXNzZXRJZCBmaWVsZCBpbiByZXNlcnZlIAUAAAAHcmVzZXJ2ZQQAAAACbWMDBQAAAA1mcm9tUHJvdGVjdGVkCQEAAAAObW92ZUNvbGxhdGVyYWwAAAAEBQAAAAhib3Jyb3dlcgUAAAAFYXNzZXQFAAAADnJlc2VydmVBZGRyZXNzBQAAAAdyZXNlcnZlBQAAAAR1bml0AwkAAAAAAAACBQAAAAJtYwUAAAACbWMEAAAADSR0MDEyNzUyMTI4NjAJAQAAAAt1c2VyQmFsYW5jZQAAAAIFAAAADnJlc2VydmVBZGRyZXNzBQAAAAhib3Jyb3dlcgMJAAAAAAAAAgUAAAANJHQwMTI3NTIxMjg2MAUAAAANJHQwMTI3NTIxMjg2MAQAAAALdXNlckRlYnRVc2QIBQAAAA0kdDAxMjc1MjEyODYwAAAAAl81BAAAAAh1c2VyRGVidAgFAAAADSR0MDEyNzUyMTI4NjAAAAACXzQEAAAADHVzZXJBc3NldFVzZAgFAAAADSR0MDEyNzUyMTI4NjAAAAACXzMEAAAAD2JvcnJvd2VyRGVwb3NpdAgFAAAADSR0MDEyNzUyMTI4NjAAAAACXzIEAAAABmlnbm9yZQgFAAAADSR0MDEyNzUyMTI4NjAAAAACXzEEAAAADXBlbmFsdGl6ZWRVc2QJAABrAAAAAwkAAZcAAAABCQAETAAAAAIFAAAADHVzZXJBc3NldFVzZAkABEwAAAACBQAAAAt1c2VyRGVidFVzZAUAAAADbmlsBQAAAA9jb2xsYXBzZVBlbmFsdHkFAAAAC2ZhY3RvcnNCYXNlBAAAABF0cmFuc2ZlcnJlZEFzc2V0cwkBAAAABWFzSW50AAAAAQkAA/wAAAAEBQAAAA5yZXNlcnZlQWRkcmVzcwIAAAASdHJhbnNmZXJBVG9rZW5zRm9yCQAETAAAAAIFAAAACGJvcnJvd2VyCQAETAAAAAIFAAAACmxpcXVpZGF0b3IJAARMAAAAAgUAAAANcGVuYWx0aXplZFVzZAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAEXRyYW5zZmVycmVkQXNzZXRzBQAAABF0cmFuc2ZlcnJlZEFzc2V0cwQAAAAEcFJ3MQkBAAAACm1vdmVTdHJlYW0AAAAFBQAAAAdyZXNlcnZlAgAAAAdkZXBvc2l0BQAAAAhib3Jyb3dlcgUAAAAKbGlxdWlkYXRvcgUAAAARdHJhbnNmZXJyZWRBc3NldHMDCQAAAAAAAAIFAAAABHBSdzEFAAAABHBSdzEEAAAACWNvbGxhcHNlZAkBAAAABWFzSW50AAAAAQkAA/wAAAAEBQAAAA5yZXNlcnZlQWRkcmVzcwIAAAALY29sbGFwc2VGb3IJAARMAAAAAgUAAAAIYm9ycm93ZXIFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAljb2xsYXBzZWQFAAAACWNvbGxhcHNlZAQAAAAE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AAdyZXNlcnZlBAAAAAR1c2VyCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPZG9TZXRDb2xsYXRlcmFsCQAD/AAAAAQJAQAAAA92YWxpZGF0ZVJlc2VydmUAAAABBQAAAAdyZXNlcnZlAgAAABlkaXNhYmxlVXNlQXNDb2xsYXRlcmFsRm9yCQAETAAAAAIFAAAABHVzZXIFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAA9kb1NldENvbGxhdGVyYWwFAAAAD2RvU2V0Q29sbGF0ZXJhbAkBAAAADXZhbGlkYXRlQWZ0ZXIAAAACBQAAAAR1c2VyAgAAABpjaGFuZ2luZyBjb2xsYXRlcmFsIHN0YXR1cwkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAMdHJhbnNmZXJEZWJ0AAAABAAAAA1ib3Jyb3dSZXNlcnZlAAAAEWNvbGxhdGVyYWxSZXNlcnZlAAAACGJvcnJvd2VyAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQJAQAAABR0cmFuc2ZlckRlYnRJbnRlcm5hbAAAAAYJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAAA1ib3Jyb3dSZXNlcnZlBQAAABFjb2xsYXRlcmFsUmVzZXJ2ZQUAAAAIYm9ycm93ZXIFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQHAAAAAWkBAAAADWZvcmNlQ29sbGFwc2UAAAACAAAAB3Jlc2VydmUAAAAIYm9ycm93ZXIJAQAAABVmb3JjZUNvbGxhcHNlSW50ZXJuYWwAAAAECQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgUAAAAHcmVzZXJ2ZQUAAAAIYm9ycm93ZXIHAAAAAWkBAAAACWxvY2tWaXJlcwAAAAIAAAAGZmFjdG9yAAAAB21pZ3JhdGUEAAAABHVzZXIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAlhY3R1YWxpemUJAAP8AAAABAUAAAACZEMCAAAAF3NoYXJlUHJvZml0RnJvbVJlc2VydmVzBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAJYWN0dWFsaXplBQAAAAlhY3R1YWxpemUEAAAADW1pZ3JhdGVBbW91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", "chainId": 87, "height": 2951207, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BcVQveN3Ct6VjL26XSajfKuNhHxkhY3DgNMYbxUVCA42 Next: rtoNMDpyMmKs1RxRcifMzBkrVXFbFzRnhVSqFbCQ1nr Diff:
OldNewDifferences
8686
8787 let reserves = split(reservesStr, "|")
8888
89-let viresMinter = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "vires_minter"), "no viresMinter")), "invalid viresMinter")
89+let ebR = addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config"))
9090
91-let maybeViresStaker = getString(config, "vires_staker")
91+let viresMinter = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "vires_minter"), "main: no viresMinter")), "invalid viresMinter")
9292
93-let viresStaker = addressFromStringValue(valueOrErrorMessage(maybeViresStaker, "no vires_staker"))
93+let maybevS = getString(config, "vires_staker")
9494
95-let maybeViresDistributor = match getString(config, distributorStore) {
95+let vS = addressFromStringValue(valueOrErrorMessage(maybevS, "no vires_staker"))
96+
97+let dC = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "dividends_contract"), "no dividends_contract")), "invalid dividends_contract")
98+
99+let mVD = match getString(config, distributorStore) {
96100 case d: String =>
97101 addressFromStringValue(d)
98102 case _ =>
99103 unit
100104 }
105+
106+let VD = valueOrErrorMessage(mVD, "no distributor to claim rewards")
101107
102108 let maybeViresAssetId = getString(viresMinter, "assetId")
103109
162168 func userBalance (reserve,user) = asUserBalanceData(invoke(reserve, "userBalance", [user], nil))
163169
164170
171+let maybeProtectedReserve = match getString(config, "protected_reserve") {
172+ case pds: String =>
173+ valueOrErrorMessage(addressFromString(pds), "bad protected_reserve")
174+ case _ =>
175+ unit
176+}
177+
178+let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected reserve")
179+
165180 func userPower (user) = {
181+ let protectedDeposit = match maybeProtectedReserve {
182+ case pa: Address =>
183+ asInt(invoke(pa, "borrowPower", [user], nil))
184+ case _ =>
185+ 0
186+ }
166187 func fold (totals,r) = {
167- let $t044314460 = totals
168- let totalD = $t044314460._1
169- let totalB = $t044314460._2
188+ let $t052285257 = totals
189+ let totalD = $t052285257._1
190+ let totalB = $t052285257._2
170191 let reserve = valueOrErrorMessage(addressFromString(r), "reserve bad address")
171192 let cf = collateralFactor(reserve)
172193 let lt = liquidationThreshold(reserve)
173- let $t046314719 = userBalance(reserve, user)
174- let token = $t046314719._1
175- let asset = $t046314719._2
176- let depositUsd = $t046314719._3
177- let debt = $t046314719._4
178- let debtUsd = $t046314719._5
179- let asCollateral = $t046314719._6
194+ let $t054275515 = userBalance(reserve, user)
195+ let token = $t054275515._1
196+ let asset = $t054275515._2
197+ let depositUsd = $t054275515._3
198+ let debt = $t054275515._4
199+ let debtUsd = $t054275515._5
200+ let asCollateral = $t054275515._6
180201 let effectiveDepositUsd = if (asCollateral)
181202 then depositUsd
182203 else 0
189210
190211 let $l = reserves
191212 let $s = size($l)
192- let $acc0 = $Tuple2(0, 0)
213+ let $acc0 = $Tuple2(protectedDeposit, 0)
193214 func $f0_1 ($a,$i) = if (($i >= $s))
194215 then $a
195216 else fold($a, $l[$i])
203224
204225
205226 func getUserHealth (account) = {
206- let $t052645307 = asInt2(userPower(account))
207- let bp = $t052645307._1
208- let bpu = $t052645307._2
227+ let $t060766119 = asInt2(userPower(account))
228+ let bp = $t060766119._1
229+ let bpu = $t060766119._2
209230 ((("bp:" + toString(bp)) + ", bpu:") + toString(bpu))
210231 }
211232
212233
213234 func validateAfter (user,op) = {
214- let $t054185449 = userPower(user)
215- let bp = $t054185449._1
216- let bpu = $t054185449._2
235+ let $t062306261 = userPower(user)
236+ let bp = $t062306261._1
237+ let bpu = $t062306261._2
217238 let accHealth = (((bp - bpu) * factorsBase) / bp)
218239 if (if ((bp == 0))
219240 then (bpu == 0)
229250 }
230251
231252
232-func updateStream (reserve,action,user,userChange,streamChange) = match maybeViresDistributor {
253+func updateStream (reserve,action,user,userChange,streamChange) = match mVD {
233254 case a: Address =>
234255 invoke(a, "onAction", [reserve, action, user, userChange, streamChange], nil)
235256 case _ =>
237258 }
238259
239260
240-func moveStream (reserve,action,from,string,amount) = match maybeViresDistributor {
261+func moveStream (reserve,action,from,string,amount) = match mVD {
241262 case a: Address =>
242263 invoke(a, "move", [reserve, action, from, string, amount], nil)
243264 case _ =>
245266 }
246267
247268
248-func syncRewardsHeight (reserve) = match maybeViresDistributor {
269+func syncRewardsHeight (reserve) = match mVD {
249270 case a: Address =>
250271 invoke(a, "syncHeight", [reserve], nil)
251272 case _ =>
256277 func stakeOrPayout (recipient,amount,stake) = if (!(stake))
257278 then [ScriptTransfer(recipient, amount, viresAssetId)]
258279 else {
259- let doStake = invoke(viresStaker, "stakeVires", [toString(recipient)], [AttachedPayment(viresAssetId, amount)])
280+ let doStake = invoke(vS, "stakeVires", [toString(recipient)], [AttachedPayment(viresAssetId, amount)])
260281 if ((doStake == doStake))
282+ then nil
283+ else throw("Strict value is not equal to itself.")
284+ }
285+
286+
287+func lockOrPayout (recipient,amount,lock) = if (!(lock))
288+ then [ScriptTransfer(recipient, amount, viresAssetId)]
289+ else {
290+ let doLock = invoke(dC, "lockFor", [toString(recipient), 1], [AttachedPayment(viresAssetId, amount)])
291+ if ((doLock == doLock))
261292 then nil
262293 else throw("Strict value is not equal to itself.")
263294 }
272303 if ((action == action))
273304 then {
274305 let amt = i.payments[0].amount
275- let propagateRewards = updateStream(reserve, "deposit", user, amt, amt)
276- if ((propagateRewards == propagateRewards))
306+ let pRw = updateStream(reserve, "deposit", user, amt, amt)
307+ if ((pRw == pRw))
277308 then if (!(useAsCollateral))
278309 then validateAfter(user, "depositing")
279310 else nil
286317
287318
288319 func claimAllRewardsForUser (user) = {
289- let distributor = valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards")
290- let rewardReserves = split(valueOrErrorMessage(getString(distributor, "reward_reserves"), "no string"), "|")
291- func fold (acc,reserve) = {
292- let claimed = asInt(invoke(valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards"), "claimRewardFor", [reserve, user, -1], nil))
293- if ((claimed == claimed))
294- then (acc + claimed)
295- else throw("Strict value is not equal to itself.")
296- }
320+ let claimedEb = asInt(invoke(ebR, "claimEbRewardFor", [user, -1], nil))
321+ if ((claimedEb == claimedEb))
322+ then {
323+ let rewardReserves = split(valueOrErrorMessage(getString(VD, "reward_reserves"), "no string"), "|")
324+ func fold (acc,reserve) = {
325+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, -1], nil))
326+ if ((claimed == claimed))
327+ then (acc + claimed)
328+ else throw("Strict value is not equal to itself.")
329+ }
297330
298- let claimedTotal = {
299- let $l = rewardReserves
300- let $s = size($l)
301- let $acc0 = 0
302- func $f0_1 ($a,$i) = if (($i >= $s))
303- then $a
304- else fold($a, $l[$i])
331+ let claimedTotal = {
332+ let $l = rewardReserves
333+ let $s = size($l)
334+ let $acc0 = 0
335+ func $f0_1 ($a,$i) = if (($i >= $s))
336+ then $a
337+ else fold($a, $l[$i])
305338
306- func $f0_2 ($a,$i) = if (($i >= $s))
307- then $a
308- else throw("List size exceeds 7")
339+ func $f0_2 ($a,$i) = if (($i >= $s))
340+ then $a
341+ else throw("List size exceeds 7")
309342
310- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
311- }
312- claimedTotal
343+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
344+ }
345+ (claimedTotal + claimedEb)
346+ }
347+ else throw("Strict value is not equal to itself.")
348+ }
349+
350+
351+func moveCollateral (addr,assetStr,reserve,reserveStr) = {
352+ let amt = asInt(invoke(protectedReserve, "withdrawToMain", [addr, assetStr], nil))
353+ if ((amt == amt))
354+ then {
355+ let assetId = if ((assetStr == "WAVES"))
356+ then unit
357+ else fromBase58String(assetStr)
358+ let dep = invoke(reserve, "depositFor", [addr, true], [AttachedPayment(assetId, amt)])
359+ if ((dep == dep))
360+ then {
361+ let prop = updateStream(reserveStr, "deposit", addr, amt, amt)
362+ if ((prop == prop))
363+ then unit
364+ else throw("Strict value is not equal to itself.")
365+ }
366+ else throw("Strict value is not equal to itself.")
367+ }
368+ else throw("Strict value is not equal to itself.")
369+ }
370+
371+
372+func transferDebtInternal (liquidator,borrowReserve,collateralReserve,borrower,liquidateDebtAmount,fromProtected) = {
373+ let sh1 = syncRewardsHeight(borrowReserve)
374+ if ((sh1 == sh1))
375+ then {
376+ let sh2 = syncRewardsHeight(collateralReserve)
377+ if ((sh2 == sh2))
378+ then if ((0 >= liquidateDebtAmount))
379+ then throw("can't liquidate non-positive amount")
380+ else if ((collateralReserve == borrowReserve))
381+ then throw("collateralReserve equals borrowReserve")
382+ else if ((liquidator == borrower))
383+ then throw("can't liquidate self")
384+ else {
385+ let $t098649899 = userPower(borrower)
386+ let bp = $t098649899._1
387+ let bpu = $t098649899._2
388+ if ((bp > bpu))
389+ then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
390+ else {
391+ let br = validateReserve(borrowReserve)
392+ let cr = validateReserve(collateralReserve)
393+ let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve))
394+ let collateralAsset = valueOrErrorMessage(getString(cr, "assetId"), ("no assetId field in collateralReserve " + collateralReserve))
395+ let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false)
396+ if ((isCollateral == isCollateral))
397+ then if (if (!(fromProtected))
398+ then !(isCollateral)
399+ else false)
400+ then throw("can't liquidate deposit not used as collateral")
401+ else {
402+ let $t01056410654 = userBalance(br, borrower)
403+ if (($t01056410654 == $t01056410654))
404+ then {
405+ let userDebtUsd = $t01056410654._5
406+ let userDebt = $t01056410654._4
407+ let userAssetUsd = $t01056410654._3
408+ let userAsset = $t01056410654._2
409+ let ignore = $t01056410654._1
410+ if ((userAsset >= userDebt))
411+ then throw("can't liquidate debt of asset of positive saldo")
412+ else if ((0 >= liquidateDebtAmount))
413+ then throw("can't liquidate zero or negative amount")
414+ else if (((liquidateDebtAmount * 2) > (userDebt - userAsset)))
415+ then throw(((((("can't liquidate more than half of saldo: debt=" + toString(userDebt)) + ", deposit=") + toString(userAsset)) + ", liquidateDebtAmount = ") + toString(liquidateDebtAmount)))
416+ else {
417+ let collateralUsd = fraction(liquidateDebtAmount, userDebtUsd, userDebt)
418+ let penaltizedUsd = fraction(collateralUsd, (factorsBase + liquidationPenalty(borrowAsset)), factorsBase)
419+ let mc = if (fromProtected)
420+ then moveCollateral(borrower, collateralAsset, cr, collateralReserve)
421+ else unit
422+ if ((mc == mc))
423+ then {
424+ let transferredCollateral = asInt(invoke(cr, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
425+ if ((transferredCollateral == transferredCollateral))
426+ then {
427+ let pRw1 = moveStream(collateralReserve, "deposit", borrower, liquidator, transferredCollateral)
428+ if ((pRw1 == pRw1))
429+ then {
430+ let transferredDebt = asInt(invoke(br, "transferDebtFor", [borrower, liquidator, liquidateDebtAmount], nil))
431+ if ((transferredDebt == transferredDebt))
432+ then {
433+ let pRw2 = moveStream(borrowReserve, "borrow", borrower, liquidator, transferredDebt)
434+ if ((pRw2 == pRw2))
435+ then {
436+ let liquidatorHealthCheck = if (contains(liquidators, liquidator))
437+ then nil
438+ else validateAfter(liquidator, "transferring debt")
439+ if ((liquidatorHealthCheck == liquidatorHealthCheck))
440+ then $Tuple2(liquidatorHealthCheck, transferredCollateral)
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ else throw("Strict value is not equal to itself.")
444+ }
445+ else throw("Strict value is not equal to itself.")
446+ }
447+ else throw("Strict value is not equal to itself.")
448+ }
449+ else throw("Strict value is not equal to itself.")
450+ }
451+ else throw("Strict value is not equal to itself.")
452+ }
453+ }
454+ else throw("Strict value is not equal to itself.")
455+ }
456+ else throw("Strict value is not equal to itself.")
457+ }
458+ }
459+ else throw("Strict value is not equal to itself.")
460+ }
461+ else throw("Strict value is not equal to itself.")
462+ }
463+
464+
465+func forceCollapseInternal (liquidator,reserve,borrower,fromProtected) = {
466+ let reserveAddress = validateReserve(reserve)
467+ if ((reserveAddress == reserveAddress))
468+ then {
469+ let sh = syncRewardsHeight(reserve)
470+ if ((sh == sh))
471+ then if ((liquidator == borrower))
472+ then throw("can't collapse self in this function")
473+ else {
474+ let $t01234112376 = userPower(borrower)
475+ let bp = $t01234112376._1
476+ let bpu = $t01234112376._2
477+ if ((bp > bpu))
478+ then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
479+ else {
480+ let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in reserve " + reserve))
481+ let mc = if (fromProtected)
482+ then moveCollateral(borrower, asset, reserveAddress, reserve)
483+ else unit
484+ if ((mc == mc))
485+ then {
486+ let $t01275212860 = userBalance(reserveAddress, borrower)
487+ if (($t01275212860 == $t01275212860))
488+ then {
489+ let userDebtUsd = $t01275212860._5
490+ let userDebt = $t01275212860._4
491+ let userAssetUsd = $t01275212860._3
492+ let borrowerDeposit = $t01275212860._2
493+ let ignore = $t01275212860._1
494+ let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase)
495+ let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
496+ if ((transferredAssets == transferredAssets))
497+ then {
498+ let pRw1 = moveStream(reserve, "deposit", borrower, liquidator, transferredAssets)
499+ if ((pRw1 == pRw1))
500+ then {
501+ let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil))
502+ if ((collapsed == collapsed))
503+ then {
504+ let pRw2 = updateStream(reserve, "borrow", borrower, -(collapsed), -(collapsed))
505+ if ((pRw2 == pRw2))
506+ then {
507+ let pRw3 = updateStream(reserve, "deposit", borrower, -(collapsed), -(collapsed))
508+ if ((pRw3 == pRw3))
509+ then nil
510+ else throw("Strict value is not equal to itself.")
511+ }
512+ else throw("Strict value is not equal to itself.")
513+ }
514+ else throw("Strict value is not equal to itself.")
515+ }
516+ else throw("Strict value is not equal to itself.")
517+ }
518+ else throw("Strict value is not equal to itself.")
519+ }
520+ else throw("Strict value is not equal to itself.")
521+ }
522+ else throw("Strict value is not equal to itself.")
523+ }
524+ }
525+ else throw("Strict value is not equal to itself.")
526+ }
527+ else throw("Strict value is not equal to itself.")
313528 }
314529
315530
344559 let repaid = asInt(invoke(validateReserve(reserve), "repayFor", [user], i.payments))
345560 if ((repaid == repaid))
346561 then {
347- let propagateRewards = updateStream(reserve, "borrow", user, -(repaid), -(repaid))
348- if ((propagateRewards == propagateRewards))
562+ let pRw = updateStream(reserve, "borrow", user, -(repaid), -(repaid))
563+ if ((pRw == pRw))
349564 then nil
350565 else throw("Strict value is not equal to itself.")
351566 }
366581 let mintedAssetAmount = asInt(invoke(targetContract, "mintAtokenFor", [user, amount], nil))
367582 if ((mintedAssetAmount == mintedAssetAmount))
368583 then {
369- let propagateRewards = updateStream(toString(targetContract), "deposit", user, -(mintedAssetAmount), 0)
370- if ((propagateRewards == propagateRewards))
584+ let pRw = updateStream(toString(targetContract), "deposit", user, -(mintedAssetAmount), 0)
585+ if ((pRw == pRw))
371586 then validateAfter(user, "minting")
372587 else throw("Strict value is not equal to itself.")
373588 }
381596 @Callable(i)
382597 func replenishWithAtoken () = {
383598 let user = toString(i.caller)
384- let aTokenId = match i.payments[0].assetId {
385- case bv: ByteVector =>
386- toBase58String(bv)
387- case _ =>
388- throw("bad assetId: waves not allowed")
389- }
599+ let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed"))
390600 let targetContract = findReserveBy(aTokenIdStore, aTokenId)
391601 let sh = syncRewardsHeight(toString(targetContract))
392602 if ((sh == sh))
394604 let replenishedAssetAmount = asInt(invoke(targetContract, "replenishWithAtokenFor", [user], i.payments))
395605 if ((replenishedAssetAmount == replenishedAssetAmount))
396606 then {
397- let propagateRewards = updateStream(toString(targetContract), "deposit", user, replenishedAssetAmount, 0)
398- if ((propagateRewards == propagateRewards))
607+ let pRw = updateStream(toString(targetContract), "deposit", user, replenishedAssetAmount, 0)
608+ if ((pRw == pRw))
399609 then nil
400610 else throw("Strict value is not equal to itself.")
401611 }
409619 @Callable(i)
410620 func redeemAtokens () = {
411621 let user = toString(i.caller)
412- let aTokenId = match i.payments[0].assetId {
413- case bv: ByteVector =>
414- toBase58String(bv)
415- case _ =>
416- throw("bad assetId: waves not allowed")
417- }
622+ let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed"))
418623 let targetContract = findReserveBy(aTokenIdStore, aTokenId)
419624 let sh = syncRewardsHeight(toString(targetContract))
420625 if ((sh == sh))
422627 let redeemedAssetAmount = asInt(invoke(targetContract, "redeemAtokensFor", [user], i.payments))
423628 if ((redeemedAssetAmount == redeemedAssetAmount))
424629 then {
425- let propagateRewards = updateStream(toString(targetContract), "deposit", user, 0, -(redeemedAssetAmount))
426- if ((propagateRewards == propagateRewards))
630+ let pRw = updateStream(toString(targetContract), "deposit", user, 0, -(redeemedAssetAmount))
631+ if ((pRw == pRw))
427632 then nil
428633 else throw("Strict value is not equal to itself.")
429634 }
444649 let withdrawnAmount = asInt(invoke(targetContract, "withdrawFor", [user, amount], nil))
445650 if ((withdrawnAmount == withdrawnAmount))
446651 then {
447- let propagateRewards = updateStream(toString(targetContract), "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
448- if ((propagateRewards == propagateRewards))
652+ let pRw = updateStream(toString(targetContract), "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
653+ if ((pRw == pRw))
449654 then validateAfter(user, "withdrawing")
450655 else throw("Strict value is not equal to itself.")
451656 }
465670 let withdrawnAmount = asInt(invoke(validateReserve(reserve), "withdrawFor", [user, amount], nil))
466671 if ((withdrawnAmount == withdrawnAmount))
467672 then {
468- let propagateRewards = updateStream(reserve, "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
469- if ((propagateRewards == propagateRewards))
673+ let pRw = updateStream(reserve, "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
674+ if ((pRw == pRw))
470675 then if (contains(liquidators, user))
471676 then nil
472677 else validateAfter(user, "withdrawing2")
474679 }
475680 else throw("Strict value is not equal to itself.")
476681 }
682+ else throw("Strict value is not equal to itself.")
683+ }
684+
685+
686+
687+@Callable(i)
688+func withdrawProtectedCollateral (assetId,amount) = {
689+ let user = toString(i.caller)
690+ let withdrawnAmount = asInt(invoke(valueOrErrorMessage(protectedReserve, "no protectedReserve"), "withdrawFor", [user, assetId, amount], nil))
691+ if ((withdrawnAmount == withdrawnAmount))
692+ then validateAfter(user, "withdrawing protected collateral")
477693 else throw("Strict value is not equal to itself.")
478694 }
479695
489705 let action = invoke(reserve, "borrowFor", [user, amount], nil)
490706 if ((action == action))
491707 then {
492- let propagateRewards = updateStream(toString(reserve), "borrow", user, amount, amount)
493- if ((propagateRewards == propagateRewards))
708+ let pRw = updateStream(toString(reserve), "borrow", user, amount, amount)
709+ if ((pRw == pRw))
494710 then validateAfter(user, "borrowing")
495711 else throw("Strict value is not equal to itself.")
496712 }
510726 let action = invoke(validateReserve(reserve), "borrowFor", [user, amount], nil)
511727 if ((action == action))
512728 then {
513- let propagateRewards = updateStream(reserve, "borrow", user, amount, amount)
514- if ((propagateRewards == propagateRewards))
729+ let pRw = updateStream(reserve, "borrow", user, amount, amount)
730+ if ((pRw == pRw))
515731 then validateAfter(user, "borrowing")
516732 else throw("Strict value is not equal to itself.")
517733 }
531747 let collapse = asInt(invoke(validateReserve(reserve), "collapseForAmount", [user, amount], nil))
532748 if ((collapse == collapse))
533749 then {
534- let propagateRewards = updateStream(reserve, "borrow", user, -(collapse), -(collapse))
535- if ((propagateRewards == propagateRewards))
750+ let pRw = updateStream(reserve, "borrow", user, -(collapse), -(collapse))
751+ if ((pRw == pRw))
536752 then {
537- let propagateRewards2 = updateStream(reserve, "deposit", user, -(collapse), -(collapse))
538- if ((propagateRewards2 == propagateRewards2))
753+ let pRw2 = updateStream(reserve, "deposit", user, -(collapse), -(collapse))
754+ if ((pRw2 == pRw2))
539755 then nil
540756 else throw("Strict value is not equal to itself.")
541757 }
551767 @Callable(i)
552768 func claimEbReward (amount,stake) = {
553769 let user = toString(i.caller)
554- let r = addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config"))
555- let claimed = asInt(invoke(r, "claimEbRewardFor", [user, amount], nil))
770+ let claimed = asInt(invoke(ebR, "claimEbRewardFor", [user, amount], nil))
556771 if ((claimed == claimed))
557772 then stakeOrPayout(i.caller, claimed, stake)
773+ else throw("Strict value is not equal to itself.")
774+ }
775+
776+
777+
778+@Callable(i)
779+func claimEbReward2 (amount,lock) = {
780+ let user = toString(i.caller)
781+ let claimed = asInt(invoke(ebR, "claimEbRewardFor", [user, amount], nil))
782+ if ((claimed == claimed))
783+ then lockOrPayout(i.caller, claimed, lock)
558784 else throw("Strict value is not equal to itself.")
559785 }
560786
566792 if ((v == v))
567793 then {
568794 let user = toString(i.caller)
569- let claimed = asInt(invoke(valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards"), "claimRewardFor", [reserve, user, amount], nil))
795+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, amount], nil))
570796 if ((claimed == claimed))
571797 then stakeOrPayout(i.caller, claimed, stake)
572798 else throw("Strict value is not equal to itself.")
577803
578804
579805 @Callable(i)
580-func claimAllRewards (stake) = {
581- let user = toString(i.caller)
582- let claimedTotal = claimAllRewardsForUser(user)
583- stakeOrPayout(i.caller, claimedTotal, stake)
806+func claimReward2 (reserve,amount,lock) = {
807+ let v = validateReserve(reserve)
808+ if ((v == v))
809+ then {
810+ let user = toString(i.caller)
811+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, amount], nil))
812+ if ((claimed == claimed))
813+ then lockOrPayout(i.caller, claimed, lock)
814+ else throw("Strict value is not equal to itself.")
815+ }
816+ else throw("Strict value is not equal to itself.")
584817 }
585818
586819
588821 @Callable(i)
589822 func claimAllRewardsAndAllEbAvailable (stake) = {
590823 let user = toString(i.caller)
591- let claimedEb = asInt(invoke(addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config")), "claimEbRewardFor", [user, -1], nil))
592- if ((claimedEb == claimedEb))
824+ stakeOrPayout(i.caller, claimAllRewardsForUser(user), stake)
825+ }
826+
827+
828+
829+@Callable(i)
830+func claimAllRewardsAndAllEbAvailable2 (lock,unstakeLegacy) = {
831+ let user = toString(i.caller)
832+ let claimedRewards = claimAllRewardsForUser(user)
833+ if ((claimedRewards == claimedRewards))
593834 then {
594- let claimedRewards = claimAllRewardsForUser(user)
595- if ((claimedRewards == claimedRewards))
596- then {
597- let claimedTotal = (claimedEb + claimedRewards)
598- if ((claimedTotal == claimedTotal))
599- then stakeOrPayout(i.caller, claimedTotal, stake)
600- else throw("Strict value is not equal to itself.")
601- }
835+ let lA = if (unstakeLegacy)
836+ then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
837+ else 0
838+ if ((lA == lA))
839+ then lockOrPayout(i.caller, (claimedRewards + lA), lock)
602840 else throw("Strict value is not equal to itself.")
603841 }
604842 else throw("Strict value is not equal to itself.")
618856
619857
620858 @Callable(i)
621-func transferDebt (borrowReserve,collateralReserve,borrower,liquidateDebtAmount) = {
622- let sh1 = syncRewardsHeight(borrowReserve)
623- if ((sh1 == sh1))
859+func transferDebt (borrowReserve,collateralReserve,borrower,liquidateDebtAmount) = transferDebtInternal(toString(i.caller), borrowReserve, collateralReserve, borrower, liquidateDebtAmount, false)
860+
861+
862+
863+@Callable(i)
864+func forceCollapse (reserve,borrower) = forceCollapseInternal(toString(i.caller), reserve, borrower, false)
865+
866+
867+
868+@Callable(i)
869+func lockVires (factor,migrate) = {
870+ let user = toString(i.caller)
871+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
872+ if ((actualize == actualize))
624873 then {
625- let sh2 = syncRewardsHeight(collateralReserve)
626- if ((sh2 == sh2))
627- then if ((0 >= liquidateDebtAmount))
628- then throw("can't liquidate non-positive amount")
629- else if ((collateralReserve == borrowReserve))
630- then throw("collateralReserve equals borrowReserve")
631- else {
632- let liquidator = toString(i.caller)
633- if ((liquidator == borrower))
634- then throw("can't liquidate self")
635- else {
636- let $t01479614831 = userPower(borrower)
637- let bp = $t01479614831._1
638- let bpu = $t01479614831._2
639- if ((bp > bpu))
640- then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
641- else {
642- let br = validateReserve(borrowReserve)
643- let cr = validateReserve(collateralReserve)
644- let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve))
645- let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false)
646- if ((isCollateral == isCollateral))
647- then if (!(isCollateral))
648- then throw("can't liquidate deposit not used as collateral")
649- else {
650- let $t01534715437 = userBalance(br, borrower)
651- if (($t01534715437 == $t01534715437))
652- then {
653- let userDebtUsd = $t01534715437._5
654- let userDebt = $t01534715437._4
655- let userAssetUsd = $t01534715437._3
656- let userAsset = $t01534715437._2
657- let ignore = $t01534715437._1
658- if ((userAsset >= userDebt))
659- then throw("can't liquidate debt of asset of positive saldo")
660- else if ((0 >= liquidateDebtAmount))
661- then throw("can't liquidate zero or negative amount")
662- else if (((liquidateDebtAmount * 2) > (userDebt - userAsset)))
663- then throw(((((("can't liquidate more than half of saldo: debt=" + toString(userDebt)) + ", deposit=") + toString(userAsset)) + ", liquidateDebtAmount = ") + toString(liquidateDebtAmount)))
664- else {
665- let collateralUsd = fraction(liquidateDebtAmount, userDebtUsd, userDebt)
666- let penaltizedUsd = fraction(collateralUsd, (factorsBase + liquidationPenalty(borrowAsset)), factorsBase)
667- let transferredCollateral = asInt(invoke(cr, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
668- if ((transferredCollateral == transferredCollateral))
669- then {
670- let propagateRewards1 = moveStream(collateralReserve, "deposit", borrower, liquidator, transferredCollateral)
671- if ((propagateRewards1 == propagateRewards1))
672- then {
673- let transferredDebt = asInt(invoke(br, "transferDebtFor", [borrower, liquidator, liquidateDebtAmount], nil))
674- if ((transferredDebt == transferredDebt))
675- then {
676- let propagateRewards2 = moveStream(borrowReserve, "borrow", borrower, liquidator, transferredDebt)
677- if ((propagateRewards2 == propagateRewards2))
678- then {
679- let liquidatorHealthCheck = if (contains(liquidators, liquidator))
680- then nil
681- else validateAfter(liquidator, "transferring debt")
682- if ((liquidatorHealthCheck == liquidatorHealthCheck))
683- then $Tuple2(liquidatorHealthCheck, transferredCollateral)
684- else throw("Strict value is not equal to itself.")
685- }
686- else throw("Strict value is not equal to itself.")
687- }
688- else throw("Strict value is not equal to itself.")
689- }
690- else throw("Strict value is not equal to itself.")
691- }
692- else throw("Strict value is not equal to itself.")
693- }
694- }
695- else throw("Strict value is not equal to itself.")
696- }
697- else throw("Strict value is not equal to itself.")
698- }
699- }
700- }
874+ let migrateAmount = if (migrate)
875+ then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
876+ else 0
877+ let attachedVires = if ((size(i.payments) == 0))
878+ then 0
879+ else i.payments[0].amount
880+ let total = (migrateAmount + attachedVires)
881+ let locking = invoke(dC, "lockFor", [user, factor], if ((total == 0))
882+ then nil
883+ else [AttachedPayment(i.payments[0].assetId, total)])
884+ if ((locking == locking))
885+ then nil
701886 else throw("Strict value is not equal to itself.")
702887 }
703888 else throw("Strict value is not equal to itself.")
706891
707892
708893 @Callable(i)
709-func forceCollapse (reserve,borrower) = {
710- let reserveAddress = validateReserve(reserve)
711- if ((reserveAddress == reserveAddress))
894+func withdrawAllPossibleVires () = {
895+ let user = toString(i.caller)
896+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
897+ if ((actualize == actualize))
712898 then {
713- let sh = syncRewardsHeight(reserve)
714- if ((sh == sh))
899+ let stakerViresAmount = asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
900+ if ((stakerViresAmount == stakerViresAmount))
715901 then {
716- let liquidator = toString(i.caller)
717- if ((liquidator == borrower))
718- then throw("can't collapse self in this function")
719- else {
720- let $t01703117066 = userPower(borrower)
721- let bp = $t01703117066._1
722- let bpu = $t01703117066._2
723- if ((bp > bpu))
724- then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
725- else {
726- let $t01721117319 = userBalance(reserveAddress, borrower)
727- if (($t01721117319 == $t01721117319))
728- then {
729- let userDebtUsd = $t01721117319._5
730- let userDebt = $t01721117319._4
731- let userAssetUsd = $t01721117319._3
732- let borrowerDeposit = $t01721117319._2
733- let ignore = $t01721117319._1
734- let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase)
735- let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
736- if ((transferredAssets == transferredAssets))
737- then {
738- let propagateRewards1 = moveStream(reserve, "deposit", borrower, liquidator, transferredAssets)
739- if ((propagateRewards1 == propagateRewards1))
740- then {
741- let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil))
742- if ((collapsed == collapsed))
743- then {
744- let propagateRewards2 = updateStream(reserve, "borrow", borrower, -(collapsed), -(collapsed))
745- if ((propagateRewards2 == propagateRewards2))
746- then {
747- let propagateRewards3 = updateStream(reserve, "deposit", borrower, -(collapsed), -(collapsed))
748- if ((propagateRewards3 == propagateRewards3))
749- then nil
750- else throw("Strict value is not equal to itself.")
751- }
752- else throw("Strict value is not equal to itself.")
753- }
754- else throw("Strict value is not equal to itself.")
755- }
756- else throw("Strict value is not equal to itself.")
757- }
758- else throw("Strict value is not equal to itself.")
759- }
760- else throw("Strict value is not equal to itself.")
761- }
762- }
902+ let unlocking = invoke(dC, "withdrawUnlockedFor", [user], nil)
903+ if ((unlocking == unlocking))
904+ then [ScriptTransfer(i.caller, stakerViresAmount, viresAssetId)]
905+ else throw("Strict value is not equal to itself.")
763906 }
907+ else throw("Strict value is not equal to itself.")
908+ }
909+ else throw("Strict value is not equal to itself.")
910+ }
911+
912+
913+
914+@Callable(i)
915+func claimProtocolProfitFrom (from,relock) = {
916+ let user = toString(i.caller)
917+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
918+ if ((actualize == actualize))
919+ then {
920+ let unlocking = invoke(dC, "claimProfit", [from, user, relock], nil)
921+ if ((unlocking == unlocking))
922+ then nil
923+ else throw("Strict value is not equal to itself.")
924+ }
925+ else throw("Strict value is not equal to itself.")
926+ }
927+
928+
929+
930+@Callable(i)
931+func withdrawUnlockedVires () = {
932+ let a = invoke(dC, "shareProfitFromReserves", nil, nil)
933+ if ((a == a))
934+ then {
935+ let u = invoke(dC, "withdrawUnlockedFor", [toString(i.caller)], nil)
936+ if ((u == u))
937+ then nil
764938 else throw("Strict value is not equal to itself.")
765939 }
766940 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let factorsBase = 1000
55
66 func fractionCeil (value,numerator,denominator) = {
77 let cand = fraction(value, numerator, denominator)
88 let D = 3037000499
99 let exact = ((((cand % D) * (denominator % D)) % D) == (((value % D) * (numerator % D)) % D))
1010 if (exact)
1111 then cand
1212 else (cand + 1)
1313 }
1414
1515
1616 func writeConstString (key,value) = if (!(isDefined(getString(this, key))))
1717 then StringEntry(key, value)
1818 else throw(("already initialized: " + key))
1919
2020
2121 func asInt (value) = match value {
2222 case int: Int =>
2323 int
2424 case _ =>
2525 throw("wrong type, expected: Int")
2626 }
2727
2828
2929 func asInt2 (value) = match value {
3030 case x: (Int, Int) =>
3131 x
3232 case t =>
3333 throw("wrong type, expected: Int2")
3434 }
3535
3636
3737 func asInt3 (value) = match value {
3838 case x: (Int, Int, Int) =>
3939 x
4040 case t =>
4141 throw("wrong type, expected: Int3")
4242 }
4343
4444
4545 func asInt4 (value) = match value {
4646 case x: (Int, Int, Int, Int) =>
4747 x
4848 case t =>
4949 throw("wrong type, expected: Int4")
5050 }
5151
5252
5353 func asInt5 (value) = match value {
5454 case x: (Int, Int, Int, Int, Int) =>
5555 x
5656 case t =>
5757 throw("wrong type, expected: Int5")
5858 }
5959
6060
6161 func asUserBalanceData (value) = match value {
6262 case x: (Int, Int, Int, Int, Int, Boolean) =>
6363 x
6464 case t =>
6565 throw("wrong type, expected: Int5&Boolean")
6666 }
6767
6868
6969 let adminStore = "admin"
7070
7171 let configStore = "config"
7272
7373 let reservesStore = "reserves"
7474
7575 let aTokenIdStore = "aTokenId"
7676
7777 let assetIdStore = "assetId"
7878
7979 let distributorStore = "vires_distributor"
8080
8181 let admin = addressFromStringValue(getStringValue(this, adminStore))
8282
8383 let config = addressFromStringValue(getStringValue(this, configStore))
8484
8585 let reservesStr = valueOrErrorMessage(getString(this, reservesStore), "no reserves registered")
8686
8787 let reserves = split(reservesStr, "|")
8888
89-let viresMinter = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "vires_minter"), "no viresMinter")), "invalid viresMinter")
89+let ebR = addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config"))
9090
91-let maybeViresStaker = getString(config, "vires_staker")
91+let viresMinter = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "vires_minter"), "main: no viresMinter")), "invalid viresMinter")
9292
93-let viresStaker = addressFromStringValue(valueOrErrorMessage(maybeViresStaker, "no vires_staker"))
93+let maybevS = getString(config, "vires_staker")
9494
95-let maybeViresDistributor = match getString(config, distributorStore) {
95+let vS = addressFromStringValue(valueOrErrorMessage(maybevS, "no vires_staker"))
96+
97+let dC = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "dividends_contract"), "no dividends_contract")), "invalid dividends_contract")
98+
99+let mVD = match getString(config, distributorStore) {
96100 case d: String =>
97101 addressFromStringValue(d)
98102 case _ =>
99103 unit
100104 }
105+
106+let VD = valueOrErrorMessage(mVD, "no distributor to claim rewards")
101107
102108 let maybeViresAssetId = getString(viresMinter, "assetId")
103109
104110 let viresAssetId = valueOrErrorMessage(fromBase58String(valueOrErrorMessage(maybeViresAssetId, "vires assetId not found")), "invalid vires assetId")
105111
106112 func assetIdOfReserve (reserve) = valueOrErrorMessage(getString(reserve, assetIdStore), "no assetId in reserve")
107113
108114
109115 func collateralFactor (reserve) = valueOrErrorMessage(getInteger(config, (assetIdOfReserve(reserve) + "_CollateralFactor")), "no CollateralFactor in config")
110116
111117
112118 func liquidationThreshold (reserve) = valueOrErrorMessage(getInteger(config, (assetIdOfReserve(reserve) + "_LiquidationThreshold")), "no LiquidationThreshold in config")
113119
114120
115121 func liquidationPenalty (assetId) = valueOrErrorMessage(getInteger(config, (assetId + "_LiquidationPenalty")), "no LiquidationPenalty in config")
116122
117123
118124 let accountHealthThreshold = valueOrErrorMessage(getInteger(config, "account_health_threshold"), "no account_health_threshold")
119125
120126 let accountHealthOverlap = valueOrErrorMessage(getInteger(config, "account_health_overlap"), "no account_health_overlap")
121127
122128 let collapsePenalty = valueOrErrorMessage(getInteger(config, "collapse_penalty"), "no collapse_penalty")
123129
124130 let liquidators = valueOrElse(getString(config, "liquidators"), "")
125131
126132 func findReserveBy (store,value) = {
127133 func fold (a,r) = match a {
128134 case found: Address =>
129135 found
130136 case _ =>
131137 let reserve = valueOrErrorMessage(addressFromString(r), "reserve bad address")
132138 if ((valueOrErrorMessage(getString(reserve, store), ("reserve has no " + store)) == value))
133139 then reserve
134140 else unit
135141 }
136142
137143 match let $l = reserves
138144 let $s = size($l)
139145 let $acc0 = unit
140146 func $f0_1 ($a,$i) = if (($i >= $s))
141147 then $a
142148 else fold($a, $l[$i])
143149
144150 func $f0_2 ($a,$i) = if (($i >= $s))
145151 then $a
146152 else throw("List size exceeds 7")
147153
148154 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7) {
149155 case found: Address =>
150156 found
151157 case _ =>
152158 throw(("unknown " + store))
153159 }
154160 }
155161
156162
157163 func validateReserve (r) = if (contains(reservesStr, r))
158164 then valueOrErrorMessage(addressFromString(r), "main: bad reserve")
159165 else throw(("unknown reserve:" + r))
160166
161167
162168 func userBalance (reserve,user) = asUserBalanceData(invoke(reserve, "userBalance", [user], nil))
163169
164170
171+let maybeProtectedReserve = match getString(config, "protected_reserve") {
172+ case pds: String =>
173+ valueOrErrorMessage(addressFromString(pds), "bad protected_reserve")
174+ case _ =>
175+ unit
176+}
177+
178+let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected reserve")
179+
165180 func userPower (user) = {
181+ let protectedDeposit = match maybeProtectedReserve {
182+ case pa: Address =>
183+ asInt(invoke(pa, "borrowPower", [user], nil))
184+ case _ =>
185+ 0
186+ }
166187 func fold (totals,r) = {
167- let $t044314460 = totals
168- let totalD = $t044314460._1
169- let totalB = $t044314460._2
188+ let $t052285257 = totals
189+ let totalD = $t052285257._1
190+ let totalB = $t052285257._2
170191 let reserve = valueOrErrorMessage(addressFromString(r), "reserve bad address")
171192 let cf = collateralFactor(reserve)
172193 let lt = liquidationThreshold(reserve)
173- let $t046314719 = userBalance(reserve, user)
174- let token = $t046314719._1
175- let asset = $t046314719._2
176- let depositUsd = $t046314719._3
177- let debt = $t046314719._4
178- let debtUsd = $t046314719._5
179- let asCollateral = $t046314719._6
194+ let $t054275515 = userBalance(reserve, user)
195+ let token = $t054275515._1
196+ let asset = $t054275515._2
197+ let depositUsd = $t054275515._3
198+ let debt = $t054275515._4
199+ let debtUsd = $t054275515._5
200+ let asCollateral = $t054275515._6
180201 let effectiveDepositUsd = if (asCollateral)
181202 then depositUsd
182203 else 0
183204 let overlapUsd = min([debtUsd, effectiveDepositUsd])
184205 let overlapCharge = fractionCeil(overlapUsd, accountHealthOverlap, factorsBase)
185206 if ((debtUsd > effectiveDepositUsd))
186207 then $Tuple2(totalD, ((totalB + fraction((debtUsd - effectiveDepositUsd), factorsBase, lt)) + overlapCharge))
187208 else $Tuple2((totalD + fraction((effectiveDepositUsd - debtUsd), cf, factorsBase)), (totalB + overlapCharge))
188209 }
189210
190211 let $l = reserves
191212 let $s = size($l)
192- let $acc0 = $Tuple2(0, 0)
213+ let $acc0 = $Tuple2(protectedDeposit, 0)
193214 func $f0_1 ($a,$i) = if (($i >= $s))
194215 then $a
195216 else fold($a, $l[$i])
196217
197218 func $f0_2 ($a,$i) = if (($i >= $s))
198219 then $a
199220 else throw("List size exceeds 7")
200221
201222 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
202223 }
203224
204225
205226 func getUserHealth (account) = {
206- let $t052645307 = asInt2(userPower(account))
207- let bp = $t052645307._1
208- let bpu = $t052645307._2
227+ let $t060766119 = asInt2(userPower(account))
228+ let bp = $t060766119._1
229+ let bpu = $t060766119._2
209230 ((("bp:" + toString(bp)) + ", bpu:") + toString(bpu))
210231 }
211232
212233
213234 func validateAfter (user,op) = {
214- let $t054185449 = userPower(user)
215- let bp = $t054185449._1
216- let bpu = $t054185449._2
235+ let $t062306261 = userPower(user)
236+ let bp = $t062306261._1
237+ let bpu = $t062306261._2
217238 let accHealth = (((bp - bpu) * factorsBase) / bp)
218239 if (if ((bp == 0))
219240 then (bpu == 0)
220241 else false)
221242 then nil
222243 else if (if ((bp == 0))
223244 then (bpu > 0)
224245 else false)
225246 then throw(((op + " too much: breaching liquidation threshold(bp=0, bpu=") + toString(bpu)))
226247 else if ((accountHealthThreshold > accHealth))
227248 then throw((((((((op + " too much: breaching liquidation threshold(bp=") + toString(bp)) + ", bpu=") + toString(bpu)) + ", health=") + toString(accHealth)) + ")"))
228249 else nil
229250 }
230251
231252
232-func updateStream (reserve,action,user,userChange,streamChange) = match maybeViresDistributor {
253+func updateStream (reserve,action,user,userChange,streamChange) = match mVD {
233254 case a: Address =>
234255 invoke(a, "onAction", [reserve, action, user, userChange, streamChange], nil)
235256 case _ =>
236257 unit
237258 }
238259
239260
240-func moveStream (reserve,action,from,string,amount) = match maybeViresDistributor {
261+func moveStream (reserve,action,from,string,amount) = match mVD {
241262 case a: Address =>
242263 invoke(a, "move", [reserve, action, from, string, amount], nil)
243264 case _ =>
244265 unit
245266 }
246267
247268
248-func syncRewardsHeight (reserve) = match maybeViresDistributor {
269+func syncRewardsHeight (reserve) = match mVD {
249270 case a: Address =>
250271 invoke(a, "syncHeight", [reserve], nil)
251272 case _ =>
252273 unit
253274 }
254275
255276
256277 func stakeOrPayout (recipient,amount,stake) = if (!(stake))
257278 then [ScriptTransfer(recipient, amount, viresAssetId)]
258279 else {
259- let doStake = invoke(viresStaker, "stakeVires", [toString(recipient)], [AttachedPayment(viresAssetId, amount)])
280+ let doStake = invoke(vS, "stakeVires", [toString(recipient)], [AttachedPayment(viresAssetId, amount)])
260281 if ((doStake == doStake))
282+ then nil
283+ else throw("Strict value is not equal to itself.")
284+ }
285+
286+
287+func lockOrPayout (recipient,amount,lock) = if (!(lock))
288+ then [ScriptTransfer(recipient, amount, viresAssetId)]
289+ else {
290+ let doLock = invoke(dC, "lockFor", [toString(recipient), 1], [AttachedPayment(viresAssetId, amount)])
291+ if ((doLock == doLock))
261292 then nil
262293 else throw("Strict value is not equal to itself.")
263294 }
264295
265296
266297 func doDeposit (i,reserve,useAsCollateral) = {
267298 let user = toString(i.caller)
268299 let sh = syncRewardsHeight(reserve)
269300 if ((sh == sh))
270301 then {
271302 let action = invoke(validateReserve(reserve), "depositFor", [user, useAsCollateral], i.payments)
272303 if ((action == action))
273304 then {
274305 let amt = i.payments[0].amount
275- let propagateRewards = updateStream(reserve, "deposit", user, amt, amt)
276- if ((propagateRewards == propagateRewards))
306+ let pRw = updateStream(reserve, "deposit", user, amt, amt)
307+ if ((pRw == pRw))
277308 then if (!(useAsCollateral))
278309 then validateAfter(user, "depositing")
279310 else nil
280311 else throw("Strict value is not equal to itself.")
281312 }
282313 else throw("Strict value is not equal to itself.")
283314 }
284315 else throw("Strict value is not equal to itself.")
285316 }
286317
287318
288319 func claimAllRewardsForUser (user) = {
289- let distributor = valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards")
290- let rewardReserves = split(valueOrErrorMessage(getString(distributor, "reward_reserves"), "no string"), "|")
291- func fold (acc,reserve) = {
292- let claimed = asInt(invoke(valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards"), "claimRewardFor", [reserve, user, -1], nil))
293- if ((claimed == claimed))
294- then (acc + claimed)
295- else throw("Strict value is not equal to itself.")
296- }
320+ let claimedEb = asInt(invoke(ebR, "claimEbRewardFor", [user, -1], nil))
321+ if ((claimedEb == claimedEb))
322+ then {
323+ let rewardReserves = split(valueOrErrorMessage(getString(VD, "reward_reserves"), "no string"), "|")
324+ func fold (acc,reserve) = {
325+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, -1], nil))
326+ if ((claimed == claimed))
327+ then (acc + claimed)
328+ else throw("Strict value is not equal to itself.")
329+ }
297330
298- let claimedTotal = {
299- let $l = rewardReserves
300- let $s = size($l)
301- let $acc0 = 0
302- func $f0_1 ($a,$i) = if (($i >= $s))
303- then $a
304- else fold($a, $l[$i])
331+ let claimedTotal = {
332+ let $l = rewardReserves
333+ let $s = size($l)
334+ let $acc0 = 0
335+ func $f0_1 ($a,$i) = if (($i >= $s))
336+ then $a
337+ else fold($a, $l[$i])
305338
306- func $f0_2 ($a,$i) = if (($i >= $s))
307- then $a
308- else throw("List size exceeds 7")
339+ func $f0_2 ($a,$i) = if (($i >= $s))
340+ then $a
341+ else throw("List size exceeds 7")
309342
310- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
311- }
312- claimedTotal
343+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
344+ }
345+ (claimedTotal + claimedEb)
346+ }
347+ else throw("Strict value is not equal to itself.")
348+ }
349+
350+
351+func moveCollateral (addr,assetStr,reserve,reserveStr) = {
352+ let amt = asInt(invoke(protectedReserve, "withdrawToMain", [addr, assetStr], nil))
353+ if ((amt == amt))
354+ then {
355+ let assetId = if ((assetStr == "WAVES"))
356+ then unit
357+ else fromBase58String(assetStr)
358+ let dep = invoke(reserve, "depositFor", [addr, true], [AttachedPayment(assetId, amt)])
359+ if ((dep == dep))
360+ then {
361+ let prop = updateStream(reserveStr, "deposit", addr, amt, amt)
362+ if ((prop == prop))
363+ then unit
364+ else throw("Strict value is not equal to itself.")
365+ }
366+ else throw("Strict value is not equal to itself.")
367+ }
368+ else throw("Strict value is not equal to itself.")
369+ }
370+
371+
372+func transferDebtInternal (liquidator,borrowReserve,collateralReserve,borrower,liquidateDebtAmount,fromProtected) = {
373+ let sh1 = syncRewardsHeight(borrowReserve)
374+ if ((sh1 == sh1))
375+ then {
376+ let sh2 = syncRewardsHeight(collateralReserve)
377+ if ((sh2 == sh2))
378+ then if ((0 >= liquidateDebtAmount))
379+ then throw("can't liquidate non-positive amount")
380+ else if ((collateralReserve == borrowReserve))
381+ then throw("collateralReserve equals borrowReserve")
382+ else if ((liquidator == borrower))
383+ then throw("can't liquidate self")
384+ else {
385+ let $t098649899 = userPower(borrower)
386+ let bp = $t098649899._1
387+ let bpu = $t098649899._2
388+ if ((bp > bpu))
389+ then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
390+ else {
391+ let br = validateReserve(borrowReserve)
392+ let cr = validateReserve(collateralReserve)
393+ let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve))
394+ let collateralAsset = valueOrErrorMessage(getString(cr, "assetId"), ("no assetId field in collateralReserve " + collateralReserve))
395+ let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false)
396+ if ((isCollateral == isCollateral))
397+ then if (if (!(fromProtected))
398+ then !(isCollateral)
399+ else false)
400+ then throw("can't liquidate deposit not used as collateral")
401+ else {
402+ let $t01056410654 = userBalance(br, borrower)
403+ if (($t01056410654 == $t01056410654))
404+ then {
405+ let userDebtUsd = $t01056410654._5
406+ let userDebt = $t01056410654._4
407+ let userAssetUsd = $t01056410654._3
408+ let userAsset = $t01056410654._2
409+ let ignore = $t01056410654._1
410+ if ((userAsset >= userDebt))
411+ then throw("can't liquidate debt of asset of positive saldo")
412+ else if ((0 >= liquidateDebtAmount))
413+ then throw("can't liquidate zero or negative amount")
414+ else if (((liquidateDebtAmount * 2) > (userDebt - userAsset)))
415+ then throw(((((("can't liquidate more than half of saldo: debt=" + toString(userDebt)) + ", deposit=") + toString(userAsset)) + ", liquidateDebtAmount = ") + toString(liquidateDebtAmount)))
416+ else {
417+ let collateralUsd = fraction(liquidateDebtAmount, userDebtUsd, userDebt)
418+ let penaltizedUsd = fraction(collateralUsd, (factorsBase + liquidationPenalty(borrowAsset)), factorsBase)
419+ let mc = if (fromProtected)
420+ then moveCollateral(borrower, collateralAsset, cr, collateralReserve)
421+ else unit
422+ if ((mc == mc))
423+ then {
424+ let transferredCollateral = asInt(invoke(cr, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
425+ if ((transferredCollateral == transferredCollateral))
426+ then {
427+ let pRw1 = moveStream(collateralReserve, "deposit", borrower, liquidator, transferredCollateral)
428+ if ((pRw1 == pRw1))
429+ then {
430+ let transferredDebt = asInt(invoke(br, "transferDebtFor", [borrower, liquidator, liquidateDebtAmount], nil))
431+ if ((transferredDebt == transferredDebt))
432+ then {
433+ let pRw2 = moveStream(borrowReserve, "borrow", borrower, liquidator, transferredDebt)
434+ if ((pRw2 == pRw2))
435+ then {
436+ let liquidatorHealthCheck = if (contains(liquidators, liquidator))
437+ then nil
438+ else validateAfter(liquidator, "transferring debt")
439+ if ((liquidatorHealthCheck == liquidatorHealthCheck))
440+ then $Tuple2(liquidatorHealthCheck, transferredCollateral)
441+ else throw("Strict value is not equal to itself.")
442+ }
443+ else throw("Strict value is not equal to itself.")
444+ }
445+ else throw("Strict value is not equal to itself.")
446+ }
447+ else throw("Strict value is not equal to itself.")
448+ }
449+ else throw("Strict value is not equal to itself.")
450+ }
451+ else throw("Strict value is not equal to itself.")
452+ }
453+ }
454+ else throw("Strict value is not equal to itself.")
455+ }
456+ else throw("Strict value is not equal to itself.")
457+ }
458+ }
459+ else throw("Strict value is not equal to itself.")
460+ }
461+ else throw("Strict value is not equal to itself.")
462+ }
463+
464+
465+func forceCollapseInternal (liquidator,reserve,borrower,fromProtected) = {
466+ let reserveAddress = validateReserve(reserve)
467+ if ((reserveAddress == reserveAddress))
468+ then {
469+ let sh = syncRewardsHeight(reserve)
470+ if ((sh == sh))
471+ then if ((liquidator == borrower))
472+ then throw("can't collapse self in this function")
473+ else {
474+ let $t01234112376 = userPower(borrower)
475+ let bp = $t01234112376._1
476+ let bpu = $t01234112376._2
477+ if ((bp > bpu))
478+ then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
479+ else {
480+ let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in reserve " + reserve))
481+ let mc = if (fromProtected)
482+ then moveCollateral(borrower, asset, reserveAddress, reserve)
483+ else unit
484+ if ((mc == mc))
485+ then {
486+ let $t01275212860 = userBalance(reserveAddress, borrower)
487+ if (($t01275212860 == $t01275212860))
488+ then {
489+ let userDebtUsd = $t01275212860._5
490+ let userDebt = $t01275212860._4
491+ let userAssetUsd = $t01275212860._3
492+ let borrowerDeposit = $t01275212860._2
493+ let ignore = $t01275212860._1
494+ let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase)
495+ let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
496+ if ((transferredAssets == transferredAssets))
497+ then {
498+ let pRw1 = moveStream(reserve, "deposit", borrower, liquidator, transferredAssets)
499+ if ((pRw1 == pRw1))
500+ then {
501+ let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil))
502+ if ((collapsed == collapsed))
503+ then {
504+ let pRw2 = updateStream(reserve, "borrow", borrower, -(collapsed), -(collapsed))
505+ if ((pRw2 == pRw2))
506+ then {
507+ let pRw3 = updateStream(reserve, "deposit", borrower, -(collapsed), -(collapsed))
508+ if ((pRw3 == pRw3))
509+ then nil
510+ else throw("Strict value is not equal to itself.")
511+ }
512+ else throw("Strict value is not equal to itself.")
513+ }
514+ else throw("Strict value is not equal to itself.")
515+ }
516+ else throw("Strict value is not equal to itself.")
517+ }
518+ else throw("Strict value is not equal to itself.")
519+ }
520+ else throw("Strict value is not equal to itself.")
521+ }
522+ else throw("Strict value is not equal to itself.")
523+ }
524+ }
525+ else throw("Strict value is not equal to itself.")
526+ }
527+ else throw("Strict value is not equal to itself.")
313528 }
314529
315530
316531 @Callable(i)
317532 func initialize (configAddress) = [writeConstString(adminStore, toString(i.caller)), writeConstString(configStore, configAddress)]
318533
319534
320535
321536 @Callable(i)
322537 func registerReserves (addresses) = if ((i.caller != admin))
323538 then throw("only admin can do")
324539 else [StringEntry(reservesStore, addresses)]
325540
326541
327542
328543 @Callable(i)
329544 func deposit (reserve,useAsCollateral) = doDeposit(i, reserve, useAsCollateral)
330545
331546
332547
333548 @Callable(i)
334549 func depositRef (reserve,useAsCollateral,ref) = doDeposit(i, reserve, useAsCollateral)
335550
336551
337552
338553 @Callable(i)
339554 func repay (reserve) = {
340555 let user = toString(i.caller)
341556 let sh = syncRewardsHeight(reserve)
342557 if ((sh == sh))
343558 then {
344559 let repaid = asInt(invoke(validateReserve(reserve), "repayFor", [user], i.payments))
345560 if ((repaid == repaid))
346561 then {
347- let propagateRewards = updateStream(reserve, "borrow", user, -(repaid), -(repaid))
348- if ((propagateRewards == propagateRewards))
562+ let pRw = updateStream(reserve, "borrow", user, -(repaid), -(repaid))
563+ if ((pRw == pRw))
349564 then nil
350565 else throw("Strict value is not equal to itself.")
351566 }
352567 else throw("Strict value is not equal to itself.")
353568 }
354569 else throw("Strict value is not equal to itself.")
355570 }
356571
357572
358573
359574 @Callable(i)
360575 func mintAtoken (aTokenId,amount) = {
361576 let user = toString(i.caller)
362577 let targetContract = findReserveBy(aTokenIdStore, aTokenId)
363578 let sh = syncRewardsHeight(toString(targetContract))
364579 if ((sh == sh))
365580 then {
366581 let mintedAssetAmount = asInt(invoke(targetContract, "mintAtokenFor", [user, amount], nil))
367582 if ((mintedAssetAmount == mintedAssetAmount))
368583 then {
369- let propagateRewards = updateStream(toString(targetContract), "deposit", user, -(mintedAssetAmount), 0)
370- if ((propagateRewards == propagateRewards))
584+ let pRw = updateStream(toString(targetContract), "deposit", user, -(mintedAssetAmount), 0)
585+ if ((pRw == pRw))
371586 then validateAfter(user, "minting")
372587 else throw("Strict value is not equal to itself.")
373588 }
374589 else throw("Strict value is not equal to itself.")
375590 }
376591 else throw("Strict value is not equal to itself.")
377592 }
378593
379594
380595
381596 @Callable(i)
382597 func replenishWithAtoken () = {
383598 let user = toString(i.caller)
384- let aTokenId = match i.payments[0].assetId {
385- case bv: ByteVector =>
386- toBase58String(bv)
387- case _ =>
388- throw("bad assetId: waves not allowed")
389- }
599+ let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed"))
390600 let targetContract = findReserveBy(aTokenIdStore, aTokenId)
391601 let sh = syncRewardsHeight(toString(targetContract))
392602 if ((sh == sh))
393603 then {
394604 let replenishedAssetAmount = asInt(invoke(targetContract, "replenishWithAtokenFor", [user], i.payments))
395605 if ((replenishedAssetAmount == replenishedAssetAmount))
396606 then {
397- let propagateRewards = updateStream(toString(targetContract), "deposit", user, replenishedAssetAmount, 0)
398- if ((propagateRewards == propagateRewards))
607+ let pRw = updateStream(toString(targetContract), "deposit", user, replenishedAssetAmount, 0)
608+ if ((pRw == pRw))
399609 then nil
400610 else throw("Strict value is not equal to itself.")
401611 }
402612 else throw("Strict value is not equal to itself.")
403613 }
404614 else throw("Strict value is not equal to itself.")
405615 }
406616
407617
408618
409619 @Callable(i)
410620 func redeemAtokens () = {
411621 let user = toString(i.caller)
412- let aTokenId = match i.payments[0].assetId {
413- case bv: ByteVector =>
414- toBase58String(bv)
415- case _ =>
416- throw("bad assetId: waves not allowed")
417- }
622+ let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed"))
418623 let targetContract = findReserveBy(aTokenIdStore, aTokenId)
419624 let sh = syncRewardsHeight(toString(targetContract))
420625 if ((sh == sh))
421626 then {
422627 let redeemedAssetAmount = asInt(invoke(targetContract, "redeemAtokensFor", [user], i.payments))
423628 if ((redeemedAssetAmount == redeemedAssetAmount))
424629 then {
425- let propagateRewards = updateStream(toString(targetContract), "deposit", user, 0, -(redeemedAssetAmount))
426- if ((propagateRewards == propagateRewards))
630+ let pRw = updateStream(toString(targetContract), "deposit", user, 0, -(redeemedAssetAmount))
631+ if ((pRw == pRw))
427632 then nil
428633 else throw("Strict value is not equal to itself.")
429634 }
430635 else throw("Strict value is not equal to itself.")
431636 }
432637 else throw("Strict value is not equal to itself.")
433638 }
434639
435640
436641
437642 @Callable(i)
438643 func withdraw (assetId,amount) = {
439644 let user = toString(i.caller)
440645 let targetContract = findReserveBy(assetIdStore, assetId)
441646 let sh = syncRewardsHeight(toString(targetContract))
442647 if ((sh == sh))
443648 then {
444649 let withdrawnAmount = asInt(invoke(targetContract, "withdrawFor", [user, amount], nil))
445650 if ((withdrawnAmount == withdrawnAmount))
446651 then {
447- let propagateRewards = updateStream(toString(targetContract), "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
448- if ((propagateRewards == propagateRewards))
652+ let pRw = updateStream(toString(targetContract), "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
653+ if ((pRw == pRw))
449654 then validateAfter(user, "withdrawing")
450655 else throw("Strict value is not equal to itself.")
451656 }
452657 else throw("Strict value is not equal to itself.")
453658 }
454659 else throw("Strict value is not equal to itself.")
455660 }
456661
457662
458663
459664 @Callable(i)
460665 func withdraw2 (reserve,amount) = {
461666 let user = toString(i.caller)
462667 let sh = syncRewardsHeight(reserve)
463668 if ((sh == sh))
464669 then {
465670 let withdrawnAmount = asInt(invoke(validateReserve(reserve), "withdrawFor", [user, amount], nil))
466671 if ((withdrawnAmount == withdrawnAmount))
467672 then {
468- let propagateRewards = updateStream(reserve, "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
469- if ((propagateRewards == propagateRewards))
673+ let pRw = updateStream(reserve, "deposit", user, -(withdrawnAmount), -(withdrawnAmount))
674+ if ((pRw == pRw))
470675 then if (contains(liquidators, user))
471676 then nil
472677 else validateAfter(user, "withdrawing2")
473678 else throw("Strict value is not equal to itself.")
474679 }
475680 else throw("Strict value is not equal to itself.")
476681 }
682+ else throw("Strict value is not equal to itself.")
683+ }
684+
685+
686+
687+@Callable(i)
688+func withdrawProtectedCollateral (assetId,amount) = {
689+ let user = toString(i.caller)
690+ let withdrawnAmount = asInt(invoke(valueOrErrorMessage(protectedReserve, "no protectedReserve"), "withdrawFor", [user, assetId, amount], nil))
691+ if ((withdrawnAmount == withdrawnAmount))
692+ then validateAfter(user, "withdrawing protected collateral")
477693 else throw("Strict value is not equal to itself.")
478694 }
479695
480696
481697
482698 @Callable(i)
483699 func borrow (assetId,amount) = {
484700 let user = toString(i.caller)
485701 let reserve = findReserveBy(assetIdStore, assetId)
486702 let sh = syncRewardsHeight(toString(reserve))
487703 if ((sh == sh))
488704 then {
489705 let action = invoke(reserve, "borrowFor", [user, amount], nil)
490706 if ((action == action))
491707 then {
492- let propagateRewards = updateStream(toString(reserve), "borrow", user, amount, amount)
493- if ((propagateRewards == propagateRewards))
708+ let pRw = updateStream(toString(reserve), "borrow", user, amount, amount)
709+ if ((pRw == pRw))
494710 then validateAfter(user, "borrowing")
495711 else throw("Strict value is not equal to itself.")
496712 }
497713 else throw("Strict value is not equal to itself.")
498714 }
499715 else throw("Strict value is not equal to itself.")
500716 }
501717
502718
503719
504720 @Callable(i)
505721 func borrow2 (reserve,amount) = {
506722 let user = toString(i.caller)
507723 let sh = syncRewardsHeight(reserve)
508724 if ((sh == sh))
509725 then {
510726 let action = invoke(validateReserve(reserve), "borrowFor", [user, amount], nil)
511727 if ((action == action))
512728 then {
513- let propagateRewards = updateStream(reserve, "borrow", user, amount, amount)
514- if ((propagateRewards == propagateRewards))
729+ let pRw = updateStream(reserve, "borrow", user, amount, amount)
730+ if ((pRw == pRw))
515731 then validateAfter(user, "borrowing")
516732 else throw("Strict value is not equal to itself.")
517733 }
518734 else throw("Strict value is not equal to itself.")
519735 }
520736 else throw("Strict value is not equal to itself.")
521737 }
522738
523739
524740
525741 @Callable(i)
526742 func collapse (reserve,amount) = {
527743 let user = toString(i.caller)
528744 let sh = syncRewardsHeight(reserve)
529745 if ((sh == sh))
530746 then {
531747 let collapse = asInt(invoke(validateReserve(reserve), "collapseForAmount", [user, amount], nil))
532748 if ((collapse == collapse))
533749 then {
534- let propagateRewards = updateStream(reserve, "borrow", user, -(collapse), -(collapse))
535- if ((propagateRewards == propagateRewards))
750+ let pRw = updateStream(reserve, "borrow", user, -(collapse), -(collapse))
751+ if ((pRw == pRw))
536752 then {
537- let propagateRewards2 = updateStream(reserve, "deposit", user, -(collapse), -(collapse))
538- if ((propagateRewards2 == propagateRewards2))
753+ let pRw2 = updateStream(reserve, "deposit", user, -(collapse), -(collapse))
754+ if ((pRw2 == pRw2))
539755 then nil
540756 else throw("Strict value is not equal to itself.")
541757 }
542758 else throw("Strict value is not equal to itself.")
543759 }
544760 else throw("Strict value is not equal to itself.")
545761 }
546762 else throw("Strict value is not equal to itself.")
547763 }
548764
549765
550766
551767 @Callable(i)
552768 func claimEbReward (amount,stake) = {
553769 let user = toString(i.caller)
554- let r = addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config"))
555- let claimed = asInt(invoke(r, "claimEbRewardFor", [user, amount], nil))
770+ let claimed = asInt(invoke(ebR, "claimEbRewardFor", [user, amount], nil))
556771 if ((claimed == claimed))
557772 then stakeOrPayout(i.caller, claimed, stake)
773+ else throw("Strict value is not equal to itself.")
774+ }
775+
776+
777+
778+@Callable(i)
779+func claimEbReward2 (amount,lock) = {
780+ let user = toString(i.caller)
781+ let claimed = asInt(invoke(ebR, "claimEbRewardFor", [user, amount], nil))
782+ if ((claimed == claimed))
783+ then lockOrPayout(i.caller, claimed, lock)
558784 else throw("Strict value is not equal to itself.")
559785 }
560786
561787
562788
563789 @Callable(i)
564790 func claimReward (reserve,amount,stake) = {
565791 let v = validateReserve(reserve)
566792 if ((v == v))
567793 then {
568794 let user = toString(i.caller)
569- let claimed = asInt(invoke(valueOrErrorMessage(maybeViresDistributor, "no distributor to claim rewards"), "claimRewardFor", [reserve, user, amount], nil))
795+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, amount], nil))
570796 if ((claimed == claimed))
571797 then stakeOrPayout(i.caller, claimed, stake)
572798 else throw("Strict value is not equal to itself.")
573799 }
574800 else throw("Strict value is not equal to itself.")
575801 }
576802
577803
578804
579805 @Callable(i)
580-func claimAllRewards (stake) = {
581- let user = toString(i.caller)
582- let claimedTotal = claimAllRewardsForUser(user)
583- stakeOrPayout(i.caller, claimedTotal, stake)
806+func claimReward2 (reserve,amount,lock) = {
807+ let v = validateReserve(reserve)
808+ if ((v == v))
809+ then {
810+ let user = toString(i.caller)
811+ let claimed = asInt(invoke(VD, "claimRewardFor", [reserve, user, amount], nil))
812+ if ((claimed == claimed))
813+ then lockOrPayout(i.caller, claimed, lock)
814+ else throw("Strict value is not equal to itself.")
815+ }
816+ else throw("Strict value is not equal to itself.")
584817 }
585818
586819
587820
588821 @Callable(i)
589822 func claimAllRewardsAndAllEbAvailable (stake) = {
590823 let user = toString(i.caller)
591- let claimedEb = asInt(invoke(addressFromStringValue(valueOrErrorMessage(getString(config, "eb_rewards"), "no eb_rewards contract in config")), "claimEbRewardFor", [user, -1], nil))
592- if ((claimedEb == claimedEb))
824+ stakeOrPayout(i.caller, claimAllRewardsForUser(user), stake)
825+ }
826+
827+
828+
829+@Callable(i)
830+func claimAllRewardsAndAllEbAvailable2 (lock,unstakeLegacy) = {
831+ let user = toString(i.caller)
832+ let claimedRewards = claimAllRewardsForUser(user)
833+ if ((claimedRewards == claimedRewards))
593834 then {
594- let claimedRewards = claimAllRewardsForUser(user)
595- if ((claimedRewards == claimedRewards))
596- then {
597- let claimedTotal = (claimedEb + claimedRewards)
598- if ((claimedTotal == claimedTotal))
599- then stakeOrPayout(i.caller, claimedTotal, stake)
600- else throw("Strict value is not equal to itself.")
601- }
835+ let lA = if (unstakeLegacy)
836+ then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
837+ else 0
838+ if ((lA == lA))
839+ then lockOrPayout(i.caller, (claimedRewards + lA), lock)
602840 else throw("Strict value is not equal to itself.")
603841 }
604842 else throw("Strict value is not equal to itself.")
605843 }
606844
607845
608846
609847 @Callable(i)
610848 func disableUseAsCollateral (reserve) = {
611849 let user = toString(i.caller)
612850 let doSetCollateral = invoke(validateReserve(reserve), "disableUseAsCollateralFor", [user], nil)
613851 if ((doSetCollateral == doSetCollateral))
614852 then validateAfter(user, "changing collateral status")
615853 else throw("Strict value is not equal to itself.")
616854 }
617855
618856
619857
620858 @Callable(i)
621-func transferDebt (borrowReserve,collateralReserve,borrower,liquidateDebtAmount) = {
622- let sh1 = syncRewardsHeight(borrowReserve)
623- if ((sh1 == sh1))
859+func transferDebt (borrowReserve,collateralReserve,borrower,liquidateDebtAmount) = transferDebtInternal(toString(i.caller), borrowReserve, collateralReserve, borrower, liquidateDebtAmount, false)
860+
861+
862+
863+@Callable(i)
864+func forceCollapse (reserve,borrower) = forceCollapseInternal(toString(i.caller), reserve, borrower, false)
865+
866+
867+
868+@Callable(i)
869+func lockVires (factor,migrate) = {
870+ let user = toString(i.caller)
871+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
872+ if ((actualize == actualize))
624873 then {
625- let sh2 = syncRewardsHeight(collateralReserve)
626- if ((sh2 == sh2))
627- then if ((0 >= liquidateDebtAmount))
628- then throw("can't liquidate non-positive amount")
629- else if ((collateralReserve == borrowReserve))
630- then throw("collateralReserve equals borrowReserve")
631- else {
632- let liquidator = toString(i.caller)
633- if ((liquidator == borrower))
634- then throw("can't liquidate self")
635- else {
636- let $t01479614831 = userPower(borrower)
637- let bp = $t01479614831._1
638- let bpu = $t01479614831._2
639- if ((bp > bpu))
640- then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
641- else {
642- let br = validateReserve(borrowReserve)
643- let cr = validateReserve(collateralReserve)
644- let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve))
645- let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false)
646- if ((isCollateral == isCollateral))
647- then if (!(isCollateral))
648- then throw("can't liquidate deposit not used as collateral")
649- else {
650- let $t01534715437 = userBalance(br, borrower)
651- if (($t01534715437 == $t01534715437))
652- then {
653- let userDebtUsd = $t01534715437._5
654- let userDebt = $t01534715437._4
655- let userAssetUsd = $t01534715437._3
656- let userAsset = $t01534715437._2
657- let ignore = $t01534715437._1
658- if ((userAsset >= userDebt))
659- then throw("can't liquidate debt of asset of positive saldo")
660- else if ((0 >= liquidateDebtAmount))
661- then throw("can't liquidate zero or negative amount")
662- else if (((liquidateDebtAmount * 2) > (userDebt - userAsset)))
663- then throw(((((("can't liquidate more than half of saldo: debt=" + toString(userDebt)) + ", deposit=") + toString(userAsset)) + ", liquidateDebtAmount = ") + toString(liquidateDebtAmount)))
664- else {
665- let collateralUsd = fraction(liquidateDebtAmount, userDebtUsd, userDebt)
666- let penaltizedUsd = fraction(collateralUsd, (factorsBase + liquidationPenalty(borrowAsset)), factorsBase)
667- let transferredCollateral = asInt(invoke(cr, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
668- if ((transferredCollateral == transferredCollateral))
669- then {
670- let propagateRewards1 = moveStream(collateralReserve, "deposit", borrower, liquidator, transferredCollateral)
671- if ((propagateRewards1 == propagateRewards1))
672- then {
673- let transferredDebt = asInt(invoke(br, "transferDebtFor", [borrower, liquidator, liquidateDebtAmount], nil))
674- if ((transferredDebt == transferredDebt))
675- then {
676- let propagateRewards2 = moveStream(borrowReserve, "borrow", borrower, liquidator, transferredDebt)
677- if ((propagateRewards2 == propagateRewards2))
678- then {
679- let liquidatorHealthCheck = if (contains(liquidators, liquidator))
680- then nil
681- else validateAfter(liquidator, "transferring debt")
682- if ((liquidatorHealthCheck == liquidatorHealthCheck))
683- then $Tuple2(liquidatorHealthCheck, transferredCollateral)
684- else throw("Strict value is not equal to itself.")
685- }
686- else throw("Strict value is not equal to itself.")
687- }
688- else throw("Strict value is not equal to itself.")
689- }
690- else throw("Strict value is not equal to itself.")
691- }
692- else throw("Strict value is not equal to itself.")
693- }
694- }
695- else throw("Strict value is not equal to itself.")
696- }
697- else throw("Strict value is not equal to itself.")
698- }
699- }
700- }
874+ let migrateAmount = if (migrate)
875+ then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
876+ else 0
877+ let attachedVires = if ((size(i.payments) == 0))
878+ then 0
879+ else i.payments[0].amount
880+ let total = (migrateAmount + attachedVires)
881+ let locking = invoke(dC, "lockFor", [user, factor], if ((total == 0))
882+ then nil
883+ else [AttachedPayment(i.payments[0].assetId, total)])
884+ if ((locking == locking))
885+ then nil
701886 else throw("Strict value is not equal to itself.")
702887 }
703888 else throw("Strict value is not equal to itself.")
704889 }
705890
706891
707892
708893 @Callable(i)
709-func forceCollapse (reserve,borrower) = {
710- let reserveAddress = validateReserve(reserve)
711- if ((reserveAddress == reserveAddress))
894+func withdrawAllPossibleVires () = {
895+ let user = toString(i.caller)
896+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
897+ if ((actualize == actualize))
712898 then {
713- let sh = syncRewardsHeight(reserve)
714- if ((sh == sh))
899+ let stakerViresAmount = asInt(invoke(vS, "unstakeAllViresFrom", [user], nil))
900+ if ((stakerViresAmount == stakerViresAmount))
715901 then {
716- let liquidator = toString(i.caller)
717- if ((liquidator == borrower))
718- then throw("can't collapse self in this function")
719- else {
720- let $t01703117066 = userPower(borrower)
721- let bp = $t01703117066._1
722- let bpu = $t01703117066._2
723- if ((bp > bpu))
724- then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu)))
725- else {
726- let $t01721117319 = userBalance(reserveAddress, borrower)
727- if (($t01721117319 == $t01721117319))
728- then {
729- let userDebtUsd = $t01721117319._5
730- let userDebt = $t01721117319._4
731- let userAssetUsd = $t01721117319._3
732- let borrowerDeposit = $t01721117319._2
733- let ignore = $t01721117319._1
734- let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase)
735- let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil))
736- if ((transferredAssets == transferredAssets))
737- then {
738- let propagateRewards1 = moveStream(reserve, "deposit", borrower, liquidator, transferredAssets)
739- if ((propagateRewards1 == propagateRewards1))
740- then {
741- let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil))
742- if ((collapsed == collapsed))
743- then {
744- let propagateRewards2 = updateStream(reserve, "borrow", borrower, -(collapsed), -(collapsed))
745- if ((propagateRewards2 == propagateRewards2))
746- then {
747- let propagateRewards3 = updateStream(reserve, "deposit", borrower, -(collapsed), -(collapsed))
748- if ((propagateRewards3 == propagateRewards3))
749- then nil
750- else throw("Strict value is not equal to itself.")
751- }
752- else throw("Strict value is not equal to itself.")
753- }
754- else throw("Strict value is not equal to itself.")
755- }
756- else throw("Strict value is not equal to itself.")
757- }
758- else throw("Strict value is not equal to itself.")
759- }
760- else throw("Strict value is not equal to itself.")
761- }
762- }
902+ let unlocking = invoke(dC, "withdrawUnlockedFor", [user], nil)
903+ if ((unlocking == unlocking))
904+ then [ScriptTransfer(i.caller, stakerViresAmount, viresAssetId)]
905+ else throw("Strict value is not equal to itself.")
763906 }
907+ else throw("Strict value is not equal to itself.")
908+ }
909+ else throw("Strict value is not equal to itself.")
910+ }
911+
912+
913+
914+@Callable(i)
915+func claimProtocolProfitFrom (from,relock) = {
916+ let user = toString(i.caller)
917+ let actualize = invoke(dC, "shareProfitFromReserves", nil, nil)
918+ if ((actualize == actualize))
919+ then {
920+ let unlocking = invoke(dC, "claimProfit", [from, user, relock], nil)
921+ if ((unlocking == unlocking))
922+ then nil
923+ else throw("Strict value is not equal to itself.")
924+ }
925+ else throw("Strict value is not equal to itself.")
926+ }
927+
928+
929+
930+@Callable(i)
931+func withdrawUnlockedVires () = {
932+ let a = invoke(dC, "shareProfitFromReserves", nil, nil)
933+ if ((a == a))
934+ then {
935+ let u = invoke(dC, "withdrawUnlockedFor", [toString(i.caller)], nil)
936+ if ((u == u))
937+ then nil
764938 else throw("Strict value is not equal to itself.")
765939 }
766940 else throw("Strict value is not equal to itself.")
767941 }
768942
769943

github/deemru/w8io/786bc32 
137.44 ms