2022.04.05 14:22 [3060480] smart account 3PAZv9tgK1PX7dKR7b4kchq5qdpUS3G5sYT > SELF 0.00000000 Waves
{ "type": 13, "id": "GPqPcWqYHNssKezTg34GapBCp2YKXCSBdqKAssMxg6xp", "fee": 1000000, "feeAssetId": null, "timestamp": 1649156629528, "version": 1, "sender": "3PAZv9tgK1PX7dKR7b4kchq5qdpUS3G5sYT", "senderPublicKey": "2cFG5wZimjVSeCT8ZCRybx7Mzo5tJF879aw2b31uLRmR", "proofs": [ "2wTppp142gjfZcFFivN5Md9bDAhhrBJYG8QAWDcKTgQBgYgndV41hN6rUX8w3241WNS5LLMqQ5gbFJbU8x2aFtjs" ], "script": "base64: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c2FnZQAAAAIJAAQdAAAAAgUAAAANY29uZmlnQWRkcmVzcwIAAAAKZWJfcmV3YXJkcwIAAAAgbm8gZWJfcmV3YXJkcyBjb250cmFjdCBpbiBjb25maWcAAAAAC3ZpcmVzTWludGVyCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAADWNvbmZpZ0FkZHJlc3MCAAAADHZpcmVzX21pbnRlcgIAAAAUbWFpbjogbm8gdmlyZXNNaW50ZXICAAAAE2ludmFsaWQgdmlyZXNNaW50ZXIAAAAAB21heWJldlMJAAQdAAAAAgUAAAANY29uZmlnQWRkcmVzcwIAAAAMdmlyZXNfc3Rha2VyAAAAAAJ2UwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACBQAAAAdtYXliZXZTAgAAAA9ubyB2aXJlc19zdGFrZXIAAAAAAmRDCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAADWNvbmZpZ0FkZHJlc3MCAAAAEmRpdmlkZW5kc19jb250cmFjdAIAAAAVbm8gZGl2aWRlbmRzX2NvbnRyYWN0AgAAABppbnZhbGlkIGRpdmlkZW5kc19jb250cmFjdAAAAAADbVZEBAAAAAckbWF0Y2gwCQAEHQAAAAIFAAAADWNvbmZpZ0FkZHJlc3MFAAAAEGRpc3RyaWJ1dG9yU3RvcmUDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABZAUAAAAHJG1hdGNoMAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAABZAUAAAAEdW5pdAAAAAACVkQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgUAAAADbVZEAgAAAB9ubyBkaXN0cmlidXRvciB0byBjbGFpbSByZXdhcmRzAAAAABFtYXliZVZpcmVzQXNzZXRJZAkABB0AAAACBQAAAAt2aXJlc01pbnRlcgIAAAAHYXNzZXRJZAAAAAAMdmlyZXNBc3NldElkCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAJZAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACBQAAABFtYXliZVZpcmVzQXNzZXRJZAIAAAAXdmlyZXMgYXNzZXRJZCBub3QgZm91bmQCAAAAFWludmFsaWQgdmlyZXMgYXNzZXRJZAEAAAAMdmlyZXNQYXltZW50AAAAAQAAAAFpAwkAAAAAAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAAAAAAAAAAwkBAAAAAiE9AAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAUAAAAMdmlyZXNBc3NldElkCQAAAgAAAAECAAAACW5vdCB2aXJlcwgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50AQAAABBhc3NldElkT2ZSZXNlcnZlAAAAAQAAAANyc3IJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAANyc3IFAAAADGFzc2V0SWRTdG9yZQIAAAARbm8gYXNzZXRJZCBpbiByc3IBAAAAEGNvbGxhdGVyYWxGYWN0b3IAAAABAAAAA3JzcgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADWNvbmZpZ0FkZHJlc3MJAAEsAAAAAgkBAAAAEGFzc2V0SWRPZlJlc2VydmUAAAABBQAAAANyc3ICAAAAEV9Db2xsYXRlcmFsRmFjdG9yAgAAAB1ubyBDb2xsYXRlcmFsRmFjdG9yIGluIGNvbmZpZwEAAAAUbGlxdWlkYXRpb25UaHJlc2hvbGQAAAABAAAAA3JzcgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADWNvbmZpZ0FkZHJlc3MJAAEsAAAAAgkBAAAAEGFzc2V0SWRPZlJlc2VydmUAAAABBQAAAANyc3ICAAAAFV9MaXF1aWRhdGlvblRocmVzaG9sZAIAAAAhbm8gTGlxdWlkYXRpb25UaHJlc2hvbGQgaW4gY29uZmlnAQAAABJsaXF1aWRhdGlvblBlbmFsdHkAAAABAAAAB2Fzc2V0SWQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA1jb25maWdBZGRyZXNzCQABLAAAAAIFAAAAB2Fzc2V0SWQCAAAAE19MaXF1aWRhdGlvblBlbmFsdHkCAAAAH25vIExpcXVpZGF0aW9uUGVuYWx0eSBpbiBjb25maWcAAAAAFmFjY291bnRIZWFsdGhUaHJlc2hvbGQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA1jb25maWdBZGRyZXNzAgAAABhhY2NvdW50X2hlYWx0aF90aHJlc2hvbGQCAAAAG25vIGFjY291bnRfaGVhbHRoX3RocmVzaG9sZAAAAAAUYWNjb3VudEhlYWx0aE92ZXJsYXAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA1jb25maWdBZGRyZXNzAgAAABZhY2NvdW50X2hlYWx0aF9vdmVybGFwAgAAABlubyBhY2NvdW50X2hlYWx0aF9vdmVybGFwAAAAAA9jb2xsYXBzZVBlbmFsdHkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA1jb25maWdBZGRyZXNzAgAAABBjb2xsYXBzZV9wZW5hbHR5AgAAABNubyBjb2xsYXBzZV9wZW5hbHR5AAAAAAtsaXF1aWRhdG9ycwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAA1jb25maWdBZGRyZXNzAgAAAAtsaXF1aWRhdG9ycwIAAAAAAQAAAA1maW5kUmVzZXJ2ZUJ5AAAAAgAAAAVzdG9yZQAAAAV2YWx1ZQoBAAAABGZvbGQAAAACAAAAAWEAAAABcgQAAAAHJG1hdGNoMAUAAAABYQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAHQWRkcmVzcwQAAAAFZm91bmQFAAAAByRtYXRjaDAFAAAABWZvdW5kBAAAAANyc3IJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABBQAAAAFyAgAAAA9yc3IgYmFkIGFkZHJlc3MDCQAAAAAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAANyc3IF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Y2FuJ3QgbGlxdWlkYXRlIGRlcG9zaXQgbm90IHVzZWQgYXMgY29sbGF0ZXJhbAQAAAANJHQwMTA2MzYxMDcyNgkBAAAAC3VzZXJCYWxhbmNlAAAAAgUAAAACYnIFAAAACGJvcnJvd2VyAwkAAAAAAAACBQAAAA0kdDAxMDYzNjEwNzI2BQAAAA0kdDAxMDYzNjEwNzI2BAAAAAt1c2VyRGVidFVzZAgFAAAADSR0MDEwNjM2MTA3MjYAAAACXzUEAAAACHVzZXJEZWJ0CAUAAAANJHQwMTA2MzYxMDcyNgAAAAJfNAQAAAAMdXNlckFzc2V0VXNkCAUAAAANJHQwMTA2MzYxMDcyNgAAAAJfMwQAAAAJdXNlckFzc2V0CAUAAAANJHQwMTA2MzYxMDcyNgAAAAJfMgQAAAAGaWdub3JlCAUAAAANJHQwMTA2MzYxMDcyNgAAAAJfMQMJAABnAAAAAgUAAAAJdXNlckFzc2V0BQAAAAh1c2VyRGVidAkAAAIAAAABAgAAAC9jYW4ndCBsaXF1aWRhdGUgZGVidCBvZiBhc3NldCBvZiBwb3NpdGl2ZSBzYWxkbwMJAABnAAAAAgAAAAAAAAAAAAUAAAATbGlxdWlkYXRlRGVidEFtb3VudAkAAAIAAAABAgAAACdjYW4ndCBsaXF1aWRhdGUgemVybyBvciBuZWdhdGl2ZSBhbW91bnQDCQAAZgAAAAIJAABoAAAAAgUAAAATbGlxdWlkYXRlRGVidEFtb3VudAAAAAAAAAAAAgkAAGUAAAACBQAAAAh1c2VyRGVidAUAAAAJdXNlckFzc2V0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAC5jYW4ndCBsaXF1aWRhdGUgbW9yZSB0aGFuIGhhbGYgb2Ygc2FsZG86IGRlYnQ9CQABpAAAAAEFAAAACHVzZXJEZWJ0AgAAAAosIGRlcG9zaXQ9CQABpAAAAAEFAAAACXVzZXJBc3NldAIAAAAYLCBsaXF1aWRhdGVEZWJ0QW1vdW50ID0gCQABpAAAAAEFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQEAAAADWNvbGxhdGVyYWxVc2QJAABrAAAAAwUAAAATbGlxdWlkYXRlRGVidEFtb3VudAUAAAALdXNlckRlYnRVc2QFAAAACHVzZXJEZWJ0BAAAAA1wZW5hbHRpemVkVXNkCQAAawAAAAMFAAAADWNvbGxhdGVyYWxVc2QJAABkAAAAAgUAAAALZmFjdG9yc0Jhc2UJAQAAABJsaXF1aWRhdGlvblBlbmFsdHkAAAABBQAAAAtib3Jyb3dBc3NldAUAAAALZmFjdG9yc0Jhc2UEAAAAAm1jAwUAAAANZnJvbVByb3RlY3RlZAkBAAAADm1vdmVDb2xsYXRlcmFsAAAABAUAAAAIYm9ycm93ZXIFAAAAD2NvbGxhdGVyYWxBc3NldAUAAAACY3IFAAAAEWNvbGxhdGVyYWxSZXNlcnZlBQAAAAR1bml0AwkAAAAAAAACBQAAAAJtYwUAAAACbWMEAAAAFXRyYW5zZmVycmVkQ29sbGF0ZXJhbAkBAAAABWFzSW50AAAAAQkAA/wAAAAEBQAAAAJjcgIAAAASdHJhbnNmZXJBVG9rZW5zRm9yCQAETAAAAAIFAAAACGJvcnJvd2VyCQAETAAAAAIFAAAACmxpcXVpZGF0b3IJAARMAAAAAgUAAAANcGVuYWx0aXplZFVzZAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAFXRyYW5zZmVycmVkQ29sbGF0ZXJhbAUAAAAVdHJhbnNmZXJyZWRDb2xsYXRlcmFsBAAAAARwUncxCQEAAAAKbW92ZVN0cmVhbQAAAAUFAAAAEWNvbGxhdGVyYWxSZXNlcnZlAgAAAAdkZXBvc2l0BQAAAAhib3Jyb3dlcgUAAAAKbGlxdWlkYXRvcgUAAAAVdHJhbnNmZXJyZWRDb2xsYXRlcmFsAwkAAAAAAAACBQAAAARwUncxBQAAAARwUncxBAAAAA90cmFuc2ZlcnJlZERlYnQJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAACYnICAAAAD3RyYW5zZmVyRGVidEZvcgkABEwAAAACBQAAAAhib3Jyb3dlcgkABEwAAAACBQAAAApsaXF1aWRhdG9yCQAETAAAAAIFAAAAE2xpcXVpZGF0ZURlYnRBbW91bnQFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAA90cmFuc2ZlcnJlZERlYnQFAAAAD3RyYW5zZmVycmVkRGVidAQAAAAEcFJ3MgkBAAAACm1vdmVTdHJlYW0AAAAFBQAAAA1ib3Jyb3dSZXNlcnZlAgAAAAZib3Jyb3cFAAAACGJvcnJvd2VyBQAAAApsaXF1aWRhdG9yBQAAAA90cmFuc2ZlcnJlZERlYnQDCQAAAAAAAAIFAAAABHBSdzIFAAAABHBSdzIEAAAAFWxpcXVpZGF0b3JIZWFsdGhDaGVjawMJAQAAAAhjb250YWlucwAAAAIFAAAAC2xpcXVpZGF0b3JzBQAAAApsaXF1aWRhdG9yBQAAAANuaWwJAQAAAA12YWxpZGF0ZUFmdGVyAAAAAgUAAAAKbGlxdWlkYXRvcgIAAAARdHJhbnNmZXJyaW5nIGRlYnQDCQAAAAAAAAIFAAAAFWxpcXVpZGF0b3JIZWFsdGhDaGVjawUAAAAVbGlxdWlkYXRvckhlYWx0aENoZWNrCQAFFAAAAAIFAAAAFWxpcXVpZGF0b3JIZWFsdGhDaGVjawUAAAAVdHJhbnNmZXJyZWRDb2xsYXRlcmFsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEAAAAVZm9yY2VDb2xsYXBzZUludGVybmFsAAAABAAAAApsaXF1aWRhdG9yAAAAA3JzcgAAAAhib3Jyb3dlcgAAAA1mcm9tUHJvdGVjdGVkBAAAAA5yZXNlcnZlQWRkcmVzcwkBAAAAA3ZsUgAAAAEFAAAAA3JzcgMJAAAAAAAAAgUAAAAOcmVzZXJ2ZUFkZHJlc3MFAAAADnJlc2VydmVBZGRyZXNzBAAAAAJzaAkBAAAAEXN5bmNSZXdhcmRzSGVpZ2h0AAAAAQUAAAADcnNyAwkAAAAAAAACBQAAAAJzaAUAAAACc2gDCQAAAAAAAAIFAAAACmxpcXVpZGF0b3IFAAAACGJvcnJvd2VyCQAAAgAAAAECAAAAJGNhbid0IGNvbGxhcHNlIHNlbGYgaW4gdGhpcyBmdW5jdGlvbgQAAAANJHQwMTIzODkxMjQyNAkBAAAACXVzZXJQb3dlcgAAAAEFAAAACGJvcnJvd2VyBAAAAAJicAgFAAAADSR0MDEyMzg5MTI0MjQAAAACXzEEAAAAA2JwdQgFAAAADSR0MDEyMzg5MTI0MjQAAAACXzIDCQAAZgAAAAIFAAAAAmJwBQAAAANicHUJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJWNhbid0IGZvcmNlIGNvbGxhcHNlIGhlYWx0aHkgdXNlcjogdT0FAAAACGJvcnJvd2VyAgAAAAUsIGJwPQkAAaQAAAABBQAAAAJicAIAAAAGLCBicHU9CQABpAAAAAEFAAAAA2JwdQQAAAAFYXNzZXQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAA5yZXNlcnZlQWRkcmVzcwIAAAAHYXNzZXRJZAkAASwAAAACAgAAABhubyBhc3NldElkIGZpZWxkIGluIHJzciAFAAAAA3JzcgQAAAACbWMDBQAAAA1mcm9tUHJvdGVjdGVkCQEAAAAObW92ZUNvbGxhdGVyYWwAAAAEBQAAAAhib3Jyb3dlcgUAAAAFYXNzZXQFAAAADnJlc2VydmVBZGRyZXNzBQAAAANyc3IFAAAABHVuaXQDCQAAAAAAAAIFAAAAAm1jBQAAAAJtYwQAAAANJHQwMTI3ODgxMjg5NgkBAAAAC3VzZXJCYWxhbmNlAAAAAgUAAAAOcmVzZXJ2ZUFkZHJlc3MFAAAACGJvcnJvd2VyAwkAAAAAAAACBQAAAA0kdDAxMjc4ODEyODk2BQAAAA0kdDAxMjc4ODEyODk2BAAAAAt1c2VyRGVidFVzZAgFAAAADSR0MDEyNzg4MTI4OTYAAAACXzUEAAAACHVzZXJEZWJ0CAUAAAANJHQwMTI3ODgxMjg5NgAAAAJfNAQAAAAMdXNlckFzc2V0VXNkCAUAAAANJHQwMTI3ODgxMjg5NgAAAAJfMwQAAAAPYm9ycm93ZXJEZXBvc2l0CAUAAAANJHQwMTI3ODgxMjg5NgAAAAJfMgQAAAAGaWdub3JlCAUAAAANJHQwMTI3ODgxMjg5NgAAAAJfMQQAAAANcGVuYWx0aXplZFVzZAkAAGsAAAADCQABlwAAAAEJAARMAAAAAgUAAAAMdXNlckFzc2V0VXNkCQAETAAAAAIFAAAAC3VzZXJEZWJ0VXNkBQAAAANuaWwFAAAAD2NvbGxhcHNlUGVuYWx0eQUAAAALZmFjdG9yc0Jhc2UEAAAAEXRyYW5zZmVycmVkQXNzZXRzCQEAAAAFYXNJbnQAAAABCQAD/AAAAAQFAAAADnJlc2VydmVBZGRyZXNzAgAAABJ0cmFuc2ZlckFUb2tlbnNGb3IJAARMAAAAAgUAAAAIYm9ycm93ZXIJAARMAAAAAgUAAAAKbGlxdWlkYXRvcgkABEwAAAACBQAAAA1wZW5hbHRpemVkVXNkBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAARdHJhbnNmZXJyZWRBc3NldHMFAAAAEXRyYW5zZmVycmVkQXNzZXRzBAAAAARwUncxCQEAAAAKbW92ZVN0cmVhbQAAAAUFAAAAA3JzcgIAAAAHZGVwb3NpdAUAAAAIYm9ycm93ZXIFAAAACmxpcXVpZGF0b3IFAAAAEXRyYW5zZmVycmVkQXNzZXRzAwkAAAAAAAACBQAAAARwUncxBQAAAARwUncxBAAAAAljb2xsYXBzZWQJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAAOcmVzZXJ2ZUFkZHJlc3MCAAAAC2NvbGxhcHNlRm9yCQAETAAAAAIFAAAACGJvcnJvd2VyBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAJY29sbGFwc2VkBQAAAAljb2xsYXBzZWQEAAAABHBSdzIJAQAAAAx1cGRhdGVTdHJlYW0AAAAF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", "chainId": 87, "height": 3060480, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Dmgi6FXUV4QaEQPFGxxa25dYa9m7YXitjLV5Eko4j5gw Next: FYugRjNsDRPdozY7MMr1DqLPC4fLem6onpqJANtykDY6 Diff:
Old | New | Differences | |
---|---|---|---|
31 | 31 | } | |
32 | 32 | ||
33 | 33 | ||
34 | - | func asInt2 (value) = match value { | |
35 | - | case x: (Int, Int) => | |
36 | - | x | |
37 | - | case t => | |
38 | - | throw("wrong type, expected: Int2") | |
39 | - | } | |
40 | - | ||
41 | - | ||
42 | 34 | func asInt3 (value) = match value { | |
43 | 35 | case x: (Int, Int, Int) => | |
44 | 36 | x | |
45 | 37 | case t => | |
46 | 38 | throw("wrong type, expected: Int3") | |
47 | - | } | |
48 | - | ||
49 | - | ||
50 | - | func asInt4 (value) = match value { | |
51 | - | case x: (Int, Int, Int, Int) => | |
52 | - | x | |
53 | - | case t => | |
54 | - | throw("wrong type, expected: Int4") | |
55 | - | } | |
56 | - | ||
57 | - | ||
58 | - | func asInt5 (value) = match value { | |
59 | - | case x: (Int, Int, Int, Int, Int) => | |
60 | - | x | |
61 | - | case t => | |
62 | - | throw("wrong type, expected: Int5") | |
63 | 39 | } | |
64 | 40 | ||
65 | 41 | ||
117 | 93 | else i.payments[0].amount | |
118 | 94 | ||
119 | 95 | ||
120 | - | func assetIdOfReserve ( | |
96 | + | func assetIdOfReserve (rsr) = valueOrErrorMessage(getString(rsr, assetIdStore), "no assetId in rsr") | |
121 | 97 | ||
122 | 98 | ||
123 | - | func collateralFactor ( | |
99 | + | func collateralFactor (rsr) = valueOrErrorMessage(getInteger(configAddress, (assetIdOfReserve(rsr) + "_CollateralFactor")), "no CollateralFactor in config") | |
124 | 100 | ||
125 | 101 | ||
126 | - | func liquidationThreshold ( | |
102 | + | func liquidationThreshold (rsr) = valueOrErrorMessage(getInteger(configAddress, (assetIdOfReserve(rsr) + "_LiquidationThreshold")), "no LiquidationThreshold in config") | |
127 | 103 | ||
128 | 104 | ||
129 | 105 | func liquidationPenalty (assetId) = valueOrErrorMessage(getInteger(configAddress, (assetId + "_LiquidationPenalty")), "no LiquidationPenalty in config") | |
142 | 118 | case found: Address => | |
143 | 119 | found | |
144 | 120 | case _ => | |
145 | - | let | |
146 | - | if ((valueOrErrorMessage(getString( | |
147 | - | then | |
121 | + | let rsr = valueOrErrorMessage(addressFromString(r), "rsr bad address") | |
122 | + | if ((valueOrErrorMessage(getString(rsr, store), ("rsr has no " + store)) == value)) | |
123 | + | then rsr | |
148 | 124 | else unit | |
149 | 125 | } | |
150 | 126 | ||
168 | 144 | } | |
169 | 145 | ||
170 | 146 | ||
171 | - | func | |
172 | - | then valueOrErrorMessage(addressFromString(r), "main: bad | |
173 | - | else throw(("unknown | |
147 | + | func vlR (r) = if (contains(reservesStr, r)) | |
148 | + | then valueOrErrorMessage(addressFromString(r), "main: bad rsr") | |
149 | + | else throw(("unknown rsr:" + r)) | |
174 | 150 | ||
175 | 151 | ||
176 | - | func userBalance ( | |
152 | + | func userBalance (rsr,user) = asUserBalanceData(invoke(rsr, "userBalance", [user], nil)) | |
177 | 153 | ||
178 | 154 | ||
179 | 155 | let maybeProtectedReserve = match getString(configAddress, "protected_reserve") { | |
183 | 159 | unit | |
184 | 160 | } | |
185 | 161 | ||
186 | - | let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected | |
162 | + | let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected rsr") | |
187 | 163 | ||
188 | 164 | func ensureNoProtected (user) = { | |
189 | 165 | let has = match maybeProtectedReserve { | |
206 | 182 | 0 | |
207 | 183 | } | |
208 | 184 | func fold (totals,r) = { | |
209 | - | let $ | |
210 | - | let totalD = $ | |
211 | - | let totalB = $ | |
212 | - | let numberOfBorrows = $ | |
213 | - | let | |
214 | - | let cf = collateralFactor( | |
215 | - | let lt = liquidationThreshold( | |
216 | - | let $ | |
217 | - | let token = $ | |
218 | - | let asset = $ | |
219 | - | let depositUsd = $ | |
220 | - | let debt = $ | |
221 | - | let debtUsd = $ | |
222 | - | let asCollateral = $ | |
185 | + | let $t053745420 = totals | |
186 | + | let totalD = $t053745420._1 | |
187 | + | let totalB = $t053745420._2 | |
188 | + | let numberOfBorrows = $t053745420._3 | |
189 | + | let rsr = valueOrErrorMessage(addressFromString(r), "rsr bad address") | |
190 | + | let cf = collateralFactor(rsr) | |
191 | + | let lt = liquidationThreshold(rsr) | |
192 | + | let $t055745658 = userBalance(rsr, user) | |
193 | + | let token = $t055745658._1 | |
194 | + | let asset = $t055745658._2 | |
195 | + | let depositUsd = $t055745658._3 | |
196 | + | let debt = $t055745658._4 | |
197 | + | let debtUsd = $t055745658._5 | |
198 | + | let asCollateral = $t055745658._6 | |
223 | 199 | let totalBorrows = (numberOfBorrows + (if ((debt > 0)) | |
224 | 200 | then 1 | |
225 | 201 | else 0)) | |
256 | 232 | ||
257 | 233 | ||
258 | 234 | func getUserHealth (account) = { | |
259 | - | let $ | |
260 | - | let bp = $ | |
261 | - | let bpu = $ | |
262 | - | let ignore = $ | |
235 | + | let $t064476498 = asInt3(userPower(account)) | |
236 | + | let bp = $t064476498._1 | |
237 | + | let bpu = $t064476498._2 | |
238 | + | let ignore = $t064476498._3 | |
263 | 239 | ((("bp:" + toString(bp)) + ", bpu:") + toString(bpu)) | |
264 | 240 | } | |
265 | 241 | ||
266 | 242 | ||
267 | 243 | func validateAfter (user,op) = { | |
268 | - | let $ | |
269 | - | let bp = $ | |
270 | - | let bpu = $ | |
244 | + | let $t066096640 = userPower(user) | |
245 | + | let bp = $t066096640._1 | |
246 | + | let bpu = $t066096640._2 | |
271 | 247 | let accHealth = (((bp - bpu) * factorsBase) / bp) | |
272 | 248 | if (if ((bp == 0)) | |
273 | 249 | then (bpu == 0) | |
283 | 259 | } | |
284 | 260 | ||
285 | 261 | ||
286 | - | func updateStream ( | |
262 | + | func updateStream (rsr,action,user,userChange,streamChange) = match mVD { | |
287 | 263 | case a: Address => | |
288 | - | invoke(a, "onAction", [ | |
264 | + | invoke(a, "onAction", [rsr, action, user, userChange, streamChange], nil) | |
289 | 265 | case _ => | |
290 | 266 | unit | |
291 | 267 | } | |
292 | 268 | ||
293 | 269 | ||
294 | - | func moveStream ( | |
270 | + | func moveStream (rsr,action,from,string,amount) = match mVD { | |
295 | 271 | case a: Address => | |
296 | - | invoke(a, "move", [ | |
272 | + | invoke(a, "move", [rsr, action, from, string, amount], nil) | |
297 | 273 | case _ => | |
298 | 274 | unit | |
299 | 275 | } | |
300 | 276 | ||
301 | 277 | ||
302 | - | func syncRewardsHeight ( | |
278 | + | func syncRewardsHeight (rsr) = match mVD { | |
303 | 279 | case a: Address => | |
304 | - | invoke(a, "syncHeight", [ | |
280 | + | invoke(a, "syncHeight", [rsr], nil) | |
305 | 281 | case _ => | |
306 | 282 | unit | |
307 | 283 | } | |
317 | 293 | } | |
318 | 294 | ||
319 | 295 | ||
320 | - | func doDeposit (i, | |
296 | + | func doDeposit (i,rsr,useAsCollateral) = { | |
321 | 297 | let user = toString(i.caller) | |
322 | 298 | let checks = ensureNoProtected(user) | |
323 | 299 | if ((checks == checks)) | |
324 | 300 | then { | |
325 | - | let sh = syncRewardsHeight( | |
301 | + | let sh = syncRewardsHeight(rsr) | |
326 | 302 | if ((sh == sh)) | |
327 | 303 | then { | |
328 | - | let action = invoke( | |
304 | + | let action = invoke(vlR(rsr), "depositFor", [user, useAsCollateral], i.payments) | |
329 | 305 | if ((action == action)) | |
330 | 306 | then { | |
331 | 307 | let amt = i.payments[0].amount | |
332 | - | let pRw = updateStream( | |
308 | + | let pRw = updateStream(rsr, "deposit", user, amt, amt) | |
333 | 309 | if ((pRw == pRw)) | |
334 | 310 | then if (!(useAsCollateral)) | |
335 | 311 | then validateAfter(user, "depositing") | |
349 | 325 | if ((claimedEb == claimedEb)) | |
350 | 326 | then { | |
351 | 327 | let rewardReserves = split(valueOrErrorMessage(getString(configAddress, "rewardable_reserves"), "no string"), "|") | |
352 | - | func fold (acc, | |
353 | - | let claimed = asInt(invoke(VD, "claimRewardFor", [ | |
328 | + | func fold (acc,rsr) = { | |
329 | + | let claimed = asInt(invoke(VD, "claimRewardFor", [rsr, user, -1], nil)) | |
354 | 330 | if ((claimed == claimed)) | |
355 | 331 | then (acc + claimed) | |
356 | 332 | else throw("Strict value is not equal to itself.") | |
376 | 352 | } | |
377 | 353 | ||
378 | 354 | ||
379 | - | func moveCollateral (addr,assetStr, | |
355 | + | func moveCollateral (addr,assetStr,rsr,reserveStr) = { | |
380 | 356 | let amt = asInt(invoke(protectedReserve, "withdrawToMain", [addr, assetStr], nil)) | |
381 | 357 | if ((amt == amt)) | |
382 | 358 | then { | |
383 | 359 | let assetId = if ((assetStr == "WAVES")) | |
384 | 360 | then unit | |
385 | 361 | else fromBase58String(assetStr) | |
386 | - | let dep = invoke( | |
362 | + | let dep = invoke(rsr, "depositFor", [addr, true], [AttachedPayment(assetId, amt)]) | |
387 | 363 | if ((dep == dep)) | |
388 | 364 | then { | |
389 | 365 | let prop = updateStream(reserveStr, "deposit", addr, amt, amt) | |
410 | 386 | else if ((liquidator == borrower)) | |
411 | 387 | then throw("can't liquidate self") | |
412 | 388 | else { | |
413 | - | let $ | |
414 | - | let bp = $ | |
415 | - | let bpu = $ | |
389 | + | let $t099609995 = userPower(borrower) | |
390 | + | let bp = $t099609995._1 | |
391 | + | let bpu = $t099609995._2 | |
416 | 392 | if ((bp > bpu)) | |
417 | 393 | then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu))) | |
418 | 394 | else { | |
419 | - | let br = | |
420 | - | let cr = | |
395 | + | let br = vlR(borrowReserve) | |
396 | + | let cr = vlR(collateralReserve) | |
421 | 397 | let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve)) | |
422 | 398 | let collateralAsset = valueOrErrorMessage(getString(cr, "assetId"), ("no assetId field in collateralReserve " + collateralReserve)) | |
423 | 399 | let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false) | |
427 | 403 | else false) | |
428 | 404 | then throw("can't liquidate deposit not used as collateral") | |
429 | 405 | else { | |
430 | - | let $ | |
431 | - | if (($ | |
406 | + | let $t01063610726 = userBalance(br, borrower) | |
407 | + | if (($t01063610726 == $t01063610726)) | |
432 | 408 | then { | |
433 | - | let userDebtUsd = $ | |
434 | - | let userDebt = $ | |
435 | - | let userAssetUsd = $ | |
436 | - | let userAsset = $ | |
437 | - | let ignore = $ | |
409 | + | let userDebtUsd = $t01063610726._5 | |
410 | + | let userDebt = $t01063610726._4 | |
411 | + | let userAssetUsd = $t01063610726._3 | |
412 | + | let userAsset = $t01063610726._2 | |
413 | + | let ignore = $t01063610726._1 | |
438 | 414 | if ((userAsset >= userDebt)) | |
439 | 415 | then throw("can't liquidate debt of asset of positive saldo") | |
440 | 416 | else if ((0 >= liquidateDebtAmount)) | |
490 | 466 | } | |
491 | 467 | ||
492 | 468 | ||
493 | - | func forceCollapseInternal (liquidator, | |
494 | - | let reserveAddress = | |
469 | + | func forceCollapseInternal (liquidator,rsr,borrower,fromProtected) = { | |
470 | + | let reserveAddress = vlR(rsr) | |
495 | 471 | if ((reserveAddress == reserveAddress)) | |
496 | 472 | then { | |
497 | - | let sh = syncRewardsHeight( | |
473 | + | let sh = syncRewardsHeight(rsr) | |
498 | 474 | if ((sh == sh)) | |
499 | 475 | then if ((liquidator == borrower)) | |
500 | 476 | then throw("can't collapse self in this function") | |
501 | 477 | else { | |
502 | - | let $ | |
503 | - | let bp = $ | |
504 | - | let bpu = $ | |
478 | + | let $t01238912424 = userPower(borrower) | |
479 | + | let bp = $t01238912424._1 | |
480 | + | let bpu = $t01238912424._2 | |
505 | 481 | if ((bp > bpu)) | |
506 | 482 | then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu))) | |
507 | 483 | else { | |
508 | - | let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in | |
484 | + | let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in rsr " + rsr)) | |
509 | 485 | let mc = if (fromProtected) | |
510 | - | then moveCollateral(borrower, asset, reserveAddress, | |
486 | + | then moveCollateral(borrower, asset, reserveAddress, rsr) | |
511 | 487 | else unit | |
512 | 488 | if ((mc == mc)) | |
513 | 489 | then { | |
514 | - | let $ | |
515 | - | if (($ | |
490 | + | let $t01278812896 = userBalance(reserveAddress, borrower) | |
491 | + | if (($t01278812896 == $t01278812896)) | |
516 | 492 | then { | |
517 | - | let userDebtUsd = $ | |
518 | - | let userDebt = $ | |
519 | - | let userAssetUsd = $ | |
520 | - | let borrowerDeposit = $ | |
521 | - | let ignore = $ | |
493 | + | let userDebtUsd = $t01278812896._5 | |
494 | + | let userDebt = $t01278812896._4 | |
495 | + | let userAssetUsd = $t01278812896._3 | |
496 | + | let borrowerDeposit = $t01278812896._2 | |
497 | + | let ignore = $t01278812896._1 | |
522 | 498 | let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase) | |
523 | 499 | let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil)) | |
524 | 500 | if ((transferredAssets == transferredAssets)) | |
525 | 501 | then { | |
526 | - | let pRw1 = moveStream( | |
502 | + | let pRw1 = moveStream(rsr, "deposit", borrower, liquidator, transferredAssets) | |
527 | 503 | if ((pRw1 == pRw1)) | |
528 | 504 | then { | |
529 | 505 | let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil)) | |
530 | 506 | if ((collapsed == collapsed)) | |
531 | 507 | then { | |
532 | - | let pRw2 = updateStream( | |
508 | + | let pRw2 = updateStream(rsr, "borrow", borrower, -(collapsed), -(collapsed)) | |
533 | 509 | if ((pRw2 == pRw2)) | |
534 | 510 | then { | |
535 | - | let pRw3 = updateStream( | |
511 | + | let pRw3 = updateStream(rsr, "deposit", borrower, -(collapsed), -(collapsed)) | |
536 | 512 | if ((pRw3 == pRw3)) | |
537 | 513 | then nil | |
538 | 514 | else throw("Strict value is not equal to itself.") | |
559 | 535 | func spfr () = invoke(dC, "shareProfitFromReserves", nil, nil) | |
560 | 536 | ||
561 | 537 | ||
562 | - | func wdInternal (user, | |
563 | - | let sh = syncRewardsHeight(toString( | |
538 | + | func wdInternal (user,rsr,amount,op) = { | |
539 | + | let sh = syncRewardsHeight(toString(rsr)) | |
564 | 540 | if ((sh == sh)) | |
565 | 541 | then { | |
566 | - | let withdrawnAmount = asInt(invoke( | |
542 | + | let withdrawnAmount = asInt(invoke(rsr, op, [user, amount], nil)) | |
567 | 543 | if ((withdrawnAmount == withdrawnAmount)) | |
568 | 544 | then { | |
569 | - | let pRw = updateStream(toString( | |
545 | + | let pRw = updateStream(toString(rsr), "deposit", user, -(withdrawnAmount), -(withdrawnAmount)) | |
570 | 546 | if ((pRw == pRw)) | |
571 | 547 | then withdrawnAmount | |
572 | 548 | else throw("Strict value is not equal to itself.") | |
583 | 559 | ||
584 | 560 | ||
585 | 561 | @Callable(i) | |
586 | - | func deposit ( | |
562 | + | func deposit (rsr,useAsCollateral) = doDeposit(i, rsr, useAsCollateral) | |
587 | 563 | ||
588 | 564 | ||
589 | 565 | ||
590 | 566 | @Callable(i) | |
591 | - | func depositRef ( | |
567 | + | func depositRef (rsr,useAsCollateral,ref) = doDeposit(i, rsr, useAsCollateral) | |
592 | 568 | ||
593 | 569 | ||
594 | 570 | ||
595 | 571 | @Callable(i) | |
596 | - | func repay ( | |
572 | + | func repay (rsr) = { | |
597 | 573 | let user = toString(i.caller) | |
598 | - | let sh = syncRewardsHeight( | |
574 | + | let sh = syncRewardsHeight(rsr) | |
599 | 575 | if ((sh == sh)) | |
600 | 576 | then { | |
601 | - | let repaid = asInt(invoke( | |
577 | + | let repaid = asInt(invoke(vlR(rsr), "repayFor", [user], i.payments)) | |
602 | 578 | if ((repaid == repaid)) | |
603 | 579 | then { | |
604 | - | let pRw = updateStream( | |
580 | + | let pRw = updateStream(rsr, "borrow", user, -(repaid), -(repaid)) | |
605 | 581 | if ((pRw == pRw)) | |
606 | 582 | then nil | |
607 | 583 | else throw("Strict value is not equal to itself.") | |
698 | 674 | ||
699 | 675 | ||
700 | 676 | @Callable(i) | |
701 | - | func withdraw2 ( | |
677 | + | func withdraw2 (rsr,amount) = { | |
702 | 678 | let user = toString(i.caller) | |
703 | - | let sh = syncRewardsHeight( | |
679 | + | let sh = syncRewardsHeight(rsr) | |
704 | 680 | if ((sh == sh)) | |
705 | 681 | then { | |
706 | - | let amt = asInt(invoke( | |
682 | + | let amt = asInt(invoke(vlR(rsr), "withdrawFor", [user, amount], nil)) | |
707 | 683 | if ((amt == amt)) | |
708 | 684 | then { | |
709 | - | let pRw = updateStream( | |
685 | + | let pRw = updateStream(rsr, "deposit", user, -(amt), -(amt)) | |
710 | 686 | if ((pRw == pRw)) | |
711 | 687 | then if (contains(liquidators, user)) | |
712 | 688 | then nil | |
721 | 697 | ||
722 | 698 | ||
723 | 699 | @Callable(i) | |
724 | - | func protectCollateral ( | |
700 | + | func protectCollateral (rsr) = { | |
725 | 701 | let user = toString(i.caller) | |
726 | - | let r = | |
702 | + | let r = vlR(rsr) | |
727 | 703 | let amt = asInt(wdInternal(user, r, -1, "withdrawToMain")) | |
728 | 704 | if ((amt == amt)) | |
729 | 705 | then { | |
750 | 726 | ||
751 | 727 | ||
752 | 728 | @Callable(i) | |
729 | + | func normalizeCollateral (rsr) = { | |
730 | + | let addr = toString(i.caller) | |
731 | + | let rA = vlR(rsr) | |
732 | + | if ((rA == rA)) | |
733 | + | then { | |
734 | + | let sh = syncRewardsHeight(rsr) | |
735 | + | if ((sh == sh)) | |
736 | + | then { | |
737 | + | let assetIdStr = valueOrErrorMessage(getString(rA, "assetId"), ("no assetId field in reserveAddress " + rsr)) | |
738 | + | let mc = moveCollateral(addr, assetIdStr, rA, rsr) | |
739 | + | if ((mc == mc)) | |
740 | + | then nil | |
741 | + | else throw("Strict value is not equal to itself.") | |
742 | + | } | |
743 | + | else throw("Strict value is not equal to itself.") | |
744 | + | } | |
745 | + | else throw("Strict value is not equal to itself.") | |
746 | + | } | |
747 | + | ||
748 | + | ||
749 | + | ||
750 | + | @Callable(i) | |
753 | 751 | func borrow (assetId,amount) = { | |
754 | 752 | let user = toString(i.caller) | |
755 | - | let | |
756 | - | let sh = syncRewardsHeight(toString( | |
753 | + | let rsr = findReserveBy(assetIdStore, assetId) | |
754 | + | let sh = syncRewardsHeight(toString(rsr)) | |
757 | 755 | if ((sh == sh)) | |
758 | 756 | then { | |
759 | - | let a = invoke( | |
757 | + | let a = invoke(rsr, "borrowFor", [user, amount], nil) | |
760 | 758 | if ((a == a)) | |
761 | 759 | then { | |
762 | - | let pRw = updateStream(toString( | |
760 | + | let pRw = updateStream(toString(rsr), "borrow", user, amount, amount) | |
763 | 761 | if ((pRw == pRw)) | |
764 | 762 | then validateAfter(user, "borrowing") | |
765 | 763 | else throw("Strict value is not equal to itself.") | |
772 | 770 | ||
773 | 771 | ||
774 | 772 | @Callable(i) | |
775 | - | func borrow2 ( | |
773 | + | func borrow2 (rsr,amount) = { | |
776 | 774 | let user = toString(i.caller) | |
777 | - | let sh = syncRewardsHeight( | |
775 | + | let sh = syncRewardsHeight(rsr) | |
778 | 776 | if ((sh == sh)) | |
779 | 777 | then { | |
780 | - | let a = invoke( | |
778 | + | let a = invoke(vlR(rsr), "borrowFor", [user, amount], nil) | |
781 | 779 | if ((a == a)) | |
782 | 780 | then { | |
783 | - | let pRw = updateStream( | |
781 | + | let pRw = updateStream(rsr, "borrow", user, amount, amount) | |
784 | 782 | if ((pRw == pRw)) | |
785 | 783 | then validateAfter(user, "borrowing") | |
786 | 784 | else throw("Strict value is not equal to itself.") | |
793 | 791 | ||
794 | 792 | ||
795 | 793 | @Callable(i) | |
796 | - | func collapse ( | |
794 | + | func collapse (rsr,amount) = { | |
797 | 795 | let user = toString(i.caller) | |
798 | - | let sh = syncRewardsHeight( | |
796 | + | let sh = syncRewardsHeight(rsr) | |
799 | 797 | if ((sh == sh)) | |
800 | 798 | then { | |
801 | - | let c = asInt(invoke( | |
799 | + | let c = asInt(invoke(vlR(rsr), "collapseForAmount", [user, amount], nil)) | |
802 | 800 | if ((c == c)) | |
803 | 801 | then { | |
804 | - | let pRw = updateStream( | |
802 | + | let pRw = updateStream(rsr, "borrow", user, -(c), -(c)) | |
805 | 803 | if ((pRw == pRw)) | |
806 | 804 | then { | |
807 | - | let pRw2 = updateStream( | |
805 | + | let pRw2 = updateStream(rsr, "deposit", user, -(c), -(c)) | |
808 | 806 | if ((pRw2 == pRw2)) | |
809 | 807 | then nil | |
810 | 808 | else throw("Strict value is not equal to itself.") | |
830 | 828 | ||
831 | 829 | ||
832 | 830 | @Callable(i) | |
833 | - | func claimReward2 ( | |
834 | - | let v = | |
831 | + | func claimReward2 (rsr,amount,lock) = { | |
832 | + | let v = vlR(rsr) | |
835 | 833 | if ((v == v)) | |
836 | 834 | then { | |
837 | 835 | let user = toString(i.caller) | |
838 | - | let c = asInt(invoke(VD, "claimRewardFor", [ | |
836 | + | let c = asInt(invoke(VD, "claimRewardFor", [rsr, user, amount], nil)) | |
839 | 837 | if ((c == c)) | |
840 | 838 | then lockOrPayout(i.caller, c, lock) | |
841 | 839 | else throw("Strict value is not equal to itself.") | |
864 | 862 | ||
865 | 863 | ||
866 | 864 | @Callable(i) | |
867 | - | func disableUseAsCollateral ( | |
865 | + | func disableUseAsCollateral (rsr) = { | |
868 | 866 | let user = toString(i.caller) | |
869 | - | let d = invoke( | |
867 | + | let d = invoke(vlR(rsr), "disableUseAsCollateralFor", [user], nil) | |
870 | 868 | if ((d == d)) | |
871 | 869 | then validateAfter(user, "changing collateral status") | |
872 | 870 | else throw("Strict value is not equal to itself.") |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 5 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let factorsBase = 1000 | |
5 | 5 | ||
6 | 6 | func fractionCeil (value,numerator,denominator) = { | |
7 | 7 | let cand = fraction(value, numerator, denominator) | |
8 | 8 | let D = 3037000499 | |
9 | 9 | let exact = ((((cand % D) * (denominator % D)) % D) == (((value % D) * (numerator % D)) % D)) | |
10 | 10 | if (exact) | |
11 | 11 | then cand | |
12 | 12 | else (cand + 1) | |
13 | 13 | } | |
14 | 14 | ||
15 | 15 | ||
16 | 16 | func assetStrToId (assetId) = if ((assetId == "WAVES")) | |
17 | 17 | then unit | |
18 | 18 | else fromBase58String(assetId) | |
19 | 19 | ||
20 | 20 | ||
21 | 21 | func writeConstString (key,value) = if (!(isDefined(getString(this, key)))) | |
22 | 22 | then StringEntry(key, value) | |
23 | 23 | else throw(("already initialized: " + key)) | |
24 | 24 | ||
25 | 25 | ||
26 | 26 | func asInt (value) = match value { | |
27 | 27 | case int: Int => | |
28 | 28 | int | |
29 | 29 | case _ => | |
30 | 30 | throw("wrong type, expected: Int") | |
31 | 31 | } | |
32 | 32 | ||
33 | 33 | ||
34 | - | func asInt2 (value) = match value { | |
35 | - | case x: (Int, Int) => | |
36 | - | x | |
37 | - | case t => | |
38 | - | throw("wrong type, expected: Int2") | |
39 | - | } | |
40 | - | ||
41 | - | ||
42 | 34 | func asInt3 (value) = match value { | |
43 | 35 | case x: (Int, Int, Int) => | |
44 | 36 | x | |
45 | 37 | case t => | |
46 | 38 | throw("wrong type, expected: Int3") | |
47 | - | } | |
48 | - | ||
49 | - | ||
50 | - | func asInt4 (value) = match value { | |
51 | - | case x: (Int, Int, Int, Int) => | |
52 | - | x | |
53 | - | case t => | |
54 | - | throw("wrong type, expected: Int4") | |
55 | - | } | |
56 | - | ||
57 | - | ||
58 | - | func asInt5 (value) = match value { | |
59 | - | case x: (Int, Int, Int, Int, Int) => | |
60 | - | x | |
61 | - | case t => | |
62 | - | throw("wrong type, expected: Int5") | |
63 | 39 | } | |
64 | 40 | ||
65 | 41 | ||
66 | 42 | func asUserBalanceData (value) = match value { | |
67 | 43 | case x: (Int, Int, Int, Int, Int, Boolean) => | |
68 | 44 | x | |
69 | 45 | case t => | |
70 | 46 | throw("wrong type, expected: Int5&Boolean") | |
71 | 47 | } | |
72 | 48 | ||
73 | 49 | ||
74 | 50 | let configStore = "config" | |
75 | 51 | ||
76 | 52 | let reservesStore = "reserves" | |
77 | 53 | ||
78 | 54 | let aTokenIdStore = "aTokenId" | |
79 | 55 | ||
80 | 56 | let assetIdStore = "assetId" | |
81 | 57 | ||
82 | 58 | let distributorStore = "vires_distributor" | |
83 | 59 | ||
84 | 60 | let configAddress = addressFromStringValue(getStringValue(this, configStore)) | |
85 | 61 | ||
86 | 62 | let reservesStr = valueOrErrorMessage(getString(configAddress, "primary_reserves"), "no reserves registered") | |
87 | 63 | ||
88 | 64 | let reserves = split(reservesStr, "|") | |
89 | 65 | ||
90 | 66 | let ebR = addressFromStringValue(valueOrErrorMessage(getString(configAddress, "eb_rewards"), "no eb_rewards contract in config")) | |
91 | 67 | ||
92 | 68 | let viresMinter = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, "vires_minter"), "main: no viresMinter")), "invalid viresMinter") | |
93 | 69 | ||
94 | 70 | let maybevS = getString(configAddress, "vires_staker") | |
95 | 71 | ||
96 | 72 | let vS = addressFromStringValue(valueOrErrorMessage(maybevS, "no vires_staker")) | |
97 | 73 | ||
98 | 74 | let dC = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configAddress, "dividends_contract"), "no dividends_contract")), "invalid dividends_contract") | |
99 | 75 | ||
100 | 76 | let mVD = match getString(configAddress, distributorStore) { | |
101 | 77 | case d: String => | |
102 | 78 | addressFromStringValue(d) | |
103 | 79 | case _ => | |
104 | 80 | unit | |
105 | 81 | } | |
106 | 82 | ||
107 | 83 | let VD = valueOrErrorMessage(mVD, "no distributor to claim rewards") | |
108 | 84 | ||
109 | 85 | let maybeViresAssetId = getString(viresMinter, "assetId") | |
110 | 86 | ||
111 | 87 | let viresAssetId = valueOrErrorMessage(fromBase58String(valueOrErrorMessage(maybeViresAssetId, "vires assetId not found")), "invalid vires assetId") | |
112 | 88 | ||
113 | 89 | func viresPayment (i) = if ((size(i.payments) == 0)) | |
114 | 90 | then 0 | |
115 | 91 | else if ((i.payments[0].assetId != viresAssetId)) | |
116 | 92 | then throw("not vires") | |
117 | 93 | else i.payments[0].amount | |
118 | 94 | ||
119 | 95 | ||
120 | - | func assetIdOfReserve ( | |
96 | + | func assetIdOfReserve (rsr) = valueOrErrorMessage(getString(rsr, assetIdStore), "no assetId in rsr") | |
121 | 97 | ||
122 | 98 | ||
123 | - | func collateralFactor ( | |
99 | + | func collateralFactor (rsr) = valueOrErrorMessage(getInteger(configAddress, (assetIdOfReserve(rsr) + "_CollateralFactor")), "no CollateralFactor in config") | |
124 | 100 | ||
125 | 101 | ||
126 | - | func liquidationThreshold ( | |
102 | + | func liquidationThreshold (rsr) = valueOrErrorMessage(getInteger(configAddress, (assetIdOfReserve(rsr) + "_LiquidationThreshold")), "no LiquidationThreshold in config") | |
127 | 103 | ||
128 | 104 | ||
129 | 105 | func liquidationPenalty (assetId) = valueOrErrorMessage(getInteger(configAddress, (assetId + "_LiquidationPenalty")), "no LiquidationPenalty in config") | |
130 | 106 | ||
131 | 107 | ||
132 | 108 | let accountHealthThreshold = valueOrErrorMessage(getInteger(configAddress, "account_health_threshold"), "no account_health_threshold") | |
133 | 109 | ||
134 | 110 | let accountHealthOverlap = valueOrErrorMessage(getInteger(configAddress, "account_health_overlap"), "no account_health_overlap") | |
135 | 111 | ||
136 | 112 | let collapsePenalty = valueOrErrorMessage(getInteger(configAddress, "collapse_penalty"), "no collapse_penalty") | |
137 | 113 | ||
138 | 114 | let liquidators = valueOrElse(getString(configAddress, "liquidators"), "") | |
139 | 115 | ||
140 | 116 | func findReserveBy (store,value) = { | |
141 | 117 | func fold (a,r) = match a { | |
142 | 118 | case found: Address => | |
143 | 119 | found | |
144 | 120 | case _ => | |
145 | - | let | |
146 | - | if ((valueOrErrorMessage(getString( | |
147 | - | then | |
121 | + | let rsr = valueOrErrorMessage(addressFromString(r), "rsr bad address") | |
122 | + | if ((valueOrErrorMessage(getString(rsr, store), ("rsr has no " + store)) == value)) | |
123 | + | then rsr | |
148 | 124 | else unit | |
149 | 125 | } | |
150 | 126 | ||
151 | 127 | match let $l = reserves | |
152 | 128 | let $s = size($l) | |
153 | 129 | let $acc0 = unit | |
154 | 130 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
155 | 131 | then $a | |
156 | 132 | else fold($a, $l[$i]) | |
157 | 133 | ||
158 | 134 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
159 | 135 | then $a | |
160 | 136 | else throw("List size exceeds 7") | |
161 | 137 | ||
162 | 138 | $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) { | |
163 | 139 | case found: Address => | |
164 | 140 | found | |
165 | 141 | case _ => | |
166 | 142 | throw(("unknown " + store)) | |
167 | 143 | } | |
168 | 144 | } | |
169 | 145 | ||
170 | 146 | ||
171 | - | func | |
172 | - | then valueOrErrorMessage(addressFromString(r), "main: bad | |
173 | - | else throw(("unknown | |
147 | + | func vlR (r) = if (contains(reservesStr, r)) | |
148 | + | then valueOrErrorMessage(addressFromString(r), "main: bad rsr") | |
149 | + | else throw(("unknown rsr:" + r)) | |
174 | 150 | ||
175 | 151 | ||
176 | - | func userBalance ( | |
152 | + | func userBalance (rsr,user) = asUserBalanceData(invoke(rsr, "userBalance", [user], nil)) | |
177 | 153 | ||
178 | 154 | ||
179 | 155 | let maybeProtectedReserve = match getString(configAddress, "protected_reserve") { | |
180 | 156 | case pds: String => | |
181 | 157 | valueOrErrorMessage(addressFromString(pds), "bad protected_reserve") | |
182 | 158 | case _ => | |
183 | 159 | unit | |
184 | 160 | } | |
185 | 161 | ||
186 | - | let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected | |
162 | + | let protectedReserve = valueOrErrorMessage(maybeProtectedReserve, "no protected rsr") | |
187 | 163 | ||
188 | 164 | func ensureNoProtected (user) = { | |
189 | 165 | let has = match maybeProtectedReserve { | |
190 | 166 | case pa: Address => | |
191 | 167 | valueOrElse(getBoolean(pa, ("protected_collateral_" + user)), false) | |
192 | 168 | case _ => | |
193 | 169 | false | |
194 | 170 | } | |
195 | 171 | if (has) | |
196 | 172 | then throw("disallowed: can't have regular when protected exists") | |
197 | 173 | else unit | |
198 | 174 | } | |
199 | 175 | ||
200 | 176 | ||
201 | 177 | func userPower (user) = { | |
202 | 178 | let protectedDeposit = match maybeProtectedReserve { | |
203 | 179 | case pa: Address => | |
204 | 180 | asInt(invoke(pa, "borrowPower", [user], nil)) | |
205 | 181 | case _ => | |
206 | 182 | 0 | |
207 | 183 | } | |
208 | 184 | func fold (totals,r) = { | |
209 | - | let $ | |
210 | - | let totalD = $ | |
211 | - | let totalB = $ | |
212 | - | let numberOfBorrows = $ | |
213 | - | let | |
214 | - | let cf = collateralFactor( | |
215 | - | let lt = liquidationThreshold( | |
216 | - | let $ | |
217 | - | let token = $ | |
218 | - | let asset = $ | |
219 | - | let depositUsd = $ | |
220 | - | let debt = $ | |
221 | - | let debtUsd = $ | |
222 | - | let asCollateral = $ | |
185 | + | let $t053745420 = totals | |
186 | + | let totalD = $t053745420._1 | |
187 | + | let totalB = $t053745420._2 | |
188 | + | let numberOfBorrows = $t053745420._3 | |
189 | + | let rsr = valueOrErrorMessage(addressFromString(r), "rsr bad address") | |
190 | + | let cf = collateralFactor(rsr) | |
191 | + | let lt = liquidationThreshold(rsr) | |
192 | + | let $t055745658 = userBalance(rsr, user) | |
193 | + | let token = $t055745658._1 | |
194 | + | let asset = $t055745658._2 | |
195 | + | let depositUsd = $t055745658._3 | |
196 | + | let debt = $t055745658._4 | |
197 | + | let debtUsd = $t055745658._5 | |
198 | + | let asCollateral = $t055745658._6 | |
223 | 199 | let totalBorrows = (numberOfBorrows + (if ((debt > 0)) | |
224 | 200 | then 1 | |
225 | 201 | else 0)) | |
226 | 202 | let effectiveDepositUsd = if (asCollateral) | |
227 | 203 | then depositUsd | |
228 | 204 | else 0 | |
229 | 205 | let overlapUsd = min([debtUsd, effectiveDepositUsd]) | |
230 | 206 | let overlapCharge = fractionCeil(overlapUsd, accountHealthOverlap, factorsBase) | |
231 | 207 | if ((debtUsd > effectiveDepositUsd)) | |
232 | 208 | then $Tuple3(totalD, ((totalB + fraction((debtUsd - effectiveDepositUsd), factorsBase, lt)) + overlapCharge), totalBorrows) | |
233 | 209 | else $Tuple3((totalD + fraction((effectiveDepositUsd - debtUsd), cf, factorsBase)), (totalB + overlapCharge), totalBorrows) | |
234 | 210 | } | |
235 | 211 | ||
236 | 212 | let r = { | |
237 | 213 | let $l = reserves | |
238 | 214 | let $s = size($l) | |
239 | 215 | let $acc0 = $Tuple3(protectedDeposit, 0, 0) | |
240 | 216 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
241 | 217 | then $a | |
242 | 218 | else fold($a, $l[$i]) | |
243 | 219 | ||
244 | 220 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
245 | 221 | then $a | |
246 | 222 | else throw("List size exceeds 7") | |
247 | 223 | ||
248 | 224 | $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) | |
249 | 225 | } | |
250 | 226 | if (if ((protectedDeposit > 0)) | |
251 | 227 | then (r._3 > 2) | |
252 | 228 | else false) | |
253 | 229 | then throw("can't have more than 2 borrows with protected collateral") | |
254 | 230 | else r | |
255 | 231 | } | |
256 | 232 | ||
257 | 233 | ||
258 | 234 | func getUserHealth (account) = { | |
259 | - | let $ | |
260 | - | let bp = $ | |
261 | - | let bpu = $ | |
262 | - | let ignore = $ | |
235 | + | let $t064476498 = asInt3(userPower(account)) | |
236 | + | let bp = $t064476498._1 | |
237 | + | let bpu = $t064476498._2 | |
238 | + | let ignore = $t064476498._3 | |
263 | 239 | ((("bp:" + toString(bp)) + ", bpu:") + toString(bpu)) | |
264 | 240 | } | |
265 | 241 | ||
266 | 242 | ||
267 | 243 | func validateAfter (user,op) = { | |
268 | - | let $ | |
269 | - | let bp = $ | |
270 | - | let bpu = $ | |
244 | + | let $t066096640 = userPower(user) | |
245 | + | let bp = $t066096640._1 | |
246 | + | let bpu = $t066096640._2 | |
271 | 247 | let accHealth = (((bp - bpu) * factorsBase) / bp) | |
272 | 248 | if (if ((bp == 0)) | |
273 | 249 | then (bpu == 0) | |
274 | 250 | else false) | |
275 | 251 | then nil | |
276 | 252 | else if (if ((bp == 0)) | |
277 | 253 | then (bpu > 0) | |
278 | 254 | else false) | |
279 | 255 | then throw(((op + " too much: breaching liquidation threshold(bp=0, bpu=") + toString(bpu))) | |
280 | 256 | else if ((accountHealthThreshold > accHealth)) | |
281 | 257 | then throw((((((((op + " too much: breaching liquidation threshold(bp=") + toString(bp)) + ", bpu=") + toString(bpu)) + ", health=") + toString(accHealth)) + ")")) | |
282 | 258 | else nil | |
283 | 259 | } | |
284 | 260 | ||
285 | 261 | ||
286 | - | func updateStream ( | |
262 | + | func updateStream (rsr,action,user,userChange,streamChange) = match mVD { | |
287 | 263 | case a: Address => | |
288 | - | invoke(a, "onAction", [ | |
264 | + | invoke(a, "onAction", [rsr, action, user, userChange, streamChange], nil) | |
289 | 265 | case _ => | |
290 | 266 | unit | |
291 | 267 | } | |
292 | 268 | ||
293 | 269 | ||
294 | - | func moveStream ( | |
270 | + | func moveStream (rsr,action,from,string,amount) = match mVD { | |
295 | 271 | case a: Address => | |
296 | - | invoke(a, "move", [ | |
272 | + | invoke(a, "move", [rsr, action, from, string, amount], nil) | |
297 | 273 | case _ => | |
298 | 274 | unit | |
299 | 275 | } | |
300 | 276 | ||
301 | 277 | ||
302 | - | func syncRewardsHeight ( | |
278 | + | func syncRewardsHeight (rsr) = match mVD { | |
303 | 279 | case a: Address => | |
304 | - | invoke(a, "syncHeight", [ | |
280 | + | invoke(a, "syncHeight", [rsr], nil) | |
305 | 281 | case _ => | |
306 | 282 | unit | |
307 | 283 | } | |
308 | 284 | ||
309 | 285 | ||
310 | 286 | func lockOrPayout (recipient,amount,lock) = if (!(lock)) | |
311 | 287 | then [ScriptTransfer(recipient, amount, viresAssetId)] | |
312 | 288 | else { | |
313 | 289 | let doLock = invoke(dC, "lockFor", [toString(recipient), 1], [AttachedPayment(viresAssetId, amount)]) | |
314 | 290 | if ((doLock == doLock)) | |
315 | 291 | then nil | |
316 | 292 | else throw("Strict value is not equal to itself.") | |
317 | 293 | } | |
318 | 294 | ||
319 | 295 | ||
320 | - | func doDeposit (i, | |
296 | + | func doDeposit (i,rsr,useAsCollateral) = { | |
321 | 297 | let user = toString(i.caller) | |
322 | 298 | let checks = ensureNoProtected(user) | |
323 | 299 | if ((checks == checks)) | |
324 | 300 | then { | |
325 | - | let sh = syncRewardsHeight( | |
301 | + | let sh = syncRewardsHeight(rsr) | |
326 | 302 | if ((sh == sh)) | |
327 | 303 | then { | |
328 | - | let action = invoke( | |
304 | + | let action = invoke(vlR(rsr), "depositFor", [user, useAsCollateral], i.payments) | |
329 | 305 | if ((action == action)) | |
330 | 306 | then { | |
331 | 307 | let amt = i.payments[0].amount | |
332 | - | let pRw = updateStream( | |
308 | + | let pRw = updateStream(rsr, "deposit", user, amt, amt) | |
333 | 309 | if ((pRw == pRw)) | |
334 | 310 | then if (!(useAsCollateral)) | |
335 | 311 | then validateAfter(user, "depositing") | |
336 | 312 | else nil | |
337 | 313 | else throw("Strict value is not equal to itself.") | |
338 | 314 | } | |
339 | 315 | else throw("Strict value is not equal to itself.") | |
340 | 316 | } | |
341 | 317 | else throw("Strict value is not equal to itself.") | |
342 | 318 | } | |
343 | 319 | else throw("Strict value is not equal to itself.") | |
344 | 320 | } | |
345 | 321 | ||
346 | 322 | ||
347 | 323 | func claimAllRewardsForUser (user) = { | |
348 | 324 | let claimedEb = asInt(invoke(ebR, "claimEbRewardFor", [user, -1], nil)) | |
349 | 325 | if ((claimedEb == claimedEb)) | |
350 | 326 | then { | |
351 | 327 | let rewardReserves = split(valueOrErrorMessage(getString(configAddress, "rewardable_reserves"), "no string"), "|") | |
352 | - | func fold (acc, | |
353 | - | let claimed = asInt(invoke(VD, "claimRewardFor", [ | |
328 | + | func fold (acc,rsr) = { | |
329 | + | let claimed = asInt(invoke(VD, "claimRewardFor", [rsr, user, -1], nil)) | |
354 | 330 | if ((claimed == claimed)) | |
355 | 331 | then (acc + claimed) | |
356 | 332 | else throw("Strict value is not equal to itself.") | |
357 | 333 | } | |
358 | 334 | ||
359 | 335 | let claimedTotal = { | |
360 | 336 | let $l = rewardReserves | |
361 | 337 | let $s = size($l) | |
362 | 338 | let $acc0 = 0 | |
363 | 339 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
364 | 340 | then $a | |
365 | 341 | else fold($a, $l[$i]) | |
366 | 342 | ||
367 | 343 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
368 | 344 | then $a | |
369 | 345 | else throw("List size exceeds 7") | |
370 | 346 | ||
371 | 347 | $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) | |
372 | 348 | } | |
373 | 349 | (claimedTotal + claimedEb) | |
374 | 350 | } | |
375 | 351 | else throw("Strict value is not equal to itself.") | |
376 | 352 | } | |
377 | 353 | ||
378 | 354 | ||
379 | - | func moveCollateral (addr,assetStr, | |
355 | + | func moveCollateral (addr,assetStr,rsr,reserveStr) = { | |
380 | 356 | let amt = asInt(invoke(protectedReserve, "withdrawToMain", [addr, assetStr], nil)) | |
381 | 357 | if ((amt == amt)) | |
382 | 358 | then { | |
383 | 359 | let assetId = if ((assetStr == "WAVES")) | |
384 | 360 | then unit | |
385 | 361 | else fromBase58String(assetStr) | |
386 | - | let dep = invoke( | |
362 | + | let dep = invoke(rsr, "depositFor", [addr, true], [AttachedPayment(assetId, amt)]) | |
387 | 363 | if ((dep == dep)) | |
388 | 364 | then { | |
389 | 365 | let prop = updateStream(reserveStr, "deposit", addr, amt, amt) | |
390 | 366 | if ((prop == prop)) | |
391 | 367 | then unit | |
392 | 368 | else throw("Strict value is not equal to itself.") | |
393 | 369 | } | |
394 | 370 | else throw("Strict value is not equal to itself.") | |
395 | 371 | } | |
396 | 372 | else throw("Strict value is not equal to itself.") | |
397 | 373 | } | |
398 | 374 | ||
399 | 375 | ||
400 | 376 | func transferDebtInternal (liquidator,borrowReserve,collateralReserve,borrower,liquidateDebtAmount,fromProtected) = { | |
401 | 377 | let sh1 = syncRewardsHeight(borrowReserve) | |
402 | 378 | if ((sh1 == sh1)) | |
403 | 379 | then { | |
404 | 380 | let sh2 = syncRewardsHeight(collateralReserve) | |
405 | 381 | if ((sh2 == sh2)) | |
406 | 382 | then if ((0 >= liquidateDebtAmount)) | |
407 | 383 | then throw("can't liquidate non-positive amount") | |
408 | 384 | else if ((collateralReserve == borrowReserve)) | |
409 | 385 | then throw("collateralReserve equals borrowReserve") | |
410 | 386 | else if ((liquidator == borrower)) | |
411 | 387 | then throw("can't liquidate self") | |
412 | 388 | else { | |
413 | - | let $ | |
414 | - | let bp = $ | |
415 | - | let bpu = $ | |
389 | + | let $t099609995 = userPower(borrower) | |
390 | + | let bp = $t099609995._1 | |
391 | + | let bpu = $t099609995._2 | |
416 | 392 | if ((bp > bpu)) | |
417 | 393 | then throw(((((("can't liquidate healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu))) | |
418 | 394 | else { | |
419 | - | let br = | |
420 | - | let cr = | |
395 | + | let br = vlR(borrowReserve) | |
396 | + | let cr = vlR(collateralReserve) | |
421 | 397 | let borrowAsset = valueOrErrorMessage(getString(br, "assetId"), ("no assetId field in borrowReserve " + borrowReserve)) | |
422 | 398 | let collateralAsset = valueOrErrorMessage(getString(cr, "assetId"), ("no assetId field in collateralReserve " + collateralReserve)) | |
423 | 399 | let isCollateral = valueOrElse(getBoolean(cr, (borrower + "_useAsCollateral")), false) | |
424 | 400 | if ((isCollateral == isCollateral)) | |
425 | 401 | then if (if (!(fromProtected)) | |
426 | 402 | then !(isCollateral) | |
427 | 403 | else false) | |
428 | 404 | then throw("can't liquidate deposit not used as collateral") | |
429 | 405 | else { | |
430 | - | let $ | |
431 | - | if (($ | |
406 | + | let $t01063610726 = userBalance(br, borrower) | |
407 | + | if (($t01063610726 == $t01063610726)) | |
432 | 408 | then { | |
433 | - | let userDebtUsd = $ | |
434 | - | let userDebt = $ | |
435 | - | let userAssetUsd = $ | |
436 | - | let userAsset = $ | |
437 | - | let ignore = $ | |
409 | + | let userDebtUsd = $t01063610726._5 | |
410 | + | let userDebt = $t01063610726._4 | |
411 | + | let userAssetUsd = $t01063610726._3 | |
412 | + | let userAsset = $t01063610726._2 | |
413 | + | let ignore = $t01063610726._1 | |
438 | 414 | if ((userAsset >= userDebt)) | |
439 | 415 | then throw("can't liquidate debt of asset of positive saldo") | |
440 | 416 | else if ((0 >= liquidateDebtAmount)) | |
441 | 417 | then throw("can't liquidate zero or negative amount") | |
442 | 418 | else if (((liquidateDebtAmount * 2) > (userDebt - userAsset))) | |
443 | 419 | then throw(((((("can't liquidate more than half of saldo: debt=" + toString(userDebt)) + ", deposit=") + toString(userAsset)) + ", liquidateDebtAmount = ") + toString(liquidateDebtAmount))) | |
444 | 420 | else { | |
445 | 421 | let collateralUsd = fraction(liquidateDebtAmount, userDebtUsd, userDebt) | |
446 | 422 | let penaltizedUsd = fraction(collateralUsd, (factorsBase + liquidationPenalty(borrowAsset)), factorsBase) | |
447 | 423 | let mc = if (fromProtected) | |
448 | 424 | then moveCollateral(borrower, collateralAsset, cr, collateralReserve) | |
449 | 425 | else unit | |
450 | 426 | if ((mc == mc)) | |
451 | 427 | then { | |
452 | 428 | let transferredCollateral = asInt(invoke(cr, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil)) | |
453 | 429 | if ((transferredCollateral == transferredCollateral)) | |
454 | 430 | then { | |
455 | 431 | let pRw1 = moveStream(collateralReserve, "deposit", borrower, liquidator, transferredCollateral) | |
456 | 432 | if ((pRw1 == pRw1)) | |
457 | 433 | then { | |
458 | 434 | let transferredDebt = asInt(invoke(br, "transferDebtFor", [borrower, liquidator, liquidateDebtAmount], nil)) | |
459 | 435 | if ((transferredDebt == transferredDebt)) | |
460 | 436 | then { | |
461 | 437 | let pRw2 = moveStream(borrowReserve, "borrow", borrower, liquidator, transferredDebt) | |
462 | 438 | if ((pRw2 == pRw2)) | |
463 | 439 | then { | |
464 | 440 | let liquidatorHealthCheck = if (contains(liquidators, liquidator)) | |
465 | 441 | then nil | |
466 | 442 | else validateAfter(liquidator, "transferring debt") | |
467 | 443 | if ((liquidatorHealthCheck == liquidatorHealthCheck)) | |
468 | 444 | then $Tuple2(liquidatorHealthCheck, transferredCollateral) | |
469 | 445 | else throw("Strict value is not equal to itself.") | |
470 | 446 | } | |
471 | 447 | else throw("Strict value is not equal to itself.") | |
472 | 448 | } | |
473 | 449 | else throw("Strict value is not equal to itself.") | |
474 | 450 | } | |
475 | 451 | else throw("Strict value is not equal to itself.") | |
476 | 452 | } | |
477 | 453 | else throw("Strict value is not equal to itself.") | |
478 | 454 | } | |
479 | 455 | else throw("Strict value is not equal to itself.") | |
480 | 456 | } | |
481 | 457 | } | |
482 | 458 | else throw("Strict value is not equal to itself.") | |
483 | 459 | } | |
484 | 460 | else throw("Strict value is not equal to itself.") | |
485 | 461 | } | |
486 | 462 | } | |
487 | 463 | else throw("Strict value is not equal to itself.") | |
488 | 464 | } | |
489 | 465 | else throw("Strict value is not equal to itself.") | |
490 | 466 | } | |
491 | 467 | ||
492 | 468 | ||
493 | - | func forceCollapseInternal (liquidator, | |
494 | - | let reserveAddress = | |
469 | + | func forceCollapseInternal (liquidator,rsr,borrower,fromProtected) = { | |
470 | + | let reserveAddress = vlR(rsr) | |
495 | 471 | if ((reserveAddress == reserveAddress)) | |
496 | 472 | then { | |
497 | - | let sh = syncRewardsHeight( | |
473 | + | let sh = syncRewardsHeight(rsr) | |
498 | 474 | if ((sh == sh)) | |
499 | 475 | then if ((liquidator == borrower)) | |
500 | 476 | then throw("can't collapse self in this function") | |
501 | 477 | else { | |
502 | - | let $ | |
503 | - | let bp = $ | |
504 | - | let bpu = $ | |
478 | + | let $t01238912424 = userPower(borrower) | |
479 | + | let bp = $t01238912424._1 | |
480 | + | let bpu = $t01238912424._2 | |
505 | 481 | if ((bp > bpu)) | |
506 | 482 | then throw(((((("can't force collapse healthy user: u=" + borrower) + ", bp=") + toString(bp)) + ", bpu=") + toString(bpu))) | |
507 | 483 | else { | |
508 | - | let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in | |
484 | + | let asset = valueOrErrorMessage(getString(reserveAddress, "assetId"), ("no assetId field in rsr " + rsr)) | |
509 | 485 | let mc = if (fromProtected) | |
510 | - | then moveCollateral(borrower, asset, reserveAddress, | |
486 | + | then moveCollateral(borrower, asset, reserveAddress, rsr) | |
511 | 487 | else unit | |
512 | 488 | if ((mc == mc)) | |
513 | 489 | then { | |
514 | - | let $ | |
515 | - | if (($ | |
490 | + | let $t01278812896 = userBalance(reserveAddress, borrower) | |
491 | + | if (($t01278812896 == $t01278812896)) | |
516 | 492 | then { | |
517 | - | let userDebtUsd = $ | |
518 | - | let userDebt = $ | |
519 | - | let userAssetUsd = $ | |
520 | - | let borrowerDeposit = $ | |
521 | - | let ignore = $ | |
493 | + | let userDebtUsd = $t01278812896._5 | |
494 | + | let userDebt = $t01278812896._4 | |
495 | + | let userAssetUsd = $t01278812896._3 | |
496 | + | let borrowerDeposit = $t01278812896._2 | |
497 | + | let ignore = $t01278812896._1 | |
522 | 498 | let penaltizedUsd = fraction(min([userAssetUsd, userDebtUsd]), collapsePenalty, factorsBase) | |
523 | 499 | let transferredAssets = asInt(invoke(reserveAddress, "transferATokensFor", [borrower, liquidator, penaltizedUsd], nil)) | |
524 | 500 | if ((transferredAssets == transferredAssets)) | |
525 | 501 | then { | |
526 | - | let pRw1 = moveStream( | |
502 | + | let pRw1 = moveStream(rsr, "deposit", borrower, liquidator, transferredAssets) | |
527 | 503 | if ((pRw1 == pRw1)) | |
528 | 504 | then { | |
529 | 505 | let collapsed = asInt(invoke(reserveAddress, "collapseFor", [borrower], nil)) | |
530 | 506 | if ((collapsed == collapsed)) | |
531 | 507 | then { | |
532 | - | let pRw2 = updateStream( | |
508 | + | let pRw2 = updateStream(rsr, "borrow", borrower, -(collapsed), -(collapsed)) | |
533 | 509 | if ((pRw2 == pRw2)) | |
534 | 510 | then { | |
535 | - | let pRw3 = updateStream( | |
511 | + | let pRw3 = updateStream(rsr, "deposit", borrower, -(collapsed), -(collapsed)) | |
536 | 512 | if ((pRw3 == pRw3)) | |
537 | 513 | then nil | |
538 | 514 | else throw("Strict value is not equal to itself.") | |
539 | 515 | } | |
540 | 516 | else throw("Strict value is not equal to itself.") | |
541 | 517 | } | |
542 | 518 | else throw("Strict value is not equal to itself.") | |
543 | 519 | } | |
544 | 520 | else throw("Strict value is not equal to itself.") | |
545 | 521 | } | |
546 | 522 | else throw("Strict value is not equal to itself.") | |
547 | 523 | } | |
548 | 524 | else throw("Strict value is not equal to itself.") | |
549 | 525 | } | |
550 | 526 | else throw("Strict value is not equal to itself.") | |
551 | 527 | } | |
552 | 528 | } | |
553 | 529 | else throw("Strict value is not equal to itself.") | |
554 | 530 | } | |
555 | 531 | else throw("Strict value is not equal to itself.") | |
556 | 532 | } | |
557 | 533 | ||
558 | 534 | ||
559 | 535 | func spfr () = invoke(dC, "shareProfitFromReserves", nil, nil) | |
560 | 536 | ||
561 | 537 | ||
562 | - | func wdInternal (user, | |
563 | - | let sh = syncRewardsHeight(toString( | |
538 | + | func wdInternal (user,rsr,amount,op) = { | |
539 | + | let sh = syncRewardsHeight(toString(rsr)) | |
564 | 540 | if ((sh == sh)) | |
565 | 541 | then { | |
566 | - | let withdrawnAmount = asInt(invoke( | |
542 | + | let withdrawnAmount = asInt(invoke(rsr, op, [user, amount], nil)) | |
567 | 543 | if ((withdrawnAmount == withdrawnAmount)) | |
568 | 544 | then { | |
569 | - | let pRw = updateStream(toString( | |
545 | + | let pRw = updateStream(toString(rsr), "deposit", user, -(withdrawnAmount), -(withdrawnAmount)) | |
570 | 546 | if ((pRw == pRw)) | |
571 | 547 | then withdrawnAmount | |
572 | 548 | else throw("Strict value is not equal to itself.") | |
573 | 549 | } | |
574 | 550 | else throw("Strict value is not equal to itself.") | |
575 | 551 | } | |
576 | 552 | else throw("Strict value is not equal to itself.") | |
577 | 553 | } | |
578 | 554 | ||
579 | 555 | ||
580 | 556 | @Callable(i) | |
581 | 557 | func initialize (ca) = [writeConstString(configStore, ca)] | |
582 | 558 | ||
583 | 559 | ||
584 | 560 | ||
585 | 561 | @Callable(i) | |
586 | - | func deposit ( | |
562 | + | func deposit (rsr,useAsCollateral) = doDeposit(i, rsr, useAsCollateral) | |
587 | 563 | ||
588 | 564 | ||
589 | 565 | ||
590 | 566 | @Callable(i) | |
591 | - | func depositRef ( | |
567 | + | func depositRef (rsr,useAsCollateral,ref) = doDeposit(i, rsr, useAsCollateral) | |
592 | 568 | ||
593 | 569 | ||
594 | 570 | ||
595 | 571 | @Callable(i) | |
596 | - | func repay ( | |
572 | + | func repay (rsr) = { | |
597 | 573 | let user = toString(i.caller) | |
598 | - | let sh = syncRewardsHeight( | |
574 | + | let sh = syncRewardsHeight(rsr) | |
599 | 575 | if ((sh == sh)) | |
600 | 576 | then { | |
601 | - | let repaid = asInt(invoke( | |
577 | + | let repaid = asInt(invoke(vlR(rsr), "repayFor", [user], i.payments)) | |
602 | 578 | if ((repaid == repaid)) | |
603 | 579 | then { | |
604 | - | let pRw = updateStream( | |
580 | + | let pRw = updateStream(rsr, "borrow", user, -(repaid), -(repaid)) | |
605 | 581 | if ((pRw == pRw)) | |
606 | 582 | then nil | |
607 | 583 | else throw("Strict value is not equal to itself.") | |
608 | 584 | } | |
609 | 585 | else throw("Strict value is not equal to itself.") | |
610 | 586 | } | |
611 | 587 | else throw("Strict value is not equal to itself.") | |
612 | 588 | } | |
613 | 589 | ||
614 | 590 | ||
615 | 591 | ||
616 | 592 | @Callable(i) | |
617 | 593 | func mintAtoken (aTokenId,amount) = { | |
618 | 594 | let user = toString(i.caller) | |
619 | 595 | let targetContract = findReserveBy(aTokenIdStore, aTokenId) | |
620 | 596 | let sh = syncRewardsHeight(toString(targetContract)) | |
621 | 597 | if ((sh == sh)) | |
622 | 598 | then { | |
623 | 599 | let amt = asInt(invoke(targetContract, "mintAtokenFor", [user, amount], nil)) | |
624 | 600 | if ((amt == amt)) | |
625 | 601 | then { | |
626 | 602 | let pRw = updateStream(toString(targetContract), "deposit", user, -(amt), 0) | |
627 | 603 | if ((pRw == pRw)) | |
628 | 604 | then validateAfter(user, "minting") | |
629 | 605 | else throw("Strict value is not equal to itself.") | |
630 | 606 | } | |
631 | 607 | else throw("Strict value is not equal to itself.") | |
632 | 608 | } | |
633 | 609 | else throw("Strict value is not equal to itself.") | |
634 | 610 | } | |
635 | 611 | ||
636 | 612 | ||
637 | 613 | ||
638 | 614 | @Callable(i) | |
639 | 615 | func replenishWithAtoken () = { | |
640 | 616 | let user = toString(i.caller) | |
641 | 617 | let checks = ensureNoProtected(user) | |
642 | 618 | if ((checks == checks)) | |
643 | 619 | then { | |
644 | 620 | let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed")) | |
645 | 621 | let targetContract = findReserveBy(aTokenIdStore, aTokenId) | |
646 | 622 | let sh = syncRewardsHeight(toString(targetContract)) | |
647 | 623 | if ((sh == sh)) | |
648 | 624 | then { | |
649 | 625 | let amt = asInt(invoke(targetContract, "replenishWithAtokenFor", [user], i.payments)) | |
650 | 626 | if ((amt == amt)) | |
651 | 627 | then { | |
652 | 628 | let pRw = updateStream(toString(targetContract), "deposit", user, amt, 0) | |
653 | 629 | if ((pRw == pRw)) | |
654 | 630 | then nil | |
655 | 631 | else throw("Strict value is not equal to itself.") | |
656 | 632 | } | |
657 | 633 | else throw("Strict value is not equal to itself.") | |
658 | 634 | } | |
659 | 635 | else throw("Strict value is not equal to itself.") | |
660 | 636 | } | |
661 | 637 | else throw("Strict value is not equal to itself.") | |
662 | 638 | } | |
663 | 639 | ||
664 | 640 | ||
665 | 641 | ||
666 | 642 | @Callable(i) | |
667 | 643 | func redeemAtokens () = { | |
668 | 644 | let user = toString(i.caller) | |
669 | 645 | let aTokenId = toBase58String(valueOrErrorMessage(i.payments[0].assetId, "bad assetId: waves not allowed")) | |
670 | 646 | let targetContract = findReserveBy(aTokenIdStore, aTokenId) | |
671 | 647 | let sh = syncRewardsHeight(toString(targetContract)) | |
672 | 648 | if ((sh == sh)) | |
673 | 649 | then { | |
674 | 650 | let amt = asInt(invoke(targetContract, "redeemAtokensFor", [user], i.payments)) | |
675 | 651 | if ((amt == amt)) | |
676 | 652 | then { | |
677 | 653 | let pRw = updateStream(toString(targetContract), "deposit", user, 0, -(amt)) | |
678 | 654 | if ((pRw == pRw)) | |
679 | 655 | then nil | |
680 | 656 | else throw("Strict value is not equal to itself.") | |
681 | 657 | } | |
682 | 658 | else throw("Strict value is not equal to itself.") | |
683 | 659 | } | |
684 | 660 | else throw("Strict value is not equal to itself.") | |
685 | 661 | } | |
686 | 662 | ||
687 | 663 | ||
688 | 664 | ||
689 | 665 | @Callable(i) | |
690 | 666 | func withdraw (assetId,amount) = { | |
691 | 667 | let user = toString(i.caller) | |
692 | 668 | let result = asInt(wdInternal(user, findReserveBy(assetIdStore, assetId), amount, "withdrawFor")) | |
693 | 669 | if ((result == result)) | |
694 | 670 | then $Tuple2(validateAfter(user, "withdrawing"), result) | |
695 | 671 | else throw("Strict value is not equal to itself.") | |
696 | 672 | } | |
697 | 673 | ||
698 | 674 | ||
699 | 675 | ||
700 | 676 | @Callable(i) | |
701 | - | func withdraw2 ( | |
677 | + | func withdraw2 (rsr,amount) = { | |
702 | 678 | let user = toString(i.caller) | |
703 | - | let sh = syncRewardsHeight( | |
679 | + | let sh = syncRewardsHeight(rsr) | |
704 | 680 | if ((sh == sh)) | |
705 | 681 | then { | |
706 | - | let amt = asInt(invoke( | |
682 | + | let amt = asInt(invoke(vlR(rsr), "withdrawFor", [user, amount], nil)) | |
707 | 683 | if ((amt == amt)) | |
708 | 684 | then { | |
709 | - | let pRw = updateStream( | |
685 | + | let pRw = updateStream(rsr, "deposit", user, -(amt), -(amt)) | |
710 | 686 | if ((pRw == pRw)) | |
711 | 687 | then if (contains(liquidators, user)) | |
712 | 688 | then nil | |
713 | 689 | else validateAfter(user, "withdrawing2") | |
714 | 690 | else throw("Strict value is not equal to itself.") | |
715 | 691 | } | |
716 | 692 | else throw("Strict value is not equal to itself.") | |
717 | 693 | } | |
718 | 694 | else throw("Strict value is not equal to itself.") | |
719 | 695 | } | |
720 | 696 | ||
721 | 697 | ||
722 | 698 | ||
723 | 699 | @Callable(i) | |
724 | - | func protectCollateral ( | |
700 | + | func protectCollateral (rsr) = { | |
725 | 701 | let user = toString(i.caller) | |
726 | - | let r = | |
702 | + | let r = vlR(rsr) | |
727 | 703 | let amt = asInt(wdInternal(user, r, -1, "withdrawToMain")) | |
728 | 704 | if ((amt == amt)) | |
729 | 705 | then { | |
730 | 706 | let assetId = assetStrToId(getStringValue(r, assetIdStore)) | |
731 | 707 | let p = invoke(protectedReserve, "supplyFor", [user], [AttachedPayment(assetId, amt)]) | |
732 | 708 | if ((p == p)) | |
733 | 709 | then $Tuple2(validateAfter(user, "protecting"), amt) | |
734 | 710 | else throw("Strict value is not equal to itself.") | |
735 | 711 | } | |
736 | 712 | else throw("Strict value is not equal to itself.") | |
737 | 713 | } | |
738 | 714 | ||
739 | 715 | ||
740 | 716 | ||
741 | 717 | @Callable(i) | |
742 | 718 | func withdrawProtectedCollateral (assetId,amount) = { | |
743 | 719 | let user = toString(i.caller) | |
744 | 720 | let a = asInt(invoke(valueOrErrorMessage(protectedReserve, "no protectedReserve"), "withdrawFor", [user, assetId, amount], nil)) | |
745 | 721 | if ((a == a)) | |
746 | 722 | then validateAfter(user, "withdrawing protected collateral") | |
747 | 723 | else throw("Strict value is not equal to itself.") | |
748 | 724 | } | |
749 | 725 | ||
750 | 726 | ||
751 | 727 | ||
752 | 728 | @Callable(i) | |
729 | + | func normalizeCollateral (rsr) = { | |
730 | + | let addr = toString(i.caller) | |
731 | + | let rA = vlR(rsr) | |
732 | + | if ((rA == rA)) | |
733 | + | then { | |
734 | + | let sh = syncRewardsHeight(rsr) | |
735 | + | if ((sh == sh)) | |
736 | + | then { | |
737 | + | let assetIdStr = valueOrErrorMessage(getString(rA, "assetId"), ("no assetId field in reserveAddress " + rsr)) | |
738 | + | let mc = moveCollateral(addr, assetIdStr, rA, rsr) | |
739 | + | if ((mc == mc)) | |
740 | + | then nil | |
741 | + | else throw("Strict value is not equal to itself.") | |
742 | + | } | |
743 | + | else throw("Strict value is not equal to itself.") | |
744 | + | } | |
745 | + | else throw("Strict value is not equal to itself.") | |
746 | + | } | |
747 | + | ||
748 | + | ||
749 | + | ||
750 | + | @Callable(i) | |
753 | 751 | func borrow (assetId,amount) = { | |
754 | 752 | let user = toString(i.caller) | |
755 | - | let | |
756 | - | let sh = syncRewardsHeight(toString( | |
753 | + | let rsr = findReserveBy(assetIdStore, assetId) | |
754 | + | let sh = syncRewardsHeight(toString(rsr)) | |
757 | 755 | if ((sh == sh)) | |
758 | 756 | then { | |
759 | - | let a = invoke( | |
757 | + | let a = invoke(rsr, "borrowFor", [user, amount], nil) | |
760 | 758 | if ((a == a)) | |
761 | 759 | then { | |
762 | - | let pRw = updateStream(toString( | |
760 | + | let pRw = updateStream(toString(rsr), "borrow", user, amount, amount) | |
763 | 761 | if ((pRw == pRw)) | |
764 | 762 | then validateAfter(user, "borrowing") | |
765 | 763 | else throw("Strict value is not equal to itself.") | |
766 | 764 | } | |
767 | 765 | else throw("Strict value is not equal to itself.") | |
768 | 766 | } | |
769 | 767 | else throw("Strict value is not equal to itself.") | |
770 | 768 | } | |
771 | 769 | ||
772 | 770 | ||
773 | 771 | ||
774 | 772 | @Callable(i) | |
775 | - | func borrow2 ( | |
773 | + | func borrow2 (rsr,amount) = { | |
776 | 774 | let user = toString(i.caller) | |
777 | - | let sh = syncRewardsHeight( | |
775 | + | let sh = syncRewardsHeight(rsr) | |
778 | 776 | if ((sh == sh)) | |
779 | 777 | then { | |
780 | - | let a = invoke( | |
778 | + | let a = invoke(vlR(rsr), "borrowFor", [user, amount], nil) | |
781 | 779 | if ((a == a)) | |
782 | 780 | then { | |
783 | - | let pRw = updateStream( | |
781 | + | let pRw = updateStream(rsr, "borrow", user, amount, amount) | |
784 | 782 | if ((pRw == pRw)) | |
785 | 783 | then validateAfter(user, "borrowing") | |
786 | 784 | else throw("Strict value is not equal to itself.") | |
787 | 785 | } | |
788 | 786 | else throw("Strict value is not equal to itself.") | |
789 | 787 | } | |
790 | 788 | else throw("Strict value is not equal to itself.") | |
791 | 789 | } | |
792 | 790 | ||
793 | 791 | ||
794 | 792 | ||
795 | 793 | @Callable(i) | |
796 | - | func collapse ( | |
794 | + | func collapse (rsr,amount) = { | |
797 | 795 | let user = toString(i.caller) | |
798 | - | let sh = syncRewardsHeight( | |
796 | + | let sh = syncRewardsHeight(rsr) | |
799 | 797 | if ((sh == sh)) | |
800 | 798 | then { | |
801 | - | let c = asInt(invoke( | |
799 | + | let c = asInt(invoke(vlR(rsr), "collapseForAmount", [user, amount], nil)) | |
802 | 800 | if ((c == c)) | |
803 | 801 | then { | |
804 | - | let pRw = updateStream( | |
802 | + | let pRw = updateStream(rsr, "borrow", user, -(c), -(c)) | |
805 | 803 | if ((pRw == pRw)) | |
806 | 804 | then { | |
807 | - | let pRw2 = updateStream( | |
805 | + | let pRw2 = updateStream(rsr, "deposit", user, -(c), -(c)) | |
808 | 806 | if ((pRw2 == pRw2)) | |
809 | 807 | then nil | |
810 | 808 | else throw("Strict value is not equal to itself.") | |
811 | 809 | } | |
812 | 810 | else throw("Strict value is not equal to itself.") | |
813 | 811 | } | |
814 | 812 | else throw("Strict value is not equal to itself.") | |
815 | 813 | } | |
816 | 814 | else throw("Strict value is not equal to itself.") | |
817 | 815 | } | |
818 | 816 | ||
819 | 817 | ||
820 | 818 | ||
821 | 819 | @Callable(i) | |
822 | 820 | func claimEbReward2 (amount,lock) = { | |
823 | 821 | let user = toString(i.caller) | |
824 | 822 | let c = asInt(invoke(ebR, "claimEbRewardFor", [user, amount], nil)) | |
825 | 823 | if ((c == c)) | |
826 | 824 | then lockOrPayout(i.caller, c, lock) | |
827 | 825 | else throw("Strict value is not equal to itself.") | |
828 | 826 | } | |
829 | 827 | ||
830 | 828 | ||
831 | 829 | ||
832 | 830 | @Callable(i) | |
833 | - | func claimReward2 ( | |
834 | - | let v = | |
831 | + | func claimReward2 (rsr,amount,lock) = { | |
832 | + | let v = vlR(rsr) | |
835 | 833 | if ((v == v)) | |
836 | 834 | then { | |
837 | 835 | let user = toString(i.caller) | |
838 | - | let c = asInt(invoke(VD, "claimRewardFor", [ | |
836 | + | let c = asInt(invoke(VD, "claimRewardFor", [rsr, user, amount], nil)) | |
839 | 837 | if ((c == c)) | |
840 | 838 | then lockOrPayout(i.caller, c, lock) | |
841 | 839 | else throw("Strict value is not equal to itself.") | |
842 | 840 | } | |
843 | 841 | else throw("Strict value is not equal to itself.") | |
844 | 842 | } | |
845 | 843 | ||
846 | 844 | ||
847 | 845 | ||
848 | 846 | @Callable(i) | |
849 | 847 | func claimAllRewardsAndAllEbAvailable2 (lock,unstakeLegacy) = { | |
850 | 848 | let user = toString(i.caller) | |
851 | 849 | let cr = claimAllRewardsForUser(user) | |
852 | 850 | if ((cr == cr)) | |
853 | 851 | then { | |
854 | 852 | let lA = if (unstakeLegacy) | |
855 | 853 | then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil)) | |
856 | 854 | else 0 | |
857 | 855 | if ((lA == lA)) | |
858 | 856 | then lockOrPayout(i.caller, (cr + lA), lock) | |
859 | 857 | else throw("Strict value is not equal to itself.") | |
860 | 858 | } | |
861 | 859 | else throw("Strict value is not equal to itself.") | |
862 | 860 | } | |
863 | 861 | ||
864 | 862 | ||
865 | 863 | ||
866 | 864 | @Callable(i) | |
867 | - | func disableUseAsCollateral ( | |
865 | + | func disableUseAsCollateral (rsr) = { | |
868 | 866 | let user = toString(i.caller) | |
869 | - | let d = invoke( | |
867 | + | let d = invoke(vlR(rsr), "disableUseAsCollateralFor", [user], nil) | |
870 | 868 | if ((d == d)) | |
871 | 869 | then validateAfter(user, "changing collateral status") | |
872 | 870 | else throw("Strict value is not equal to itself.") | |
873 | 871 | } | |
874 | 872 | ||
875 | 873 | ||
876 | 874 | ||
877 | 875 | @Callable(i) | |
878 | 876 | func transferDebt (br,cr,b,la) = transferDebtInternal(toString(i.caller), br, cr, b, la, false) | |
879 | 877 | ||
880 | 878 | ||
881 | 879 | ||
882 | 880 | @Callable(i) | |
883 | 881 | func transferDebt2 (br,cr,b,la) = transferDebtInternal(toString(i.caller), br, cr, b, la, true) | |
884 | 882 | ||
885 | 883 | ||
886 | 884 | ||
887 | 885 | @Callable(i) | |
888 | 886 | func forceCollapse (r,b) = forceCollapseInternal(toString(i.caller), r, b, false) | |
889 | 887 | ||
890 | 888 | ||
891 | 889 | ||
892 | 890 | @Callable(i) | |
893 | 891 | func forceCollapse2 (r,b) = forceCollapseInternal(toString(i.caller), r, b, true) | |
894 | 892 | ||
895 | 893 | ||
896 | 894 | ||
897 | 895 | @Callable(i) | |
898 | 896 | func lockVires (factor,migrate) = { | |
899 | 897 | let user = toString(i.caller) | |
900 | 898 | let a = spfr() | |
901 | 899 | if ((a == a)) | |
902 | 900 | then { | |
903 | 901 | let migrateAmount = if (migrate) | |
904 | 902 | then asInt(invoke(vS, "unstakeAllViresFrom", [user], nil)) | |
905 | 903 | else 0 | |
906 | 904 | let total = (migrateAmount + viresPayment(i)) | |
907 | 905 | let l = invoke(dC, "lockFor", [user, factor], if ((total == 0)) | |
908 | 906 | then nil | |
909 | 907 | else [AttachedPayment(viresAssetId, total)]) | |
910 | 908 | if ((l == l)) | |
911 | 909 | then nil | |
912 | 910 | else throw("Strict value is not equal to itself.") | |
913 | 911 | } | |
914 | 912 | else throw("Strict value is not equal to itself.") | |
915 | 913 | } | |
916 | 914 | ||
917 | 915 | ||
918 | 916 | ||
919 | 917 | @Callable(i) | |
920 | 918 | func withdrawAllPossibleVires () = { | |
921 | 919 | let user = toString(i.caller) | |
922 | 920 | let a = spfr() | |
923 | 921 | if ((a == a)) | |
924 | 922 | then { | |
925 | 923 | let stakerViresAmount = asInt(invoke(vS, "unstakeAllViresFrom", [user], nil)) | |
926 | 924 | if ((stakerViresAmount == stakerViresAmount)) | |
927 | 925 | then { | |
928 | 926 | let u = invoke(dC, "withdrawUnlockedFor", [user], nil) | |
929 | 927 | if ((u == u)) | |
930 | 928 | then [ScriptTransfer(i.caller, stakerViresAmount, viresAssetId)] | |
931 | 929 | else throw("Strict value is not equal to itself.") | |
932 | 930 | } | |
933 | 931 | else throw("Strict value is not equal to itself.") | |
934 | 932 | } | |
935 | 933 | else throw("Strict value is not equal to itself.") | |
936 | 934 | } | |
937 | 935 | ||
938 | 936 | ||
939 | 937 | ||
940 | 938 | @Callable(i) | |
941 | 939 | func claimProtocolProfitFrom (from,relock) = { | |
942 | 940 | let user = toString(i.caller) | |
943 | 941 | let a = spfr() | |
944 | 942 | if ((a == a)) | |
945 | 943 | then { | |
946 | 944 | let u = invoke(dC, "claimProfit", [from, user, relock], nil) | |
947 | 945 | if ((u == u)) | |
948 | 946 | then nil | |
949 | 947 | else throw("Strict value is not equal to itself.") | |
950 | 948 | } | |
951 | 949 | else throw("Strict value is not equal to itself.") | |
952 | 950 | } | |
953 | 951 | ||
954 | 952 | ||
955 | 953 | ||
956 | 954 | @Callable(i) | |
957 | 955 | func withdrawUnlockedVires () = { | |
958 | 956 | let a = spfr() | |
959 | 957 | if ((a == a)) | |
960 | 958 | then { | |
961 | 959 | let u = invoke(dC, "withdrawUnlockedFor", [toString(i.caller)], nil) | |
962 | 960 | if ((u == u)) | |
963 | 961 | then nil | |
964 | 962 | else throw("Strict value is not equal to itself.") | |
965 | 963 | } | |
966 | 964 | else throw("Strict value is not equal to itself.") | |
967 | 965 | } | |
968 | 966 | ||
969 | 967 |
github/deemru/w8io/786bc32 163.73 ms ◑